ATLAS Offline Software
ProfilerService.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 
6 // GPT include(s):
7 #ifdef ATLAS_CMAKE
8 #include <google/profiler.h>
9 #else
10 #include <gperftools/profiler.h>
11 #endif
12 
13 // Gaudi/Athena include(s):
15 
16 // Local include(s):
17 #include "ProfilerService.h"
18 
19 namespace GPT {
20 
21  //
22  // Convenience variable(s):
23  //
24  static const std::string BEGINEVENT_INCIDENT_NAME = "BeginEvent";
25  static const std::string ENDEVTLOOP_INCIDENT_NAME = "EndEvtLoop";
26 
27  ProfilerService::ProfilerService( const std::string& name, ISvcLocator* svcloc )
28  : base_class( name, svcloc ),
29  m_incidentSvc( "IncidentSvc", name ),
30  m_running( false ), m_fileName( "" ), m_processedEvents( 0 ) {
31 
32  declareProperty( "ControlledProfiling", m_controlledProfiling = false,
33  "Will the service be controlled by another component?" );
34  declareProperty( "InitEvent", m_initEvent = -1,
35  "Event in which to start the profiling. Negative number "
36  "profiles the entire job." );
37  declareProperty( "ProfileFileName", m_profFileName = "gpt.profile",
38  "Profile file name in con-controlled mode." );
39  }
40 
42 
43  // Stop the CPU profiling at this point if it's still running:
44  if( m_running ) {
45  stop().ignore();
46  }
47  }
48 
50 
51  ATH_MSG_INFO( "Initializing GPT::ProfilerService" );
52 
53  // Don't do anything fancy if the profiling is under user control, just
54  // remind the user of it:
55  if( m_controlledProfiling ) {
56  ATH_MSG_INFO( " Profiling is under user control" );
57  return StatusCode::SUCCESS;
58  }
59 
60  // Start the profiling at this point if full-job profiling is requested:
61  if( m_initEvent < 0 ) {
62 
64 
65  } else {
66 
67  // Set up listening to the incidents only if we are profiling the
68  // event loop with this service:
69  CHECK( m_incidentSvc.retrieve() );
70  m_incidentSvc->addListener( this, BEGINEVENT_INCIDENT_NAME );
71  m_incidentSvc->addListener( this, ENDEVTLOOP_INCIDENT_NAME );
72 
73  }
74 
75  // Reset the event counter:
77 
78  return StatusCode::SUCCESS;
79  }
80 
82 
83  ATH_MSG_INFO( "Finalizing GPT::ProfilerService" );
84 
85  // The profiling should only be stopped in the destructor even if we
86  // are not under user control...
87 
88  return StatusCode::SUCCESS;
89  }
90 
100 
101  // Check whether the CPU profiling is already running:
102  if( m_running ) {
103  CHECK( stopCPUProfiling() );
104  }
105 
106  // Tell the user what's happening:
107  ATH_MSG_INFO( "Starting CPU profiling using output file: " << filename );
108 
109  // Remember the profile file name:
111 
112  // Start the Google profiler:
113  ProfilerStart( m_fileName.c_str() );
114 
115  // Remember that we are in a running state:
116  m_running = true;
117 
118  return StatusCode::SUCCESS;
119  }
120 
128 
129  // This should not be called when we are not running:
130  if( ! m_running ) {
131  REPORT_MESSAGE( MSG::ERROR )
132  << "CPU profiling not running at the time of call";
133  return StatusCode::RECOVERABLE;
134  }
135 
136  // Stop the profiler:
137  ProfilerStop();
138 
139  // Tell the user what happened:
140  ATH_MSG_INFO( "Stopped CPU profiling using output file: " << m_fileName );
141 
142  // Remember that we are not running anymore:
143  m_running = false;
144 
145  return StatusCode::SUCCESS;
146  }
147 
156 
157  return m_running;
158  }
159 
167  void ProfilerService::handle( const Incident& inc ) {
168 
169  //
170  // Stop the profiling after the last event, if we are only profiling
171  // the event loop:
172  //
173  if( ( inc.type() == ENDEVTLOOP_INCIDENT_NAME ) &&
174  ( ! m_controlledProfiling ) &&
175  ( m_initEvent >= 0 ) ) {
176  if( stopCPUProfiling().isFailure() ) {
177  REPORT_MESSAGE( MSG::ERROR )
178  << "Could not stop the CPU profiling";
179  }
180  return;
181  }
182 
183  //
184  // Start the profiling if we only profile the event loop,
185  // and we're in the correct event:
186  //
187  if( ( inc.type() == BEGINEVENT_INCIDENT_NAME ) &&
188  ( ! m_controlledProfiling ) ) {
189  if( m_initEvent == m_processedEvents ) {
190  if( startCPUProfiling( m_profFileName ).isFailure() ) {
191  REPORT_MESSAGE( MSG::ERROR )
192  << "Could not start the CPU profiling";
193  }
194  }
196  return;
197  }
198 
199  // Complain if we received an incident that we didn't expect:
200  ATH_MSG_WARNING( "Wrong incident type received: " << inc.type() );
201  return;
202  }
203 
204 } // namespace GPT
ProfilerService.h
GPT::ProfilerService::isCPUProfilingRunning
virtual bool isCPUProfilingRunning() const override
Is the GPT profiling running at the moment?
Definition: ProfilerService.cxx:155
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
GPT::ProfilerService::m_processedEvents
int m_processedEvents
Number of events processed so far.
Definition: ProfilerService.h:75
GPT::ProfilerService::m_fileName
std::string m_fileName
Name of the current profile file.
Definition: ProfilerService.h:72
GPT::ProfilerService::m_controlledProfiling
bool m_controlledProfiling
Property: Is profiling controlled from the outside?
Definition: ProfilerService.h:63
PixelModuleFeMask_create_db.stop
int stop
Definition: PixelModuleFeMask_create_db.py:76
GPT
Definition: IProfilerSvc.h:16
GPT::ProfilerService::m_running
bool m_running
Is the CPU profiling running at the moment?
Definition: ProfilerService.h:70
GPT::ProfilerService::handle
virtual void handle(const Incident &inc) override
Function handling incoming incidents.
Definition: ProfilerService.cxx:167
GPT::ProfilerService::finalize
virtual StatusCode finalize() override
Standard Gaudi finalization function.
Definition: ProfilerService.cxx:81
GPT::ProfilerService::~ProfilerService
virtual ~ProfilerService()
Destructor.
Definition: ProfilerService.cxx:41
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
GPT::ProfilerService::ProfilerService
ProfilerService(const std::string &name, ISvcLocator *svcloc)
Standard Gaudi service constructor.
Definition: ProfilerService.cxx:27
CHECK
#define CHECK(...)
Evaluate an expression and check for errors.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:422
GPT::ProfilerService::m_initEvent
int m_initEvent
Property: Event in which non-controlled profiling should start.
Definition: ProfilerService.h:65
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
errorcheck.h
Helpers for checking error return status codes and reporting errors.
REPORT_MESSAGE
#define REPORT_MESSAGE(LVL)
Report a message.
Definition: Control/AthenaKernel/AthenaKernel/errorcheck.h:365
GPT::ProfilerService::startCPUProfiling
virtual StatusCode startCPUProfiling(const std::string &filename) override
Start GPT profiling.
Definition: ProfilerService.cxx:99
GPT::ProfilerService::stopCPUProfiling
virtual StatusCode stopCPUProfiling() override
Stop the GPT profiling.
Definition: ProfilerService.cxx:127
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
GPT::ProfilerService::m_incidentSvc
ServiceHandle< IIncidentSvc > m_incidentSvc
Handle to the incident service.
Definition: ProfilerService.h:60
GPT::ProfilerService::m_profFileName
std::string m_profFileName
Property: Profile file name in non-controlled profiling.
Definition: ProfilerService.h:67
GPT::ProfilerService::initialize
virtual StatusCode initialize() override
Standard Gaudi initialization function.
Definition: ProfilerService.cxx:49
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24