Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v36r16 (ea80daf8)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
TimingAuditor.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include "GaudiKernel/Auditor.h"
12 #include "GaudiKernel/HashMap.h"
15 #include "GaudiKernel/IToolSvc.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/VectorMap.h"
18 // ============================================================================
19 // GaudiAlg
20 // ============================================================================
22 // ============================================================================
23 #ifdef __ICC
24 // disable icc warning #654: overloaded virtual function "B::Y" is only partially overridden in class "C"
25 // TODO: there is only a partial overload of IAuditor::before and IAuditor::after
26 # pragma warning( disable : 654 )
27 #endif
28 
37 class TimingAuditor : public extends<Auditor, IIncidentListener> {
38 public:
39  void before( StandardEventType evt, INamedInterface* alg ) override;
40  void after( StandardEventType evt, INamedInterface* alg, const StatusCode& sc ) override;
41 
42  using Auditor::before; // avoid hiding base-class methods
43  void before( CustomEventTypeRef evt, const std::string& name ) override;
44  using Auditor::after; // avoid hiding base-class methods
45  void after( CustomEventTypeRef evt, const std::string& name, const StatusCode& sc ) override;
46 
47 private:
53 
54 public:
56  void handle( const Incident& ) override;
57 
58 public:
59  StatusCode initialize() override;
60  StatusCode finalize() override;
61 
62 public:
63  using extends::extends;
64 
65  // delete default/copy constructor and assignment
66  TimingAuditor() = delete;
67  TimingAuditor( const TimingAuditor& ) = delete;
68  TimingAuditor& operator=( const TimingAuditor& ) = delete;
69 
70 private:
71  // tool service
73  // incident service
75  // the timer tool
77  // ApplicationManager
79  //
81  // indentation level
82  int m_indent = 0;
83  // "in event"
84  bool m_inEvent = false;
85  //
87 
88  // Whether the timing has been saved already
89  bool m_histoSaved = false;
90 
91  Gaudi::Property<bool> m_goodForDOD{ this, "OptimizedForDOD", false,
92  "enable optimization for Data-On-Demand Service" };
93 };
94 // ============================================================================
96 // ============================================================================
98 // ============================================================================
99 StatusCode TimingAuditor::initialize() {
101  if ( sc.isFailure() ) { return sc; } // RETURN
102 
103  // get tool service
104  if ( !m_toolSvc ) {
105  m_toolSvc = Auditor::service( "ToolSvc" );
106  if ( !m_toolSvc ) {
107  error() << "Could not retrieve 'ToolSvc' " << endmsg;
108  return StatusCode::FAILURE; // RETURN
109  }
110  if ( !m_timer ) {
111  sc = m_toolSvc->retrieveTool( "SequencerTimerTool/TIMER", m_timer, this, true );
112  if ( sc.isFailure() ) {
113  error() << "Could not retrieve ISequencerTimerTool" << endmsg;
114  return sc;
115  }
116  }
117  }
118  // get incident service
119  if ( !m_incSvc ) {
120  m_incSvc = Auditor::service( "IncidentSvc" );
121  if ( !m_incSvc ) {
122  error() << "Could not retrieve 'IncidentSvc'" << endmsg;
123  return StatusCode::FAILURE;
124  }
125  m_incSvc->addListener( this, IncidentType::BeginEvent );
126  m_incSvc->addListener( this, IncidentType::EndEvent );
127  }
128  // get the application manager
129  if ( !m_appMgr ) {
130  m_appMgr = Auditor::service( "ApplicationMgr" );
131  if ( !m_appMgr ) {
132  error() << "Could not retrieve 'ApplicationMgr'" << endmsg;
133  return sc;
134  }
135  if ( m_map.end() == m_map.find( m_appMgr.get() ) ) {
136  m_map.insert( m_appMgr.get(), m_timer->addTimer( "EVENT LOOP" ) );
137  }
138  }
139  //
140  return StatusCode::SUCCESS;
141 }
142 // ============================================================================
144  if ( m_incSvc ) {
145  m_incSvc->removeListener( this, IncidentType::BeginEvent );
146  m_incSvc->removeListener( this, IncidentType::EndEvent );
147  m_incSvc.reset();
148  }
149  if ( m_toolSvc ) {
150  // the 2 following line are commented out: it is
151  // is a temporary hack which prevent a crash due to a problem in
152  // the reference counting
153  // if ( 0 != m_timer )
154  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
155  m_toolSvc.reset();
156  }
157  m_appMgr.reset();
158  // clear the map
159  m_map.clear();
160  // finalize the base class
161  return Auditor::finalize();
162 }
163 // ============================================================================
164 void TimingAuditor::before( StandardEventType evt, INamedInterface* alg ) {
165  switch ( evt ) {
168  break;
169  case IAuditor::Execute:
170  i_beforeExecute( alg );
171  break;
172  case IAuditor::Finalize:
174  break;
175  default:
176  break;
177  }
178 }
179 // ============================================================================
180 void TimingAuditor::after( StandardEventType evt, INamedInterface* alg, const StatusCode& ) {
181  switch ( evt ) {
184  break;
185  case IAuditor::Execute:
186  i_afterExecute( alg );
187  break;
188  default:
189  break;
190  }
191 }
192 // ============================================================================
194  if ( !m_histoSaved ) {
196  m_histoSaved = true;
197  }
198 }
199 
200 // ============================================================================
202  if ( m_goodForDOD ) { return; }
203  //
204  if ( !alg ) { return; }
205  auto found = m_map.find( alg );
206  if ( m_map.end() != found ) { return; }
207  ++m_indent;
208  std::string nick = alg->name();
209  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
210  if ( m_inEvent ) {
211  nick[0] = '*';
212  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
213  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
214  }
215  int timer = m_timer->addTimer( nick );
216  m_map.insert( alg, timer );
217  m_timer->start( timer );
218 }
219 // ============================================================================
221  if ( m_goodForDOD || !alg ) { return; }
222  --m_indent;
223 }
224 // ============================================================================
226  if ( !alg ) { return; }
227  ++m_indent;
228  auto found = m_map.find( alg );
229  if ( m_map.end() == found ) {
230  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
231  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
232  std::string nick = alg->name();
233  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
234  if ( !m_goodForDOD ) { nick[0] = '*'; }
235  int timer = m_timer->addTimer( nick );
236  m_map.insert( alg, timer );
237  m_timer->start( timer );
238  return;
239  }
240  m_timer->start( found->second );
241 }
242 // ============================================================================
244  if ( !alg ) { return; }
245  auto found = m_map.find( alg );
246  if ( m_map.end() == found ) { return; }
247  m_timer->stop( found->second );
248  --m_indent;
249 }
250 // ============================================================================
251 void TimingAuditor::before( CustomEventTypeRef evt, const std::string& name ) {
252  // Ignore obvious mistakes
253  if ( name.empty() && evt.empty() ) { return; }
254 
255  // look for the user timer in the map
256  int timer = 0;
257  std::string nick = std::string{ name }.append( ":" ).append( evt );
258  auto found = m_mapUser.find( nick );
259 
260  if ( m_mapUser.end() == found ) {
261  // add a new timer if not yet available
262  timer = m_timer->addTimer( nick );
263  m_mapUser[nick] = timer;
264  } else {
265  timer = found->second;
266  }
267  m_timer->start( timer );
268 }
269 // ============================================================================
270 void TimingAuditor::after( CustomEventTypeRef evt, const std::string& name, const StatusCode& ) {
271  // Ignore obvious mistakes
272  if ( name.empty() && evt.empty() ) { return; }
273 
274  // look for the user timer in the map
275  std::string nick = std::string{ name }.append( ":" ).append( evt );
276  auto found = m_mapUser.find( nick );
277 
278  // We cannot do much if the timer is not available
279  if ( m_mapUser.end() == found ) {
280  warning() << "Trying to stop the measure of the timing for '" << nick
281  << "' but it was never started. Check the code" << endmsg;
282  return;
283  }
284  m_timer->stop( found->second );
285 }
286 // ============================================================================
287 void TimingAuditor::handle( const Incident& i ) {
288  if ( IncidentType::BeginEvent == i.type() ) {
289  m_timer->start( m_map[m_appMgr.get()] );
290  ++m_indent;
291  m_inEvent = true;
292  } else if ( IncidentType::EndEvent == i.type() ) {
293  m_timer->stop( m_map[m_appMgr.get()] );
294  --m_indent;
295  m_inEvent = false;
296  }
297 }
298 // ============================================================================
299 // The END
300 // ============================================================================
IOTest.evt
evt
Definition: IOTest.py:105
std::string
STL class.
TimingAuditor::m_appMgr
SmartIF< INamedInterface > m_appMgr
ApplicationManager.
Definition: TimingAuditor.cpp:78
IAuditor::Execute
@ Execute
Definition: IAuditor.h:34
GaudiUtils::Map::find
iterator find(const key_type &key)
Definition: Map.h:157
SmartIF::reset
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:96
GaudiUtils::VectorMap< const INamedInterface *, int >
Auditor::before
void before(StandardEventType, INamedInterface *) override
The following methods are meant to be implemented by the child class...
Definition: Auditor.cpp:82
TimingAuditor::initialize
StatusCode initialize() override
factory:
Definition: TimingAuditor.cpp:99
ISequencerTimerTool
Definition: ISequencerTimerTool.h:24
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:313
TimingAuditor::m_histoSaved
bool m_histoSaved
Definition: TimingAuditor.cpp:89
TimingAuditor::m_goodForDOD
Gaudi::Property< bool > m_goodForDOD
Definition: TimingAuditor.cpp:91
HashMap.h
Auditor::finalize
virtual StatusCode finalize()
Definition: Auditor.cpp:190
GaudiUtils::VectorMap::clear
void clear()
clear the container
Definition: VectorMap.h:476
basic.alg
alg
Definition: basic.py:15
TimingAuditor::m_toolSvc
SmartIF< IToolSvc > m_toolSvc
tool service
Definition: TimingAuditor.cpp:72
IIncidentSvc.h
Auditor::initialize
virtual StatusCode initialize()
Definition: Auditor.cpp:79
IToolSvc.h
Auditor::name
const std::string & name() const override
Definition: Auditor.cpp:192
IAuditor::Finalize
@ Finalize
Definition: IAuditor.h:34
TimingAuditor::m_inEvent
bool m_inEvent
"In event" flag
Definition: TimingAuditor.cpp:84
TimingAuditor::i_beforeFinalize
void i_beforeFinalize(INamedInterface *alg)
Definition: TimingAuditor.cpp:193
VectorMap.h
TimingAuditor::operator=
TimingAuditor & operator=(const TimingAuditor &)=delete
Auditor::after
void after(StandardEventType, INamedInterface *, const StatusCode &) override
Definition: Auditor.cpp:112
TimingHistograms.name
name
Definition: TimingHistograms.py:25
StatusCode
Definition: StatusCode.h:65
TimingAuditor::TimingAuditor
TimingAuditor()=delete
TimingAuditor::finalize
StatusCode finalize() override
Definition: TimingAuditor.cpp:143
ISequencerTimerTool::saveHistograms
virtual void saveHistograms()=0
prepares and saves the timing histograms
IAuditor::Initialize
@ Initialize
Definition: IAuditor.h:34
GaudiUtils::VectorMap::end
iterator end() const
"end" iterator for sequential access (const-only version!)
Definition: VectorMap.h:198
TimingAuditor::m_map
GaudiUtils::VectorMap< const INamedInterface *, int > m_map
Definition: TimingAuditor.cpp:80
SmartIF< IToolSvc >
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:203
TimingAuditor::TimingAuditor
TimingAuditor(const TimingAuditor &)=delete
extends
Base class used to extend a class implementing other interfaces.
Definition: extends.h:20
ISequencerTimerTool::start
virtual void start(int index)=0
start the counter, i.e.
std::string::append
T append(T... args)
GaudiUtils::Map::end
iterator end()
Definition: Map.h:140
TimingAuditor::i_afterInitialize
void i_afterInitialize(INamedInterface *alg)
Definition: TimingAuditor.cpp:220
TimingAuditor::m_mapUser
GaudiUtils::HashMap< std::string, int > m_mapUser
map used to record user timing events
Definition: TimingAuditor.cpp:86
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:129
INamedInterface
Definition: INamedInterface.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
SmartIF::get
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:86
TimingAuditor::i_afterExecute
void i_afterExecute(INamedInterface *alg)
Definition: TimingAuditor.cpp:243
IIncidentListener.h
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
GaudiUtils::VectorMap::insert
result_type insert(const key_type &key, const mapped_type &mapped)
insert the (key,value) pair into the container
Definition: VectorMap.h:312
std::string::empty
T empty(T... args)
ISequencerTimerTool.h
Incident::type
const std::string & type() const
Access to the incident type.
Definition: Incident.h:48
TimingAuditor
Definition: TimingAuditor.cpp:37
TimingAuditor::i_beforeExecute
void i_beforeExecute(INamedInterface *alg)
Definition: TimingAuditor.cpp:225
GaudiUtils::HashMap< std::string, int >
TimingAuditor::before
void before(StandardEventType evt, INamedInterface *alg) override
Definition: TimingAuditor.cpp:164
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
TimingAuditor::i_beforeInitialize
void i_beforeInitialize(INamedInterface *alg)
Definition: TimingAuditor.cpp:201
TimingAuditor::m_indent
int m_indent
indentation level
Definition: TimingAuditor.cpp:82
TimingAuditor::after
void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc) override
Definition: TimingAuditor.cpp:180
Incident
Definition: Incident.h:27
Auditor::service
StatusCode service(std::string_view name, T *&svc, bool createIf=false) const
Access a service by name, creating it if it doesn't already exist.
Definition: Auditor.h:109
GaudiUtils::VectorMap::find
iterator find(const key_type &key) const
find the element by key
Definition: VectorMap.h:440
TimingAuditor::m_timer
ISequencerTimerTool * m_timer
the timer tool
Definition: TimingAuditor.cpp:76
Gaudi::Property< bool >
ISequencerTimerTool::stop
virtual double stop(int index)=0
stop the counter, return the elapsed time
TimingAuditor::m_incSvc
SmartIF< IIncidentSvc > m_incSvc
incident service
Definition: TimingAuditor.cpp:74
MsgStream.h
Auditor.h
ISequencerTimerTool::addTimer
virtual int addTimer(const std::string &name)=0
add a timer entry with the specified name
TimingAuditor::handle
void handle(const Incident &) override
Inform that a new incident has occurred.
Definition: TimingAuditor.cpp:287