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