Skip to content

Commit 7f3389e

Browse files
committed
[SYCL] Plugin Interface Changes to query a list of function pointers.
- Plugin now keeps a list of the function pointers in a predetermined order. - A single dlsym call is made returning the location of this list. - The PI function pointers are populated using offsets and this location. Signed-off-by: Garima Gupta <[email protected]>
1 parent 844eccb commit 7f3389e

File tree

3 files changed

+218
-90
lines changed

3 files changed

+218
-90
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//==------- pi_functionoffsets.h - Plugin Interface Function Offsets ------==//
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+
// #define NameoftheAPI Offset_to_add.
9+
// Map the names of PI APIs to the corresponding offsets. This offset is added
10+
// to the address of the Function Pointer list(returned by the Plugin) to get
11+
// the location of the corresponding API Function Pointer implemented by the
12+
// Plugin. Eg: Plugin returns address 0x0000 for the Function List. To get the
13+
// function pointer for function piQueueCreate, we add 13*(8) = 104 to 0x0000
14+
// and access it. So (*0x0068) gives the function pointer to piQueueCreate
15+
// implemented by the Plugin. Call is made using:
16+
// (*0x0068)(context,device,properties,queue);
17+
18+
#define FUNCTION_PTR_SIZE sizeof(void (*)())
19+
20+
// Platform
21+
22+
#define piPlatformsGet_Offset 0
23+
#define piPlatformGetInfo_Offset 1 * FUNCTION_PTR_SIZE
24+
// Device
25+
#define piDevicesGet_Offset 2 * FUNCTION_PTR_SIZE
26+
#define piDeviceGetInfo_Offset 3 * FUNCTION_PTR_SIZE
27+
#define piDevicePartition_Offset 4 * FUNCTION_PTR_SIZE
28+
#define piDeviceRetain_Offset 5 * FUNCTION_PTR_SIZE
29+
#define piDeviceRelease_Offset 6 * FUNCTION_PTR_SIZE
30+
#define piextDeviceSelectBinary_Offset 7 * FUNCTION_PTR_SIZE
31+
#define piextGetDeviceFunctionPointer_Offset 8 * FUNCTION_PTR_SIZE
32+
// Context
33+
#define piContextCreate_Offset 9 * FUNCTION_PTR_SIZE
34+
#define piContextGetInfo_Offset 10 * FUNCTION_PTR_SIZE
35+
#define piContextRetain_Offset 11 * FUNCTION_PTR_SIZE
36+
#define piContextRelease_Offset 12 * FUNCTION_PTR_SIZE
37+
// Queue
38+
#define piQueueCreate_Offset 13 * FUNCTION_PTR_SIZE
39+
#define piQueueGetInfo_Offset 14 * FUNCTION_PTR_SIZE
40+
#define piQueueFinish_Offset 15 * FUNCTION_PTR_SIZE
41+
#define piQueueRetain_Offset 16 * FUNCTION_PTR_SIZE
42+
#define piQueueRelease_Offset 17 * FUNCTION_PTR_SIZE
43+
// Memory
44+
#define piMemBufferCreate_Offset 18 * FUNCTION_PTR_SIZE
45+
#define piMemImageCreate_Offset 19 * FUNCTION_PTR_SIZE
46+
#define piMemGetInfo_Offset 20 * FUNCTION_PTR_SIZE
47+
#define piMemImageGetInfo_Offset 21 * FUNCTION_PTR_SIZE
48+
#define piMemRetain_Offset 22 * FUNCTION_PTR_SIZE
49+
#define piMemRelease_Offset 23 * FUNCTION_PTR_SIZE
50+
#define piMemBufferPartition_Offset 24 * FUNCTION_PTR_SIZE
51+
// Program
52+
#define piProgramCreate_Offset 25 * FUNCTION_PTR_SIZE
53+
#define piclProgramCreateWithSource_Offset 26 * FUNCTION_PTR_SIZE
54+
#define piclProgramCreateWithBinary_Offset 27 * FUNCTION_PTR_SIZE
55+
#define piProgramGetInfo_Offset 28 * FUNCTION_PTR_SIZE
56+
#define piProgramCompile_Offset 29 * FUNCTION_PTR_SIZE
57+
#define piProgramBuild_Offset 30 * FUNCTION_PTR_SIZE
58+
#define piProgramLink_Offset 31 * FUNCTION_PTR_SIZE
59+
#define piProgramGetBuildInfo_Offset 32 * FUNCTION_PTR_SIZE
60+
#define piProgramRetain_Offset 33 * FUNCTION_PTR_SIZE
61+
#define piProgramRelease_Offset 34 * FUNCTION_PTR_SIZE
62+
// Kernel
63+
#define piKernelCreate_Offset 35 * FUNCTION_PTR_SIZE
64+
#define piKernelSetArg_Offset 36 * FUNCTION_PTR_SIZE
65+
#define piKernelGetInfo_Offset 37 * FUNCTION_PTR_SIZE
66+
#define piKernelGetGroupInfo_Offset 38 * FUNCTION_PTR_SIZE
67+
#define piKernelGetSubGroupInfo_Offset 39 * FUNCTION_PTR_SIZE
68+
#define piKernelRetain_Offset 40 * FUNCTION_PTR_SIZE
69+
#define piKernelRelease_Offset 41 * FUNCTION_PTR_SIZE
70+
// Event
71+
#define piEventCreate_Offset 42 * FUNCTION_PTR_SIZE
72+
#define piEventGetInfo_Offset 43 * FUNCTION_PTR_SIZE
73+
#define piEventGetProfilingInfo_Offset 44 * FUNCTION_PTR_SIZE
74+
#define piEventsWait_Offset 45 * FUNCTION_PTR_SIZE
75+
#define piEventSetCallback_Offset 46 * FUNCTION_PTR_SIZE
76+
#define piEventSetStatus_Offset 47 * FUNCTION_PTR_SIZE
77+
#define piEventRetain_Offset 48 * FUNCTION_PTR_SIZE
78+
#define piEventRelease_Offset 49 * FUNCTION_PTR_SIZE
79+
// Sampler
80+
#define piSamplerCreate_Offset 50 * FUNCTION_PTR_SIZE
81+
#define piSamplerGetInfo_Offset 51 * FUNCTION_PTR_SIZE
82+
#define piSamplerRetain_Offset 52 * FUNCTION_PTR_SIZE
83+
#define piSamplerRelease_Offset 53 * FUNCTION_PTR_SIZE
84+
// Queue commands
85+
#define piEnqueueKernelLaunch_Offset 54 * FUNCTION_PTR_SIZE
86+
#define piEnqueueNativeKernel_Offset 55 * FUNCTION_PTR_SIZE
87+
#define piEnqueueEventsWait_Offset 56 * FUNCTION_PTR_SIZE
88+
#define piEnqueueMemBufferRead_Offset 57 * FUNCTION_PTR_SIZE
89+
#define piEnqueueMemBufferReadRect_Offset 58 * FUNCTION_PTR_SIZE
90+
#define piEnqueueMemBufferWrite_Offset 59 * FUNCTION_PTR_SIZE
91+
#define piEnqueueMemBufferWriteRect_Offset 60 * FUNCTION_PTR_SIZE
92+
#define piEnqueueMemBufferCopy_Offset 61 * FUNCTION_PTR_SIZE
93+
#define piEnqueueMemBufferCopyRect_Offset 62 * FUNCTION_PTR_SIZE
94+
#define piEnqueueMemBufferFill_Offset 63 * FUNCTION_PTR_SIZE
95+
#define piEnqueueMemImageRead_Offset 64 * FUNCTION_PTR_SIZE
96+
#define piEnqueueMemImageWrite_Offset 65 * FUNCTION_PTR_SIZE
97+
#define piEnqueueMemImageCopy_Offset 66 * FUNCTION_PTR_SIZE
98+
#define piEnqueueMemImageFill_Offset 67 * FUNCTION_PTR_SIZE
99+
#define piEnqueueMemBufferMap_Offset 68 * FUNCTION_PTR_SIZE
100+
#define piEnqueueMemUnmap_Offset 69 * FUNCTION_PTR_SIZE
101+

sycl/plugins/opencl/pi_opencl.cpp

Lines changed: 98 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8+
// This file implements an OpenCL Plugin, which is comformant to the Plugin
9+
// Interface. The plugin implements a single function call which returns the
10+
// location of the Plugin Interface Function Pointers list. The order of the
11+
// functions is the same as the order of the functions declared in pi.h file. It
12+
// is important to adhere to this order, as the plugin interface assumes this
13+
// order when it computes the offset for a specific function.
14+
815
#include "CL/opencl.h"
916
#include <CL/sycl/detail/pi.h>
1017
#include <cassert>
@@ -19,6 +26,8 @@
1926
return cast<pi_result>(reterr); \
2027
}
2128

29+
std::string SupportedVersion = "Version 1.1";
30+
2231
// Want all the needed casts be explicit, do not define conversion operators.
2332
template <class To, class From> To cast(From value) {
2433
// TODO: see if more sanity checks are possible.
@@ -270,91 +279,100 @@ pi_result OCL(piextGetDeviceFunctionPointer)(pi_device device,
270279
function_pointer_ret));
271280
}
272281

282+
// Plugin Interface Functions List.
283+
struct PluginInterfaceFunctions {
273284
// TODO: Remove the 'OclPtr' extension used with the PI_APIs.
274285
// Forward calls to OpenCL RT.
275286
#define _PI_CL(pi_api, ocl_api) \
276287
decltype(::pi_api) *pi_api##OclPtr = cast<decltype(&::pi_api)>(&ocl_api);
277288

278-
// Platform
279-
_PI_CL(piPlatformsGet, OCL(piPlatformsGet))
280-
_PI_CL(piPlatformGetInfo, clGetPlatformInfo)
281-
// Device
282-
_PI_CL(piDevicesGet, OCL(piDevicesGet))
283-
_PI_CL(piDeviceGetInfo, clGetDeviceInfo)
284-
_PI_CL(piDevicePartition, clCreateSubDevices)
285-
_PI_CL(piDeviceRetain, clRetainDevice)
286-
_PI_CL(piDeviceRelease, clReleaseDevice)
287-
_PI_CL(piextDeviceSelectBinary, OCL(piextDeviceSelectBinary))
288-
_PI_CL(piextGetDeviceFunctionPointer, OCL(piextGetDeviceFunctionPointer))
289-
// Context
290-
_PI_CL(piContextCreate, clCreateContext)
291-
_PI_CL(piContextGetInfo, clGetContextInfo)
292-
_PI_CL(piContextRetain, clRetainContext)
293-
_PI_CL(piContextRelease, clReleaseContext)
294-
// Queue
295-
_PI_CL(piQueueCreate, OCL(piQueueCreate))
296-
_PI_CL(piQueueGetInfo, clGetCommandQueueInfo)
297-
_PI_CL(piQueueFinish, clFinish)
298-
_PI_CL(piQueueRetain, clRetainCommandQueue)
299-
_PI_CL(piQueueRelease, clReleaseCommandQueue)
300-
// Memory
301-
_PI_CL(piMemBufferCreate, clCreateBuffer)
302-
_PI_CL(piMemImageCreate, clCreateImage)
303-
_PI_CL(piMemGetInfo, clGetMemObjectInfo)
304-
_PI_CL(piMemImageGetInfo, clGetImageInfo)
305-
_PI_CL(piMemRetain, clRetainMemObject)
306-
_PI_CL(piMemRelease, clReleaseMemObject)
307-
_PI_CL(piMemBufferPartition, clCreateSubBuffer)
308-
// Program
309-
_PI_CL(piProgramCreate, OCL(piProgramCreate))
310-
_PI_CL(piclProgramCreateWithSource, clCreateProgramWithSource)
311-
_PI_CL(piclProgramCreateWithBinary, clCreateProgramWithBinary)
312-
_PI_CL(piProgramGetInfo, clGetProgramInfo)
313-
_PI_CL(piProgramCompile, clCompileProgram)
314-
_PI_CL(piProgramBuild, clBuildProgram)
315-
_PI_CL(piProgramLink, clLinkProgram)
316-
_PI_CL(piProgramGetBuildInfo, clGetProgramBuildInfo)
317-
_PI_CL(piProgramRetain, clRetainProgram)
318-
_PI_CL(piProgramRelease, clReleaseProgram)
319-
// Kernel
320-
_PI_CL(piKernelCreate, clCreateKernel)
321-
_PI_CL(piKernelSetArg, clSetKernelArg)
322-
_PI_CL(piKernelGetInfo, clGetKernelInfo)
323-
_PI_CL(piKernelGetGroupInfo, clGetKernelWorkGroupInfo)
324-
_PI_CL(piKernelGetSubGroupInfo, clGetKernelSubGroupInfo)
325-
_PI_CL(piKernelRetain, clRetainKernel)
326-
_PI_CL(piKernelRelease, clReleaseKernel)
327-
// Event
328-
_PI_CL(piEventCreate, clCreateUserEvent)
329-
_PI_CL(piEventGetInfo, clGetEventInfo)
330-
_PI_CL(piEventGetProfilingInfo, clGetEventProfilingInfo)
331-
_PI_CL(piEventsWait, clWaitForEvents)
332-
_PI_CL(piEventSetCallback, clSetEventCallback)
333-
_PI_CL(piEventSetStatus, clSetUserEventStatus)
334-
_PI_CL(piEventRetain, clRetainEvent)
335-
_PI_CL(piEventRelease, clReleaseEvent)
336-
// Sampler
337-
_PI_CL(piSamplerCreate, OCL(piSamplerCreate))
338-
_PI_CL(piSamplerGetInfo, clGetSamplerInfo)
339-
_PI_CL(piSamplerRetain, clRetainSampler)
340-
_PI_CL(piSamplerRelease, clReleaseSampler)
341-
// Queue commands
342-
_PI_CL(piEnqueueKernelLaunch, clEnqueueNDRangeKernel)
343-
_PI_CL(piEnqueueNativeKernel, clEnqueueNativeKernel)
344-
_PI_CL(piEnqueueEventsWait, clEnqueueMarkerWithWaitList)
345-
_PI_CL(piEnqueueMemBufferRead, clEnqueueReadBuffer)
346-
_PI_CL(piEnqueueMemBufferReadRect, clEnqueueReadBufferRect)
347-
_PI_CL(piEnqueueMemBufferWrite, clEnqueueWriteBuffer)
348-
_PI_CL(piEnqueueMemBufferWriteRect, clEnqueueWriteBufferRect)
349-
_PI_CL(piEnqueueMemBufferCopy, clEnqueueCopyBuffer)
350-
_PI_CL(piEnqueueMemBufferCopyRect, clEnqueueCopyBufferRect)
351-
_PI_CL(piEnqueueMemBufferFill, clEnqueueFillBuffer)
352-
_PI_CL(piEnqueueMemImageRead, clEnqueueReadImage)
353-
_PI_CL(piEnqueueMemImageWrite, clEnqueueWriteImage)
354-
_PI_CL(piEnqueueMemImageCopy, clEnqueueCopyImage)
355-
_PI_CL(piEnqueueMemImageFill, clEnqueueFillImage)
356-
_PI_CL(piEnqueueMemBufferMap, clEnqueueMapBuffer)
357-
_PI_CL(piEnqueueMemUnmap, clEnqueueUnmapMemObject)
289+
// Platform
290+
_PI_CL(piPlatformsGet, OCL(piPlatformsGet))
291+
_PI_CL(piPlatformGetInfo, clGetPlatformInfo)
292+
// Device
293+
_PI_CL(piDevicesGet, OCL(piDevicesGet))
294+
_PI_CL(piDeviceGetInfo, clGetDeviceInfo)
295+
_PI_CL(piDevicePartition, clCreateSubDevices)
296+
_PI_CL(piDeviceRetain, clRetainDevice)
297+
_PI_CL(piDeviceRelease, clReleaseDevice)
298+
_PI_CL(piextDeviceSelectBinary, OCL(piextDeviceSelectBinary))
299+
_PI_CL(piextGetDeviceFunctionPointer, OCL(piextGetDeviceFunctionPointer))
300+
// Context
301+
_PI_CL(piContextCreate, clCreateContext)
302+
_PI_CL(piContextGetInfo, clGetContextInfo)
303+
_PI_CL(piContextRetain, clRetainContext)
304+
_PI_CL(piContextRelease, clReleaseContext)
305+
// Queue
306+
_PI_CL(piQueueCreate, OCL(piQueueCreate))
307+
_PI_CL(piQueueGetInfo, clGetCommandQueueInfo)
308+
_PI_CL(piQueueFinish, clFinish)
309+
_PI_CL(piQueueRetain, clRetainCommandQueue)
310+
_PI_CL(piQueueRelease, clReleaseCommandQueue)
311+
// Memory
312+
_PI_CL(piMemBufferCreate, clCreateBuffer)
313+
_PI_CL(piMemImageCreate, clCreateImage)
314+
_PI_CL(piMemGetInfo, clGetMemObjectInfo)
315+
_PI_CL(piMemImageGetInfo, clGetImageInfo)
316+
_PI_CL(piMemRetain, clRetainMemObject)
317+
_PI_CL(piMemRelease, clReleaseMemObject)
318+
_PI_CL(piMemBufferPartition, clCreateSubBuffer)
319+
// Program
320+
_PI_CL(piProgramCreate, OCL(piProgramCreate))
321+
_PI_CL(piclProgramCreateWithSource, clCreateProgramWithSource)
322+
_PI_CL(piclProgramCreateWithBinary, clCreateProgramWithBinary)
323+
_PI_CL(piProgramGetInfo, clGetProgramInfo)
324+
_PI_CL(piProgramCompile, clCompileProgram)
325+
_PI_CL(piProgramBuild, clBuildProgram)
326+
_PI_CL(piProgramLink, clLinkProgram)
327+
_PI_CL(piProgramGetBuildInfo, clGetProgramBuildInfo)
328+
_PI_CL(piProgramRetain, clRetainProgram)
329+
_PI_CL(piProgramRelease, clReleaseProgram)
330+
// Kernel
331+
_PI_CL(piKernelCreate, clCreateKernel)
332+
_PI_CL(piKernelSetArg, clSetKernelArg)
333+
_PI_CL(piKernelGetInfo, clGetKernelInfo)
334+
_PI_CL(piKernelGetGroupInfo, clGetKernelWorkGroupInfo)
335+
_PI_CL(piKernelGetSubGroupInfo, clGetKernelSubGroupInfo)
336+
_PI_CL(piKernelRetain, clRetainKernel)
337+
_PI_CL(piKernelRelease, clReleaseKernel)
338+
// Event
339+
_PI_CL(piEventCreate, clCreateUserEvent)
340+
_PI_CL(piEventGetInfo, clGetEventInfo)
341+
_PI_CL(piEventGetProfilingInfo, clGetEventProfilingInfo)
342+
_PI_CL(piEventsWait, clWaitForEvents)
343+
_PI_CL(piEventSetCallback, clSetEventCallback)
344+
_PI_CL(piEventSetStatus, clSetUserEventStatus)
345+
_PI_CL(piEventRetain, clRetainEvent)
346+
_PI_CL(piEventRelease, clReleaseEvent)
347+
// Sampler
348+
_PI_CL(piSamplerCreate, OCL(piSamplerCreate))
349+
_PI_CL(piSamplerGetInfo, clGetSamplerInfo)
350+
_PI_CL(piSamplerRetain, clRetainSampler)
351+
_PI_CL(piSamplerRelease, clReleaseSampler)
352+
// Queue commands
353+
_PI_CL(piEnqueueKernelLaunch, clEnqueueNDRangeKernel)
354+
_PI_CL(piEnqueueNativeKernel, clEnqueueNativeKernel)
355+
_PI_CL(piEnqueueEventsWait, clEnqueueMarkerWithWaitList)
356+
_PI_CL(piEnqueueMemBufferRead, clEnqueueReadBuffer)
357+
_PI_CL(piEnqueueMemBufferReadRect, clEnqueueReadBufferRect)
358+
_PI_CL(piEnqueueMemBufferWrite, clEnqueueWriteBuffer)
359+
_PI_CL(piEnqueueMemBufferWriteRect, clEnqueueWriteBufferRect)
360+
_PI_CL(piEnqueueMemBufferCopy, clEnqueueCopyBuffer)
361+
_PI_CL(piEnqueueMemBufferCopyRect, clEnqueueCopyBufferRect)
362+
_PI_CL(piEnqueueMemBufferFill, clEnqueueFillBuffer)
363+
_PI_CL(piEnqueueMemImageRead, clEnqueueReadImage)
364+
_PI_CL(piEnqueueMemImageWrite, clEnqueueWriteImage)
365+
_PI_CL(piEnqueueMemImageCopy, clEnqueueCopyImage)
366+
_PI_CL(piEnqueueMemImageFill, clEnqueueFillImage)
367+
_PI_CL(piEnqueueMemBufferMap, clEnqueueMapBuffer)
368+
_PI_CL(piEnqueueMemUnmap, clEnqueueUnmapMemObject)
369+
} FunctionTable;
370+
371+
void *initialize_pi_opencl(char *RetSuppVersion) {
372+
RetSuppVersion = strcpy((char *)malloc(strlen(SupportedVersion.c_str()) + 1),
373+
SupportedVersion.c_str());
374+
return &FunctionTable;
375+
}
358376

359377
#undef _PI_CL
360378
}

sycl/source/detail/pi.cpp

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88
#include <CL/sycl/detail/common.hpp>
99
#include <CL/sycl/detail/pi.hpp>
10+
#include <CL/sycl/detail/pi_offsets.h>
1011
#include <cstdarg>
1112
#include <iostream>
1213
#include <map>
@@ -48,6 +49,7 @@ bool useBackend(Backend TheBackend) {
4849

4950
// Definitions of the PI dispatch entries, they will be initialized
5051
// at their first use with piInitialize.
52+
// ::api are defined in pi.h as Functions.
5153
#define _PI_API(api) decltype(::api) *api = nullptr;
5254
#include <CL/sycl/detail/pi.def>
5355

@@ -68,21 +70,28 @@ void *loadPlugin(const std::string &PluginPath) {
6870
return loadOsLibrary(PluginPath);
6971
}
7072

73+
void *(*PluginInitFuncPtr)(char *);
74+
7175
// Binds all the PI Interface APIs to Plugin Library Function Addresses.
72-
// TODO: Remove the 'OclPtr' extension to PI_API.
73-
// TODO: Change the functionality such that a single getOsLibraryFuncAddress
74-
// call is done to get all Interface API mapping. The plugin interface also
75-
// needs to setup infrastructure to route PI_CALLs to the appropriate plugins.
76-
// Currently, we bind to a singe plugin.
76+
// TODO: The plugin interface needs to setup infrastructure to route PI_CALLs to
77+
// the appropriate plugins. Currently, we bind to a singe plugin.
7778
bool bindPlugin(void *Library) {
79+
decltype(PluginInitFuncPtr) InitializeFunction =
80+
(decltype(PluginInitFuncPtr))(
81+
getOsLibraryFuncAddress(Library, "initialize_pi_opencl"));
82+
char *SupportedVersion;
83+
// FuncTable is a list of all Interface Function pointers, where each
84+
// Interface Function is located at a predetermined offset.
85+
void *FuncTable = InitializeFunction(SupportedVersion);
86+
7887
#define STRINGIZE(x) #x
7988

89+
// At the predetermined "api"_Offset from the FunctionTable, the function
90+
// pointer for "api" is stored. So we dereference the location to get the
91+
// function pointer.
8092
#define _PI_API(api) \
81-
decltype(&api) api##_ptr = ((decltype(&api))( \
82-
getOsLibraryFuncAddress(Library, STRINGIZE(api##OclPtr)))); \
83-
if (!api##_ptr) \
84-
return false; \
85-
api = *api##_ptr;
93+
api = *((decltype(&api))((char *)FuncTable + (api##_Offset)));
94+
8695
#include <CL/sycl/detail/pi.def>
8796

8897
#undef STRINGIZE

0 commit comments

Comments
 (0)