Skip to content

Commit ac9e5d9

Browse files
[SYCL] Unload libraries in jit_compiler and kernel_compiler_opencl destructors (#16517)
Fixes memory leaks in jit_compiler and kernel_compiler_opencl classes. Libraries loaded to provide compilation utils have to be released. --------- Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
1 parent 6e0d90e commit ac9e5d9

File tree

3 files changed

+39
-21
lines changed

3 files changed

+39
-21
lines changed

sycl/source/detail/jit_compiler.cpp

+20-9
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,38 @@ namespace sycl {
2323
inline namespace _V1 {
2424
namespace detail {
2525

26+
std::function<void(void *)> jit_compiler::CustomDeleterForLibHandle =
27+
[](void *StoredPtr) {
28+
if (!StoredPtr)
29+
return;
30+
std::ignore = sycl::detail::ur::unloadOsLibrary(StoredPtr);
31+
};
32+
2633
static inline void printPerformanceWarning(const std::string &Message) {
2734
if (detail::SYCLConfig<detail::SYCL_RT_WARNING_LEVEL>::get() > 0) {
2835
std::cerr << "WARNING: " << Message << "\n";
2936
}
3037
}
3138

32-
jit_compiler::jit_compiler() {
39+
jit_compiler::jit_compiler()
40+
: LibraryHandle(nullptr, CustomDeleterForLibHandle) {
3341
auto checkJITLibrary = [this]() -> bool {
3442
#ifdef _WIN32
3543
static const std::string dir = sycl::detail::OSUtil::getCurrentDSODir();
3644
static const std::string JITLibraryName = dir + "\\" + "sycl-jit.dll";
3745
#else
3846
static const std::string JITLibraryName = "libsycl-jit.so";
3947
#endif
40-
41-
void *LibraryPtr = sycl::detail::ur::loadOsLibrary(JITLibraryName);
48+
std::unique_ptr<void, decltype(CustomDeleterForLibHandle)> LibraryPtr(
49+
sycl::detail::ur::loadOsLibrary(JITLibraryName),
50+
CustomDeleterForLibHandle);
4251
if (LibraryPtr == nullptr) {
4352
printPerformanceWarning("Could not find JIT library " + JITLibraryName);
4453
return false;
4554
}
4655

4756
this->AddToConfigHandle = reinterpret_cast<AddToConfigFuncT>(
48-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr,
57+
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(),
4958
"addToJITConfiguration"));
5059
if (!this->AddToConfigHandle) {
5160
printPerformanceWarning(
@@ -54,7 +63,7 @@ jit_compiler::jit_compiler() {
5463
}
5564

5665
this->ResetConfigHandle = reinterpret_cast<ResetConfigFuncT>(
57-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr,
66+
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(),
5867
"resetJITConfiguration"));
5968
if (!this->ResetConfigHandle) {
6069
printPerformanceWarning(
@@ -63,7 +72,8 @@ jit_compiler::jit_compiler() {
6372
}
6473

6574
this->FuseKernelsHandle = reinterpret_cast<FuseKernelsFuncT>(
66-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, "fuseKernels"));
75+
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(),
76+
"fuseKernels"));
6777
if (!this->FuseKernelsHandle) {
6878
printPerformanceWarning(
6979
"Cannot resolve JIT library function entry point");
@@ -73,21 +83,22 @@ jit_compiler::jit_compiler() {
7383
this->MaterializeSpecConstHandle =
7484
reinterpret_cast<MaterializeSpecConstFuncT>(
7585
sycl::detail::ur::getOsLibraryFuncAddress(
76-
LibraryPtr, "materializeSpecConstants"));
86+
LibraryPtr.get(), "materializeSpecConstants"));
7787
if (!this->MaterializeSpecConstHandle) {
7888
printPerformanceWarning(
7989
"Cannot resolve JIT library function entry point");
8090
return false;
8191
}
8292

8393
this->CompileSYCLHandle = reinterpret_cast<CompileSYCLFuncT>(
84-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, "compileSYCL"));
94+
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr.get(),
95+
"compileSYCL"));
8596
if (!this->CompileSYCLHandle) {
8697
printPerformanceWarning(
8798
"Cannot resolve JIT library function entry point");
8899
return false;
89100
}
90-
101+
LibraryHandle = std::move(LibraryPtr);
91102
return true;
92103
};
93104
Available = checkJITLibrary();

sycl/source/detail/jit_compiler.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <KernelFusion.h>
1717
#endif // SYCL_EXT_JIT_ENABLE
1818

19+
#include <functional>
1920
#include <unordered_map>
2021

2122
namespace jit_compiler {
@@ -80,7 +81,7 @@ class jit_compiler {
8081
const ::jit_compiler::SYCLKernelAttribute &Attr) const;
8182

8283
// Indicate availability of the JIT compiler
83-
bool Available;
84+
bool Available = false;
8485

8586
// Manages the lifetime of the UR structs for device binaries.
8687
std::vector<DeviceBinariesCollection> JITDeviceBinaries;
@@ -98,6 +99,8 @@ class jit_compiler {
9899
CompileSYCLFuncT CompileSYCLHandle = nullptr;
99100
ResetConfigFuncT ResetConfigHandle = nullptr;
100101
AddToConfigFuncT AddToConfigHandle = nullptr;
102+
static std::function<void(void *)> CustomDeleterForLibHandle;
103+
std::unique_ptr<void, decltype(CustomDeleterForLibHandle)> LibraryHandle;
101104
#endif // SYCL_EXT_JIT_ENABLE
102105
};
103106

sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp

+15-11
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
#include "../online_compiler/ocloc_api.h"
1515
#include "../split_string.hpp"
1616

17-
#include <cstring> // strlen
18-
#include <numeric> // for std::accumulate
17+
#include <cstring> // strlen
18+
#include <functional> // for std::function
19+
#include <numeric> // for std::accumulate
1920
#include <regex>
2021
#include <sstream>
2122

@@ -56,16 +57,21 @@ void checkOclocLibrary(void *OclocLibrary) {
5657
}
5758
}
5859

59-
static void *OclocLibrary = nullptr;
60+
static std::unique_ptr<void, std::function<void(void *)>>
61+
OclocLibrary(nullptr, [](void *StoredPtr) {
62+
if (!StoredPtr)
63+
return;
64+
std::ignore = sycl::detail::ur::unloadOsLibrary(StoredPtr);
65+
});
6066

6167
// load the ocloc shared library, check it.
62-
void *loadOclocLibrary() {
68+
void loadOclocLibrary() {
6369
#ifdef __SYCL_RT_OS_WINDOWS
6470
static const std::string OclocLibraryName = "ocloc64.dll";
6571
#else
6672
static const std::string OclocLibraryName = "libocloc.so";
6773
#endif
68-
void *tempPtr = OclocLibrary;
74+
void *tempPtr = OclocLibrary.get();
6975
if (tempPtr == nullptr) {
7076
tempPtr = sycl::detail::ur::loadOsLibrary(OclocLibraryName);
7177

@@ -75,10 +81,8 @@ void *loadOclocLibrary() {
7581

7682
checkOclocLibrary(tempPtr);
7783

78-
OclocLibrary = tempPtr;
84+
OclocLibrary.reset(tempPtr);
7985
}
80-
81-
return OclocLibrary;
8286
}
8387

8488
bool OpenCLC_Compilation_Available() {
@@ -103,13 +107,13 @@ void SetupLibrary(voidPtr &oclocInvokeHandle, voidPtr &oclocFreeOutputHandle,
103107
if (OclocLibrary == nullptr)
104108
loadOclocLibrary();
105109

106-
oclocInvokeHandle =
107-
sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke");
110+
oclocInvokeHandle = sycl::detail::ur::getOsLibraryFuncAddress(
111+
OclocLibrary.get(), "oclocInvoke");
108112
if (!oclocInvokeHandle)
109113
throw sycl::exception(the_errc, "Cannot load oclocInvoke() function");
110114

111115
oclocFreeOutputHandle = sycl::detail::ur::getOsLibraryFuncAddress(
112-
OclocLibrary, "oclocFreeOutput");
116+
OclocLibrary.get(), "oclocFreeOutput");
113117
if (!oclocFreeOutputHandle)
114118
throw sycl::exception(the_errc, "Cannot load oclocFreeOutput() function");
115119
}

0 commit comments

Comments
 (0)