From 177c7c16ccaca4d7cb5b6f433f5d26424fb83446 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Mon, 24 Aug 2026 15:28:13 +0200 Subject: [PATCH 1/2] Improve MLOps target and NPU resolution Select default hardware and simulator targets by capability, using their declaration position as starting point. Restrict NPU listings to the selected device processor. Warn when explicit NPU requirements do not match DFP info. --- tools/projmgr/src/ProjMgrMlops.cpp | 66 +++++++++++++------ tools/projmgr/src/ProjMgrWorker.cpp | 11 ++++ .../data/MLOps/npu_mismatch.csolution.yml | 33 ++++++++++ tools/projmgr/test/src/ProjMgrUnitTests.cpp | 27 ++++++++ 4 files changed, 116 insertions(+), 21 deletions(-) create mode 100644 tools/projmgr/test/data/MLOps/npu_mismatch.csolution.yml diff --git a/tools/projmgr/src/ProjMgrMlops.cpp b/tools/projmgr/src/ProjMgrMlops.cpp index 2ec569de0..96094ec96 100644 --- a/tools/projmgr/src/ProjMgrMlops.cpp +++ b/tools/projmgr/src/ProjMgrMlops.cpp @@ -10,6 +10,8 @@ #include "ProjMgrParser.h" #include "ProjMgrUtils.h" +#include + using namespace std; ProjMgrMlops::ProjMgrMlops(ProjMgrWorker* worker) : m_worker(worker) { @@ -56,31 +58,34 @@ bool ProjMgrMlops::GetTargetSetItemRef(const TargetType& targetType, optional& npus, const string& filter) { if (!LoadPacks(context)) { return false; } + if (!selectedContext.empty()) { + if (!ProcessPrecedences(context, BoardOrDevice::Both)) { + return false; + } + if (!SetTargetAttributes(context, context.targetAttributes)) { + return false; + } + } CollectNpuInfo(context); for (const auto& npuInfoItem : context.npuInfoItems) { string npuString = npuInfoItem.type + " (" + npuInfoItem.macs + "):"; @@ -6460,6 +6468,9 @@ void ProjMgrWorker::CollectNpuInfo(ContextItem& context) { } // collect NPU features for each processor for (const auto& [pname, processor] : device->GetProcessors()) { + if (!context.deviceItem.pname.empty() && context.deviceItem.pname != pname) { + continue; + } const auto& features = device->GetEffectiveProperties("feature", pname); for (const auto& feature : features) { if (feature->GetAttribute("type") != "NPU") { diff --git a/tools/projmgr/test/data/MLOps/npu_mismatch.csolution.yml b/tools/projmgr/test/data/MLOps/npu_mismatch.csolution.yml new file mode 100644 index 000000000..e843837e8 --- /dev/null +++ b/tools/projmgr/test/data/MLOps/npu_mismatch.csolution.yml @@ -0,0 +1,33 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Open-CMSIS-Pack/devtools/main/tools/projmgr/schemas/csolution.schema.json + +solution: + compiler: AC6 + + mlops: + description: explicit npu configuration does not match DFP device information + npu: + type: Ethos-U85 + macs: 128 + + target-types: + - type: Hardware + device: RteTest_ARMCM0_Dual + target-set: + - set: + images: + - project-context: core0 + - project-context: core1 + + - type: Simulator + device: RteTest_ARMCM0_Dual + target-set: + - set: FVP-Test + debugger: + name: Arm-FVP + images: + - project-context: core0 + - project-context: core1 + + projects: + - project: core0/core0.cproject.yml + - project: core1/core1.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 229a5a0d4..9b3d37282 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -618,6 +618,21 @@ Ethos-U55 \\(128MACs\\):\n\ EXPECT_TRUE(regex_search(outStr, regex("\ Ethos-U55 \\(128MACs\\):\n\ ARM::RteTest_ARMCM0_Single, \\[cm0_core1\\] Cortex-M0\n"))); + + // verify NPU listing is restricted to the device and processor selected by a context + streamRedirect.ClearStringStreams(); + const string& csolution = testinput_folder + "/MLOps/minimal.csolution.yml"; + argv[3] = (char*)"--solution"; + argv[4] = (char*)csolution.c_str(); + argv[5] = (char*)"-c"; + argv[6] = (char*)"core0+Hardware"; + EXPECT_EQ(0, RunProjMgr(7, argv, 0)); + outStr = streamRedirect.GetOutString(); + EXPECT_NE(string::npos, outStr.find("ARM::RteTest_ARMCM0_Dual")); + EXPECT_NE(string::npos, outStr.find("[cm0_core0]")); + EXPECT_EQ(string::npos, outStr.find("ARM::RteTest_ARMCM0_Single")); + EXPECT_EQ(string::npos, outStr.find("[cm0_core1]")); + EXPECT_EQ(string::npos, outStr.find("Ethos-U55 (256MACs)")); } TEST_F(ProjMgrUnitTests, RunProjMgr_ListComponents) { @@ -7869,6 +7884,7 @@ TEST_F(ProjMgrUnitTests, ParseCommandLine_MutualExclusionOptions) { } TEST_F(ProjMgrUnitTests, GenerateMLOps) { + StdStreamRedirect streamRedirect; char* argv[5]; string csolution = testinput_folder + "/MLOps/minimal.csolution.yml"; argv[1] = (char*)"convert"; @@ -7908,6 +7924,17 @@ TEST_F(ProjMgrUnitTests, GenerateMLOps) { EXPECT_EQ("Ethos-U55", mlopsMacsOnly["cbuild-mlops"]["npu"]["type"].as()); EXPECT_EQ("128", mlopsMacsOnly["cbuild-mlops"]["npu"]["macs"].as()); + // Ethos-U85 and 128 MACs both exist in the DFP, but not as the same NPU capability + // verify that the type matches while the incompatible MAC count produces a warning + csolution = testinput_folder + "/MLOps/npu_mismatch.csolution.yml"; + argv[2] = (char*)csolution.c_str(); + EXPECT_EQ(0, RunProjMgr(5, argv, m_envp)); + const string& warningStr = streamRedirect.GetErrorString(); + EXPECT_EQ(string::npos, warningStr.find("npu_mismatch.csolution.yml - warning csolution: " + "mlops.npu.type value does not match DFP device information")); + EXPECT_NE(string::npos, warningStr.find("npu_mismatch.csolution.yml - warning csolution: " + "mlops.npu.macs value does not match DFP device information")); + // hardware target is not present csolution = testinput_folder + "/MLOps/no_hardware.csolution.yml"; argv[2] = (char*)csolution.c_str(); From 68d56a6815e418b662efa6d196b0358768fc6023 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Mon, 24 Aug 2026 16:07:03 +0200 Subject: [PATCH 2/2] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tools/projmgr/test/src/ProjMgrUnitTests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 9b3d37282..f03e78d29 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -7926,10 +7926,11 @@ TEST_F(ProjMgrUnitTests, GenerateMLOps) { // Ethos-U85 and 128 MACs both exist in the DFP, but not as the same NPU capability // verify that the type matches while the incompatible MAC count produces a warning + streamRedirect.ClearStringStreams(); csolution = testinput_folder + "/MLOps/npu_mismatch.csolution.yml"; argv[2] = (char*)csolution.c_str(); EXPECT_EQ(0, RunProjMgr(5, argv, m_envp)); - const string& warningStr = streamRedirect.GetErrorString(); + const string warningStr = streamRedirect.GetErrorString(); EXPECT_EQ(string::npos, warningStr.find("npu_mismatch.csolution.yml - warning csolution: " "mlops.npu.type value does not match DFP device information")); EXPECT_NE(string::npos, warningStr.find("npu_mismatch.csolution.yml - warning csolution: "