Hedgehog  0.0.0
A library to generate hybrid pipeline workflow systems
nvtx_profiler.h
1 // NIST-developed software is provided by NIST as a public service. You may use, copy and distribute copies of the
2 // software in any medium, provided that you keep intact this entire notice. You may improve, modify and create
3 // derivative works of the software or any portion of the software, and you may copy and distribute such modifications
4 // or works. Modified works should carry a notice stating that you changed the software and should note the date and
5 // nature of any such change. Please explicitly acknowledge the National Institute of Standards and Technology as the
6 // source of the software. NIST-developed software is expressly provided "AS IS." NIST MAKES NO WARRANTY OF ANY KIND,
7 // EXPRESS, IMPLIED, IN FACT OR ARISING BY OPERATION OF LAW, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTY OF
8 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT AND DATA ACCURACY. NIST NEITHER REPRESENTS NOR
9 // WARRANTS THAT THE OPERATION OF THE SOFTWARE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT ANY DEFECTS WILL BE
10 // CORRECTED. NIST DOES NOT WARRANT OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF THE SOFTWARE OR THE RESULTS
11 // THEREOF, INCLUDING BUT NOT LIMITED TO THE CORRECTNESS, ACCURACY, RELIABILITY, OR USEFULNESS OF THE SOFTWARE. You
12 // are solely responsible for determining the appropriateness of using and distributing the software and you assume
13 // all risks associated with its use, including but not limited to the risks and costs of program errors, compliance
14 // with applicable laws, damage to or loss of data, programs or equipment, and the unavailability or interruption of
15 // operation. This software is not intended to be used in any situation where a failure could cause risk of injury or
16 // damage to property. The software developed by NIST employees is not subject to copyright protection within the
17 // United States.
18 
19 
20 #ifndef HEDGEHOG_NVTX_PROFILER_H
21 #define HEDGEHOG_NVTX_PROFILER_H
22 
23 #ifdef HH_USE_NVTX
24 #include <nvtx3/nvToolsExt.h>
25 #endif
26 
27 #include <string_view>
28 #include <cstring>
29 #include <iostream>
30 
32 namespace hh {
33 #define NVTX_COLOR_INITIALIZING 0xFF123456
34 #define NVTX_COLOR_EXECUTING 0xFF72ff68
35 #define NVTX_COLOR_WAITING 0xFFff7f83
36 #define NVTX_COLOR_WAITING_FOR_MEM 0xFFffc86a
37 #define NVTX_COLOR_RELEASE_MEM 0xFF7fbdff
38 #define NVTX_COLOR_SHUTTING_DOWN 0xFF654321
39 
57 class NvtxProfiler {
58  private:
59 #ifdef HH_USE_NVTX
60  std::string_view initializeName_{};
61  std::string_view executeName_{};
62  std::string_view waitName_{};
63  std::string_view waitForMemName_{};
64  std::string_view releaseMemName_{};
65  std::string_view shutdownName_{};
66 
67  nvtxDomainHandle_t taskDomain_;
68 
69  nvtxStringHandle_t initializeString_{};
70  nvtxStringHandle_t executeString_{};
71  nvtxStringHandle_t waitString_{};
72  nvtxStringHandle_t waitForMemString_{};
73  nvtxStringHandle_t releaseMemString_{};
74  nvtxStringHandle_t shutdownString_{};
75 
76  nvtxEventAttributes_t *initializeAttrib_;
77  nvtxEventAttributes_t *executeAttrib_;
78  nvtxEventAttributes_t *waitAttrib_;
79  nvtxEventAttributes_t *waitForMemAttrib_;
80  nvtxEventAttributes_t *releaseMemAttrib_;
81  nvtxEventAttributes_t *shutdownAttrib_;
82 
83  nvtxRangeId_t initializeRangeId_ = 0;
84  nvtxRangeId_t executeRangeId_ = 0;
85  nvtxRangeId_t waitRangeId_ = 0;
86  nvtxRangeId_t waitForMemRangeId_ = 0;
87  nvtxRangeId_t shutdownRangeId_ = 0;
88 
89 
92  nvtxEventAttributes_t *createEventAttribute(uint32_t color) {
93  nvtxEventAttributes_t *event = new nvtxEventAttributes_t;
94  bzero(event, NVTX_EVENT_ATTRIB_STRUCT_SIZE);
95  event->version = NVTX_VERSION;
96  event->size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
97  event->colorType = NVTX_COLOR_ARGB;
98  event->color = color;
99  return event;
100  }
101 #endif
102 
103  public:
104 
106  NvtxProfiler() = delete;
107 
108 
109 #ifdef HH_USE_NVTX
110  explicit NvtxProfiler(std::string_view const & taskName) {
115  taskDomain_ = nvtxDomainCreateA(taskName.data());
116 
117  initializeAttrib_ = createEventAttribute(NVTX_COLOR_INITIALIZING);
118  executeAttrib_ = createEventAttribute(NVTX_COLOR_EXECUTING);
119 
120  waitAttrib_ = createEventAttribute(NVTX_COLOR_WAITING);
121  waitAttrib_->payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
122 
123  waitAttrib_->payload.ullValue = 0;
124 
125  waitForMemAttrib_ = createEventAttribute(NVTX_COLOR_WAITING_FOR_MEM);
126  releaseMemAttrib_ = createEventAttribute(NVTX_COLOR_RELEASE_MEM);
127  shutdownAttrib_ = createEventAttribute(NVTX_COLOR_SHUTTING_DOWN);
128  }
129 #else //HH_USE_NVTX
130  explicit NvtxProfiler(std::string_view const &) {}
134 #endif //HH_USE_NVTX
135 
136 #ifdef HH_USE_NVTX
137  ~NvtxProfiler() {
139  delete initializeAttrib_;
140  delete executeAttrib_;
141  delete waitAttrib_;
142  delete waitForMemAttrib_;
143  delete releaseMemAttrib_;
144  delete shutdownAttrib_;
145  nvtxDomainDestroy(taskDomain_);
146  }
147 #else //HH_USE_NVTX
148  ~NvtxProfiler() = default;
150 #endif //HH_USE_NVTX
151 
155  void initialize([[maybe_unused]]int threadId) {
156 #ifdef HH_USE_NVTX
157  std::string prefixName(std::to_string(threadId));
158  initializeName_ = prefixName + ":Initializing";
159  executeName_ = prefixName + ":Executing";
160  waitName_ = prefixName + ":Waiting";
161  waitForMemName_ = prefixName + ":MemWait";
162  releaseMemName_ = prefixName + ":Release";
163  shutdownName_ = prefixName + ":Shutdown";
164 
165  initializeString_ = nvtxDomainRegisterStringA(taskDomain_, initializeName_.data());
166  executeString_ = nvtxDomainRegisterStringA(taskDomain_, executeName_.data());
167  waitString_ = nvtxDomainRegisterStringA(taskDomain_, waitName_.data());
168  waitForMemString_ = nvtxDomainRegisterStringA(taskDomain_, waitForMemName_.data());
169  releaseMemString_ = nvtxDomainRegisterStringA(taskDomain_, releaseMemName_.data());
170  shutdownString_ = nvtxDomainRegisterStringA(taskDomain_, shutdownName_.data());
171 
172  initializeAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
173  initializeAttrib_->message.registered = initializeString_;
174 
175  executeAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
176  executeAttrib_->message.registered = executeString_;
177 
178  waitAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
179  waitAttrib_->message.registered = waitString_;
180 
181  waitForMemAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
182  waitForMemAttrib_->message.registered = waitForMemString_;
183 
184  releaseMemAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
185  releaseMemAttrib_->message.registered = releaseMemString_;
186 
187  shutdownAttrib_->messageType = NVTX_MESSAGE_TYPE_REGISTERED;
188  shutdownAttrib_->message.registered = shutdownString_;
189 #endif
190  }
191 
194 #ifdef HH_USE_NVTX
195  nvtxDomainMarkEx(taskDomain_, releaseMemAttrib_);
196 #endif
197  }
198 
201 #ifdef HH_USE_NVTX
202  initializeRangeId_ = nvtxDomainRangeStartEx(taskDomain_, initializeAttrib_);
203 #endif
204  }
205 
208 #ifdef HH_USE_NVTX
209  executeRangeId_ = nvtxDomainRangeStartEx(taskDomain_, executeAttrib_);
210 #endif
211  }
212 
216  void startRangeWaiting([[maybe_unused]]uint64_t const &queueSize) {
217 #ifdef HH_USE_NVTX
218  waitAttrib_->payload.ullValue = queueSize;
219  waitRangeId_ = nvtxDomainRangeStartEx(taskDomain_, waitAttrib_);
220 #endif
221  }
222 
226 #ifdef HH_USE_NVTX
227  waitForMemRangeId_ = nvtxDomainRangeStartEx(taskDomain_, waitForMemAttrib_);
228 #endif
229  }
230 
233 #ifdef HH_USE_NVTX
234  shutdownRangeId_ = nvtxDomainRangeStartEx(taskDomain_, shutdownAttrib_);
235 #endif
236  }
237 
240 #ifdef HH_USE_NVTX
241  nvtxDomainRangeEnd(taskDomain_, initializeRangeId_);
242 #endif
243  }
244 
247 #ifdef HH_USE_NVTX
248  nvtxDomainRangeEnd(taskDomain_, executeRangeId_);
249 #endif
250  }
251 
254 #ifdef HH_USE_NVTX
255  nvtxDomainRangeEnd(taskDomain_, waitRangeId_);
256 #endif
257  }
258 
261 #ifdef HH_USE_NVTX
262  nvtxDomainRangeEnd(taskDomain_, waitForMemRangeId_);
263 #endif
264  }
265 
268 #ifdef HH_USE_NVTX
269  nvtxDomainRangeEnd(taskDomain_, shutdownRangeId_);
270 #endif
271  }
272 #ifdef HH_USE_NVTX
273 
274 
277  nvtxDomainHandle_t taskDomain() const {
278  return taskDomain_;
279  }
280 #endif
281 
282 };
283 }
284 #endif //HEDGEHOG_NVTX_PROFILER_H
A class to wrap calls to the NVTX library for tracking events that occur within an Hedgehog task grap...
Definition: nvtx_profiler.h:57
void startRangeWaiting([[maybe_unused]]uint64_t const &queueSize)
Starts tracking execution in the timeline to show when the task has started waiting for data...
void startRangeWaitingForMemory()
Starts tracking waiting for memory in the timeline to show when the task has started waiting for memo...
void endRangeWaiting()
Ends tracking the waiting for data for a task.
NvtxProfiler()=delete
Deleted default constructor.
Hedgehog main namespace.
void initialize([[maybe_unused]]int threadId)
Initializes the NvtxProfiler, and adds the threadId that is associated with the task.
void startRangeExecuting()
Starts tracking execution in the timeline to show when the task has started executing on data...
void endRangeWaitingForMem()
Ends tracking the waiting for memory from a memory edge.
void startRangeInitializing()
Starts tracking intialization in the timeline to show when the task has started its initialization ph...
void endRangeShuttingDown()
Ends tracking the shutdown phase for a task.
void endRangeInitializing()
Ends tracking the initialization phase for a task.
void addReleaseMarker()
Adds a release marker into the timeline to show when the task released memory.
void startRangeShuttingDown()
Starts tracking shutdown in the timeline to show when the task has started its shutdown phase...
~NvtxProfiler()=default
Destructor, deletes all attributes allocated.
void endRangeExecuting()
Ends tracking the execute for a task.