The Gaudi Framework  master (bdbe7744)
Loading...
Searching...
No Matches
NVTXAuditor Class Reference

Auditor that uses NVTX to annotate ranges and incidents for profiling with NVIDIA tools. More...

Inheritance diagram for NVTXAuditor:
Collaboration diagram for NVTXAuditor:

Private Member Functions

StatusCode initialize () override
 Initialize the auditor and register for all available incidents if the Incident service exists.
StatusCode finalize () override
 Finalize the auditor, releasing the NVTX domain.
void handle (const Incident &incident) override
 Handle an incident by annotating it with an NVTX marker.
std::string make_key (std::string const &event, std::string const &caller, EventContext const &ctx) const
 Helper to create an identifier key for storing an associated range in the map.
std::string make_label (std::string const &event, std::string const &caller) const
 Helper to create a label for the audited event.
nvtxRangeId_t start_range (std::string const &label, EventContext const &ctx)
 Start an NVTX range for the audited event.
void before (std::string const &event, std::string const &caller, EventContext const &ctx) override
 Handle 'before' audit for given event by starting an associated NVTX range.
void after (std::string const &event, std::string const &caller, EventContext const &ctx, StatusCode const &=StatusCode::SUCCESS) override
 Handle 'after' audit for given event by ending the associated NVTX range.

Private Attributes

tbb::concurrent_hash_map< std::string, nvtxRangeId_t > m_ranges

Static Private Attributes

static nvtxDomainHandle_t s_domain { nullptr }
static uint32_t s_numCategories { 0 }

Additional Inherited Members

Public Types inherited from extends< Gaudi::Auditor, IIncidentListener >
using base_class
 Typedef to this class.
using extend_interfaces_base
 Typedef to the base of this class.
Public Types inherited from Gaudi::Auditor
using Factory = Gaudi::PluginService::Factory<IAuditor*( const std::string&, ISvcLocator* )>
Public Types inherited from PropertyHolder< CommonMessaging< implements< IAuditor, IProperty > > >
using PropertyHolderImpl
 Typedef used to refer to this class from derived classes, as in.
Public Types inherited from CommonMessaging< implements< IAuditor, IProperty > >
using base_class
Public Types inherited from extend_interfaces< Interfaces... >
using ext_iids
 take union of the ext_iids of all Interfaces...
Public Member Functions inherited from extends< Gaudi::Auditor, IIncidentListener >
void const * i_cast (const InterfaceID &tid) const override
 Implementation of IInterface::i_cast.
StatusCode queryInterface (const InterfaceID &ti, void **pp) override
 Implementation of IInterface::queryInterface.
std::vector< std::string > getInterfaceNames () const override
 Implementation of IInterface::getInterfaceNames.
Public Member Functions inherited from Gaudi::Auditor
 Auditor (std::string name, ISvcLocator *svcloc)
 Auditor (const Auditor &a)=delete
Auditor & operator= (const Auditor &rhs)=delete
StatusCode sysInitialize () override
StatusCode sysFinalize () override
void before (std::string const &, std::string const &, EventContext const &) override
void after (std::string const &, std::string const &, EventContext const &, StatusCode const &=StatusCode::SUCCESS) override
const std::string & name () const override
bool isEnabled () const override
SmartIF< ISvcLocator > & serviceLocator () const override
 The standard service locator.
template<class T = IService>
SmartIF< T > service (std::string_view name, bool createIf=false) const
 Access a service by name, creating it if it doesn't already exist.
Public Member Functions inherited from PropertyHolder< CommonMessaging< implements< IAuditor, IProperty > > >
StatusCode setProperty (const Gaudi::Details::PropertyBase &p)
 Set the property from a property.
StatusCode setProperty (const std::string &name, const char *v)
 Special case for string literals.
StatusCode setProperty (const std::string &name, const std::string &v)
 Special case for std::string.
StatusCode setProperty (const std::string &name, const TYPE &value)
 set the property form the value
 PropertyHolder ()=default
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Details::PropertyBase &prop)
 Declare a property.
Gaudi::Details::PropertyBase * declareRemoteProperty (const std::string &name, IProperty *rsvc, const std::string &rname="")
 Declare a remote property.
StatusCode setPropertyRepr (const std::string &n, const std::string &r) override
 set the property from name and value string representation
StatusCode getProperty (Gaudi::Details::PropertyBase *p) const override
 get the property
const std::vector< Gaudi::Details::PropertyBase * > & getProperties () const override
 get all properties
bool hasProperty (std::string_view name) const override
 Return true if we have a property with the given name.
Gaudi::Details::PropertyBase * property (std::string_view name) const
 \fixme property and bindPropertiesTo should be protected
void bindPropertiesTo (Gaudi::Interfaces::IOptionsSvc &optsSvc)
PropertyHolder & operator= (const PropertyHolder &)=delete
Public Member Functions inherited from CommonMessagingBase
virtual ~CommonMessagingBase ()=default
 Virtual destructor.
const SmartIF< IMessageSvc > & msgSvc () const
 The standard message service.
MsgStream & msgStream () const
 Return an uninitialized MsgStream.
MsgStream & msgStream (const MSG::Level level) const
 Predefined configurable message stream for the efficient printouts.
MsgStream & always () const
 shortcut for the method msgStream(MSG::ALWAYS)
MsgStream & fatal () const
 shortcut for the method msgStream(MSG::FATAL)
MsgStream & err () const
 shortcut for the method msgStream(MSG::ERROR)
MsgStream & error () const
 shortcut for the method msgStream(MSG::ERROR)
MsgStream & warning () const
 shortcut for the method msgStream(MSG::WARNING)
MsgStream & info () const
 shortcut for the method msgStream(MSG::INFO)
MsgStream & debug () const
 shortcut for the method msgStream(MSG::DEBUG)
MsgStream & verbose () const
 shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & msg () const
 shortcut for the method msgStream(MSG::INFO)
MSG::Level msgLevel () const
 get the cached level (originally extracted from the embedded MsgStream)
bool msgLevel (MSG::Level lvl) const
 get the output level from the embedded MsgStream
Protected Member Functions inherited from CommonMessaging< implements< IAuditor, IProperty > >
MSG::Level setUpMessaging () const override final
 Set up local caches.
MSG::Level resetMessaging ()
 Reinitialize internal states.
void updateMsgStreamOutputLevel (int level)
 Update the output level of the cached MsgStream.

Detailed Description

Auditor that uses NVTX to annotate ranges and incidents for profiling with NVIDIA tools.

This auditor creates NVTX ranges around audited events and marks incidents with NVTX markers. The ranges and markers are created in a custom "Gaudi" NVTX domain. Ranges and markers related to events are annotated with event number in the payload, colored based on an event number and put in categories based on event slot. Ranges and markers not related to events are put into the default category with no payload and default color.

Author
Mateusz Jakub Fila

Definition at line 54 of file NVTXAuditor.cpp.

Member Function Documentation

◆ after()

void NVTXAuditor::after ( std::string const & event,
std::string const & caller,
EventContext const & ctx,
StatusCode const & = StatusCode::SUCCESS )
inlineoverrideprivate

Handle 'after' audit for given event by ending the associated NVTX range.

Parameters
eventThe name of the audited event.
callerThe name of the caller of the audited event.
ctxThe EventContext associated with the audited event.
statusThe status code of the audited event.
Note
In case of a suspension event, the range for the execution is created to indicate resumption rather than creating a range for suspension.

Definition at line 258 of file NVTXAuditor.cpp.

259 {
260 // Suspension has ended, so resume the execution by creating a new
261 // execution range. Do not create a range for Suspend itself.
262 if ( IAuditor::Suspension == event ) {
263 auto execute_key = make_key( IAuditor::Execute, caller, ctx );
264 auto label = make_label( IAuditor::Execute, caller );
265 auto id = start_range( label, ctx );
266 auto ret = m_ranges.emplace( execute_key, id );
267 if ( !ret ) {
268 error() << std::format( "Execution range for {} already exists while resuming", execute_key ) << endmsg;
269 nvtxDomainRangeEnd( s_domain, id ); // the newly started range would otherwise never be closed
270 } else {
271 debug() << std::format( "Resumed execution range for {}", execute_key ) << endmsg;
272 }
273 return;
274 }
275
276 auto key = make_key( event, caller, ctx );
277 auto acc = decltype( m_ranges )::accessor{};
278 if ( m_ranges.find( acc, key ) ) {
279 nvtxDomainRangeEnd( s_domain, acc->second );
280 m_ranges.erase( acc );
281 } else {
282 error() << std::format( "Range for {} does not exist", key ) << endmsg;
283 }
284 debug() << std::format( "Finished range for {}", key ) << endmsg;
285 }
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
std::string make_label(std::string const &event, std::string const &caller) const
Helper to create a label for the audited event.
static nvtxDomainHandle_t s_domain
tbb::concurrent_hash_map< std::string, nvtxRangeId_t > m_ranges
nvtxRangeId_t start_range(std::string const &label, EventContext const &ctx)
Start an NVTX range for the audited event.
std::string make_key(std::string const &event, std::string const &caller, EventContext const &ctx) const
Helper to create an identifier key for storing an associated range in the map.

◆ before()

void NVTXAuditor::before ( std::string const & event,
std::string const & caller,
EventContext const & ctx )
inlineoverrideprivate

Handle 'before' audit for given event by starting an associated NVTX range.

Parameters
eventThe name of the audited event.
callerThe name of the caller of the audited event.
ctxThe EventContext associated with the audited event.
Note
In case of a suspension event, the range for the execution is closed instead of creating a range for suspension.

Definition at line 219 of file NVTXAuditor.cpp.

219 {
220 // Suspension pauses the execution, so close the currently active
221 // execution range instead of creating a range for the suspension.
222 if ( IAuditor::Suspension == event ) {
223 auto execute_key = make_key( IAuditor::Execute, caller, ctx );
224 auto acc = decltype( m_ranges )::accessor{};
225 if ( !m_ranges.find( acc, execute_key ) ) {
226 error() << std::format( "Execution range for {} does not exist while suspending", execute_key ) << endmsg;
227 } else {
228 nvtxDomainRangeEnd( s_domain, acc->second );
229 m_ranges.erase( acc );
230 debug() << std::format( "Suspended execution range for {}", execute_key ) << endmsg;
231 }
232 return;
233 }
234
235 auto key = make_key( event, caller, ctx );
236 auto label = make_label( event, caller );
237 auto id = start_range( label, ctx );
238 auto ret = m_ranges.emplace( key, id );
239 if ( !ret ) {
240 error() << std::format( "Range for {} already exists", key ) << endmsg;
241 nvtxDomainRangeEnd( s_domain, id ); // the newly started range would otherwise never be closed
242 } else {
243 debug() << std::format( "Started range for {}", key ) << endmsg;
244 }
245 }

◆ finalize()

StatusCode NVTXAuditor::finalize ( )
inlineoverrideprivatevirtual

Finalize the auditor, releasing the NVTX domain.

Returns
StatusCode indicating success or failure.

Reimplemented from Gaudi::Auditor.

Definition at line 117 of file NVTXAuditor.cpp.

117 {
118 if ( s_domain ) {
119 nvtxDomainDestroy( s_domain );
120 s_domain = nullptr;
121 }
122 return base_class::finalize();
123 }

◆ handle()

void NVTXAuditor::handle ( const Incident & incident)
inlineoverrideprivate

Handle an incident by annotating it with an NVTX marker.

Parameters
incidentThe incident to handle.

Annotates the given incident with an NVTX marker. If the incident has a valid event context, the marker is annotated with event number in the payload, colored based on event number and put in category based on event slot. If the incident does not have a valid event context, the marker is created without payload, default color and default category.

Definition at line 134 of file NVTXAuditor.cpp.

134 {
135 auto eventAttrib = nvtxEventAttributes_t{};
136 eventAttrib.version = NVTX_VERSION;
137 eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
138 eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
139 eventAttrib.message.ascii = incident.type().c_str();
140
141 if ( !incident.context().valid() ) {
142 nvtxDomainMarkEx( s_domain, &eventAttrib );
143 debug() << std::format( "Marked incident {} from {}", incident.type(), incident.source() ) << endmsg;
144 return;
145 }
146
147 eventAttrib.colorType = NVTX_COLOR_ARGB;
148 eventAttrib.color = ::cycle_color( incident.context().evt() );
149 eventAttrib.category = incident.context().slot() + 1;
150 eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
151 eventAttrib.payload.ullValue = incident.context().evt();
152
153 nvtxDomainMarkEx( s_domain, &eventAttrib );
154 debug() << std::format( "Marked incident {} from {} with context {}", incident.type(), incident.source(),
155 incident.context() )
156 << endmsg;
157 }
ContextEvt_t evt() const
ContextID_t slot() const
bool valid() const
const EventContext & context() const
Access to the EventContext of the source of the incident.
Definition Incident.h:55
const std::string & type() const
Access to the incident type.
Definition Incident.h:43
const std::string & source() const
Access to the source of the incident.
Definition Incident.h:49

◆ initialize()

StatusCode NVTXAuditor::initialize ( )
inlineoverrideprivatevirtual

Initialize the auditor and register for all available incidents if the Incident service exists.

Returns
StatusCode indicating success or failure.
Note
Creates the NVTX domain and categories, which must be done only once.

Name a category for each slot in the HiveWhiteBoard

name a category for a single slot if no HiveWhiteBoard

Reimplemented from Gaudi::Auditor.

Definition at line 77 of file NVTXAuditor.cpp.

77 {
78
79 return base_class::initialize()
80 .andThen( [this]() {
81 auto incidentSvc = service<IIncidentSvc>( "IncidentSvc" );
82 if ( incidentSvc.isValid() ) {
83 incidentSvc->addListener( this, "ALL" );
84 } else {
85 info() << "No IncidentSvc, NVTXAuditor will not be able to annotate incidents." << endmsg;
86 }
87 } )
88 .andThen( [this]() {
89 if ( s_numCategories > 0 ) {
90 error() << "Attempting to initialize NVTX categories more than once." << endmsg;
92 }
93
94 s_domain = nvtxDomainCreateA( "Gaudi" );
95
96 auto hiveWhiteBoard = service<IHiveWhiteBoard>( "EventDataSvc" );
97 if ( hiveWhiteBoard.isValid() ) {
99 s_numCategories = hiveWhiteBoard->getNumberOfStores();
100 for ( auto slot = 0u; slot < s_numCategories; ++slot ) {
101 // slot + 1 for 1-indexing of categories in NVTX
102 nvtxDomainNameCategoryA( s_domain, slot + 1, std::format( "Slot {}", slot ).c_str() );
103 }
104 } else {
106 s_numCategories = 1;
107 nvtxDomainNameCategoryA( s_domain, 1, "Slot 0" );
108 }
109 return StatusCode::SUCCESS;
110 } );
111 }
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
SmartIF< T > service(std::string_view name, bool createIf=false) const
Access a service by name, creating it if it doesn't already exist.
Definition Auditor.h:63
static uint32_t s_numCategories
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100

◆ make_key()

std::string NVTXAuditor::make_key ( std::string const & event,
std::string const & caller,
EventContext const & ctx ) const
inlineprivate

Helper to create an identifier key for storing an associated range in the map.

Parameters
eventThe name of the audited event.
callerThe name of the caller of the audited event.
ctxThe event context associated with the audited event.
Returns
A key for the event.

Definition at line 166 of file NVTXAuditor.cpp.

166 {
167 if ( ctx.valid() ) { return std::format( "{}:{}:{}", caller, event, ctx.evt() ); }
168 return std::format( "{}:{}", caller, event );
169 }

◆ make_label()

std::string NVTXAuditor::make_label ( std::string const & event,
std::string const & caller ) const
inlineprivate

Helper to create a label for the audited event.

Definition at line 174 of file NVTXAuditor.cpp.

174 {
175 return std::format( "{}:{}", caller, event );
176 }

◆ start_range()

nvtxRangeId_t NVTXAuditor::start_range ( std::string const & label,
EventContext const & ctx )
inlineprivate

Start an NVTX range for the audited event.

Parameters
labelThe label to attach to the range.
ctxThe event context associated with the audited event.
Returns
The opaque handle for the started NVTX range.

Starts an NVTX range for the audited event. If the context is valid, the range is annotated with event number in the payload, colored based on event number and put in category based on event slot. If the context is not valid, the range is created without payload, default color and default category.

Definition at line 187 of file NVTXAuditor.cpp.

187 {
188 auto eventAttrib = nvtxEventAttributes_t{};
189 eventAttrib.version = NVTX_VERSION;
190 eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
191 eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
192 eventAttrib.message.ascii = label.c_str();
193
194 if ( !ctx.valid() ) {
195 debug() << std::format( "Starting range for {}", label ) << endmsg;
196 return nvtxDomainRangeStartEx( s_domain, &eventAttrib );
197 }
198
199 eventAttrib.colorType = NVTX_COLOR_ARGB;
200 eventAttrib.color = ::cycle_color( ctx.evt() );
201 eventAttrib.category = ctx.slot() + 1;
202 eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
203 eventAttrib.payload.ullValue = ctx.evt();
204
205 debug() << std::format( "Starting range for {} with context {}", label, ctx ) << endmsg;
206 return nvtxDomainRangeStartEx( s_domain, &eventAttrib );
207 }

Member Data Documentation

◆ m_ranges

tbb::concurrent_hash_map<std::string, nvtxRangeId_t> NVTXAuditor::m_ranges
private

Definition at line 69 of file NVTXAuditor.cpp.

◆ s_domain

nvtxDomainHandle_t NVTXAuditor::s_domain { nullptr }
inlinestaticprivate

Definition at line 60 of file NVTXAuditor.cpp.

60{ nullptr };

◆ s_numCategories

uint32_t NVTXAuditor::s_numCategories { 0 }
inlinestaticprivate

Definition at line 64 of file NVTXAuditor.cpp.

64{ 0 };

The documentation for this class was generated from the following file: