The Gaudi Framework  v29r0 (ff2e7097)
TimingAuditor.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/Auditor.h"
2 #include "GaudiKernel/HashMap.h"
5 #include "GaudiKernel/IToolSvc.h"
8 // ============================================================================
9 // GaudiAlg
10 // ============================================================================
12 // ============================================================================
13 #ifdef __ICC
14 // disable icc warning #654: overloaded virtual function "B::Y" is only partially overridden in class "C"
15 // TODO: there is only a partial overload of IAuditor::before and IAuditor::after
16 #pragma warning( disable : 654 )
17 #endif
18 
27 class TimingAuditor : public extends<Auditor, IIncidentListener>
28 {
29 public:
30  void before( StandardEventType evt, INamedInterface* alg ) override;
31  void after( StandardEventType evt, INamedInterface* alg, const StatusCode& sc ) override;
32 
33  using Auditor::before; // avoid hiding base-class methods
34  void before( CustomEventTypeRef evt, const std::string& name ) override;
35  using Auditor::after; // avoid hiding base-class methods
36  void after( CustomEventTypeRef evt, const std::string& name, const StatusCode& sc ) override;
37 
38 private:
41  void i_beforeFinalize( INamedInterface* alg );
42  void i_beforeExecute( INamedInterface* alg );
43  void i_afterExecute( INamedInterface* alg );
44 
45 public:
47  void handle( const Incident& ) override;
48 
49 public:
50  StatusCode initialize() override;
51  StatusCode finalize() override;
52 
53 public:
54  using extends::extends;
56  ~TimingAuditor() override = default;
57 
58  // delete default/copy constructor and assignment
59  TimingAuditor() = delete;
60  TimingAuditor( const TimingAuditor& ) = delete;
61  TimingAuditor& operator=( const TimingAuditor& ) = delete;
62 
63 private:
64  // tool service
66  // incident service
68  // the timer tool
70  // ApplicationManager
72  //
74  // indentation level
75  int m_indent = 0;
76  // "in event"
77  bool m_inEvent = false;
78  //
80 
81  // Whether the timing has been saved already
82  bool m_histoSaved = false;
83 
84  Gaudi::Property<bool> m_goodForDOD{this, "OptimizedForDOD", false, "enable optimization for Data-On-Demand Service"};
85 };
86 // ============================================================================
88 // ============================================================================
90 // ============================================================================
92 {
94  if ( sc.isFailure() ) {
95  return sc;
96  } // RETURN
97 
98  // get tool service
99  if ( !m_toolSvc ) {
100  m_toolSvc = Auditor::service( "ToolSvc" );
101  if ( !m_toolSvc ) {
102  error() << "Could not retrieve 'ToolSvc' " << endmsg;
103  return StatusCode::FAILURE; // RETURN
104  }
105  if ( !m_timer ) {
106  sc = m_toolSvc->retrieveTool( "SequencerTimerTool/TIMER", m_timer, this, true );
107  if ( sc.isFailure() ) {
108  error() << "Could not retrieve ISequencerTimerTool" << endmsg;
109  return sc;
110  }
111  }
112  }
113  // get incident service
114  if ( !m_incSvc ) {
115  m_incSvc = Auditor::service( "IncidentSvc" );
116  if ( !m_incSvc ) {
117  error() << "Could not retrieve 'IncidentSvc'" << endmsg;
118  return StatusCode::FAILURE;
119  }
120  m_incSvc->addListener( this, IncidentType::BeginEvent );
121  m_incSvc->addListener( this, IncidentType::EndEvent );
122  }
123  // get the application manager
124  if ( !m_appMgr ) {
125  m_appMgr = Auditor::service( "ApplicationMgr" );
126  if ( !m_appMgr ) {
127  error() << "Could not retrieve 'ApplicationMgr'" << endmsg;
128  return sc;
129  }
130  if ( m_map.end() == m_map.find( m_appMgr.get() ) ) {
131  m_map.insert( m_appMgr.get(), m_timer->addTimer( "EVENT LOOP" ) );
132  }
133  }
134  //
135  return StatusCode::SUCCESS;
136 }
137 // ============================================================================
139 {
140  if ( m_incSvc ) {
141  m_incSvc->removeListener( this, IncidentType::BeginEvent );
142  m_incSvc->removeListener( this, IncidentType::EndEvent );
143  m_incSvc.reset();
144  }
145  if ( m_toolSvc ) {
146  // the 2 following line are commented out: it is
147  // is a temporary hack which prevent a crash due to a problem in
148  // the reference counting
149  // if ( 0 != m_timer )
150  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
151  m_toolSvc.reset();
152  }
153  m_appMgr.reset();
154  // clear the map
155  m_map.clear();
156  // finalize the base class
157  return Auditor::finalize();
158 }
159 // ============================================================================
160 void TimingAuditor::before( StandardEventType evt, INamedInterface* alg )
161 {
162  switch ( evt ) {
164  i_beforeInitialize( alg );
165  break;
166  case IAuditor::Execute:
167  i_beforeExecute( alg );
168  break;
169  case IAuditor::Finalize:
170  i_beforeFinalize( alg );
171  break;
172  default:
173  break;
174  }
175 }
176 // ============================================================================
177 void TimingAuditor::after( StandardEventType evt, INamedInterface* alg, const StatusCode& )
178 {
179  switch ( evt ) {
181  i_afterInitialize( alg );
182  break;
183  case IAuditor::Execute:
184  i_afterExecute( alg );
185  break;
186  default:
187  break;
188  }
189 }
190 // ============================================================================
192 {
193  if ( !m_histoSaved ) {
195  m_histoSaved = true;
196  }
197 }
198 
199 // ============================================================================
201 {
202  if ( m_goodForDOD ) {
203  return;
204  }
205  //
206  if ( !alg ) {
207  return;
208  }
209  auto found = m_map.find( alg );
210  if ( m_map.end() != found ) {
211  return;
212  }
213  ++m_indent;
214  std::string nick = alg->name();
215  if ( 0 < m_indent ) {
216  nick = std::string( m_indent, ' ' ) + nick;
217  }
218  if ( m_inEvent ) {
219  nick[0] = '*';
220  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
221  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
222  }
223  int timer = m_timer->addTimer( nick );
224  m_map.insert( alg, timer );
225  m_timer->start( timer );
226 }
227 // ============================================================================
229 {
230  if ( m_goodForDOD || !alg ) {
231  return;
232  }
233  --m_indent;
234 }
235 // ============================================================================
237 {
238  if ( !alg ) {
239  return;
240  }
241  ++m_indent;
242  auto found = m_map.find( alg );
243  if ( m_map.end() == found ) {
244  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
245  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
246  std::string nick = alg->name();
247  if ( 0 < m_indent ) {
248  nick = std::string( m_indent, ' ' ) + nick;
249  }
250  if ( !m_goodForDOD ) {
251  nick[0] = '*';
252  }
253  int timer = m_timer->addTimer( nick );
254  m_map.insert( alg, timer );
255  m_timer->start( timer );
256  return;
257  }
258  m_timer->start( found->second );
259 }
260 // ============================================================================
262 {
263  if ( !alg ) {
264  return;
265  }
266  auto found = m_map.find( alg );
267  if ( m_map.end() == found ) {
268  return;
269  }
270  m_timer->stop( found->second );
271  --m_indent;
272 }
273 // ============================================================================
274 void TimingAuditor::before( CustomEventTypeRef evt, const std::string& name )
275 {
276  // Ignore obvious mistakes
277  if ( name.empty() && evt.empty() ) {
278  return;
279  }
280 
281  // look for the user timer in the map
282  int timer = 0;
283  std::string nick = name + ":" + evt;
284  auto found = m_mapUser.find( nick );
285 
286  if ( m_mapUser.end() == found ) {
287  // add a new timer if not yet available
288  timer = m_timer->addTimer( nick );
289  m_mapUser[nick] = timer;
290  } else {
291  timer = found->second;
292  }
293  m_timer->start( timer );
294 }
295 // ============================================================================
296 void TimingAuditor::after( CustomEventTypeRef evt, const std::string& name, const StatusCode& )
297 {
298  // Ignore obvious mistakes
299  if ( name.empty() && evt.empty() ) {
300  return;
301  }
302 
303  // look for the user timer in the map
304  std::string nick = name + ":" + evt;
305  auto found = m_mapUser.find( nick );
306 
307  // We cannot do much if the timer is not available
308  if ( m_mapUser.end() == found ) {
309  warning() << "Trying to stop the measure of the timing for '" << nick
310  << "' but it was never started. Check the code" << endmsg;
311  return;
312  }
313  m_timer->stop( found->second );
314 }
315 // ============================================================================
317 {
318  if ( IncidentType::BeginEvent == i.type() ) {
319  m_timer->start( m_map[m_appMgr.get()] );
320  ++m_indent;
321  m_inEvent = true;
322  } else if ( IncidentType::EndEvent == i.type() ) {
323  m_timer->stop( m_map[m_appMgr.get()] );
324  --m_indent;
325  m_inEvent = false;
326  }
327 }
328 // ============================================================================
329 // The END
330 // ============================================================================
void i_afterInitialize(INamedInterface *alg)
void i_beforeInitialize(INamedInterface *alg)
GaudiUtils::HashMap< std::string, int > m_mapUser
map used to record user timing events
TimingAuditor & operator=(const TimingAuditor &)=delete
virtual StatusCode finalize()
Definition: Auditor.cpp:200
T empty(T...args)
StatusCode service(const std::string &name, T *&svc, bool createIf=false) const
Access a service by name, creating it if it doesn&#39;t already exist.
Definition: Auditor.h:109
const std::string & type() const
Access to the incident type.
Definition: Incident.h:41
Implementation of property with value of concrete type.
Definition: Property.h:319
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:329
virtual int addTimer(const std::string &name)=0
add a timer entry with the specified name
bool m_inEvent
"In event" flag
GaudiUtils::VectorMap< const INamedInterface *, int > m_map
StatusCode finalize() override
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:312
void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc) override
bool isFailure() const
Test for a status code of FAILURE.
Definition: StatusCode.h:86
StatusCode retrieveTool(const std::string &type, T *&tool, const IInterface *parent=nullptr, bool createIf=true)
Retrieve specified tool sub-type with tool dependent part of the name automatically assigned...
Definition: IToolSvc.h:139
#define DECLARE_COMPONENT(type)
Definition: PluginService.h:33
STL class.
StatusCode initialize() override
factory:
iterator find(const key_type &key) const
find the element by key
Definition: VectorMap.h:449
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:82
int m_indent
indentation level
iterator end() const
"end" iterator for sequential access (const-only version!)
Definition: VectorMap.h:191
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
iterator end()
Definition: Map.h:134
SmartIF< INamedInterface > m_appMgr
ApplicationManager.
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
SmartIF< IIncidentSvc > m_incSvc
incident service
void before(StandardEventType evt, INamedInterface *alg) override
virtual void saveHistograms()=0
prepares and saves the timing histograms
iterator find(const key_type &key)
Definition: Map.h:151
void after(StandardEventType, INamedInterface *, const StatusCode &) override
Definition: Auditor.cpp:110
~TimingAuditor() override=default
destructor
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.
TimingAuditor()=delete
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
Base class for all Incidents (computing events).
Definition: Incident.h:17
virtual void addListener(IIncidentListener *lis, const std::string &type="", long priority=0, bool rethrow=false, bool singleShot=false)=0
Add listener.
Implements the time measurement inside a sequencer.
void clear()
clear the container
Definition: VectorMap.h:488
SmartIF< IToolSvc > m_toolSvc
tool service
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:92
ISequencerTimerTool * m_timer
the timer tool
virtual StatusCode initialize()
Definition: Auditor.cpp:70
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
void handle(const Incident &) override
Inform that a new incident has occurred.
virtual double stop(int index)=0
stop the counter, return the elapsed time
Gaudi::Property< bool > m_goodForDOD
void before(StandardEventType, INamedInterface *) override
The following methods are meant to be implemented by the child class...
Definition: Auditor.cpp:73
const std::string & name() const override
Definition: Auditor.cpp:202
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
virtual const std::string & name() const =0
Retrieve the name of the instance.
evt
Definition: IOTest.py:96
void i_afterExecute(INamedInterface *alg)
Simple auditor which uses SequencerTimerTool for ALL algorithms, including the algorithm from main Ga...