diff --git a/sycl/source/detail/jit_compiler.cpp b/sycl/source/detail/jit_compiler.cpp index daec9af9ff6dc..79e3a767bb562 100644 --- a/sycl/source/detail/jit_compiler.cpp +++ b/sycl/source/detail/jit_compiler.cpp @@ -23,13 +23,21 @@ namespace sycl { inline namespace _V1 { namespace detail { +std::function jit_compiler::CustomDeleterForLibHandle = + [](void *StoredPtr) { + if (!StoredPtr) + return; + std::ignore = sycl::detail::ur::unloadOsLibrary(StoredPtr); + }; + static inline void printPerformanceWarning(const std::string &Message) { if (detail::SYCLConfig::get() > 0) { std::cerr << "WARNING: " << Message << "\n"; } } -jit_compiler::jit_compiler() { +jit_compiler::jit_compiler() + : LibraryHandle(nullptr, CustomDeleterForLibHandle) { auto checkJITLibrary = [this]() -> bool { #ifdef _WIN32 static const std::string dir = sycl::detail::OSUtil::getCurrentDSODir(); @@ -37,15 +45,16 @@ jit_compiler::jit_compiler() { #else static const std::string JITLibraryName = "libsycl-jit.so"; #endif - - void *LibraryPtr = sycl::detail::ur::loadOsLibrary(JITLibraryName); + std::unique_ptr LibraryPtr( + sycl::detail::ur::loadOsLibrary(JITLibraryName), + CustomDeleterForLibHandle); if (LibraryPtr == nullptr) { printPerformanceWarning("Could not find JIT library " + JITLibraryName); return false; } this->AddToConfigHandle = reinterpret_cast( - sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, + sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(), "addToJITConfiguration")); if (!this->AddToConfigHandle) { printPerformanceWarning( @@ -54,7 +63,7 @@ jit_compiler::jit_compiler() { } this->ResetConfigHandle = reinterpret_cast( - sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, + sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(), "resetJITConfiguration")); if (!this->ResetConfigHandle) { printPerformanceWarning( @@ -63,7 +72,8 @@ jit_compiler::jit_compiler() { } this->FuseKernelsHandle = reinterpret_cast( - sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, "fuseKernels")); + sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(), + "fuseKernels")); if (!this->FuseKernelsHandle) { printPerformanceWarning( "Cannot resolve JIT library function entry point"); @@ -73,7 +83,7 @@ jit_compiler::jit_compiler() { this->MaterializeSpecConstHandle = reinterpret_cast( sycl::detail::ur::getOsLibraryFuncAddress( - LibraryPtr, "materializeSpecConstants")); + LibraryPtr.get(), "materializeSpecConstants")); if (!this->MaterializeSpecConstHandle) { printPerformanceWarning( "Cannot resolve JIT library function entry point"); @@ -81,13 +91,14 @@ jit_compiler::jit_compiler() { } this->CompileSYCLHandle = reinterpret_cast( - sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, "compileSYCL")); + sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(), + "compileSYCL")); if (!this->CompileSYCLHandle) { printPerformanceWarning( "Cannot resolve JIT library function entry point"); return false; } - + LibraryHandle = std::move(LibraryPtr); return true; }; Available = checkJITLibrary(); diff --git a/sycl/source/detail/jit_compiler.hpp b/sycl/source/detail/jit_compiler.hpp index b673e4d37b8fa..cc6e4e50bec5e 100644 --- a/sycl/source/detail/jit_compiler.hpp +++ b/sycl/source/detail/jit_compiler.hpp @@ -16,6 +16,7 @@ #include #endif // SYCL_EXT_JIT_ENABLE +#include #include namespace jit_compiler { @@ -80,7 +81,7 @@ class jit_compiler { const ::jit_compiler::SYCLKernelAttribute &Attr) const; // Indicate availability of the JIT compiler - bool Available; + bool Available = false; // Manages the lifetime of the UR structs for device binaries. std::vector JITDeviceBinaries; @@ -98,6 +99,8 @@ class jit_compiler { CompileSYCLFuncT CompileSYCLHandle = nullptr; ResetConfigFuncT ResetConfigHandle = nullptr; AddToConfigFuncT AddToConfigHandle = nullptr; + static std::function CustomDeleterForLibHandle; + std::unique_ptr LibraryHandle; #endif // SYCL_EXT_JIT_ENABLE }; diff --git a/sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp b/sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp index 10a65d05dec1f..5452bf40795dd 100644 --- a/sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp +++ b/sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp @@ -14,8 +14,9 @@ #include "../online_compiler/ocloc_api.h" #include "../split_string.hpp" -#include // strlen -#include // for std::accumulate +#include // strlen +#include // for std::function +#include // for std::accumulate #include #include @@ -56,16 +57,21 @@ void checkOclocLibrary(void *OclocLibrary) { } } -static void *OclocLibrary = nullptr; +static std::unique_ptr> + OclocLibrary(nullptr, [](void *StoredPtr) { + if (!StoredPtr) + return; + std::ignore = sycl::detail::ur::unloadOsLibrary(StoredPtr); + }); // load the ocloc shared library, check it. -void *loadOclocLibrary() { +void loadOclocLibrary() { #ifdef __SYCL_RT_OS_WINDOWS static const std::string OclocLibraryName = "ocloc64.dll"; #else static const std::string OclocLibraryName = "libocloc.so"; #endif - void *tempPtr = OclocLibrary; + void *tempPtr = OclocLibrary.get(); if (tempPtr == nullptr) { tempPtr = sycl::detail::ur::loadOsLibrary(OclocLibraryName); @@ -75,10 +81,8 @@ void *loadOclocLibrary() { checkOclocLibrary(tempPtr); - OclocLibrary = tempPtr; + OclocLibrary.reset(tempPtr); } - - return OclocLibrary; } bool OpenCLC_Compilation_Available() { @@ -103,13 +107,13 @@ void SetupLibrary(voidPtr &oclocInvokeHandle, voidPtr &oclocFreeOutputHandle, if (OclocLibrary == nullptr) loadOclocLibrary(); - oclocInvokeHandle = - sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke"); + oclocInvokeHandle = sycl::detail::ur::getOsLibraryFuncAddress( + OclocLibrary.get(), "oclocInvoke"); if (!oclocInvokeHandle) throw sycl::exception(the_errc, "Cannot load oclocInvoke() function"); oclocFreeOutputHandle = sycl::detail::ur::getOsLibraryFuncAddress( - OclocLibrary, "oclocFreeOutput"); + OclocLibrary.get(), "oclocFreeOutput"); if (!oclocFreeOutputHandle) throw sycl::exception(the_errc, "Cannot load oclocFreeOutput() function"); }