According to Intel, dynamic linkage of device code is a work in progress for DPCPP. No immediate solution was found on the Khronos forum either.
The link provided by shs_sf contains an example where a const char* OpenCL kernel source is specified and compiled to run under SYCL. Interoperating this way requires linking to OpenCL, which makes it difficult to run the kernels on Nvidia devices.
#include<CL/sycl.hpp>
#include<iostream>
int main() {
constexpr size_t size = 16;
std::array<int, size> data;
for (int i = 0; i < size; i++) { data[i] = i; }
sycl::device dev(sycl::cpu_selector{});
sycl::context ctx=sycl::context(dev);
auto ocl_dev=sycl::get_native<cl::sycl::backend::opencl,sycl::device>(dev);
auto ocl_ctx=sycl::get_native<cl::sycl::backend::opencl,sycl::context>(ctx);
cl_int err = CL_SUCCESS;
cl_command_queue ocl_queue = clCreateCommandQueueWithProperties(ocl_ctx, ocl_dev,0,&err);
sycl::queue q=sycl::make_queue<sycl::backend::opencl>(ocl_queue,ctx);
cl_mem ocl_buf = clCreateBuffer(ocl_ctx,CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, size * sizeof(int), &data[0],&err);
sycl::buffer<int, 1> buffer =sycl::make_buffer<sycl::backend::opencl, int>(ocl_buf, ctx);
const char* kernelSource =
R"CLC(
kernel void add(global int* data) {
int index = get_global_id(0);
data[index] = data[index] + 1;
}
)CLC";
cl_program ocl_program = clCreateProgramWithSource(ocl_ctx,1,&kernelSource, nullptr, &err);
clBuildProgram(ocl_program, 1, &ocl_dev, nullptr, nullptr, nullptr);
cl_kernel ocl_kernel = clCreateKernel(ocl_program, "add", nullptr);
sycl::kernel add_kernel = sycl::make_kernel<sycl::backend::opencl>(ocl_kernel, ctx);
q.submit([&](sycl::handler& h){
auto data_acc =buffer.get_access<sycl::access_mode::read_write, sycl::target::device>(h);
h.set_args(data_acc);
h.parallel_for(size,add_kernel);
}).wait();
clEnqueueReadBuffer(ocl_queue, ocl_buf, CL_TRUE, 0, size*sizeof(int), &data[0], 0, NULL, NULL);
for (int i = 0; i < size; i++) {
if (data[i] != i + 1) { std::cout << "Results did not validate at index " << i << "!\n"; return -1; }
}
std::cout << "Success!\n";
return 0;
}
Since SYCL has been able to circumvent these issues by transpiling to nvptx, it would be nice to find a way within its standard to compile the kernels.