| The Gaudi Framework v32r1 (f65d50dc)

TimingAuditor.cpp
Go to the documentation of this file.
1 #include "GaudiKernel/Auditor.h"
2 #include "GaudiKernel/HashMap.h"
3 #include "GaudiKernel/IIncidentListener.h"
4 #include "GaudiKernel/IIncidentSvc.h"
5 #include "GaudiKernel/IToolSvc.h"
6 #include "GaudiKernel/MsgStream.h"
7 #include "GaudiKernel/VectorMap.h"
8 // ============================================================================
9 // GaudiAlg
10 // ============================================================================
11 #include "GaudiAlg/ISequencerTimerTool.h"
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:
38 void i_beforeInitialize( INamedInterface* alg );
39 void i_afterInitialize( INamedInterface* alg );
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
62 SmartIF<IToolSvc> m_toolSvc = nullptr;
63 // incident service
64 SmartIF<IIncidentSvc> m_incSvc = nullptr;
65 // the timer tool
66 ISequencerTimerTool* m_timer = nullptr;
67 // ApplicationManager
68 SmartIF<INamedInterface> m_appMgr = nullptr;
69 //
70 GaudiUtils::VectorMap<const INamedInterface*, int> m_map;
71 // indentation level
72 int m_indent = 0;
73 // "in event"
74 bool m_inEvent = false;
75 //
76 GaudiUtils::HashMap<std::string, int> m_mapUser;
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 // ============================================================================
86 DECLARE_COMPONENT( TimingAuditor )
87 // ============================================================================
88 StatusCode TimingAuditor::initialize() {
89 StatusCode sc = Auditor::initialize();
90 if ( sc.isFailure() ) { return sc; } // RETURN
91
92 // get tool service
93 if ( !m_toolSvc ) {
94 m_toolSvc = Auditor::service( "ToolSvc", true );
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", true );
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 // ============================================================================
132 StatusCode TimingAuditor::finalize() {
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 ) {
155 case IAuditor::Initialize:
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 ) {
171 case IAuditor::Initialize:
172 i_afterInitialize( alg );
173 break;
174 case IAuditor::Execute:
175 i_afterExecute( alg );
176 break;
177 default:
178 break;
179 }
180 }
181 // ============================================================================
182 void TimingAuditor::i_beforeFinalize( INamedInterface* /*alg*/ ) {
183 if ( !m_histoSaved ) {
184 m_timer->saveHistograms();
185 m_histoSaved = true;
186 }
187 }
188
189 // ============================================================================
190 void TimingAuditor::i_beforeInitialize( INamedInterface* alg ) {
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 // ============================================================================
209 void TimingAuditor::i_afterInitialize( INamedInterface* alg ) {
210 if ( m_goodForDOD || !alg ) { return; }
211 --m_indent;
212 }
213 // ============================================================================
214 void TimingAuditor::i_beforeExecute( INamedInterface* alg ) {
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 // ============================================================================
232 void TimingAuditor::i_afterExecute( INamedInterface* alg ) {
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 // ============================================================================
TimingAuditor::i_afterInitialize
void i_afterInitialize(INamedInterface *alg)
Definition: TimingAuditor.cpp:209
TimingAuditor::i_beforeInitialize
void i_beforeInitialize(INamedInterface *alg)
Definition: TimingAuditor.cpp:190
TimingAuditor::m_mapUser
GaudiUtils::HashMap< std::string, int > m_mapUser
map used to record user timing events
Definition: TimingAuditor.cpp:76
GaudiUtils::VectorMap< const INamedInterface *, int >
TimingAuditor::operator=
TimingAuditor & operator=(const TimingAuditor &)=delete
SmartIF< IToolSvc >
Auditor::finalize
virtual StatusCode finalize()
Definition: Auditor.cpp:191
std::string::empty
T empty(T... args)
ManySmallAlgs.alg
alg
Definition: ManySmallAlgs.py:69
gaudiComponentHelp.name
name
Definition: gaudiComponentHelp.py:41
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:352
MsgStream.h
CommonMessagingBase::warning
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
Definition: CommonMessaging.h:101
Auditor::service
StatusCode service(const std::string &name, T *&svc, bool createIf=false) const
Access a service by name, creating it if it doesn't already exist.
Definition: Auditor.h:105
Incident::type
const std::string & type() const
Access to the incident type.
Definition: Incident.h:38
System::typeinfoName
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition: System.cpp:298
ISequencerTimerTool::addTimer
virtual int addTimer(const std::string &name)=0
add a timer entry with the specified name
TimingAuditor::m_inEvent
bool m_inEvent
"In event" flag
Definition: TimingAuditor.cpp:74
TimingAuditor::m_map
GaudiUtils::VectorMap< const INamedInterface *, int > m_map
Definition: TimingAuditor.cpp:70
GaudiUtils::VectorMap::end
iterator end() const
"end" iterator for sequential access (const-only version!)
Definition: VectorMap.h:188
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
TimingAuditor::finalize
StatusCode finalize() override
Definition: TimingAuditor.cpp:132
TimingAuditor::i_beforeExecute
void i_beforeExecute(INamedInterface *alg)
Definition: TimingAuditor.cpp:214
HashMap.h
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:302
TimingAuditor::after
void after(StandardEventType evt, INamedInterface *alg, const StatusCode &sc) override
Definition: TimingAuditor.cpp:169
IToolSvc.h
SmartIF::get
TYPE * get() const
Get interface pointer.
Definition: SmartIF.h:76
std::string
STL class.
TimingAuditor::initialize
StatusCode initialize() override
factory:
Definition: TimingAuditor.cpp:88
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
TimingAuditor::m_indent
int m_indent
indentation level
Definition: TimingAuditor.cpp:72
GaudiUtils::Map::end
iterator end()
Definition: Map.h:130
TimingAuditor::m_appMgr
SmartIF< INamedInterface > m_appMgr
ApplicationManager.
Definition: TimingAuditor.cpp:68
VectorMap.h
IIncidentSvc.h
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
TimingAuditor::m_incSvc
SmartIF< IIncidentSvc > m_incSvc
incident service
Definition: TimingAuditor.cpp:64
TimingAuditor::before
void before(StandardEventType evt, INamedInterface *alg) override
Definition: TimingAuditor.cpp:153
IAuditor::Finalize
Definition: IAuditor.h:24
ISequencerTimerTool::saveHistograms
virtual void saveHistograms()=0
prepares and saves the timing histograms
GaudiUtils::Map::find
iterator find(const key_type &key)
Definition: Map.h:147
Auditor::after
void after(StandardEventType, INamedInterface *, const StatusCode &) override
Definition: Auditor.cpp:103
CommonMessagingBase::debug
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
Definition: CommonMessaging.h:107
IAuditor::Initialize
Definition: IAuditor.h:24
TimingAuditor::i_beforeFinalize
void i_beforeFinalize(INamedInterface *alg)
Definition: TimingAuditor.cpp:182
ISequencerTimerTool::start
virtual void start(int index)=0
start the counter, i.e.
INamedInterface
IInterface compliant class extending IInterface with the name() method.
Definition: INamedInterface.h:15
TimingAuditor::TimingAuditor
TimingAuditor()=delete
extends
Base class used to extend a class implementing other interfaces.
Definition: extends.h:10
Incident
Base class for all Incidents (computing events).
Definition: Incident.h:17
IAuditor::Execute
Definition: IAuditor.h:24
ISequencerTimerTool
Implements the time measurement inside a sequencer.
Definition: ISequencerTimerTool.h:14
GaudiUtils::HashMap< std::string, int >
Auditor::name
const std::string & name() const override
Definition: Auditor.cpp:193
ISequencerTimerTool.h
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
GaudiUtils::VectorMap::clear
void clear()
clear the container
Definition: VectorMap.h:466
TimingAuditor::m_toolSvc
SmartIF< IToolSvc > m_toolSvc
tool service
Definition: TimingAuditor.cpp:62
GaudiUtils::VectorMap::find
iterator find(const key_type &key) const
find the element by key
Definition: VectorMap.h:430
IIncidentListener.h
SmartIF::reset
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:86
TimingAuditor::m_timer
ISequencerTimerTool * m_timer
the timer tool
Definition: TimingAuditor.cpp:66
Auditor::initialize
virtual StatusCode initialize()
Definition: Auditor.cpp:64
IIncidentSvc::removeListener
virtual void removeListener(IIncidentListener *lis, const std::string &type="")=0
Remove listener.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:130
TimingAuditor::handle
void handle(const Incident &) override
Inform that a new incident has occurred.
Definition: TimingAuditor.cpp:276
TimingAuditor::m_histoSaved
bool m_histoSaved
Definition: TimingAuditor.cpp:79
ISequencerTimerTool::stop
virtual double stop(int index)=0
stop the counter, return the elapsed time
Auditor.h
TimingAuditor::m_goodForDOD
Gaudi::Property< bool > m_goodForDOD
Definition: TimingAuditor.cpp:81
Auditor::before
void before(StandardEventType, INamedInterface *) override
The following methods are meant to be implemented by the child class...
Definition: Auditor.cpp:67
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
IOTest.evt
evt
Definition: IOTest.py:94
TimingAuditor::i_afterExecute
void i_afterExecute(INamedInterface *alg)
Definition: TimingAuditor.cpp:232
TimingAuditor
Simple auditor which uses SequencerTimerTool for ALL algorithms, including the algorithm from main Ga...
Definition: TimingAuditor.cpp:27