4040
4141#include < atomic>
4242#include < mutex>
43+ #include < sstream>
4344#include < string>
4445
4546// / 32-Bit field data attributes controlling information presented to the user.
@@ -62,6 +63,38 @@ enum OpenMPInfoType : uint32_t {
6263 OMP_INFOTYPE_ALL = 0xffffffff ,
6364};
6465
66+ // / 32-bit field attributes controlling debug trace/dump
67+ enum DebugInfoType : uint32_t {
68+ // / Generic plugin/runtime interface/management
69+ DEBUG_INFOTYPE_RTL = 0x0001 ,
70+ // / Generic device activity
71+ DEBUG_INFOTYPE_DEVICE = 0x0002 ,
72+ // / Module preparation
73+ DEBUG_INFOTYPE_MODULE = 0x0004 ,
74+ // / Kernel preparation and invocation
75+ DEBUG_INFOTYPE_KERNEL = 0x0008 ,
76+ // / Memory allocation/deallocation or related activities
77+ DEBUG_INFOTYPE_MEMORY = 0x0010 ,
78+ // / Data-mapping activities
79+ DEBUG_INFOTYPE_MAP = 0x0020 ,
80+ // / Data-copying or similar activities
81+ DEBUG_INFOTYPE_COPY = 0x0040 ,
82+ // / OpenMP interop
83+ DEBUG_INFOTYPE_INTEROP = 0x0080 ,
84+ // / Tool interface
85+ DEBUG_INFOTYPE_TOOL = 0x0100 ,
86+ // / Backend API tracing
87+ DEBUG_INFOTYPE_API = 0x0200 ,
88+ // / All
89+ DEBUG_INFOTYPE_ALL = 0xffffffff ,
90+ };
91+
92+ // / Debug option struct to support both numeric and string value
93+ struct DebugOptionTy {
94+ uint32_t Level;
95+ uint32_t Type;
96+ };
97+
6598inline std::atomic<uint32_t > &getInfoLevelInternal () {
6699 static std::atomic<uint32_t > InfoLevel;
67100 static std::once_flag Flag{};
@@ -75,17 +108,49 @@ inline std::atomic<uint32_t> &getInfoLevelInternal() {
75108
76109inline uint32_t getInfoLevel () { return getInfoLevelInternal ().load (); }
77110
78- inline uint32_t getDebugLevel () {
79- static uint32_t DebugLevel = 0 ;
80- static std::once_flag Flag{};
81- std::call_once (Flag, []() {
82- if (char *EnvStr = getenv (" LIBOMPTARGET_DEBUG" ))
83- DebugLevel = std::stoi (EnvStr);
84- });
85-
86- return DebugLevel;
111+ inline DebugOptionTy &getDebugOption () {
112+ static DebugOptionTy DebugOption = []() {
113+ DebugOptionTy OptVal{0 , 0 };
114+ char *EnvStr = getenv (" LIBOMPTARGET_DEBUG" );
115+ if (!EnvStr || *EnvStr == ' 0' )
116+ return OptVal; // undefined or explicitly defined as zero
117+ OptVal.Level = std::atoi (EnvStr);
118+ if (OptVal.Level )
119+ return OptVal; // defined as numeric value
120+ // Check string value of the option
121+ std::istringstream Tokens (EnvStr);
122+ for (std::string Token; std::getline (Tokens, Token, ' ,' );) {
123+ if (Token == " rtl" )
124+ OptVal.Type |= DEBUG_INFOTYPE_RTL;
125+ else if (Token == " device" )
126+ OptVal.Type |= DEBUG_INFOTYPE_DEVICE;
127+ else if (Token == " module" )
128+ OptVal.Type |= DEBUG_INFOTYPE_MODULE;
129+ else if (Token == " kernel" )
130+ OptVal.Type |= DEBUG_INFOTYPE_KERNEL;
131+ else if (Token == " memory" )
132+ OptVal.Type |= DEBUG_INFOTYPE_MEMORY;
133+ else if (Token == " map" )
134+ OptVal.Type |= DEBUG_INFOTYPE_MAP;
135+ else if (Token == " copy" )
136+ OptVal.Type |= DEBUG_INFOTYPE_COPY;
137+ else if (Token == " interop" )
138+ OptVal.Type |= DEBUG_INFOTYPE_INTEROP;
139+ else if (Token == " tool" )
140+ OptVal.Type |= DEBUG_INFOTYPE_TOOL;
141+ else if (Token == " api" )
142+ OptVal.Type |= DEBUG_INFOTYPE_API;
143+ else if (Token == " all" )
144+ OptVal.Type |= DEBUG_INFOTYPE_ALL;
145+ }
146+ return OptVal;
147+ }();
148+ return DebugOption;
87149}
88150
151+ inline uint32_t getDebugLevel () { return getDebugOption ().Level ; }
152+ inline uint32_t getDebugType () { return getDebugOption ().Type ; }
153+
89154#undef USED
90155#undef GCC_VERSION
91156
@@ -154,18 +219,25 @@ inline uint32_t getDebugLevel() {
154219 fprintf (stderr, __VA_ARGS__); \
155220 }
156221
157- // / Emit a message for debugging
158- #define DP (...) \
222+ // / Check if debug option is turned on for `Type`
223+ #define DPSET (Type ) \
224+ ((getDebugType() & DEBUG_INFOTYPE_##Type) || getDebugLevel() > 0 )
225+
226+ // / Emit a message for debugging if related to `Type`
227+ #define DPIF (Type, ...) \
159228 do { \
160- if (getDebugLevel () > 0 ) { \
229+ if (DPSET (Type) ) { \
161230 DEBUGP (DEBUG_PREFIX, __VA_ARGS__); \
162231 } \
163232 } while (false )
164233
234+ // / Emit a message for debugging
235+ #define DP (...) DPIF(ALL, __VA_ARGS__);
236+
165237// / Emit a message for debugging or failure if debugging is disabled
166238#define REPORT (...) \
167239 do { \
168- if (getDebugLevel () > 0 ) { \
240+ if (DPSET (ALL) ) { \
169241 DP (__VA_ARGS__); \
170242 } else { \
171243 FAILURE_MESSAGE (__VA_ARGS__); \
@@ -174,15 +246,45 @@ inline uint32_t getDebugLevel() {
174246#else
175247#define DEBUGP (prefix, ...) \
176248 {}
249+ #define DPSET (Type ) false
250+ #define DPIF (Type, ...) \
251+ { \
252+ }
177253#define DP (...) \
178254 {}
179255#define REPORT (...) FAILURE_MESSAGE(__VA_ARGS__);
180256#endif // OMPTARGET_DEBUG
181257
258+ #ifdef OMPTARGET_DEBUG
259+ // Convert `OpenMPInfoType` to corresponding `DebugInfoType`
260+ inline bool debugInfoEnabled (OpenMPInfoType InfoType) {
261+ switch (InfoType) {
262+ case OMP_INFOTYPE_KERNEL_ARGS:
263+ [[fallthrough]];
264+ case OMP_INFOTYPE_PLUGIN_KERNEL:
265+ return DPSET (KERNEL);
266+ case OMP_INFOTYPE_MAPPING_EXISTS:
267+ [[fallthrough]];
268+ case OMP_INFOTYPE_DUMP_TABLE:
269+ [[fallthrough]];
270+ case OMP_INFOTYPE_MAPPING_CHANGED:
271+ [[fallthrough]];
272+ case OMP_INFOTYPE_EMPTY_MAPPING:
273+ return DPSET (MAP);
274+ case OMP_INFOTYPE_DATA_TRANSFER:
275+ return DPSET (COPY);
276+ case OMP_INFOTYPE_ALL:
277+ return DPSET (ALL);
278+ }
279+ }
280+ #else
281+ #define debugInfoEnabled (InfoType ) false
282+ #endif // OMPTARGET_DEBUG
283+
182284// / Emit a message giving the user extra information about the runtime if
183285#define INFO (_flags, _id, ...) \
184286 do { \
185- if (getDebugLevel () > 0 ) { \
287+ if (debugInfoEnabled (_flags) ) { \
186288 DEBUGP (DEBUG_PREFIX, __VA_ARGS__); \
187289 } else if (getInfoLevel () & _flags) { \
188290 INFO_MESSAGE (_id, __VA_ARGS__); \
0 commit comments