Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 public:
29  void before( StandardEventType evt, INamedInterface* alg ) override;
30  void after( StandardEventType evt, INamedInterface* alg, const StatusCode& sc ) override;
31 
32  using Auditor::before; // avoid hiding base-class methods
33  void before( CustomEventTypeRef evt, const std::string& name ) override;
34  using Auditor::after; // avoid hiding base-class methods
35  void after( CustomEventTypeRef evt, const std::string& name, const StatusCode& sc ) override;
36 
37 private:
40  void i_beforeFinalize( INamedInterface* alg );
41  void i_beforeExecute( INamedInterface* alg );
42  void i_afterExecute( INamedInterface* alg );
43 
44 public:
46  void handle( const Incident& ) override;
47 
48 public:
49  StatusCode initialize() override;
50  StatusCode finalize() override;
51 
52 public:
53  using extends::extends;
54 
55  // delete default/copy constructor and assignment
56  TimingAuditor() = delete;
57  TimingAuditor( const TimingAuditor& ) = delete;
58  TimingAuditor& operator=( const TimingAuditor& ) = delete;
59 
60 private:
61  // tool service
63  // incident service
65  // the timer tool
67  // ApplicationManager
69  //
71  // indentation level
72  int m_indent = 0;
73  // "in event"
74  bool m_inEvent = false;
75  //
77 
78  // Whether the timing has been saved already
79  bool m_histoSaved = false;
80 
81  Gaudi::Property<bool> m_goodForDOD{this, "OptimizedForDOD", false, "enable optimization for Data-On-Demand Service"};
82 };
83 // ============================================================================
85 // ============================================================================
87 // ============================================================================
90  if ( sc.isFailure() ) { return sc; } // RETURN
91 
92  // get tool service
93  if ( !m_toolSvc ) {
94  m_toolSvc = Auditor::service( "ToolSvc" );
95  if ( !m_toolSvc ) {
96  error() << "Could not retrieve 'ToolSvc' " << endmsg;
97  return StatusCode::FAILURE; // RETURN
98  }
99  if ( !m_timer ) {
100  sc = m_toolSvc->retrieveTool( "SequencerTimerTool/TIMER", m_timer, this, true );
101  if ( sc.isFailure() ) {
102  error() << "Could not retrieve ISequencerTimerTool" << endmsg;
103  return sc;
104  }
105  }
106  }
107  // get incident service
108  if ( !m_incSvc ) {
109  m_incSvc = Auditor::service( "IncidentSvc" );
110  if ( !m_incSvc ) {
111  error() << "Could not retrieve 'IncidentSvc'" << endmsg;
112  return StatusCode::FAILURE;
113  }
114  m_incSvc->addListener( this, IncidentType::BeginEvent );
115  m_incSvc->addListener( this, IncidentType::EndEvent );
116  }
117  // get the application manager
118  if ( !m_appMgr ) {
119  m_appMgr = Auditor::service( "ApplicationMgr" );
120  if ( !m_appMgr ) {
121  error() << "Could not retrieve 'ApplicationMgr'" << endmsg;
122  return sc;
123  }
124  if ( m_map.end() == m_map.find( m_appMgr.get() ) ) {
125  m_map.insert( m_appMgr.get(), m_timer->addTimer( "EVENT LOOP" ) );
126  }
127  }
128  //
129  return StatusCode::SUCCESS;
130 }
131 // ============================================================================
133  if ( m_incSvc ) {
134  m_incSvc->removeListener( this, IncidentType::BeginEvent );
135  m_incSvc->removeListener( this, IncidentType::EndEvent );
136  m_incSvc.reset();
137  }
138  if ( m_toolSvc ) {
139  // the 2 following line are commented out: it is
140  // is a temporary hack which prevent a crash due to a problem in
141  // the reference counting
142  // if ( 0 != m_timer )
143  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
144  m_toolSvc.reset();
145  }
146  m_appMgr.reset();
147  // clear the map
148  m_map.clear();
149  // finalize the base class
150  return Auditor::finalize();
151 }
152 // ============================================================================
153 void TimingAuditor::before( StandardEventType evt, INamedInterface* alg ) {
154  switch ( evt ) {
156  i_beforeInitialize( alg );
157  break;
158  case IAuditor::Execute:
159  i_beforeExecute( alg );
160  break;
161  case IAuditor::Finalize:
162  i_beforeFinalize( alg );
163  break;
164  default:
165  break;
166  }
167 }
168 // ============================================================================
169 void TimingAuditor::after( StandardEventType evt, INamedInterface* alg, const StatusCode& ) {
170  switch ( evt ) {
172  i_afterInitialize( alg );
173  break;
174  case IAuditor::Execute:
175  i_afterExecute( alg );
176  break;
177  default:
178  break;
179  }
180 }
181 // ============================================================================
183  if ( !m_histoSaved ) {
185  m_histoSaved = true;
186  }
187 }
188 
189 // ============================================================================
191  if ( m_goodForDOD ) { return; }
192  //
193  if ( !alg ) { return; }
194  auto found = m_map.find( alg );
195  if ( m_map.end() != found ) { return; }
196  ++m_indent;
197  std::string nick = alg->name();
198  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
199  if ( m_inEvent ) {
200  nick[0] = '*';
201  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
202  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
203  }
204  int timer = m_timer->addTimer( nick );
205  m_map.insert( alg, timer );
206  m_timer->start( timer );
207 }
208 // ============================================================================
210  if ( m_goodForDOD || !alg ) { return; }
211  --m_indent;
212 }
213 // ============================================================================
215  if ( !alg ) { return; }
216  ++m_indent;
217  auto found = m_map.find( alg );
218  if ( m_map.end() == found ) {
219  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
220  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
221  std::string nick = alg->name();
222  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
223  if ( !m_goodForDOD ) { nick[0] = '*'; }
224  int timer = m_timer->addTimer( nick );
225  m_map.insert( alg, timer );
226  m_timer->start( timer );
227  return;
228  }
229  m_timer->start( found->second );
230 }
231 // ============================================================================
233  if ( !alg ) { return; }
234  auto found = m_map.find( alg );
235  if ( m_map.end() == found ) { return; }
236  m_timer->stop( found->second );
237  --m_indent;
238 }
239 // ============================================================================
240 void TimingAuditor::before( CustomEventTypeRef evt, const std::string& name ) {
241  // Ignore obvious mistakes
242  if ( name.empty() && evt.empty() ) { return; }
243 
244  // look for the user timer in the map
245  int timer = 0;
246  std::string nick = name + ":" + evt;
247  auto found = m_mapUser.find( nick );
248 
249  if ( m_mapUser.end() == found ) {
250  // add a new timer if not yet available
251  timer = m_timer->addTimer( nick );
252  m_mapUser[nick] = timer;
253  } else {
254  timer = found->second;
255  }
256  m_timer->start( timer );
257 }
258 // ============================================================================
259 void TimingAuditor::after( CustomEventTypeRef evt, const std::string& name, const StatusCode& ) {
260  // Ignore obvious mistakes
261  if ( name.empty() && evt.empty() ) { return; }
262 
263  // look for the user timer in the map
264  std::string nick = name + ":" + evt;
265  auto found = m_mapUser.find( nick );
266 
267  // We cannot do much if the timer is not available
268  if ( m_mapUser.end() == found ) {
269  warning() << "Trying to stop the measure of the timing for '" << nick
270  << "' but it was never started. Check the code" << endmsg;
271  return;
272  }
273  m_timer->stop( found->second );
274 }
275 // ============================================================================
276 void TimingAuditor::handle( const Incident& i ) {
277  if ( IncidentType::BeginEvent == i.type() ) {
278  m_timer->start( m_map[m_appMgr.get()] );
279  ++m_indent;
280  m_inEvent = true;
281  } else if ( IncidentType::EndEvent == i.type() ) {
282  m_timer->stop( m_map[m_appMgr.get()] );
283  --m_indent;
284  m_inEvent = false;
285  }
286 }
287 // ============================================================================
288 // The END
289 // ============================================================================
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:191
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:105
const std::string & type() const
Access to the incident type.
Definition: Incident.h:38
Implementation of property with value of concrete type.
Definition: Property.h:352
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:309
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
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
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:302
void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc) override
bool isFailure() const
Definition: StatusCode.h:130
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:138
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:430
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
int m_indent
indentation level
iterator end() const
"end" iterator for sequential access (const-only version!)
Definition: VectorMap.h:188
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
iterator end()
Definition: Map.h:130
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:50
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:147
void after(StandardEventType, INamedInterface *, const StatusCode &) override
Definition: Auditor.cpp:103
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.
constexpr static const auto FAILURE
Definition: StatusCode.h:86
void clear()
clear the container
Definition: VectorMap.h:466
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:86
ISequencerTimerTool * m_timer
the timer tool
virtual StatusCode initialize()
Definition: Auditor.cpp:64
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:67
const std::string & name() const override
Definition: Auditor.cpp:193
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
virtual const std::string & name() const =0
Retrieve the name of the instance.
evt
Definition: IOTest.py:94
void i_afterExecute(INamedInterface *alg)
Simple auditor which uses SequencerTimerTool for ALL algorithms, including the algorithm from main Ga...