From 33e948978a43227463304d00ebbb65454b5ed505 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 9 Jul 2025 09:24:46 +0200 Subject: [PATCH 1/2] DPL: fixes for dependency checks of devices with sporadic inputs in TopologyPolicy --- Framework/Core/src/TopologyPolicy.cxx | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/Framework/Core/src/TopologyPolicy.cxx b/Framework/Core/src/TopologyPolicy.cxx index a36f478909d6b..23e2a2eac0c5c 100644 --- a/Framework/Core/src/TopologyPolicy.cxx +++ b/Framework/Core/src/TopologyPolicy.cxx @@ -147,7 +147,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) if (!isAExpendable && !isBExpendable) { bool sporadic = sporadicDataDeps(a, b); if (sporadic) { - O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "false. Neither %s nor %s are expendable. However the former has sporadic inputs so we sort it after.", + O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. Neither %s nor %s are expendable. However the former has sporadic inputs so we sort it after.", a.name.c_str(), b.name.c_str()); return true; } @@ -159,7 +159,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) if (isAExpendable && isBExpendable) { bool sporadic = sporadicDataDeps(a, b); if (sporadic) { - O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "false. Both %s and %s are expendable. However the former has sporadic inputs, so we sort it after.", + O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. Both %s and %s are expendable. However the former has sporadic inputs, so we sort it after.", a.name.c_str(), b.name.c_str()); return true; } @@ -172,7 +172,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) if (isAExpendable && bResilient) { bool sporadic = sporadicDataDeps(a, b); if (sporadic) { - O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "false. %s is expendable but %s is resilient, however the former also has sporadic inputs, so we sort it after.", + O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. %s is expendable but %s is resilient, however the former also has sporadic inputs, so we sort it after.", a.name.c_str(), b.name.c_str()); return true; } @@ -188,8 +188,6 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) a.name.c_str(), hasDependency ? "There is however an inverse dependency" : "No inverse dependency", b.name.c_str(), a.name.c_str(), !hasDependency ? "true" : "false"); if (!hasDependency) { - O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "%s is expendable. There is however an inverse dependecy from %s to %s => true.", - a.name.c_str(), b.name.c_str(), a.name.c_str()); return true; } bool sporadic = sporadicDataDeps(a, b); @@ -203,13 +201,6 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) return false; } // b is expendable and a is not. We are fine with no dependency. - bool sporadic = sporadicDataDeps(a, b); - if (sporadic) { - O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "false. %s is expendable but %s is not. However the former has an sporadic input => true.", - b.name.c_str(), a.name.c_str()); - return true; - } - // b is expendable and a is not. We are fine with no dependency. O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "false. %s is expendable but %s is not. No need to add an unneeded dependency.", b.name.c_str(), a.name.c_str()); @@ -270,6 +261,12 @@ TopologyPolicy::DependencyChecker TopologyPolicyHelpers::alwaysDependent() hasDependency ? "true" : "false", dependent.name.c_str(), hasDependency ? "has" : "has not", ancestor.name.c_str()); return hasDependency; } + + if (sporadicDataDeps(ancestor, dependent)) { + O2_SIGNPOST_END(topology, sid, "alwaysDependent", "false. Dependent %s is an output proxy and ancestor %s has sporadic inputs", dependent.name.c_str(), ancestor.name.c_str()); + return false; + } + O2_SIGNPOST_END(topology, sid, "alwaysDependent", "true by default. Ancestor %s is not an output proxy.", ancestor.name.c_str()); return true; }; From 54c6f795b1ca01ab3c9b5ee0f4c5c8e21348e375 Mon Sep 17 00:00:00 2001 From: Ernst Hellbar Date: Wed, 9 Jul 2025 10:52:29 +0200 Subject: [PATCH 2/2] keeping the previous logic that output-proxies should be last --- Framework/Core/src/TopologyPolicy.cxx | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/Framework/Core/src/TopologyPolicy.cxx b/Framework/Core/src/TopologyPolicy.cxx index 23e2a2eac0c5c..f5a378e983b08 100644 --- a/Framework/Core/src/TopologyPolicy.cxx +++ b/Framework/Core/src/TopologyPolicy.cxx @@ -142,11 +142,14 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) bool isBExpendable = std::find_if(b.labels.begin(), b.labels.end(), checkExpendable) != b.labels.end(); bool isAExpendable = std::find_if(a.labels.begin(), a.labels.end(), checkExpendable) != a.labels.end(); bool bResilient = std::find_if(b.labels.begin(), b.labels.end(), checkResilient) != b.labels.end(); + const std::regex matcher(".*output-proxy.*"); + std::cmatch m; + bool isBOutputProxy = std::regex_match(b.name.data(), m, matcher); // If none is expendable. We simply return false and sort as usual. if (!isAExpendable && !isBExpendable) { bool sporadic = sporadicDataDeps(a, b); - if (sporadic) { + if (sporadic && !isBOutputProxy) { O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. Neither %s nor %s are expendable. However the former has sporadic inputs so we sort it after.", a.name.c_str(), b.name.c_str()); return true; @@ -158,7 +161,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) // If both are expendable. We return false and sort as usual. if (isAExpendable && isBExpendable) { bool sporadic = sporadicDataDeps(a, b); - if (sporadic) { + if (sporadic && !isBOutputProxy) { O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. Both %s and %s are expendable. However the former has sporadic inputs, so we sort it after.", a.name.c_str(), b.name.c_str()); return true; @@ -171,7 +174,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) // If a is expendable but b is resilient, we can keep the same order. if (isAExpendable && bResilient) { bool sporadic = sporadicDataDeps(a, b); - if (sporadic) { + if (sporadic && !isBOutputProxy) { O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "true. %s is expendable but %s is resilient, however the former also has sporadic inputs, so we sort it after.", a.name.c_str(), b.name.c_str()); return true; @@ -191,7 +194,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) return true; } bool sporadic = sporadicDataDeps(a, b); - if (sporadic) { + if (sporadic && !isBOutputProxy) { O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "%s is expendable. No inverse dependency from %s to %s. However the former has an occasioanl input => true.", a.name.c_str(), b.name.c_str(), a.name.c_str()); return true; @@ -262,11 +265,6 @@ TopologyPolicy::DependencyChecker TopologyPolicyHelpers::alwaysDependent() return hasDependency; } - if (sporadicDataDeps(ancestor, dependent)) { - O2_SIGNPOST_END(topology, sid, "alwaysDependent", "false. Dependent %s is an output proxy and ancestor %s has sporadic inputs", dependent.name.c_str(), ancestor.name.c_str()); - return false; - } - O2_SIGNPOST_END(topology, sid, "alwaysDependent", "true by default. Ancestor %s is not an output proxy.", ancestor.name.c_str()); return true; };