20 #define ON_DEBUG if ( msgLevel( MSG::DEBUG ) ) 21 #define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) ) 32 if ( sc.isFailure() ) {
33 fatal() <<
"Base class failed to initialize" <<
endmsg;
38 if ( m_dumpPrecTrace || m_dumpPrecRules ) {
39 if ( !boost::filesystem::create_directory( m_dumpDirName ) ) {
40 error() <<
"Could not create directory " << m_dumpDirName
42 "for task precedence tracing" 48 if ( m_dumpPrecRules ) m_PRGraph.enableAnalysis();
51 m_algResourcePool = serviceLocator()->service(
"AlgResourcePool" );
52 if ( !m_algResourcePool.isValid() ) {
53 fatal() <<
"Error retrieving AlgoResourcePool" <<
endmsg;
57 info() <<
"Assembling CF and DF task precedence rules" <<
endmsg;
64 for (
const auto& ialgoPtr : m_algResourcePool->getTopAlgList() ) {
65 auto algorithm = dynamic_cast<Gaudi::Algorithm*>( ialgoPtr );
66 if ( !algorithm ) fatal() <<
"Conversion from IAlgorithm to Gaudi::Algorithm failed" <<
endmsg;
67 sc = assembleCFRules( algorithm,
"RootDecisionHub" );
68 if ( sc.isFailure() ) {
69 fatal() <<
"Could not assemble the CF precedence realm" <<
endmsg;
74 if ( m_ignoreDFRules ) {
75 warning() <<
"Ignoring DF precedence rules, disabling all associated features" <<
endmsg;
80 sc = m_PRGraph.initialize();
81 if ( sc.isFailure() ) {
82 fatal() <<
"Could not assemble the DF precedence realm" <<
endmsg;
87 if ( m_mode ==
"PCE" ) {
89 m_PRGraph.rankAlgorithms( ranker );
90 }
else if ( m_mode ==
"COD" ) {
92 m_PRGraph.rankAlgorithms( ranker );
93 }
else if ( m_mode ==
"E" ) {
95 m_PRGraph.rankAlgorithms( ranker );
96 }
else if ( m_mode ==
"T" ) {
98 m_PRGraph.rankAlgorithms( ranker );
99 }
else if ( m_mode ==
"DRE" ) {
101 m_PRGraph.rankAlgorithms( ranker );
102 }
else if ( !m_mode.empty() ) {
103 error() <<
"Requested prioritization rule '" << m_mode <<
"' is unknown" <<
endmsg;
109 if ( m_verifyRules ) {
114 m_PRGraph.accept( propValidator );
115 if ( !propValidator.passed() )
116 warning() << propValidator.reply() <<
endmsg;
122 m_PRGraph.accept( prodValidator );
123 if ( !prodValidator.passed() ) {
124 error() << prodValidator.reply() <<
endmsg;
131 m_PRGraph.accept( sccFinder );
132 if ( !sccFinder.passed() ) {
133 error() << sccFinder.reply() <<
endmsg;
140 if ( sc.isSuccess() ) info() <<
"PrecedenceSvc initialized successfully" <<
endmsg;
147 unsigned int recursionDepth ) {
154 bool isGaudiSequencer(
false );
155 bool isAthSequencer(
false );
163 isGaudiSequencer =
true;
165 isAthSequencer =
true;
168 auto seq = dynamic_cast<Gaudi::Sequence*>( algo );
170 error() <<
"Algorithm " << algo->
name() <<
" has isSequence==true, but unable to dcast to Sequence" <<
endmsg;
174 auto subAlgorithms =
seq->subAlgorithms();
180 bool allPass =
false;
181 bool promptDecision =
false;
182 bool isSequential =
false;
183 bool isInverted =
false;
185 if ( isGaudiSequencer ) {
186 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
187 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
188 promptDecision = ( algo->
getProperty(
"ShortCircuit" ).toString() ==
"True" );
189 isInverted = ( algo->
getProperty(
"Invert" ).toString() ==
"True" );
190 if ( allPass ) promptDecision =
false;
191 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
192 }
else if ( isAthSequencer ) {
193 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
194 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
195 promptDecision = ( algo->
getProperty(
"StopOverride" ).toString() ==
"False" );
196 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
201 error() <<
"Failed to add DecisionHub " << algo->
name() <<
" to graph of precedence rules" <<
endmsg;
205 for (
auto subalgo : *subAlgorithms ) {
208 error() <<
"Algorithm " << subalgo->name() <<
" could not be flattened" <<
endmsg;
253 int prevAlgosNum = visitor.m_nodesSucceeded;
257 if ( prevNodeDecisions == nodeDecisions ) {
258 error() <<
" No progress on iteration " << cntr <<
" detected, node decisions are:" << nodeDecisions <<
endmsg;
261 info() <<
" Iteration #" << cntr <<
" finished, total algorithms executed: " << visitor.m_nodesSucceeded
265 s << cntr <<
", " << ( visitor.m_nodesSucceeded - prevAlgosNum ) <<
"\n";
268 myfile.
open(
"RunSimulation.csv", std::ios::app );
272 if ( visitor.m_nodesSucceeded != prevAlgosNum ) counters.
push_back( visitor.m_nodesSucceeded );
275 info() <<
"Asymptotical intra-event speedup: " << (float)visitor.m_nodesSucceeded / (
float)counters.
size() <<
endmsg;
279 nodeDecisions.assign( nodeDecisions.size(), -1 );
313 warning() <<
"To trace temporal and topological aspects of execution flow, " 314 <<
"set DumpPrecedenceRules property to True " <<
endmsg;
323 fileName =
"rules.evt-" +
std::to_string( eventID.event_number() ) +
"." +
"run-" +
330 pth.append( fileName );
339 warning() <<
"To trace task precedence patterns, set DumpPrecedenceTrace " 340 <<
"property to True " <<
endmsg;
349 fileName =
"trace.evt-" +
std::to_string( eventID.event_number() ) +
"." +
"run-" +
356 pth.append( fileName );
Gaudi::Property< bool > m_dumpPrecTrace
concurrency::PrecedenceRulesGraph m_PRGraph
Graph of precedence rules.
StatusCode initialize() override
Class representing an event slot.
void dumpPrecedenceRules(EventSlot &) override
Dump precedence rules (available only in DEBUG mode, and must be enabled with the corresponding servi...
AlgorithmNode * getAlgorithmNode(const std::string &algoName) const
Get the AlgorithmNode from by algorithm name using graph index.
const std::string printState(EventSlot &) const override
StatusCode assembleCFRules(Gaudi::Algorithm *, const std::string &, unsigned int recursionDepth=0)
StatusCode finalize() override
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
StatusCode addAlgorithmNode(Gaudi::Algorithm *daughterAlgo, const std::string &parentName, bool inverted, bool allPass)
Add algorithm node.
void dumpDataFlow() const override
A service to resolve the task execution precedence.
void dumpPrecRules(const boost::filesystem::path &, const EventSlot &slot)
dump to file the precedence rules
constexpr static const auto SUCCESS
boost::filesystem::path m_dumpDirName
Precedence analysis facilities.
std::vector< int > controlFlowState
State of the control flow.
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
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)
Gaudi::Property< std::string > m_dumpPrecRulesFile
bool accept(IGraphVisitor &visitor) override
Visitor entry point.
void dumpPrecTrace(const boost::filesystem::path &)
dump to file the precedence trace
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
void printState(std::stringstream &output, EventSlot &slot, const unsigned int &recursionLevel) const
Print a string representing the control flow state.
Gaudi::tagged_bool< class Inverted_tag > Inverted
StatusCode finalize() override
Finalize.
This class is used for returning status codes from appropriate routines.
std::string dumpControlFlow() const
Print out control flow of Algorithms and Sequences.
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
The visitor implements the Tarjan algorithm for searching strongly connected components in the data f...
bool CFRulesResolved(EventSlot &) const override
Check if the root CF decision is resolved.
void dumpPrecedenceTrace(EventSlot &) override
Dump precedence trace (available only in DEBUG mode, and must be enabled with the corresponding servi...
Gaudi::tagged_bool< class Concurrent_tag > Concurrent
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
Gaudi::Property< bool > m_dumpPrecRules
DecisionNode * getHeadNode() const
Get head node.
Base class from which all concrete algorithm classes should be derived.
StatusCode simulate(EventSlot &) const override
Simulate execution flow.
Gaudi::tagged_bool< class AllPass_tag > AllPass
constexpr static const auto FAILURE
bool isSequence() const override
Are we a Sequence?
EventSlot * parentSlot
Pointer to parent slot (null for top level)
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
bool accept(IGraphVisitor &visitor) override
Visitor entry point.
Gaudi::Property< std::string > m_dumpPrecTraceFile
std::string dumpDataFlow() const
Print out all data origins and destinations, as reflected in the EF graph.
const unsigned int & getNodeIndex() const
Get node index.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
std::unique_ptr< EventContext > eventContext
Cache for the eventContext.
const std::string & name() const override
The identifying name of the algorithm object.
AlgsExecutionStates algsStates
Vector of algorithms states.
const EventIDBase & eventID() const
void dumpControlFlow() const override
Dump precedence rules.