7 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) ) 8 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) ) 20 if ( sc.isFailure() ) {
21 fatal() <<
"Base class failed to initialize" <<
endmsg;
26 if ( m_dumpPrecTrace || m_dumpPrecRules ) {
27 if ( !boost::filesystem::create_directory( m_dumpDirName ) ) {
28 error() <<
"Could not create directory " << m_dumpDirName <<
"required " 29 "for task precedence tracing" 35 if ( m_dumpPrecRules ) m_PRGraph.enableAnalysis();
38 m_algResourcePool = serviceLocator()->service(
"AlgResourcePool" );
39 if ( !m_algResourcePool.isValid() ) {
40 fatal() <<
"Error retrieving AlgoResourcePool" <<
endmsg;
44 info() <<
"Assembling CF and DF task precedence rules" <<
endmsg;
51 for (
const auto& ialgoPtr : m_algResourcePool->getTopAlgList() ) {
52 auto algorithm =
dynamic_cast<Algorithm*
>( ialgoPtr );
53 if ( !algorithm ) fatal() <<
"Conversion from IAlgorithm to Algorithm failed" <<
endmsg;
54 sc = assembleCFRules( algorithm,
"RootDecisionHub" );
55 if ( sc.isFailure() ) {
56 fatal() <<
"Could not assemble the CF precedence realm" <<
endmsg;
61 if ( m_ignoreDFRules ) {
62 warning() <<
"Ignoring DF precedence rules, disabling all associated features" <<
endmsg;
67 sc = m_PRGraph.initialize();
68 if ( sc.isFailure() ) {
69 fatal() <<
"Could not assemble the DF precedence realm" <<
endmsg;
74 if ( m_mode ==
"PCE" ) {
76 m_PRGraph.rankAlgorithms( ranker );
77 }
else if ( m_mode ==
"COD" ) {
79 m_PRGraph.rankAlgorithms( ranker );
80 }
else if ( m_mode ==
"E" ) {
82 m_PRGraph.rankAlgorithms( ranker );
83 }
else if ( m_mode ==
"T" ) {
85 m_PRGraph.rankAlgorithms( ranker );
86 }
else if ( m_mode ==
"DRE" ) {
88 m_PRGraph.rankAlgorithms( ranker );
89 }
else if ( !m_mode.empty() ) {
90 error() <<
"Requested prioritization rule '" << m_mode <<
"' is unknown" <<
endmsg;
96 if ( sc.isSuccess() ) info() <<
"PrecedenceSvc initialized successfully" <<
endmsg;
110 bool isGaudiSequencer(
false );
111 bool isAthSequencer(
false );
115 isGaudiSequencer =
true;
117 isAthSequencer =
true;
123 ( subAlgorithms->
empty() && !( isGaudiSequencer || isAthSequencer ) ) ) {
126 sc = m_PRGraph.addAlgorithmNode( algo, parentName,
false,
false );
134 bool allPass =
false;
135 bool promptDecision =
false;
136 bool isSequential =
false;
137 bool isInverted =
false;
139 if ( isGaudiSequencer ) {
140 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
141 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
142 promptDecision = ( algo->
getProperty(
"ShortCircuit" ).toString() ==
"True" );
143 isInverted = ( algo->
getProperty(
"Invert" ).toString() ==
"True" );
144 if ( allPass ) promptDecision =
false;
145 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
146 }
else if ( isAthSequencer ) {
147 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
148 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
149 promptDecision = ( algo->
getProperty(
"StopOverride" ).toString() ==
"False" );
150 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
155 error() <<
"Failed to add DecisionHub " << algo->
name() <<
" to graph of precedence rules" <<
endmsg;
159 for (
Algorithm* subalgo : *subAlgorithms ) {
160 sc = assembleCFRules( subalgo, algo->
name(), recursionDepth );
162 error() <<
"Algorithm " << subalgo->name() <<
" could not be flattened" <<
endmsg;
176 m_PRGraph.getAlgorithmNode( cause.
m_sourceName )->accept( visitor );
180 m_PRGraph.getHeadNode()->accept( visitor );
207 while ( !CFRulesResolved( slot ) ) {
209 int prevAlgosNum = visitor.m_nodesSucceeded;
210 ON_DEBUG debug() <<
" Proceeding with iteration #" << cntr <<
endmsg;
212 m_PRGraph.getHeadNode()->accept( visitor );
213 if ( prevNodeDecisions == nodeDecisions ) {
214 error() <<
" No progress on iteration " << cntr <<
" detected, node decisions are:" << nodeDecisions <<
endmsg;
217 info() <<
" Iteration #" << cntr <<
" finished, total algorithms executed: " << visitor.m_nodesSucceeded
221 s << cntr <<
", " << ( visitor.m_nodesSucceeded - prevAlgosNum ) <<
"\n";
224 myfile.
open(
"RunSimulation.csv", std::ios::app );
228 if ( visitor.m_nodesSucceeded != prevAlgosNum ) counters.
push_back( visitor.m_nodesSucceeded );
231 info() <<
"Asymptotical intra-event speedup: " << (float)visitor.m_nodesSucceeded / (
float)counters.
size() <<
endmsg;
235 nodeDecisions.assign( nodeDecisions.size(), -1 );
243 return ( -1 != slot.
controlFlowState[m_PRGraph.getHeadNode()->getNodeIndex()] ?
true : false );
251 info() << m_PRGraph.dumpControlFlow() <<
endmsg;
256 info() <<
std::endl <<
"===================== Data Flow Configuration ====================" <<
std::endl;
257 info() << m_PRGraph.dumpDataFlow() <<
endmsg;
273 if ( !m_dumpPrecRules ) {
274 warning() <<
"To trace temporal and topological aspects of execution flow, " 275 <<
"set DumpPrecedenceRules property to True " <<
endmsg;
279 ON_DEBUG debug() <<
"Dumping temporal precedence rules" <<
endmsg;
282 if ( m_dumpPrecRulesFile.empty() ) {
284 fileName =
"rules.evt-" +
std::to_string( eventID.event_number() ) +
"." +
"run-" +
287 fileName = m_dumpPrecRulesFile;
291 pth.append( fileName );
293 m_PRGraph.dumpPrecRules( pth, slot );
300 if ( !m_dumpPrecTrace ) {
301 warning() <<
"To trace task precedence patterns, set DumpPrecedenceTrace " 302 <<
"property to True " <<
endmsg;
306 ON_DEBUG debug() <<
"Dumping temporal precedence trace" <<
endmsg;
309 if ( m_dumpPrecTraceFile.empty() ) {
311 fileName =
"trace.evt-" +
std::to_string( eventID.event_number() ) +
"." +
"run-" +
314 fileName = m_dumpPrecTraceFile;
318 pth.append( fileName );
320 m_PRGraph.dumpPrecTrace( pth );
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
constexpr static const auto FAILURE
StatusCode initialize() override
void dumpPrecedenceRules(EventSlot &) override
Dump precedence rules (available only in DEBUG mode, and must be enabled with the corresponding servi...
const std::string & name() const override
The identifying name of the algorithm object.
void dumpDataFlow() const override
StatusCode finalize() override
AlgsExecutionStates algsStates
Vector of algorithms states.
StatusCode assembleCFRules(Algorithm *, const std::string &, unsigned int recursionDepth=0)
EventContext * eventContext
Cache for the eventContext.
A service to resolve the task execution precedence.
bool hasProperty(const std::string &name) const override
Return true if we have a property with the given name.
Gaudi::tagged_bool< class ModeOr_tag > ModeOr
StatusCode iterate(EventSlot &, const Cause &) override
Infer the precedence effect caused by an execution flow event.
#define DECLARE_COMPONENT(type)
std::vector< int > controlFlowState
State of the control flow.
Gaudi::tagged_bool< class Inverted_tag > Inverted
StatusCode finalize() override
Finalize.
This class is used for returning status codes from appropriate routines.
EventSlot * parentSlot
Pointer to parent slot (null for top level)
void dumpPrecedenceTrace(EventSlot &) override
Dump precedence trace (available only in DEBUG mode, and must be enabled with the corresponding servi...
bool CFRulesResolved(EventSlot &) const override
Check if the root CF decision is resolved.
StatusCode simulate(EventSlot &) const override
Simulate execution flow.
Gaudi::tagged_bool< class Concurrent_tag > Concurrent
constexpr static const auto SUCCESS
const std::vector< Algorithm * > * subAlgorithms() const
List of sub-algorithms. Returns a pointer to a vector of (sub) Algorithms.
Base class from which all concrete algorithm classes should be derived.
Gaudi::tagged_bool< class PromptDecision_tag > PromptDecision
bool isSequence() const override
Are we a Sequence?
Class representing the event slot.
Gaudi::tagged_bool< class AllPass_tag > AllPass
const std::string printState(EventSlot &) const override
const EventIDBase & eventID() const
void dumpControlFlow() const override
Dump precedence rules.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.