Skip to content

Commit f8e931e

Browse files
grasci-armedriouk
andauthored
RTE Model: improve collecting device properties for multi-core devices (#2403)
Collect device effective properties for Pname="" also in case of multi-core devices Fix several typos in function names and comments Co-authored-by: Evgueni Driouk <edriouk@arm.com>
1 parent 1c81f58 commit f8e931e

9 files changed

Lines changed: 289 additions & 45 deletions

File tree

libs/rtemodel/include/RteDevice.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99
/******************************************************************************/
1010
/*
11-
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
11+
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
1212
*
1313
* SPDX-License-Identifier: Apache-2.0
1414
*/
@@ -1132,24 +1132,24 @@ class RteDeviceItem : public RteDeviceElement
11321132
* @brief collect effective properties for a supplied tag (e.g. "debug") and processor (e.g. "core_one")
11331133
* @param tag property tag
11341134
* @param properties reference to list of pointers to RteDeviceProperty to fill
1135-
* @param pName processor name, empty to collect properties for all processors
1135+
* @param pName processor name; if empty, collects only common properties (without Pname)
11361136
* @param bRecursive flag to collect properties recursively from RteDeviceItem parent chain
11371137
*/
11381138
void CollectEffectiveProperties(const std::string& tag, std::list<RteDeviceProperty*>& properties, const std::string& pName = EMPTY_STRING, bool bRecursive = true) const;
11391139

11401140
/**
11411141
* @brief collect all effective properties for given processor name
11421142
* @param properties reference to RteDevicePropertyMap to fill
1143-
* @param pName processor name, empty to collect properties for all processors
1143+
* @param pName processor name; if empty, collects only common properties (without Pname)
11441144
*/
11451145
void CollectEffectiveProperties(RteDevicePropertyMap& properties, const std::string& pName = EMPTY_STRING) const;
11461146

11471147

11481148
/**
11491149
* @brief fill m_effectiveProperties member by calling via CollectEffectiveProperties(RteDevicePropertyMap&, const std::string&)
1150-
* @param pName processor name, empty to collect properties for all processors
1150+
* @param pName processor name; if empty, collects only common properties (without Pname)
11511151
*/
1152-
void CollectEffectiveProperties(const std::string& pName = EMPTY_STRING);
1152+
const RteDevicePropertyMap& CollectEffectiveProperties(const std::string& pName = EMPTY_STRING);
11531153

11541154
protected:
11551155
std::map<std::string, RteDeviceProperty*> m_processors; // processor properties

libs/rtemodel/include/RteTarget.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99
/******************************************************************************/
1010
/*
11-
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
11+
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
1212
*
1313
* SPDX-License-Identifier: Apache-2.0
1414
*/
@@ -897,7 +897,7 @@ class RteTarget : public RteItem
897897

898898
/**
899899
* @brief getter for list of boards compatible with target's device
900-
* @param boards collection of RteBoad to fill
900+
* @param boards collection of RteBoard to fill
901901
*/
902902
void GetBoards(std::vector<RteBoard*>& boards) const;
903903

@@ -1042,7 +1042,7 @@ class RteTarget : public RteItem
10421042

10431043
void CollectPreIncludeStrings(RteComponent* c, int count);
10441044

1045-
void AddBoadProperties(RteDeviceItem* device, const std::string& processorName);
1045+
void AddBoardProperties(RteDeviceItem* device, const std::string& processorName);
10461046
void AddAlgorithm(RteItem* algo, RteItem* holder);
10471047

10481048
std::string NormalizeIncPath(const std::string& path) const;

libs/rtemodel/src/RteDevice.cpp

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
/******************************************************************************/
88
/*
9-
* Copyright (c) 2020-2021 Arm Limited. All rights reserved.
9+
* Copyright (c) 2020-2026 Arm Limited. All rights reserved.
1010
*
1111
* SPDX-License-Identifier: Apache-2.0
1212
*/
@@ -709,7 +709,7 @@ void RteDeviceItem::CollectEffectiveProperties(const string& tag, list<RteDevice
709709
RteDeviceProperty* p = dynamic_cast<RteDeviceProperty*>(child);
710710
if (p) {
711711
const string& propPname = p->GetProcessorName();
712-
if (pName.empty() || propPname.empty() || propPname == pName) {
712+
if (propPname.empty() || propPname == pName) {
713713
const string& id = p->GetID();
714714
RteDeviceProperty* pInserted = RteDeviceProperty::GetPropertyFromList(id, properties);
715715
if (p == pInserted)
@@ -736,8 +736,7 @@ void RteDeviceItem::CollectEffectiveProperties(const string& tag, list<RteDevice
736736
// more complicated - gets all available properties
737737
void RteDeviceItem::CollectEffectiveProperties(RteDevicePropertyMap& properties, const string& pName) const
738738
{
739-
RteDevicePropertyMap::iterator dstIt;
740-
for (auto [tag, props] : m_properties) {
739+
for (const auto& [tag, props] : m_properties) {
741740
auto dstIt = properties.find(tag);
742741
// add top containers if not yet exist
743742
if (dstIt == properties.end()) {
@@ -754,17 +753,18 @@ void RteDeviceItem::CollectEffectiveProperties(RteDevicePropertyMap& properties,
754753
}
755754

756755

757-
void RteDeviceItem::CollectEffectiveProperties(const string& pName)
756+
const RteDevicePropertyMap& RteDeviceItem::CollectEffectiveProperties(const string& pName)
758757
{
759758
m_effectiveProperties[pName] = RteEffectiveProperties();
760759
auto it = m_effectiveProperties.find(pName);
761760
RteDevicePropertyMap& pmap = it->second.m_propertyMap;
762761
CollectEffectiveProperties(pmap, pName);
763-
for (auto [_, l] : pmap) {
762+
for (const auto& [_, l] : pmap) {
764763
for (auto p : l) {
765764
p->CalculateCachedValues();
766765
}
767766
}
767+
return pmap;
768768
}
769769

770770

@@ -779,32 +779,21 @@ const list<RteDeviceProperty*>& RteEffectiveProperties::GetProperties(const stri
779779

780780
const RteDevicePropertyMap& RteDeviceItem::GetEffectiveProperties(const string& pName)
781781
{
782-
if (m_effectiveProperties.empty()) {
783-
for (auto [pn, p] : m_processors) {
784-
CollectEffectiveProperties(pn);
782+
if(pName.empty() || contains_key(m_processors, pName)) {
783+
auto itp = m_effectiveProperties.find(pName);
784+
if(itp != m_effectiveProperties.end()) {
785+
return itp->second.m_propertyMap;
785786
}
787+
return CollectEffectiveProperties(pName);
786788
}
787-
788-
auto itp = m_effectiveProperties.find(pName);
789-
if (itp != m_effectiveProperties.end()) {
790-
return itp->second.m_propertyMap;
791-
}
792-
793789
static const RteDevicePropertyMap EMPTY_PROPERTY_MAP;
794790
return EMPTY_PROPERTY_MAP;
795791
}
796792

797793
const list<RteDeviceProperty*>& RteDeviceItem::GetEffectiveProperties(const string& tag, const string& pName)
798794
{
799-
if (m_effectiveProperties.empty()) {
800-
GetEffectiveProperties(pName);
801-
}
802-
auto itp = m_effectiveProperties.find(pName);
803-
if (itp != m_effectiveProperties.end()) {
804-
const RteEffectiveProperties& effectiveProps = itp->second;
805-
return effectiveProps.GetProperties(tag);
806-
}
807-
return EMPTY_PROPERTY_LIST;
795+
const RteDevicePropertyMap& effectivePropMap = GetEffectiveProperties(pName);
796+
return get_or_default_const_ref(effectivePropMap, tag, EMPTY_PROPERTY_LIST);
808797
}
809798

810799
RteDeviceProperty* RteDeviceItem::GetSingleEffectiveProperty(const string& tag, const string& pName)
@@ -817,11 +806,11 @@ RteDeviceProperty* RteDeviceItem::GetSingleEffectiveProperty(const string& tag,
817806

818807
std::list<RteDeviceProperty*> RteDeviceItem::GetAllEffectiveProperties(const std::string& tag)
819808
{
820-
// Make a copy, simpler to merge with potential processor specific memories
821-
list<RteDeviceProperty*> properties = GetEffectiveProperties(tag, RteUtils::EMPTY_STRING);
809+
// Collect a list of unique properties (by pointer) across all processors for the given tag, without merging/normalizing them
810+
list<RteDeviceProperty*> properties;
822811
// Iterate over processors
823-
for(auto [pname, _] : GetProcessors()) {
824-
// Collect processor - unique memories
812+
for (const auto& [pname, _] : GetProcessors()) {
813+
// Collect processor-specific properties for this tag
825814
const list<RteDeviceProperty*>& procProps = GetEffectiveProperties(tag, pname);
826815
for(auto p : procProps) {
827816
if(std::find(properties.begin(), properties.end(), p) == properties.end()) {
@@ -1226,7 +1215,7 @@ string RteDeviceItemAggregate::GetSummaryString() const
12261215
// Memory (RAM/ROM)
12271216
unsigned long long ramSize = 0, romSize = 0;
12281217
// Get all memory properties
1229-
list<RteDeviceProperty*> mems = item->GetAllEffectiveProperties("memory");
1218+
const list<RteDeviceProperty*>& mems = item->GetAllEffectiveProperties("memory");
12301219
for (auto memsIt = mems.begin(); memsIt != mems.end(); ++memsIt) {
12311220
RteDeviceMemory* mem = dynamic_cast<RteDeviceMemory*>(*memsIt);
12321221
if (!mem) {

libs/rtemodel/src/RteTarget.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ void RteTarget::SetBoard(RteBoard* board) {
211211
if (project)
212212
project->SetBoardInfo(GetName(), board);
213213

214-
AddBoadProperties(GetDevice(), GetProcessorName());
214+
AddBoardProperties(GetDevice(), GetProcessorName());
215215
}
216216

217217

@@ -622,7 +622,7 @@ void RteTarget::ProcessAttributes() // called from SetAttributes(), AddAttribute
622622
AddDeviceProperties(m_device, GetProcessorName());
623623
};
624624

625-
void RteTarget::AddBoadProperties(RteDeviceItem* device, const string& processorName) {
625+
void RteTarget::AddBoardProperties(RteDeviceItem* device, const string& processorName) {
626626

627627
// remove all board algos if any: target can only refer to a single board
628628
for (auto it = m_algos.begin(); it != m_algos.end();) {
@@ -658,14 +658,14 @@ void RteTarget::AddDeviceProperties(RteDeviceItem* d, const string& processorNam
658658
return;
659659
}
660660

661-
AddBoadProperties(d, processorName);
661+
AddBoardProperties(d, processorName);
662662

663663
string packagePath = RteUtils::ExtractFilePath(package->GetPackageFileName(), true);
664664
// get properties for given processor:
665665
const RteDevicePropertyMap& propMap = d->GetEffectiveProperties(processorName);
666666

667667
for (auto itpm = propMap.begin(); itpm != propMap.end(); ++itpm) {
668-
const string& propType = itpm->first; // processor, feature, mamory, etc.
668+
const string& propType = itpm->first; // processor, feature, memory, etc.
669669
const list<RteDeviceProperty*>& props = itpm->second;
670670
for (auto itp = props.begin(); itp != props.end(); ++itp) {
671671
RteDeviceProperty *p = *itp;

libs/rtemodel/test/src/RteModelTest.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,29 @@ TEST(RteModelTest, LoadPacks) {
179179
// test recommended memory attributes: name and access
180180
summary = da->GetSummaryString();
181181
EXPECT_EQ(summary, "ARM Cortex-M4, 10 MHz, 128 KiB RAM, 256 KiB ROM");
182+
auto di = da->GetDeviceItem();
183+
EXPECT_EQ(di->GetProcessorCount(), 1);
184+
EXPECT_TRUE(di->GetEffectiveProperties("foo").empty());
185+
const auto& m4Properties = di->GetEffectiveProperties("");
186+
EXPECT_FALSE(m4Properties.empty());
187+
188+
da = rteModel->GetDeviceAggregate("RteTest_ARMCM0_Dual", "ARM:82");
189+
ASSERT_NE(da, nullptr);
190+
// test recommended memory attributes: name and access
191+
summary = da->GetSummaryString();
192+
EXPECT_EQ(summary, "ARM Cortex-M0, 10 MHz, ARM Cortex-M0, 10 MHz, 256 KiB RAM, 768 KiB ROM");
193+
di = da->GetDeviceItem();
194+
ASSERT_NE(di, nullptr);
195+
EXPECT_EQ(di->GetProcessorCount(), 2);
196+
const auto& commonProperties = di->GetEffectiveProperties("");
197+
const auto& core0Properties = di->GetEffectiveProperties("cm0_core0");
198+
const auto& core1Properties = di->GetEffectiveProperties("cm0_core1");
199+
200+
EXPECT_TRUE(RteModelTestConfig::IsSubset(commonProperties, core0Properties));
201+
EXPECT_TRUE(RteModelTestConfig::IsSubset(commonProperties, core1Properties));
202+
EXPECT_FALSE(RteModelTestConfig::IsSubset(core0Properties, commonProperties));
203+
EXPECT_FALSE(RteModelTestConfig::IsSubset(core1Properties, commonProperties));
204+
EXPECT_FALSE(RteModelTestConfig::IsSubset(core0Properties, core1Properties));
182205

183206
RteBoard* board = rteModel->FindBoard("RteTest board listing (Rev.C)");
184207
ASSERT_NE(board, nullptr);

libs/rtemodel/test/src/RteModelTestConfig.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <iostream>
1111
#include <fstream>
12+
#include <unordered_set>
1213

1314
using namespace std;
1415

@@ -60,6 +61,28 @@ void RteModelTestConfig::TearDown()
6061
RteFsUtils::DeleteTree(localPacks);
6162
}
6263

64+
65+
66+
bool RteModelTestConfig::IsSubset( const RteDevicePropertyMap& subset, const RteDevicePropertyMap& superset)
67+
{
68+
for(const auto& [key, subsetList] : subset) {
69+
auto it = superset.find(key);
70+
if(it == superset.end()) {
71+
return false;
72+
}
73+
std::unordered_set<RteDeviceProperty*> supersetListAsSet(it->second.begin(), it->second.end());
74+
75+
for(auto* ptr : subsetList) {
76+
if(supersetListAsSet.find(ptr) == supersetListAsSet.end()) {
77+
return false;
78+
}
79+
}
80+
}
81+
return true;
82+
}
83+
84+
85+
6386
void RteModelTestConfig::compareFile(const string& newFile, const string& refFile,
6487
const std::unordered_map<string, string>& expectedChangedFlags, const string& toolchain) const {
6588
ifstream streamNewFile, streamRefFile;

libs/rtemodel/test/src/RteModelTestConfig.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
#include <string>
1919
#include <unordered_map>
2020

21+
#include "RteDevice.h"
22+
2123
class RteModelTestConfig : public ::testing::Test
2224
{
2325
public:
@@ -26,6 +28,8 @@ class RteModelTestConfig : public ::testing::Test
2628
void compareFile(const std::string& newFile, const std::string& refFile,
2729
const std::unordered_map<std::string, std::string>& expectedChangedFlags, const std::string& toolchain) const;
2830

31+
static bool IsSubset(const RteDevicePropertyMap& subset, const RteDevicePropertyMap& superset);
32+
2933
protected:
3034
void SetUp() override;
3135
void TearDown() override;

0 commit comments

Comments
 (0)