Skip to content

Commit 3b007d9

Browse files
authored
[UR][L0] Init/deinit L0 adapter on first/last use (#19089)
Instead of using a global constructor to initialize the L0 adapter, do it in the first call to `urAdapterGet`. Likewise, instead of de-initing it as a global destructor, do it in the last call to `urAdapterRelease`. As well as not doing L0 initialization where the user is not using L0, it also allows `urAdapterRelease` to be called in a global destructor (e.g. what the SYCL runtime does) without worrying about global destructor order.
1 parent fb18321 commit 3b007d9

File tree

4 files changed

+27
-69
lines changed

4 files changed

+27
-69
lines changed

unified-runtime/source/adapters/level_zero/CMakeLists.txt

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,6 @@ if(UR_BUILD_ADAPTER_L0)
9090
endforeach()
9191
endif()
9292

93-
if(NOT WIN32)
94-
target_sources(ur_adapter_level_zero
95-
PRIVATE
96-
${CMAKE_CURRENT_SOURCE_DIR}/adapter_lib_init_linux.cpp
97-
)
98-
endif()
99-
10093
# TODO: fix level_zero adapter conversion warnings
10194
target_compile_options(ur_adapter_level_zero PRIVATE
10295
$<$<CXX_COMPILER_ID:MSVC>:/wd4805 /wd4244>
@@ -195,11 +188,6 @@ if(UR_BUILD_ADAPTER_L0_V2)
195188
# api.cpp contains NOT_SUPPORTED functions-only
196189
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/v2/api.cpp
197190
PROPERTIES APPEND_STRING PROPERTY COMPILE_FLAGS "-Wno-unused-parameter")
198-
199-
target_sources(ur_adapter_level_zero_v2
200-
PRIVATE
201-
${CMAKE_CURRENT_SOURCE_DIR}/adapter_lib_init_linux.cpp
202-
)
203191
endif()
204192

205193
target_compile_definitions(ur_adapter_level_zero_v2 PUBLIC UR_STATIC_LEVEL_ZERO)

unified-runtime/source/adapters/level_zero/adapter.cpp

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -665,24 +665,19 @@ ur_result_t urAdapterGet(
665665
ur_adapter_handle_t *Adapters,
666666
/// [out][optional] returns the total number of adapters available.
667667
uint32_t *NumAdapters) {
668+
static std::mutex AdapterConstructionMutex{};
669+
668670
if (NumEntries > 0 && Adapters) {
669-
if (GlobalAdapter) {
670-
std::lock_guard<std::mutex> Lock{GlobalAdapter->Mutex};
671-
if (GlobalAdapter->RefCount++ == 0) {
672-
adapterStateInit();
673-
}
674-
} else {
675-
// If the GetAdapter is called after the Library began or was torndown,
676-
// then temporarily create a new Adapter handle and register a new
677-
// cleanup.
671+
std::lock_guard<std::mutex> Lock{AdapterConstructionMutex};
672+
673+
if (!GlobalAdapter) {
678674
GlobalAdapter = new ur_adapter_handle_t_();
679-
std::lock_guard<std::mutex> Lock{GlobalAdapter->Mutex};
680-
if (GlobalAdapter->RefCount++ == 0) {
681-
adapterStateInit();
682-
}
683-
std::atexit(globalAdapterOnDemandCleanup);
684675
}
685676
*Adapters = GlobalAdapter;
677+
678+
if (GlobalAdapter->RefCount++ == 0) {
679+
adapterStateInit();
680+
}
686681
}
687682

688683
if (NumAdapters) {
@@ -692,29 +687,31 @@ ur_result_t urAdapterGet(
692687
return UR_RESULT_SUCCESS;
693688
}
694689

695-
ur_result_t urAdapterRelease(ur_adapter_handle_t) {
696-
// Check first if the Adapter pointer is valid
697-
if (GlobalAdapter) {
698-
std::lock_guard<std::mutex> Lock{GlobalAdapter->Mutex};
699-
if (--GlobalAdapter->RefCount == 0) {
700-
auto result = adapterStateTeardown();
690+
ur_result_t urAdapterRelease([[maybe_unused]] ur_adapter_handle_t Adapter) {
691+
assert(GlobalAdapter && GlobalAdapter == Adapter);
692+
693+
// NOTE: This does not require guarding with a mutex; the instant the ref
694+
// count hits zero, both Get and Retain are UB.
695+
if (--GlobalAdapter->RefCount == 0) {
696+
auto result = adapterStateTeardown();
701697
#ifdef UR_STATIC_LEVEL_ZERO
702-
// Given static linking of the L0 Loader, we must delay the loader's
703-
// destruction of its context until after the UR Adapter is destroyed.
704-
zelLoaderContextTeardown();
698+
// Given static linking of the L0 Loader, we must delay the loader's
699+
// destruction of its context until after the UR Adapter is destroyed.
700+
zelLoaderContextTeardown();
705701
#endif
706-
return result;
707-
}
702+
703+
delete GlobalAdapter;
704+
GlobalAdapter = nullptr;
705+
706+
return result;
708707
}
709708

710709
return UR_RESULT_SUCCESS;
711710
}
712711

713-
ur_result_t urAdapterRetain(ur_adapter_handle_t) {
714-
if (GlobalAdapter) {
715-
std::lock_guard<std::mutex> Lock{GlobalAdapter->Mutex};
716-
GlobalAdapter->RefCount++;
717-
}
712+
ur_result_t urAdapterRetain([[maybe_unused]] ur_adapter_handle_t Adapter) {
713+
assert(GlobalAdapter && GlobalAdapter == Adapter);
714+
GlobalAdapter->RefCount++;
718715

719716
return UR_RESULT_SUCCESS;
720717
}

unified-runtime/source/adapters/level_zero/adapter.hpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <atomic>
1515
#include <loader/ur_loader.hpp>
1616
#include <loader/ze_loader.h>
17-
#include <mutex>
1817
#include <optional>
1918
#include <ur/ur.hpp>
2019
#include <ze_api.h>
@@ -28,7 +27,6 @@ class ur_legacy_sink;
2827
struct ur_adapter_handle_t_ : ur::handle_base<ur::level_zero::ddi_getter> {
2928
ur_adapter_handle_t_();
3029
std::atomic<uint32_t> RefCount = 0;
31-
std::mutex Mutex;
3230

3331
zes_pfnDriverGetDeviceByUuidExp_t getDeviceByUUIdFunctionPtr = nullptr;
3432
zes_pfnDriverGet_t getSysManDriversFunctionPtr = nullptr;

unified-runtime/source/adapters/level_zero/adapter_lib_init_linux.cpp

Lines changed: 0 additions & 25 deletions
This file was deleted.

0 commit comments

Comments
 (0)