All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TimingAuditor.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/Auditor.h"
2 #include "GaudiKernel/IToolSvc.h"
5 #include "GaudiKernel/IToolSvc.h"
7 #include "GaudiKernel/HashMap.h"
9 // ============================================================================
10 // GaudiAlg
11 // ============================================================================
13 // ============================================================================
14 #ifdef __ICC
15 // disable icc warning #654: overloaded virtual function "B::Y" is only partially overridden in class "C"
16 // TODO: there is only a partial overload of IAuditor::before and IAuditor::after
17 #pragma warning(disable:654)
18 #endif
19 
28 class TimingAuditor: public extends1<Auditor, IIncidentListener> {
29 public:
30 
31  virtual void before(StandardEventType evt, INamedInterface* alg);
32  virtual void after(StandardEventType evt, INamedInterface* alg, const StatusCode &sc);
33 
34  using Auditor::before; // avoid hiding base-class methods
35  virtual void before(CustomEventTypeRef evt, const std::string& name);
36  using Auditor::after; // avoid hiding base-class methods
37  virtual void after(CustomEventTypeRef evt, const std::string& name, const StatusCode &sc);
38 
39 private:
42  void i_beforeFinalize( INamedInterface* alg );
43  void i_beforeExecute( INamedInterface* alg );
44  void i_afterExecute( INamedInterface* alg);
45 
46 public:
48  virtual void handle ( const Incident& ) ;
49 
50 public:
51  virtual StatusCode initialize () ;
52  virtual StatusCode finalize () ;
53 
54 public:
57  ( const std::string& name ,
58  ISvcLocator* pSvc )
59  : base_class ( name , pSvc )
60  //
61  , m_toolSvc ( 0 )
62  , m_incSvc ( 0 )
63  //
64  , m_timer ( 0 )
65  //
66  , m_appMgr ( 0 )
67  //
68  , m_map ( )
69  , m_indent ( 0 )
70  , m_inEvent ( false )
71  , m_goodForDOD ( false )
72  , m_mapUser ( )
73  , m_histoSaved ( false )
74  {
75  declareProperty ( "OptimizedForDOD" , m_goodForDOD ) ;
76  } ;
78  virtual ~TimingAuditor() {}
79 private:
80  // the default constructor is disabled
81  TimingAuditor () ;
82  // copy constructor is disabled
83  TimingAuditor ( const TimingAuditor& ) ;
84  // assignement operator is disabled
86 private:
87  // tool service
89  // incident service
91  // the timer tool
93  // ApplicationManager
95  //
98  // indentation level
99  int m_indent ;
100  // "in event"
101  bool m_inEvent ;
102  // "optimized for Data-On-Demand Service"
103  bool m_goodForDOD ;
104  //
107 
108  // Whether the timing has been saved already
110 
111 
112 } ;
113 // ============================================================================
115 // ============================================================================
117 // ============================================================================
118 StatusCode TimingAuditor::initialize ()
119 {
121  if ( sc.isFailure() ) { return sc ; } // RETURN
122 
123  MsgStream log ( msgSvc() , name() ) ;
124 
125  // get tool service
126  if ( 0 == m_toolSvc )
127  {
128  sc = Auditor::service ( "ToolSvc" , m_toolSvc ) ;
129  if ( sc.isFailure() )
130  {
131  log << "Could not retrieve 'ToolSvc' " << sc << endmsg ;
132  return sc ; // RETURN
133  }
134  if ( 0 == m_timer )
135  {
136  sc = m_toolSvc->retrieveTool
137  ( "SequencerTimerTool/TIMER" , m_timer , this , true ) ;
138  if ( sc.isFailure() )
139  {
140  log << MSG::ERROR
141  << "Could not retrieve ISequencerTimerTool" << endmsg ;
142  return sc ;
143  }
144  }
145  }
146  // get incident service
147  if ( 0 == m_incSvc )
148  {
149  sc = Auditor::service ( "IncidentSvc" , m_incSvc ) ;
150  if ( sc.isFailure() )
151  {
152  log << MSG::ERROR
153  << "Could not retrieve 'IncidentSvc'" << sc << endmsg ;
154  return sc ;
155  }
156  m_incSvc -> addListener ( this , IncidentType::BeginEvent ) ;
157  m_incSvc -> addListener ( this , IncidentType::EndEvent ) ;
158  }
159  // get the application manager
160  if ( 0 == m_appMgr )
161  {
162  sc = Auditor::service ( "ApplicationMgr" , m_appMgr ) ;
163  if ( sc.isFailure() )
164  {
165  log << MSG::ERROR
166  << "Could not retrieve 'ApplicationMgr'" << sc << endmsg ;
167  return sc ;
168  }
169  if ( m_map.end() == m_map.find( m_appMgr ) )
170  {
171  int timer = m_timer->addTimer( "EVENT LOOP" ) ;
172  m_map.insert ( m_appMgr , timer ) ;
173  }
174  }
175  //
176  return StatusCode::SUCCESS ;
177 }
178 // ============================================================================
180 {
181  if ( 0 != m_incSvc )
182  {
183  m_incSvc -> removeListener ( this , IncidentType::BeginEvent ) ;
184  m_incSvc -> removeListener ( this , IncidentType::EndEvent ) ;
185  m_incSvc -> release () ;
186  m_incSvc = 0 ;
187  }
188  if ( 0 != m_toolSvc )
189  {
190  // the 2 following line are commented out: it is
191  // is a temporary hack which prevent a crash due to a problem in
192  // the reference counting
193  // if ( 0 != m_timer )
194  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
195  m_toolSvc -> release () ;
196  m_toolSvc = 0 ;
197  }
198  if ( 0 != m_appMgr ) { m_appMgr -> release () ; m_appMgr = 0 ; }
199  // clear the map
200  m_map.clear() ;
201  // finalize the base class
202  return Auditor::finalize () ;
203 }
204 // ============================================================================
206 {
207  switch (evt) {
208  case IAuditor::Initialize : i_beforeInitialize( alg ); break;
209  case IAuditor::Execute : i_beforeExecute( alg ); break;
210  case IAuditor::Finalize : i_beforeFinalize( alg ); break;
211  default: break;
212  }
213 }
214 // ============================================================================
216 {
217  switch (evt) {
218  case IAuditor::Initialize : i_afterInitialize( alg ); break;
219  case IAuditor::Execute : i_afterExecute( alg ); break;
220  default: break;
221  }
222 }
223 // ============================================================================
225 {
226  if (!m_histoSaved)
227  {
229  m_histoSaved = true;
230  }
231 }
232 
233 // ============================================================================
235 {
236  if ( m_goodForDOD ) { return ; }
237  //
238  if ( 0 == alg ) { return ; }
239  Map::iterator found = m_map.find( alg ) ;
240  if ( m_map.end() != found ) { return ; }
241  ++m_indent ;
242  std::string nick = alg->name() ;
243  if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
244  if ( m_inEvent )
245  {
246  nick[0] = '*' ;
247  MsgStream log( msgSvc() , name() ) ;
248  log << MSG::DEBUG
249  << "Insert non-structural component '"
250  << alg->name() << "' of type '"
251  << System::typeinfoName(typeid(*alg)) << "' at level "
252  << m_indent << endmsg ;
253  }
254  int timer = m_timer->addTimer( nick ) ;
255  m_map.insert ( alg , timer ) ;
256  m_timer->start( timer ) ;
257 }
258 // ============================================================================
260 {
261  if ( m_goodForDOD ) { return ; }
262  if ( 0 == alg ) { return ; }
263  --m_indent ;
264 }
265 // ============================================================================
267 {
268  if ( 0 == alg ) { return ; }
269  ++m_indent ;
270  Map::iterator found = m_map.find( alg ) ;
271  if ( m_map.end() == found )
272  {
273  MsgStream log( msgSvc() , name() ) ;
274  log << MSG::DEBUG
275  << "Insert non-structural component '"
276  << alg->name() << "' of type '"
277  << System::typeinfoName(typeid(*alg)) << "' at level "
278  << m_indent << endmsg ;
279  std::string nick = alg->name() ;
280  if ( 0 < m_indent ) { nick = std::string ( m_indent , ' ') + nick ; }
281  if ( !m_goodForDOD ) { nick[0]='*' ;}
282  int timer = m_timer->addTimer( nick ) ;
283  m_map.insert ( alg , timer ) ;
284  m_timer->start( timer ) ;
285  return ;
286  }
287  m_timer->start( found->second ) ;
288 }
289 // ============================================================================
291 {
292  if ( 0 == alg ) { return ; }
293  Map::iterator found = m_map.find( alg ) ;
294  if ( m_map.end() == found ) { return ; }
295  m_timer->stop( found->second ) ;
296  --m_indent ;
297 }
298 // ============================================================================
299 void TimingAuditor::before(CustomEventTypeRef evt, const std::string& name)
300 {
301  // Ignore obvious mistakes
302  if ( name.empty() && evt.empty() ) { return; }
303 
304  // look for the user timer in the map
305  int timer = 0;
306  std::string nick = name + ":" + evt;
307  MapUser::iterator found = m_mapUser.find( nick );
308 
309  if ( m_mapUser.end() == found ) {
310  // add a new timer if not yet available
311  timer = m_timer->addTimer( nick ) ;
312  m_mapUser[nick] = timer;
313  }
314  else {
315  timer = found->second;
316  }
317 
318  m_timer->start( timer );
319 }
320 // ============================================================================
321 void TimingAuditor::after(CustomEventTypeRef evt, const std::string& name, const StatusCode &)
322 {
323  // Ignore obvious mistakes
324  if ( name.empty() && evt.empty() ) { return; }
325 
326  // look for the user timer in the map
327  std::string nick = name + ":" + evt;
328  MapUser::iterator found = m_mapUser.find( nick );
329 
330  // We cannot do much if the timer is not available
331  if ( m_mapUser.end() == found ) {
332  MsgStream log(msgSvc(), this->name());
333  log << MSG::WARNING << "Trying to stop the measure of the timing for '"
334  << nick << "' but it was never started. Check the code"
335  << endmsg;
336  return;
337  }
338  m_timer->stop( found->second );
339 }
340 // ============================================================================
342 {
343  if ( IncidentType::BeginEvent == i.type () )
344  {
345  m_timer -> start ( m_map[ m_appMgr ] ) ;
346  ++m_indent ;
347  m_inEvent = true ;
348  }
349  else if ( IncidentType::EndEvent == i.type () )
350  {
351  m_timer -> stop ( m_map[ m_appMgr ] ) ;
352  --m_indent ;
353  m_inEvent = false ;
354  }
355 }
356 // ============================================================================
357 // The END
358 // ============================================================================
const std::string BeginEvent
Processing of a new event has started.
Definition: Incident.h:60
void i_afterInitialize(INamedInterface *alg)
void i_beforeInitialize(INamedInterface *alg)
The interface implemented by the IToolSvc base class.
Definition: IToolSvc.h:17
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
virtual StatusCode finalize()
Definition: Auditor.cpp:213
StatusCode service(const std::string &name, T *&svc, bool createIf=false) const
Access a service by name, creating it if it doesn't already exist.
Definition: Auditor.h:119
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:26
virtual const std::string & name() const
Retrieve the name of the instance.
Definition: Auditor.cpp:218
const std::string & type() const
Access to the incident type.
Definition: Incident.h:34
SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
Definition: Auditor.cpp:226
StandardEventType
Defines the standard (= used by the framework) auditable event types.
Definition: IAuditor.h:24
TimingAuditor & operator=(const TimingAuditor &)
virtual void before(StandardEventType evt, INamedInterface *alg)
The following methods are meant to be implemented by the child class...
IToolSvc * m_toolSvc
tool service
virtual StatusCode initialize()
factory:
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
virtual int addTimer(const std::string &name)=0
add a timer entry with the specified name
virtual ~TimingAuditor()
virtual destructor
bool m_inEvent
"In event" flag
const CustomEventType & CustomEventTypeRef
Used in function calls for optimization purposes.
Definition: IAuditor.h:41
_vector::const_iterator iterator
visible const_iterator (exported)
Definition: VectorMap.h:149
void i_beforeExecute(INamedInterface *alg)
result_type insert(const key_type &key, const mapped_type &mapped)
insert the (key,value) pair into the container
Definition: VectorMap.h:319
extends1 base_class
Typedef to this class.
Definition: extends.h:12
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:85
virtual void handle(const Incident &)
Inform that a new incident has occurred.
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:36
virtual const std::string & name() const =0
Retrieve the name of the instance.
iterator find(const key_type &key) const
find the element by key
Definition: VectorMap.h:457
virtual void before(StandardEventType, INamedInterface *)
The following methods are meant to be implemented by the child class...
Definition: Auditor.cpp:102
int m_indent
indentation level
const std::string EndEvent
Processing of the last event has finished.
Definition: Incident.h:61
Property * declareProperty(const std::string &name, T &property, const std::string &doc="none") const
Declare the named property.
Definition: Auditor.h:235
iterator end() const
"end" iterator for sequential access (const-only version!)
Definition: VectorMap.h:200
iterator end()
Definition: Map.h:131
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:30
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
GaudiUtils::HashMap< std::string, int > MapUser
virtual void saveHistograms()=0
prepares and saves the timing histograms
iterator find(const key_type &key)
Definition: Map.h:148
IIncidentSvc * m_incSvc
incident service
virtual StatusCode finalize()
MapUser m_mapUser
map used to record user timing events
INamedInterface * m_appMgr
ApplicationManager.
void i_beforeFinalize(INamedInterface *alg)
virtual void start(int index)=0
start the counter, i.e.
IInterface compliant class extending IInterface with the name() method.
map_type::iterator iterator
Definition: Map.h:98
virtual unsigned long release()=0
Release Interface instance.
Base class for all Incidents (computing events).
Definition: Incident.h:16
Implements the time measurement inside a sequencer.
void clear()
clear the container
Definition: VectorMap.h:499
virtual void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc)
Audit the end of a standard "event".
ISequencerTimerTool * m_timer
the timer tool
virtual StatusCode initialize()
Definition: Auditor.cpp:97
GaudiUtils::VectorMap< const INamedInterface *, int > Map
bool m_goodForDOD
"optimized for DOD"
list i
Definition: ana.py:128
virtual double stop(int index)=0
stop the counter, return the elapsed time
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:244
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:22
tuple start
Definition: IOTest.py:88
virtual void after(StandardEventType, INamedInterface *, const StatusCode &)
Audit the end of a standard "event".
Definition: Auditor.cpp:122
void i_afterExecute(INamedInterface *alg)
Simple auditor which uses SequencerTimerTool for ALL algorithms, including the algorithm from main Ga...