Skip to content

Commit ec6091f

Browse files
authored
[OFFLOAD][LIBOMPTARGET] Start to update debug messages in libomptarget (#170265)
* Add compatibility support for DP and REPORT macros * Define a set of predefined Debug Type for libomptarget * Start to update libomptarget files (OffloadRTL.cpp, device.cpp)
1 parent 9885aed commit ec6091f

File tree

3 files changed

+205
-142
lines changed

3 files changed

+205
-142
lines changed

offload/include/Shared/Debug.h

Lines changed: 192 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#define OMPTARGET_SHARED_DEBUG_H
4040

4141
#include <atomic>
42+
#include <cstdarg>
4243
#include <mutex>
4344
#include <string>
4445

@@ -78,17 +79,6 @@ inline std::atomic<uint32_t> &getInfoLevelInternal() {
7879

7980
inline uint32_t getInfoLevel() { return getInfoLevelInternal().load(); }
8081

81-
inline uint32_t getDebugLevel() {
82-
static uint32_t DebugLevel = 0;
83-
static std::once_flag Flag{};
84-
std::call_once(Flag, []() {
85-
if (char *EnvStr = getenv("LIBOMPTARGET_DEBUG"))
86-
DebugLevel = std::stoi(EnvStr);
87-
});
88-
89-
return DebugLevel;
90-
}
91-
9282
#undef USED
9383
#undef GCC_VERSION
9484

@@ -147,46 +137,11 @@ inline uint32_t getDebugLevel() {
147137
fprintf(_stdDst, __VA_ARGS__); \
148138
} while (0)
149139

150-
// Debugging messages
151-
#ifdef OMPTARGET_DEBUG
152-
#include <stdio.h>
153-
154-
#define DEBUGP(prefix, ...) \
155-
{ \
156-
fprintf(stderr, "%s --> ", prefix); \
157-
fprintf(stderr, __VA_ARGS__); \
158-
}
159-
160-
/// Emit a message for debugging
161-
#define DP(...) \
162-
do { \
163-
if (getDebugLevel() > 0) { \
164-
DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \
165-
} \
166-
} while (false)
167-
168-
/// Emit a message for debugging or failure if debugging is disabled
169-
#define REPORT(...) \
170-
do { \
171-
if (getDebugLevel() > 0) { \
172-
DP(__VA_ARGS__); \
173-
} else { \
174-
FAILURE_MESSAGE(__VA_ARGS__); \
175-
} \
176-
} while (false)
177-
#else
178-
#define DEBUGP(prefix, ...) \
179-
{}
180-
#define DP(...) \
181-
{}
182-
#define REPORT(...) FAILURE_MESSAGE(__VA_ARGS__);
183-
#endif // OMPTARGET_DEBUG
184-
185140
/// Emit a message giving the user extra information about the runtime if
186141
#define INFO(_flags, _id, ...) \
187142
do { \
188-
if (getDebugLevel() > 0) { \
189-
DEBUGP(DEBUG_PREFIX, __VA_ARGS__); \
143+
if (::llvm::offload::debug::isDebugEnabled()) { \
144+
DP(__VA_ARGS__); \
190145
} else if (getInfoLevel() & _flags) { \
191146
INFO_MESSAGE(_id, __VA_ARGS__); \
192147
} \
@@ -203,17 +158,92 @@ inline uint32_t getDebugLevel() {
203158

204159
namespace llvm::offload::debug {
205160

206-
#ifdef OMPTARGET_DEBUG
161+
/// A raw_ostream that tracks `\n` and print the prefix after each
162+
/// newline. Based on raw_ldbg_ostream from Support/DebugLog.h
163+
class LLVM_ABI odbg_ostream final : public raw_ostream {
164+
public:
165+
enum IfLevel : uint32_t;
166+
enum OnlyLevel : uint32_t;
207167

208-
struct DebugFilter {
209-
StringRef Type;
210-
uint32_t Level;
211-
};
168+
private:
169+
std::string Prefix;
170+
raw_ostream &Os;
171+
uint32_t BaseLevel;
172+
bool ShouldPrefixNextString;
173+
bool ShouldEmitNewLineOnDestruction;
174+
bool NeedEndNewLine = false;
212175

213-
struct DebugSettings {
214-
bool Enabled = false;
215-
uint32_t DefaultLevel = 1;
216-
llvm::SmallVector<DebugFilter> Filters;
176+
/// If the stream is muted, writes to it are ignored
177+
bool Muted = false;
178+
179+
/// Split the line on newlines and insert the prefix before each
180+
/// newline. Forward everything to the underlying stream.
181+
void write_impl(const char *Ptr, size_t Size) final {
182+
if (Muted)
183+
return;
184+
185+
NeedEndNewLine = false;
186+
auto Str = StringRef(Ptr, Size);
187+
auto Eol = Str.find('\n');
188+
// Handle `\n` occurring in the string, ensure to print the prefix at the
189+
// beginning of each line.
190+
while (Eol != StringRef::npos) {
191+
// Take the line up to the newline (including the newline).
192+
StringRef Line = Str.take_front(Eol + 1);
193+
if (!Line.empty())
194+
writeWithPrefix(Line);
195+
// We printed a newline, record here to print a prefix.
196+
ShouldPrefixNextString = true;
197+
Str = Str.drop_front(Eol + 1);
198+
Eol = Str.find('\n');
199+
}
200+
if (!Str.empty()) {
201+
writeWithPrefix(Str);
202+
NeedEndNewLine = true;
203+
}
204+
}
205+
void emitPrefix() { Os.write(Prefix.c_str(), Prefix.size()); }
206+
void writeWithPrefix(StringRef Str) {
207+
if (ShouldPrefixNextString) {
208+
emitPrefix();
209+
ShouldPrefixNextString = false;
210+
}
211+
Os.write(Str.data(), Str.size());
212+
}
213+
214+
public:
215+
explicit odbg_ostream(std::string Prefix, raw_ostream &Os, uint32_t BaseLevel,
216+
bool ShouldPrefixNextString = true,
217+
bool ShouldEmitNewLineOnDestruction = true)
218+
: Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel),
219+
ShouldPrefixNextString(ShouldPrefixNextString),
220+
ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) {
221+
SetUnbuffered();
222+
}
223+
~odbg_ostream() final {
224+
if (ShouldEmitNewLineOnDestruction && NeedEndNewLine)
225+
Os << '\n';
226+
}
227+
odbg_ostream(const odbg_ostream &) = delete;
228+
odbg_ostream &operator=(const odbg_ostream &) = delete;
229+
odbg_ostream(odbg_ostream &&other) : Os(other.Os) {
230+
Prefix = std::move(other.Prefix);
231+
BaseLevel = other.BaseLevel;
232+
ShouldPrefixNextString = other.ShouldPrefixNextString;
233+
ShouldEmitNewLineOnDestruction = other.ShouldEmitNewLineOnDestruction;
234+
NeedEndNewLine = other.NeedEndNewLine;
235+
Muted = other.Muted;
236+
}
237+
238+
/// Forward the current_pos method to the underlying stream.
239+
uint64_t current_pos() const final { return Os.tell(); }
240+
241+
/// Some of the `<<` operators expect an lvalue, so we trick the type
242+
/// system.
243+
odbg_ostream &asLvalue() { return *this; }
244+
245+
void shouldMute(const IfLevel Filter) { Muted = Filter > BaseLevel; }
246+
void shouldMute(const OnlyLevel Filter) { Muted = BaseLevel != Filter; }
217247
};
218248

219249
/// dbgs - Return a circular-buffered debug stream.
@@ -228,6 +258,19 @@ struct DebugSettings {
228258
return thestrm.strm;
229259
}
230260

261+
#ifdef OMPTARGET_DEBUG
262+
263+
struct DebugFilter {
264+
StringRef Type;
265+
uint32_t Level;
266+
};
267+
268+
struct DebugSettings {
269+
bool Enabled = false;
270+
uint32_t DefaultLevel = 1;
271+
llvm::SmallVector<DebugFilter> Filters;
272+
};
273+
231274
[[maybe_unused]] static DebugFilter parseDebugFilter(StringRef Filter) {
232275
size_t Pos = Filter.find(':');
233276
if (Pos == StringRef::npos)
@@ -309,80 +352,6 @@ shouldPrintDebug(const char *Component, const char *Type, uint32_t &Level) {
309352
return false;
310353
}
311354

312-
/// A raw_ostream that tracks `\n` and print the prefix after each
313-
/// newline. Based on raw_ldbg_ostream from Support/DebugLog.h
314-
class LLVM_ABI odbg_ostream final : public raw_ostream {
315-
public:
316-
enum IfLevel : uint32_t;
317-
enum OnlyLevel : uint32_t;
318-
319-
private:
320-
std::string Prefix;
321-
raw_ostream &Os;
322-
uint32_t BaseLevel;
323-
bool ShouldPrefixNextString;
324-
bool ShouldEmitNewLineOnDestruction;
325-
326-
/// If the stream is muted, writes to it are ignored
327-
bool Muted = false;
328-
329-
/// Split the line on newlines and insert the prefix before each
330-
/// newline. Forward everything to the underlying stream.
331-
void write_impl(const char *Ptr, size_t Size) final {
332-
if (Muted)
333-
return;
334-
335-
auto Str = StringRef(Ptr, Size);
336-
auto Eol = Str.find('\n');
337-
// Handle `\n` occurring in the string, ensure to print the prefix at the
338-
// beginning of each line.
339-
while (Eol != StringRef::npos) {
340-
// Take the line up to the newline (including the newline).
341-
StringRef Line = Str.take_front(Eol + 1);
342-
if (!Line.empty())
343-
writeWithPrefix(Line);
344-
// We printed a newline, record here to print a prefix.
345-
ShouldPrefixNextString = true;
346-
Str = Str.drop_front(Eol + 1);
347-
Eol = Str.find('\n');
348-
}
349-
if (!Str.empty())
350-
writeWithPrefix(Str);
351-
}
352-
void emitPrefix() { Os.write(Prefix.c_str(), Prefix.size()); }
353-
void writeWithPrefix(StringRef Str) {
354-
if (ShouldPrefixNextString) {
355-
emitPrefix();
356-
ShouldPrefixNextString = false;
357-
}
358-
Os.write(Str.data(), Str.size());
359-
}
360-
361-
public:
362-
explicit odbg_ostream(std::string Prefix, raw_ostream &Os, uint32_t BaseLevel,
363-
bool ShouldPrefixNextString = true,
364-
bool ShouldEmitNewLineOnDestruction = false)
365-
: Prefix(std::move(Prefix)), Os(Os), BaseLevel(BaseLevel),
366-
ShouldPrefixNextString(ShouldPrefixNextString),
367-
ShouldEmitNewLineOnDestruction(ShouldEmitNewLineOnDestruction) {
368-
SetUnbuffered();
369-
}
370-
~odbg_ostream() final {
371-
if (ShouldEmitNewLineOnDestruction)
372-
Os << '\n';
373-
}
374-
375-
/// Forward the current_pos method to the underlying stream.
376-
uint64_t current_pos() const final { return Os.tell(); }
377-
378-
/// Some of the `<<` operators expect an lvalue, so we trick the type
379-
/// system.
380-
odbg_ostream &asLvalue() { return *this; }
381-
382-
void shouldMute(const IfLevel Filter) { Muted = Filter > BaseLevel; }
383-
void shouldMute(const OnlyLevel Filter) { Muted = BaseLevel != Filter; }
384-
};
385-
386355
/// Compute the prefix for the debug log in the form of:
387356
/// "Component --> "
388357
[[maybe_unused]] static std::string computePrefix(StringRef Component,
@@ -463,6 +432,8 @@ static inline raw_ostream &operator<<(raw_ostream &Os,
463432

464433
#else
465434

435+
inline bool isDebugEnabled() { return false; }
436+
466437
#define ODBG_NULL \
467438
for (bool _c = false; _c; _c = false) \
468439
::llvm::nulls()
@@ -479,4 +450,94 @@ static inline raw_ostream &operator<<(raw_ostream &Os,
479450

480451
} // namespace llvm::offload::debug
481452

453+
namespace llvm::omp::target::debug {
454+
using namespace llvm::offload::debug;
455+
456+
enum OmpDebugLevel : uint32_t {
457+
ODL_Default = 1,
458+
ODL_Error = ODL_Default,
459+
ODL_Detailed = 2,
460+
ODL_Verbose = 3,
461+
ODL_VeryVerbose = 4,
462+
ODL_Dumping = 5
463+
};
464+
465+
/* Debug types to use in libomptarget */
466+
constexpr const char *ODT_Init = "Init";
467+
constexpr const char *ODT_Mapping = "Mapping";
468+
constexpr const char *ODT_Kernel = "Kernel";
469+
constexpr const char *ODT_DataTransfer = "DataTransfer";
470+
constexpr const char *ODT_Sync = "Sync";
471+
constexpr const char *ODT_Deinit = "Deinit";
472+
constexpr const char *ODT_Error = "Error";
473+
constexpr const char *ODT_KernelArgs = "KernelArgs";
474+
constexpr const char *ODT_MappingExists = "MappingExists";
475+
constexpr const char *ODT_DumpTable = "DumpTable";
476+
constexpr const char *ODT_MappingChanged = "MappingChanged";
477+
constexpr const char *ODT_PluginKernel = "PluginKernel";
478+
constexpr const char *ODT_EmptyMapping = "EmptyMapping";
479+
480+
static inline odbg_ostream reportErrorStream() {
481+
#ifdef OMPTARGET_DEBUG
482+
if (::llvm::offload::debug::isDebugEnabled()) {
483+
uint32_t RealLevel = ODL_Error;
484+
if (::llvm::offload::debug::shouldPrintDebug(GETNAME(TARGET_NAME),
485+
(ODT_Error), RealLevel))
486+
return odbg_ostream{
487+
::llvm::offload::debug::computePrefix(DEBUG_PREFIX, ODT_Error),
488+
::llvm::offload::debug::dbgs(), RealLevel};
489+
else
490+
return odbg_ostream{"", ::llvm::nulls(), 1};
491+
}
492+
#endif
493+
return odbg_ostream{GETNAME(TARGET_NAME) " error: ",
494+
::llvm::offload::debug::dbgs(), ODL_Error};
495+
}
496+
497+
#ifdef OMPTARGET_DEBUG
498+
// Deprecated debug print macros
499+
[[maybe_unused]] static std::string formatToStr(const char *format, ...) {
500+
va_list args;
501+
va_start(args, format);
502+
size_t len = std::vsnprintf(NULL, 0, format, args);
503+
va_end(args);
504+
llvm::SmallVector<char, 128> vec(len + 1);
505+
va_start(args, format);
506+
std::vsnprintf(&vec[0], len + 1, format, args);
507+
va_end(args);
508+
return &vec[0];
509+
}
510+
511+
// helper macro to support old DP and REPORT macros with printf syntax
512+
#define FORMAT_TO_STR(Format, ...) \
513+
::llvm::omp::target::debug::formatToStr(Format __VA_OPT__(, ) __VA_ARGS__)
514+
515+
#define DP(...) ODBG() << FORMAT_TO_STR(__VA_ARGS__);
516+
517+
#define REPORT_INT_OLD(...) \
518+
do { \
519+
if (::llvm::offload::debug::isDebugEnabled()) { \
520+
ODBG(::llvm::omp::target::debug::ODT_Error, \
521+
::llvm::omp::target::debug::ODL_Error) \
522+
<< FORMAT_TO_STR(__VA_ARGS__); \
523+
} else { \
524+
FAILURE_MESSAGE(__VA_ARGS__); \
525+
} \
526+
} while (false)
527+
528+
#else
529+
#define DP(...) \
530+
{ \
531+
}
532+
#define REPORT_INT_OLD(...) FAILURE_MESSAGE(__VA_ARGS__);
533+
#endif // OMPTARGET_DEBUG
534+
535+
// This is used for the new style REPORT macro
536+
#define REPORT_INT() ::llvm::omp::target::debug::reportErrorStream()
537+
538+
// Make REPORT compatible with old and new syntax
539+
#define REPORT(...) REPORT_INT##__VA_OPT__(_OLD)(__VA_ARGS__)
540+
541+
} // namespace llvm::omp::target::debug
542+
482543
#endif // OMPTARGET_SHARED_DEBUG_H

0 commit comments

Comments
 (0)