All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
EventLoopMgr.cpp
Go to the documentation of this file.
1 #define GAUDISVC_EVENTLOOPMGR_CPP
2 
3 #include "GaudiKernel/Incident.h"
12 
13 #include <chrono>
14 
15 #include "HistogramAgent.h"
16 #include "EventLoopMgr.h"
17 
18 
19 // Instantiation of a static factory class used by clients to create instances of this service
21 
22 
23 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
24 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
25 
26 #define DEBMSG ON_DEBUG debug()
27 #define VERMSG ON_VERBOSE verbose()
28 
29 //--------------------------------------------------------------------------------------------
30 // Standard Destructor
31 //--------------------------------------------------------------------------------------------
33  delete m_evtContext;
34 }
35 
36 //--------------------------------------------------------------------------------------------
37 // implementation of IAppMgrUI::initialize
38 //--------------------------------------------------------------------------------------------
40  // Initialize the base class
42  if( !sc.isSuccess() ) {
43  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
44  return sc;
45  }
46 
47  // Setup access to event data services
48  m_evtDataMgrSvc = serviceLocator()->service("EventDataSvc");
49  if( !m_evtDataMgrSvc ) {
50  fatal() << "Error retrieving EventDataSvc interface IDataManagerSvc." << endmsg;
51  return StatusCode::FAILURE;
52  }
53  m_evtDataSvc = serviceLocator()->service("EventDataSvc");
54  if( !m_evtDataSvc ) {
55  fatal() << "Error retrieving EventDataSvc interface IDataProviderSvc." << endmsg;
56  return StatusCode::FAILURE;
57  }
58 
59  // Obtain the IProperty of the ApplicationMgr
61  if ( ! m_appMgrProperty ) {
62  fatal() << "IProperty interface not found in ApplicationMgr." << endmsg;
63  return StatusCode::FAILURE;
64  }
65 
66  // We do not expect a Event Selector necessarily being declared
67  setProperty(m_appMgrProperty->getProperty("EvtSel")).ignore();
68 
69  if( m_evtsel != "NONE" || m_evtsel.length() == 0) {
70  m_evtSelector = serviceLocator()->service("EventSelector");
71  if( m_evtSelector ) {
72  // Setup Event Selector
74  if( !sc.isSuccess() ) {
75  fatal() << "Can not create the event selector Context." << endmsg;
76  return sc;
77  }
78  }
79  else {
80  fatal() << "EventSelector not found." << endmsg;
81  return sc;
82  }
83  } else {
84  m_evtSelector = nullptr;
85  m_evtContext = nullptr;
86  if ( m_warnings ) {
87  warning() << "Unable to locate service \"EventSelector\" " << endmsg;
88  warning() << "No events will be processed from external input." << endmsg;
89  }
90  }
91 
92  // Setup access to histogramming services
93  m_histoDataMgrSvc = serviceLocator()->service("HistogramDataSvc");
94  if( !m_histoDataMgrSvc ) {
95  fatal() << "Error retrieving HistogramDataSvc." << endmsg;
96  return sc;
97  }
98  // Setup histogram persistency
99  m_histoPersSvc = serviceLocator()->service("HistogramPersistencySvc");
100  if( !m_histoPersSvc ) {
101  warning() << "Histograms cannot not be saved - though required." << endmsg;
102  return sc;
103  }
104 
105  return StatusCode::SUCCESS;
106 }
107 //--------------------------------------------------------------------------------------------
108 // implementation of IService::reinitialize
109 //--------------------------------------------------------------------------------------------
111 
112  // Initialize the base class
114  if( !sc.isSuccess() ) {
115  DEBMSG << "Error Initializing base class MinimalEventLoopMgr." << endmsg;
116  return sc;
117  }
118 
119  // Check to see whether a new Event Selector has been specified
121  if( m_evtsel != "NONE" || m_evtsel.length() == 0) {
122  auto theSvc = serviceLocator()->service<IService>("EventSelector");
123  auto theEvtSel = theSvc.as<IEvtSelector>();
124  if( theEvtSel && ( theEvtSel.get() != m_evtSelector.get() ) ) {
125  // Setup Event Selector
126  if ( m_evtSelector.get() && m_evtContext ) {
127  // Need to release context before switching to new event selector
129  m_evtContext = nullptr;
130  }
131  m_evtSelector = theEvtSel;
132  if (theSvc->FSMState() == Gaudi::StateMachine::INITIALIZED) {
133  sc = theSvc->reinitialize();
134  if( !sc.isSuccess() ) {
135  error() << "Failure Reinitializing EventSelector "
136  << theSvc->name( ) << endmsg;
137  return sc;
138  }
139  } else {
140  sc = theSvc->sysInitialize();
141  if( !sc.isSuccess() ) {
142  error() << "Failure Initializing EventSelector "
143  << theSvc->name( ) << endmsg;
144  return sc;
145  }
146  }
148  if( !sc.isSuccess() ) {
149  error() << "Can not create Context " << theSvc->name( ) << endmsg;
150  return sc;
151  }
152  info() << "EventSelector service changed to "
153  << theSvc->name( ) << endmsg;
154  }
155  else if ( m_evtSelector ) {
156  if ( m_evtContext ) {
158  m_evtContext = nullptr;
159  }
161  if( !sc.isSuccess() ) {
162  error() << "Can not create Context " << theSvc->name( ) << endmsg;
163  return sc;
164  }
165  }
166  }
167  else if ( m_evtSelector && m_evtContext ) {
169  m_evtSelector = nullptr;
170  m_evtContext = nullptr;
171  }
172  return StatusCode::SUCCESS;
173 }
174 
175 
176 //--------------------------------------------------------------------------------------------
177 // implementation of IService::stop
178 //--------------------------------------------------------------------------------------------
180  if ( ! m_endEventFired ) {
181  // Fire pending EndEvent incident
182  m_incidentSvc->fireIncident(Incident(name(),IncidentType::EndEvent));
183  m_endEventFired = true;
184  }
185  return MinimalEventLoopMgr::stop();
186 }
187 
188 //--------------------------------------------------------------------------------------------
189 // implementation of IAppMgrUI::finalize
190 //--------------------------------------------------------------------------------------------
192  StatusCode sc;
193 
194  // Finalize base class
196  if (! sc.isSuccess()) {
197  error() << "Error finalizing base class" << endmsg;
198  return sc;
199  }
200 
201  // Save Histograms Now
202  if ( m_histoPersSvc ) {
203  HistogramAgent agent;
204  sc = m_histoDataMgrSvc->traverseTree( &agent );
205  if( sc.isSuccess() ) {
206  IDataSelector* objects = agent.selectedObjects();
207  // skip /stat entry!
208  if ( objects->size() > 0 ) {
209  for ( auto& i : *objects ) {
210  IOpaqueAddress* pAddr = nullptr;
211  StatusCode iret = m_histoPersSvc->createRep(i, pAddr);
212  if ( iret.isSuccess() ) {
213  i->registry()->setAddress(pAddr);
214  }
215  else {
216  sc = iret;
217  }
218  }
219  for ( auto& i : *objects ) {
220  IRegistry* reg = i->registry();
221  StatusCode iret = m_histoPersSvc->fillRepRefs(reg->address(), i);
222  if ( !iret.isSuccess() ) sc = iret;
223  }
224  }
225  if ( sc.isSuccess() ) {
226  info() << "Histograms converted successfully according to request." << endmsg;
227  }
228  else {
229  error() << "Error while saving Histograms." << endmsg;
230  }
231  }
232  else {
233  error() << "Error while traversing Histogram data store" << endmsg;
234  }
235  }
236 
237  // Release event selector context
238  if ( m_evtSelector && m_evtContext ) {
240  m_evtContext = nullptr;
241  }
242 
243  // Release all interfaces...
244  m_histoDataMgrSvc = nullptr;
245  m_histoPersSvc = nullptr;
246 
247  m_evtSelector = nullptr;
248  m_evtDataSvc = nullptr;
249  m_evtDataMgrSvc = nullptr;
250 
251  return StatusCode::SUCCESS;
252 }
253 
254 //--------------------------------------------------------------------------------------------
255 // executeEvent(void* par)
256 //--------------------------------------------------------------------------------------------
258 
259  // DP Monitoring
260 
261 
262 
263  // Fire BeginEvent "Incident"
264  m_incidentSvc->fireIncident(Incident(name(),IncidentType::BeginEvent));
265  // An incident may schedule a stop, in which case is better to exit before the actual execution.
266  if ( m_scheduledStop ) {
267  always() << "Terminating event processing loop due to a stop scheduled by an incident listener" << endmsg;
268  return StatusCode::SUCCESS;
269  }
270 
271  // Execute Algorithms
272  m_incidentSvc->fireIncident(Incident(name(), IncidentType::BeginProcessing));
274  m_incidentSvc->fireIncident(Incident(name(), IncidentType::EndProcessing));
275 
276  // Check if there was an error processing current event
277  if( UNLIKELY(!sc.isSuccess()) ){
278  error() << "Terminating event processing loop due to errors" << endmsg;
279  }
280  return sc;
281 }
282 
283 //--------------------------------------------------------------------------------------------
284 // implementation of IAppMgrUI::nextEvent
285 //--------------------------------------------------------------------------------------------
286 // External libraries
287 #include "GaudiKernel/Memory.h"
289 
290  // DP Monitoring
291  // Calculate runtime
294 
295  const float oneOver1024 = 1.f/1024.f;
296 
297 
298  static int total_nevt = 0;
299  DataObject* pObject = nullptr;
301 
302  // loop over events if the maxevt (received as input) if different from -1.
303  // if evtmax is -1 it means infinite loop
304  time_point start_time = Clock::now();
305  for( int nevt = 0; maxevt == -1 || nevt < maxevt; ++nevt, ++total_nevt) {
306 
307  if(1 == nevt) // reset after first evt
308  start_time = Clock::now();
309 
310  //always() << "Event Number = " << total_nevt
311  // << " WSS (MB) = " << System::mappedMemory(System::MemoryUnit::kByte)*oneOver1024
312  // << " Time (s) = " << secsFromStart(start_time) << endmsg;
313 
314 
315  // Check if there is a scheduled stop issued by some algorithm/service
316  if ( m_scheduledStop ) {
317  m_scheduledStop = false;
318  always() << "Terminating event processing loop due to scheduled stop" << endmsg;
319  break;
320  }
321  // Clear the event store, if used in the event loop
322  if( 0 != total_nevt ) {
323 
324  if ( ! m_endEventFired ) {
325  // Fire EndEvent "Incident" (it is considered part of the clearing of the TS)
326  m_incidentSvc->fireIncident(Incident(name(),IncidentType::EndEvent));
327  m_endEventFired = true;
328  }
329  sc = m_evtDataMgrSvc->clearStore();
330  if( !sc.isSuccess() ) {
331  DEBMSG << "Clear of Event data store failed" << endmsg;
332  }
333  }
334 
335  // Setup event in the event store
336  if( m_evtContext ) {
337  IOpaqueAddress* addr = nullptr;
338  // Only if there is a EventSelector
339  sc = getEventRoot(addr);
340  if( !sc.isSuccess() ) {
341  info() << "No more events in event selection " << endmsg;
342  break;
343  }
344  // Set root clears the event data store first
345  sc = m_evtDataMgrSvc->setRoot ("/Event", addr);
346  if( !sc.isSuccess() ) {
347  warning() << "Error declaring event root address." << endmsg;
348  continue;
349  }
350  sc = m_evtDataSvc->retrieveObject("/Event", pObject);
351  if( !sc.isSuccess() ) {
352  warning() << "Unable to retrieve Event root object" << endmsg;
353  break;
354  }
355  } else {
356  sc = m_evtDataMgrSvc->setRoot ("/Event", new DataObject());
357  if( !sc.isSuccess() ) {
358  warning() << "Error declaring event root DataObject" << endmsg;
359  }
360  }
361  // Execute event for all required algorithms
362  sc = executeEvent(nullptr);
363  m_endEventFired = false;
364  if( !sc.isSuccess() ){
365  error() << "Terminating event processing loop due to errors" << endmsg;
367  return sc;
368  }
369  }
370  time_point end_time = Clock::now();
371 
372  if (UNLIKELY(outputLevel() <= MSG::DEBUG))
373  debug() << "---> Loop Finished - "
374  << " WSS " << System::mappedMemory(System::MemoryUnit::kByte)*oneOver1024
375  << " | total time (skipping 1st evt) "
376  << std::chrono::duration_cast < std::chrono::nanoseconds > (end_time - start_time).count()
377  << " ns" << endmsg;
378 
379  return StatusCode::SUCCESS;
380 }
381 
384  refpAddr = nullptr;
386  if ( !sc.isSuccess() ) return sc;
387  // Create root address and assign address to data service
388  sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
389  if( !sc.isSuccess() ) {
391  if ( sc.isSuccess() ) {
392  sc = m_evtSelector->createAddress(*m_evtContext,refpAddr);
393  if ( !sc.isSuccess() ) {
394  warning() << "Error creating IOpaqueAddress." << endmsg;
395  }
396  }
397  }
398  return sc;
399 }
StatusCode finalize() override
implementation of IService::finalize
const std::string & name() const override
Retrieve name of the service.
Definition: Service.cpp:289
StatusCode finalize() override
implementation of IService::finalize
bool m_scheduledStop
Scheduled stop of event processing.
SmartIF< IConversionSvc > m_histoPersSvc
Reference to the Histogram Persistency Service.
Definition: EventLoopMgr.h:59
StatusCode setProperty(const Gaudi::Details::PropertyBase &p) override
set the property form another property
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
Gaudi::Property< bool > m_warnings
Definition: EventLoopMgr.h:46
The Event Selector Interface.
Definition: IEvtSelector.h:18
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
HistogramAgent base in charge of collecting all the refereces to DataObjects in a transient store tha...
StatusCode initialize() override
implementation of IService::initialize
int outputLevel() const
get the Service&#39;s output level
Definition: Service.h:196
#define UNLIKELY(x)
Definition: Kernel.h:126
StatusCode reinitialize() override
implementation of IService::reinitialize
T duration_cast(T...args)
virtual StatusCode getProperty(Gaudi::Details::PropertyBase *p) const =0
Get the property by property.
virtual StatusCode createRep(DataObject *pObject, IOpaqueAddress *&refpAddress)=0
Convert the transient object to the requested representation.
Class definition of EventLoopMgr.
Definition: EventLoopMgr.h:38
StatusCode reinitialize() override
implementation of IService::reinitialize
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
StatusCode stop() override
implementation of IService::stop
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
virtual StatusCode traverseTree(IDataStoreAgent *pAgent)=0
Analyse by traversing all data objects in the data store.
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void* par)
StatusCode nextEvent(int maxevt) override
implementation of IService::nextEvent
General service interface definition.
Definition: IService.h:18
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
StatusCode getEventRoot(IOpaqueAddress *&refpAddr)
Create event address using event selector.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
virtual StatusCode releaseContext(Context *&) const =0
Release the Context object.
std::chrono::high_resolution_clock Clock
Definition: ITimelineSvc.h:10
IDataSelector * selectedObjects()
Return the set of selected DataObjects.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to the incident service.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
Definition: AppReturnCode.h:51
virtual StatusCode setRoot(std::string root_name, DataObject *pObject)=0
Initialize data store for new event by giving new event path.
SmartIF< IDataManagerSvc > m_evtDataMgrSvc
Reference to the Event Data Service&#39;s IDataManagerSvc interface.
Definition: EventLoopMgr.h:49
GAUDI_API long mappedMemory(MemoryUnit unit=kByte, InfoType fetch=Memory, long pid=-1)
Basic Process Information: priority boost.
Definition: Memory.cpp:180
T size(T...args)
StatusCode initialize() override
implementation of IService::initialize
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
SmartIF< IProperty > m_appMgrProperty
Property interface of ApplicationMgr.
Definition: EventLoopMgr.h:61
IEvtSelector::Context * m_evtContext
Event Iterator.
Definition: EventLoopMgr.h:55
SmartIF< IEvtSelector > m_evtSelector
Reference to the Event Selector.
Definition: EventLoopMgr.h:53
Clock::time_point time_point
Definition: ITimelineSvc.h:11
#define DEBMSG
StatusCode stop() override
implementation of IService::stop
Base class for all Incidents (computing events).
Definition: Incident.h:17
constexpr int AlgorithmFailure
Definition: AppReturnCode.h:26
virtual StatusCode clearStore()=0
Remove all data objects in the data store.
Gaudi::Property< std::string > m_evtsel
Definition: EventLoopMgr.h:45
bool m_endEventFired
Flag to avoid to fire the EnvEvent incident twice in a row (and also not before the first event) ...
Definition: EventLoopMgr.h:64
SmartIF< IDataProviderSvc > m_evtDataSvc
Reference to the Event Data Service&#39;s IDataProviderSvc interface.
Definition: EventLoopMgr.h:51
virtual StatusCode next(Context &c) const =0
Fetch the next event or the first event if it will be use soon after the creation of the context...
virtual StatusCode createContext(Context *&c) const =0
Create and return a context object that will keep track of the state of selection.
~EventLoopMgr() override
Standard Destructor.
virtual StatusCode createAddress(const Context &c, IOpaqueAddress *&iop) const =0
Create an IOpaqueAddress object from the event fetched.
Opaque address interface definition.
int maxevt
Definition: Bootstrap.cpp:279
void ignore() const
Definition: StatusCode.h:106
MsgStream & fatal() const
shortcut for the method msgStream(MSG::FATAL)
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
MsgStream & always() const
shortcut for the method msgStream(MSG::ALWAYS)
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
virtual StatusCode fillRepRefs(IOpaqueAddress *pAddress, DataObject *pObject)=0
Resolve the references of the converted object.
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition: Service.cpp:292
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
StatusCode executeEvent(void *par) override
implementation of IEventProcessor::executeEvent(void* par)
SmartIF< IDataManagerSvc > m_histoDataMgrSvc
Reference to the Histogram Data Service.
Definition: EventLoopMgr.h:57
virtual StatusCode retrieveObject(IRegistry *pDirectory, const std::string &path, DataObject *&pObject)=0
Retrieve object identified by its directory entry.