Skip to content

Commit 2d71c8e

Browse files
[SYCL][PI][CUDA] Implements get_native interoperability (#1332)
* [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. * [SYCL][PI][OpenCL] Generalizing interop handler getters This commit makes get_mem and get_queue of interop_handler return types based on a specified backend. The backend defaults to OpenCL to avoid breakages. * [SYCL][PI] Splitting the converter function * [SYCL][PI] PI objects created with native handles takes ownership PI objects created with the associated piextCreate*WithNativeHandle function takes ownership of the native handle passed to it. For OpenCL this means that the native OpenCL object is not retained, so the PI object effectively owns the reference of the caller. The OpenCL interoperability have been changed to retain the native OpenCL handle as the implementation no longer does it. This is required by the SYCL 1.2.1 specification (Rev6, section 4.3.1.) Signed-off-by: Steffen Larsen <[email protected]>
1 parent 3f21371 commit 2d71c8e

40 files changed

+855
-233
lines changed

sycl/include/CL/sycl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
#include <CL/sycl/accessor.hpp>
1212
#include <CL/sycl/atomic.hpp>
13+
#include <CL/sycl/backend.hpp>
14+
#include <CL/sycl/backend/opencl.hpp>
1315
#include <CL/sycl/buffer.hpp>
1416
#include <CL/sycl/builtins.hpp>
1517
#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: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
//==---------------- opencl.hpp - SYCL OpenCL backend ----------------------==//
3+
//
4+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5+
// See https://llvm.org/LICENSE.txt for license information.
6+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#pragma once
11+
12+
#include <CL/cl.h>
13+
#include <CL/sycl/accessor.hpp>
14+
#include <CL/sycl/backend_types.hpp>
15+
16+
__SYCL_INLINE_NAMESPACE(cl) {
17+
namespace sycl {
18+
19+
template <> struct interop<backend::opencl, queue> {
20+
using type = cl_command_queue;
21+
};
22+
23+
template <typename DataT, int Dimensions, access::mode AccessMode>
24+
struct interop<backend::opencl, accessor<DataT, Dimensions, AccessMode,
25+
access::target::global_buffer,
26+
access::placeholder::false_t>> {
27+
using type = cl_mem;
28+
};
29+
30+
} // namespace sycl
31+
} // __SYCL_INLINE_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/cg.hpp

Lines changed: 43 additions & 11 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/accessor_impl.hpp>
1213
#include <CL/sycl/detail/common.hpp>
1314
#include <CL/sycl/detail/export.hpp>
@@ -29,6 +30,12 @@
2930
__SYCL_INLINE_NAMESPACE(cl) {
3031
namespace sycl {
3132

33+
// Forward declaration
34+
class queue;
35+
namespace detail {
36+
class queue_impl;
37+
} // namespace detail
38+
3239
// Interoperability handler
3340
//
3441
class interop_handler {
@@ -37,26 +44,51 @@ class interop_handler {
3744
access::target AccTarget, access::placeholder isPlaceholder>
3845
friend class accessor;
3946
public:
47+
using QueueImplPtr = std::shared_ptr<detail::queue_impl>;
4048
using ReqToMem = std::pair<detail::Requirement*, pi_mem>;
4149

42-
interop_handler(std::vector<ReqToMem> MemObjs, cl_command_queue PiQueue) :
43-
MQueue(PiQueue), MMemObjs(MemObjs) {}
50+
interop_handler(std::vector<ReqToMem> MemObjs, QueueImplPtr Queue)
51+
: MQueue(std::move(Queue)), MMemObjs(std::move(MemObjs)) {}
4452

45-
cl_command_queue get_queue() const noexcept { return MQueue; };
53+
template <backend BackendName = backend::opencl>
54+
auto get_queue() const -> typename interop<BackendName, queue>::type {
55+
return reinterpret_cast<typename interop<BackendName, queue>::type>(
56+
GetNativeQueue());
57+
}
4658

47-
template <typename DataT, int Dims, access::mode AccessMode,
48-
access::target AccessTarget,
59+
template <backend BackendName = backend::opencl, typename DataT, int Dims,
60+
access::mode AccessMode, access::target AccessTarget,
4961
access::placeholder IsPlaceholder = access::placeholder::false_t>
50-
cl_mem get_mem(accessor<DataT, Dims, AccessMode, AccessTarget,
51-
access::placeholder::false_t>
52-
Acc) const {
62+
auto get_mem(accessor<DataT, Dims, AccessMode, AccessTarget,
63+
access::placeholder::false_t>
64+
Acc) const ->
65+
typename interop<BackendName,
66+
accessor<DataT, Dims, AccessMode, AccessTarget,
67+
access::placeholder::false_t>>::type {
5368
detail::AccessorBaseHost *AccBase = (detail::AccessorBaseHost *)&Acc;
54-
return getMemImpl(detail::getSyclObjImpl(*AccBase).get());
69+
return getMemImpl<BackendName, DataT, Dims, AccessMode, AccessTarget,
70+
access::placeholder::false_t>(
71+
detail::getSyclObjImpl(*AccBase).get());
5572
}
73+
5674
private:
57-
cl_command_queue MQueue;
75+
QueueImplPtr MQueue;
5876
std::vector<ReqToMem> MMemObjs;
59-
__SYCL_EXPORT cl_mem getMemImpl(detail::Requirement *Req) const;
77+
78+
template <backend BackendName, typename DataT, int Dims,
79+
access::mode AccessMode, access::target AccessTarget,
80+
access::placeholder IsPlaceholder>
81+
__SYCL_EXPORT auto
82+
getMemImpl(detail::Requirement *Req) const -> typename interop<
83+
BackendName,
84+
accessor<DataT, Dims, AccessMode, AccessTarget, IsPlaceholder>>::type {
85+
return (typename interop<BackendName,
86+
accessor<DataT, Dims, AccessMode, AccessTarget,
87+
IsPlaceholder>>::type)GetNativeMem(Req);
88+
}
89+
90+
__SYCL_EXPORT pi_native_handle GetNativeMem(detail::Requirement *Req) const;
91+
__SYCL_EXPORT pi_native_handle GetNativeQueue() const;
6092
};
6193

6294
namespace detail {
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: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,31 @@
1818
_PI_API(piPlatformsGet)
1919
_PI_API(piPlatformGetInfo)
2020
// Device
21-
_PI_API(piextDeviceConvert)
2221
_PI_API(piDevicesGet)
2322
_PI_API(piDeviceGetInfo)
2423
_PI_API(piDevicePartition)
2524
_PI_API(piDeviceRetain)
2625
_PI_API(piDeviceRelease)
2726
_PI_API(piextDeviceSelectBinary)
2827
_PI_API(piextGetDeviceFunctionPointer)
28+
_PI_API(piextDeviceGetNativeHandle)
29+
_PI_API(piextDeviceCreateWithNativeHandle)
2930
// Context
3031
_PI_API(piContextCreate)
3132
_PI_API(piContextGetInfo)
3233
_PI_API(piContextRetain)
3334
_PI_API(piContextRelease)
3435
_PI_API(piextContextSetExtendedDeleter)
36+
_PI_API(piextContextGetNativeHandle)
37+
_PI_API(piextContextCreateWithNativeHandle)
3538
// Queue
3639
_PI_API(piQueueCreate)
3740
_PI_API(piQueueGetInfo)
3841
_PI_API(piQueueFinish)
3942
_PI_API(piQueueRetain)
4043
_PI_API(piQueueRelease)
44+
_PI_API(piextQueueGetNativeHandle)
45+
_PI_API(piextQueueCreateWithNativeHandle)
4146
// Memory
4247
_PI_API(piMemBufferCreate)
4348
_PI_API(piMemImageCreate)
@@ -46,8 +51,9 @@ _PI_API(piMemImageGetInfo)
4651
_PI_API(piMemRetain)
4752
_PI_API(piMemRelease)
4853
_PI_API(piMemBufferPartition)
54+
_PI_API(piextMemGetNativeHandle)
55+
_PI_API(piextMemCreateWithNativeHandle)
4956
// Program
50-
_PI_API(piextProgramConvert)
5157
_PI_API(piProgramCreate)
5258
_PI_API(piclProgramCreateWithSource)
5359
_PI_API(piclProgramCreateWithBinary)
@@ -59,6 +65,8 @@ _PI_API(piProgramGetBuildInfo)
5965
_PI_API(piProgramRetain)
6066
_PI_API(piProgramRelease)
6167
_PI_API(piextProgramSetSpecializationConstant)
68+
_PI_API(piextProgramGetNativeHandle)
69+
_PI_API(piextProgramCreateWithNativeHandle)
6270
// Kernel
6371
_PI_API(piKernelCreate)
6472
_PI_API(piKernelSetArg)
@@ -78,6 +86,8 @@ _PI_API(piEventSetCallback)
7886
_PI_API(piEventSetStatus)
7987
_PI_API(piEventRetain)
8088
_PI_API(piEventRelease)
89+
_PI_API(piextEventGetNativeHandle)
90+
_PI_API(piextEventCreateWithNativeHandle)
8191
// Sampler
8292
_PI_API(piSamplerCreate)
8393
_PI_API(piSamplerGetInfo)

0 commit comments

Comments
 (0)