From f63c8e6027290d797a99a00c6574f08d68cb09b1 Mon Sep 17 00:00:00 2001 From: Alex Duran Date: Tue, 2 Dec 2025 09:56:37 +0100 Subject: [PATCH 1/3] [OFFLOAD][LIBOMPTARGET] Add compatibility support; start to update messages --- offload/include/Shared/Debug.h | 327 +++++++++++++++++----------- offload/libomptarget/OffloadRTL.cpp | 8 +- offload/libomptarget/device.cpp | 14 +- 3 files changed, 207 insertions(+), 142 deletions(-) diff --git a/offload/include/Shared/Debug.h b/offload/include/Shared/Debug.h index 41613a37c3548..feba3c9dddb29 100644 --- a/offload/include/Shared/Debug.h +++ b/offload/include/Shared/Debug.h @@ -39,6 +39,7 @@ #define OMPTARGET_SHARED_DEBUG_H #include +#include #include #include @@ -78,17 +79,6 @@ inline std::atomic &getInfoLevelInternal() { inline uint32_t getInfoLevel() { return getInfoLevelInternal().load(); } -inline uint32_t getDebugLevel() { - static uint32_t DebugLevel = 0; - static std::once_flag Flag{}; - std::call_once(Flag, []() { - if (char *EnvStr = getenv("LIBOMPTARGET_DEBUG")) - DebugLevel = std::stoi(EnvStr); - }); - - return DebugLevel; -} - #undef USED #undef GCC_VERSION @@ -147,46 +137,11 @@ inline uint32_t getDebugLevel() { fprintf(_stdDst, __VA_ARGS__); \ } while (0) -// Debugging messages -#ifdef OMPTARGET_DEBUG -#include - -#define DEBUGP(prefix, ...) \ - { \ - fprintf(stderr, "%s --> ", prefix); \ - fprintf(stderr, __VA_ARGS__); \ - } - -/// Emit a message for debugging -#define DP(...) \ - do { \ - if (getDebugLevel() > 0) { \ - DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \ - } \ - } while (false) - -/// Emit a message for debugging or failure if debugging is disabled -#define REPORT(...) \ - do { \ - if (getDebugLevel() > 0) { \ - DP(__VA_ARGS__); \ - } else { \ - FAILURE_MESSAGE(__VA_ARGS__); \ - } \ - } while (false) -#else -#define DEBUGP(prefix, ...) \ - {} -#define DP(...) \ - {} -#define REPORT(...) FAILURE_MESSAGE(__VA_ARGS__); -#endif // OMPTARGET_DEBUG - /// Emit a message giving the user extra information about the runtime if #define INFO(_flags, _id, ...) \ do { \ - if (getDebugLevel() > 0) { \ - DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \ + if (::llvm::offload::debug::isDebugEnabled()) { \ + DP(__VA_ARGS__); \ } else if (getInfoLevel() & _flags) { \ INFO_MESSAGE(_id, __VA_ARGS__); \ } \ @@ -203,17 +158,92 @@ inline uint32_t getDebugLevel() { namespace llvm::offload::debug { -#ifdef OMPTARGET_DEBUG +/// A raw_ostream that tracks `\n` and print the prefix after each +/// newline. Based on raw_ldbg_ostream from Support/DebugLog.h +class LLVM_ABI odbg_ostream final : public raw_ostream { +public: + enum IfLevel : uint32_t; + enum OnlyLevel : uint32_t; -struct DebugFilter { - StringRef Type; - uint32_t Level; -}; +private: + std::string Prefix; + raw_ostream &Os; + uint32_t BaseLevel; + bool ShouldPrefixNextString; + bool ShouldEmitNewLineOnDestruction; + bool NeedEndNewLine = false; -struct DebugSettings { - bool Enabled = false; - uint32_t DefaultLevel = 1; - llvm::SmallVector Filters; + /// If the stream is muted, writes to it are ignored + bool Muted = false; + + /// Split the line on newlines and insert the prefix before each + /// newline. Forward everything to the underlying stream. + void write_impl(const char *Ptr, size_t Size) final { + if (Muted) + return; + + NeedEndNewLine = false; + auto Str = StringRef(Ptr, Size); + auto Eol = Str.find('\n'); + // Handle `\n` occurring in the string, ensure to print the prefix at the + // beginning of each line. + while (Eol != StringRef::npos) { + // Take the line up to the newline (including the newline). + StringRef Line = Str.take_front(Eol + 1); + if (!Line.empty()) + writeWithPrefix(Line); + // We printed a newline, record here to print a prefix. + ShouldPrefixNextString = true; + Str = Str.drop_front(Eol + 1); + Eol = Str.find('\n'); + } + if (!Str.empty()) { + writeWithPrefix(Str); + NeedEndNewLine = true; + } + } + void emitPrefix() { Os.write(Prefix.c_str(), Prefix.size()); } + void writeWithPrefix(StringRef Str) { + if (ShouldPrefixNextString) { + emitPrefix(); + ShouldPrefixNextString = false; + } + Os.write(Str.data(), Str.size()); + } + +public: + explicit odbg_ostream(std::string Prefix, raw_ostream &Os, uint32_t BaseLevel, + bool ShouldPrefixNextString = true, + bool ShouldEmitNewLineOnDestruction = true) + : Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel), + ShouldPrefixNextString(ShouldPrefixNextString), + ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) { + SetUnbuffered(); + } + ~odbg_ostream() final { + if (ShouldEmitNewLineOnDestruction && NeedEndNewLine) + Os << '\n'; + } + odbg_ostream(const odbg_ostream &) = delete; + odbg_ostream &operator=(const odbg_ostream &) = delete; + odbg_ostream(odbg_ostream &&other) : Os(other.Os) { + Prefix = std::move(other.Prefix); + BaseLevel = other.BaseLevel; + ShouldPrefixNextString = other.ShouldPrefixNextString; + ShouldEmitNewLineOnDestruction = other.ShouldEmitNewLineOnDestruction; + NeedEndNewLine = other.NeedEndNewLine; + Muted = other.Muted; + } + + /// Forward the current_pos method to the underlying stream. + uint64_t current_pos() const final { return Os.tell(); } + + /// Some of the `<<` operators expect an lvalue, so we trick the type + /// system. + odbg_ostream &asLvalue() { return *this; } + + void shouldMute(const IfLevel Filter) { Muted = Filter > BaseLevel; } + void shouldMute(const OnlyLevel Filter) { Muted = BaseLevel != Filter; } }; /// dbgs - Return a circular-buffered debug stream. @@ -228,6 +258,19 @@ struct DebugSettings { return thestrm.strm; } +#ifdef OMPTARGET_DEBUG + +struct DebugFilter { + StringRef Type; + uint32_t Level; +}; + +struct DebugSettings { + bool Enabled = false; + uint32_t DefaultLevel = 1; + llvm::SmallVector Filters; +}; + [[maybe_unused]] static DebugFilter parseDebugFilter(StringRef Filter) { size_t Pos = Filter.find(':'); if (Pos == StringRef::npos) @@ -309,80 +352,6 @@ shouldPrintDebug(const char *Component, const char *Type, uint32_t &Level) { return false; } -/// A raw_ostream that tracks `\n` and print the prefix after each -/// newline. Based on raw_ldbg_ostream from Support/DebugLog.h -class LLVM_ABI odbg_ostream final : public raw_ostream { -public: - enum IfLevel : uint32_t; - enum OnlyLevel : uint32_t; - -private: - std::string Prefix; - raw_ostream &Os; - uint32_t BaseLevel; - bool ShouldPrefixNextString; - bool ShouldEmitNewLineOnDestruction; - - /// If the stream is muted, writes to it are ignored - bool Muted = false; - - /// Split the line on newlines and insert the prefix before each - /// newline. Forward everything to the underlying stream. - void write_impl(const char *Ptr, size_t Size) final { - if (Muted) - return; - - auto Str = StringRef(Ptr, Size); - auto Eol = Str.find('\n'); - // Handle `\n` occurring in the string, ensure to print the prefix at the - // beginning of each line. - while (Eol != StringRef::npos) { - // Take the line up to the newline (including the newline). - StringRef Line = Str.take_front(Eol + 1); - if (!Line.empty()) - writeWithPrefix(Line); - // We printed a newline, record here to print a prefix. - ShouldPrefixNextString = true; - Str = Str.drop_front(Eol + 1); - Eol = Str.find('\n'); - } - if (!Str.empty()) - writeWithPrefix(Str); - } - void emitPrefix() { Os.write(Prefix.c_str(), Prefix.size()); } - void writeWithPrefix(StringRef Str) { - if (ShouldPrefixNextString) { - emitPrefix(); - ShouldPrefixNextString = false; - } - Os.write(Str.data(), Str.size()); - } - -public: - explicit odbg_ostream(std::string Prefix, raw_ostream &Os, uint32_t BaseLevel, - bool ShouldPrefixNextString = true, - bool ShouldEmitNewLineOnDestruction = false) - : Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel), - ShouldPrefixNextString(ShouldPrefixNextString), - ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) { - SetUnbuffered(); - } - ~odbg_ostream() final { - if (ShouldEmitNewLineOnDestruction) - Os << '\n'; - } - - /// Forward the current_pos method to the underlying stream. - uint64_t current_pos() const final { return Os.tell(); } - - /// Some of the `<<` operators expect an lvalue, so we trick the type - /// system. - odbg_ostream &asLvalue() { return *this; } - - void shouldMute(const IfLevel Filter) { Muted = Filter > BaseLevel; } - void shouldMute(const OnlyLevel Filter) { Muted = BaseLevel != Filter; } -}; - /// Compute the prefix for the debug log in the form of: /// "Component --> " [[maybe_unused]] static std::string computePrefix(StringRef Component, @@ -463,6 +432,8 @@ static inline raw_ostream &operator<<(raw_ostream &Os, #else +inline bool isDebugEnabled() { return false; } + #define ODBG_NULL \ for (bool _c = false; _c; _c = false) \ ::llvm::nulls() @@ -479,4 +450,98 @@ static inline raw_ostream &operator<<(raw_ostream &Os, } // namespace llvm::offload::debug +namespace llvm::omptarget::debug { +using namespace llvm::offload::debug; + +enum OmpDebugLevel : uint32_t { + ODL_Default = 1, + ODL_Error = ODL_Default, + ODL_Detailed = 2, + ODL_Verbose = 3, + ODL_VeryVerbose = 4, + ODL_Dumping = 5 +}; + +/* Debug types to use in libomptarget */ +constexpr const char *ODT_Init = "Init"; +constexpr const char *ODT_Mapping = "Mapping"; +constexpr const char *ODT_Kernel = "Kernel"; +constexpr const char *ODT_DataTransfer = "DataTransfer"; +constexpr const char *ODT_Sync = "Sync"; +constexpr const char *ODT_Deinit = "Deinit"; +constexpr const char *ODT_Error = "Error"; +constexpr const char *ODT_KernelArgs = "KernelArgs"; +constexpr const char *ODT_MappingExists = "MappingExists"; +constexpr const char *ODT_DumpTable = "DumpTable"; +constexpr const char *ODT_MappingChanged = "MappingChanged"; +constexpr const char *ODT_PluginKernel = "PluginKernel"; +constexpr const char *ODT_EmptyMapping = "EmptyMapping"; + +static inline odbg_ostream reportErrorStream() { +#ifdef OMPTARGET_DEBUG + if (::llvm::offload::debug::isDebugEnabled()) { + uint32_t RealLevel = ODL_Error; + if (::llvm::offload::debug::shouldPrintDebug(GETNAME(TARGET_NAME), + (ODT_Error), RealLevel)) + return odbg_ostream{ + ::llvm::offload::debug::computePrefix(DEBUG_PREFIX, ODT_Error), + ::llvm::offload::debug::dbgs(), RealLevel}; + else + return odbg_ostream{"", ::llvm::nulls(), 1}; + } +#endif + return odbg_ostream{GETNAME(TARGET_NAME) " error: ", + ::llvm::offload::debug::dbgs(), ODL_Error}; +} + +#ifdef OMPTARGET_DEBUG +// Deprecated debug print macros +[[maybe_unused]] static std::string formatToStr(const char *format, ...) { + va_list args; + va_start(args, format); + size_t len = std::vsnprintf(NULL, 0, format, args); + va_end(args); + llvm::SmallVector vec(len + 1); + va_start(args, format); + std::vsnprintf(&vec[0], len + 1, format, args); + va_end(args); + return &vec[0]; +} + +// helper macro to support old DP and REPORT macros with printf syntax +#define FORMAT_TO_STR(Format, ...) \ + ::llvm::omptarget::debug::formatToStr(Format __VA_OPT__(, ) __VA_ARGS__) + +#define DP(...) ODBG() << FORMAT_TO_STR(__VA_ARGS__); + +#define REPORT_INT_OLD(...) \ + do { \ + if (::llvm::offload::debug::isDebugEnabled()) { \ + ODBG(ODT_Error, ODL_Error) << FORMAT_TO_STR(__VA_ARGS__); \ + } else { \ + FAILURE_MESSAGE(__VA_ARGS__); \ + } \ + } while (false) + +#else +#define DP(...) \ + { \ + } +#define REPORT_INT_OLD(...) FAILURE_MESSAGE(__VA_ARGS__); +#endif // OMPTARGET_DEBUG + +// This is used for the new style REPORT macro +#define REPORT_INT() ::llvm::omptarget::debug::reportErrorStream() + +// Make REPORT compatible with old and new syntax +#define REPORT(...) REPORT_INT##__VA_OPT__(_OLD)(__VA_ARGS__) + +} // namespace llvm::omptarget::debug + +using namespace llvm::omptarget::debug; + +static inline int getDebugLevel() { + return ::llvm::offload::debug::isDebugEnabled(); +} + #endif // OMPTARGET_SHARED_DEBUG_H diff --git a/offload/libomptarget/OffloadRTL.cpp b/offload/libomptarget/OffloadRTL.cpp index 0ae325bf496d9..77c5768b62168 100644 --- a/offload/libomptarget/OffloadRTL.cpp +++ b/offload/libomptarget/OffloadRTL.cpp @@ -35,7 +35,7 @@ void initRuntime() { RefCount++; if (RefCount == 1) { - ODBG() << "Init offload library!"; + ODBG(ODT_Init) << "Init offload library!"; #ifdef OMPT_SUPPORT // Initialize OMPT first llvm::omp::target::ompt::connectLibrary(); @@ -54,12 +54,12 @@ void deinitRuntime() { assert(PM && "Runtime not initialized"); if (RefCount == 1) { - DP("Deinit offload library!\n"); + ODBG(ODT_Deinit) << "Deinit offload library!"; // RTL deinitialization has started RTLAlive = false; while (RTLOngoingSyncs > 0) { - DP("Waiting for ongoing syncs to finish, count: %d\n", - RTLOngoingSyncs.load()); + ODBG(ODT_Sync) << "Waiting for ongoing syncs to finish, count:" + << RTLOngoingSyncs.load(); std::this_thread::sleep_for(std::chrono::milliseconds(100)); } PM->deinit(); diff --git a/offload/libomptarget/device.cpp b/offload/libomptarget/device.cpp index ee36fbed935a5..5637a77508039 100644 --- a/offload/libomptarget/device.cpp +++ b/offload/libomptarget/device.cpp @@ -48,7 +48,7 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, void *Event = getEvent(); bool NeedNewEvent = Event == nullptr; if (NeedNewEvent && Device.createEvent(&Event) != OFFLOAD_SUCCESS) { - REPORT("Failed to create event\n"); + REPORT() << "Failed to create event"; return OFFLOAD_FAIL; } @@ -56,7 +56,7 @@ int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, // know if the target support event. But if a target doesn't, // recordEvent should always return success. if (Device.recordEvent(Event, AsyncInfo) != OFFLOAD_SUCCESS) { - REPORT("Failed to set dependence on event " DPxMOD "\n", DPxPTR(Event)); + REPORT() << "Failed to set dependence on event " << Event; return OFFLOAD_FAIL; } @@ -278,21 +278,21 @@ int32_t DeviceTy::dataFence(AsyncInfoTy &AsyncInfo) { } int32_t DeviceTy::notifyDataMapped(void *HstPtr, int64_t Size) { - DP("Notifying about new mapping: HstPtr=" DPxMOD ", Size=%" PRId64 "\n", - DPxPTR(HstPtr), Size); + ODBG(ODT_Mapping) << "Notifying about new mapping: HstPtr=" << HstPtr + << ", Size=" << Size; if (RTL->data_notify_mapped(RTLDeviceID, HstPtr, Size)) { - REPORT("Notifying about data mapping failed.\n"); + REPORT() << "Notifying about data mapping failed."; return OFFLOAD_FAIL; } return OFFLOAD_SUCCESS; } int32_t DeviceTy::notifyDataUnmapped(void *HstPtr) { - DP("Notifying about an unmapping: HstPtr=" DPxMOD "\n", DPxPTR(HstPtr)); + ODBG(ODT_Mapping) << "Notifying about an unmapping: HstPtr=" << HstPtr; if (RTL->data_notify_unmapped(RTLDeviceID, HstPtr)) { - REPORT("Notifying about data unmapping failed.\n"); + REPORT() << "Notifying about data unmapping failed."; return OFFLOAD_FAIL; } return OFFLOAD_SUCCESS; From 1305a3eeafe10920f87e5140a43cce64af8aa9a3 Mon Sep 17 00:00:00 2001 From: Alex Duran Date: Tue, 2 Dec 2025 10:05:01 +0100 Subject: [PATCH 2/3] minor cleanup --- offload/include/Shared/Debug.h | 10 +++------- offload/libomptarget/OffloadRTL.cpp | 1 + offload/libomptarget/device.cpp | 1 + 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/offload/include/Shared/Debug.h b/offload/include/Shared/Debug.h index feba3c9dddb29..3a7687b24d8d4 100644 --- a/offload/include/Shared/Debug.h +++ b/offload/include/Shared/Debug.h @@ -517,7 +517,9 @@ static inline odbg_ostream reportErrorStream() { #define REPORT_INT_OLD(...) \ do { \ if (::llvm::offload::debug::isDebugEnabled()) { \ - ODBG(ODT_Error, ODL_Error) << FORMAT_TO_STR(__VA_ARGS__); \ + ODBG(::llvm::omptarget::debug::ODT_Error, \ + ::llvm::omptarget::debug::ODL_Error) \ + << FORMAT_TO_STR(__VA_ARGS__); \ } else { \ FAILURE_MESSAGE(__VA_ARGS__); \ } \ @@ -538,10 +540,4 @@ static inline odbg_ostream reportErrorStream() { } // namespace llvm::omptarget::debug -using namespace llvm::omptarget::debug; - -static inline int getDebugLevel() { - return ::llvm::offload::debug::isDebugEnabled(); -} - #endif // OMPTARGET_SHARED_DEBUG_H diff --git a/offload/libomptarget/OffloadRTL.cpp b/offload/libomptarget/OffloadRTL.cpp index 77c5768b62168..3dc37db1e1d67 100644 --- a/offload/libomptarget/OffloadRTL.cpp +++ b/offload/libomptarget/OffloadRTL.cpp @@ -19,6 +19,7 @@ #ifdef OMPT_SUPPORT extern void llvm::omp::target::ompt::connectLibrary(); #endif +using namespace llvm::omptarget::debug; static std::mutex PluginMtx; static uint32_t RefCount = 0; diff --git a/offload/libomptarget/device.cpp b/offload/libomptarget/device.cpp index 5637a77508039..055b901372a37 100644 --- a/offload/libomptarget/device.cpp +++ b/offload/libomptarget/device.cpp @@ -38,6 +38,7 @@ using namespace llvm::omp::target::ompt; #endif using namespace llvm::omp::target::plugin; +using namespace llvm::omptarget::debug; int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, AsyncInfoTy &AsyncInfo) const { From 845c5b2587a9ce358104aba2fccfcda5319bad17 Mon Sep 17 00:00:00 2001 From: Alex Duran Date: Tue, 2 Dec 2025 10:07:44 +0100 Subject: [PATCH 3/3] update namespace name --- offload/include/Shared/Debug.h | 12 ++++++------ offload/libomptarget/OffloadRTL.cpp | 2 +- offload/libomptarget/device.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/offload/include/Shared/Debug.h b/offload/include/Shared/Debug.h index 3a7687b24d8d4..9e657e64484c0 100644 --- a/offload/include/Shared/Debug.h +++ b/offload/include/Shared/Debug.h @@ -450,7 +450,7 @@ inline bool isDebugEnabled() { return false; } } // namespace llvm::offload::debug -namespace llvm::omptarget::debug { +namespace llvm::omp::target::debug { using namespace llvm::offload::debug; enum OmpDebugLevel : uint32_t { @@ -510,15 +510,15 @@ static inline odbg_ostream reportErrorStream() { // helper macro to support old DP and REPORT macros with printf syntax #define FORMAT_TO_STR(Format, ...) \ - ::llvm::omptarget::debug::formatToStr(Format __VA_OPT__(, ) __VA_ARGS__) + ::llvm::omp::target::debug::formatToStr(Format __VA_OPT__(, ) __VA_ARGS__) #define DP(...) ODBG() << FORMAT_TO_STR(__VA_ARGS__); #define REPORT_INT_OLD(...) \ do { \ if (::llvm::offload::debug::isDebugEnabled()) { \ - ODBG(::llvm::omptarget::debug::ODT_Error, \ - ::llvm::omptarget::debug::ODL_Error) \ + ODBG(::llvm::omp::target::debug::ODT_Error, \ + ::llvm::omp::target::debug::ODL_Error) \ << FORMAT_TO_STR(__VA_ARGS__); \ } else { \ FAILURE_MESSAGE(__VA_ARGS__); \ @@ -533,11 +533,11 @@ static inline odbg_ostream reportErrorStream() { #endif // OMPTARGET_DEBUG // This is used for the new style REPORT macro -#define REPORT_INT() ::llvm::omptarget::debug::reportErrorStream() +#define REPORT_INT() ::llvm::omp::target::debug::reportErrorStream() // Make REPORT compatible with old and new syntax #define REPORT(...) REPORT_INT##__VA_OPT__(_OLD)(__VA_ARGS__) -} // namespace llvm::omptarget::debug +} // namespace llvm::omp::target::debug #endif // OMPTARGET_SHARED_DEBUG_H diff --git a/offload/libomptarget/OffloadRTL.cpp b/offload/libomptarget/OffloadRTL.cpp index 3dc37db1e1d67..3a18d76aaae15 100644 --- a/offload/libomptarget/OffloadRTL.cpp +++ b/offload/libomptarget/OffloadRTL.cpp @@ -19,7 +19,7 @@ #ifdef OMPT_SUPPORT extern void llvm::omp::target::ompt::connectLibrary(); #endif -using namespace llvm::omptarget::debug; +using namespace llvm::omp::target::debug; static std::mutex PluginMtx; static uint32_t RefCount = 0; diff --git a/offload/libomptarget/device.cpp b/offload/libomptarget/device.cpp index 055b901372a37..e5434f68c2105 100644 --- a/offload/libomptarget/device.cpp +++ b/offload/libomptarget/device.cpp @@ -38,7 +38,7 @@ using namespace llvm::omp::target::ompt; #endif using namespace llvm::omp::target::plugin; -using namespace llvm::omptarget::debug; +using namespace llvm::omp::target::debug; int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device, AsyncInfoTy &AsyncInfo) const {