Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PrecedenceRulesGraph.cpp
Go to the documentation of this file.
1 #include "PrecedenceRulesGraph.h"
2 #include "PRGraphVisitors.h"
3 
4 #include <boost/property_map/transform_value_property_map.hpp>
5 #include <fstream>
6 
8 
9 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
10 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
11 
12 namespace {
13  //---------------------------------------------------------------------------
15  const char* stateToString( const int& stateId ) {
16  switch ( stateId ) {
17  case 0:
18  return "FALSE";
19  case 1:
20  return "TRUE";
21  default:
22  return "UNDEFINED";
23  }
24  }
25 } // namespace
26 
27 namespace concurrency {
28 
29  //---------------------------------------------------------------------------
31 
32  if ( std::find( m_parents.begin(), m_parents.end(), node ) == m_parents.end() ) m_parents.push_back( node );
33  }
34 
35  //--------------------------------------------------------------------------
37 
38  if ( std::find( m_children.begin(), m_children.end(), node ) == m_children.end() ) m_children.push_back( node );
39  }
40 
41  //---------------------------------------------------------------------------
43  const std::vector<int>& node_decisions, const unsigned int& recursionLevel ) const {
44 
45  output << std::string( recursionLevel, ' ' ) << m_nodeName << " (" << m_nodeIndex << ")"
46  << ", w/ decision: " << stateToString( node_decisions[m_nodeIndex] ) << "(" << node_decisions[m_nodeIndex]
47  << ")" << std::endl;
48 
49  for ( auto daughter : m_children ) daughter->printState( output, states, node_decisions, recursionLevel + 2 );
50  }
51 
52  //---------------------------------------------------------------------------
54 
55  if ( visitor.visitEnter( *this ) ) {
56  // try to aggregate a decision
57  bool result = visitor.visit( *this );
58  return !result;
59  }
60 
61  return false; // visitor was rejected (since the decision node has an aggregated decision already)
62  }
63 
64  //---------------------------------------------------------------------------
66  const std::vector<int>& node_decisions, const unsigned int& recursionLevel ) const {
67  output << std::string( recursionLevel, ' ' ) << m_nodeName << " (" << m_nodeIndex << ")"
68  << ", w/ decision: " << stateToString( node_decisions[m_nodeIndex] ) << "(" << node_decisions[m_nodeIndex]
69  << ")"
70  << ", in state: " << states[m_algoIndex] << std::endl;
71  }
72 
73  //---------------------------------------------------------------------------
75 
76  if ( visitor.visitEnter( *this ) ) {
77  visitor.visit( *this );
78  return true; // visitor was accepted to promote the algorithm
79  }
80 
81  return false; // visitor was rejected (since the algorithm already produced a decision)
82  }
83 
84  //---------------------------------------------------------------------------
86 
87  if ( std::find( m_parents.begin(), m_parents.end(), node ) == m_parents.end() ) m_parents.push_back( node );
88  }
89 
90  //---------------------------------------------------------------------------
92 
93  if ( std::find( m_outputs.begin(), m_outputs.end(), node ) == m_outputs.end() ) m_outputs.push_back( node );
94  }
95 
96  //---------------------------------------------------------------------------
98 
99  if ( std::find( m_inputs.begin(), m_inputs.end(), node ) == m_inputs.end() ) m_inputs.push_back( node );
100  }
101 
102  //---------------------------------------------------------------------------
104  if ( serviceLocator()->existsService( "CondSvc" ) ) {
105  SmartIF<ICondSvc> condSvc{serviceLocator()->service( "CondSvc" )};
106  if ( condSvc.isValid() ) {
107  info() << "CondSvc found. DF precedence rules will be augmented with 'Conditions'" << endmsg;
108  m_conditionsRealmEnabled = true;
109  }
110  }
111 
112  // Detach condition algorithms from the CF realm
113  if ( m_conditionsRealmEnabled ) {
114  SmartIF<ICondSvc> condSvc{serviceLocator()->service( "CondSvc", false )};
115  auto& condAlgs = condSvc->condAlgs();
116  for ( const auto algo : condAlgs ) {
117  auto itA = m_algoNameToAlgoNodeMap.find( algo->name() );
118  if ( itA != m_algoNameToAlgoNodeMap.end() ) {
119  concurrency::AlgorithmNode* algoNode = itA->second.get();
120  debug() << "Detaching condition algorithm '" << algo->name() << "' from the CF realm.." << endmsg;
121  for ( auto parent : algoNode->getParentDecisionHubs() ) {
122  parent->m_children.erase( std::remove( parent->m_children.begin(), parent->m_children.end(), algoNode ),
123  parent->m_children.end() );
124  // clean up also auxiliary BGL-based graph of precedence rules
125  if ( m_enableAnalysis )
126  boost::remove_edge( node( algoNode->getNodeName() ), node( parent->getNodeName() ), m_PRGraph );
127  }
128  algoNode->m_parents.clear();
129 
130  } else {
131  warning() << "Algorithm '" << algo->name() << "' is not registered in the graph" << endmsg;
132  }
133  }
134  }
135 
136  StatusCode sc = buildDataDependenciesRealm();
137 
138  if ( !sc.isSuccess() ) error() << "Could not build the data dependency realm." << endmsg;
139 
140  ON_DEBUG debug() << dumpDataFlow() << endmsg;
141 
142  return sc;
143  }
144 
145  //---------------------------------------------------------------------------
147 
148  const std::string& algoName = algo->name();
149 
150  m_algoNameToAlgoInputsMap[algoName] = algo->inputDataObjs();
151  m_algoNameToAlgoOutputsMap[algoName] = algo->outputDataObjs();
152 
153  ON_VERBOSE {
154  verbose() << " Inputs of " << algoName << ": ";
155  for ( auto tag : algo->inputDataObjs() ) verbose() << tag << " | ";
156  verbose() << endmsg;
157 
158  verbose() << " Outputs of " << algoName << ": ";
159  for ( auto tag : algo->outputDataObjs() ) verbose() << tag << " | ";
160  verbose() << endmsg;
161  }
162  }
163 
164  //---------------------------------------------------------------------------
166 
167  StatusCode global_sc( StatusCode::SUCCESS, true );
168 
169  // Production of DataNodes by AlgorithmNodes (DataNodes are created here)
170  for ( auto& algo : m_algoNameToAlgoNodeMap ) {
171 
172  auto& outputs = m_algoNameToAlgoOutputsMap[algo.first];
173  for ( auto output : outputs ) {
174  const auto sc = addDataNode( output );
175  if ( !sc.isSuccess() ) {
176  error() << "Extra producer (" << algo.first << ") for DataObject @ " << output
177  << " has been detected: this is not allowed." << endmsg;
178  global_sc = sc;
179  }
180  auto dataNode = getDataNode( output );
181  dataNode->addProducerNode( algo.second.get() );
182  algo.second->addOutputDataNode( dataNode );
183 
184  // Mirror the action above in the BGL-based graph
185  if ( m_enableAnalysis )
186  boost::add_edge( node( algo.second->getNodeName() ), node( output.fullKey() ), m_PRGraph );
187  }
188  }
189 
190  // Consumption of DataNodes by AlgorithmNodes
191  for ( auto& algo : m_algoNameToAlgoNodeMap ) {
192 
193  for ( auto input : m_algoNameToAlgoInputsMap[algo.first] ) {
194 
195  auto itP = m_dataPathToDataNodeMap.find( input );
196 
197  DataNode* dataNode = ( itP != m_dataPathToDataNodeMap.end() ? getDataNode( input ) : nullptr );
198  if ( dataNode ) {
199  dataNode->addConsumerNode( algo.second.get() );
200  algo.second->addInputDataNode( dataNode );
201 
202  // Mirror the action above in the BGL-based graph
203  if ( m_enableAnalysis )
204  boost::add_edge( node( input.fullKey() ), node( algo.second->getNodeName() ), m_PRGraph );
205  }
206  }
207  }
208 
209  return global_sc;
210  }
211 
212  //---------------------------------------------------------------------------
214  bool inverted, bool allPass ) {
215 
217 
219 
220  auto& algoName = algo->name();
221 
222  concurrency::AlgorithmNode* algoNode;
223 
224  auto itA = m_algoNameToAlgoNodeMap.find( algoName );
225  if ( itA != m_algoNameToAlgoNodeMap.end() ) {
226  algoNode = itA->second.get();
227  } else {
228  auto r = m_algoNameToAlgoNodeMap.emplace(
229  algoName, std::make_unique<concurrency::AlgorithmNode>( *this, algo, m_nodeCounter, m_algoCounter, inverted,
230  allPass ) );
231  algoNode = r.first->second.get();
232 
233  // Mirror AlgorithmNode in the BGL-based graph
234  if ( m_enableAnalysis ) {
235  boost::add_vertex( AlgoProps( algo, m_nodeCounter, m_algoCounter, inverted, allPass ), m_PRGraph );
236  }
237  ++m_nodeCounter;
238  ++m_algoCounter;
239  ON_VERBOSE verbose() << "AlgorithmNode '" << algoName << "' added @ " << algoNode << endmsg;
240 
241  registerIODataObjects( algo );
242  }
243 
245  auto itP = m_decisionNameToDecisionHubMap.find( parentName );
246  if ( itP != m_decisionNameToDecisionHubMap.end() ) {
247  auto parentNode = itP->second.get();
248 
249  parentNode->addDaughterNode( algoNode );
250  algoNode->addParentNode( parentNode );
251 
252  // Mirror algorithm to CF parent relationship in the BGL-based graph
253  if ( m_enableAnalysis ) boost::add_edge( node( algo->name() ), node( parentName ), m_PRGraph );
254 
255  ON_VERBOSE verbose() << "Attached AlgorithmNode '" << algo->name() << "' to parent DecisionNode '" << parentName
256  << "'" << endmsg;
257  } else {
258  sc = StatusCode::FAILURE;
259  error() << "Parent DecisionNode '" << parentName << "' was not found" << endmsg;
260  }
261 
262  return sc;
263  }
264 
265  //---------------------------------------------------------------------------
267 
268  auto itD = m_dataPathToDataNodeMap.find( dataPath );
269  if ( itD != m_dataPathToDataNodeMap.end() ) return StatusCode::SUCCESS;
270 
272  if ( !m_conditionsRealmEnabled ) {
273  dataNode = std::make_unique<concurrency::DataNode>( *this, dataPath );
274  ON_VERBOSE verbose() << " DataNode " << dataPath << " added @ " << dataNode.get() << endmsg;
275  // Mirror the action above in the BGL-based graph
276  if ( m_enableAnalysis ) boost::add_vertex( DataProps( dataPath ), m_PRGraph );
277  } else {
278  SmartIF<ICondSvc> condSvc{serviceLocator()->service( "CondSvc", false )};
279  if ( condSvc->isRegistered( dataPath ) ) {
280  dataNode = std::make_unique<concurrency::ConditionNode>( *this, dataPath, condSvc );
281  ON_VERBOSE verbose() << " ConditionNode " << dataPath << " added @ " << dataNode.get() << endmsg;
282  // Mirror the action above in the BGL-based graph
283  if ( m_enableAnalysis ) boost::add_vertex( CondDataProps( dataPath ), m_PRGraph );
284  } else {
285  dataNode = std::make_unique<concurrency::DataNode>( *this, dataPath );
286  ON_VERBOSE verbose() << " DataNode " << dataPath << " added @ " << dataNode.get() << endmsg;
287  // Mirror the action above in the BGL-based graph
288  if ( m_enableAnalysis ) boost::add_vertex( DataProps( dataPath ), m_PRGraph );
289  }
290  }
291  m_dataPathToDataNodeMap.emplace( dataPath, std::move( dataNode ) );
292  return StatusCode::SUCCESS;
293  }
294 
295  //---------------------------------------------------------------------------
297  Concurrent modeConcurrent, PromptDecision modePromptDecision,
298  ModeOr modeOR, AllPass allPass, Inverted isInverted ) {
299 
301 
303 
304  auto& decisionHubName = decisionHubAlgo->name();
305 
306  auto itA = m_decisionNameToDecisionHubMap.find( decisionHubName );
307  concurrency::DecisionNode* decisionHubNode;
308  if ( itA != m_decisionNameToDecisionHubMap.end() ) {
309  decisionHubNode = itA->second.get();
310  } else {
311  auto r = m_decisionNameToDecisionHubMap.emplace(
312  decisionHubName,
313  std::make_unique<concurrency::DecisionNode>( *this, m_nodeCounter, decisionHubName, modeConcurrent,
314  modePromptDecision, modeOR, allPass, isInverted ) );
315  decisionHubNode = r.first->second.get();
316  // Mirror DecisionNode in the BGL-based graph
317  if ( m_enableAnalysis ) {
318  boost::add_vertex( DecisionHubProps( decisionHubName, m_nodeCounter, modeConcurrent, modePromptDecision, modeOR,
319  allPass, isInverted ),
320  m_PRGraph );
321  }
322 
323  ++m_nodeCounter;
324 
325  ON_VERBOSE verbose() << "DecisionNode '" << decisionHubName << "' added @ " << decisionHubNode << endmsg;
326  }
327 
329  auto itP = m_decisionNameToDecisionHubMap.find( parentName );
330  if ( itP != m_decisionNameToDecisionHubMap.end() ) {
331  auto parentNode = itP->second.get();
332  parentNode->addDaughterNode( decisionHubNode );
333  decisionHubNode->addParentNode( parentNode );
334 
335  // Mirror DecisionNode-to-DecisionNode relationship in the BGL-based graph
336  if ( m_enableAnalysis ) boost::add_edge( node( decisionHubName ), node( parentName ), m_PRGraph );
337 
338  ON_VERBOSE verbose() << "Attached DecisionNode '" << decisionHubName << "' to parent DecisionNode '" << parentName
339  << "'" << endmsg;
340  } else {
341  sc = StatusCode::FAILURE;
342  error() << "Parent DecisionNode '" << parentName << "' was not found" << endmsg;
343  }
344 
345  return sc;
346  }
347 
348  //---------------------------------------------------------------------------
350  concurrency::PromptDecision modePromptDecision, concurrency::ModeOr modeOR,
351  concurrency::AllPass allPass, concurrency::Inverted isInverted ) {
352 
353  auto itH = m_decisionNameToDecisionHubMap.find( headName );
354  if ( itH != m_decisionNameToDecisionHubMap.end() ) {
355  m_headNode = itH->second.get();
356  } else {
357  auto r = m_decisionNameToDecisionHubMap.emplace(
358  headName, std::make_unique<concurrency::DecisionNode>( *this, m_nodeCounter, headName, modeConcurrent,
359  modePromptDecision, modeOR, allPass, isInverted ) );
360  m_headNode = r.first->second.get();
361 
362  // Mirror the action above in the BGL-based graph
363  if ( m_enableAnalysis ) {
364  boost::add_vertex( DecisionHubProps( headName, m_nodeCounter, modeConcurrent, modePromptDecision, modeOR,
365  allPass, isInverted ),
366  m_PRGraph );
367  }
368 
369  ++m_nodeCounter;
370  }
371  }
372 
373  //---------------------------------------------------------------------------
375  auto vp = vertices( m_PRGraph );
376  auto i = std::find_if( vp.first, vp.second, [&]( const PRVertexDesc& v ) {
377  return boost::apply_visitor( precedence::VertexName(), m_PRGraph[v] ) == name;
378  } );
379  return i != vp.second ? *i : PRVertexDesc{};
380  }
381 
382  //---------------------------------------------------------------------------
384  // iterate through Algorithm nodes
385  for ( auto& pr : m_algoNameToAlgoNodeMap ) pr.second->accept( visitor );
386 
387  // iterate through DecisionHub nodes
388  for ( auto& pr : m_decisionNameToDecisionHubMap ) pr.second->accept( visitor );
389 
390  // iterate through Data [and Conditions] nodes
391  for ( auto& pr : m_dataPathToDataNodeMap ) pr.second->accept( visitor );
392  }
393 
394  //---------------------------------------------------------------------------
396 
397  info() << "Starting ranking by data outputs .. " << endmsg;
398  for ( auto& pair : m_algoNameToAlgoNodeMap ) {
399  ON_DEBUG debug() << " Ranking " << pair.first << "... " << endmsg;
400  pair.second->accept( ranker );
401  ON_DEBUG debug() << " ... rank of " << pair.first << ": " << pair.second->getRank() << endmsg;
402  }
403  }
404 
406  std::ostringstream ost;
407  dumpControlFlow( ost, m_headNode, 0 );
408  return ost.str();
409  }
410 
412  const int& indent ) const {
413  ost << std::string( indent * 2, ' ' );
414  DecisionNode* dn = dynamic_cast<DecisionNode*>( node );
415  AlgorithmNode* an = dynamic_cast<AlgorithmNode*>( node );
416  if ( dn != 0 ) {
417  if ( node != m_headNode ) {
418  ost << node->getNodeName() << " [Seq] ";
419  ost << ( ( dn->m_modeConcurrent ) ? " [Concurrent] " : " [Sequential] " );
420  ost << ( ( dn->m_modePromptDecision ) ? " [Prompt] " : "" );
421  ost << ( ( dn->m_modeOR ) ? " [OR] " : "" );
422  ost << ( ( dn->m_allPass ) ? " [PASS] " : "" );
423  ost << "\n";
424  }
425  for ( const auto& i : dn->getDaughters() ) dumpControlFlow( ost, i, indent + 1 );
426  } else if ( an != 0 ) {
427  ost << node->getNodeName() << " [Alg] ";
428  if ( an != 0 ) {
429  auto ar = an->getAlgorithm();
430  ost << " [n= " << ar->cardinality() << "]";
431  ost << ( ( !ar->isClonable() ) ? " [unclonable] " : "" );
432  }
433  ost << "\n";
434  }
435  }
436 
437  //---------------------------------------------------------------------------
439 
440  const char idt[] = " ";
441  std::ostringstream ost;
442 
443  ost << "\n" << idt << "====================================\n";
444  ost << idt << "Data origins and destinations:\n";
445  ost << idt << "====================================\n";
446 
447  for ( auto& pair : m_dataPathToDataNodeMap ) {
448 
449  for ( auto algoNode : pair.second->getProducers() ) ost << idt << " " << algoNode->getNodeName() << "\n";
450 
451  ost << idt << " V\n";
452  ost << idt << " o " << pair.first << "\n";
453  ost << idt << " V\n";
454 
455  for ( auto algoNode : pair.second->getConsumers() ) ost << idt << " " << algoNode->getNodeName() << "\n";
456 
457  ost << idt << "====================================\n";
458  }
459 
460  return ost.str();
461  }
462 
463  //---------------------------------------------------------------------------
464 
466  boost::filesystem::ofstream myfile;
467  myfile.open( fileName, std::ios::app );
468 
469  // Declare properties to dump
470  boost::dynamic_properties dp;
471 
472  dp.property( "Entity", boost::make_transform_value_property_map(
473  []( const VariantVertexProps& v ) { return boost::lexical_cast<std::string>( v ); },
474  boost::get( boost::vertex_bundle, m_PRGraph ) ) );
475 
476  auto add_prop = [&]( auto name, auto&& vis ) {
477  dp.property( name, boost::make_transform_value_property_map(
478  [vis = std::forward<decltype( vis )>( vis )]( const VariantVertexProps& v ) {
479  return boost::apply_visitor( vis, v );
480  },
481  boost::get( boost::vertex_bundle, m_PRGraph ) ) );
482  };
483 
484  add_prop( "Name", precedence::VertexName() );
485  add_prop( "Mode", precedence::GroupMode() );
486  add_prop( "Logic", precedence::GroupLogic() );
487  add_prop( "Decision Negation", precedence::DecisionNegation() );
488  add_prop( "Negative Decision Inversion", precedence::AllPass() );
489  add_prop( "Exit Policy", precedence::GroupExit() );
490  add_prop( "Operations", precedence::Operations() );
491  add_prop( "CF Decision", precedence::CFDecision( slot ) );
492  add_prop( "State", precedence::EntityState( slot, serviceLocator(), m_conditionsRealmEnabled ) );
493  add_prop( "Start Time (Epoch ns)", precedence::StartTime( slot, serviceLocator() ) );
494  add_prop( "End Time (Epoch ns)", precedence::EndTime( slot, serviceLocator() ) );
495  add_prop( "Runtime (ns)", precedence::Duration( slot, serviceLocator() ) );
496 
497  boost::write_graphml( myfile, m_PRGraph, dp );
498 
499  myfile.close();
500  }
501 
502  //---------------------------------------------------------------------------
504  boost::filesystem::ofstream myfile;
505  myfile.open( fileName, std::ios::app );
506 
507  // Fill runtimes (as this could not be done on the fly during trace assembling)
508  SmartIF<ITimelineSvc> timelineSvc = m_svcLocator->service<ITimelineSvc>( "TimelineSvc", false );
509  if ( !timelineSvc.isValid() ) {
510  warning() << "Failed to get the TimelineSvc, timing will not be added to "
511  << "the task precedence trace dump" << endmsg;
512  } else {
513 
514  for ( auto vp = vertices( m_precTrace ); vp.first != vp.second; ++vp.first ) {
515  TimelineEvent te{};
516  te.algorithm = m_precTrace[*vp.first].m_name;
517  timelineSvc->getTimelineEvent( te );
518  int runtime = std::chrono::duration_cast<std::chrono::nanoseconds>( te.end - te.start ).count();
519  m_precTrace[*vp.first].m_runtime = runtime;
520  }
521  }
522 
523  // Declare properties to dump
524  boost::dynamic_properties dp;
525  using boost::get;
527  dp.property( "Name", get( &AlgoTraceProps::m_name, m_precTrace ) );
528  dp.property( "Rank", get( &AlgoTraceProps::m_rank, m_precTrace ) );
529  dp.property( "Runtime", get( &AlgoTraceProps::m_runtime, m_precTrace ) );
530 
531  boost::write_graphml( myfile, m_precTrace, dp );
532 
533  myfile.close();
534  }
535 
537 
538  std::string u_name = u == nullptr ? "ENTRY" : u->getNodeName();
539  std::string v_name = v->getNodeName();
540 
542 
543  if ( !u ) {
544  auto itT = m_prec_trace_map.find( "ENTRY" );
545  if ( itT != m_prec_trace_map.end() ) {
546  source = itT->second;
547  } else {
548  source = boost::add_vertex( precedence::AlgoTraceProps( "ENTRY", -1, -1, -1.0 ), m_precTrace );
549  m_prec_trace_map["ENTRY"] = source;
550  }
551  } else {
552  auto itS = m_prec_trace_map.find( u_name );
553  if ( itS != m_prec_trace_map.end() ) {
554  source = itS->second;
555  } else {
556 
557  source =
558  boost::add_vertex( precedence::AlgoTraceProps( u_name, u->getAlgoIndex(), u->getRank(), -1 ), m_precTrace );
559  m_prec_trace_map[u_name] = source;
560  }
561  }
562 
564 
565  auto itP = m_prec_trace_map.find( v_name );
566  if ( itP != m_prec_trace_map.end() ) {
567  target = itP->second;
568  } else {
569 
570  target =
571  boost::add_vertex( precedence::AlgoTraceProps( v_name, v->getAlgoIndex(), v->getRank(), -1 ), m_precTrace );
572  m_prec_trace_map[v_name] = target;
573  }
574 
575  boost::add_edge( source, target, m_precTrace );
576 
577  ON_DEBUG debug() << u_name << "-->" << v_name << " precedence trait added" << endmsg;
578  }
579 
580 } // namespace concurrency
PRVertexDesc node(const std::string &) const
const unsigned int & getAlgoIndex() const
Get algorithm index.
Class representing an event slot.
Definition: EventSlot.h:14
std::vector< DecisionNode * > m_parents
Direct parent nodes.
void accept(IGraphVisitor &visitor) const
An entry point to visit all graph nodes.
void addDaughterNode(ControlFlowNode *node)
Add a daughter node.
boost::graph_traits< PrecTrace >::vertex_descriptor AlgoTraceVertex
boost::graph_traits< PRGraph >::vertex_descriptor PRVertexDesc
const std::string & name() const override
The identifying name of the algorithm object.
Definition: Algorithm.cpp:635
StatusCode addAlgorithmNode(Gaudi::Algorithm *daughterAlgo, const std::string &parentName, bool inverted, bool allPass)
Add algorithm node.
const DataObjIDColl & outputDataObjs() const override
bool isSuccess() const
Definition: StatusCode.h:267
virtual bool visit(DecisionNode &)
Definition: IGraphVisitor.h:16
std::vector< ControlFlowNode * > m_children
All direct daughter nodes in the tree.
Gaudi::Algorithm * getAlgorithm() const
get Algorithm representatives
void dumpPrecRules(const boost::filesystem::path &, const EventSlot &slot)
dump to file the precedence rules
T endl(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
std::vector< DecisionNode * > m_parents
Control flow parents of an AlgorithmNode (DecisionNodes)
std::string algorithm
Definition: ITimelineSvc.h:21
T duration_cast(T...args)
StatusCode addDataNode(const DataObjID &dataPath)
Add DataNode that represents DataObject.
void rankAlgorithms(IGraphVisitor &ranker) const
Rank Algorithm nodes by the number of data outputs.
#define ON_DEBUG
bool m_allPass
Whether always passing regardless of daughter results.
const std::vector< DecisionNode * > & getParentDecisionHubs() const
Get all parent decision hubs.
T remove(T...args)
Gaudi::tagged_bool< class ModeOr_tag > ModeOr
virtual bool visitEnter(DecisionNode &) const
Definition: IGraphVisitor.h:15
STL class.
bool m_modeOR
Whether acting as "and" (false) or "or" node (true)
void addInputDataNode(DataNode *node)
Associate an AlgorithmNode, which is a data consumer of this one.
bool accept(IGraphVisitor &visitor) override
Visitor entry point.
StatusCode initialize()
Initialize graph.
void dumpPrecTrace(const boost::filesystem::path &)
dump to file the precedence trace
const float & getRank() const
Get Algorithm rank.
The AlgsExecutionStates encodes the state machine for the execution of algorithms within a single eve...
virtual const std::set< IAlgorithm * > & condAlgs() const =0
get list of all registered condition Algorithms
Gaudi::tagged_bool< class Inverted_tag > Inverted
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
const DataObjIDColl & inputDataObjs() const override
std::string dumpDataFlow() const
Print out all data origins and destinations, as reflected in the EF graph.
const std::vector< ControlFlowNode * > & getDaughters() const
Get children nodes.
void registerIODataObjects(const Gaudi::Algorithm *algo)
Register algorithm in the Data Dependency index.
T move(T...args)
Gaudi::tagged_bool< class Concurrent_tag > Concurrent
bool m_modePromptDecision
Whether to evaluate the hub decision ASA its child decisions allow to do that.
virtual bool getTimelineEvent(TimelineEvent &) const =0
void addEdgeToPrecTrace(const AlgorithmNode *u, const AlgorithmNode *v)
set cause-effect connection between two algorithms in the precedence trace
T get(T...args)
void addOutputDataNode(DataNode *node)
Associate an AlgorithmNode, which is a data supplier for this one.
T find(T...args)
std::vector< InputHandle_t< In > > m_inputs
StatusCode addDecisionHubNode(Gaudi::Algorithm *daughterAlgo, const std::string &parentName, concurrency::Concurrent, concurrency::PromptDecision, concurrency::ModeOr, concurrency::AllPass, concurrency::Inverted)
Add a node, which aggregates decisions of direct daughter nodes.
Gaudi::tagged_bool< class PromptDecision_tag > PromptDecision
void addParentNode(DecisionNode *node)
Add a parent node.
bool isValid() const
Allow for check if smart pointer is valid.
Definition: SmartIF.h:62
bool m_modeConcurrent
Whether all daughters will be evaluated concurrently or sequentially.
void printState(std::stringstream &output, AlgsExecutionStates &states, const std::vector< int > &node_decisions, const unsigned int &recursionLevel) const override
Print a string representing the control flow state.
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:79
Gaudi::tagged_bool< class AllPass_tag > AllPass
constexpr static const auto FAILURE
Definition: StatusCode.h:86
void addParentNode(DecisionNode *node)
Add a parent node.
bool accept(IGraphVisitor &visitor) override
Visitor entry point.
const std::string & getNodeName() const
Get node name.
#define ON_VERBOSE
void printState(std::stringstream &output, AlgsExecutionStates &states, const std::vector< int > &node_decisions, const unsigned int &recursionLevel) const override
Print a string representing the control flow state.
StatusCode buildDataDependenciesRealm()
Build data dependency realm WITH data object nodes participating.
std::string dumpControlFlow() const
Print out control flow of Algorithms and Sequences.
T forward(T...args)
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
void addHeadNode(const std::string &headName, concurrency::Concurrent, concurrency::PromptDecision, concurrency::ModeOr, concurrency::AllPass, concurrency::Inverted)
Add a node, which has no parents.
boost::variant< AlgoProps, DecisionHubProps, DataProps, CondDataProps > VariantVertexProps
void addConsumerNode(AlgorithmNode *node)
Add relationship to consumer AlgorithmNode.