The Gaudi Framework  v36r1 (3e2fb5a8)
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, "enable optimization for Data-On-Demand Service"};
92 };
93 // ============================================================================
95 // ============================================================================
97 // ============================================================================
98 StatusCode TimingAuditor::initialize() {
100  if ( sc.isFailure() ) { return sc; } // RETURN
101 
102  // get tool service
103  if ( !m_toolSvc ) {
104  m_toolSvc = Auditor::service( "ToolSvc" );
105  if ( !m_toolSvc ) {
106  error() << "Could not retrieve 'ToolSvc' " << endmsg;
107  return StatusCode::FAILURE; // RETURN
108  }
109  if ( !m_timer ) {
110  sc = m_toolSvc->retrieveTool( "SequencerTimerTool/TIMER", m_timer, this, true );
111  if ( sc.isFailure() ) {
112  error() << "Could not retrieve ISequencerTimerTool" << endmsg;
113  return sc;
114  }
115  }
116  }
117  // get incident service
118  if ( !m_incSvc ) {
119  m_incSvc = Auditor::service( "IncidentSvc" );
120  if ( !m_incSvc ) {
121  error() << "Could not retrieve 'IncidentSvc'" << endmsg;
122  return StatusCode::FAILURE;
123  }
124  m_incSvc->addListener( this, IncidentType::BeginEvent );
125  m_incSvc->addListener( this, IncidentType::EndEvent );
126  }
127  // get the application manager
128  if ( !m_appMgr ) {
129  m_appMgr = Auditor::service( "ApplicationMgr" );
130  if ( !m_appMgr ) {
131  error() << "Could not retrieve 'ApplicationMgr'" << endmsg;
132  return sc;
133  }
134  if ( m_map.end() == m_map.find( m_appMgr.get() ) ) {
135  m_map.insert( m_appMgr.get(), m_timer->addTimer( "EVENT LOOP" ) );
136  }
137  }
138  //
139  return StatusCode::SUCCESS;
140 }
141 // ============================================================================
143  if ( m_incSvc ) {
144  m_incSvc->removeListener( this, IncidentType::BeginEvent );
145  m_incSvc->removeListener( this, IncidentType::EndEvent );
146  m_incSvc.reset();
147  }
148  if ( m_toolSvc ) {
149  // the 2 following line are commented out: it is
150  // is a temporary hack which prevent a crash due to a problem in
151  // the reference counting
152  // if ( 0 != m_timer )
153  // { m_toolSvc -> releaseTool ( m_timer ) . ignore() ; m_timer = 0 ; }
154  m_toolSvc.reset();
155  }
156  m_appMgr.reset();
157  // clear the map
158  m_map.clear();
159  // finalize the base class
160  return Auditor::finalize();
161 }
162 // ============================================================================
163 void TimingAuditor::before( StandardEventType evt, INamedInterface* alg ) {
164  switch ( evt ) {
167  break;
168  case IAuditor::Execute:
169  i_beforeExecute( alg );
170  break;
171  case IAuditor::Finalize:
173  break;
174  default:
175  break;
176  }
177 }
178 // ============================================================================
179 void TimingAuditor::after( StandardEventType evt, INamedInterface* alg, const StatusCode& ) {
180  switch ( evt ) {
183  break;
184  case IAuditor::Execute:
185  i_afterExecute( alg );
186  break;
187  default:
188  break;
189  }
190 }
191 // ============================================================================
193  if ( !m_histoSaved ) {
195  m_histoSaved = true;
196  }
197 }
198 
199 // ============================================================================
201  if ( m_goodForDOD ) { return; }
202  //
203  if ( !alg ) { return; }
204  auto found = m_map.find( alg );
205  if ( m_map.end() != found ) { return; }
206  ++m_indent;
207  std::string nick = alg->name();
208  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
209  if ( m_inEvent ) {
210  nick[0] = '*';
211  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
212  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
213  }
214  int timer = m_timer->addTimer( nick );
215  m_map.insert( alg, timer );
216  m_timer->start( timer );
217 }
218 // ============================================================================
220  if ( m_goodForDOD || !alg ) { return; }
221  --m_indent;
222 }
223 // ============================================================================
225  if ( !alg ) { return; }
226  ++m_indent;
227  auto found = m_map.find( alg );
228  if ( m_map.end() == found ) {
229  debug() << "Insert non-structural component '" << alg->name() << "' of type '"
230  << System::typeinfoName( typeid( *alg ) ) << "' at level " << m_indent << endmsg;
231  std::string nick = alg->name();
232  if ( 0 < m_indent ) { nick = std::string( m_indent, ' ' ) + nick; }
233  if ( !m_goodForDOD ) { nick[0] = '*'; }
234  int timer = m_timer->addTimer( nick );
235  m_map.insert( alg, timer );
236  m_timer->start( timer );
237  return;
238  }
239  m_timer->start( found->second );
240 }
241 // ============================================================================
243  if ( !alg ) { return; }
244  auto found = m_map.find( alg );
245  if ( m_map.end() == found ) { return; }
246  m_timer->stop( found->second );
247  --m_indent;
248 }
249 // ============================================================================
250 void TimingAuditor::before( CustomEventTypeRef evt, const std::string& name ) {
251  // Ignore obvious mistakes
252  if ( name.empty() && evt.empty() ) { return; }
253 
254  // look for the user timer in the map
255  int timer = 0;
256  std::string nick = std::string{name}.append( ":" ).append( evt );
257  auto found = m_mapUser.find( nick );
258 
259  if ( m_mapUser.end() == found ) {
260  // add a new timer if not yet available
261  timer = m_timer->addTimer( nick );
262  m_mapUser[nick] = timer;
263  } else {
264  timer = found->second;
265  }
266  m_timer->start( timer );
267 }
268 // ============================================================================
269 void TimingAuditor::after( CustomEventTypeRef evt, const std::string& name, const StatusCode& ) {
270  // Ignore obvious mistakes
271  if ( name.empty() && evt.empty() ) { return; }
272 
273  // look for the user timer in the map
274  std::string nick = std::string{name}.append( ":" ).append( evt );
275  auto found = m_mapUser.find( nick );
276 
277  // We cannot do much if the timer is not available
278  if ( m_mapUser.end() == found ) {
279  warning() << "Trying to stop the measure of the timing for '" << nick
280  << "' but it was never started. Check the code" << endmsg;
281  return;
282  }
283  m_timer->stop( found->second );
284 }
285 // ============================================================================
286 void TimingAuditor::handle( const Incident& i ) {
287  if ( IncidentType::BeginEvent == i.type() ) {
288  m_timer->start( m_map[m_appMgr.get()] );
289  ++m_indent;
290  m_inEvent = true;
291  } else if ( IncidentType::EndEvent == i.type() ) {
292  m_timer->stop( m_map[m_appMgr.get()] );
293  --m_indent;
294  m_inEvent = false;
295  }
296 }
297 // ============================================================================
298 // The END
299 // ============================================================================
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:98
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:308
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:192
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:23
StatusCode
Definition: StatusCode.h:65
TimingAuditor::TimingAuditor
TimingAuditor()=delete
TimingAuditor::finalize
StatusCode finalize() override
Definition: TimingAuditor.cpp:142
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:219
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:142
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:242
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:224
GaudiUtils::HashMap< std::string, int >
TimingAuditor::before
void before(StandardEventType evt, INamedInterface *alg) override
Definition: TimingAuditor.cpp:163
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
TimingAuditor::i_beforeInitialize
void i_beforeInitialize(INamedInterface *alg)
Definition: TimingAuditor.cpp:200
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:179
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:286