27 std::function<void(IAlgorithm*,std::set<IAlgorithm*>&,
bool)> func;
32 func = [&](IAlgorithm* alg, std::set<IAlgorithm*>& thealgs,
bool isAdding) {
33 isAdding = (isAdding || std::regex_search( std::string(alg->nameKey()) , sequenceNameRegex) );
37 if(
auto seq =
dynamic_cast<Gaudi::Sequence*
>( alg )) {
38 auto subalgs = seq->subAlgorithms();
39 for(
auto thisAlg : *subalgs) {
40 func(thisAlg,thealgs,isAdding);
47 std::set<IAlgorithm*> subalgs;
48 for ( IAlgorithm* ialgoPtr : algos ) {
49 func(ialgoPtr,subalgs,
false);
53 DataObjIDColl globalInp, globalOutp;
54 std::map<std::string, DataObjIDColl> algosOutputDependenciesMap;
55 std::map<std::string, DataObjIDColl> algosInputDependenciesMap;
57 for ( IAlgorithm* ialgoPtr : subalgs ) {
58 if(ialgoPtr->isSequence())
continue;
60 Gaudi::Algorithm* algoPtr =
dynamic_cast<Gaudi::Algorithm*
>( ialgoPtr );
61 if ( !algoPtr )
continue;
62 DataObjIDColl algoOutputs;
63 for (
const auto &
id : algoPtr->outputDataObjs() ) {
64 globalOutp.insert(
id );
65 algoOutputs.insert(
id );
71 DHHVisitor avis( i1, i2 );
72 algoPtr->acceptDHVisitor( &avis );
74 DataObjIDColl algoDependencies;
75 for (
const DataObjID&
id : algoPtr->inputDataObjs() ) {
76 algoDependencies.insert(
id );
77 globalInp.insert(
id );
80 std::string algoName = ialgoPtr->nameKey();
81 if(ialgoPtr->type()!= algoName) {
82 algoName = ialgoPtr->type() +
"/" + algoName;
85 algosInputDependenciesMap[algoName] = std::move(algoDependencies);
86 algosOutputDependenciesMap[algoName] = std::move(algoOutputs);
92 std::ofstream stream{
m_fileName, std::ofstream::out };
93 stream <<
"digraph datadeps {\n rankdir=\"LR\";\n";
95 auto addNode = [&](std::string_view id, std::string_view name, std::string_view shape=
"box" ) {
96 stream <<
" " <<
id <<
" [label=\"" << name <<
"\";shape=" << shape <<
"];\n";
98 auto addEdge = [&](std::string_view srcId, std::string_view tgtId, std::string_view
label ) {
99 stream <<
" " << srcId <<
" -> " << tgtId <<
" [label=\"" <<
label <<
"\"];\n";
103 std::map<std::string,std::pair<std::set<std::string>,std::set<std::string>>> deps;
108 for (
const auto& [algName, ideps] : algosInputDependenciesMap ) {
109 for (
const auto &dep: ideps) {
110 deps[dep.key()].second.insert(algName);
113 for (
const auto& [algName, odeps] : algosOutputDependenciesMap ) {
114 for (
const auto &dep: odeps) {
115 deps[dep.key()].first.insert(algName);
119 std::size_t algoIndex = 0ul;
120 std::map<std::string,std::string> keyToName;
121 std::string inputs,outputs;
123 for(
auto& [dep, pcs] : deps) {
124 auto& [producers,consumers] = pcs;
125 if(producers.empty()) {
126 std::string algIndex =
"Input_" + std::to_string( algoIndex );
127 addNode( algIndex, dep,
"plaintext" );
128 keyToName[dep] = algIndex;
130 producers.insert(dep);
131 inputs += algIndex +
"; ";
132 }
else if(consumers.empty()) {
133 std::string algIndex =
"Output_" + std::to_string( algoIndex );
134 addNode( algIndex, dep,
"plaintext" );
135 keyToName[dep] = algIndex;
137 consumers.insert(dep);
138 outputs += algIndex +
"; ";
142 for (
const auto& [algName, ideps] : algosInputDependenciesMap ) {
143 std::string algIndex =
"Alg_" + std::to_string( algoIndex );
144 addNode( algIndex, algName,
"box" );
145 keyToName[algName] = std::move(algIndex);
149 for(
const auto& [dep, pcs] : deps) {
150 auto& [producers,consumers] = pcs;
151 for(
auto& producer : producers) {
152 for(
auto& consumer: consumers) {
153 addEdge(keyToName.at(producer),keyToName.at(consumer),dep!=producer && dep!=consumer ? dep :
" ");
158 if(!inputs.empty()) {
159 stream <<
" { rank = same; " << inputs <<
"}\n";
161 if(!outputs.empty()) {
162 stream <<
" { rank = same; " << outputs <<
"}\n";
168 return StatusCode::SUCCESS;