1 //===------------- debug.h - NVPTX OpenMP debug macros ----------- CUDA -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains debug macros to be used in the application.
10 //
11 //   Usage guide
12 //
13 //   PRINT0(flag, str)        : if debug flag is on, print (no arguments)
14 //   PRINT(flag, str, args)   : if debug flag is on, print (arguments)
15 //   DON(flag)                : return true if debug flag is on
16 //
17 //   ASSERT(flag, cond, str, args): if test flag is on, test the condition
18 //                                  if the condition is false, print str+args
19 //          and assert.
20 //          CAUTION: cond may be evaluate twice
21 //   AON(flag)                     : return true if test flag is on
22 //
23 //   WARNING(flag, str, args)      : if warning flag is on, print the warning
24 //   WON(flag)                     : return true if warning flag is on
25 //
26 //===----------------------------------------------------------------------===//
27 
28 #ifndef _OMPTARGET_NVPTX_DEBUG_H_
29 #define _OMPTARGET_NVPTX_DEBUG_H_
30 
31 #include "common/device_environment.h"
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 // set desired level of debugging
35 ////////////////////////////////////////////////////////////////////////////////
36 
37 #define LD_SET_NONE 0ULL /* none */
38 #define LD_SET_ALL -1ULL /* all */
39 
40 // pos 1
41 #define LD_SET_LOOP 0x1ULL  /* basic loop */
42 #define LD_SET_LOOPD 0x2ULL /* basic loop */
43 #define LD_SET_PAR 0x4ULL   /* basic parallel */
44 #define LD_SET_PARD 0x8ULL  /* basic parallel */
45 
46 // pos 2
47 #define LD_SET_SYNC 0x10ULL  /* sync info */
48 #define LD_SET_SYNCD 0x20ULL /* sync info */
49 #define LD_SET_WAIT 0x40ULL  /* state when waiting */
50 #define LD_SET_TASK 0x80ULL  /* print task info (high level) */
51 
52 // pos 3
53 #define LD_SET_IO 0x100ULL     /* big region io (excl atomic) */
54 #define LD_SET_IOD 0x200ULL    /* big region io (excl atomic) */
55 #define LD_SET_ENV 0x400ULL    /* env info */
56 #define LD_SET_CANCEL 0x800ULL /* print cancel info */
57 
58 // pos 4
59 #define LD_SET_MEM 0x1000ULL /* malloc / free */
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 // set the desired flags to print selected output.
63 
64 // these are some examples of possible definitions that can be used for
65 // debugging.
66 //#define OMPTARGET_NVPTX_DEBUG (LD_SET_ALL)
67 //#define OMPTARGET_NVPTX_DEBUG (LD_SET_LOOP) // limit to loop printfs to save
68 // on cuda buffer
69 //#define OMPTARGET_NVPTX_DEBUG (LD_SET_IO)
70 //#define OMPTARGET_NVPTX_DEBUG (LD_SET_IO | LD_SET_ENV)
71 //#define OMPTARGET_NVPTX_DEBUG (LD_SET_PAR)
72 
73 #ifndef OMPTARGET_NVPTX_DEBUG
74 #define OMPTARGET_NVPTX_DEBUG LD_SET_NONE
75 #elif OMPTARGET_NVPTX_DEBUG
76 #warning debug is used, not good for measurements
77 #endif
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 // set desired level of asserts
81 ////////////////////////////////////////////////////////////////////////////////
82 
83 ////////////////////////////////////////////////////////////////////////////////
84 // available flags
85 
86 #define LT_SET_NONE 0x0 /* unsafe */
87 #define LT_SET_SAFETY                                                          \
88   0x1 /* check malloc type of stuff, input at creation, cheap */
89 #define LT_SET_INPUT 0x2 /* check also all runtime inputs */
90 #define LT_SET_FUSSY 0x4 /* fussy checks, expensive */
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 // set the desired flags
94 
95 #ifndef OMPTARGET_NVPTX_TEST
96 #if OMPTARGET_NVPTX_DEBUG
97 #define OMPTARGET_NVPTX_TEST (LT_SET_FUSSY)
98 #else
99 #define OMPTARGET_NVPTX_TEST (LT_SET_SAFETY)
100 #endif
101 #endif
102 
103 ////////////////////////////////////////////////////////////////////////////////
104 // set desired level of warnings
105 ////////////////////////////////////////////////////////////////////////////////
106 
107 ////////////////////////////////////////////////////////////////////////////////
108 // available flags
109 
110 #define LW_SET_ALL -1
111 #define LW_SET_NONE 0x0
112 #define LW_SET_ENV 0x1
113 #define LW_SET_INPUT 0x2
114 #define LW_SET_FUSSY 0x4
115 
116 ////////////////////////////////////////////////////////////////////////////////
117 // set the desired flags
118 
119 #if OMPTARGET_NVPTX_DEBUG
120 #define OMPTARGET_NVPTX_WARNING (LW_SET_NONE)
121 #else
122 #define OMPTARGET_NVPTX_WARNING (LW_SET_FUSSY)
123 #endif
124 
125 ////////////////////////////////////////////////////////////////////////////////
126 // implementation for debug
127 ////////////////////////////////////////////////////////////////////////////////
128 
129 #if OMPTARGET_NVPTX_DEBUG || OMPTARGET_NVPTX_TEST || OMPTARGET_NVPTX_WARNING
130 #include "common/support.h"
131 
132 template <typename... Arguments>
log(const char * fmt,Arguments...parameters)133 NOINLINE static void log(const char *fmt, Arguments... parameters) {
134   printf(fmt, (int)GetBlockIdInKernel(), (int)GetThreadIdInBlock(),
135          (int)GetWarpId(), (int)GetLaneId(), parameters...);
136 }
137 
138 #endif
139 #if OMPTARGET_NVPTX_TEST
140 
141 template <typename... Arguments>
check(bool cond,const char * fmt,Arguments...parameters)142 NOINLINE static void check(bool cond, const char *fmt,
143                            Arguments... parameters) {
144   if (!cond)
145     printf(fmt, (int)GetBlockIdInKernel(), (int)GetThreadIdInBlock(),
146            (int)GetWarpId(), (int)GetLaneId(), parameters...);
147   assert(cond);
148 }
149 
check(bool cond)150 NOINLINE static void check(bool cond) { assert(cond); }
151 #endif
152 
153 // set flags that are tested (inclusion properties)
154 
155 #define LD_ALL (LD_SET_ALL)
156 
157 #define LD_LOOP (LD_SET_LOOP | LD_SET_LOOPD)
158 #define LD_LOOPD (LD_SET_LOOPD)
159 #define LD_PAR (LD_SET_PAR | LD_SET_PARD)
160 #define LD_PARD (LD_SET_PARD)
161 
162 // pos 2
163 #define LD_SYNC (LD_SET_SYNC | LD_SET_SYNCD)
164 #define LD_SYNCD (LD_SET_SYNCD)
165 #define LD_WAIT (LD_SET_WAIT)
166 #define LD_TASK (LD_SET_TASK)
167 
168 // pos 3
169 #define LD_IO (LD_SET_IO | LD_SET_IOD)
170 #define LD_IOD (LD_SET_IOD)
171 #define LD_ENV (LD_SET_ENV)
172 #define LD_CANCEL (LD_SET_CANCEL)
173 
174 // pos 3
175 #define LD_MEM (LD_SET_MEM)
176 
177 // implement
178 #if OMPTARGET_NVPTX_DEBUG
179 
180 #define DON(_flag) ((unsigned)(OMPTARGET_NVPTX_DEBUG) & (_flag))
181 
182 #define PRINT0(_flag, _str)                                                    \
183   {                                                                            \
184     if (omptarget_device_environment.debug_level && DON(_flag)) {              \
185       log("<b %2d, t %4d, w %2d, l %2d>: " _str);                              \
186     }                                                                          \
187   }
188 
189 #define PRINT(_flag, _str, _args...)                                           \
190   {                                                                            \
191     if (omptarget_device_environment.debug_level && DON(_flag)) {              \
192       log("<b %2d, t %4d, w %2d, l %2d>: " _str, _args);                       \
193     }                                                                          \
194   }
195 #else
196 
197 #define DON(_flag) (0)
198 #define PRINT0(flag, str)
199 #define PRINT(flag, str, _args...)
200 
201 #endif
202 
203 // for printing without worrying about precision, pointers...
204 #define P64(_x) ((unsigned long long)(_x))
205 
206 ////////////////////////////////////////////////////////////////////////////////
207 // early defs for test
208 ////////////////////////////////////////////////////////////////////////////////
209 
210 #define LT_SAFETY (LT_SET_SAFETY | LT_SET_INPUT | LT_SET_FUSSY)
211 #define LT_INPUT (LT_SET_INPUT | LT_SET_FUSSY)
212 #define LT_FUSSY (LT_SET_FUSSY)
213 
214 #if OMPTARGET_NVPTX_TEST == LT_SET_SAFETY
215 
216 #define TON(_flag) ((OMPTARGET_NVPTX_TEST) & (_flag))
217 #define ASSERT0(_flag, _cond, _str)                                            \
218   {                                                                            \
219     if (TON(_flag)) {                                                          \
220       check(_cond);                                                            \
221     }                                                                          \
222   }
223 #define ASSERT(_flag, _cond, _str, _args...)                                   \
224   {                                                                            \
225     if (TON(_flag)) {                                                          \
226       check(_cond);                                                            \
227     }                                                                          \
228   }
229 
230 #elif OMPTARGET_NVPTX_TEST >= LT_SET_INPUT
231 
232 #define TON(_flag) ((OMPTARGET_NVPTX_TEST) & (_flag))
233 #define ASSERT0(_flag, _cond, _str)                                            \
234   {                                                                            \
235     if (TON(_flag)) {                                                          \
236       check((_cond), "<b %3d, t %4d, w %2d, l %2d> ASSERT: " _str "\n");       \
237     }                                                                          \
238   }
239 #define ASSERT(_flag, _cond, _str, _args...)                                   \
240   {                                                                            \
241     if (TON(_flag)) {                                                          \
242       check((_cond), "<b %3d, t %4d, w %2d, l %d2> ASSERT: " _str "\n",        \
243             _args);                                                            \
244     }                                                                          \
245   }
246 
247 #else
248 
249 #define TON(_flag) (0)
250 #define ASSERT0(_flag, _cond, _str)
251 #define ASSERT(_flag, _cond, _str, _args...)
252 
253 #endif
254 
255 ////////////////////////////////////////////////////////////////////////////////
256 // early defs for warning
257 
258 #define LW_ALL (LW_SET_ALL)
259 #define LW_ENV (LW_SET_FUSSY | LW_SET_INPUT | LW_SET_ENV)
260 #define LW_INPUT (LW_SET_FUSSY | LW_SET_INPUT)
261 #define LW_FUSSY (LW_SET_FUSSY)
262 
263 #if OMPTARGET_NVPTX_WARNING
264 
265 #define WON(_flag) ((OMPTARGET_NVPTX_WARNING) & (_flag))
266 #define WARNING0(_flag, _str)                                                  \
267   {                                                                            \
268     if (WON(_flag)) {                                                          \
269       log("<b %2d, t %4d, w %2d, l %2d> WARNING: " _str);                      \
270     }                                                                          \
271   }
272 #define WARNING(_flag, _str, _args...)                                         \
273   {                                                                            \
274     if (WON(_flag)) {                                                          \
275       log("<b %2d, t %4d, w %2d, l %2d> WARNING: " _str, _args);               \
276     }                                                                          \
277   }
278 
279 #else
280 
281 #define WON(_flag) (0)
282 #define WARNING0(_flag, _str)
283 #define WARNING(_flag, _str, _args...)
284 
285 #endif
286 
287 #endif
288