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 //
155 // Enable Projections trace events when built against CMK_TRACE_ENABLED
156 // version of Charm++ by defining NAMD_CMK_TRACE_ENABLED in Make.config
157 //
158 #elif defined(CMK_TRACE_ENABLED) && defined(NAMD_CMK_TRACE_ENABLED)
159 
160 // XXX should be more general than tracing Sequencer functions
161 // XXX why offset event numbers by 150?
162 #define SEQUENCER_EVENT_ID_START 150
163 
164 #define NAMD_PROFILE_START() \
165  do { } while(0) // must terminate with semi-colon
166 
167 #define NAMD_PROFILE_STOP() \
168  do { } while(0) // must terminate with semi-colon
169 
170 #define NAMD_REGISTER_EVENT(name,id) \
171  do { \
172  int eventID = SEQUENCER_EVENT_ID_START+id; \
173  traceRegisterUserEvent(name, eventID); \
174  } while(0) // must terminate with semi-colon
175 
176 #define NAMD_EVENT_START(eon,id) \
177  do {\
178  if (eon) { \
179  int eventID = SEQUENCER_EVENT_ID_START+id; \
180  traceBeginUserBracketEvent(eventID); \
181  } \
182  } while(0) // must terminate with semi-colon
183 
184 #define NAMD_EVENT_START_EX(eon,id,str) \
185  NAMD_EVENT_START(eon,id)
186 
187 #define NAMD_EVENT_STOP(eon,id) \
188  do { \
189  if (eon) { \
190  int eventID = SEQUENCER_EVENT_ID_START+id; \
191  traceEndUserBracketEvent(eventID); \
192  } \
193  } while(0) // must terminate with semi-colon
194 
195 // XXX should be more general than Sequencer
196 class NAMD_Sequencer_Events_Tracer {
197  int tEventID;
198  int tEventOn;
199  public:
200  NAMD_Sequencer_Events_Tracer(int eon, int id = 0)
201  : tEventOn(eon), tEventID(id) {
202  NAMD_EVENT_START(tEventOn, tEventID);
203  }
204  ~NAMD_Sequencer_Events_Tracer() {
205  NAMD_EVENT_STOP(tEventOn, tEventID);
206  }
207 };
208 
209 // call NAMD_EVENT_RANGE at beginning of function to push event recording
210 // destructor is automatically called on return to pop event recording
211 #define NAMD_EVENT_RANGE(eon,id) \
212  NAMD_Sequencer_Events_Tracer namd_events_tracer(eon,id)
213  // must terminate with semi-colon
214 
215 #if defined(NAMD_PROFILE_EVENT_LAYER_2)
216 #define NAMD_EVENT_RANGE_2(eon,id) \
217  NAMD_EVENT_RANGE(eon,id)
218 #else
219 #define NAMD_EVENT_RANGE_2(eon,id) \
220  do { } while(0) // must terminate with semi-colon
221 #endif
222 
223 #else
224 
225 //
226 // Otherwise all profiling macros become no-ops.
227 //
228 #define NAMD_PROFILE_START() \
229  do { } while(0) // must terminate with semi-colon
230 
231 #define NAMD_PROFILE_STOP() \
232  do { } while(0) // must terminate with semi-colon
233 
234 #define NAMD_REGISTER_EVENT(name,cid) \
235  do { } while(0) // must terminate with semi-colon
236 
237 #define NAMD_EVENT_START(eon,id) \
238  do { } while(0) // must terminate with semi-colon
239 
240 #define NAMD_EVENT_START_EX(eon,id,str) \
241  do { } while(0) // must terminate with semi-colon
242 
243 #define NAMD_EVENT_STOP(eon,id) \
244  do { } while(0) // must terminate with semi-colon
245 
246 #define NAMD_EVENT_RANGE(eon,id) \
247  do { } while(0) // must terminate with semi-colon
248 
249 #define NAMD_EVENT_RANGE_2(eon,id) \
250  do { } while(0) // must terminate with semi-colon
251 
252 #endif // NAMD_CUDA && NAMD_NVTX_ENABLED
253 
254 #endif /* NAMDEVENTSPROFILING_H */
#define NAMD_EVENT_STOP(eon, id)
char const *const NamdProfileEventStr[]
#define NAMD_EVENT_START(eon, id)