QUDA  v1.1.0
A library for QCD on GPUs
timer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifdef __CUDACC_RTC__
4 
5 namespace quda {
6  // dummy Implementation that can safely be parsed by nvrtc
7  enum QudaProfileType { };
8 
9  class TimeProfile {
10  public:
11  TimeProfile(std::string fname);
12  TimeProfile(std::string fname, bool use_global);
13  void Print();
14  void Start_(const char *func, const char *file, int line, QudaProfileType idx);
15  void Stop_(const char *func, const char *file, int line, QudaProfileType idx);
16  void Reset_(const char *func, const char *file, int line);
17  double Last(QudaProfileType idx);
18  void PrintGlobal();
19  bool isRunning(QudaProfileType idx);
20  };
21 }
22 
23 #else
24 
25 #include <sys/time.h>
26 
27 #ifdef INTERFACE_NVTX
28 #if QUDA_NVTX_VERSION == 3
29 #include "nvtx3/nvToolsExt.h"
30 #else
31 #include "nvToolsExt.h"
32 #endif
33 #endif
34 
35 namespace quda {
36 
42  struct Timer {
44  double time;
45 
47  double last;
48 
50  timeval start;
51 
53  timeval stop;
54 
56  bool running;
57 
59  int count;
60 
61  Timer() : time(0.0), last(0.0), running(false), count(0) { ; }
62 
63  void Start(const char *func, const char *file, int line) {
64  if (running) {
65  printfQuda("ERROR: Cannot start an already running timer (%s:%d in %s())\n", file, line, func);
66  errorQuda("Aborting");
67  }
68  gettimeofday(&start, NULL);
69  running = true;
70  }
71 
72  void Stop(const char *func, const char *file, int line) {
73  if (!running) {
74  printfQuda("ERROR: Cannot stop an unstarted timer (%s:%d in %s())\n", file, line, func);
75  errorQuda("Aborting");
76  }
77  gettimeofday(&stop, NULL);
78 
79  long ds = stop.tv_sec - start.tv_sec;
80  long dus = stop.tv_usec - start.tv_usec;
81  last = ds + 0.000001*dus;
82  time += last;
83  count++;
84 
85  running = false;
86  }
87 
88  double Last() { return last; }
89 
90  void Reset(const char *func, const char *file, int line) {
91  if (running) {
92  printfQuda("ERROR: Cannot reset a started timer (%s:%d in %s())\n", file, line, func);
93  errorQuda("Aborting");
94  }
95  time = 0.0;
96  last = 0.0;
97  count = 0;
98  }
99 
100  };
101 
121  // lower level counters used in the dslash and api profiling
151  };
152 
153 #ifdef INTERFACE_NVTX
154 
155 #define PUSH_RANGE(name,cid) { \
156  int color_id = cid; \
157  color_id = color_id%nvtx_num_colors;\
158  nvtxEventAttributes_t eventAttrib = {0}; \
159  eventAttrib.version = NVTX_VERSION; \
160  eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE; \
161  eventAttrib.colorType = NVTX_COLOR_ARGB; \
162  eventAttrib.color = nvtx_colors[color_id]; \
163  eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII; \
164  eventAttrib.message.ascii = name; \
165  eventAttrib.category = cid;\
166  nvtxRangePushEx(&eventAttrib); \
167 }
168 #define POP_RANGE nvtxRangePop();
169 #else
170 #define PUSH_RANGE(name,cid)
171 #define POP_RANGE
172 #endif
173 
174  class TimeProfile {
175  std::string fname;
176 #ifdef INTERFACE_NVTX
177  static const uint32_t nvtx_colors[];// = { 0x0000ff00, 0x000000ff, 0x00ffff00, 0x00ff00ff, 0x0000ffff, 0x00ff0000, 0x00ffffff };
178  static const int nvtx_num_colors;// = sizeof(nvtx_colors)/sizeof(uint32_t);
179 #endif
180  Timer profile[QUDA_PROFILE_COUNT];
181  static std::string pname[];
182 
183  bool switchOff;
184  bool use_global;
185 
186  // global timer
187  static Timer global_profile[QUDA_PROFILE_COUNT];
188  static bool global_switchOff[QUDA_PROFILE_COUNT];
189  static int global_total_level[QUDA_PROFILE_COUNT]; // zero initialize
190 
191  static void StopGlobal(const char *func, const char *file, int line, QudaProfileType idx) {
192 
193  global_total_level[idx]--;
194  if (global_total_level[idx]==0) global_profile[idx].Stop(func,file,line);
195 
196  // switch off total timer if we need to
197  if (global_switchOff[idx]) {
198  global_total_level[idx]--;
199  if (global_total_level[idx]==0) global_profile[idx].Stop(func,file,line);
200  global_switchOff[idx] = false;
201  }
202  }
203 
204  static void StartGlobal(const char *func, const char *file, int line, QudaProfileType idx) {
205  // if total timer isn't running, then start it running
206  if (!global_profile[idx].running) {
207  global_profile[idx].Start(func,file,line);
208  global_total_level[idx]++;
209  global_switchOff[idx] = true;
210  }
211 
212  if (global_total_level[idx]==0) global_profile[idx].Start(func,file,line);
213  global_total_level[idx]++;
214  }
215 
216  public:
217  TimeProfile(std::string fname) : fname(fname), switchOff(false), use_global(true) { ; }
218 
219  TimeProfile(std::string fname, bool use_global) : fname(fname), switchOff(false), use_global(use_global) { ; }
220 
222  void Print();
223 
224  void Start_(const char *func, const char *file, int line, QudaProfileType idx) {
225  // if total timer isn't running, then start it running
226  if (!profile[QUDA_PROFILE_TOTAL].running && idx != QUDA_PROFILE_TOTAL) {
227  profile[QUDA_PROFILE_TOTAL].Start(func,file,line);
228  switchOff = true;
229  }
230 
231  profile[idx].Start(func, file, line);
232  PUSH_RANGE(fname.c_str(),idx)
233  if (use_global) StartGlobal(func,file,line,idx);
234  }
235 
236 
237  void Stop_(const char *func, const char *file, int line, QudaProfileType idx) {
238  profile[idx].Stop(func, file, line);
239  POP_RANGE
240 
241  // switch off total timer if we need to
242  if (switchOff && idx != QUDA_PROFILE_TOTAL) {
243  profile[QUDA_PROFILE_TOTAL].Stop(func,file,line);
244  switchOff = false;
245  }
246  if (use_global) StopGlobal(func,file,line,idx);
247  }
248 
249  void Reset_(const char *func, const char *file, int line) {
250  for (int idx=0; idx<QUDA_PROFILE_COUNT; idx++)
251  profile[idx].Reset(func, file, line);
252  }
253 
254  double Last(QudaProfileType idx) {
255  return profile[idx].last;
256  }
257 
258  static void PrintGlobal();
259 
260  bool isRunning(QudaProfileType idx) { return profile[idx].running; }
261 
262  };
263 
264 } // namespace quda
265 
266 #endif
267 
268 
269 #undef PUSH_RANGE
270 #undef POP_RANGE
271 
272 #define TPSTART(idx) Start_(__func__, __FILE__, __LINE__, idx)
273 #define TPSTOP(idx) Stop_(__func__, __FILE__, __LINE__, idx)
274 #define TPRESET() Reset_(__func__, __FILE__, __LINE__)
275 
void Print()
Definition: timer.cpp:7
TimeProfile(std::string fname, bool use_global)
Definition: timer.h:219
static void PrintGlobal()
Definition: timer.cpp:84
double Last(QudaProfileType idx)
Definition: timer.h:254
void Start_(const char *func, const char *file, int line, QudaProfileType idx)
Definition: timer.h:224
bool isRunning(QudaProfileType idx)
Definition: timer.h:260
TimeProfile(std::string fname)
Definition: timer.h:217
void Stop_(const char *func, const char *file, int line, QudaProfileType idx)
Definition: timer.h:237
void Reset_(const char *func, const char *file, int line)
Definition: timer.h:249
QudaProfileType
Definition: timer.h:103
@ QUDA_PROFILE_INIT
Definition: timer.h:106
@ QUDA_PROFILE_MEMCPY_H2D_ASYNC
Definition: timer.h:141
@ QUDA_PROFILE_EVENT_SYNCHRONIZE
Definition: timer.h:134
@ QUDA_PROFILE_FUNC_SET_ATTRIBUTE
Definition: timer.h:132
@ QUDA_PROFILE_MEMCPY_D2D_ASYNC
Definition: timer.h:138
@ QUDA_PROFILE_DEVICE_SYNCHRONIZE
Definition: timer.h:136
@ QUDA_PROFILE_STREAM_SYNCHRONIZE
Definition: timer.h:135
@ QUDA_PROFILE_EVENT_QUERY
Definition: timer.h:130
@ QUDA_PROFILE_EPILOGUE
Definition: timer.h:110
@ QUDA_PROFILE_HOST_COMPUTE
Definition: timer.h:119
@ QUDA_PROFILE_COUNT
Definition: timer.h:150
@ QUDA_PROFILE_STREAM_WAIT_EVENT
Definition: timer.h:131
@ QUDA_PROFILE_IO
Definition: timer.h:112
@ QUDA_PROFILE_COMMS
Definition: timer.h:109
@ QUDA_PROFILE_SCATTER
Definition: timer.h:126
@ QUDA_PROFILE_COMPUTE
Definition: timer.h:108
@ QUDA_PROFILE_EIGENQR
Definition: timer.h:117
@ QUDA_PROFILE_CONSTANT
Definition: timer.h:147
@ QUDA_PROFILE_TOTAL
Definition: timer.h:149
@ QUDA_PROFILE_EIGENEV
Definition: timer.h:116
@ QUDA_PROFILE_MEMCPY_DEFAULT_ASYNC
Definition: timer.h:142
@ QUDA_PROFILE_EIGENLU
Definition: timer.h:115
@ QUDA_PROFILE_ARPACK
Definition: timer.h:118
@ QUDA_PROFILE_MEMCPY_D2H_ASYNC
Definition: timer.h:139
@ QUDA_PROFILE_LAUNCH_KERNEL
Definition: timer.h:128
@ QUDA_PROFILE_LOWER_LEVEL
Definition: timer.h:122
@ QUDA_PROFILE_FREE
Definition: timer.h:111
@ QUDA_PROFILE_EVENT_RECORD
Definition: timer.h:129
@ QUDA_PROFILE_PREAMBLE
Definition: timer.h:107
@ QUDA_PROFILE_COMMS_QUERY
Definition: timer.h:145
@ QUDA_PROFILE_MEMCPY2D_D2H_ASYNC
Definition: timer.h:140
@ QUDA_PROFILE_CHRONO
Definition: timer.h:113
@ QUDA_PROFILE_COMMS_START
Definition: timer.h:144
@ QUDA_PROFILE_GATHER
Definition: timer.h:125
@ QUDA_PROFILE_PACK_KERNEL
Definition: timer.h:123
@ QUDA_PROFILE_DSLASH_KERNEL
Definition: timer.h:124
@ QUDA_PROFILE_EIGEN
Definition: timer.h:114
@ QUDA_PROFILE_H2D
Definition: timer.h:104
@ QUDA_PROFILE_D2H
Definition: timer.h:105
::std::string string
Definition: gtest-port.h:891
void Stop(const char *func, const char *file, int line)
Definition: timer.h:72
double Last()
Definition: timer.h:88
void Reset(const char *func, const char *file, int line)
Definition: timer.h:90
timeval stop
Definition: timer.h:53
bool running
Definition: timer.h:56
Timer()
Definition: timer.h:61
void Start(const char *func, const char *file, int line)
Definition: timer.h:63
timeval start
Definition: timer.h:50
int count
Definition: timer.h:59
double time
Definition: timer.h:44
double last
Definition: timer.h:47
#define POP_RANGE
Definition: timer.h:171
#define PUSH_RANGE(name, cid)
Definition: timer.h:170
#define printfQuda(...)
Definition: util_quda.h:114
#define errorQuda(...)
Definition: util_quda.h:120