Skip to content

Commit a8e86c7

Browse files
committed
[SYCL] Using a single call to Plugin, and populating a Plugin
datastructure with all function pointers. Extension to this will allow us to bind multiple plugins. Signed-off-by: Garima Gupta <[email protected]>
1 parent ee4b1f7 commit a8e86c7

File tree

6 files changed

+184
-21
lines changed

6 files changed

+184
-21
lines changed

sycl/include/CL/sycl/detail/pi.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,16 @@ typedef _pi_image_desc pi_image_desc;
377377
// TODO: describe interfaces in Doxygen format
378378
//
379379

380+
struct _pi_plugin;
381+
typedef _pi_plugin pi_plugin;
382+
383+
// PI Plugin Initialise.
384+
// Must be implemented by a plugin.
385+
// Plugin will read the PIVersion,
386+
// populate the PluginVersion and update targets field and populate the PIFunctionTable with the function pointers for the APIs supported by PIVersion.
387+
// The pointers are in a predetermined order in pi.def file.
388+
pi_result piPluginInit(pi_plugin *plugin_info);
389+
380390
//
381391
// Platform
382392
//
@@ -903,6 +913,19 @@ pi_result piEnqueueMemUnmap(
903913
const pi_event * event_wait_list,
904914
pi_event * event);
905915

916+
struct _pi_plugin{
917+
// PI version supported by host passed to the plugin. The Plugin this
918+
// way knows the number of APIs it can write into the PIFunctionTable.
919+
const char PiVersion[4] = "1.1";
920+
char PluginVersion[4] = "1.1"; // Plugin edits this.
921+
// TODO: what is this field for?
922+
char *Targets;
923+
struct FunctionPointers {
924+
#define _PI_API(api) decltype(::api) *api;
925+
#include <CL/sycl/detail/pi.def>
926+
} PiFunctionTable;
927+
};
928+
906929
#ifdef __cplusplus
907930
} // extern "C"
908931
#endif // __cplusplus

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

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
#include <cassert>
1818
#include <string>
1919

20+
namespace cl {
21+
namespace sycl {
22+
namespace detail {
23+
namespace pi {
24+
2025
// Function to load the shared library
2126
// Implementation is OS dependent.
2227
void *loadOsLibrary(const std::string &Library);
@@ -25,10 +30,6 @@ void *loadOsLibrary(const std::string &Library);
2530
// library, implementation is OS dependent.
2631
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName);
2732

28-
namespace cl {
29-
namespace sycl {
30-
namespace detail {
31-
namespace pi {
3233
// For selection of SYCL RT back-end, now manually through the "SYCL_BE"
3334
// environment variable.
3435
//
@@ -80,8 +81,11 @@ void assertion(bool Condition, const char *Message = nullptr);
8081
template <class To, class From> To cast(From value);
8182

8283
// Forward declarations of the PI dispatch entries.
83-
#define _PI_API(api) __SYCL_EXPORTED extern decltype(::api) *(api);
84-
#include <CL/sycl/detail/pi.def>
84+
//#define _PI_API(api) __SYCL_EXPORTED extern decltype(::api) *(api);
85+
//#include <CL/sycl/detail/pi.def>
86+
87+
// Holds the PluginInformation for the plugin that is bound.
88+
extern pi_plugin PluginInformation;
8589

8690
// Performs PI one-time initialization.
8791
void initialize();
@@ -163,7 +167,9 @@ namespace RT = cl::sycl::detail::pi;
163167

164168
#define PI_ASSERT(cond, msg) RT::assertion((cond), "assert: " msg);
165169

166-
#define PI_TRACE(func) RT::Trace<decltype(func)>(func, #func)
170+
#define PI_TRACE(func) RT::Trace<decltype(func)>(RT::PluginInformation.func, #func)
171+
172+
#define PI_TRACE_ONLY(func) RT::Trace<decltype(func)>(func, #func)
167173

168174
// Use this macro to initialize the Plugin, call the API, do the trace
169175
// and the check for no errors.

sycl/plugins/opencl/pi_opencl.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
return cast<pi_result>(reterr); \
2121
}
2222

23+
const char SupportedVersion[] = "1.1";
2324
// Want all the needed casts be explicit, do not define conversion operators.
2425
template <class To, class From> To cast(From value) {
2526
// TODO: see if more sanity checks are possible.
@@ -452,6 +453,7 @@ pi_result OCL(piEnqueueMemBufferMap)(
452453
return ret_err;
453454
}
454455

456+
/*
455457
// TODO: Remove the 'OclPtr' extension used with the PI_APIs.
456458
// Forward calls to OpenCL RT.
457459
#define _PI_CL(pi_api, ocl_api) \
@@ -539,4 +541,105 @@ _PI_CL(piEnqueueMemBufferMap, OCL(piEnqueueMemBufferMap))
539541
_PI_CL(piEnqueueMemUnmap, clEnqueueUnmapMemObject)
540542
541543
#undef _PI_CL
544+
*/
545+
546+
pi_result piPluginInit(pi_plugin *PluginInit) {
547+
strcpy(PluginInit->PluginVersion, SupportedVersion);
548+
int CompareVersions = strcmp(PluginInit->PiVersion, SupportedVersion);
549+
if (CompareVersions < 0) {
550+
// PI interface supports lower version of PI.
551+
assert(false && "incompatible versions.!!\n");
552+
return PI_INVALID_OPERATION;
553+
} else {
554+
// PI interface supports higher version or the same version.
555+
556+
#define _PI_CL(pi_api, ocl_api) \
557+
(PluginInit->PiFunctionTable).pi_api = (decltype(&::pi_api))(&ocl_api);
558+
559+
// Platform
560+
_PI_CL(piPlatformsGet, OCL(piPlatformsGet))
561+
_PI_CL(piPlatformGetInfo, clGetPlatformInfo)
562+
// Device
563+
_PI_CL(piDevicesGet, OCL(piDevicesGet))
564+
_PI_CL(piDeviceGetInfo, clGetDeviceInfo)
565+
_PI_CL(piDevicePartition, clCreateSubDevices)
566+
_PI_CL(piDeviceRetain, clRetainDevice)
567+
_PI_CL(piDeviceRelease, clReleaseDevice)
568+
_PI_CL(piextDeviceSelectBinary, OCL(piextDeviceSelectBinary))
569+
_PI_CL(piextGetDeviceFunctionPointer, OCL(piextGetDeviceFunctionPointer))
570+
// Context
571+
_PI_CL(piContextCreate, OCL(piContextCreate))
572+
_PI_CL(piContextGetInfo, clGetContextInfo)
573+
_PI_CL(piContextRetain, clRetainContext)
574+
_PI_CL(piContextRelease, clReleaseContext)
575+
// Queue
576+
_PI_CL(piQueueCreate, OCL(piQueueCreate))
577+
_PI_CL(piQueueGetInfo, clGetCommandQueueInfo)
578+
_PI_CL(piQueueFinish, clFinish)
579+
_PI_CL(piQueueRetain, clRetainCommandQueue)
580+
_PI_CL(piQueueRelease, clReleaseCommandQueue)
581+
// Memory
582+
_PI_CL(piMemBufferCreate, OCL(piMemBufferCreate))
583+
_PI_CL(piMemImageCreate, OCL(piMemImageCreate))
584+
_PI_CL(piMemGetInfo, clGetMemObjectInfo)
585+
_PI_CL(piMemImageGetInfo, clGetImageInfo)
586+
_PI_CL(piMemRetain, clRetainMemObject)
587+
_PI_CL(piMemRelease, clReleaseMemObject)
588+
_PI_CL(piMemBufferPartition, OCL(piMemBufferPartition))
589+
// Program
590+
_PI_CL(piProgramCreate, OCL(piProgramCreate))
591+
_PI_CL(piclProgramCreateWithSource, OCL(piclProgramCreateWithSource))
592+
_PI_CL(piclProgramCreateWithBinary, OCL(piclProgramCreateWithBinary))
593+
_PI_CL(piProgramGetInfo, clGetProgramInfo)
594+
_PI_CL(piProgramCompile, clCompileProgram)
595+
_PI_CL(piProgramBuild, clBuildProgram)
596+
_PI_CL(piProgramLink, OCL(piProgramLink))
597+
_PI_CL(piProgramGetBuildInfo, clGetProgramBuildInfo)
598+
_PI_CL(piProgramRetain, clRetainProgram)
599+
_PI_CL(piProgramRelease, clReleaseProgram)
600+
// Kernel
601+
_PI_CL(piKernelCreate, OCL(piKernelCreate))
602+
_PI_CL(piKernelSetArg, clSetKernelArg)
603+
_PI_CL(piKernelGetInfo, clGetKernelInfo)
604+
_PI_CL(piKernelGetGroupInfo, clGetKernelWorkGroupInfo)
605+
_PI_CL(piKernelGetSubGroupInfo, clGetKernelSubGroupInfo)
606+
_PI_CL(piKernelRetain, clRetainKernel)
607+
_PI_CL(piKernelRelease, clReleaseKernel)
608+
// Event
609+
_PI_CL(piEventCreate, OCL(piEventCreate))
610+
_PI_CL(piEventGetInfo, clGetEventInfo)
611+
_PI_CL(piEventGetProfilingInfo, clGetEventProfilingInfo)
612+
_PI_CL(piEventsWait, clWaitForEvents)
613+
_PI_CL(piEventSetCallback, clSetEventCallback)
614+
_PI_CL(piEventSetStatus, clSetUserEventStatus)
615+
_PI_CL(piEventRetain, clRetainEvent)
616+
_PI_CL(piEventRelease, clReleaseEvent)
617+
// Sampler
618+
_PI_CL(piSamplerCreate, OCL(piSamplerCreate))
619+
_PI_CL(piSamplerGetInfo, clGetSamplerInfo)
620+
_PI_CL(piSamplerRetain, clRetainSampler)
621+
_PI_CL(piSamplerRelease, clReleaseSampler)
622+
// Queue commands
623+
_PI_CL(piEnqueueKernelLaunch, clEnqueueNDRangeKernel)
624+
_PI_CL(piEnqueueNativeKernel, clEnqueueNativeKernel)
625+
_PI_CL(piEnqueueEventsWait, clEnqueueMarkerWithWaitList)
626+
_PI_CL(piEnqueueMemBufferRead, clEnqueueReadBuffer)
627+
_PI_CL(piEnqueueMemBufferReadRect, clEnqueueReadBufferRect)
628+
_PI_CL(piEnqueueMemBufferWrite, clEnqueueWriteBuffer)
629+
_PI_CL(piEnqueueMemBufferWriteRect, clEnqueueWriteBufferRect)
630+
_PI_CL(piEnqueueMemBufferCopy, clEnqueueCopyBuffer)
631+
_PI_CL(piEnqueueMemBufferCopyRect, clEnqueueCopyBufferRect)
632+
_PI_CL(piEnqueueMemBufferFill, clEnqueueFillBuffer)
633+
_PI_CL(piEnqueueMemImageRead, clEnqueueReadImage)
634+
_PI_CL(piEnqueueMemImageWrite, clEnqueueWriteImage)
635+
_PI_CL(piEnqueueMemImageCopy, clEnqueueCopyImage)
636+
_PI_CL(piEnqueueMemImageFill, clEnqueueFillImage)
637+
_PI_CL(piEnqueueMemBufferMap, OCL(piEnqueueMemBufferMap))
638+
_PI_CL(piEnqueueMemUnmap, clEnqueueUnmapMemObject)
639+
640+
#undef _PI_CL
641+
}
642+
return PI_SUCCESS;
542643
}
644+
645+
} // end extern 'C'

sycl/source/detail/linux_pi.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
#include <dlfcn.h>
22
#include <string>
33

4+
namespace cl {
5+
namespace sycl {
6+
namespace detail {
7+
namespace pi {
8+
49
void *loadOsLibrary(const std::string &PluginPath) {
510
// TODO: Check if the option RTLD_NOW is correct. Explore using
611
// RTLD_DEEPBIND option when there are multiple plugins.
@@ -10,3 +15,8 @@ void *loadOsLibrary(const std::string &PluginPath) {
1015
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName) {
1116
return dlsym(Library, FunctionName.c_str());
1217
}
18+
19+
} // namespace pi
20+
} // namespace detail
21+
} // namespace sycl
22+
} // namespace cl

sycl/source/detail/pi.cpp

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ bool useBackend(Backend TheBackend) {
4848

4949
// Definitions of the PI dispatch entries, they will be initialized
5050
// at their first use with piInitialize.
51-
#define _PI_API(api) decltype(::api) *api = nullptr;
52-
#include <CL/sycl/detail/pi.def>
51+
//#define _PI_API(api) decltype(::api) *api = nullptr;
52+
//#include <CL/sycl/detail/pi.def>
53+
54+
pi_plugin PluginInformation;
5355

5456
// Find the plugin at the appropriate location and return the location.
5557
// TODO: Change the function appropriately when there are multiple plugins.
@@ -74,18 +76,27 @@ void *loadPlugin(const std::string &PluginPath) {
7476
// needs to setup infrastructure to route PI_CALLs to the appropriate plugins.
7577
// Currently, we bind to a singe plugin.
7678
bool bindPlugin(void *Library) {
77-
#define STRINGIZE(x) #x
78-
79-
#define _PI_API(api) \
80-
decltype(&api) api##_ptr = ((decltype(&api))( \
81-
getOsLibraryFuncAddress(Library, STRINGIZE(api##OclPtr)))); \
82-
if (!api##_ptr) \
83-
return false; \
84-
api = *api##_ptr;
85-
#include <CL/sycl/detail/pi.def>
86-
87-
#undef STRINGIZE
88-
#undef _PI_API
79+
80+
decltype(::piPluginInit) *PluginInitializeFunction =
81+
(decltype(&::piPluginInit))(
82+
getOsLibraryFuncAddress(Library, "piPluginInit"));
83+
// FuncTable is a list of all Interface Function pointers, where each
84+
// Interface Function is located at a predetermined offset.
85+
int err = PluginInitializeFunction(&PluginInformation);
86+
87+
// TODO: Check err code.
88+
89+
// At the predetermined api's offset from the FunctionTable, the function
90+
// pointer for "api" is stored. So we dereference the location to get the
91+
// function pointer.
92+
93+
//#define _PI_API(api) \
94+
api = ((decltype(api))(PluginInformation.PiFunctionTable.api));
95+
96+
//#include <CL/sycl/detail/pi.def>
97+
98+
// #undef _PI_API
99+
89100
return true;
90101
}
91102

sycl/source/detail/windows_pi.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,20 @@
22
#include <winreg.h>
33
#include <string>
44

5+
namespace cl {
6+
namespace sycl {
7+
namespace detail {
8+
namespace pi {
9+
510
void *loadOsLibrary(const std::string &PluginPath) {
611
return (void *)LoadLibraryA(PluginPath.c_str());
712
}
813

914
void *getOsLibraryFuncAddress(void *Library, const std::string &FunctionName) {
1015
return GetProcAddress((HMODULE)Library, FunctionName.c_str());
1116
}
17+
18+
} // namespace pi
19+
} // namespace detail
20+
} // namespace sycl
21+
} // namespace cl

0 commit comments

Comments
 (0)