Skip to content

Commit 25a76c5

Browse files
author
Steffen Larsen
committed
[SYCL][PI][CUDA] Implements get_native interoperability
Implements get_native for CUDA allowing queries for native handles on SYCL objects; queue, event, context, and device. Signed-off-by: Steffen Larsen <[email protected]>
1 parent 86acff3 commit 25a76c5

33 files changed

+428
-85
lines changed

sycl/include/CL/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <CL/sycl/accessor.hpp>
1212
#include <CL/sycl/atomic.hpp>
13+
#include <CL/sycl/backend.hpp>
1314
#include <CL/sycl/buffer.hpp>
1415
#include <CL/sycl/builtins.hpp>
1516
#include <CL/sycl/context.hpp>

sycl/include/CL/sycl/backend.hpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//==---------------- backend.hpp - SYCL PI backends ------------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <CL/sycl/accessor.hpp>
12+
#include <CL/sycl/backend_types.hpp>
13+
14+
__SYCL_INLINE_NAMESPACE(cl) {
15+
namespace sycl {
16+
17+
template <backend BackendName, class SyclObjectT>
18+
auto get_native(const SyclObjectT &Obj) ->
19+
typename interop<BackendName, SyclObjectT>::type {
20+
return Obj.template get_native<BackendName>();
21+
}
22+
23+
// Native handle of an accessor should be accessed through interop_handler
24+
template <backend BackendName, typename DataT, int Dimensions,
25+
access::mode AccessMode, access::target AccessTarget,
26+
access::placeholder IsPlaceholder>
27+
auto get_native(const accessor<DataT, Dimensions, AccessMode, AccessTarget,
28+
IsPlaceholder> &Obj) ->
29+
typename interop<BackendName, accessor<DataT, Dimensions, AccessMode,
30+
AccessTarget, IsPlaceholder>>::type =
31+
delete;
32+
33+
} // namespace sycl
34+
} // __SYCL_INLINE_NAMESPACE(cl)

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

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
//==---------------- cuda.hpp - SYCL CUDA backend --------------------------==//
23
//
34
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
@@ -6,29 +7,45 @@
67
//
78
//===----------------------------------------------------------------------===//
89

10+
#pragma once
11+
12+
#include <CL/sycl/accessor.hpp>
13+
#include <CL/sycl/backend_types.hpp>
14+
#include <CL/sycl/context.hpp>
915
#include <CL/sycl/detail/defines.hpp>
16+
#include <CL/sycl/device.hpp>
17+
#include <CL/sycl/event.hpp>
18+
#include <CL/sycl/queue.hpp>
19+
20+
typedef int CUdevice;
21+
typedef struct CUctx_st *CUcontext;
22+
typedef struct CUstream_st *CUstream;
23+
typedef struct CUevent_st *CUevent;
24+
25+
// As defined in the CUDA 10.1 header file. This requires CUDA version > 3.2
26+
#if defined(_WIN64) || defined(__LP64__)
27+
typedef unsigned long long CUdeviceptr;
28+
#else
29+
typedef unsigned int CUdeviceptr;
30+
#endif
1031

1132
__SYCL_INLINE_NAMESPACE(cl) {
1233
namespace sycl {
13-
namespace backend {
14-
namespace cuda {
15-
16-
// CUDA backend specific options
17-
// TODO: Use values that won't overlap with others
18-
19-
// Mem Object info: Retrieve the raw CUDA pointer from a cl_mem
20-
#define PI_CUDA_RAW_POINTER (0xFF01)
21-
// Context creation: Use a primary CUDA context instead of a custom one by
22-
// providing a property value of PI_TRUE for the following
23-
// property ID.
24-
#define PI_CONTEXT_PROPERTIES_CUDA_PRIMARY (0xFF02)
25-
26-
// PI Command Queue using Default stream
27-
#define PI_CUDA_USE_DEFAULT_STREAM (0xFF03)
28-
// PI Command queue will sync with default stream
29-
#define PI_CUDA_SYNC_WITH_DEFAULT (0xFF04)
30-
31-
} // namespace cuda
32-
} // namespace backend
34+
35+
template <> struct interop<backend::cuda, device> { using type = CUdevice; };
36+
37+
template <> struct interop<backend::cuda, context> { using type = CUcontext; };
38+
39+
template <> struct interop<backend::cuda, queue> { using type = CUstream; };
40+
41+
template <> struct interop<backend::cuda, event> { using type = CUevent; };
42+
43+
template <typename DataT, int Dimensions, access::mode AccessMode>
44+
struct interop<backend::cuda, accessor<DataT, Dimensions, AccessMode,
45+
access::target::global_buffer,
46+
access::placeholder::false_t>> {
47+
using type = CUdeviceptr;
48+
};
49+
3350
} // namespace sycl
3451
} // namespace cl
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
//==-------------- backend_types.hpp - SYCL backend types ------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
namespace cl {
12+
namespace sycl {
13+
14+
enum class backend { host, opencl, cuda };
15+
16+
template <backend name, typename SYCLObjectT> struct interop;
17+
18+
} // namespace sycl
19+
} // namespace cl

sycl/include/CL/sycl/context.hpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
//===----------------------------------------------------------------------===//
88

99
#pragma once
10+
11+
#include <CL/sycl/backend_types.hpp>
1012
#include <CL/sycl/detail/common.hpp>
1113
#include <CL/sycl/detail/export.hpp>
1214
#include <CL/sycl/exception_list.hpp>
@@ -135,10 +137,21 @@ class __SYCL_EXPORT context {
135137
/// \return a vector of valid SYCL device instances.
136138
vector_class<device> get_devices() const;
137139

140+
/// Gets the native handle of the SYCL context.
141+
///
142+
/// \return a native handle, the type of which defined by the backend.
143+
template <backend BackendName>
144+
auto get_native() const -> typename interop<BackendName, context>::type {
145+
return reinterpret_cast<typename interop<BackendName, context>::type>(
146+
getNative());
147+
}
148+
138149
private:
139150
/// Constructs a SYCL context object from a valid context_impl instance.
140151
context(shared_ptr_class<detail::context_impl> Impl);
141152

153+
pi_native_handle getNative() const;
154+
142155
shared_ptr_class<detail::context_impl> impl;
143156
template <class Obj>
144157
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);

sycl/include/CL/sycl/detail/buffer_impl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ class __SYCL_EXPORT buffer_impl final : public SYCLMemObjT {
4444
using typename BaseT::MemObjType;
4545

4646
public:
47+
static constexpr pi_handle_type PIHandleType = PI_NATIVE_HANDLE_MEM;
48+
4749
buffer_impl(size_t SizeInBytes, size_t RequiredAlign,
4850
const property_list &Props,
4951
unique_ptr_class<SYCLMemObjAllocator> Allocator)
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
//==------------ cuda_definitions.hpp - SYCL CUDA backend ------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
// CUDA backend specific options
12+
// TODO: Use values that won't overlap with others
13+
14+
// Mem Object info: Retrieve the raw CUDA pointer from a cl_mem
15+
#define PI_CUDA_RAW_POINTER (0xFF01)
16+
// Context creation: Use a primary CUDA context instead of a custom one by
17+
// providing a property value of PI_TRUE for the following
18+
// property ID.
19+
#define PI_CONTEXT_PROPERTIES_CUDA_PRIMARY (0xFF02)
20+
21+
// PI Command Queue using Default stream
22+
#define PI_CUDA_USE_DEFAULT_STREAM (0xFF03)
23+
// PI Command queue will sync with default stream
24+
#define PI_CUDA_SYNC_WITH_DEFAULT (0xFF04)

sycl/include/CL/sycl/detail/pi.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,4 +113,7 @@ _PI_API(piextUSMGetMemAllocInfo)
113113

114114
_PI_API(piextKernelSetArgMemObj)
115115

116+
// Interop
117+
_PI_API(piGetNativeHandle)
118+
116119
#undef _PI_API

sycl/include/CL/sycl/detail/pi.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,16 @@ using pi_uint32 = uint32_t;
5959
using pi_uint64 = uint64_t;
6060
using pi_bool = pi_uint32;
6161
using pi_bitfield = pi_uint64;
62+
using pi_native_handle = uintptr_t;
63+
64+
enum pi_handle_type {
65+
PI_NATIVE_HANDLE_CONTEXT,
66+
PI_NATIVE_HANDLE_DEVICE,
67+
PI_NATIVE_HANDLE_QUEUE,
68+
PI_NATIVE_HANDLE_EVENT,
69+
PI_NATIVE_HANDLE_MEM,
70+
PI_NATIVE_HANDLE_PLATFORM
71+
};
6272

6373
//
6474
// NOTE: prefer to map 1:1 to OpenCL so that no translation is needed
@@ -1346,6 +1356,14 @@ pi_result piextUSMGetMemAllocInfo(pi_context context, const void *ptr,
13461356
size_t param_value_size, void *param_value,
13471357
size_t *param_value_size_ret);
13481358

1359+
/// Gets the native handle of a SYCL object.
1360+
///
1361+
/// \param handleType is a representation of the native handle.
1362+
/// \param piObject is the PI object to get the native handle of.
1363+
/// \param nativeHandle is the native handle of piObject.
1364+
pi_result piGetNativeHandle(pi_handle_type handleType, void *piObject,
1365+
pi_native_handle *nativeHandle);
1366+
13491367
struct _pi_plugin {
13501368
// PI version supported by host passed to the plugin. The Plugin
13511369
// checks and writes the appropriate Function Pointers in

sycl/include/CL/sycl/device.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/backend_types.hpp>
1112
#include <CL/sycl/detail/common.hpp>
1213
#include <CL/sycl/detail/export.hpp>
1314
#include <CL/sycl/info/info_desc.hpp>
@@ -165,10 +166,21 @@ class __SYCL_EXPORT device {
165166
static vector_class<device>
166167
get_devices(info::device_type deviceType = info::device_type::all);
167168

169+
/// Gets the native handle of the SYCL device.
170+
///
171+
/// \return a native handle, the type of which defined by the backend.
172+
template <backend BackendName>
173+
auto get_native() const -> typename interop<BackendName, device>::type {
174+
return static_cast<typename interop<BackendName, device>::type>(
175+
getNative());
176+
}
177+
168178
private:
169179
shared_ptr_class<detail::device_impl> impl;
170180
device(shared_ptr_class<detail::device_impl> impl) : impl(impl) {}
171181

182+
pi_native_handle getNative() const;
183+
172184
template <class Obj>
173185
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
174186

sycl/include/CL/sycl/event.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/backend_types.hpp>
1112
#include <CL/sycl/detail/common.hpp>
1213
#include <CL/sycl/detail/export.hpp>
1314
#include <CL/sycl/info/info_desc.hpp>
@@ -113,9 +114,19 @@ class __SYCL_EXPORT event {
113114
typename info::param_traits<info::event_profiling, param>::return_type
114115
get_profiling_info() const;
115116

117+
/// Gets the native handle of the SYCL event.
118+
///
119+
/// \return a native handle, the type of which defined by the backend.
120+
template <backend BackendName>
121+
auto get_native() const -> typename interop<BackendName, event>::type {
122+
return static_cast<typename interop<BackendName, event>::type>(getNative());
123+
}
124+
116125
private:
117126
event(shared_ptr_class<detail::event_impl> EventImpl);
118127

128+
pi_native_handle getNative() const;
129+
119130
shared_ptr_class<detail::event_impl> impl;
120131

121132
template <class Obj>

sycl/include/CL/sycl/queue.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <CL/sycl/backend_types.hpp>
1112
#include <CL/sycl/detail/common.hpp>
1213
#include <CL/sycl/detail/export.hpp>
1314
#include <CL/sycl/device.hpp>
@@ -638,7 +639,18 @@ class __SYCL_EXPORT queue {
638639
/// Equivalent to has_property<property::queue::in_order>()
639640
bool is_in_order() const;
640641

642+
/// Gets the native handle of the SYCL queue.
643+
///
644+
/// \return a native handle, the type of which defined by the backend.
645+
template <backend BackendName>
646+
auto get_native() const -> typename interop<BackendName, queue>::type {
647+
return reinterpret_cast<typename interop<BackendName, queue>::type>(
648+
getNative());
649+
}
650+
641651
private:
652+
pi_native_handle getNative() const;
653+
642654
shared_ptr_class<detail::queue_impl> impl;
643655
template <class Obj>
644656
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);

sycl/plugins/cuda/pi_cuda.cpp

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
///
1212
/// \ingroup sycl_pi_cuda
1313

14-
#include <CL/sycl/backend/cuda.hpp>
14+
#include <CL/sycl/detail/cuda_definitions.hpp>
1515
#include <CL/sycl/detail/pi.hpp>
1616
#include <pi_cuda.hpp>
1717

@@ -3554,6 +3554,46 @@ pi_result cuda_piextUSMGetMemAllocInfo(pi_context context, const void *ptr,
35543554
return result;
35553555
}
35563556

3557+
// Native interop
3558+
3559+
pi_result cuda_piGetNativeHandle(pi_handle_type handleType, void *piObject,
3560+
pi_native_handle *nativeHandle) {
3561+
switch (handleType) {
3562+
case pi_handle_type::PI_NATIVE_HANDLE_CONTEXT: {
3563+
pi_context context = static_cast<pi_context>(piObject);
3564+
*nativeHandle = reinterpret_cast<pi_native_handle>(context->get());
3565+
return PI_SUCCESS;
3566+
}
3567+
case pi_handle_type::PI_NATIVE_HANDLE_DEVICE: {
3568+
pi_device device = static_cast<pi_device>(piObject);
3569+
*nativeHandle = static_cast<pi_native_handle>(device->get());
3570+
return PI_SUCCESS;
3571+
}
3572+
case pi_handle_type::PI_NATIVE_HANDLE_QUEUE: {
3573+
pi_queue queue = static_cast<pi_queue>(piObject);
3574+
*nativeHandle = reinterpret_cast<pi_native_handle>(queue->get());
3575+
return PI_SUCCESS;
3576+
}
3577+
case pi_handle_type::PI_NATIVE_HANDLE_EVENT: {
3578+
pi_event event = static_cast<pi_event>(piObject);
3579+
if (event->is_user_event()) {
3580+
return PI_INVALID_EVENT;
3581+
}
3582+
*nativeHandle = reinterpret_cast<pi_native_handle>(event->get());
3583+
return PI_SUCCESS;
3584+
}
3585+
case pi_handle_type::PI_NATIVE_HANDLE_MEM: {
3586+
pi_mem mem = static_cast<pi_mem>(piObject);
3587+
*nativeHandle = static_cast<pi_native_handle>(mem->get());
3588+
return PI_SUCCESS;
3589+
}
3590+
default:
3591+
PI_HANDLE_UNKNOWN_PARAM_NAME(handleType);
3592+
}
3593+
cl::sycl::detail::pi::die("Native handle request not implemented");
3594+
return {};
3595+
}
3596+
35573597
const char SupportedVersion[] = _PI_H_VERSION_STRING;
35583598

35593599
pi_result piPluginInit(pi_plugin *PluginInit) {
@@ -3673,6 +3713,8 @@ pi_result piPluginInit(pi_plugin *PluginInit) {
36733713
_PI_CL(piextUSMGetMemAllocInfo, cuda_piextUSMGetMemAllocInfo)
36743714

36753715
_PI_CL(piextKernelSetArgMemObj, cuda_piextKernelSetArgMemObj)
3716+
// Interop
3717+
_PI_CL(piGetNativeHandle, cuda_piGetNativeHandle)
36763718

36773719
#undef _PI_CL
36783720

0 commit comments

Comments
 (0)