Skip to content

Commit 67c035f

Browse files
committed
[SYCL] Plugin Interface And Creation of OpenCL Plugin.
- created a plugin as a shared plugin: lib/libpi_opencl.so. Moved the sources to new location plugins/opencl. - removed the dependency on pi.cpp by pi_opencl.cpp - added the preliminary plugin recognition mechanism and loading the plugin as a shared object using dlopen/dlsym etc. Signed-off-by: Garima Gupta <garima.gupta@intel.com>
1 parent 918b285 commit 67c035f

File tree

10 files changed

+657
-568
lines changed

10 files changed

+657
-568
lines changed

sycl/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ add_subdirectory(source)
149149
# SYCL toolchain builds all components: compiler, libraries, headers, etc.
150150
add_custom_target( sycl-toolchain
151151
DEPENDS ${SYCL_RT_LIBS}
152+
pi_opencl
152153
clang
153154
clang-offload-wrapper
154155
clang-offload-bundler
@@ -172,6 +173,7 @@ option(SYCL_INCLUDE_TESTS
172173
"Generate build targets for the SYCL unit tests."
173174
${LLVM_INCLUDE_TESTS})
174175

176+
add_subdirectory( plugins )
175177
add_subdirectory(tools)
176178

177179
if(SYCL_INCLUDE_TESTS)

sycl/include/CL/sycl/detail/pi.hpp

Lines changed: 141 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -13,169 +13,176 @@
1313
#include <CL/sycl/detail/common.hpp>
1414
#include <CL/sycl/detail/os_util.hpp>
1515
#include <CL/sycl/detail/pi.h>
16+
#include <cassert>
17+
#include <string>
18+
19+
// Function to load the shared library
20+
// Implementation is OS dependent.
21+
void *loadOsLibrary(const std::string &library);
22+
23+
// Function to get Address of a symbol defined in the shared
24+
// library, Implementation is OS dependent.
25+
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName);
1626

1727
namespace cl {
1828
namespace sycl {
1929
namespace detail {
2030
namespace pi {
21-
// For selection of SYCL RT back-end, now manually through the "SYCL_BE"
22-
// environment variable.
23-
//
24-
enum Backend {
25-
SYCL_BE_PI_OPENCL,
26-
SYCL_BE_PI_OTHER
27-
};
28-
29-
// Check for manually selected BE at run-time.
30-
bool useBackend(Backend Backend);
31-
32-
using PiResult = ::pi_result;
33-
using PiPlatform = ::pi_platform;
34-
using PiDevice = ::pi_device;
35-
using PiDeviceType = ::pi_device_type;
36-
using PiDeviceInfo = ::pi_device_info;
37-
using PiDeviceBinaryType = ::pi_device_binary_type;
38-
using PiContext = ::pi_context;
39-
using PiProgram = ::pi_program;
40-
using PiKernel = ::pi_kernel;
41-
using PiQueue = ::pi_queue;
42-
using PiQueueProperties = ::pi_queue_properties;
43-
using PiMem = ::pi_mem;
44-
using PiMemFlags = ::pi_mem_flags;
45-
using PiEvent = ::pi_event;
46-
using PiSampler = ::pi_sampler;
47-
using PiSamplerInfo = ::pi_sampler_info;
48-
using PiSamplerProperties = ::pi_sampler_properties;
49-
using PiSamplerAddressingMode = ::pi_sampler_addressing_mode;
50-
using PiSamplerFilterMode = ::pi_sampler_filter_mode;
51-
using PiMemImageFormat = ::pi_image_format;
52-
using PiMemImageDesc = ::pi_image_desc;
53-
using PiMemImageInfo = ::pi_image_info;
54-
using PiMemObjectType = ::pi_mem_type;
55-
using PiMemImageChannelOrder = ::pi_image_channel_order;
56-
using PiMemImageChannelType = ::pi_image_channel_type;
57-
58-
// Get a string representing a _pi_platform_info enum
59-
std::string platformInfoToString(pi_platform_info info);
60-
61-
// Report error and no return (keeps compiler happy about no return statements).
62-
[[noreturn]] void die(const char *Message);
63-
void assertion(bool Condition, const char *Message = nullptr);
64-
65-
// Want all the needed casts be explicit, do not define conversion operators.
66-
template<class To, class From>
67-
To cast(From value);
68-
69-
// Forward declarations of the PI dispatch entries.
31+
// For selection of SYCL RT back-end, now manually through the "SYCL_BE"
32+
// environment variable.
33+
//
34+
enum Backend { SYCL_BE_PI_OPENCL, SYCL_BE_PI_OTHER };
35+
36+
#ifdef SYCL_RT_OS_WINDOWS
37+
#define PLUGIN_NAME "pi_opencl.dll"
38+
#else
39+
#define PLUGIN_NAME "libpi_opencl.so"
40+
#endif
41+
42+
// Check for manually selected BE at run-time.
43+
bool useBackend(Backend Backend);
44+
45+
using PiResult = ::pi_result;
46+
using PiPlatform = ::pi_platform;
47+
using PiDevice = ::pi_device;
48+
using PiDeviceType = ::pi_device_type;
49+
using PiDeviceInfo = ::pi_device_info;
50+
using PiDeviceBinaryType = ::pi_device_binary_type;
51+
using PiContext = ::pi_context;
52+
using PiProgram = ::pi_program;
53+
using PiKernel = ::pi_kernel;
54+
using PiQueue = ::pi_queue;
55+
using PiQueueProperties = ::pi_queue_properties;
56+
using PiMem = ::pi_mem;
57+
using PiMemFlags = ::pi_mem_flags;
58+
using PiEvent = ::pi_event;
59+
using PiSampler = ::pi_sampler;
60+
using PiSamplerInfo = ::pi_sampler_info;
61+
using PiSamplerProperties = ::pi_sampler_properties;
62+
using PiSamplerAddressingMode = ::pi_sampler_addressing_mode;
63+
using PiSamplerFilterMode = ::pi_sampler_filter_mode;
64+
using PiMemImageFormat = ::pi_image_format;
65+
using PiMemImageDesc = ::pi_image_desc;
66+
using PiMemImageInfo = ::pi_image_info;
67+
using PiMemObjectType = ::pi_mem_type;
68+
using PiMemImageChannelOrder = ::pi_image_channel_order;
69+
using PiMemImageChannelType = ::pi_image_channel_type;
70+
71+
// Get a string representing a _pi_platform_info enum
72+
std::string platformInfoToString(pi_platform_info info);
73+
74+
// Report error and no return (keeps compiler happy about no return statements).
75+
[[noreturn]] void die(const char *Message);
76+
void assertion(bool Condition, const char *Message = nullptr);
77+
78+
// Want all the needed casts be explicit, do not define conversion operators.
79+
template <class To, class From> To cast(From value);
80+
81+
// Forward declarations of the PI dispatch entries.
7082
#define _PI_API(api) __SYCL_EXPORTED extern decltype(::api) *(api);
7183
#include <CL/sycl/detail/pi.def>
7284

73-
// Performs PI one-time initialization.
74-
void initialize();
75-
76-
// The PiCall helper structure facilitates performing a call to PI.
77-
// It holds utilities to do the tracing and to check the returned result.
78-
// TODO: implement a more mature and controllable tracing of PI calls.
79-
class PiCall {
80-
PiResult m_Result;
81-
static bool m_TraceEnabled;
82-
83-
public:
84-
explicit PiCall(const char *Trace = nullptr);
85-
~PiCall();
86-
PiResult get(PiResult Result);
87-
template<typename Exception>
88-
void check(PiResult Result);
89-
};
90-
91-
// The run-time tracing of PI calls.
92-
// TODO: replace PiCall completely with this one (PiTrace)
93-
//
94-
template <typename T> inline
95-
void print(T val) {
96-
std::cout << "<unknown> : " << val;
97-
}
85+
// Performs PI one-time initialization.
86+
void initialize();
87+
88+
// The PiCall helper structure facilitates performing a call to PI.
89+
// It holds utilities to do the tracing and to check the returned result.
90+
// TODO: implement a more mature and controllable tracing of PI calls.
91+
class PiCall {
92+
PiResult m_Result;
93+
static bool m_TraceEnabled;
94+
95+
public:
96+
explicit PiCall(const char *Trace = nullptr);
97+
~PiCall();
98+
PiResult get(PiResult Result);
99+
template <typename Exception> void check(PiResult Result);
100+
};
101+
102+
// The run-time tracing of PI calls.
103+
// TODO: replace PiCall completely with this one (PiTrace)
104+
//
105+
template <typename T> inline void print(T val) {
106+
std::cout << "<unknown> : " << val;
107+
}
98108

99-
template<> inline void print<> (PiPlatform val) { std::cout << "pi_platform : " << val; }
100-
template<> inline void print<> (PiResult val) {
101-
std::cout << "pi_result : ";
102-
if (val == PI_SUCCESS)
103-
std::cout << "PI_SUCCESS";
104-
else
105-
std::cout << val;
106-
}
107-
108-
inline void printArgs(void) {}
109-
template <typename Arg0, typename... Args>
110-
void printArgs(Arg0 arg0, Args... args) {
111-
std::cout << std::endl << " ";
112-
print(arg0);
113-
printArgs(std::forward<Args>(args)...);
109+
template <> inline void print<>(PiPlatform val) {
110+
std::cout << "pi_platform : " << val;
111+
}
112+
template <> inline void print<>(PiResult val) {
113+
std::cout << "pi_result : ";
114+
if (val == PI_SUCCESS)
115+
std::cout << "PI_SUCCESS";
116+
else
117+
std::cout << val;
118+
}
119+
120+
inline void printArgs(void) {}
121+
template <typename Arg0, typename... Args>
122+
void printArgs(Arg0 arg0, Args... args) {
123+
std::cout << std::endl << " ";
124+
print(arg0);
125+
printArgs(std::forward<Args>(args)...);
126+
}
127+
128+
template <typename FnType> class Trace {
129+
private:
130+
FnType m_FnPtr;
131+
static bool m_TraceEnabled;
132+
133+
public:
134+
Trace(FnType FnPtr, const std::string &FnName) : m_FnPtr(FnPtr) {
135+
if (m_TraceEnabled)
136+
std::cout << "---> " << FnName << "(";
114137
}
115-
116-
template <typename FnType>
117-
class Trace {
118-
private:
119-
FnType m_FnPtr;
120-
static bool m_TraceEnabled;
121-
public:
122-
Trace(FnType FnPtr, const std::string &FnName) : m_FnPtr(FnPtr) {
123-
if (m_TraceEnabled)
124-
std::cout << "---> " << FnName << "(";
125-
}
126-
127-
template <typename... Args>
128-
typename std::result_of<FnType(Args...)>::type
129-
operator() (Args... args) {
130-
if (m_TraceEnabled)
131-
printArgs(args...);
132-
133-
initialize();
134-
auto r = m_FnPtr(args...);
135-
136-
if (m_TraceEnabled) {
137-
std::cout << ") ---> ";
138-
std::cout << (print(r),"") << "\n";
139-
}
140-
return r;
138+
139+
template <typename... Args>
140+
typename std::result_of<FnType(Args...)>::type operator()(Args... args) {
141+
if (m_TraceEnabled)
142+
printArgs(args...);
143+
144+
initialize();
145+
auto r = m_FnPtr(args...);
146+
147+
if (m_TraceEnabled) {
148+
std::cout << ") ---> ";
149+
std::cout << (print(r), "") << "\n";
141150
}
142-
};
151+
return r;
152+
}
153+
};
143154

144-
template <typename FnType>
145-
bool Trace<FnType>::m_TraceEnabled = (std::getenv("SYCL_PI_TRACE") != nullptr);
155+
template <typename FnType>
156+
bool Trace<FnType>::m_TraceEnabled = (std::getenv("SYCL_PI_TRACE") != nullptr);
146157

147158
} // namespace pi
148159

149160
namespace RT = cl::sycl::detail::pi;
150161

151-
#define PI_ASSERT(cond, msg) \
152-
RT::assertion((cond), "assert: " msg);
162+
#define PI_ASSERT(cond, msg) RT::assertion((cond), "assert: " msg);
153163

154164
#define PI_TRACE(func) RT::Trace<decltype(func)>(func, #func)
155165

156166
// This does the call, the trace and the check for no errors.
157-
#define PI_CALL(pi) \
158-
RT::initialize(), \
159-
RT::PiCall(#pi).check<cl::sycl::runtime_error>( \
160-
RT::cast<detail::RT::PiResult>(pi))
167+
#define PI_CALL(pi) \
168+
RT::initialize(), RT::PiCall(#pi).check<cl::sycl::runtime_error>( \
169+
RT::cast<detail::RT::PiResult>(pi))
161170

162171
// This does the trace, the call, and returns the result
163-
#define PI_CALL_RESULT(pi) \
164-
RT::PiCall(#pi).get(detail::RT::cast<detail::RT::PiResult>(pi))
172+
#define PI_CALL_RESULT(pi) \
173+
RT::PiCall(#pi).get(detail::RT::cast<detail::RT::PiResult>(pi))
165174

166175
// This does the check for no errors and possibly throws
167-
#define PI_CHECK(pi) \
168-
RT::PiCall().check<cl::sycl::runtime_error>( \
169-
RT::cast<detail::RT::PiResult>(pi))
176+
#define PI_CHECK(pi) \
177+
RT::PiCall().check<cl::sycl::runtime_error>( \
178+
RT::cast<detail::RT::PiResult>(pi))
170179

171180
// This does the check for no errors and possibly throws x
172-
#define PI_CHECK_THROW(pi, x) \
173-
RT::PiCall().check<x>( \
174-
RT::cast<detail::RT::PiResult>(pi))
181+
#define PI_CHECK_THROW(pi, x) \
182+
RT::PiCall().check<x>(RT::cast<detail::RT::PiResult>(pi))
175183

176184
// Want all the needed casts be explicit, do not define conversion operators.
177-
template<class To, class From>
178-
To pi::cast(From value) {
185+
template <class To, class From> To pi::cast(From value) {
179186
// TODO: see if more sanity checks are possible.
180187
PI_ASSERT(sizeof(From) == sizeof(To), "cast failed size check");
181188
return (To)(value);

sycl/plugins/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(opencl)

sycl/plugins/opencl/CMakeLists.txt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#TODO:
2+
#1. Figure out why CMP0057 has to be set. Should have been taken care of earlier in the build
3+
#2. Use AddLLVM to modify the build and access config options
4+
#cmake_policy(SET CMP0057 NEW)
5+
#include(AddLLVM)
6+
7+
# Plugin for OpenCL
8+
# Create Shared library for libpi_opencl.so.
9+
#TODO: remove dependency on pi.hpp in sycl project.
10+
#TODO: Currently, the pi.hpp header is common between sycl and plugin library sources.
11+
#This can be changed by copying the pi.hpp file in the plugins project.
12+
add_library(pi_opencl SHARED
13+
"${sycl_inc_dir}/CL/sycl/detail/pi.h"
14+
"pi_opencl.cpp"
15+
)
16+
17+
add_dependencies(pi_opencl
18+
ocl-icd
19+
ocl-headers
20+
)
21+
22+
add_dependencies(sycl pi_opencl)
23+
24+
set_target_properties(pi_opencl PROPERTIES LINKER_LANGUAGE CXX)
25+
26+
#preprocessor definitions for compiling a target's sources. We do not need it for pi_opencl
27+
target_include_directories(pi_opencl PRIVATE "${sycl_inc_dir}")
28+
29+
#link pi_opencl with OpenCL headers and ICD Loader.
30+
target_link_libraries( pi_opencl
31+
PRIVATE OpenCL::Headers
32+
PRIVATE ${OpenCL_LIBRARIES}
33+
)
34+
35+
if (SYCL_USE_LIBCXX)
36+
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
37+
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
38+
target_compile_options(pi_opencl PRIVATE -nostdinc++)
39+
if ((NOT (DEFINED SYCL_LIBCXX_INCLUDE_PATH)) OR (NOT (DEFINED SYCL_LIBCXX_LIBRARY_PATH)))
40+
message(FATAL_ERROR "When building with libc++ SYCL_LIBCXX_INCLUDE_PATHS and"
41+
"SYCL_LIBCXX_LIBRARY_PATH should be set")
42+
endif()
43+
target_include_directories(pi_opencl PRIVATE "${SYCL_LIBCXX_INCLUDE_PATH}")
44+
target_link_libraries(pi_opencl PRIVATE "-L${SYCL_LIBCXX_LIBRARY_PATH}" -nodefaultlibs -lc++ -lc)
45+
else()
46+
message(FATAL_ERROR "Build with libc++ is not yet supported for this compiler")
47+
endif()
48+
else()
49+
50+
# Workaround for bug in GCC version 5 and higher.
51+
# More information https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899
52+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND
53+
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0)
54+
target_link_libraries(pi_opencl PRIVATE gcc_s gcc)
55+
endif()
56+
57+
endif()
58+
59+
install(TARGETS pi_opencl
60+
LIBRARY DESTINATION "lib" COMPONENT pi_opencl
61+
RUNTIME DESTINATION "bin" COMPONENT pi_opencl)

0 commit comments

Comments
 (0)