The Gaudi Framework  v30r3 (a5ef0a68)
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;
55 
56  // delete default/copy constructor and assignment
57  TimingAuditor() = delete;
58  TimingAuditor( const TimingAuditor& ) = delete;
59  TimingAuditor& operator=( const TimingAuditor& ) = delete;
60 
61 private:
62  // tool service
64  // incident service
66  // the timer tool
68  // ApplicationManager
70  //
72  // indentation level
73  int m_indent = 0;
74  // "in event"
75  bool m_inEvent = false;
76  //
78 
79  // Whether the timing has been saved already
80  bool m_histoSaved = false;
81 
82  Gaudi::Property<bool> m_goodForDOD{this, "OptimizedForDOD", false, "enable optimization for Data-On-Demand Service"};
83 };
84 // ============================================================================
86 // ============================================================================
88 // ============================================================================
90 {
92  if ( sc.isFailure() ) {
93  return sc;
94  } // RETURN
95 
96  // get tool service
97  if ( !m_toolSvc ) {
98  m_toolSvc = Auditor::service( "ToolSvc" );
99  if ( !m_toolSvc ) {
100  error() << "Could not retrieve 'ToolSvc' " << endmsg;
101  return StatusCode::FAILURE; // RETURN
102  }
103  if ( !m_timer ) {
104  sc = m_toolSvc->retrieveTool( "SequencerTimerTool/TIMER", m_timer, this, true );
105  if ( sc.isFailure() ) {
106  error() << "Could not retrieve ISequencerTimerTool" << endmsg;
107  return sc;
108  }
109  }
110  }
111  // get incident service
112  if ( !m_incSvc ) {
113  m_incSvc = Auditor::service( "IncidentSvc" );
114  if ( !m_incSvc ) {
115  error() << "Could not retrieve 'IncidentSvc'" << endmsg;
116  return StatusCode::FAILURE;
117  }
118  m_incSvc->addListener( this, IncidentType::BeginEvent );
119  m_incSvc->addListener( this, IncidentType::EndEvent );
120  }
121  // get the application manager
122  if ( !m_appMgr ) {
123  m_appMgr = Auditor::service( "ApplicationMgr" );
124  if ( !m_appMgr ) {
125  error() << "Could not retrieve 'ApplicationMgr'" << endmsg;
126  return sc;
127  }
128  if ( m_map.end() == m_map.find( m_appMgr.get() ) ) {
129  m_map.insert( m_appMgr.get(), m_timer->addTimer( "EVENT LOOP" ) );
130  }
131  }
132  //
133  return StatusCode::SUCCESS;
134 }
135 // ============================================================================
137 {
138  if ( m_incSvc ) {
139  m_incSvc->removeListener( this, IncidentType::BeginEvent );
140  m_incSvc->removeListener( this, IncidentType::EndEvent );
141  m_incSvc.reset();
142  }
143  if ( m_toolSvc ) {
144  // the 2 following line are commented out: it is
145  // is a temporary hack which prevent a crash due to a problem in
146  // the reference counting
147  // if ( 0 != m_timer )
148  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
149  m_toolSvc.reset();
150  }
151  m_appMgr.reset();
152  // clear the map
153  m_map.clear();
154  // finalize the base class
155  return Auditor::finalize();
156 }
157 // ============================================================================
158 void TimingAuditor::before( StandardEventType evt, INamedInterface* alg )
159 {
160  switch ( evt ) {
162  i_beforeInitialize( alg );
163  break;
164  case IAuditor::Execute:
165  i_beforeExecute( alg );
166  break;
167  case IAuditor::Finalize:
168  i_beforeFinalize( alg );
169  break;
170  default:
171  break;
172  }
173 }
174 // ============================================================================
175 void TimingAuditor::after( StandardEventType evt, INamedInterface* alg, const StatusCode& )
176 {
177  switch ( evt ) {
179  i_afterInitialize( alg );
180  break;
181  case IAuditor::Execute:
182  i_afterExecute( alg );
183  break;
184  default:
185  break;
186  }
187 }
188 // ============================================================================
190 {
191  if ( !m_histoSaved ) {
193  m_histoSaved = true;
194  }
195 }
196 
197 // ============================================================================
199 {
200  if ( m_goodForDOD ) {
201  return;
202  }
203  //
204  if ( !alg ) {
205  return;
206  }
207  auto found = m_map.find( alg );
208  if ( m_map.end() != found ) {
209  return;
210  }
211  ++m_indent;
212  std::string nick = alg->name();
213  if ( 0 < m_indent ) {
214  nick = std::string( m_indent, ' ' ) + nick;
215  }
216  if ( m_inEvent ) {
217  nick[0] = '*';
218  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
219  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
220  }
221  int timer = m_timer->addTimer( nick );
222  m_map.insert( alg, timer );
223  m_timer->start( timer );
224 }
225 // ============================================================================
227 {
228  if ( m_goodForDOD || !alg ) {
229  return;
230  }
231  --m_indent;
232 }
233 // ============================================================================
235 {
236  if ( !alg ) {
237  return;
238  }
239  ++m_indent;
240  auto found = m_map.find( alg );
241  if ( m_map.end() == found ) {
242  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
243  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
244  std::string nick = alg->name();
245  if ( 0 < m_indent ) {
246  nick = std::string( m_indent, ' ' ) + nick;
247  }
248  if ( !m_goodForDOD ) {
249  nick[0] = '*';
250  }
251  int timer = m_timer->addTimer( nick );
252  m_map.insert( alg, timer );
253  m_timer->start( timer );
254  return;
255  }
256  m_timer->start( found->second );
257 }
258 // ============================================================================
260 {
261  if ( !alg ) {
262  return;
263  }
264  auto found = m_map.find( alg );
265  if ( m_map.end() == found ) {
266  return;
267  }
268  m_timer->stop( found->second );
269  --m_indent;
270 }
271 // ============================================================================
272 void TimingAuditor::before( CustomEventTypeRef evt, const std::string& name )
273 {
274  // Ignore obvious mistakes
275  if ( name.empty() && evt.empty() ) {
276  return;
277  }
278 
279  // look for the user timer in the map
280  int timer = 0;
281  std::string nick = name + ":" + evt;
282  auto found = m_mapUser.find( nick );
283 
284  if ( m_mapUser.end() == found ) {
285  // add a new timer if not yet available
286  timer = m_timer->addTimer( nick );
287  m_mapUser[nick] = timer;
288  } else {
289  timer = found->second;
290  }
291  m_timer->start( timer );
292 }
293 // ============================================================================
294 void TimingAuditor::after( CustomEventTypeRef evt, const std::string& name, const StatusCode& )
295 {
296  // Ignore obvious mistakes
297  if ( name.empty() && evt.empty() ) {
298  return;
299  }
300 
301  // look for the user timer in the map
302  std::string nick = name + ":" + evt;
303  auto found = m_mapUser.find( nick );
304 
305  // We cannot do much if the timer is not available
306  if ( m_mapUser.end() == found ) {
307  warning() << "Trying to stop the measure of the timing for '" << nick
308  << "' but it was never started. Check the code" << endmsg;
309  return;
310  }
311  m_timer->stop( found->second );
312 }
313 // ============================================================================
315 {
316  if ( IncidentType::BeginEvent == i.type() ) {
317  m_timer->start( m_map[m_appMgr.get()] );
318  ++m_indent;
319  m_inEvent = true;
320  } else if ( IncidentType::EndEvent == i.type() ) {
321  m_timer->stop( m_map[m_appMgr.get()] );
322  --m_indent;
323  m_inEvent = false;
324  }
325 }
326 // ============================================================================
327 // The END
328 // ============================================================================
void i_afterInitialize(INamedInterface *alg)
void i_beforeInitialize(INamedInterface *alg)
GaudiUtils::HashMap< std::string, int > m_mapUser
map used to record user timing events
constexpr static const auto FAILURE
Definition: StatusCode.h:88
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:107
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:381
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:332
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
Definition: StatusCode.h:139
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
STL class.
StatusCode initialize() override
factory:
#define DECLARE_COMPONENT(type)
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:51
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
constexpr static const auto SUCCESS
Definition: StatusCode.h:87
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...