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