29#define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
30#define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
41 if ( sc.isFailure() ) {
42 fatal() <<
"Base class failed to initialize" <<
endmsg;
48 std::string pattern =
"precedence.analysis.XXXXXX";
49 if ( !mkdtemp( pattern.data() ) ) {
50 error() <<
"Could not create directory \"precedence.analysis.XXXXXX\" required for task precedence tracing"
62 fatal() <<
"Error retrieving AlgoResourcePool" <<
endmsg;
66 info() <<
"Assembling CF and DF task precedence rules" <<
endmsg;
75 if ( !algorithm )
fatal() <<
"Conversion from IAlgorithm to Gaudi::Algorithm failed" <<
endmsg;
77 if ( sc.isFailure() ) {
78 fatal() <<
"Could not assemble the CF precedence realm" <<
endmsg;
84 warning() <<
"Ignoring DF precedence rules, disabling all associated features" <<
endmsg;
90 if ( sc.isFailure() ) {
91 fatal() <<
"Could not assemble the DF precedence realm" <<
endmsg;
99 }
else if (
m_mode ==
"COD" ) {
102 }
else if (
m_mode ==
"E" ) {
105 }
else if (
m_mode ==
"T" ) {
108 }
else if (
m_mode ==
"DRE" ) {
111 }
else if ( !
m_mode.empty() ) {
112 error() <<
"Requested prioritization rule '" <<
m_mode <<
"' is unknown" <<
endmsg;
124 if ( !propValidator.passed() )
132 if ( !prodValidator.passed() ) {
141 if ( !sccFinder.passed() ) {
149 if ( sc.isSuccess() )
info() <<
"PrecedenceSvc initialized successfully" <<
endmsg;
156 unsigned int recursionDepth ) {
163 bool isGaudiSequencer(
false );
164 bool isAthSequencer(
false );
167 ON_DEBUG debug() << std::string( recursionDepth,
' ' ) <<
"Algorithm '" << algo->
name() <<
"' discovered" <<
endmsg;
168 sc =
m_PRGraph.addAlgorithmNode( algo, parentName );
172 isGaudiSequencer =
true;
174 isAthSequencer =
true;
179 error() <<
"Algorithm " << algo->
name() <<
" has isSequence==true, but unable to dcast to Sequence" <<
endmsg;
183 auto subAlgorithms = seq->subAlgorithms();
186 ON_DEBUG debug() << std::string( recursionDepth,
' ' ) <<
"Decision hub '" << algo->
name() <<
"' discovered"
189 bool allPass =
false;
190 bool promptDecision =
false;
191 bool isSequential =
false;
192 bool isInverted =
false;
194 if ( isGaudiSequencer ) {
195 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
196 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
197 promptDecision = ( algo->
getProperty(
"ShortCircuit" ).toString() ==
"True" );
198 isInverted = ( algo->
getProperty(
"Invert" ).toString() ==
"True" );
199 if ( allPass ) promptDecision =
false;
200 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
201 }
else if ( isAthSequencer ) {
202 modeOr = ( algo->
getProperty(
"ModeOR" ).toString() ==
"True" );
203 allPass = ( algo->
getProperty(
"IgnoreFilterPassed" ).toString() ==
"True" );
204 promptDecision = ( algo->
getProperty(
"StopOverride" ).toString() ==
"False" );
205 isSequential = ( algo->
hasProperty(
"Sequential" ) && ( algo->
getProperty(
"Sequential" ).toString() ==
"True" ) );
210 error() <<
"Failed to add DecisionHub " << algo->
name() <<
" to graph of precedence rules" <<
endmsg;
214 for (
auto subalgo : *subAlgorithms ) {
217 error() <<
"Algorithm " << subalgo->name() <<
" could not be flattened" <<
endmsg;
234 m_PRGraph.getHeadNode()->accept( visitor );
256 std::vector<int> prevNodeDecisions;
258 std::vector<int> counters;
262 int prevAlgosNum = visitor.m_nodesSucceeded;
265 m_PRGraph.getHeadNode()->accept( visitor );
266 if ( prevNodeDecisions == nodeDecisions ) {
267 error() <<
" No progress on iteration " << cntr <<
" detected, node decisions are:" << nodeDecisions <<
endmsg;
270 info() <<
" Iteration #" << cntr <<
" finished, total algorithms executed: " << visitor.m_nodesSucceeded
274 s << cntr <<
", " << ( visitor.m_nodesSucceeded - prevAlgosNum ) <<
"\n";
276 std::ofstream myfile;
277 myfile.open(
"RunSimulation.csv", std::ios::app );
281 if ( visitor.m_nodesSucceeded != prevAlgosNum ) counters.push_back( visitor.m_nodesSucceeded );
284 info() <<
"Asymptotical intra-event speedup: " << (float)visitor.m_nodesSucceeded / (
float)counters.size() <<
endmsg;
288 nodeDecisions.assign( nodeDecisions.size(), -1 );
301 info() << std::endl <<
"==================== Control Flow Configuration ==================" << std::endl << std::endl;
306 info() << std::endl <<
"===================== Data Flow Configuration ====================" << std::endl;
313 std::stringstream ss;
322 warning() <<
"To trace temporal and topological aspects of execution flow, "
323 <<
"set DumpPrecedenceRules property to True " <<
endmsg;
329 std::string fileName;
332 fileName =
"rules_evt-" + std::to_string( eventID.event_number() ) +
"_slot-" +
333 std::to_string( slot.
eventContext->
slot() ) +
"_run-" + std::to_string( eventID.run_number() ) +
349 warning() <<
"To trace task precedence patterns, set DumpPrecedenceTrace "
350 <<
"property to True " <<
endmsg;
356 std::string fileName;
359 fileName =
"trace_evt-" + std::to_string( eventID.event_number() ) +
"_slot-" +
360 std::to_string( slot.
eventContext->
slot() ) +
"_run-" + std::to_string( eventID.run_number() ) +
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
const EventIDBase & eventID() const
Base class from which all concrete algorithm classes should be derived.
const std::string & name() const override
The identifying name of the algorithm object.
bool isSequence() const override
Are we a Sequence?
A service to resolve the task execution precedence.
PrecedenceSvc(const std::string &name, ISvcLocator *svcLoc)
Constructor.
void dumpControlFlow() const override
Dump precedence rules.
Gaudi::Property< bool > m_showDataFlow
concurrency::PrecedenceRulesGraph m_PRGraph
Graph of precedence rules.
Gaudi::Property< bool > m_dumpPrecTrace
Gaudi::Property< std::string > m_dumpPrecTraceFile
Gaudi::Property< bool > m_ignoreDFRules
Scheduling strategy.
Gaudi::Property< bool > m_dumpPrecRules
StatusCode iterate(EventSlot &, const Cause &) override
Infer the precedence effect caused by an execution flow event.
Gaudi::Property< std::string > m_dumpPrecRulesFile
const std::string printState(EventSlot &) const override
StatusCode finalize() override
Finalize.
Gaudi::Property< bool > m_verifyRules
StatusCode simulate(EventSlot &) const override
Simulate execution flow.
SmartIF< IAlgResourcePool > m_algResourcePool
A shortcut to the algorithm resource pool.
void dumpPrecedenceRules(const EventSlot &) override
Dump precedence rules (available only in DEBUG mode, and must be enabled with the corresponding servi...
Gaudi::Property< std::string > m_mode
Scheduling strategy.
bool CFRulesResolved(EventSlot &) const override
Check if the root CF decision is resolved.
StatusCode initialize() override
Initialize.
void dumpPrecedenceTrace(const EventSlot &) override
Dump precedence trace (available only in DEBUG mode, and must be enabled with the corresponding servi...
std::filesystem::path m_dumpDirName
Precedence analysis facilities.
StatusCode assembleCFRules(Gaudi::Algorithm *, const std::string &, unsigned int recursionDepth=0)
void dumpDataFlow() const override
StatusCode getProperty(Gaudi::Details::PropertyBase *p) const override
get the property
bool hasProperty(std::string_view name) const override
Return true if we have a property with the given name.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
StatusCode finalize() override
StatusCode initialize() override
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
The visitor implements the Tarjan algorithm for searching strongly connected components in the data f...
Gaudi::tagged_bool< class AllPass_tag > AllPass
Gaudi::tagged_bool< class Concurrent_tag > Concurrent
Gaudi::tagged_bool< class ModeOr_tag > ModeOr
Gaudi::tagged_bool< class PromptDecision_tag > PromptDecision
Gaudi::tagged_bool< class Inverted_tag > Inverted
Class representing an event slot.
std::unique_ptr< EventContext > eventContext
Cache for the eventContext.
EventSlot * parentSlot
Pointer to parent slot (null for top level).
AlgsExecutionStates algsStates
Vector of algorithms states.
std::vector< int > controlFlowState
State of the control flow.