NAMD
NamdEventsProfiling.h
Go to the documentation of this file.
1 
7 #ifndef NAMDEVENTSPROFILING_H
8 #define NAMDEVENTSPROFILING_H
9 
10 #include "common.h"
11 #include <map>
12 
13 //
14 // Charm++ Projections requires user defined trace events to be registered
15 // with event ID tags and string names.
16 //
17 // Use the NAMD_PROFILE_EVENT macro within NamdEventsProfiling.def
18 // to define these event ID tags and string names. The IDs generate
19 // a set of enumerated types and corresponding array of string names.
20 //
22  typedef enum {
23  #define NAMD_PROFILE_EVENT(a,b) a,
24  #include "NamdEventsProfiling.def"
25  #undef NAMD_PROFILE_EVENT
27  } Event;
28 };
29 
30 char const* const NamdProfileEventStr[] = {
31  #define NAMD_PROFILE_EVENT(a,b) b,
32  #include "NamdEventsProfiling.def"
33  #undef NAMD_PROFILE_EVENT
34  0
35 };
36 
37 #undef NAMD_PROFILE_START
38 #undef NAMD_PROFILE_STOP
39 #undef NAMD_REGISTER_EVENT
40 #undef NAMD_EVENT_START
41 #undef NAMD_EVENT_START_EX
42 #undef NAMD_EVENT_STOP
43 #undef NAMD_EVENT_RANGE
44 #undef NAMD_EVENT_RANGE_2
45 
46 //
47 // Enable NVTX instrumentation for nvvp or Nsight profiling
48 // NAMD_CUDA build by defining NAMD_NVTX_ENABLED in Make.config
49 //
50 #if defined(NAMD_CUDA) && defined(NAMD_NVTX_ENABLED)
51 
52 #if CUDART_VERSION >= 10000
53 #include <nvtx3/nvToolsExt.h> // CUDA >= 10 has NVTX V3+
54 #include <nvtx3/nvToolsExtCuda.h>
55 #else
56 #error NVTXv3 requires CUDA 10.0 or greater
57 //#include <nvToolsExt.h> // CUDA < 10 has NVTX V2
58 #endif
59 #include <cuda_profiler_api.h>
60 
61 // start profiling
62 #define NAMD_PROFILE_START() \
63  do { \
64  cudaProfilerStart(); \
65  } while (0) // must terminate with semi-colon
66 
67 // stop profiling
68 #define NAMD_PROFILE_STOP() \
69  do { \
70  cudaProfilerStop(); \
71  } while (0) // must terminate with semi-colon
72 
73 // C++ note: declaring const variables implies static (internal) linkage,
74 // and you have to explicitly specify "extern" to get external linkage.
75 const uint32_t NAMD_nvtx_colors[] = {
76  0x0000ff00,
77  0x000000ff,
78  0x00ffff00,
79  0x00ff00ff,
80  0x0000ffff,
81  0x00ff0000,
82  0x00006600,
83  0x00663300,
84  0x00000000,
85  0x007300e6,
86  0x00ff8c00,
87 };
88 const int NAMD_nvtx_colors_len = sizeof(NAMD_nvtx_colors)/sizeof(uint32_t);
89 
90 #define NAMD_REGISTER_EVENT(name,cid) \
91  do { } while(0) // must terminate with semi-colon
92 
93 // start recording an event
94 #define NAMD_EVENT_START(eon,id) \
95  do { \
96  if (eon) { \
97  int color_id = id; \
98  color_id = color_id % NAMD_nvtx_colors_len; \
99  nvtxEventAttributes_t eventAttrib = {0}; \
100  eventAttrib.version = NVTX_VERSION; \
101  eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; \
102  eventAttrib.colorType = NVTX_COLOR_ARGB; \
103  eventAttrib.color = NAMD_nvtx_colors[color_id]; \
104  eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII; \
105  eventAttrib.message.ascii = NamdProfileEventStr[id]; \
106  nvtxRangePushEx(&eventAttrib); \
107  } \
108  } while(0) // must terminate with semi-colon
109 
110 // start recording an event
111 #define NAMD_EVENT_START_EX(eon,id,str) \
112  do { \
113  if (eon) { \
114  int color_id = id; \
115  color_id = color_id % NAMD_nvtx_colors_len; \
116  nvtxEventAttributes_t eventAttrib = {0}; \
117  eventAttrib.version = NVTX_VERSION; \
118  eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; \
119  eventAttrib.colorType = NVTX_COLOR_ARGB; \
120  eventAttrib.color = NAMD_nvtx_colors[color_id]; \
121  eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII; \
122  eventAttrib.message.ascii = str; \
123  nvtxRangePushEx(&eventAttrib); \
124  } \
125  } while(0) // must terminate with semi-colon
126 
127 // stop recording an event
128 #define NAMD_EVENT_STOP(eon,id) \
129  do { \
130  if (eon) { \
131  nvtxRangePop(); \
132  } \
133  } while (0) // must terminate with semi-colon
134 
135 // embed event recording in class to automatically pop when destroyed
136 class NAMD_NVTX_Tracer {
137  protected:
138  int evon; // is event on?
139  public:
140  NAMD_NVTX_Tracer(int eon, int id = 0) : evon(eon) {
141  NAMD_EVENT_START(eon, id);
142  }
143  ~NAMD_NVTX_Tracer() { NAMD_EVENT_STOP(evon, 0); }
144 };
145 
146 // call NAMD_EVENT_RANGE at beginning of function to push event recording
147 // destructor is automatically called on return to pop event recording
148 #define NAMD_EVENT_RANGE(eon,id) \
149  NAMD_NVTX_Tracer namd_nvtx_tracer(eon,id)
150  // must terminate with semi-colon
151 
152 #if defined(NAMD_PROFILE_EVENT_LAYER_2)
153 #define NAMD_EVENT_RANGE_2(eon,id) \
154  NAMD_EVENT_RANGE(eon,id)
155 #else
156 #define NAMD_EVENT_RANGE_2(eon,id) \
157  do { } while(0) // must terminate with semi-colon
158 #endif
159 
160 #elif defined(NAMD_HIP) && defined(NAMD_ROCTX_ENABLED)
161 
162 #include <roctracer.h>
163 #include <roctracer_ext.h>
164 #include <roctx.h>
165 
166 // start profiling
167 #define NAMD_PROFILE_START() \
168  do { \
169  roctracer_start(); \
170  } while (0) // must terminate with semi-colon
171 
172 // stop profiling
173 #define NAMD_PROFILE_STOP() \
174  do { \
175  roctracer_stop(); \
176  } while (0) // must terminate with semi-colon
177 
178 #define NAMD_REGISTER_EVENT(name,cid) \
179  do { } while(0) // must terminate with semi-colon
180 
181 // start recording an event
182 #define NAMD_EVENT_START(eon,id) \
183  do { \
184  if (eon) { \
185  roctxRangePush(NamdProfileEventStr[id]); \
186  } \
187  } while(0) // must terminate with semi-colon
188 
189 // start recording an event
190 #define NAMD_EVENT_START_EX(eon,id,str) \
191  do { \
192  if (eon) { \
193  roctxRangePush(str); \
194  } \
195  } while(0) // must terminate with semi-colon
196 
197 // stop recording an event
198 #define NAMD_EVENT_STOP(eon,id) \
199  do { \
200  if (eon) { \
201  roctxRangePop(); \
202  } \
203  } while (0) // must terminate with semi-colon
204 
205 // embed event recording in class to automatically pop when destroyed
206 class NAMD_ROCTX_Tracer {
207  protected:
208  int evon; // is event on?
209  public:
210  NAMD_ROCTX_Tracer(int eon, int id = 0) : evon(eon) {
211  NAMD_EVENT_START(eon, id);
212  }
213  ~NAMD_ROCTX_Tracer() { NAMD_EVENT_STOP(evon, 0); }
214 };
215 
216 // call NAMD_EVENT_RANGE at beginning of function to push event recording
217 // destructor is automatically called on return to pop event recording
218 #define NAMD_EVENT_RANGE(eon,id) \
219  NAMD_ROCTX_Tracer namd_roctx_tracer(eon,id)
220  // must terminate with semi-colon
221 
222 #if defined(NAMD_PROFILE_EVENT_LAYER_2)
223 #define NAMD_EVENT_RANGE_2(eon,id) \
224  NAMD_EVENT_RANGE(eon,id)
225 #else
226 #define NAMD_EVENT_RANGE_2(eon,id) \
227  do { } while(0) // must terminate with semi-colon
228 #endif
229 //
230 // Enable Projections trace events when built against CMK_TRACE_ENABLED
231 // version of Charm++ by defining NAMD_CMK_TRACE_ENABLED in Make.config
232 //
233 #elif defined(CMK_TRACE_ENABLED) && defined(NAMD_CMK_TRACE_ENABLED)
234 
235 // XXX should be more general than tracing Sequencer functions
236 // XXX why offset event numbers by 150?
237 #define SEQUENCER_EVENT_ID_START 150
238 
239 #define NAMD_PROFILE_START() \
240  do { } while(0) // must terminate with semi-colon
241 
242 #define NAMD_PROFILE_STOP() \
243  do { } while(0) // must terminate with semi-colon
244 
245 #define NAMD_REGISTER_EVENT(name,id) \
246  do { \
247  int eventID = SEQUENCER_EVENT_ID_START+id; \
248  traceRegisterUserEvent(name, eventID); \
249  } while(0) // must terminate with semi-colon
250 
251 #define NAMD_EVENT_START(eon,id) \
252  do {\
253  if (eon) { \
254  int eventID = SEQUENCER_EVENT_ID_START+id; \
255  traceBeginUserBracketEvent(eventID); \
256  } \
257  } while(0) // must terminate with semi-colon
258 
259 #define NAMD_EVENT_START_EX(eon,id,str) \
260  NAMD_EVENT_START(eon,id)
261 
262 #define NAMD_EVENT_STOP(eon,id) \
263  do { \
264  if (eon) { \
265  int eventID = SEQUENCER_EVENT_ID_START+id; \
266  traceEndUserBracketEvent(eventID); \
267  } \
268  } while(0) // must terminate with semi-colon
269 
270 // XXX should be more general than Sequencer
271 class NAMD_Sequencer_Events_Tracer {
272  int tEventID;
273  int tEventOn;
274  public:
275  NAMD_Sequencer_Events_Tracer(int eon, int id = 0)
276  : tEventOn(eon), tEventID(id) {
277  NAMD_EVENT_START(tEventOn, tEventID);
278  }
279  ~NAMD_Sequencer_Events_Tracer() {
280  NAMD_EVENT_STOP(tEventOn, tEventID);
281  }
282 };
283 
284 // call NAMD_EVENT_RANGE at beginning of function to push event recording
285 // destructor is automatically called on return to pop event recording
286 #define NAMD_EVENT_RANGE(eon,id) \
287  NAMD_Sequencer_Events_Tracer namd_events_tracer(eon,id)
288  // must terminate with semi-colon
289 
290 #if defined(NAMD_PROFILE_EVENT_LAYER_2)
291 #define NAMD_EVENT_RANGE_2(eon,id) \
292  NAMD_EVENT_RANGE(eon,id)
293 #else
294 #define NAMD_EVENT_RANGE_2(eon,id) \
295  do { } while(0) // must terminate with semi-colon
296 #endif
297 
298 #else
299 
300 //
301 // Otherwise all profiling macros become no-ops.
302 //
303 #define NAMD_PROFILE_START() \
304  do { } while(0) // must terminate with semi-colon
305 
306 #define NAMD_PROFILE_STOP() \
307  do { } while(0) // must terminate with semi-colon
308 
309 #define NAMD_REGISTER_EVENT(name,cid) \
310  do { } while(0) // must terminate with semi-colon
311 
312 #define NAMD_EVENT_START(eon,id) \
313  do { } while(0) // must terminate with semi-colon
314 
315 #define NAMD_EVENT_START_EX(eon,id,str) \
316  do { } while(0) // must terminate with semi-colon
317 
318 #define NAMD_EVENT_STOP(eon,id) \
319  do { } while(0) // must terminate with semi-colon
320 
321 #define NAMD_EVENT_RANGE(eon,id) \
322  do { } while(0) // must terminate with semi-colon
323 
324 #define NAMD_EVENT_RANGE_2(eon,id) \
325  do { } while(0) // must terminate with semi-colon
326 
327 #endif // NAMD_CUDA && NAMD_NVTX_ENABLED
328 
329 #endif /* NAMDEVENTSPROFILING_H */
#define NAMD_EVENT_STOP(eon, id)
char const *const NamdProfileEventStr[]
#define NAMD_EVENT_START(eon, id)