Skip to content

Commit c696415

Browse files
[SYCL] Make Level-Zero interop API SYCL 2020 compliant for platform, device and context (#4479)
Signed-off-by: Sergey V Maslov <[email protected]>
1 parent 2a35df0 commit c696415

File tree

6 files changed

+148
-10
lines changed

6 files changed

+148
-10
lines changed

sycl/include/CL/sycl/backend.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#pragma once
1010

1111
#include <CL/sycl/accessor.hpp>
12+
#include <CL/sycl/backend.hpp>
1213
#include <CL/sycl/backend_types.hpp>
1314
#include <CL/sycl/buffer.hpp>
1415
#include <CL/sycl/context.hpp>

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

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,15 +60,32 @@ struct interop<backend::level_zero,
6060
using type = ze_image_handle_t;
6161
};
6262

63+
namespace level_zero {
64+
// Since Level-Zero is not doing any reference counting itself, we have to
65+
// be explicit about the ownership of the native handles used in the
66+
// interop functions below.
67+
//
68+
enum class ownership { transfer, keep };
69+
} // namespace level_zero
70+
6371
namespace detail {
72+
73+
template <> struct BackendInput<backend::level_zero, context> {
74+
using type = struct {
75+
interop<backend::level_zero, context>::type NativeHandle;
76+
std::vector<device> DeviceList;
77+
level_zero::ownership Ownership;
78+
};
79+
};
80+
6481
template <> struct BackendReturn<backend::level_zero, kernel> {
6582
using type = ze_kernel_handle_t;
6683
};
6784

6885
template <> struct InteropFeatureSupportMap<backend::level_zero> {
6986
static constexpr bool MakePlatform = true;
70-
static constexpr bool MakeDevice = false;
71-
static constexpr bool MakeContext = false;
87+
static constexpr bool MakeDevice = true;
88+
static constexpr bool MakeContext = true;
7289
static constexpr bool MakeQueue = false;
7390
static constexpr bool MakeEvent = true;
7491
static constexpr bool MakeBuffer = false;
@@ -78,15 +95,9 @@ template <> struct InteropFeatureSupportMap<backend::level_zero> {
7895
} // namespace detail
7996

8097
namespace level_zero {
81-
82-
// Since Level-Zero is not doing any reference counting itself, we have to
83-
// be explicit about the ownership of the native handles used in the
84-
// interop functions below.
85-
//
86-
enum class ownership { transfer, keep };
87-
8898
// Implementation of various "make" functions resides in libsycl.so and thus
8999
// their interface needs to be backend agnostic.
100+
// TODO: remove/merge with similar functions in sycl::detail
90101
__SYCL_EXPORT platform make_platform(pi_native_handle NativeHandle);
91102
__SYCL_EXPORT device make_device(const platform &Platform,
92103
pi_native_handle NativeHandle);
@@ -105,13 +116,15 @@ __SYCL_EXPORT event make_event(const context &Context,
105116
// Construction of SYCL platform.
106117
template <typename T, typename detail::enable_if_t<
107118
std::is_same<T, platform>::value> * = nullptr>
119+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::make_platform free function")
108120
T make(typename interop<backend::level_zero, T>::type Interop) {
109121
return make_platform(reinterpret_cast<pi_native_handle>(Interop));
110122
}
111123

112124
// Construction of SYCL device.
113125
template <typename T, typename detail::enable_if_t<
114126
std::is_same<T, device>::value> * = nullptr>
127+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::make_device free function")
115128
T make(const platform &Platform,
116129
typename interop<backend::level_zero, T>::type Interop) {
117130
return make_device(Platform, reinterpret_cast<pi_native_handle>(Interop));
@@ -128,6 +141,7 @@ T make(const platform &Platform,
128141
///
129142
template <typename T, typename std::enable_if<
130143
std::is_same<T, context>::value>::type * = nullptr>
144+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::make_context free function")
131145
T make(const std::vector<device> &DeviceList,
132146
typename interop<backend::level_zero, T>::type Interop,
133147
ownership Ownership = ownership::transfer) {
@@ -162,7 +176,18 @@ T make(const context &Context,
162176
return make_event(Context, reinterpret_cast<pi_native_handle>(Interop),
163177
Ownership == ownership::keep);
164178
}
165-
166179
} // namespace level_zero
180+
181+
// Specialization of sycl::make_context for Level-Zero backend.
182+
template <>
183+
context make_context<backend::level_zero>(
184+
const backend_input_t<backend::level_zero, context> &BackendObject,
185+
const async_handler &Handler) {
186+
return level_zero::make_context(
187+
BackendObject.DeviceList,
188+
detail::pi::cast<pi_native_handle>(BackendObject.NativeHandle),
189+
BackendObject.Ownership == level_zero::ownership::keep);
190+
}
191+
167192
} // namespace sycl
168193
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/include/CL/sycl/context.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ class __SYCL_EXPORT context {
216216
///
217217
/// \return a native handle, the type of which defined by the backend.
218218
template <backend BackendName>
219+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::get_native free function")
219220
auto get_native() const -> typename interop<BackendName, context>::type {
220221
return reinterpret_cast<typename interop<BackendName, context>::type>(
221222
getNative());

sycl/include/CL/sycl/device.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ class __SYCL_EXPORT device {
184184
///
185185
/// \return a native handle, the type of which defined by the backend.
186186
template <backend BackendName>
187+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::get_native free function")
187188
auto get_native() const -> typename interop<BackendName, device>::type {
188189
return (typename interop<BackendName, device>::type)getNative();
189190
}

sycl/include/CL/sycl/platform.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ class __SYCL_EXPORT platform {
116116
///
117117
/// \return a native handle, the type of which defined by the backend.
118118
template <backend BackendName>
119+
__SYCL_DEPRECATED("Use SYCL-2020 sycl::get_native free function")
119120
auto get_native() const -> typename interop<BackendName, platform>::type {
120121
return reinterpret_cast<typename interop<BackendName, platform>::type>(
121122
getNative());
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
// RUN: %clangxx %fsycl-host-only -fsyntax-only -Xclang -verify -Xclang -verify-ignore-unexpected=note %s -o %t.out
2+
3+
// Test for SYCL-2020 Level Zero interop API
4+
5+
#include <sycl/sycl.hpp>
6+
// clang-format off
7+
#include <level_zero/ze_api.h>
8+
#include <CL/sycl/backend/level_zero.hpp>
9+
// clang-format on
10+
11+
using namespace sycl;
12+
13+
//
14+
// 4.5.1 SYCL application interoperability may be provided for
15+
// platform,
16+
// device,
17+
// context,
18+
// TODO:
19+
// buffer,
20+
// device_image,
21+
// event,
22+
// kernel,
23+
// kernel_bundle,
24+
// queue,
25+
// sampled_image,
26+
// unsampled_image.
27+
28+
int main() {
29+
30+
// Create SYCL objects
31+
device Device;
32+
platform Platform = Device.get_info<info::device::platform>();
33+
context Context(Device);
34+
35+
// 4.5.1.1 For each SYCL runtime class T which supports SYCL application
36+
// interoperability with the SYCL backend, a specialization of return_type
37+
// must be defined as the type of SYCL application interoperability native
38+
// backend object associated with T for the SYCL backend, specified in the
39+
// SYCL backend specification.
40+
//
41+
// return_type is used when retrieving the backend specific native object from
42+
// a SYCL object. See the relevant backend specification for details.
43+
44+
backend_traits<backend::level_zero>::return_type<platform> ZeDriver;
45+
backend_traits<backend::level_zero>::return_type<device> ZeDevice;
46+
backend_traits<backend::level_zero>::return_type<context> ZeContext;
47+
48+
// 4.5.1.2 For each SYCL runtime class T which supports SYCL application
49+
// interoperability, a specialization of get_native must be defined, which
50+
// takes an instance of T and returns a SYCL application interoperability
51+
// native backend object associated with syclObject which can be used for SYCL
52+
// application interoperability. The lifetime of the object returned are
53+
// backend-defined and specified in the backend specification.
54+
55+
ZeDriver = get_native<backend::level_zero>(Platform);
56+
ZeDevice = get_native<backend::level_zero>(Device);
57+
ZeContext = get_native<backend::level_zero>(Context);
58+
59+
// Check deprecated
60+
// expected-warning@+2 {{'get_native' is deprecated: Use SYCL-2020 sycl::get_native free function}}
61+
// expected-warning@+1 {{'get_native<sycl::backend::level_zero>' is deprecated: Use SYCL-2020 sycl::get_native free function}}
62+
ZeDriver = Platform.get_native<backend::level_zero>();
63+
// expected-warning@+2 {{'get_native' is deprecated: Use SYCL-2020 sycl::get_native free function}}
64+
// expected-warning@+1 {{'get_native<sycl::backend::level_zero>' is deprecated: Use SYCL-2020 sycl::get_native free function}}
65+
ZeDevice = Device.get_native<backend::level_zero>();
66+
// expected-warning@+2 {{'get_native' is deprecated: Use SYCL-2020 sycl::get_native free function}}
67+
// expected-warning@+1 {{'get_native<sycl::backend::level_zero>' is deprecated: Use SYCL-2020 sycl::get_native free function}}
68+
ZeContext = Context.get_native<backend::level_zero>();
69+
70+
// 4.5.1.1 For each SYCL runtime class T which supports SYCL application
71+
// interoperability with the SYCL backend, a specialization of input_type must
72+
// be defined as the type of SYCL application interoperability native backend
73+
// object associated with T for the SYCL backend, specified in the SYCL
74+
// backend specification. input_type is used when constructing SYCL objects
75+
// from backend specific native objects. See the relevant backend
76+
// specification for details.
77+
78+
// 4.5.1.3 For each SYCL runtime class T which supports SYCL application
79+
// interoperability, a specialization of the appropriate template function
80+
// make_{sycl_class} where {sycl_class} is the class name of T, must be
81+
// defined, which takes a SYCL application interoperability native backend
82+
// object and constructs and returns an instance of T. The availability and
83+
// behavior of these template functions is defined by the SYCL backend
84+
// specification document.
85+
86+
backend_input_t<backend::level_zero, platform> InteropPlatformInput{ZeDriver};
87+
platform InteropPlatform =
88+
make_platform<backend::level_zero>(InteropPlatformInput);
89+
90+
backend_input_t<backend::level_zero, device> InteropDeviceInput{ZeDevice};
91+
device InteropDevice = make_device<backend::level_zero>(InteropDeviceInput);
92+
93+
backend_input_t<backend::level_zero, context> InteropContextInput{
94+
ZeContext, std::vector<device>(1, InteropDevice),
95+
level_zero::ownership::keep};
96+
context InteropContext =
97+
make_context<backend::level_zero>(InteropContextInput);
98+
99+
// Check deprecated
100+
// expected-warning@+1 {{'make<sycl::platform, nullptr>' is deprecated: Use SYCL-2020 sycl::make_platform free function}}
101+
auto P = level_zero::make<platform>(ZeDriver);
102+
// expected-warning@+1 {{'make<sycl::device, nullptr>' is deprecated: Use SYCL-2020 sycl::make_device free function}}
103+
auto D = level_zero::make<device>(P, ZeDevice);
104+
// expected-warning@+1 {{'make<sycl::context, nullptr>' is deprecated: Use SYCL-2020 sycl::make_context free function}}
105+
auto C = level_zero::make<context>(std::vector<device>(1, D), ZeContext,
106+
level_zero::ownership::keep);
107+
108+
return 0;
109+
}

0 commit comments

Comments
 (0)