Skip to content

Commit 280b93c

Browse files
author
Ivan Karachun
authored
[SYCL] Minor host task corrections (#2145)
1. Fixed compilation error which appeared in case of usage get_native_mem method with accessor with host target. 2. Exceptions which raised in host task reported as async exceptions. 3. Fixed stable deadlock which appeared when reporting an async exception raised in a host task. Signed-off-by: Ivan Karachun <[email protected]>
1 parent 5816745 commit 280b93c

File tree

7 files changed

+84
-19
lines changed

7 files changed

+84
-19
lines changed

sycl/include/CL/sycl/backend/cuda.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,12 @@ struct interop<backend::cuda, accessor<DataT, Dimensions, AccessMode,
5050
using type = CUdeviceptr;
5151
};
5252

53+
template <typename DataT, int Dimensions, access::mode AccessMode>
54+
struct interop<backend::cuda, accessor<DataT, Dimensions, AccessMode,
55+
access::target::constant_buffer,
56+
access::placeholder::false_t>> {
57+
using type = CUdeviceptr;
58+
};
59+
5360
} // namespace sycl
5461
} // namespace cl

sycl/include/CL/sycl/backend/level_zero.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ struct interop<backend::level0, accessor<DataT, Dimensions, AccessMode,
3737
using type = char *;
3838
};
3939

40+
template <typename DataT, int Dimensions, access::mode AccessMode>
41+
struct interop<backend::level0, accessor<DataT, Dimensions, AccessMode,
42+
access::target::constant_buffer,
43+
access::placeholder::false_t>> {
44+
using type = char *;
45+
};
46+
4047
namespace level0 {
4148

4249
// Implementation of various "make" functions resides in libsycl.so

sycl/include/CL/sycl/backend/opencl.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ struct interop<backend::opencl, accessor<DataT, Dimensions, AccessMode,
4343
using type = cl_mem;
4444
};
4545

46+
template <typename DataT, int Dimensions, access::mode AccessMode>
47+
struct interop<backend::opencl, accessor<DataT, Dimensions, AccessMode,
48+
access::target::constant_buffer,
49+
access::placeholder::false_t>> {
50+
using type = cl_mem;
51+
};
52+
4653
namespace opencl {
4754

4855
// Implementation of various "make" functions resides in SYCL RT because

sycl/include/CL/sycl/interop_handle.hpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ class interop_handle {
4545
template <backend BackendName = backend::opencl, typename DataT, int Dims,
4646
access::mode Mode, access::target Target, access::placeholder IsPlh>
4747
typename std::enable_if<
48-
Target != access::target::host_buffer,
48+
Target == access::target::global_buffer ||
49+
Target == access::target::constant_buffer,
4950
typename interop<BackendName,
5051
accessor<DataT, Dims, Mode, Target, IsPlh>>::type>::type
5152
get_native_mem(const accessor<DataT, Dims, Mode, Target, IsPlh> &Acc) const {
@@ -63,12 +64,14 @@ class interop_handle {
6364
template <backend BackendName = backend::opencl, typename DataT, int Dims,
6465
access::mode Mode, access::target Target, access::placeholder IsPlh>
6566
typename std::enable_if<
66-
Target == access::target::host_buffer,
67-
typename interop<BackendName,
68-
accessor<DataT, Dims, Mode, Target, IsPlh>>::type>::type
67+
!(Target == access::target::global_buffer ||
68+
Target == access::target::constant_buffer),
69+
typename interop<BackendName, accessor<DataT, Dims, Mode,
70+
access::target::global_buffer,
71+
IsPlh>>::type>::type
6972
get_native_mem(const accessor<DataT, Dims, Mode, Target, IsPlh> &) const {
70-
throw invalid_object_error("Getting memory object out of host accessor is "
71-
"not allowed",
73+
throw invalid_object_error("Getting memory object out of accessor for "
74+
"specified target is not allowed",
7275
PI_INVALID_MEM_OBJECT);
7376
}
7477

sycl/source/detail/queue_impl.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,18 @@ void queue_impl::wait(const detail::code_location &CodeLoc) {
192192
TelemetryEvent = instrumentationProlog(CodeLoc, Name, StreamID, IId);
193193
#endif
194194

195-
std::lock_guard<mutex_class> Guard(MMutex);
196-
for (std::weak_ptr<event_impl> &EventImplWeakPtr : MEvents) {
197-
if (std::shared_ptr<event_impl> EventImplPtr = EventImplWeakPtr.lock())
198-
EventImplPtr->wait(EventImplPtr);
195+
std::vector<std::shared_ptr<event_impl>> Events;
196+
{
197+
std::lock_guard<mutex_class> Guard(MMutex);
198+
for (std::weak_ptr<event_impl> &EventImplWeakPtr : MEvents)
199+
if (std::shared_ptr<event_impl> EventImplPtr = EventImplWeakPtr.lock())
200+
Events.push_back(EventImplPtr);
201+
}
202+
203+
for (std::shared_ptr<event_impl> &Event : Events) {
204+
Event->wait(Event);
199205
}
206+
200207
for (event &Event : MUSMEvents) {
201208
Event.wait();
202209
}

sycl/source/detail/scheduler/commands.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -201,15 +201,19 @@ class DispatchHostTask {
201201

202202
CGHostTask &HostTask = static_cast<CGHostTask &>(MThisCmd->getCG());
203203

204-
// we're ready to call the user-defined lambda now
205-
if (HostTask.MHostTask->isInteropTask()) {
206-
interop_handle IH{MReqToMem, HostTask.MQueue,
207-
getSyclObjImpl(HostTask.MQueue->get_device()),
208-
HostTask.MQueue->getContextImplPtr()};
209-
210-
HostTask.MHostTask->call(IH);
211-
} else
212-
HostTask.MHostTask->call();
204+
try {
205+
// we're ready to call the user-defined lambda now
206+
if (HostTask.MHostTask->isInteropTask()) {
207+
interop_handle IH{MReqToMem, HostTask.MQueue,
208+
getSyclObjImpl(HostTask.MQueue->get_device()),
209+
HostTask.MQueue->getContextImplPtr()};
210+
211+
HostTask.MHostTask->call(IH);
212+
} else
213+
HostTask.MHostTask->call();
214+
} catch (...) {
215+
HostTask.MQueue->reportAsyncException(std::current_exception());
216+
}
213217

214218
HostTask.MHostTask.reset();
215219

sycl/test/host-interop-task/interop-task.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,11 +219,41 @@ void test5() {
219219
}
220220
}
221221

222+
// The test checks that an exception which is thrown from host_task body
223+
// is reported as asynchronous.
224+
void test6() {
225+
queue Queue([](sycl::exception_list ExceptionList) {
226+
if (ExceptionList.size() != 1) {
227+
std::cerr << "Should be one exception in exception list" << std::endl;
228+
std::abort();
229+
}
230+
std::rethrow_exception(*ExceptionList.begin());
231+
});
232+
233+
try {
234+
size_t size = 1;
235+
buffer<int, 1> Buf{size};
236+
Queue.submit([&](sycl::handler &CGH) {
237+
auto acc = Buf.get_access<mode::write, target::host_buffer>(CGH);
238+
CGH.codeplay_host_task(
239+
[=](interop_handle IH) { (void)IH.get_native_mem(acc); });
240+
});
241+
Queue.wait_and_throw();
242+
assert(!"Expected exception was not caught");
243+
} catch (sycl::exception &ExpectedException) {
244+
assert(std::string(ExpectedException.what())
245+
.find("memory object out of accessor for specified target "
246+
"is not allowed") != std::string::npos &&
247+
"Unexpected error was caught!");
248+
}
249+
}
250+
222251
int main() {
223252
test1();
224253
test2();
225254
test3();
226255
test4();
227256
test5();
257+
test6();
228258
return 0;
229259
}

0 commit comments

Comments
 (0)