Skip to content

Commit c4eafea

Browse files
authored
Merge pull request #708 from garimagu/private/garimagu/pi_discovery
[SYCL] Plugin Interface And Creation of OpenCL Plugin.
2 parents b8e5157 + 884459b commit c4eafea

File tree

9 files changed

+469
-337
lines changed

9 files changed

+469
-337
lines changed

sycl/CMakeLists.txt

+34-1
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,37 @@ if (MSVC)
143143
list(APPEND SYCL_RT_LIBS sycld)
144144
endif()
145145

146+
# This function allows building multiple libraries with the same options.
147+
# Currently used by sycl and plugins library.
148+
# Currently handles linking with libcxx support and gcc workaround
149+
function( add_common_options LIB_NAME)
150+
if (SYCL_USE_LIBCXX)
151+
if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
152+
(CMAKE_CXX_COMPILER_ID STREQUAL "Clang"))
153+
target_compile_options(${LIB_NAME} PRIVATE -nostdinc++)
154+
if ((NOT (DEFINED SYCL_LIBCXX_INCLUDE_PATH)) OR (NOT (DEFINED SYCL_LIBCXX_LIBRARY_PATH)))
155+
message(FATAL_ERROR "When building with libc++ SYCL_LIBCXX_INCLUDE_PATHS and"
156+
"SYCL_LIBCXX_LIBRARY_PATH should be set")
157+
endif()
158+
target_include_directories(${LIB_NAME} PRIVATE "${SYCL_LIBCXX_INCLUDE_PATH}")
159+
target_link_libraries(${LIB_NAME} PRIVATE "-L${SYCL_LIBCXX_LIBRARY_PATH}" -nodefaultlibs -lc++ -lc++abi -lm -lc -lgcc_s -lgcc)
160+
else()
161+
message(FATAL_ERROR "Build with libc++ is not yet supported for this compiler")
162+
endif()
163+
else()
164+
165+
# Workaround for bug in GCC version 5 and higher.
166+
# More information https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899
167+
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND
168+
CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.0)
169+
target_link_libraries(${LIB_NAME} PRIVATE gcc_s gcc)
170+
endif()
171+
172+
endif()
173+
endfunction(add_common_options)
174+
146175
# SYCL runtime library
147-
add_subdirectory(source)
176+
add_subdirectory( source )
148177

149178
# SYCL toolchain builds all components: compiler, libraries, headers, etc.
150179
add_custom_target( sycl-toolchain
@@ -173,6 +202,10 @@ option(SYCL_INCLUDE_TESTS
173202
"Generate build targets for the SYCL unit tests."
174203
${LLVM_INCLUDE_TESTS})
175204

205+
206+
# Plugin Library
207+
add_subdirectory( plugins )
208+
176209
add_subdirectory(tools)
177210

178211
if(SYCL_INCLUDE_TESTS)

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

+142-134
Original file line numberDiff line numberDiff line change
@@ -14,168 +14,176 @@
1414
#include <CL/sycl/detail/os_util.hpp>
1515
#include <CL/sycl/detail/pi.h>
1616

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

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

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)...);
110+
template <> inline void print<>(PiPlatform val) {
111+
std::cout << "pi_platform : " << val;
112+
}
113+
template <> inline void print<>(PiResult val) {
114+
std::cout << "pi_result : ";
115+
if (val == PI_SUCCESS)
116+
std::cout << "PI_SUCCESS";
117+
else
118+
std::cout << val;
119+
}
120+
121+
inline void printArgs(void) {}
122+
template <typename Arg0, typename... Args>
123+
void printArgs(Arg0 arg0, Args... args) {
124+
std::cout << std::endl << " ";
125+
print(arg0);
126+
printArgs(std::forward<Args>(args)...);
127+
}
128+
129+
template <typename FnType> class Trace {
130+
private:
131+
FnType m_FnPtr;
132+
static bool m_TraceEnabled;
133+
134+
public:
135+
Trace(FnType FnPtr, const std::string &FnName) : m_FnPtr(FnPtr) {
136+
if (m_TraceEnabled)
137+
std::cout << "---> " << FnName << "(";
114138
}
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;
139+
140+
template <typename... Args>
141+
typename std::result_of<FnType(Args...)>::type operator()(Args... args) {
142+
if (m_TraceEnabled)
143+
printArgs(args...);
144+
145+
initialize();
146+
auto r = m_FnPtr(args...);
147+
148+
if (m_TraceEnabled) {
149+
std::cout << ") ---> ";
150+
std::cout << (print(r), "") << "\n";
141151
}
142-
};
152+
return r;
153+
}
154+
};
143155

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

147159
} // namespace pi
148160

149161
namespace RT = cl::sycl::detail::pi;
150162

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

154165
#define PI_TRACE(func) RT::Trace<decltype(func)>(func, #func)
155166

156167
// 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))
168+
#define PI_CALL(pi) \
169+
RT::initialize(), RT::PiCall(#pi).check<cl::sycl::runtime_error>( \
170+
RT::cast<detail::RT::PiResult>(pi))
161171

162172
// 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))
173+
#define PI_CALL_RESULT(pi) \
174+
RT::PiCall(#pi).get(detail::RT::cast<detail::RT::PiResult>(pi))
165175

166176
// 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))
177+
#define PI_CHECK(pi) \
178+
RT::PiCall().check<cl::sycl::runtime_error>( \
179+
RT::cast<detail::RT::PiResult>(pi))
170180

171181
// 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))
182+
#define PI_CHECK_THROW(pi, x) \
183+
RT::PiCall().check<x>(RT::cast<detail::RT::PiResult>(pi))
175184

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

sycl/plugins/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_subdirectory(opencl)

0 commit comments

Comments
 (0)