The Gaudi Framework  v30r5 (c7afbd0d)
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  boost::optional<std::ofstream> dot{boost::in_place_init_if, !m_dotfile.empty(), m_dotfile.value()};
230 
231  if ( dot ) {
232  *dot << "digraph G {\n";
233  for ( auto* a : m_algos ) {
234  bool is_consumer = a->outputDataObjs().empty();
235  *dot << '\"' << a->name() << "\" [shape=box" << ( is_consumer ? ",style=filled" : "" ) << "];\n";
236  }
237  }
238 
239  // figure out all outputs
241  for ( Algorithm* algoPtr : m_algos ) {
242  for ( auto id : algoPtr->outputDataObjs() ) {
243  auto r = globalOutp.insert( id );
244  producers[id] = algoPtr;
245  if ( !r.second ) {
246  warning() << "multiple algorithms declare " << id
247  << " as output! could be a single instance in multiple paths "
248  "though, or control flow may guarantee only one runs...!"
249  << endmsg;
250  }
251  }
252  }
253 
254  // Building and printing Data Dependencies
255  std::vector<DataObjIDColl> algosDependencies;
256  algosDependencies.reserve( m_algos.size() ); // reserve so that pointers into the vector do not get invalidated...
258  info() << "Data Dependencies for Algorithms:";
259 
260  for ( Algorithm* algoPtr : m_algos ) {
261  info() << "\n " << algoPtr->name();
262 
263  DataObjIDColl algoDependencies;
264  if ( !algoPtr->inputDataObjs().empty() || !algoPtr->outputDataObjs().empty() ) {
265  for ( const DataObjID* idp : sortedDataObjIDColl( algoPtr->inputDataObjs() ) ) {
266  DataObjID id = *idp;
267  info() << "\n o INPUT " << id;
268  if ( id.key().find( ":" ) != std::string::npos ) {
269  info() << " contains alternatives which require resolution...\n";
270  auto tokens = boost::tokenizer<boost::char_separator<char>>{id.key(), boost::char_separator<char>{":"}};
271  auto itok = std::find_if( tokens.begin(), tokens.end(), [&]( const std::string& t ) {
272  return globalOutp.find( DataObjID{t} ) != globalOutp.end();
273  } );
274  if ( itok != tokens.end() ) {
275  info() << "found matching output for " << *itok << " -- updating scheduler info\n";
276  id.updateKey( *itok );
277  } else {
278  error() << "failed to find alternate in global output list"
279  << " for id: " << id << " in Alg " << algoPtr->name() << endmsg;
280  }
281  }
282  algoDependencies.insert( id );
283  if ( dot ) *dot << DataObjIDDotRepr{id} << " -> \"" << algoPtr->name() << "\";\n";
284  globalInp.insert( id );
285  }
286  for ( const DataObjID* id : sortedDataObjIDColl( algoPtr->outputDataObjs() ) ) {
287  info() << "\n o OUTPUT " << *id;
288  if ( id->key().find( ":" ) != std::string::npos ) {
289  error() << " in Alg " << algoPtr->name() << " alternatives are NOT allowed for outputs! id: " << *id
290  << endmsg;
291  }
292  if ( dot ) *dot << '\"' << algoPtr->name() << "\" -> " << DataObjIDDotRepr{*id} << ";\n";
293  }
294  } else {
295  info() << "\n none";
296  }
297  algosDependencies.emplace_back( algoDependencies );
298  algo2Deps[algoPtr] = &algosDependencies.back();
299  }
300  if ( dot ) {
301  for ( const auto& t : globalOutp ) {
302  if ( globalInp.find( t ) == globalInp.end() ) *dot << DataObjIDDotRepr{t} << " [style=filled];\n";
303  }
304  *dot << "}\n";
305  }
306  info() << endmsg;
307 
308  // Check if we have unmet global input dependencies
309  DataObjIDColl unmetDep;
310  for ( auto o : globalInp ) {
311  if ( globalOutp.find( o ) == globalOutp.end() ) unmetDep.insert( o );
312  }
313  if ( unmetDep.size() > 0 ) {
314  std::ostringstream ost;
315  for ( const DataObjID* o : sortedDataObjIDColl( unmetDep ) ) {
316  ost << "\n o " << *o << " required by Algorithm: ";
317  for ( const auto& i : algo2Deps ) {
318  if ( i.second->find( *o ) != i.second->end() ) {
319  ost << "\n * " << i.first->name();
320  }
321  }
322  }
323  fatal() << "The following unmet INPUT dependencies were found:" << ost.str() << endmsg;
324  return StatusCode::FAILURE;
325  } else {
326  info() << "No unmet INPUT data dependencies were found" << endmsg;
327  }
328 
329  // rework the flat algo list to respect data dependencies
330  auto start = m_algos.begin();
331  auto end = m_algos.end();
332  auto current =
333  std::partition( start, end, [&algo2Deps]( const Algorithm* algo ) { return algo2Deps[algo]->empty(); } );
334 
335  // Repeatedly put in front algos for which input are already fullfilled
336  while ( current != end ) {
337  current = std::partition( current, end, [start, current, &producers, &algo2Deps]( const Algorithm* algo ) {
338  return std::none_of( algo2Deps[algo]->begin(), algo2Deps[algo]->end(),
339  [start, current, &producers]( const DataObjID& id ) {
340  return std::find( start, current, producers[id] ) == current;
341  } );
342  } );
343  }
344  }
345 
346  // Clearly inform about the level of concurrency
347  info() << "Concurrency level information:" << endmsg;
348  info() << " o Number of events slots: " << m_whiteboard->getNumberOfStores() << endmsg;
349  info() << " o TBB thread pool size: " << m_threadPoolSize << endmsg;
350 
351  // Fill the containers to convert algo names to index
352  debug() << "Order of algo execution :" << endmsg;
353  for ( const Algorithm* algo : m_algos ) debug() << " . " << algo->name() << endmsg;
354 
355  return sc;
356 }
357 
359 {
360  StatusCode sc;
361  // Save Histograms Now
362  if ( m_histoPersSvc ) {
363  HistogramAgent agent;
364  sc = m_histoDataMgrSvc->traverseTree( &agent );
365  if ( sc.isSuccess() ) {
366  const IDataSelector& objects = agent.selectedObjects();
367  // skip /stat entry!
368  sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode s, const auto& i ) {
369  IOpaqueAddress* pAddr = nullptr;
370  StatusCode iret = m_histoPersSvc->createRep( i, pAddr );
371  if ( iret.isSuccess() ) i->registry()->setAddress( pAddr );
372  return s.isFailure() ? s : iret;
373  } );
374  sc = std::accumulate( begin( objects ), end( objects ), sc, [&]( StatusCode s, const auto& i ) {
375  IRegistry* reg = i->registry();
376  StatusCode iret = m_histoPersSvc->fillRepRefs( reg->address(), i );
377  return s.isFailure() ? s : iret;
378  } );
379  if ( sc.isSuccess() ) {
380  info() << "Histograms converted successfully according to request." << endmsg;
381  } else {
382  error() << "Error while saving Histograms." << endmsg;
383  }
384  } else {
385  error() << "Error while traversing Histogram data store" << endmsg;
386  }
387  }
388 
390  return sc.isFailure() ? sc2.ignore(), sc : sc2;
391 }
392 
393 StatusCode HLTEventLoopMgr::executeEvent( void* createdEvts_IntPtr )
394 {
395  // Leave the interface intact and swallow this C trick.
396  int& createdEvts = *reinterpret_cast<int*>( createdEvts_IntPtr );
397 
398  auto evtContext = std::make_unique<EventContext>();
399  evtContext->set( createdEvts, m_whiteboard->allocateStore( createdEvts ) );
400  m_algExecStateSvc->reset( *evtContext );
401 
402  StatusCode sc = m_whiteboard->selectStore( evtContext->slot() );
403  if ( sc.isFailure() ) {
404  fatal() << "Slot " << evtContext->slot() << " could not be selected for the WhiteBoard\n"
405  << "Impossible to create event context" << endmsg;
406  return StatusCode::FAILURE;
407  }
408 
409  StatusCode declEvtRootSc = declareEventRootAddress();
410  if ( declEvtRootSc.isFailure() ) { // We ran out of events!
411  createdEvts = -1; // Set created event to a negative value: we finished!
412  return StatusCode::SUCCESS;
413  }
414 
415  // Now add event to the scheduler
416  if ( msgLevel( MSG::DEBUG ) )
417  debug() << "Event " << evtContext->evt() << " submitting in slot " << evtContext->slot() << endmsg;
418 
419  // Event processing slot forced to be the same as the wb slot
420  tbb::task* task = new ( tbb::task::allocate_root() )
421  HLTExecutionTask( m_algos, std::move( evtContext ), serviceLocator(), m_algExecStateSvc, this );
422  tbb::task::enqueue( *task );
423 
424  if ( msgLevel( MSG::DEBUG ) )
425  debug() << "All algorithms were submitted on event " << evtContext->evt() << " in slot " << evtContext->slot()
426  << endmsg; // FIXME: use after std::move..
427 
428  createdEvts++;
429  return StatusCode::SUCCESS;
430 }
431 
433 {
434  // Set the application return code
435  auto appmgr = serviceLocator()->as<IProperty>();
437  error() << "Could not set return code of the application (" << Gaudi::ReturnCode::ScheduledStop << ")" << endmsg;
438  }
439  return StatusCode::SUCCESS;
440 }
441 
443 {
444  // Calculate runtime
446 
447  // Reset the application return code.
448  auto appmgr = serviceLocator()->as<IProperty>();
450 
451  // create m_evtSelContext used internally in executeEvent and more
452  // precisely in declareEventRootAddress. Cannot be passed through the interface
453  // without breaking other schedulers
454  StatusCode sc = m_evtSelector->createContext( m_evtSelContext );
455  if ( !sc.isSuccess() ) {
456  fatal() << "Can not create the event selector Context." << endmsg;
457  return sc;
458  }
459 
460  // create th tbb thread pool
461  tbb::task_scheduler_init tbbSchedInit( m_threadPoolSize.value() + 1 );
462 
463  int createdEvts = 0;
464  // Run the first event before spilling more than one
465  bool newEvtAllowed = false;
466 
467  info() << "Starting loop on events" << endmsg;
468  auto start_time = Clock::now();
469  while ( maxevt < 0 || m_finishedEvt < (unsigned int)maxevt ) {
470  // if the created events did not reach maxevt, create an event
471  if ( !( ( newEvtAllowed || createdEvts == 0 ) && // Launch the first event alone
472  // The events are not finished with an unlimited number of events
473  createdEvts >= 0 &&
474  // The events are not finished with a limited number of events
475  ( createdEvts < maxevt || maxevt < 0 ) &&
476  // There are still free slots in the whiteboard
477  m_whiteboard->freeSlots() > 0 ) ) {
478 
479  std::unique_lock<std::mutex> lock{m_createEventMutex};
480  using namespace std::chrono_literals;
481  m_createEventCond.wait_for( lock, 1ms, [this, newEvtAllowed, createdEvts, maxevt] {
482  return ( newEvtAllowed || createdEvts == 0 ) && // Launch the first event alone
483  // The events are not finished with an unlimited number of events
484  createdEvts >= 0 &&
485  // The events are not finished with a limited number of events
486  ( createdEvts < maxevt || maxevt < 0 ) &&
487  // There are still free slots in the whiteboard
488  this->m_whiteboard->freeSlots() > 0;
489  } );
490  continue;
491  }
492  if ( 1 == createdEvts ) // reset counter to count from event 1
493  start_time = Clock::now();
494 
495  // TODO can we adapt the interface of executeEvent for a nicer solution?
497  sc = executeEvent( &createdEvts );
498  if ( !sc.isSuccess() ) return StatusCode::FAILURE; // else we have an success --> exit loop
499  newEvtAllowed = true;
500  } // end main loop on finished events
501  auto end_time = Clock::now();
502 
503  delete m_evtSelContext;
504  m_evtSelContext = nullptr;
505 
506  constexpr double oneOver1024 = 1. / 1024.;
507  info() << "---> Loop Finished (skipping 1st evt) - "
508  << " WSS " << System::mappedMemory( System::MemoryUnit::kByte ) * oneOver1024 << " total time "
509  << std::chrono::duration_cast<std::chrono::milliseconds>( end_time - start_time ).count() << " ms" << endmsg;
510  return StatusCode::SUCCESS;
511 }
512 
514 {
515  IOpaqueAddress* pAddr = nullptr;
516  StatusCode sc = m_evtSelector->next( *m_evtSelContext );
517  if ( sc.isSuccess() ) {
518  // Create root address and assign address to data service
519  sc = m_evtSelector->createAddress( *m_evtSelContext, pAddr );
520  if ( !sc.isSuccess() ) {
521  sc = m_evtSelector->next( *m_evtSelContext );
522  if ( sc.isSuccess() ) {
523  sc = m_evtSelector->createAddress( *m_evtSelContext, pAddr );
524  if ( !sc.isSuccess() ) warning() << "Error creating IOpaqueAddress." << endmsg;
525  }
526  }
527  }
528  if ( !sc.isSuccess() ) {
529  info() << "No more events in event selection " << endmsg;
530  return StatusCode::FAILURE;
531  }
532  sc = m_evtDataMgrSvc->setRoot( "/Event", pAddr );
533  if ( !sc.isSuccess() ) {
534  warning() << "Error declaring event root address." << endmsg;
535  }
536  return StatusCode::SUCCESS;
537 }
538 
545 {
546  fatal() << "*** Event " << eventContext->evt() << " on slot " << eventContext->slot() << " failed! ***" << endmsg;
547  std::ostringstream ost;
548  m_algExecStateSvc->dump( ost, *eventContext );
549  info() << "Dumping Alg Exec State for slot " << eventContext->slot() << ":\n" << ost.str() << endmsg;
550  return StatusCode::FAILURE;
551 }
552 
554 {
555  // Check if the execution failed
556  if ( m_algExecStateSvc->eventStatus( *eventContext ) != EventStatus::Success )
557  eventFailed( eventContext.get() ).ignore();
558  int si = eventContext->slot();
559 
560  // if ( msgLevel( MSG::DEBUG ) )
561  // debug() << "Event " << eventContext->evt() << " executed in slot " << si << "." << endmsg;
562 
563  // Schedule the cleanup of the event
564  if ( m_algExecStateSvc->eventStatus( *eventContext ) == EventStatus::Success ) {
565  if ( msgLevel( MSG::DEBUG ) )
566  debug() << "Event " << eventContext->evt() << " finished (slot " << si << ")." << endmsg;
567  } else {
568  fatal() << "Failed event detected on " << *eventContext << endmsg;
569  }
570 
571  debug() << "Clearing slot " << si << " (event " << eventContext->evt() << ") of the whiteboard" << endmsg;
572 
573  StatusCode sc = m_whiteboard->clearStore( si );
574  if ( !sc.isSuccess() ) warning() << "Clear of Event data store failed" << endmsg;
575  sc = m_whiteboard->freeStore( si );
576  if ( !sc.isSuccess() ) error() << "Whiteboard slot " << eventContext->slot() << " could not be properly cleared";
577  ++m_finishedEvt;
578  m_createEventCond.notify_all();
579 }
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:1284
#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
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
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)