Skip to content

Commit 74369c8

Browse files
authored
[SYCL][CUDA] Add experimental cuda interop with event (#6288)
This PR is adds part of the CUDA-backend spec interop proposed in KhronosGroup/SYCL-Docs#197. The changes work with the CUDA CTS interop checks KhronosGroup/SYCL-CTS#336. This PR just adds the event interop. llvm-test-suite: intel/llvm-test-suite#1053
1 parent c73f0d5 commit 74369c8

File tree

5 files changed

+64
-8
lines changed

5 files changed

+64
-8
lines changed

sycl/include/sycl/ext/oneapi/experimental/backend/backend_traits_cuda.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ template <> struct InteropFeatureSupportMap<backend::ext_oneapi_cuda> {
132132
static constexpr bool MakeDevice = true;
133133
static constexpr bool MakeContext = true;
134134
static constexpr bool MakeQueue = true;
135-
static constexpr bool MakeEvent = false;
135+
static constexpr bool MakeEvent = true;
136136
static constexpr bool MakeBuffer = false;
137137
static constexpr bool MakeKernel = false;
138138
static constexpr bool MakeKernelBundle = false;

sycl/include/sycl/ext/oneapi/experimental/backend/cuda.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ inline __SYCL_EXPORT device make_device(pi_native_handle NativeHandle) {
2424
return sycl::detail::make_device(NativeHandle, backend::ext_oneapi_cuda);
2525
}
2626

27+
// Implementation of cuda::has_native_event
28+
inline __SYCL_EXPORT bool has_native_event(event sycl_event) {
29+
if (sycl_event.get_backend() == backend::ext_oneapi_cuda)
30+
return get_native<backend::ext_oneapi_cuda>(sycl_event) != nullptr;
31+
32+
return false;
33+
}
34+
2735
} // namespace cuda
2836
} // namespace oneapi
2937
} // namespace ext
@@ -71,6 +79,16 @@ inline device make_device<backend::ext_oneapi_cuda>(
7179
return ext::oneapi::cuda::make_device(NativeHandle);
7280
}
7381

82+
// CUDA event specialization
83+
template <>
84+
inline event make_event<backend::ext_oneapi_cuda>(
85+
const backend_input_t<backend::ext_oneapi_cuda, event> &BackendObject,
86+
const context &TargetContext) {
87+
return detail::make_event(detail::pi::cast<pi_native_handle>(BackendObject),
88+
TargetContext, true,
89+
/*Backend*/ backend::ext_oneapi_cuda);
90+
}
91+
7492
// CUDA queue specialization
7593
template <>
7694
inline queue make_queue<backend::ext_oneapi_cuda>(

sycl/plugins/cuda/pi_cuda.cpp

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -450,8 +450,8 @@ CUstream _pi_queue::get_next_transfer_stream() {
450450

451451
_pi_event::_pi_event(pi_command_type type, pi_context context, pi_queue queue,
452452
CUstream stream, pi_uint32 stream_token)
453-
: commandType_{type}, refCount_{1}, hasBeenWaitedOn_{false},
454-
isRecorded_{false}, isStarted_{false},
453+
: commandType_{type}, refCount_{1}, has_ownership_{true},
454+
hasBeenWaitedOn_{false}, isRecorded_{false}, isStarted_{false},
455455
streamToken_{stream_token}, evEnd_{nullptr}, evStart_{nullptr},
456456
evQueued_{nullptr}, queue_{queue}, stream_{stream}, context_{context} {
457457

@@ -471,6 +471,13 @@ _pi_event::_pi_event(pi_command_type type, pi_context context, pi_queue queue,
471471
cuda_piContextRetain(context_);
472472
}
473473

474+
_pi_event::_pi_event(pi_context context, CUevent eventNative)
475+
: commandType_{PI_COMMAND_TYPE_USER}, refCount_{1}, has_ownership_{false},
476+
hasBeenWaitedOn_{false}, isRecorded_{false}, isStarted_{false},
477+
streamToken_{std::numeric_limits<pi_uint32>::max()}, evEnd_{eventNative},
478+
evStart_{nullptr}, evQueued_{nullptr}, queue_{nullptr}, context_{
479+
context} {}
480+
474481
_pi_event::~_pi_event() {
475482
if (queue_ != nullptr) {
476483
cuda_piQueueRelease(queue_);
@@ -583,7 +590,11 @@ pi_result _pi_event::wait() {
583590
}
584591

585592
pi_result _pi_event::release() {
593+
if (!backend_has_ownership())
594+
return PI_SUCCESS;
595+
586596
assert(queue_ != nullptr);
597+
587598
PI_CHECK_ERROR(cuEventDestroy(evEnd_));
588599

589600
if (queue_->properties_ & PI_QUEUE_PROFILING_ENABLE) {
@@ -3910,11 +3921,19 @@ pi_result cuda_piextEventGetNativeHandle(pi_event event,
39103921
/// \param[out] event Set to the PI event object created from native handle.
39113922
///
39123923
/// \return TBD
3913-
pi_result cuda_piextEventCreateWithNativeHandle(pi_native_handle, pi_context,
3914-
bool, pi_event *) {
3915-
cl::sycl::detail::pi::die(
3916-
"Creation of PI event from native handle not implemented");
3917-
return {};
3924+
pi_result cuda_piextEventCreateWithNativeHandle(pi_native_handle nativeHandle,
3925+
pi_context context,
3926+
bool ownNativeHandle,
3927+
pi_event *event) {
3928+
(void)ownNativeHandle;
3929+
assert(!ownNativeHandle);
3930+
3931+
std::unique_ptr<_pi_event> event_ptr{nullptr};
3932+
3933+
*event = _pi_event::make_with_native(context,
3934+
reinterpret_cast<CUevent>(nativeHandle));
3935+
3936+
return PI_SUCCESS;
39183937
}
39193938

39203939
/// Creates a PI sampler object

sycl/plugins/cuda/pi_cuda.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,8 @@ struct _pi_event {
635635

636636
pi_uint32 get_event_id() const noexcept { return eventId_; }
637637

638+
bool backend_has_ownership() const noexcept { return has_ownership_; }
639+
638640
// Returns the counter time when the associated command(s) were enqueued
639641
//
640642
pi_uint64 get_queued_time() const;
@@ -655,6 +657,10 @@ struct _pi_event {
655657
stream_token);
656658
}
657659

660+
static pi_event make_with_native(pi_context context, CUevent eventNative) {
661+
return new _pi_event(context, eventNative);
662+
}
663+
658664
pi_result release();
659665

660666
~_pi_event();
@@ -665,10 +671,16 @@ struct _pi_event {
665671
_pi_event(pi_command_type type, pi_context context, pi_queue queue,
666672
CUstream stream, pi_uint32 stream_token);
667673

674+
// This constructor is private to force programmers to use the
675+
// make_with_native for event introp
676+
_pi_event(pi_context context, CUevent eventNative);
677+
668678
pi_command_type commandType_; // The type of command associated with event.
669679

670680
std::atomic_uint32_t refCount_; // Event reference count.
671681

682+
bool has_ownership_; // Signifies if event owns the native type.
683+
672684
bool hasBeenWaitedOn_; // Signifies whether the event has been waited
673685
// on through a call to wait(), which implies
674686
// that it has completed.

sycl/test/basic_tests/interop-cuda-experimental.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ int main() {
2828
device Device;
2929
context Context(Device);
3030
queue Queue(Device);
31+
event Event;
3132

3233
// 4.5.1.1 For each SYCL runtime class T which supports SYCL application
3334
// interoperability with the SYCL backend, a specialization of return_type
@@ -40,6 +41,7 @@ int main() {
4041

4142
backend_traits<backend::ext_oneapi_cuda>::return_type<device> cu_device;
4243
backend_traits<backend::ext_oneapi_cuda>::return_type<context> cu_context;
44+
backend_traits<backend::ext_oneapi_cuda>::return_type<event> cu_event;
4345
backend_traits<backend::ext_oneapi_cuda>::return_type<queue> cu_queue;
4446

4547
// 4.5.1.2 For each SYCL runtime class T which supports SYCL application
@@ -51,6 +53,7 @@ int main() {
5153

5254
cu_device = get_native<backend::ext_oneapi_cuda>(Device);
5355
cu_context = get_native<backend::ext_oneapi_cuda>(Context);
56+
cu_event = get_native<backend::ext_oneapi_cuda>(Event);
5457
cu_queue = get_native<backend::ext_oneapi_cuda>(Queue);
5558

5659
// Check deprecated
@@ -62,6 +65,9 @@ int main() {
6265
cu_context = Context.get_native<backend::ext_oneapi_cuda>();
6366
// expected-warning@+2 {{'get_native' is deprecated: Use SYCL 2020 sycl::get_native free function}}
6467
// expected-warning@+1 {{'get_native<sycl::backend::ext_oneapi_cuda>' is deprecated: Use SYCL 2020 sycl::get_native free function}}
68+
cu_event = Event.get_native<backend::ext_oneapi_cuda>();
69+
// expected-warning@+2 {{'get_native' is deprecated: Use SYCL 2020 sycl::get_native free function}}
70+
// expected-warning@+1 {{'get_native<sycl::backend::ext_oneapi_cuda>' is deprecated: Use SYCL 2020 sycl::get_native free function}}
6571
cu_queue = Queue.get_native<backend::ext_oneapi_cuda>();
6672

6773
// 4.5.1.1 For each SYCL runtime class T which supports SYCL application
@@ -89,6 +95,7 @@ int main() {
8995
cu_context[0]};
9096
context InteropContext =
9197
make_context<backend::ext_oneapi_cuda>(InteropContextInput);
98+
event InteropEvent = make_event<backend::ext_oneapi_cuda>(cu_event, Context);
9299

93100
queue InteropQueue = make_queue<backend::ext_oneapi_cuda>(cu_queue, Context);
94101

0 commit comments

Comments
 (0)