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