diff --git a/sycl/source/detail/context_impl.cpp b/sycl/source/detail/context_impl.cpp index d738053302e54..74e7a90c2b163 100644 --- a/sycl/source/detail/context_impl.cpp +++ b/sycl/source/detail/context_impl.cpp @@ -131,12 +131,23 @@ context_impl::~context_impl() { DeviceGlobal); DGEntry->removeAssociatedResources(this); } +#ifdef _WIN32 + if (!sycl::detail::GlobalHandler::instance().isUrTearDowned) { + for (auto LibProg : MCachedLibPrograms) { + assert(LibProg.second && "Null program must not be kept in the cache"); + getPlugin()->call(urProgramRelease, LibProg.second); + } + // TODO catch an exception and put it to list of asynchronous exceptions + getPlugin()->call_nocheck(urContextRelease, MContext); + } +#else for (auto LibProg : MCachedLibPrograms) { assert(LibProg.second && "Null program must not be kept in the cache"); getPlugin()->call(urProgramRelease, LibProg.second); } // TODO catch an exception and put it to list of asynchronous exceptions getPlugin()->call_nocheck(urContextRelease, MContext); +#endif } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~context_impl", e); } diff --git a/sycl/source/detail/device_image_impl.hpp b/sycl/source/detail/device_image_impl.hpp index 0786457d3a7c9..d2f9a4027fe4b 100644 --- a/sycl/source/detail/device_image_impl.hpp +++ b/sycl/source/detail/device_image_impl.hpp @@ -311,8 +311,15 @@ class device_image_impl { ~device_image_impl() { try { if (MProgram) { +#ifdef _WIN32 + if (!sycl::detail::GlobalHandler::instance().isUrTearDowned) { + const PluginPtr &Plugin = getSyclObjImpl(MContext)->getPlugin(); + Plugin->call(urProgramRelease, MProgram); + } +#else const PluginPtr &Plugin = getSyclObjImpl(MContext)->getPlugin(); Plugin->call(urProgramRelease, MProgram); +#endif } if (MSpecConstsBuffer) { std::lock_guard Lock{MSpecConstAccessMtx}; diff --git a/sycl/source/detail/global_handler.cpp b/sycl/source/detail/global_handler.cpp index 8376212984d76..d78d2a603c74b 100644 --- a/sycl/source/detail/global_handler.cpp +++ b/sycl/source/detail/global_handler.cpp @@ -303,6 +303,7 @@ void GlobalHandler::drainThreadPool() { // accidentally retain device handles. etc void shutdown_win() { GlobalHandler *&Handler = GlobalHandler::getInstancePtr(); + Handler->isUrTearDowned = true; Handler->unloadPlugins(); } #else diff --git a/sycl/source/detail/global_handler.hpp b/sycl/source/detail/global_handler.hpp index 069fff3dbcdd5..04eaeea9bc592 100644 --- a/sycl/source/detail/global_handler.hpp +++ b/sycl/source/detail/global_handler.hpp @@ -50,6 +50,7 @@ class GlobalHandler { /// as runtime library is loaded (i.e. untill `DllMain` or /// `__attribute__((destructor))` is called). static GlobalHandler &instance(); + bool isUrTearDowned = false; GlobalHandler(const GlobalHandler &) = delete; GlobalHandler(GlobalHandler &&) = delete; diff --git a/sycl/source/detail/kernel_impl.cpp b/sycl/source/detail/kernel_impl.cpp index c458e6b3d47f9..c5bac15e4a5d7 100644 --- a/sycl/source/detail/kernel_impl.cpp +++ b/sycl/source/detail/kernel_impl.cpp @@ -58,8 +58,15 @@ kernel_impl::kernel_impl(ur_kernel_handle_t Kernel, ContextImplPtr ContextImpl, kernel_impl::~kernel_impl() { try { +#ifdef _WIN32 + if (!sycl::detail::GlobalHandler::instance().isUrTearDowned) { + // TODO catch an exception and put it to list of asynchronous exceptions + getPlugin()->call(urKernelRelease, MKernel); + } +#else // TODO catch an exception and put it to list of asynchronous exceptions getPlugin()->call(urKernelRelease, MKernel); +#endif } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~kernel_impl", e); } diff --git a/sycl/source/detail/kernel_program_cache.hpp b/sycl/source/detail/kernel_program_cache.hpp index 7492aa7969477..466f7eeb9f2e0 100644 --- a/sycl/source/detail/kernel_program_cache.hpp +++ b/sycl/source/detail/kernel_program_cache.hpp @@ -102,8 +102,15 @@ class KernelProgramCache { ~ProgramBuildResult() { try { if (Val) { +#ifdef _WIN32 + if (!sycl::detail::GlobalHandler::instance().isUrTearDowned) { + ur_result_t Err = Plugin->call_nocheck(urProgramRelease, Val); + __SYCL_CHECK_UR_CODE_NO_EXC(Err); + } +#else ur_result_t Err = Plugin->call_nocheck(urProgramRelease, Val); __SYCL_CHECK_UR_CODE_NO_EXC(Err); +#endif } } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~ProgramBuildResult", @@ -140,8 +147,15 @@ class KernelProgramCache { ~KernelBuildResult() { try { if (Val.first) { +#ifdef _WIN32 + if (!sycl::detail::GlobalHandler::instance().isUrTearDowned) { + ur_result_t Err = Plugin->call_nocheck(urKernelRelease, Val.first); + __SYCL_CHECK_UR_CODE_NO_EXC(Err); + } +#else ur_result_t Err = Plugin->call_nocheck(urKernelRelease, Val.first); __SYCL_CHECK_UR_CODE_NO_EXC(Err); +#endif } } catch (std::exception &e) { __SYCL_REPORT_EXCEPTION_TO_STREAM("exception in ~KernelBuildResult", e);