diff --git a/Framework/Core/src/TopologyPolicy.cxx b/Framework/Core/src/TopologyPolicy.cxx index 5458d9d65da4a..a36f478909d6b 100644 --- a/Framework/Core/src/TopologyPolicy.cxx +++ b/Framework/Core/src/TopologyPolicy.cxx @@ -87,10 +87,6 @@ bool sporadicDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) if (isAWithSporadicInput && isBWithSporadicInput) { return false; } - // If a has sporadic inputs - if (isAWithSporadicInput && isBWithSporadicInput) { - return false; - } // We have a with sporadic inputs. We sort it later, unless there was already some actual // dependency between A and B. @@ -200,6 +196,7 @@ bool expendableDataDeps(DataProcessorSpec const& a, DataProcessorSpec const& b) if (sporadic) { 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; } O2_SIGNPOST_END(topology, sid, "expendableDataDeps", "%s is expendable. No inverse dependency from %s to %s => false.", a.name.c_str(), b.name.c_str(), a.name.c_str()); diff --git a/Framework/Core/src/runDataProcessing.cxx b/Framework/Core/src/runDataProcessing.cxx index f1111da79edd5..d691041a366cf 100644 --- a/Framework/Core/src/runDataProcessing.cxx +++ b/Framework/Core/src/runDataProcessing.cxx @@ -2835,6 +2835,20 @@ std::unique_ptr createRegistry() return std::make_unique(); } +void describeDataProcessorSpec(std::ostream& stream, DataProcessorSpec const& spec) +{ + stream << spec.name; + if (!spec.labels.empty()) { + stream << "("; + bool first = false; + for (auto& label : spec.labels) { + stream << (first ? "" : ",") << label.value; + first = true; + } + stream << ")"; + } +} + // This is a toy executor for the workflow spec // What it needs to do is: // @@ -3059,18 +3073,22 @@ int doMain(int argc, char** argv, o2::framework::WorkflowSpec const& workflow, edges.emplace_back(i, j); if (both) { std::ostringstream str; + describeDataProcessorSpec(str, physicalWorkflow[i]); + str << " has circular dependency with "; + describeDataProcessorSpec(str, physicalWorkflow[j]); + str << ":\n"; for (auto x : {i, j}) { str << physicalWorkflow[x].name << ":\n"; str << "inputs:\n"; for (auto& input : physicalWorkflow[x].inputs) { - str << "- " << input << "\n"; + str << "- " << input << " " << (int)input.lifetime << "\n"; } str << "outputs:\n"; for (auto& output : physicalWorkflow[x].outputs) { - str << "- " << output << "\n"; + str << "- " << output << " " << (int)output.lifetime << "\n"; } } - throw std::runtime_error(physicalWorkflow[i].name + " has circular dependency with " + physicalWorkflow[j].name + ":\n" + str.str()); + throw std::runtime_error(str.str()); } } }