Warning: This file is not a C or C++ file. It does not have highlighting.
| 1 | //===-- Shared/Debug.h - Target independent OpenMP target RTL -- C++ ------===// |
|---|---|
| 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 | // Routines used to provide debug messages and information from libomptarget |
| 10 | // and plugin RTLs to the user. |
| 11 | // |
| 12 | // Each plugin RTL and libomptarget define TARGET_NAME and DEBUG_PREFIX for use |
| 13 | // when sending messages to the user. These indicate which RTL sent the message |
| 14 | // |
| 15 | // Debug and information messages are controlled by the environment variables |
| 16 | // LIBOMPTARGET_DEBUG and LIBOMPTARGET_INFO which is set upon initialization |
| 17 | // of libomptarget or the plugin RTL. |
| 18 | // |
| 19 | // To printf a pointer in hex with a fixed width of 16 digits and a leading 0x, |
| 20 | // use printf("ptr=" DPxMOD "...\n", DPxPTR(ptr)); |
| 21 | // |
| 22 | // DPxMOD expands to: |
| 23 | // "0x%0*" PRIxPTR |
| 24 | // where PRIxPTR expands to an appropriate modifier for the type uintptr_t on a |
| 25 | // specific platform, e.g. "lu" if uintptr_t is typedef'd as unsigned long: |
| 26 | // "0x%0*lu" |
| 27 | // |
| 28 | // Ultimately, the whole statement expands to: |
| 29 | // printf("ptr=0x%0*lu...\n", // the 0* modifier expects an extra argument |
| 30 | // // specifying the width of the output |
| 31 | // (int)(2*sizeof(uintptr_t)), // the extra argument specifying the width |
| 32 | // // 8 digits for 32bit systems |
| 33 | // // 16 digits for 64bit |
| 34 | // (uintptr_t) ptr); |
| 35 | // |
| 36 | //===----------------------------------------------------------------------===// |
| 37 | |
| 38 | #ifndef OMPTARGET_SHARED_DEBUG_H |
| 39 | #define OMPTARGET_SHARED_DEBUG_H |
| 40 | |
| 41 | #include <atomic> |
| 42 | #include <mutex> |
| 43 | #include <string> |
| 44 | |
| 45 | /// 32-Bit field data attributes controlling information presented to the user. |
| 46 | enum OpenMPInfoType : uint32_t { |
| 47 | // Print data arguments and attributes upon entering an OpenMP device kernel. |
| 48 | OMP_INFOTYPE_KERNEL_ARGS = 0x0001, |
| 49 | // Indicate when an address already exists in the device mapping table. |
| 50 | OMP_INFOTYPE_MAPPING_EXISTS = 0x0002, |
| 51 | // Dump the contents of the device pointer map at kernel exit or failure. |
| 52 | OMP_INFOTYPE_DUMP_TABLE = 0x0004, |
| 53 | // Indicate when an address is added to the device mapping table. |
| 54 | OMP_INFOTYPE_MAPPING_CHANGED = 0x0008, |
| 55 | // Print kernel information from target device plugins. |
| 56 | OMP_INFOTYPE_PLUGIN_KERNEL = 0x0010, |
| 57 | // Print whenever data is transferred to the device |
| 58 | OMP_INFOTYPE_DATA_TRANSFER = 0x0020, |
| 59 | // Print whenever data does not have a viable device counterpart. |
| 60 | OMP_INFOTYPE_EMPTY_MAPPING = 0x0040, |
| 61 | // Enable every flag. |
| 62 | OMP_INFOTYPE_ALL = 0xffffffff, |
| 63 | }; |
| 64 | |
| 65 | inline std::atomic<uint32_t> &getInfoLevelInternal() { |
| 66 | static std::atomic<uint32_t> InfoLevel; |
| 67 | static std::once_flag Flag{}; |
| 68 | std::call_once(Flag, []() { |
| 69 | if (char *EnvStr = getenv("LIBOMPTARGET_INFO")) |
| 70 | InfoLevel.store(std::stoi(EnvStr)); |
| 71 | }); |
| 72 | |
| 73 | return InfoLevel; |
| 74 | } |
| 75 | |
| 76 | inline uint32_t getInfoLevel() { return getInfoLevelInternal().load(); } |
| 77 | |
| 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; |
| 87 | } |
| 88 | |
| 89 | #undef USED |
| 90 | #undef GCC_VERSION |
| 91 | |
| 92 | #ifndef __STDC_FORMAT_MACROS |
| 93 | #define __STDC_FORMAT_MACROS |
| 94 | #endif |
| 95 | #include <inttypes.h> |
| 96 | #undef __STDC_FORMAT_MACROS |
| 97 | |
| 98 | #define DPxMOD "0x%0*" PRIxPTR |
| 99 | #define DPxPTR(ptr) ((int)(2 * sizeof(uintptr_t))), ((uintptr_t)(ptr)) |
| 100 | #define GETNAME2(name) #name |
| 101 | #define GETNAME(name) GETNAME2(name) |
| 102 | |
| 103 | /// Print a generic message string from libomptarget or a plugin RTL |
| 104 | #define MESSAGE0(_str) \ |
| 105 | do { \ |
| 106 | fprintf(stderr, GETNAME(TARGET_NAME) " message: %s\n", _str); \ |
| 107 | } while (0) |
| 108 | |
| 109 | /// Print a printf formatting string message from libomptarget or a plugin RTL |
| 110 | #define MESSAGE(_str, ...) \ |
| 111 | do { \ |
| 112 | fprintf(stderr, GETNAME(TARGET_NAME) " message: " _str "\n", __VA_ARGS__); \ |
| 113 | } while (0) |
| 114 | |
| 115 | /// Print fatal error message with an error string and error identifier |
| 116 | #define FATAL_MESSAGE0(_num, _str) \ |
| 117 | do { \ |
| 118 | fprintf(stderr, GETNAME(TARGET_NAME) " fatal error %d: %s\n", (int)_num, \ |
| 119 | _str); \ |
| 120 | abort(); \ |
| 121 | } while (0) |
| 122 | |
| 123 | /// Print fatal error message with a printf string and error identifier |
| 124 | #define FATAL_MESSAGE(_num, _str, ...) \ |
| 125 | do { \ |
| 126 | fprintf(stderr, GETNAME(TARGET_NAME) " fatal error %d: " _str "\n", \ |
| 127 | (int)_num, __VA_ARGS__); \ |
| 128 | abort(); \ |
| 129 | } while (0) |
| 130 | |
| 131 | /// Print a generic error string from libomptarget or a plugin RTL |
| 132 | #define FAILURE_MESSAGE(...) \ |
| 133 | do { \ |
| 134 | fprintf(stderr, GETNAME(TARGET_NAME) " error: "); \ |
| 135 | fprintf(stderr, __VA_ARGS__); \ |
| 136 | } while (0) |
| 137 | |
| 138 | /// Print a generic information string used if LIBOMPTARGET_INFO=1 |
| 139 | #define INFO_MESSAGE(_num, ...) INFO_MESSAGE_TO(stderr, _num, __VA_ARGS__) |
| 140 | |
| 141 | #define INFO_MESSAGE_TO(_stdDst, _num, ...) \ |
| 142 | do { \ |
| 143 | fprintf(_stdDst, GETNAME(TARGET_NAME) " device %d info: ", (int)_num); \ |
| 144 | fprintf(_stdDst, __VA_ARGS__); \ |
| 145 | } while (0) |
| 146 | |
| 147 | // Debugging messages |
| 148 | #ifdef OMPTARGET_DEBUG |
| 149 | #include <stdio.h> |
| 150 | |
| 151 | #define DEBUGP(prefix, ...) \ |
| 152 | { \ |
| 153 | fprintf(stderr, "%s --> ", prefix); \ |
| 154 | fprintf(stderr, __VA_ARGS__); \ |
| 155 | } |
| 156 | |
| 157 | /// Emit a message for debugging |
| 158 | #define DP(...) \ |
| 159 | do { \ |
| 160 | if (getDebugLevel() > 0) { \ |
| 161 | DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \ |
| 162 | } \ |
| 163 | } while (false) |
| 164 | |
| 165 | /// Emit a message for debugging or failure if debugging is disabled |
| 166 | #define REPORT(...) \ |
| 167 | do { \ |
| 168 | if (getDebugLevel() > 0) { \ |
| 169 | DP(__VA_ARGS__); \ |
| 170 | } else { \ |
| 171 | FAILURE_MESSAGE(__VA_ARGS__); \ |
| 172 | } \ |
| 173 | } while (false) |
| 174 | #else |
| 175 | #define DEBUGP(prefix, ...) \ |
| 176 | {} |
| 177 | #define DP(...) \ |
| 178 | {} |
| 179 | #define REPORT(...) FAILURE_MESSAGE(__VA_ARGS__); |
| 180 | #endif // OMPTARGET_DEBUG |
| 181 | |
| 182 | /// Emit a message giving the user extra information about the runtime if |
| 183 | #define INFO(_flags, _id, ...) \ |
| 184 | do { \ |
| 185 | if (getDebugLevel() > 0) { \ |
| 186 | DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \ |
| 187 | } else if (getInfoLevel() & _flags) { \ |
| 188 | INFO_MESSAGE(_id, __VA_ARGS__); \ |
| 189 | } \ |
| 190 | } while (false) |
| 191 | |
| 192 | #define DUMP_INFO(toStdOut, _flags, _id, ...) \ |
| 193 | do { \ |
| 194 | if (toStdOut) { \ |
| 195 | INFO_MESSAGE_TO(stdout, _id, __VA_ARGS__); \ |
| 196 | } else { \ |
| 197 | INFO(_flags, _id, __VA_ARGS__); \ |
| 198 | } \ |
| 199 | } while (false) |
| 200 | |
| 201 | #endif // OMPTARGET_SHARED_DEBUG_H |
| 202 |
Warning: This file is not a C or C++ file. It does not have highlighting.
