Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  master (f31105fd)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
GoogleAuditor.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2025 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 
12 #include <GaudiKernel/Auditor.h>
14 #include <GaudiKernel/IAlgorithm.h>
18 #include <GaudiKernel/MsgStream.h>
19 #include <algorithm>
20 #include <gperftools/heap-checker.h>
21 #include <gperftools/heap-profiler.h>
22 #include <gperftools/profiler.h>
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 namespace Google {
29 
37  class AuditorBase : public extends<Auditor, IIncidentListener> {
38 
39  public:
41  using extends::extends;
42 
44  StatusCode initialize() override {
45  info() << "Initialised" << endmsg;
46 
47  // add a listener for begin event
48  auto inSvc = serviceLocator()->service<IIncidentSvc>( "IncidentSvc" );
49  if ( !inSvc ) return StatusCode::FAILURE;
50  inSvc->addListener( this, IncidentType::BeginEvent );
51 
52  // sort various lists for speed when searching
53  std::sort( m_when.begin(), m_when.end() );
54  std::sort( m_veto.begin(), m_veto.end() );
55  std::sort( m_list.begin(), m_list.end() );
56 
57  return StatusCode::SUCCESS;
58  }
59 
61  StatusCode finalize() override {
62  if ( alreadyRunning() ) stopAudit();
63  return StatusCode::SUCCESS;
64  }
65 
66  private:
68  inline void startAudit() {
69  info() << " -> Starting full audit from event " << m_nEvts << " to " << m_nEvts + m_nSampleEvents << endmsg;
70  m_inFullAudit = true;
73  t << "FULL-Events" << m_nEvts << "To" << m_nEvts + m_nSampleEvents;
74  google_before( t.str() );
75  }
76 
78  inline void stopAudit() {
79  info() << " -> Stopping full audit" << endmsg;
81  t << "FULL-Events" << m_nEvts << "To" << m_nEvts + m_nSampleEvents;
82  google_after( t.str() );
83  m_inFullAudit = false;
85  }
86 
87  // Check if the component in question is a Sequencer
88  inline bool isSequencer( INamedInterface* i ) const {
89  if ( auto alg = dynamic_cast<IAlgorithm*>( i ) ) { return alg->isSequence(); }
90  return false;
91  }
92 
94  inline bool isPhaseEnabled( CustomEventTypeRef type ) const {
95  return ( std::find( m_when.begin(), m_when.end(), type ) != m_when.end() );
96  }
97 
99  inline bool isComponentEnabled( std::string_view name ) const {
100  return ( std::find( m_veto.begin(), m_veto.end(), name ) == m_veto.end() &&
101  ( m_list.empty() || std::find( m_list.begin(), m_list.end(), name ) != m_list.end() ) );
102  }
103 
104  // Construct the dump name based on processing phase and component name
105  std::string getDumpName( CustomEventTypeRef type, std::string_view name ) const {
107  t << name << "-" << type;
108  if ( type == "Execute" ) t << "-Event" << m_nEvts;
109  return t.str();
110  }
111 
112  public:
118  void handle( const Incident& incident ) override {
119  if ( IncidentType::BeginEvent == incident.type() ) {
120  ++m_nEvts;
121  m_audit = ( m_nEvts > m_eventsToSkip && ( m_freq < 0 || m_nEvts == 1 || m_nEvts % m_freq == 0 ) );
122  if ( msgLevel( MSG::DEBUG ) ) debug() << "Event " << m_nEvts << " Audit=" << m_audit << endmsg;
123  if ( m_fullEventAudit ) {
124  if ( m_inFullAudit ) {
126  stopAudit();
127  } else {
129  }
130  }
131  if ( m_audit && !m_inFullAudit && !alreadyRunning() ) { startAudit(); }
132  }
133  }
134  }
135 
136  public:
137  void before( StandardEventType type, INamedInterface* i ) override {
138  if ( !m_skipSequencers || !isSequencer( i ) ) { before( type, i->name() ); }
139  }
140 
141  void before( CustomEventTypeRef type, INamedInterface* i ) override {
142  if ( !m_skipSequencers || !isSequencer( i ) ) { before( type, i->name() ); }
143  }
144 
145  void before( StandardEventType type, const std::string& s ) override {
147  t << type;
148  before( t.str(), s );
149  }
150 
151  void before( CustomEventTypeRef type, const std::string& s ) override {
153  if ( !alreadyRunning() ) {
154  info() << "Starting Auditor for " << s << ":" << type << endmsg;
155  m_startedBy = s;
157  } else {
158  warning() << "Auditor already running. Cannot be started for " << s << endmsg;
159  }
160  }
161  }
162 
163  void after( StandardEventType type, INamedInterface* i, const StatusCode& sc ) override {
164  if ( !m_skipSequencers || !isSequencer( i ) ) {
166  t << type;
167  after( t.str(), i, sc );
168  }
169  }
170 
171  void after( CustomEventTypeRef type, INamedInterface* i, const StatusCode& sc ) override {
172  if ( !m_skipSequencers || !isSequencer( i ) ) { after( type, i->name(), sc ); }
173  }
174 
175  void after( StandardEventType type, const std::string& s, const StatusCode& sc ) override {
177  t << type;
178  after( t.str(), s, sc );
179  }
180 
181  void after( CustomEventTypeRef type, const std::string& s, const StatusCode& ) override {
183  if ( s == m_startedBy ) { google_after( getDumpName( type, s ) ); }
184  }
185  }
186 
187  protected:
189  virtual void google_before( const std::string& s ) = 0;
190 
192  virtual void google_after( const std::string& s ) = 0;
193 
195  virtual bool alreadyRunning() = 0;
196 
197  private:
199  "ActivateAt",
200  { "Initialize", "ReInitialize", "Execute", "Finalize" },
201  "List of phases to activate the Auditoring during" };
203  this, "DisableFor", {}, "List of component names to disable the auditing for" };
205  this, "EnableFor", {}, "Any component in this list will be audited. If empty, all will be done." };
206  Gaudi::Property<int> m_freq{ this, "ProfileFreq", -1, "The frequence to audit events. -1 means all events" };
208  this, "DoFullEventProfile", false,
209  "If true, instead of individually auditing components, the full event (or events) will be audited in one go" };
211  this, "FullEventNSampleEvents", 1, "The number of events to include in a full event audit, if enabled" };
213  "Number of events to skip before activating the auditing" };
214  Gaudi::Property<bool> m_skipSequencers{ this, "SkipSequencers", true,
215  "If true, auditing will be skipped for Sequencer objects." };
216 
217  bool m_audit = true;
218  unsigned long long m_nEvts = 0;
219  unsigned long long m_sampleEventCount =
220  0;
221  bool m_inFullAudit = false;
223  };
224 
238  class HeapProfiler : public AuditorBase {
239 
240  public:
242  using AuditorBase::AuditorBase;
243 
244  protected:
245  void google_before( const std::string& s ) override { HeapProfilerStart( s.c_str() ); }
246 
247  void google_after( const std::string& s ) override {
248  if ( m_dumpProfileHeaps ) { HeapProfilerDump( s.c_str() ); }
249  if ( m_printProfilesToLog ) {
250  const char* profile = GetHeapProfile();
251  info() << profile << endmsg;
252  delete profile;
253  }
254  HeapProfilerStop();
255  }
256 
257  bool alreadyRunning() override { return IsHeapProfilerRunning(); }
258 
259  private:
260  Gaudi::Property<bool> m_dumpProfileHeaps{ this, "DumpHeapProfiles", true, "" };
261  Gaudi::Property<bool> m_printProfilesToLog{ this, "PrintProfilesToLog", false, "" };
262  };
263 
277  class HeapChecker : public AuditorBase {
278 
279  public:
281  using AuditorBase::AuditorBase;
282 
283  StatusCode initialize() override {
284  const StatusCode sc = AuditorBase::initialize();
285  if ( sc.isFailure() ) return sc;
286 
287  const char* HEAPCHECK = getenv( "HEAPCHECK" );
288  if ( !HEAPCHECK ) {
289  fatal() << "Environment variable HEAPCHECK must be set to 'local'" << endmsg;
290  return StatusCode::FAILURE;
291  }
292  if ( std::string( HEAPCHECK ) != "local" ) {
293  warning() << "Environment variable HEAPCHECK is set to " << HEAPCHECK
294  << " Partial Program Heap Checking is disabled" << endmsg;
295  m_enabled = false;
296  }
297 
298  return sc;
299  }
300 
301  protected:
302  void google_before( const std::string& s ) override {
303  if ( m_enabled && !m_checker ) { m_checker.reset( new HeapLeakChecker( s.c_str() ) ); }
304  }
305 
306  void google_after( const std::string& s ) override {
307  if ( m_enabled && m_checker ) {
308  if ( !m_checker->NoLeaks() ) { warning() << "Leak detected for " << s << endmsg; }
309  m_checker.reset();
310  }
311  }
312 
313  bool alreadyRunning() override { return m_enabled && m_checker; }
314 
315  private:
316  bool m_enabled = true;
318  };
319 
333  class CPUProfiler : public AuditorBase {
334 
335  public:
336  using AuditorBase::AuditorBase;
337 
338  protected:
339  void google_before( const std::string& s ) override {
340  if ( !m_running ) {
341  m_running = true;
342  ProfilerStart( ( s + ".prof" ).c_str() );
343  }
344  }
345 
346  void google_after( const std::string& ) override {
347  if ( m_running ) {
348  ProfilerStop();
349  m_running = false;
350  }
351  }
352 
353  bool alreadyRunning() override { return m_running; }
354 
355  private:
356  bool m_running = false;
357  };
358 
362 } // namespace Google
Google::AuditorBase::after
void after(CustomEventTypeRef type, const std::string &s, const StatusCode &) override
Definition: GoogleAuditor.cpp:181
Auditor::serviceLocator
SmartIF< ISvcLocator > & serviceLocator() const override
The standard service locator.
Definition: Auditor.h:88
MSG::DEBUG
@ DEBUG
Definition: IMessageSvc.h:25
Google::AuditorBase::before
void before(CustomEventTypeRef type, const std::string &s) override
Definition: GoogleAuditor.cpp:151
Google::HeapProfiler::google_before
void google_before(const std::string &s) override
Start the google tool.
Definition: GoogleAuditor.cpp:245
Google::AuditorBase::m_freq
Gaudi::Property< int > m_freq
Definition: GoogleAuditor.cpp:206
std::string
STL class.
Google::HeapProfiler::m_dumpProfileHeaps
Gaudi::Property< bool > m_dumpProfileHeaps
Definition: GoogleAuditor.cpp:260
GaudiException.h
gaudirun.s
string s
Definition: gaudirun.py:346
std::find
T find(T... args)
Google::AuditorBase::after
void after(StandardEventType type, INamedInterface *i, const StatusCode &sc) override
Definition: GoogleAuditor.cpp:163
Google::AuditorBase::m_inFullAudit
bool m_inFullAudit
Internal flag to indicate if we are current in a full event audit.
Definition: GoogleAuditor.cpp:221
Google::HeapChecker::alreadyRunning
bool alreadyRunning() override
check if we are already running the tool
Definition: GoogleAuditor.cpp:313
INamedInterface::name
virtual const std::string & name() const =0
Retrieve the name of the instance.
Google::AuditorBase::before
void before(CustomEventTypeRef type, INamedInterface *i) override
Definition: GoogleAuditor.cpp:141
Google::AuditorBase::isPhaseEnabled
bool isPhaseEnabled(CustomEventTypeRef type) const
Check if auditing is enabled for the current processing phase.
Definition: GoogleAuditor.cpp:94
Google::AuditorBase::initialize
StatusCode initialize() override
Initialize the auditor base.
Definition: GoogleAuditor.cpp:44
Google::AuditorBase::m_skipSequencers
Gaudi::Property< bool > m_skipSequencers
Definition: GoogleAuditor.cpp:214
Google::AuditorBase::google_before
virtual void google_before(const std::string &s)=0
Start the google tool.
std::sort
T sort(T... args)
std::unique_ptr::reset
T reset(T... args)
CommonMessaging< implements< IAuditor, IProperty > >::msgLevel
MSG::Level msgLevel() const
get the cached level (originally extracted from the embedded MsgStream)
Definition: CommonMessaging.h:148
IAuditorSvc.h
IIncidentSvc.h
Google::HeapChecker::google_before
void google_before(const std::string &s) override
Start the google tool.
Definition: GoogleAuditor.cpp:302
ManySmallAlgs.alg
alg
Definition: ManySmallAlgs.py:81
Google::AuditorBase::isSequencer
bool isSequencer(INamedInterface *i) const
Definition: GoogleAuditor.cpp:88
bug_34121.t
t
Definition: bug_34121.py:31
Google::CPUProfiler::m_running
bool m_running
Definition: GoogleAuditor.cpp:356
Google::AuditorBase::after
void after(CustomEventTypeRef type, INamedInterface *i, const StatusCode &sc) override
Definition: GoogleAuditor.cpp:171
StatusCode
Definition: StatusCode.h:65
Google::AuditorBase::handle
void handle(const Incident &incident) override
Implement the handle method for the Incident service.
Definition: GoogleAuditor.cpp:118
IAlgorithm
Definition: IAlgorithm.h:38
Google::AuditorBase::getDumpName
std::string getDumpName(CustomEventTypeRef type, std::string_view name) const
Definition: GoogleAuditor.cpp:105
Google::HeapProfiler
Definition: GoogleAuditor.cpp:238
Google::CPUProfiler
Definition: GoogleAuditor.cpp:333
Google::AuditorBase::alreadyRunning
virtual bool alreadyRunning()=0
check if we are already running the tool
Google::AuditorBase::m_veto
Gaudi::Property< std::vector< std::string > > m_veto
Definition: GoogleAuditor.cpp:202
Google::AuditorBase::m_list
Gaudi::Property< std::vector< std::string > > m_list
Definition: GoogleAuditor.cpp:204
Google::AuditorBase::isComponentEnabled
bool isComponentEnabled(std::string_view name) const
Check if auditing is enabled for the given component.
Definition: GoogleAuditor.cpp:99
Google::AuditorBase::m_eventsToSkip
Gaudi::Property< unsigned long long > m_eventsToSkip
Definition: GoogleAuditor.cpp:212
Google::AuditorBase::stopAudit
void stopAudit()
stop a full event audit
Definition: GoogleAuditor.cpp:78
Google::CPUProfiler::google_after
void google_after(const std::string &) override
stop the google tool
Definition: GoogleAuditor.cpp:346
Google::AuditorBase::before
void before(StandardEventType type, const std::string &s) override
Definition: GoogleAuditor.cpp:145
Google::AuditorBase::after
void after(StandardEventType type, const std::string &s, const StatusCode &sc) override
Definition: GoogleAuditor.cpp:175
Google::HeapChecker::m_checker
std::unique_ptr< HeapLeakChecker > m_checker
Definition: GoogleAuditor.cpp:317
Google::HeapChecker
Definition: GoogleAuditor.cpp:277
Google::AuditorBase::m_audit
bool m_audit
Internal flag to say if auditing is enabled or not for the current event.
Definition: GoogleAuditor.cpp:217
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
extends
Base class used to extend a class implementing other interfaces.
Definition: extends.h:20
Google::HeapChecker::m_enabled
bool m_enabled
Definition: GoogleAuditor.cpp:316
Google::AuditorBase::m_when
Gaudi::Property< std::vector< std::string > > m_when
Definition: GoogleAuditor.cpp:198
Google::AuditorBase::m_nEvts
unsigned long long m_nEvts
Number of events processed.
Definition: GoogleAuditor.cpp:218
Google::HeapChecker::google_after
void google_after(const std::string &s) override
stop the google tool
Definition: GoogleAuditor.cpp:306
std::ostringstream
STL class.
StatusCode::isFailure
bool isFailure() const
Definition: StatusCode.h:130
Google::AuditorBase::google_after
virtual void google_after(const std::string &s)=0
stop the google tool
gaudirun.type
type
Definition: gaudirun.py:160
INamedInterface
Definition: INamedInterface.h:25
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
Google::AuditorBase::startAudit
void startAudit()
Start a full event audit.
Definition: GoogleAuditor.cpp:68
Google::AuditorBase::m_nSampleEvents
Gaudi::Property< unsigned long long > m_nSampleEvents
Definition: GoogleAuditor.cpp:210
Google::CPUProfiler::alreadyRunning
bool alreadyRunning() override
check if we are already running the tool
Definition: GoogleAuditor.cpp:353
Google::HeapChecker::initialize
StatusCode initialize() override
Initialize the auditor base.
Definition: GoogleAuditor.cpp:283
IIncidentListener.h
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
Google::HeapProfiler::m_printProfilesToLog
Gaudi::Property< bool > m_printProfilesToLog
Definition: GoogleAuditor.cpp:261
Google::AuditorBase::finalize
StatusCode finalize() override
Finalize the auditor base.
Definition: GoogleAuditor.cpp:61
Google::AuditorBase::m_fullEventAudit
Gaudi::Property< bool > m_fullEventAudit
Definition: GoogleAuditor.cpp:207
Google::AuditorBase::m_sampleEventCount
unsigned long long m_sampleEventCount
Internal count of the number of events currently processed during an audit.
Definition: GoogleAuditor.cpp:219
Incident::type
const std::string & type() const
Access to the incident type.
Definition: Incident.h:48
Google::AuditorBase::m_startedBy
std::string m_startedBy
Name of the component we are currently auditing.
Definition: GoogleAuditor.cpp:222
IAlgorithm.h
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
Google::AuditorBase
Definition: GoogleAuditor.cpp:37
Auditor::name
const std::string & name() const override
Definition: Auditor.h:80
IIncidentSvc
Definition: IIncidentSvc.h:33
Incident
Definition: Incident.h:27
std::unique_ptr< HeapLeakChecker >
Google
Definition: GoogleAuditor.cpp:28
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:37
Google::HeapProfiler::google_after
void google_after(const std::string &s) override
stop the google tool
Definition: GoogleAuditor.cpp:247
Google::CPUProfiler::google_before
void google_before(const std::string &s) override
Start the google tool.
Definition: GoogleAuditor.cpp:339
MsgStream.h
Google::AuditorBase::before
void before(StandardEventType type, INamedInterface *i) override
Definition: GoogleAuditor.cpp:137
Auditor.h
Google::HeapProfiler::alreadyRunning
bool alreadyRunning() override
check if we are already running the tool
Definition: GoogleAuditor.cpp:257