Skip to content

Commit 5e7cbef

Browse files
authored
[SYCL] Fix get() method for non-opencl backends (#3070)
Before this patch, if you use non-opencl backend, then get() method returns casted wrapper of the native handle and SYCL user can’t use it in his own code. As the user can't release the returned object, it used to lead to a memory leak. Since, get() method is applicable only for OpenCL backend, this patch adds an exception for cases when get() method is called for non-opencl backend. Signed-off-by: Alexander Flegontov <[email protected]>
1 parent b489479 commit 5e7cbef

File tree

11 files changed

+61
-49
lines changed

11 files changed

+61
-49
lines changed

sycl/source/context.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,14 @@ context::context(const vector_class<device> &DeviceList,
6363
PropList);
6464
else {
6565
const device &NonHostDevice = *NonHostDeviceIter;
66-
const auto &NonHostPlatform = NonHostDevice.get_platform().get();
66+
const auto &NonHostPlatform =
67+
detail::getSyclObjImpl(NonHostDevice.get_platform())->getHandleRef();
6768
if (std::any_of(DeviceList.begin(), DeviceList.end(),
6869
[&](const device &CurrentDevice) {
69-
return (CurrentDevice.is_host() ||
70-
(CurrentDevice.get_platform().get() !=
71-
NonHostPlatform));
70+
return (
71+
CurrentDevice.is_host() ||
72+
(detail::getSyclObjImpl(CurrentDevice.get_platform())
73+
->getHandleRef() != NonHostPlatform));
7274
}))
7375
throw invalid_parameter_error(
7476
"Can't add devices across platforms to a single context.",

sycl/source/detail/context_impl.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,14 @@ context_impl::context_impl(RT::PiContext PiContext, async_handler AsyncHandler,
101101
}
102102

103103
cl_context context_impl::get() const {
104-
if (!MHostContext) {
105-
// TODO catch an exception and put it to list of asynchronous exceptions
106-
getPlugin().call<PiApiKind::piContextRetain>(MContext);
107-
return pi::cast<cl_context>(MContext);
104+
if (MHostContext || getPlugin().getBackend() != cl::sycl::backend::opencl) {
105+
throw invalid_object_error(
106+
"This instance of context doesn't support OpenCL interoperability.",
107+
PI_INVALID_CONTEXT);
108108
}
109-
throw invalid_object_error(
110-
"This instance of context doesn't support OpenCL interoperability.",
111-
PI_INVALID_CONTEXT);
109+
// TODO catch an exception and put it to list of asynchronous exceptions
110+
getPlugin().call<PiApiKind::piContextRetain>(MContext);
111+
return pi::cast<cl_context>(MContext);
112112
}
113113

114114
bool context_impl::is_host() const { return MHostContext; }

sycl/source/detail/device_impl.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,13 @@ bool device_impl::is_affinity_supported(
8989
}
9090

9191
cl_device_id device_impl::get() const {
92-
if (MIsHostDevice)
93-
throw invalid_object_error("This instance of device is a host instance",
94-
PI_INVALID_DEVICE);
95-
96-
const detail::plugin &Plugin = getPlugin();
97-
92+
if (MIsHostDevice || getPlugin().getBackend() != cl::sycl::backend::opencl) {
93+
throw invalid_object_error(
94+
"This instance of device doesn't support OpenCL interoperability.",
95+
PI_INVALID_DEVICE);
96+
}
9897
// TODO catch an exception and put it to list of asynchronous exceptions
99-
Plugin.call<PiApiKind::piDeviceRetain>(MDevice);
98+
getPlugin().call<PiApiKind::piDeviceRetain>(MDevice);
10099
return pi::cast<cl_device_id>(getNative());
101100
}
102101

sycl/source/detail/event_impl.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,14 @@ extern xpti::trace_event_data_t *GSYCLGraphEvent;
3535
bool event_impl::is_host() const { return MHostEvent || !MOpenCLInterop; }
3636

3737
cl_event event_impl::get() const {
38-
if (MOpenCLInterop) {
39-
getPlugin().call<PiApiKind::piEventRetain>(MEvent);
40-
return pi::cast<cl_event>(MEvent);
38+
if (!MOpenCLInterop ||
39+
getPlugin().getBackend() != cl::sycl::backend::opencl) {
40+
throw invalid_object_error(
41+
"This instance of event doesn't support OpenCL interoperability.",
42+
PI_INVALID_EVENT);
4143
}
42-
throw invalid_object_error(
43-
"This instance of event doesn't support OpenCL interoperability.",
44-
PI_INVALID_EVENT);
44+
getPlugin().call<PiApiKind::piEventRetain>(MEvent);
45+
return pi::cast<cl_event>(MEvent);
4546
}
4647

4748
event_impl::~event_impl() {

sycl/source/detail/kernel_impl.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,11 @@ class kernel_impl {
8080
///
8181
/// \return a valid cl_kernel instance
8282
cl_kernel get() const {
83-
if (is_host())
84-
throw invalid_object_error("This instance of kernel is a host instance",
85-
PI_INVALID_KERNEL);
83+
if (is_host() || getPlugin().getBackend() != cl::sycl::backend::opencl) {
84+
throw invalid_object_error(
85+
"This instance of kernel doesn't support OpenCL interoperability.",
86+
PI_INVALID_KERNEL);
87+
}
8688
getPlugin().call<PiApiKind::piKernelRetain>(MKernel);
8789
return pi::cast<cl_kernel>(MKernel);
8890
}

sycl/source/detail/platform_impl.hpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ class platform_impl {
7676

7777
/// \return an instance of OpenCL cl_platform_id.
7878
cl_platform_id get() const {
79-
if (is_host())
80-
throw invalid_object_error("This instance of platform is a host instance",
81-
PI_INVALID_PLATFORM);
82-
79+
if (is_host() || getPlugin().getBackend() != cl::sycl::backend::opencl) {
80+
throw invalid_object_error(
81+
"This instance of platform doesn't support OpenCL interoperability.",
82+
PI_INVALID_PLATFORM);
83+
}
8384
return pi::cast<cl_platform_id>(MPlatform);
8485
}
8586

sycl/source/detail/program_impl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,12 @@ program_impl::~program_impl() {
212212

213213
cl_program program_impl::get() const {
214214
throw_if_state_is(program_state::none);
215-
if (is_host()) {
216-
throw invalid_object_error("This instance of program is a host instance",
217-
PI_INVALID_PROGRAM);
215+
if (is_host() || getPlugin().getBackend() != cl::sycl::backend::opencl) {
216+
throw invalid_object_error(
217+
"This instance of program doesn't support OpenCL interoperability.",
218+
PI_INVALID_PROGRAM);
218219
}
219-
const detail::plugin &Plugin = getPlugin();
220-
Plugin.call<PiApiKind::piProgramRetain>(MProgram);
220+
getPlugin().call<PiApiKind::piProgramRetain>(MProgram);
221221
return pi::cast<cl_program>(MProgram);
222222
}
223223

sycl/source/detail/queue_impl.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,13 +126,13 @@ class queue_impl {
126126

127127
/// \return an OpenCL interoperability queue handle.
128128
cl_command_queue get() {
129-
if (!MHostQueue) {
130-
getPlugin().call<PiApiKind::piQueueRetain>(MQueues[0]);
131-
return pi::cast<cl_command_queue>(MQueues[0]);
129+
if (MHostQueue || getPlugin().getBackend() != cl::sycl::backend::opencl) {
130+
throw invalid_object_error(
131+
"This instance of queue doesn't support OpenCL interoperability",
132+
PI_INVALID_QUEUE);
132133
}
133-
throw invalid_object_error(
134-
"This instance of queue doesn't support OpenCL interoperability",
135-
PI_INVALID_QUEUE);
134+
getPlugin().call<PiApiKind::piQueueRetain>(MQueues[0]);
135+
return pi::cast<cl_command_queue>(MQueues[0]);
136136
}
137137

138138
/// \return an associated SYCL context.

sycl/source/detail/scheduler/commands.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2010,8 +2010,6 @@ cl_int ExecCGCommand::enqueueImp() {
20102010
ExecInterop->MInteropTask->call(InteropHandler);
20112011
Plugin.call<PiApiKind::piEnqueueEventsWait>(MQueue->getHandleRef(), 0,
20122012
nullptr, &Event);
2013-
Plugin.call<PiApiKind::piQueueRelease>(
2014-
reinterpret_cast<pi_queue>(MQueue->get()));
20152013

20162014
return CL_SUCCESS;
20172015
}

sycl/test/basic_tests/platform.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,11 @@ int main() {
2020
for (const auto &plt : platform::get_platforms()) {
2121
std::cout << "Platform " << i++
2222
<< " is available: " << ((plt.is_host()) ? "host: " : "OpenCL: ")
23-
<< std::hex << ((plt.is_host()) ? nullptr : plt.get())
23+
<< std::hex
24+
<< ((plt.is_host() ||
25+
plt.get_backend() != cl::sycl::backend::opencl)
26+
? nullptr
27+
: plt.get())
2428
<< std::endl;
2529
}
2630

@@ -34,7 +38,8 @@ int main() {
3438
platform MovedPlatform(std::move(Platform));
3539
assert(hash == hash_class<platform>()(MovedPlatform));
3640
assert(platformA.is_host() == MovedPlatform.is_host());
37-
if (!platformA.is_host()) {
41+
if (!platformA.is_host() &&
42+
platformA.get_backend() == cl::sycl::backend::opencl) {
3843
assert(MovedPlatform.get() != nullptr);
3944
}
4045
}
@@ -46,7 +51,8 @@ int main() {
4651
WillMovedPlatform = std::move(Platform);
4752
assert(hash == hash_class<platform>()(WillMovedPlatform));
4853
assert(platformA.is_host() == WillMovedPlatform.is_host());
49-
if (!platformA.is_host()) {
54+
if (!platformA.is_host() &&
55+
platformA.get_backend() == cl::sycl::backend::opencl) {
5056
assert(WillMovedPlatform.get() != nullptr);
5157
}
5258
}

0 commit comments

Comments
 (0)