|
12 | 12 |
|
13 | 13 | #include <sycl/detail/export.hpp> // for __SYCL_EXPORT
|
14 | 14 |
|
| 15 | +#include <array> |
15 | 16 | #include <cstdlib> // for size_t
|
16 | 17 | #include <functional>
|
17 | 18 | #include <string> // for string
|
@@ -106,27 +107,38 @@ void fileTreeWalk(const std::string Path,
|
106 | 107 | std::function<void(const std::string)> Func,
|
107 | 108 | bool ignoreErrors = false);
|
108 | 109 |
|
109 |
| -void *dynLookup(const char *WinName, const char *LinName, const char *FunName); |
110 |
| - |
111 | 110 | // Look up a function name that was dynamically linked
|
112 |
| -// This is used by the runtime where it needs to manipulate native handles (e.g. |
113 |
| -// retaining OpenCL handles). On Windows, the symbol name is looked up in |
114 |
| -// `WinName`. In Linux, it uses `LinName`. |
| 111 | +// This is used by the runtime where it needs to manipulate native handles |
| 112 | +// (e.g. retaining OpenCL handles). |
115 | 113 | //
|
116 | 114 | // The library must already have been loaded (perhaps by UR), otherwise this
|
117 | 115 | // function throws a SYCL runtime exception.
|
| 116 | +void *dynLookup(const char *const *LibNames, size_t LibNameSizes, |
| 117 | + const char *FunName); |
| 118 | + |
118 | 119 | template <typename fn>
|
119 |
| -fn *dynLookupFunction(const char *WinName, const char *LinName, |
| 120 | +fn *dynLookupFunction(const char *const *LibNames, size_t LibNameSize, |
120 | 121 | const char *FunName) {
|
121 |
| - return reinterpret_cast<fn *>(dynLookup(WinName, LinName, FunName)); |
| 122 | + return reinterpret_cast<fn *>(dynLookup(LibNames, LibNameSize, FunName)); |
122 | 123 | }
|
123 |
| -// On Linux, the name of OpenCL that was used to link against may be either |
124 |
| -// `OpenCL.so`, `OpenCL.so.1` or possibly anything else. |
125 |
| -// `libur_adapter_opencl.so` is a more stable name, since it is hardcoded into |
126 |
| -// the loader. |
| 124 | + |
| 125 | +// On Linux, first try to load from libur_adapter_opencl.so, then |
| 126 | +// libur_adapter_opencl.so.0 if the first is not found. libur_adapter_opencl.so |
| 127 | +// and libur_adapter_opencl.so.0 might be different libraries if they are not |
| 128 | +// symlinked, which is the case with PyPi compiler distribution package. |
| 129 | +// We can't load libur_adapter_opencl.so.0 always as the first choice because |
| 130 | +// that would break SYCL unittests, which rely on mocking libur_adapter_opencl. |
| 131 | +#ifdef __SYCL_RT_OS_WINDOWS |
| 132 | +constexpr std::array<const char *, 1> OCLLibNames = {"OpenCL"}; |
| 133 | +#else |
| 134 | +constexpr std::array<const char *, 2> OCLLibNames = { |
| 135 | + "libur_adapter_opencl.so", "libur_adapter_opencl.so.0"}; |
| 136 | +#endif |
| 137 | + |
127 | 138 | #define __SYCL_OCL_CALL(FN, ...) \
|
128 | 139 | (sycl::_V1::detail::dynLookupFunction<decltype(FN)>( \
|
129 |
| - "OpenCL", "libur_adapter_opencl.so", #FN)(__VA_ARGS__)) |
| 140 | + sycl::detail::OCLLibNames.data(), sycl::detail::OCLLibNames.size(), \ |
| 141 | + #FN)(__VA_ARGS__)) |
130 | 142 |
|
131 | 143 | } // namespace detail
|
132 | 144 | } // namespace _V1
|
|
0 commit comments