ATLAS Offline Software
Loading...
Searching...
No Matches
VTuneProfilerService.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Gaudi/Athena include(s):
7
8// Local include(s):
10
11//
12// Convenience variable(s):
13//
14static const std::string BEGINEVENT_INCIDENT_NAME = "BeginEvent";
15static const std::string ENDEVENT_INCIDENT_NAME = "EndEvent";
16static const std::string ENDEVTLOOP_INCIDENT_NAME = "EndEvtLoop";
17
21VTuneProfilerService::VTuneProfilerService( const std::string& name, ISvcLocator* svcloc )
22 : base_class( name, svcloc ),
23 m_incidentSvc( "IncidentSvc", name ),
25
26 declareProperty( "ResumeEvent", m_resumeEvent = 0,
27 "Event in which to resume the profiling." );
28 declareProperty( "PauseEvent", m_pauseEvent = -1,
29 "Event in which to pause the profiling. Negative number "
30 "profiles the entire event-loop." );
31 declareProperty( "ProfiledAlgs", m_algs,
32 "List of profiled algorithms." );
33
34}
35
40
41 // Print information
42 ATH_MSG_INFO( "Initializing VTuneProfilerService" );
43
44 // Use the auditor if a list of algorithms is provided
45 if(!m_algs.empty()) {
46
47 // Resume/Pause event don't work in conjuction w/ a list of algorithms
48 ATH_MSG_INFO("ResumeEvent/PauseEvent don't work in conjuction with ProfiledAlgs. " <<
49 "Execute methods of all provided algorithms will be sampled in all events." );
50
51 // Create the auditor
52 ATH_CHECK( auditorSvc()->addAuditor("VTuneAuditor") );
53 }
54
55 // Set up listening to the incidents
56 CHECK( m_incidentSvc.retrieve() );
57 m_incidentSvc->addListener( this, BEGINEVENT_INCIDENT_NAME );
58 m_incidentSvc->addListener( this, ENDEVENT_INCIDENT_NAME );
59 m_incidentSvc->addListener( this, ENDEVTLOOP_INCIDENT_NAME );
60
61 // Reset the event counter:
63
64 return StatusCode::SUCCESS;
65
66}
67
72
73 // Check whether the profiling is already running:
74 if( m_runner ) {
75 ATH_MSG_INFO( "VTune profiling already running!" );
76 return StatusCode::SUCCESS;
77 }
78
79 // Print information
80 ATH_MSG_INFO( "Starting VTune profiling." );
81
82 // Resume VTune
83 m_runner = std::make_unique< VTuneProfileRunner >();
84
85 return StatusCode::SUCCESS;
86
87}
88
93
94 // Check whether the profiling is already running:
95 if( !m_runner ) {
96 ATH_MSG_INFO( "VTune profiling is not running!" );
97 return StatusCode::SUCCESS;
98 }
99
100 // Print information
101 ATH_MSG_INFO( "Stopping VTune profiling." );
102
103 // Pause VTune
104 m_runner.reset();
105
106 return StatusCode::SUCCESS;
107
108}
109
114
115 return (m_runner!=nullptr);
116
117}
118
122void VTuneProfilerService::handle( const Incident& inc ) {
123
124 // Use incidents only if there is no auditor
125 // Next step is to get rid of the incidents altogether
126 if ( !m_algs.empty() ) return;
127
128 //
129 // Pause the profiling after the last event
130 //
131 if( inc.type() == ENDEVTLOOP_INCIDENT_NAME ) {
132 if( m_runner ) {
133 if( pauseProfiling().isFailure() ) {
134 REPORT_MESSAGE( MSG::ERROR )
135 << "Could not pause the profiling";
136 }
137 }
138 return;
139 }
140
141 //
142 // Resume/Pause the profiling on the right event
143 //
144 if( inc.type() == BEGINEVENT_INCIDENT_NAME ) {
146 !m_runner ) {
147 std::lock_guard<std::mutex> lock(m_mutex);
148 //double checked locking pattern
149 //https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
150 //cppcheck-suppress identicalInnerCondition
151 if (!m_runner) {
152 if( resumeProfiling().isFailure() ) {
153 REPORT_MESSAGE( MSG::ERROR )
154 << "Could not resume the profiling";
155 }
156 }
157 }
159 return;
160 }
161 else if( inc.type() == ENDEVENT_INCIDENT_NAME ) {
163 std::lock_guard<std::mutex> lock(m_mutex);
164 //double checked locking pattern
165 //https://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
166 //cppcheck-suppress identicalInnerCondition
167 if (m_runner) {
168 if( pauseProfiling().isFailure() &&
169 m_runner ) {
170 REPORT_MESSAGE( MSG::ERROR )
171 << "Could not pause the profiling";
172 }
173 }
174 }
175 return;
176 }
177
178 // Complain if we received an incident that we didn't expect:
179 ATH_MSG_WARNING( "Wrong incident type received: " << inc.type() );
180 return;
181
182}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE(LVL)
Report a message.
#define CHECK(...)
Evaluate an expression and check for errors.
static const std::string BEGINEVENT_INCIDENT_NAME
static const std::string ENDEVENT_INCIDENT_NAME
static const std::string ENDEVTLOOP_INCIDENT_NAME
VTuneProfilerService(const std::string &name, ISvcLocator *svcloc)
Standard Gaudi service constructor.
std::unique_ptr< VTuneProfileRunner > m_runner
Unique ptr to the VTuneProfileRunner.
int m_pauseEvent
Property: Event in which profiling should pause.
std::vector< std::string > m_algs
Property: List of algorithms to profile.
std::atomic< int > m_processedEvents
Number of events processed so far.
int m_resumeEvent
Property: Event in which profiling should start.
virtual bool isProfilingRunning() const override
Is the profiling running at the moment?
virtual void handle(const Incident &inc) override
Function handling incoming incidents.
ServiceHandle< IIncidentSvc > m_incidentSvc
Handle to the incident service.
virtual StatusCode resumeProfiling() override
Resume profiling.
virtual StatusCode pauseProfiling() override
Pause profiling.
virtual StatusCode initialize() override
Standard Gaudi initialization function.