Skip to content

Commit 889f83b

Browse files
committed
[SYCL][NFC] Detach library loading helpers from UR
Functions to dynamically load a library and query a symbol out of it should not be attached to UR, because they are used for other libraries as well. Moved them from `detail::ur` into `detail` namespace, outlined into a seprate header and removed declarations from public SYCL headers.
1 parent ebb3b4a commit 889f83b

File tree

9 files changed

+114
-57
lines changed

9 files changed

+114
-57
lines changed

sycl/include/sycl/detail/ur.hpp

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,6 @@ template <sycl::backend BE>
6464
__SYCL_EXPORT void *getPluginOpaqueData(void *opaquedata_arg);
6565

6666
namespace ur {
67-
// Function to load a shared library
68-
// Implementation is OS dependent
69-
void *loadOsLibrary(const std::string &Library);
70-
71-
// Function to unload a shared library
72-
// Implementation is OS dependent (see posix-ur.cpp and windows-ur.cpp)
73-
int unloadOsLibrary(void *Library);
74-
75-
// Function to get Address of a symbol defined in the shared
76-
// library, implementation is OS dependent.
77-
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName);
78-
7967
// Performs UR one-time initialization.
8068
std::vector<PluginPtr> &
8169
initializeUr(ur_loader_config_handle_t LoaderConfig = nullptr);

sycl/source/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,8 @@ set(SYCL_COMMON_SOURCES
296296
"spirv_ops.cpp"
297297
"virtual_mem.cpp"
298298
"$<$<PLATFORM_ID:Windows>:detail/windows_ur.cpp>"
299-
"$<$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Darwin>>:detail/posix_ur.cpp>"
299+
"$<$<PLATFORM_ID:Windows>:detail/windows_dlopen.cpp>"
300+
"$<$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Darwin>>:detail/posix_dlopen.cpp>"
300301
)
301302

302303
set(SYCL_NON_PREVIEW_SOURCES "${SYCL_COMMON_SOURCES}"

sycl/source/detail/dlopen_utils.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//===------ dlopen_utils - Helpers for libraries loading -------*- C++ -*--===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <string>
12+
13+
namespace sycl {
14+
inline namespace _V1 {
15+
namespace detail {
16+
17+
// Function to load a shared library
18+
// Implementation is OS dependent
19+
void *loadOsLibrary(const std::string &Library);
20+
21+
// Function to unload a shared library
22+
// Implementation is OS dependent (see posix-pi.cpp and windows-pi.cpp)
23+
int unloadOsLibrary(void *Library);
24+
25+
// Function to get Address of a symbol defined in the shared
26+
// library, implementation is OS dependent.
27+
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName);
28+
29+
}}}

sycl/source/detail/jit_compiler.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <detail/device_image_impl.hpp>
1212
#include <detail/jit_compiler.hpp>
1313
#include <detail/kernel_bundle_impl.hpp>
14+
#include <detail/dlopen_utils.hpp>
1415
#include <detail/kernel_impl.hpp>
1516
#include <detail/queue_impl.hpp>
1617
#include <detail/sycl_mem_obj_t.hpp>
@@ -32,14 +33,14 @@ jit_compiler::jit_compiler() {
3233
auto checkJITLibrary = [this]() -> bool {
3334
static const std::string JITLibraryName = "libsycl-fusion.so";
3435

35-
void *LibraryPtr = sycl::detail::ur::loadOsLibrary(JITLibraryName);
36+
void *LibraryPtr = sycl::detail::loadOsLibrary(JITLibraryName);
3637
if (LibraryPtr == nullptr) {
3738
printPerformanceWarning("Could not find JIT library " + JITLibraryName);
3839
return false;
3940
}
4041

4142
this->AddToConfigHandle = reinterpret_cast<AddToConfigFuncT>(
42-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr,
43+
sycl::detail::getOsLibraryFuncAddress(LibraryPtr,
4344
"addToJITConfiguration"));
4445
if (!this->AddToConfigHandle) {
4546
printPerformanceWarning(
@@ -48,7 +49,7 @@ jit_compiler::jit_compiler() {
4849
}
4950

5051
this->ResetConfigHandle = reinterpret_cast<ResetConfigFuncT>(
51-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr,
52+
sycl::detail::getOsLibraryFuncAddress(LibraryPtr,
5253
"resetJITConfiguration"));
5354
if (!this->ResetConfigHandle) {
5455
printPerformanceWarning(
@@ -57,7 +58,7 @@ jit_compiler::jit_compiler() {
5758
}
5859

5960
this->FuseKernelsHandle = reinterpret_cast<FuseKernelsFuncT>(
60-
sycl::detail::ur::getOsLibraryFuncAddress(LibraryPtr, "fuseKernels"));
61+
sycl::detail::getOsLibraryFuncAddress(LibraryPtr, "fuseKernels"));
6162
if (!this->FuseKernelsHandle) {
6263
printPerformanceWarning(
6364
"Cannot resolve JIT library function entry point");
@@ -66,7 +67,7 @@ jit_compiler::jit_compiler() {
6667

6768
this->MaterializeSpecConstHandle =
6869
reinterpret_cast<MaterializeSpecConstFuncT>(
69-
sycl::detail::ur::getOsLibraryFuncAddress(
70+
sycl::detail::getOsLibraryFuncAddress(
7071
LibraryPtr, "materializeSpecConstants"));
7172
if (!this->MaterializeSpecConstHandle) {
7273
printPerformanceWarning(

sycl/source/detail/kernel_compiler/kernel_compiler_opencl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9-
#include <sycl/detail/ur.hpp> // getOsLibraryFuncAddress
9+
#include <detail/dlopen_utils.hpp>
1010
#include <sycl/exception.hpp> // make_error_code
1111

1212
#include "kernel_compiler_opencl.hpp"
@@ -26,7 +26,7 @@ namespace detail {
2626
// ensures the OclocLibrary has the right version, etc.
2727
void checkOclocLibrary(void *OclocLibrary) {
2828
void *OclocVersionHandle =
29-
sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocVersion");
29+
sycl::detail::getOsLibraryFuncAddress(OclocLibrary, "oclocVersion");
3030
// The initial versions of ocloc library did not have the oclocVersion()
3131
// function. Those versions had the same API as the first version of ocloc
3232
// library having that oclocVersion() function.
@@ -66,7 +66,7 @@ void *loadOclocLibrary() {
6666
#endif
6767
void *tempPtr = OclocLibrary;
6868
if (tempPtr == nullptr) {
69-
tempPtr = sycl::detail::ur::loadOsLibrary(OclocLibraryName);
69+
tempPtr = sycl::detail::loadOsLibrary(OclocLibraryName);
7070

7171
if (tempPtr == nullptr)
7272
throw sycl::exception(make_error_code(errc::build),
@@ -103,11 +103,11 @@ void SetupLibrary(voidPtr &oclocInvokeHandle, voidPtr &oclocFreeOutputHandle,
103103
loadOclocLibrary();
104104

105105
oclocInvokeHandle =
106-
sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke");
106+
sycl::detail::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke");
107107
if (!oclocInvokeHandle)
108108
throw sycl::exception(the_errc, "Cannot load oclocInvoke() function");
109109

110-
oclocFreeOutputHandle = sycl::detail::ur::getOsLibraryFuncAddress(
110+
oclocFreeOutputHandle = sycl::detail::getOsLibraryFuncAddress(
111111
OclocLibrary, "oclocFreeOutput");
112112
if (!oclocFreeOutputHandle)
113113
throw sycl::exception(the_errc, "Cannot load oclocFreeOutput() function");

sycl/source/detail/online_compiler/online_compiler.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <sycl/detail/os_util.hpp>
1010
#include <sycl/detail/ur.hpp>
1111
#include <sycl/ext/intel/experimental/online_compiler.hpp>
12+
#include <detail/dlopen_utils.hpp>
1213

1314
#include <cstring>
1415

@@ -94,12 +95,12 @@ compileToSPIRV(const std::string &Source, sycl::info::device_type DeviceType,
9495
#else
9596
static const std::string OclocLibraryName = "libocloc.so";
9697
#endif
97-
void *OclocLibrary = sycl::detail::ur::loadOsLibrary(OclocLibraryName);
98+
void *OclocLibrary = sycl::detail::loadOsLibrary(OclocLibraryName);
9899
if (!OclocLibrary)
99100
throw online_compile_error("Cannot load ocloc library: " +
100101
OclocLibraryName);
101102
void *OclocVersionHandle =
102-
sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocVersion");
103+
sycl::detail::getOsLibraryFuncAddress(OclocLibrary, "oclocVersion");
103104
// The initial versions of ocloc library did not have the oclocVersion()
104105
// function. Those versions had the same API as the first version of ocloc
105106
// library having that oclocVersion() function.
@@ -126,10 +127,10 @@ compileToSPIRV(const std::string &Source, sycl::info::device_type DeviceType,
126127
".N), where (N >= " + std::to_string(CurrentVersionMinor) + ").");
127128

128129
CompileToSPIRVHandle =
129-
sycl::detail::ur::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke");
130+
sycl::detail::getOsLibraryFuncAddress(OclocLibrary, "oclocInvoke");
130131
if (!CompileToSPIRVHandle)
131132
throw online_compile_error("Cannot load oclocInvoke() function");
132-
FreeSPIRVOutputsHandle = sycl::detail::ur::getOsLibraryFuncAddress(
133+
FreeSPIRVOutputsHandle = sycl::detail::getOsLibraryFuncAddress(
133134
OclocLibrary, "oclocFreeOutput");
134135
if (!FreeSPIRVOutputsHandle)
135136
throw online_compile_error("Cannot load oclocFreeOutput() function");

sycl/source/detail/posix_ur.cpp renamed to sycl/source/detail/posix_dlopen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include <detail/dlopen_utils.hpp>
910
#include <sycl/detail/defines_elementary.hpp>
1011
#include <sycl/detail/iostream_proxy.hpp>
1112
#include <sycl/detail/ur.hpp>
@@ -15,7 +16,7 @@
1516

1617
namespace sycl {
1718
inline namespace _V1 {
18-
namespace detail::ur {
19+
namespace detail {
1920

2021
void *loadOsLibrary(const std::string &LibraryPath) {
2122
// TODO: Check if the option RTLD_NOW is correct. Explore using
@@ -35,6 +36,6 @@ void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName) {
3536
return dlsym(Library, FunctionName.c_str());
3637
}
3738

38-
} // namespace detail::ur
39+
} // namespace detail
3940
} // namespace _V1
4041
} // namespace sycl

sycl/source/detail/windows_dlopen.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//==---------------- windows_dlopen.cpp ------------------------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "dlopen_utils.hpp"
10+
11+
#include <cassert>
12+
#include <string>
13+
#include <windows.h>
14+
15+
namespace sycl {
16+
inline namespace _V1 {
17+
namespace detail {
18+
19+
void *loadOsLibrary(const std::string &LibraryPath) {
20+
// Tells the system to not display the critical-error-handler message box.
21+
// Instead, the system sends the error to the calling process.
22+
// This is crucial for graceful handling of shared libs that can't be
23+
// loaded, e.g. due to missing native run-times.
24+
25+
UINT SavedMode = SetErrorMode(SEM_FAILCRITICALERRORS);
26+
// Exclude current directory from DLL search path
27+
if (!SetDllDirectoryA("")) {
28+
assert(false && "Failed to update DLL search path");
29+
}
30+
31+
auto Result = (void *)LoadLibraryExA(LibraryPath.c_str(), NULL, NULL);
32+
(void)SetErrorMode(SavedMode);
33+
if (!SetDllDirectoryA(nullptr)) {
34+
assert(false && "Failed to restore DLL search path");
35+
}
36+
37+
return Result;
38+
}
39+
40+
int unloadOsLibrary(void *Library) {
41+
return (int)FreeLibrary((HMODULE)Library);
42+
}
43+
44+
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName) {
45+
return reinterpret_cast<void *>(
46+
GetProcAddress((HMODULE)Library, FunctionName.c_str()));
47+
}
48+
49+
} // namespace detail
50+
} // namespace _V1
51+
} // namespace sycl

sycl/source/detail/windows_ur.cpp

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,52 +6,38 @@
66
//
77
//===----------------------------------------------------------------------===//
88

9+
#include <detail/dlopen_utils.hpp>
10+
911
#include <sycl/backend.hpp>
1012
#include <sycl/detail/defines.hpp>
1113

1214
#include <cassert>
1315
#include <string>
1416
#include <windows.h>
15-
#include <winreg.h>
1617

1718
#include "detail/windows_os_utils.hpp"
1819
#include "ur_win_proxy_loader.hpp"
1920

2021
namespace sycl {
2122
inline namespace _V1 {
22-
namespace detail {
23-
namespace ur {
24-
25-
void *loadOsLibrary(const std::string &LibraryPath) {
26-
// Tells the system to not display the critical-error-handler message box.
27-
// Instead, the system sends the error to the calling process.
28-
// This is crucial for graceful handling of shared libs that can't be
29-
// loaded, e.g. due to missing native run-times.
30-
31-
UINT SavedMode = SetErrorMode(SEM_FAILCRITICALERRORS);
32-
// Exclude current directory from DLL search path
33-
if (!SetDllDirectoryA("")) {
34-
assert(false && "Failed to update DLL search path");
35-
}
23+
namespace detail::ur {
3624

37-
auto Result = (void *)LoadLibraryExA(LibraryPath.c_str(), NULL, NULL);
38-
(void)SetErrorMode(SavedMode);
39-
if (!SetDllDirectoryA(nullptr)) {
40-
assert(false && "Failed to restore DLL search path");
41-
}
25+
void *loadOsPluginLibrary(const std::string &PluginPath) {
26+
// We fetch the preloaded plugin from the pi_win_proxy_loader.
27+
// The proxy_loader handles any required error suppression.
28+
auto Result = getPreloadedPlugin(PluginPath);
4229

4330
return Result;
4431
}
4532

46-
int unloadOsLibrary(void *Library) {
33+
int unloadOsPluginLibrary(void *Library) {
34+
// The mock plugin does not have an associated library, so we allow nullptr
35+
// here to avoid it trying to free a non-existent library.
36+
if (!Library)
37+
return 1;
4738
return (int)FreeLibrary((HMODULE)Library);
4839
}
4940

50-
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName) {
51-
return reinterpret_cast<void *>(
52-
GetProcAddress((HMODULE)Library, FunctionName.c_str()));
53-
}
54-
5541
static std::filesystem::path getCurrentDSODirPath() {
5642
wchar_t Path[MAX_PATH];
5743
auto Handle =
@@ -70,7 +56,6 @@ static std::filesystem::path getCurrentDSODirPath() {
7056
return std::filesystem::path(Path);
7157
}
7258

73-
} // namespace ur
74-
} // namespace detail
59+
} // namespace detail::ur
7560
} // namespace _V1
7661
} // namespace sycl

0 commit comments

Comments
 (0)