Skip to content

Commit 2a45f51

Browse files
alexbatashevbader
authored andcommitted
[SYCL] Support cl_khr_il_program extension (#315)
clCreateProgramWithIL is used by SYCL, and this function is only available with OpenCL 2.1 or later. For OpenCL < 2.1 there is an extension cl_khr_il_program which makes the same function available under a different name: clCreateProgramWithILKHR. Make SYCL runtime check for its availability and use it. Signed-off-by: Alexander Batashev [email protected]
1 parent 74527fc commit 2a45f51

File tree

2 files changed

+88
-4
lines changed

2 files changed

+88
-4
lines changed

sycl/source/detail/pi_opencl.cpp

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
#include <CL/sycl/detail/pi.hpp>
98
#include "CL/opencl.h"
9+
#include <CL/sycl/detail/pi.hpp>
10+
#include <cassert>
11+
#include <cstring>
1012

1113
namespace cl {
1214
namespace sycl {
@@ -79,6 +81,87 @@ pi_result OCL(piextDeviceSelectBinary)(
7981
return PI_SUCCESS;
8082
}
8183

84+
pi_program OCL(piProgramCreate)(pi_context context, const void *il,
85+
size_t length, pi_result *err) {
86+
87+
size_t deviceCount;
88+
cl_program resProgram;
89+
90+
cl_int ret_err = clGetContextInfo(pi_cast<cl_context>(context),
91+
CL_CONTEXT_DEVICES, 0, NULL, &deviceCount);
92+
93+
std::vector<cl_device_id> devicesInCtx;
94+
devicesInCtx.reserve(deviceCount);
95+
96+
ret_err = clGetContextInfo(pi_cast<cl_context>(context), CL_CONTEXT_DEVICES,
97+
deviceCount * sizeof(cl_device_id),
98+
devicesInCtx.data(), NULL);
99+
100+
if (ret_err != CL_SUCCESS || deviceCount < 1) {
101+
if (err != nullptr)
102+
*err = pi_cast<pi_result>(CL_INVALID_CONTEXT);
103+
return pi_cast<pi_program>(resProgram);
104+
}
105+
106+
cl_platform_id curPlatform;
107+
ret_err = clGetDeviceInfo(devicesInCtx[0], CL_DEVICE_PLATFORM,
108+
sizeof(cl_platform_id), &curPlatform, NULL);
109+
110+
if (ret_err != CL_SUCCESS) {
111+
if (err != nullptr)
112+
*err = pi_cast<pi_result>(CL_INVALID_CONTEXT);
113+
return pi_cast<pi_program>(resProgram);
114+
}
115+
116+
size_t devVerSize;
117+
ret_err =
118+
clGetPlatformInfo(curPlatform, CL_PLATFORM_VERSION, 0, NULL, &devVerSize);
119+
std::string devVer(devVerSize, '\0');
120+
ret_err = clGetPlatformInfo(curPlatform, CL_PLATFORM_VERSION, devVerSize,
121+
&devVer.front(), NULL);
122+
123+
if (ret_err != CL_SUCCESS) {
124+
if (err != nullptr)
125+
*err = pi_cast<pi_result>(CL_INVALID_CONTEXT);
126+
return pi_cast<pi_program>(resProgram);
127+
}
128+
129+
if (devVer.find("OpenCL 1.0") == std::string::npos &&
130+
devVer.find("OpenCL 1.1") == std::string::npos &&
131+
devVer.find("OpenCL 1.2") == std::string::npos &&
132+
devVer.find("OpenCL 2.0") == std::string::npos) {
133+
resProgram = clCreateProgramWithIL(pi_cast<cl_context>(context), il, length,
134+
pi_cast<cl_int *>(err));
135+
return pi_cast<pi_program>(resProgram);
136+
}
137+
138+
size_t extSize;
139+
ret_err = clGetPlatformInfo(curPlatform, CL_PLATFORM_EXTENSIONS, 0, NULL,
140+
&extSize);
141+
std::string extStr(extSize, '\0');
142+
ret_err = clGetPlatformInfo(curPlatform, CL_PLATFORM_EXTENSIONS,
143+
extSize, &extStr.front(), NULL);
144+
145+
if (ret_err != CL_SUCCESS ||
146+
extStr.find("cl_khr_il_program") == std::string::npos) {
147+
if (err != nullptr)
148+
*err = pi_cast<pi_result>(CL_INVALID_CONTEXT);
149+
return pi_cast<pi_program>(resProgram);
150+
}
151+
152+
using apiFuncT =
153+
cl_program(CL_API_CALL *)(cl_context, const void *, size_t, cl_int *);
154+
apiFuncT funcPtr =
155+
reinterpret_cast<apiFuncT>(clGetExtensionFunctionAddressForPlatform(
156+
curPlatform, "clCreateProgramWithILKHR"));
157+
158+
assert(funcPtr != nullptr);
159+
resProgram = funcPtr(pi_cast<cl_context>(context), il, length,
160+
pi_cast<cl_int *>(err));
161+
162+
return pi_cast<pi_program>(resProgram);
163+
}
164+
82165
// TODO: implement portable call forwarding (ifunc is a GNU extension).
83166
// TODO: reuse same PI -> OCL mapping in pi_opencl.hpp, or maybe just
84167
// wait until that one is completely removed.
@@ -116,7 +199,6 @@ _PI_CL(piMemGetInfo, clGetMemObjectInfo)
116199
_PI_CL(piMemRetain, clRetainMemObject)
117200
_PI_CL(piMemRelease, clReleaseMemObject)
118201
// Program
119-
_PI_CL(piProgramCreate, clCreateProgramWithIL)
120202
_PI_CL(piclProgramCreateWithSource, clCreateProgramWithSource)
121203
_PI_CL(piclProgramCreateWithBinary, clCreateProgramWithBinary)
122204
_PI_CL(piProgramGetInfo, clGetProgramInfo)

sycl/source/detail/program_manager/program_manager.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,10 @@ static RT::PiProgram createSpirvProgram(const RT::PiContext Context,
7979
size_t DataLen) {
8080
RT::PiResult Err = PI_SUCCESS;
8181
RT::PiProgram Program;
82-
PI_CALL((Program = RT::piProgramCreate(
83-
Context, Data, DataLen, &Err), Err));
82+
PI_CALL((Program = pi_cast<cl_program>(
83+
pi::piProgramCreate(pi_cast<pi_context>(Context), Data, DataLen,
84+
pi_cast<pi_result *>(&Err))),
85+
Err));
8486
return Program;
8587
}
8688

0 commit comments

Comments
 (0)