Skip to content

Commit f2dd1ec

Browse files
author
omarahmed1111
committed
ensure UR will clear context on unloading
1 parent 35e4ba1 commit f2dd1ec

6 files changed

Lines changed: 109 additions & 1 deletion

File tree

source/adapters/level_zero/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ if(UR_BUILD_ADAPTER_L0)
140140
PRIVATE
141141
${CMAKE_CURRENT_SOURCE_DIR}/adapter_lib_init_linux.cpp
142142
)
143+
else()
144+
target_sources(ur_adapter_level_zero
145+
PRIVATE
146+
${CMAKE_CURRENT_SOURCE_DIR}/adapter_lib_init_windows.cpp
147+
)
143148
endif()
144149

145150
# TODO: fix level_zero adapter conversion warnings
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===--------- adapter_lib_init_linux.cpp - Level Zero Adapter ------------===//
2+
//
3+
// Copyright (C) 2023 Intel Corporation
4+
//
5+
// Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM
6+
// Exceptions. See LICENSE.TXT
7+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
#include "adapter.hpp"
12+
#include "ur_level_zero.hpp"
13+
14+
#include <windows.h>
15+
16+
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
17+
DWORD fdwReason, // reason for calling function
18+
LPVOID lpReserved) // reserved
19+
{
20+
switch (fdwReason) {
21+
case DLL_PROCESS_ATTACH:
22+
break;
23+
case DLL_PROCESS_DETACH: {
24+
std::lock_guard<std::mutex> Lock{GlobalAdapter->Mutex};
25+
const auto *platforms = GlobalAdapter->PlatformCache->get_value();
26+
for (const auto &p : *platforms) {
27+
std::scoped_lock<ur_shared_mutex> ContextsLock(p->ContextsMutex);
28+
while (!p->Contexts.empty()) {
29+
ur_context_handle_t &ctx = p->Contexts.front();
30+
ctx->deleteCachedObjectsOnDestruction();
31+
UR_CALL(urContextRelease(ctx));
32+
deleteFromCachedList<ur_context_handle_t>(ctx, p->Contexts);
33+
}
34+
}
35+
break;
36+
}
37+
case DLL_THREAD_ATTACH:
38+
break;
39+
case DLL_THREAD_DETACH:
40+
break;
41+
}
42+
return TRUE;
43+
}

source/adapters/level_zero/common.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,9 @@ extern const bool UseUSMAllocator;
450450

451451
// Controls support of the indirect access kernels and deferred memory release.
452452
const bool IndirectAccessTrackingEnabled = [] {
453+
#ifdef _WIN32
454+
return false;
455+
#endif
453456
char *UrRet = std::getenv("UR_L0_TRACK_INDIRECT_ACCESS_MEMORY");
454457
char *PiRet = std::getenv("SYCL_PI_LEVEL_ZERO_TRACK_INDIRECT_ACCESS_MEMORY");
455458
const bool RetVal = UrRet ? std::stoi(UrRet) : (PiRet ? std::stoi(PiRet) : 0);
@@ -530,4 +533,19 @@ extern thread_local int32_t ErrorAdapterNativeCode;
530533
ur_result_t ErrorCode,
531534
int32_t AdapterErrorCode);
532535

536+
template <class T>
537+
void addToCachedList(T &CachedObject, std::list<T> &CachedList) {
538+
auto It = std::find(CachedList.begin(), CachedList.end(), CachedObject);
539+
if (It == CachedList.end()) {
540+
CachedList.push_back(CachedObject);
541+
}
542+
}
543+
544+
template <class T>
545+
void deleteFromCachedList(T &CachedObject, std::list<T> &CachedList) {
546+
auto It = std::find(CachedList.begin(), CachedList.end(), CachedObject);
547+
if (It != CachedList.end())
548+
CachedList.erase(It);
549+
}
550+
533551
#define L0_DRIVER_INORDER_MIN_VERSION 29534

source/adapters/level_zero/context.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@ UR_APIEXPORT ur_result_t UR_APICALL urContextCreate(
4040

4141
Context->initialize();
4242
*RetContext = reinterpret_cast<ur_context_handle_t>(Context);
43+
#ifdef _WIN32
44+
std::scoped_lock<ur_shared_mutex> Lock(Platform->ContextsMutex);
45+
addToCachedList<ur_context_handle_t>(*RetContext, Platform->Contexts);
46+
#else
4347
if (IndirectAccessTrackingEnabled) {
4448
std::scoped_lock<ur_shared_mutex> Lock(Platform->ContextsMutex);
4549
Platform->Contexts.push_back(*RetContext);
4650
}
51+
#endif
4752
} catch (const std::bad_alloc &) {
4853
return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY;
4954
} catch (...) {
@@ -355,13 +360,21 @@ ur_result_t ContextReleaseHelper(ur_context_handle_t Context) {
355360
if (!Context->RefCount.decrementAndTest())
356361
return UR_RESULT_SUCCESS;
357362

358-
if (IndirectAccessTrackingEnabled) {
363+
auto DeleteFromContextsCache = [&]() {
359364
ur_platform_handle_t Plt = Context->getPlatform();
360365
auto &Contexts = Plt->Contexts;
361366
auto It = std::find(Contexts.begin(), Contexts.end(), Context);
362367
if (It != Contexts.end())
363368
Contexts.erase(It);
369+
};
370+
371+
#ifdef _WIN32
372+
DeleteFromContextsCache();
373+
#else
374+
if (IndirectAccessTrackingEnabled) {
375+
DeleteFromContextsCache();
364376
}
377+
#endif
365378
ze_context_handle_t DestroyZeContext =
366379
Context->OwnNativeHandle ? Context->ZeContext : nullptr;
367380

@@ -451,6 +464,12 @@ ur_result_t ur_context_handle_t_::finalize() {
451464
}
452465
}
453466
}
467+
468+
for (auto &kernel : KernelsCache) {
469+
UR_CALL(urKernelRelease(kernel));
470+
}
471+
KernelsCache.clear();
472+
454473
return UR_RESULT_SUCCESS;
455474
}
456475

source/adapters/level_zero/context.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,8 @@ struct ur_context_handle_t_ : _ur_object {
175175
std::vector<std::unordered_map<ur_device_handle_t, size_t>>
176176
EventCachesDeviceMap{4};
177177

178+
std::list<ur_kernel_handle_t> KernelsCache;
179+
178180
// Initialize the PI context.
179181
ur_result_t initialize();
180182

@@ -309,6 +311,14 @@ struct ur_context_handle_t_ : _ur_object {
309311
// Get handle to the L0 context
310312
ze_context_handle_t getZeHandle() const;
311313

314+
void deleteCachedObjectsOnDestruction() {
315+
while (!KernelsCache.empty()) {
316+
ur_kernel_handle_t &kernel = KernelsCache.front();
317+
UR_CALL_THROWS(urKernelRelease(kernel));
318+
deleteFromCachedList(kernel, KernelsCache);
319+
}
320+
}
321+
312322
private:
313323
// Get the cache of events for a provided scope and profiling mode.
314324
auto getEventCache(bool HostVisible, bool WithProfiling,

source/adapters/level_zero/kernel.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,16 @@ UR_APIEXPORT ur_result_t UR_APICALL urKernelCreate(
591591
try {
592592
ur_kernel_handle_t_ *UrKernel = new ur_kernel_handle_t_(true, Program);
593593
*RetKernel = reinterpret_cast<ur_kernel_handle_t>(UrKernel);
594+
595+
#ifdef _WIN32
596+
auto &Context = Program->Context;
597+
auto It = std::find(Context->KernelsCache.begin(),
598+
Context->KernelsCache.end(), *RetKernel);
599+
if (It == Context->KernelsCache.end()) {
600+
Context->KernelsCache.push_back(*RetKernel);
601+
}
602+
#endif
603+
594604
} catch (const std::bad_alloc &) {
595605
return UR_RESULT_ERROR_OUT_OF_HOST_MEMORY;
596606
} catch (...) {
@@ -902,10 +912,13 @@ UR_APIEXPORT ur_result_t UR_APICALL urKernelRelease(
902912
return ze2urResult(ZeResult);
903913
}
904914
}
915+
905916
Kernel->ZeKernelMap.clear();
917+
906918
if (IndirectAccessTrackingEnabled) {
907919
UR_CALL(urContextRelease(KernelProgram->Context));
908920
}
921+
909922
// do a release on the program this kernel was part of without delete of the
910923
// program handle
911924
KernelProgram->ur_release_program_resources(false);

0 commit comments

Comments
 (0)