From eeaa897f07911186bd9673adf52b2d3e09c0dda9 Mon Sep 17 00:00:00 2001 From: omarahmed1111 Date: Fri, 23 Aug 2024 10:55:41 +0100 Subject: [PATCH 1/2] Add umfInit/umfTearDown to urAdapterGet/urAdapterRelease --- source/adapters/level_zero/adapter.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source/adapters/level_zero/adapter.cpp b/source/adapters/level_zero/adapter.cpp index 5ae1d52e7b..7aa72bc3e7 100644 --- a/source/adapters/level_zero/adapter.cpp +++ b/source/adapters/level_zero/adapter.cpp @@ -12,6 +12,14 @@ #include "ur_level_zero.hpp" #include +// As windows order of unloading dlls is reversed from linux, windows will call +// umfTearDown before it could release umf objects in level_zero, so we call +// umfInit on urAdapterGet and umfAdapterTearDown to enforce the teardown of umf +// after umf objects are destructed. +#if defined(_WIN32) +#include +#endif + // Due to multiple DLLMain definitions with SYCL, Global Adapter is init at // variable creation. #if defined(_WIN32) @@ -74,7 +82,14 @@ ur_result_t initPlatforms(PlatformVec &platforms) noexcept try { return exceptionToResult(std::current_exception()); } -ur_result_t adapterStateInit() { return UR_RESULT_SUCCESS; } +ur_result_t adapterStateInit() { + +#if defined(_WIN32) + umfInit(); +#endif + + return UR_RESULT_SUCCESS; +} ur_adapter_handle_t_::ur_adapter_handle_t_() : logger(logger::get_logger("level_zero")) { @@ -258,6 +273,7 @@ ur_result_t adapterStateTeardown() { // Due to multiple DLLMain definitions with SYCL, register to cleanup the // Global Adapter after refcnt is 0 #if defined(_WIN32) + umfTearDown(); std::atexit(globalAdapterOnDemandCleanup); #endif From 581a0d8d91b1fa680ca2e58df91225fd2c3d6a2c Mon Sep 17 00:00:00 2001 From: omarahmed1111 Date: Tue, 27 Aug 2024 10:56:20 +0100 Subject: [PATCH 2/2] Add a workaround for the logger on windows --- source/adapters/level_zero/adapter.cpp | 13 +++++++++++-- source/common/logger/ur_sinks.hpp | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/source/adapters/level_zero/adapter.cpp b/source/adapters/level_zero/adapter.cpp index 7aa72bc3e7..ed52254ec3 100644 --- a/source/adapters/level_zero/adapter.cpp +++ b/source/adapters/level_zero/adapter.cpp @@ -27,7 +27,12 @@ ur_adapter_handle_t_ *GlobalAdapter = new ur_adapter_handle_t_(); #else ur_adapter_handle_t_ *GlobalAdapter; #endif - +// This is a temporary workaround on windows, where UR adapter is teardowned +// before the UR loader, which will result in access violation when we use print +// function as the overrided print function was already released with the UR +// adapter. +// TODO: Change adapters to use a common sink class in the loader instead of +// using thier own sink class that inherit from logger::Sink. class ur_legacy_sink : public logger::Sink { public: ur_legacy_sink(std::string logger_name = "", bool skip_prefix = true) @@ -40,7 +45,11 @@ class ur_legacy_sink : public logger::Sink { fprintf(stderr, "%s", msg.c_str()); } - ~ur_legacy_sink() = default; + ~ur_legacy_sink() { +#if defined(_WIN32) + logger::isTearDowned = true; +#endif + }; }; ur_result_t initPlatforms(PlatformVec &platforms) noexcept try { diff --git a/source/common/logger/ur_sinks.hpp b/source/common/logger/ur_sinks.hpp index b2ebf72a7a..e0d8144a31 100644 --- a/source/common/logger/ur_sinks.hpp +++ b/source/common/logger/ur_sinks.hpp @@ -17,6 +17,10 @@ namespace logger { +#if defined(_WIN32) +inline bool isTearDowned = false; +#endif + class Sink { public: template @@ -28,7 +32,21 @@ class Sink { } format(buffer, fmt, std::forward(args)...); +// This is a temporary workaround on windows, where UR adapter is teardowned +// before the UR loader, which will result in access violation when we use print +// function as the overrided print function was already released with the UR +// adapter. +// TODO: Change adapters to use a common sink class in the loader instead of +// using thier own sink class that inherit from logger::Sink. +#if defined(_WIN32) + if (isTearDowned) { + std::cerr << buffer.str() << "\n"; + } else { + print(level, buffer.str()); + } +#else print(level, buffer.str()); +#endif } void setFlushLevel(logger::Level level) { this->flush_level = level; }