The Gaudi Framework  v30r4 (9b837755)
HLTEventLoopMgr.cpp
Go to the documentation of this file.
1 // FW includes
5 #include "GaudiKernel/DataSvc.h"
10 #include "GaudiKernel/IAlgorithm.h"
15 #include "GaudiKernel/IScheduler.h"
16 #include "GaudiKernel/Memory.h"
18 
19 #include "EventSlot.h"
21 #include "HistogramAgent.h"
22 #include "RetCodeGuard.h"
23 
24 #include <algorithm>
25 #include <chrono>
26 #include <condition_variable>
27 #include <fstream>
28 #include <map>
29 #include <sstream>
30 
31 #include "boost/algorithm/string.hpp"
32 #include "boost/optional.hpp"
33 #include "boost/thread.hpp"
34 #include "boost/tokenizer.hpp"
35 #include "tbb/task_scheduler_init.h"
36 
37 #include "HLTEventLoopMgr.h"
38 
39 // Instantiation of a static factory class used by clients to create instances of this service
41 
42 namespace
43 {
44  struct DataObjIDDotRepr {
45  const DataObjID& parent;
46  friend std::ostream& operator<<( std::ostream& os, const DataObjIDDotRepr& repr )
47  {
48  return os << '\"' << repr.parent.fullKey() << '\"';
49  }
50  };
51 
52  struct DataObjIDSorter {
53  bool operator()( const DataObjID* a, const DataObjID* b ) { return a->fullKey() < b->fullKey(); }
54  };
55 
56  // Sort a DataObjIDColl in a well-defined, reproducible manner.
57  // Used for making debugging dumps.
58  std::vector<const DataObjID*> sortedDataObjIDColl( const DataObjIDColl& coll )
59  {
61  v.reserve( coll.size() );
62  for ( const DataObjID& id : coll ) v.push_back( &id );
63  std::sort( v.begin(), v.end(), DataObjIDSorter() );
64  return v;
65  }
66 }
67 
68 struct HLTEventLoopMgr::HLTExecutionTask final : tbb::task {
69 
75 
77  IAlgExecStateSvc* aem, const HLTEventLoopMgr* parent )
78  : m_algorithms( algorithms )
79  , m_evtCtx( std::move( ctx ) )
80  , m_aess( aem )
81  , m_serviceLocator( svcLocator )
82  , m_parent( parent )
83  {
84  }
85 
87  {
88  SmartIF<IMessageSvc> messageSvc( m_serviceLocator );
89  return MsgStream( messageSvc, "HLTExecutionTask" );
90  }
91 
92  tbb::task* execute() override
93  {
94  bool eventfailed = false;
95  Gaudi::Hive::setCurrentContext( m_evtCtx.get() );
96 
97  const SmartIF<IProperty> appmgr( m_serviceLocator );
98 
99  for ( Algorithm* ialg : m_algorithms ) {
100 
101  // select the appropriate store
102  ialg->whiteboard()->selectStore( m_evtCtx->valid() ? m_evtCtx->slot() : 0 ).ignore();
103 
105  try {
107  m_aess->algExecState( ialg, *m_evtCtx ).setState( AlgExecState::State::Executing );
108  sc = ialg->sysExecute( *m_evtCtx );
109  if ( UNLIKELY( !sc.isSuccess() ) ) {
110  log() << MSG::WARNING << "Execution of algorithm " << ialg->name() << " failed" << endmsg;
111  eventfailed = true;
112  }
113  rcg.ignore(); // disarm the guard
114  } catch ( const GaudiException& Exception ) {
115  log() << MSG::FATAL << ".executeEvent(): Exception with tag=" << Exception.tag() << " thrown by "
116  << ialg->name() << endmsg << MSG::ERROR << Exception << endmsg;
117  eventfailed = true;
118  } catch ( const std::exception& Exception ) {
119  log() << MSG::FATAL << ".executeEvent(): Standard std::exception thrown by " << ialg->name() << endmsg
120  << MSG::ERROR << Exception.what() << endmsg;
121  eventfailed = true;
122  } catch ( ... ) {
123  log() << MSG::FATAL << ".executeEvent(): UNKNOWN Exception thrown by " << ialg->name() << endmsg;
124  eventfailed = true;
125  }
126 
127  // DP it is important to propagate the failure of an event.
128  // We need to stop execution when this happens so that execute run can
129  // then receive the FAILURE
130  m_aess->algExecState( ialg, *m_evtCtx ).setState( AlgExecState::State::Done, sc );
131  m_aess->updateEventStatus( eventfailed, *m_evtCtx );
132 
133  // in case the algorithm was a filter and the filter did not pass, stop here
134  if ( !ialg->filterPassed() ) break;
135  }
136  // update scheduler state
137  m_parent->promoteToExecuted( std::move( m_evtCtx ) );
139 
140  return nullptr;
141  }
142 };
143 
145 {
147  if ( !sc.isSuccess() ) {
148  error() << "Failed to initialize Service Base class." << endmsg;
149  return StatusCode::FAILURE;
150  }
151  // Setup access to event data services
152  m_evtDataMgrSvc = serviceLocator()->service<IDataManagerSvc>( "EventDataSvc" );
153  if ( !m_evtDataMgrSvc ) {
154  fatal() << "Error retrieving EventDataSvc interface IDataManagerSvc." << endmsg;
155  return StatusCode::FAILURE;
156  }
157  m_whiteboard = serviceLocator()->service<IHiveWhiteBoard>( "EventDataSvc" );
158  if ( !m_whiteboard ) {
159  fatal() << "Error retrieving EventDataSvc interface IHiveWhiteBoard." << endmsg;
160  return StatusCode::FAILURE;
161  }
162  // Obtain the IProperty of the ApplicationMgr
163  IProperty* appMgrProperty = serviceLocator()->service<IProperty>( "ApplicationMgr" );
164  if ( !appMgrProperty ) {
165  fatal() << "IProperty interface not found in ApplicationMgr." << endmsg;
166  return StatusCode::FAILURE;
167  }
168  // We do not expect a Event Selector necessarily being declared
169  setProperty( appMgrProperty->getProperty( "EvtSel" ) ).ignore();
170 
171  if ( m_evtsel != "NONE" || m_evtsel.length() == 0 ) {
172  m_evtSelector = serviceLocator()->service<IEvtSelector>( "EventSelector" );
173  } else {
174  m_evtSelector = nullptr;
175  warning() << "Unable to locate service \"EventSelector\" " << endmsg;
176  warning() << "No events will be processed from external input." << endmsg;
177  }
178 
179  // Setup access to histogramming services
180  m_histoDataMgrSvc = serviceLocator()->service<IDataManagerSvc>( "HistogramDataSvc" );
181  if ( !m_histoDataMgrSvc ) {
182  fatal() << "Error retrieving HistogramDataSvc." << endmsg;
183  return sc;
184  }
185  // Setup histogram persistency
186  m_histoPersSvc = serviceLocator()->service<IConversionSvc>( "HistogramPersistencySvc" );
187  if ( !m_histoPersSvc ) {
188  warning() << "Histograms cannot not be saved - though required." << endmsg;
189  return sc;
190  }
191 
192  m_algExecStateSvc = serviceLocator()->service<IAlgExecStateSvc>( "AlgExecStateSvc" );
193  if ( !m_algExecStateSvc ) {
194  fatal() << "Error retrieving AlgExecStateSvc" << endmsg;
195  return StatusCode::FAILURE;
196  }
197 
198  if ( !m_topAlgs.empty() ) {
199  auto databroker = serviceLocator()->service<IDataBroker>( "HiveDataBrokerSvc" );
200  // the only control flow supported here is to run the 'topAlgs' (and their depedencies) in a 'lazy_and' fashion
201  // as a result, we can just 'flatten' the list, and make sure algorithms appear only once (the latter is not
202  // strictly neccessary, but an optimization)
203  for ( const auto& alg : m_topAlgs.value() ) {
204  auto algs = databroker->algorithmsRequiredFor( alg );
205  std::copy_if( begin( algs ), end( algs ), std::back_inserter( m_algos ), [this]( const Algorithm* a ) {
206  return std::find( begin( this->m_algos ), end( this->m_algos ), a ) == end( this->m_algos );
207  } );
208  }
209  } else {
210  // Get the list of algorithms
211  IAlgResourcePool* algResourcePool = serviceLocator()->service<IAlgResourcePool>( "AlgResourcePool" );
212  if ( !algResourcePool ) {
213  fatal() << "Error retrieving AlgoResourcePool" << endmsg;
214  return StatusCode::FAILURE;
215  }
216  for ( auto alg : algResourcePool->getFlatAlgList() ) {
217  Algorithm* algoPtr = dynamic_cast<Algorithm*>( alg );
218  if ( !algoPtr ) {
219  fatal() << "Could not convert IAlgorithm into Algorithm: this will result in a crash." << endmsg;
220  }
221  m_algos.push_back( algoPtr );
222  }
223  /* Dependencies
224  1) Look for handles in algo, if none
225  2) Assume none are required
226  */
227  DataObjIDColl globalInp, globalOutp;
228 
229  using AccessMode = Gaudi::v2::DataHandle::AccessMode;
230 
231  boost::optional<std::ofstream> dot{boost::in_place_init_if, !m_dotfile.empty(), m_dotfile.value()};
232 
233  if ( dot ) {
234  *dot << "digraph G {\n";
235  for ( auto* a : m_algos ) {
236  bool is_consumer = a->dataDependencies( AccessMode::Write ).empty();
237  *dot << '\"' << a->name() << "\" [shape=box" << ( is_consumer ? ",style=filled" : "" ) << "];\n";
238  }
239  }
240 
241  // figure out all outputs
243  for ( Algorithm* algoPtr : m_algos ) {
244  for ( auto id : algoPtr->dataDependencies( AccessMode::Write ) ) {
245  auto r = globalOutp.insert( id );
246  producers[id] = algoPtr;
247  if ( !r.second ) {
248  warning() << "multiple algorithms declare " << id
249  << " as output! could be a single instance in multiple paths "
250  "though, or control flow may guarantee only one runs...!"
251  << endmsg;
252  }
253  }
254  }
255 
256  // Building and printing Data Dependencies
257  std::vector<DataObjIDColl> algosDependencies;
258  algosDependencies.reserve( m_algos.size() ); // reserve so that pointers into the vector do not get invalidated...
260  info() << "Data Dependencies for Algorithms:";
261 
262  for ( Algorithm* algoPtr : m_algos ) {
263  info() << "\n " << algoPtr->name();
264 
265  DataObjIDColl algoDependencies;
266  if ( !algoPtr->dataDependencies( AccessMode::Read ).empty() ||
267  !algoPtr->dataDependencies( AccessMode::Write ).empty() ) {
268  for ( const DataObjID* idp : sortedDataObjIDColl( algoPtr->dataDependencies( AccessMode::Read ) ) ) {
269  DataObjID id = *idp;
270  info() << "\n o INPUT " << id;
271  if ( id.key().find( ":" ) != std::string::npos ) {
272  info() << " contains alternatives which require resolution...\n";
273  auto tokens = boost::tokenizer<boost::char_separator<char>>{id.key(), boost::char_separator<char>{":"}};
274  auto itok = std::find_if( tokens.begin(), tokens.end(), [&]( const std::string& t ) {
275  return globalOutp.find( DataObjID{t} ) != globalOutp.end();
276  } );
277  if ( itok != tokens.end() ) {
278  info() << "found matching output for " << *itok << " -- updating scheduler info\n";
279  id.updateKey( *itok );
280  } else {
281  error() << "failed to find alternate in global output list"
282  << " for id: " << id << " in Alg " << algoPtr->name() << endmsg;
283  }
284  }
285  algoDependencies.insert( id );
286  if ( dot ) *dot << DataObjIDDotRepr{id} << " -> \"" << algoPtr->name() << "\";\n";
287  globalInp.insert( id );
288  }
289  for ( const DataObjID* id : sortedDataObjIDColl( algoPtr->dataDependencies( AccessMode::Write ) ) ) {
290  info() << "\n o OUTPUT " << *id;
291  if ( id->key().find( ":" ) != std::string::npos ) {
292  error() << " in Alg " << algoPtr->name() << " alternatives are NOT allowed for outputs! id: " << *id
293  << endmsg;
294  }
295  if ( dot ) *dot << '\"' << algoPtr->name() << "\" -> " << DataObjIDDotRepr{*id} << ";\n";
296  }
297  } else {
298  info() << "\n none";
299  }
300  algosDependencies.emplace_back( algoDependencies );
301  algo2Deps[algoPtr] = &algosDependencies.back();
302  }
303  if ( dot ) {
304  for ( const auto& t : globalOutp ) {
305  if ( globalInp.find( t ) == globalInp.end() ) *dot << DataObjIDDotRepr{t} << " [style=filled];\n";
306  }
307  *dot << "}\n";
308  }
309  info() << endmsg;
310 
311  // Check if we have unmet global input dependencies
312  DataObjIDColl unmetDep;
313  for ( auto o : globalInp ) {
314  if ( globalOutp.find( o ) == globalOutp.end() ) unmetDep.insert( o );
315  }
316  if ( unmetDep.size() > 0 ) {
317  std::ostringstream ost;
318  for ( const DataObjID* o : sortedDataObjIDColl( unmetDep ) ) {
319  ost << "\n o " << *o << " required by Algorithm: ";
320  for ( const auto& i : algo2Deps ) {
321  if ( i.second->find( *o ) != i.second->end() ) {
322  ost << "\n * " << i.first->name();
323  }
324  }
325  }
326  fatal() << "The following unmet INPUT dependencies were found:" << ost.str() << endmsg;
327  return StatusCode::FAILURE;
328  } else {
329  info() << "No unmet INPUT data dependencies were found" << endmsg;
330  }
331 
332  // rework the flat algo list to respect data dependencies
333  auto start = m_algos.begin();
334  auto end = m_algos.end();
335  auto current =
336  std::partition( start, end, [&algo2Deps]( const Algorithm* algo ) { return algo2Deps[algo]->empty(); } );
337 
338  // Repeatedly put in front algos for which input are already fullfilled
339  while ( current != end ) {
340  current = std::partition( current, end, [start, current, &producers, &algo2Deps]( const Algorithm* algo ) {
341  return std::none_of( algo2Deps[algo]->begin(), algo2Deps[algo]->end(),
342  [start, current, &producers]( const DataObjID& id ) {
343  return std::find( start, current, producers[id] ) == current;
344  } );
345  } );
346  }
347  }
348 
349  // Clearly inform about the level of concurrency
350  info() << "Concurrency level information:" << endmsg;
351  info() << " o Number of events slots: " << m_whiteboard->getNumberOfStores() << endmsg;
352  info() << " o TBB thread pool size: " << m_threadPoolSize << endmsg;
353 
354  // Fill the containers to convert algo names to index
355  debug() << "Order of algo execution :" << endmsg;
356  for ( const Algorithm* algo : m_algos ) debug() << " . " << algo->name() << endmsg;
357 
358  return sc;
359 }
360 
362 {
363  StatusCode sc;
364  // Save Histograms Now
365  if ( m_histoPersSvc ) {
366  HistogramAgent agent;
367  sc = m_histoDataMgrSvc->traverseTree( &agent );
368  if ( sc.isSuccess() ) {
369  const IDataSelector& objects = agent.selectedObjects();
370  // skip /stat entry!
371  sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode s, const auto& i ) {
372  IOpaqueAddress* pAddr = nullptr;
373  StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
374  if ( iret.isSuccess() ) i->registry()->setAddress( pAddr );
375  return s.isFailure() ? s : iret;
376  } );
377  sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode s, const auto& i ) {
378  IRegistry* reg = i->registry();
379  StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
380  return s.isFailure() ? s : iret;
381  } );
382  if ( sc.isSuccess() ) {
383  info() << "Histograms converted successfully according to request." << endmsg;
384  } else {
385  error() << "Error while saving Histograms." << endmsg;
386  }
387  } else {
388  error() << "Error while traversing Histogram data store" << endmsg;
389  }
390  }
391 
393  return sc.isFailure() ? sc2.ignore(), sc : sc2;
394 }
395 
396 StatusCode HLTEventLoopMgr::executeEvent( void* createdEvts_IntPtr )
397 {
398  // Leave the interface intact and swallow this C trick.
399  int& createdEvts = *reinterpret_cast<int*>( createdEvts_IntPtr );
400 
401  auto evtContext = std::make_unique<EventContext>();
402  evtContext->set( createdEvts, m_whiteboard->allocateStore( createdEvts ) );
403  m_algExecStateSvc->reset( *evtContext );
404 
405  StatusCode sc = m_whiteboard->selectStore( evtContext->slot() );
406  if ( sc.isFailure() ) {
407  fatal() << "Slot " << evtContext->slot() << " could not be selected for the WhiteBoard\n"
408  << "Impossible to create event context" << endmsg;
409  return StatusCode::FAILURE;
410  }
411 
412  StatusCode declEvtRootSc = declareEventRootAddress();
413  if ( declEvtRootSc.isFailure() ) { // We ran out of events!
414  createdEvts = -1; // Set created event to a negative value: we finished!
415  return StatusCode::SUCCESS;
416  }
417 
418  // Now add event to the scheduler
419  if ( msgLevel( MSG::DEBUG ) )
420  debug() << "Event " << evtContext->evt() << " submitting in slot " << evtContext->slot() << endmsg;
421 
422  // Event processing slot forced to be the same as the wb slot
423  tbb::task* task = new ( tbb::task::allocate_root() )
424  HLTExecutionTask( m_algos, std::move( evtContext ), serviceLocator(), m_algExecStateSvc, this );
425  tbb::task::enqueue( *task );
426 
427  if ( msgLevel( MSG::DEBUG ) )
428  debug() << "All algorithms were submitted on event " << evtContext->evt() << " in slot " << evtContext->slot()
429  << endmsg; // FIXME: use after std::move..
430 
431  createdEvts++;
432  return StatusCode::SUCCESS;
433 }
434 
436 {
437  // Set the application return code
438  auto appmgr = serviceLocator()->as<IProperty>();
440  error() << "Could not set return code of the application (" << Gaudi::ReturnCode::ScheduledStop << ")" << endmsg;
441  }
442  return StatusCode::SUCCESS;
443 }
444 
446 {
447  // Calculate runtime
449 
450  // Reset the application return code.
451  auto appmgr = serviceLocator()->as<IProperty>();
453 
454  // create m_evtSelContext used internally in executeEvent and more
455  // precisely in declareEventRootAddress. Cannot be passed through the interface
456  // without breaking other schedulers
457  StatusCode sc = m_evtSelector->createContext( m_evtSelContext );
458  if ( !sc.isSuccess() ) {
459  fatal() << "Can not create the event selector Context." << endmsg;
460  return sc;
461  }
462 
463  // create th tbb thread pool
464  tbb::task_scheduler_init tbbSchedInit( m_threadPoolSize.value() + 1 );
465 
466  int createdEvts = 0;
467  // Run the first event before spilling more than one
468  bool newEvtAllowed = false;
469 
470  info() << "Starting loop on events" << endmsg;
471  auto start_time = Clock::now();
472  while ( maxevt < 0 || m_finishedEvt < (unsigned int)maxevt ) {
473  // if the created events did not reach maxevt, create an event
474  if ( !( ( newEvtAllowed || createdEvts == 0 ) && // Launch the first event alone
475  // The events are not finished with an unlimited number of events
476  createdEvts >= 0 &&
477  // The events are not finished with a limited number of events
478  ( createdEvts < maxevt || maxevt < 0 ) &&
479  // There are still free slots in the whiteboard
480  m_whiteboard->freeSlots() > 0 ) ) {
481 
482  std::unique_lock<std::mutex> lock{m_createEventMutex};
483  using namespace std::chrono_literals;
484  m_createEventCond.wait_for( lock, 1ms, [this, newEvtAllowed, createdEvts, maxevt] {
485  return ( newEvtAllowed || createdEvts == 0 ) && // Launch the first event alone
486  // The events are not finished with an unlimited number of events
487  createdEvts >= 0 &&
488  // The events are not finished with a limited number of events
489  ( createdEvts < maxevt || maxevt < 0 ) &&
490  // There are still free slots in the whiteboard
491  this->m_whiteboard->freeSlots() > 0;
492  } );
493  continue;
494  }
495  if ( 1 == createdEvts ) // reset counter to count from event 1
496  start_time = Clock::now();
497 
498  // TODO can we adapt the interface of executeEvent for a nicer solution?
500  sc = executeEvent( &createdEvts );
501  if ( !sc.isSuccess() ) return StatusCode::FAILURE; // else we have an success --> exit loop
502  newEvtAllowed = true;
503  } // end main loop on finished events
504  auto end_time = Clock::now();
505 
506  delete m_evtSelContext;
507  m_evtSelContext = nullptr;
508 
509  constexpr double oneOver1024 = 1. / 1024.;
510  info() << "---> Loop Finished (skipping 1st evt) - "
511  << " WSS " << System::mappedMemory( System::MemoryUnit::kByte ) * oneOver1024 << " total time "
512  << std::chrono::duration_cast<std::chrono::milliseconds>( end_time - start_time ).count() << " ms" << endmsg;
513  return StatusCode::SUCCESS;
514 }
515 
517 {
518  IOpaqueAddress* pAddr = nullptr;
519  StatusCode sc = m_evtSelector->next( *m_evtSelContext );
520  if ( sc.isSuccess() ) {
521  // Create root address and assign address to data service
522  sc = m_evtSelector->createAddress( *m_evtSelContext, pAddr );
523  if ( !sc.isSuccess() ) {
524  sc = m_evtSelector->next( *m_evtSelContext );
525  if ( sc.isSuccess() ) {
526  sc = m_evtSelector->createAddress( *m_evtSelContext, pAddr );
527  if ( !sc.isSuccess() ) warning() << "Error creating IOpaqueAddress." << endmsg;
528  }
529  }
530  }
531  if ( !sc.isSuccess() ) {
532  info() << "No more events in event selection " << endmsg;
533  return StatusCode::FAILURE;
534  }
535  sc = m_evtDataMgrSvc->setRoot( "/Event", pAddr );
536  if ( !sc.isSuccess() ) {
537  warning() << "Error declaring event root address." << endmsg;
538  }
539  return StatusCode::SUCCESS;
540 }
541 
548 {
549  fatal() << "*** Event " << eventContext->evt() << " on slot " << eventContext->slot() << " failed! ***" << endmsg;
550  std::ostringstream ost;
551  m_algExecStateSvc->dump( ost, *eventContext );
552  info() << "Dumping Alg Exec State for slot " << eventContext->slot() << ":\n" << ost.str() << endmsg;
553  return StatusCode::FAILURE;
554 }
555 
557 {
558  // Check if the execution failed
559  if ( m_algExecStateSvc->eventStatus( *eventContext ) != EventStatus::Success )
560  eventFailed( eventContext.get() ).ignore();
561  int si = eventContext->slot();
562 
563  // if ( msgLevel( MSG::DEBUG ) )
564  // debug() << "Event " << eventContext->evt() << " executed in slot " << si << "." << endmsg;
565 
566  // Schedule the cleanup of the event
567  if ( m_algExecStateSvc->eventStatus( *eventContext ) == EventStatus::Success ) {
568  if ( msgLevel( MSG::DEBUG ) )
569  debug() << "Event " << eventContext->evt() << " finished (slot " << si << ")." << endmsg;
570  } else {
571  fatal() << "Failed event detected on " << *eventContext << endmsg;
572  }
573 
574  debug() << "Clearing slot " << si << " (event " << eventContext->evt() << ") of the whiteboard" << endmsg;
575 
576  StatusCode sc = m_whiteboard->clearStore( si );
577  if ( !sc.isSuccess() ) warning() << "Clear of Event data store failed" << endmsg;
578  sc = m_whiteboard->freeStore( si );
579  if ( !sc.isSuccess() ) error() << "Whiteboard slot " << eventContext->slot() << " could not be properly cleared";
580  ++m_finishedEvt;
581  m_createEventCond.notify_all();
582 }
StatusCode setProperty(IProperty *component, const std::string &name, const TYPE &value, const std::string &doc)
simple function to set the property of the given object from the value
Definition: Property.h:1305
#define UNLIKELY(x)
Definition: Kernel.h:89
constexpr static const auto FAILURE
Definition: StatusCode.h:88
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode initialize() override
Definition: Service.cpp:63
T empty(T...args)
T copy_if(T...args)
Define general base for Gaudi exception.
Helper class to set the application return code in case of early exit (e.g.
Definition: RetCodeGuard.h:9
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
StatusCode finalize() override
Definition: Service.cpp:173
ContextID_t slot() const
Definition: EventContext.h:50
IDataHandleMetadata::AccessMode AccessMode
Definition: DataHandle.h:115
The Event Selector Interface.
Definition: IEvtSelector.h:18
StatusCode finalize() override
implementation of IService::finalize
bool isSuccess() const
Definition: StatusCode.h:287
HistogramAgent base in charge of collecting all the references to DataObjects in a transient store th...
Header file for class GaudiAlgorithm.
STL namespace.
T duration_cast(T...args)
T end(T...args)
virtual StatusCode getProperty(Gaudi::Details::PropertyBase *p) const =0
Get the property by property.
virtual std::list< IAlgorithm * > getFlatAlgList()=0
Get the flat list of algorithms.
This class represents an entry point to all the event specific data.
Definition: EventContext.h:31
STL class.
bool isFailure() const
Definition: StatusCode.h:139
T partition(T...args)
constexpr int ScheduledStop
Definition: AppReturnCode.h:27
void setState(State s)
ContextEvt_t evt() const
Definition: EventContext.h:49
STL class.
The IAlgResourcePool is the interface for managing algorithm instances, in particular if clones of th...
#define DECLARE_COMPONENT(type)
constexpr int UnhandledException
Definition: AppReturnCode.h:29
T push_back(T...args)
GAUDI_API ISvcLocator * svcLocator()
T what(T...args)
Abstract interface for a service that manages the Algorithm execution states.
constexpr static const auto RECOVERABLE
Definition: StatusCode.h:89
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:51
virtual const AlgExecState & algExecState(const Gaudi::StringKey &algName, const EventContext &ctx) const =0
const std::string & key() const
Definition: DataObjID.h:49
start
Definition: IOTest.py:99
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
const IDataSelector & selectedObjects() const
Return the set of selected DataObjects.
virtual const std::string & tag() const
name tag for the exception, or exception type
STL class.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:51
HLTExecutionTask(std::vector< Algorithm * > &algorithms, std::unique_ptr< EventContext > ctx, ISvcLocator *svcLocator, IAlgExecStateSvc *aem, const HLTEventLoopMgr *parent)
GAUDI_API void setCurrentContext(const EventContext *ctx)
T move(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
virtual void updateEventStatus(const bool &b, const EventContext &ctx)=0
const HLTEventLoopMgr * m_parent
T get(T...args)
T insert(T...args)
Base class from which all concrete algorithm classes should be derived.
Definition: Algorithm.h:79
SmartIF< ISvcLocator > m_serviceLocator
void promoteToExecuted(std::unique_ptr< EventContext > eventContext) const
T find(T...args)
GAUDI_API long mappedMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.
Definition: Memory.cpp:204
T size(T...args)
virtual std::vector< Algorithm * > algorithmsRequiredFor(const DataObjIDColl &requested, const std::vector< std::string > &stoppers={}) const =0
Get the (ordered!) list of algorithms required to provide a given DataObjIDColl.
STL class.
StatusCode nextEvent(int maxevt) override
implementation of IEventProcessor::nextEvent
bool empty() const
Tell if this DataObjID is has an empty key.
Definition: DataObjID.h:53
virtual Out operator()(const vector_of_const_< In > &inputs) const =0
StatusCode initialize() override
implementation of IService::initialize
T begin(T...args)
T back_inserter(T...args)
T none_of(T...args)
const StatusCode & ignore() const
Ignore/check StatusCode.
Definition: StatusCode.h:165
T back(T...args)
string s
Definition: gaudirun.py:253
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void* par)
GAUDI_API void setCurrentContextEvt(long int evtN)
void ignore()
Definition: RetCodeGuard.h:13
T sort(T...args)
StatusCode stopRun() override
implementation of IEventProcessor::stopRun()
AttribStringParser::Iterator begin(const AttribStringParser &parser)
T accumulate(T...args)
Opaque address interface definition.
StatusCode declareEventRootAddress()
Declare the root address of the event.
int maxevt
Definition: Bootstrap.cpp:276
constexpr int Success
Definition: AppReturnCode.h:18
The IProperty is the basic interface for all components which have properties that can be set or get...
Definition: IProperty.h:20
std::string fullKey() const
Definition: DataObjID.cpp:99
StatusCode eventFailed(EventContext *eventContext) const
Method to check if an event failed and take appropriate actions.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
std::vector< Algorithm * > & m_algorithms
STL class.
constexpr double ms
std::unique_ptr< EventContext > m_evtCtx
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
T reserve(T...args)
std::ostream & operator<<(std::ostream &str, const GaudiAlg::ID &id)
Operator overloading for ostream.
Definition: GaudiHistoID.h:136
bool valid() const
Definition: EventContext.h:53
T emplace_back(T...args)