mirror of
https://github.com/intel/llvm.git
synced 2026-01-13 11:02:04 +08:00
[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)
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
#define OMPTARGET_SHARED_DEBUG_H
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdarg>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
@@ -78,17 +79,6 @@ inline std::atomic<uint32_t> &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 <stdio.h>
|
||||
|
||||
#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<DebugFilter> 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<DebugFilter> 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,94 @@ static inline raw_ostream &operator<<(raw_ostream &Os,
|
||||
|
||||
} // namespace llvm::offload::debug
|
||||
|
||||
namespace llvm::omp::target::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<char, 128> 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::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::omp::target::debug::ODT_Error, \
|
||||
::llvm::omp::target::debug::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::omp::target::debug::reportErrorStream()
|
||||
|
||||
// Make REPORT compatible with old and new syntax
|
||||
#define REPORT(...) REPORT_INT##__VA_OPT__(_OLD)(__VA_ARGS__)
|
||||
|
||||
} // namespace llvm::omp::target::debug
|
||||
|
||||
#endif // OMPTARGET_SHARED_DEBUG_H
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#ifdef OMPT_SUPPORT
|
||||
extern void llvm::omp::target::ompt::connectLibrary();
|
||||
#endif
|
||||
using namespace llvm::omp::target::debug;
|
||||
|
||||
static std::mutex PluginMtx;
|
||||
static uint32_t RefCount = 0;
|
||||
@@ -35,7 +36,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 +55,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();
|
||||
|
||||
@@ -38,6 +38,7 @@ using namespace llvm::omp::target::ompt;
|
||||
#endif
|
||||
|
||||
using namespace llvm::omp::target::plugin;
|
||||
using namespace llvm::omp::target::debug;
|
||||
|
||||
int HostDataToTargetTy::addEventIfNecessary(DeviceTy &Device,
|
||||
AsyncInfoTy &AsyncInfo) const {
|
||||
@@ -48,7 +49,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 +57,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;
|
||||
}
|
||||
|
||||
@@ -315,21 +316,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;
|
||||
|
||||
Reference in New Issue
Block a user