Skip to content

Commit 2c9ab05

Browse files
Fznamznonbader
authored andcommitted
[SYCL] Retain OpenCL kernel in SYCL kernel constructor
Also added check that passed SYCL context represents the same underlying OpenCL context associated with the OpenCL kernel object. Signed-off-by: Mariya Podchishchaeva <[email protected]>
1 parent 54e4ecb commit 2c9ab05

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

sycl/include/CL/sycl/detail/kernel_impl.hpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,16 @@ class kernel_impl {
3333
std::shared_ptr<program_impl> ProgramImpl,
3434
bool IsCreatedFromSource)
3535
: ClKernel(ClKernel), Context(SyclContext), ProgramImpl(ProgramImpl),
36-
IsCreatedFromSource(IsCreatedFromSource) {}
36+
IsCreatedFromSource(IsCreatedFromSource) {
37+
cl_context Context = nullptr;
38+
CHECK_OCL_CODE(clGetKernelInfo(ClKernel, CL_KERNEL_CONTEXT, sizeof(Context),
39+
&Context, nullptr));
40+
auto ContextImpl = detail::getSyclObjImpl(SyclContext);
41+
if (ContextImpl->getHandleRef() != Context)
42+
throw cl::sycl::invalid_parameter_error(
43+
"Input context must be the same as the context of cl_kernel");
44+
CHECK_OCL_CODE(clRetainKernel(ClKernel));
45+
}
3746

3847
// Host kernel constructor
3948
kernel_impl(const context &SyclContext,
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// RUN: %clang -std=c++11 -fsycl %s -o %t.out -lstdc++ -lOpenCL
2+
// RUN: %CPU_RUN_PLACEHOLDER %t.out
3+
// RUN: %GPU_RUN_PLACEHOLDER %t.out
4+
// RUN: %ACC_RUN_PLACEHOLDER %t.out
5+
6+
//==--------------- kernel_interop.cpp - SYCL kernel ocl interop test ------==//
7+
//
8+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
9+
// See https://llvm.org/LICENSE.txt for license information.
10+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
11+
//
12+
//===----------------------------------------------------------------------===//
13+
#include <CL/sycl.hpp>
14+
15+
#include <cassert>
16+
17+
using namespace cl::sycl;
18+
19+
// This test checks that SYCL kernel interoperabitily constructor is implemented
20+
// in accordance with SYCL spec:
21+
// - It throws an exception when passed SYCL context doesn't represent the same
22+
// underlying OpenCL context associated with passed cl_kernel
23+
// - It retains passed cl_kernel so releasing kernel won't produce errors.
24+
25+
int main() {
26+
queue Queue;
27+
if (!Queue.is_host()) {
28+
29+
context Context = Queue.get_context();
30+
31+
cl_context ClContext = Context.get();
32+
33+
const size_t CountSources = 1;
34+
const char *Sources[CountSources] = {
35+
"kernel void foo1(global float* Array, global int* Value) { *Array = "
36+
"42; *Value = 1; }\n",
37+
};
38+
39+
cl_int Err;
40+
cl_program ClProgram = clCreateProgramWithSource(ClContext, CountSources,
41+
Sources, nullptr, &Err);
42+
CHECK_OCL_CODE(Err);
43+
44+
Err = clBuildProgram(ClProgram, 0, nullptr, nullptr, nullptr, nullptr);
45+
CHECK_OCL_CODE(Err);
46+
47+
cl_kernel ClKernel = clCreateKernel(ClProgram, "foo1", &Err);
48+
CHECK_OCL_CODE(Err);
49+
50+
// Try to create kernel with another context
51+
bool Pass = false;
52+
queue Queue1;
53+
context Context1 = Queue1.get_context();
54+
try {
55+
kernel Kernel(ClKernel, Context1);
56+
} catch (cl::sycl::invalid_parameter_error e) {
57+
Pass = true;
58+
}
59+
assert(Pass);
60+
61+
kernel Kernel(ClKernel, Context);
62+
63+
64+
CHECK_OCL_CODE(clReleaseKernel(ClKernel));
65+
CHECK_OCL_CODE(clReleaseContext(ClContext));
66+
CHECK_OCL_CODE(clReleaseProgram(ClProgram));
67+
68+
}
69+
return 0;
70+
}

0 commit comments

Comments
 (0)