Skip to content

[SYCL] Make Level-Zero interop API SYCL-2020 compliant for queue, event, and kernel_bundle(was program). #4512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Sep 13, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions sycl/include/CL/sycl/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ using backend_return_t =
typename backend_traits<Backend>::template return_type<SyclType>;

template <backend BackendName, class SyclObjectT>
auto get_native(const SyclObjectT &Obj) ->
typename interop<BackendName, SyclObjectT>::type {
auto get_native(const SyclObjectT &Obj)
-> backend_return_t<BackendName, SyclObjectT> {
// TODO use SYCL 2020 exception when implemented
if (Obj.get_backend() != BackendName)
throw runtime_error("Backends mismatch", PI_INVALID_OPERATION);
Expand Down Expand Up @@ -146,17 +146,18 @@ make_context(
}

template <backend Backend>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_queue free function")
typename std::enable_if<
detail::InteropFeatureSupportMap<Backend>::MakeQueue == true, queue>::type
make_queue(const typename backend_traits<Backend>::template input_type<queue>
&BackendObject,
const context &TargetContext, bool KeepOwnership,
const async_handler Handler = {}) {
make_queue(
const typename backend_traits<Backend>::template input_type<queue>
&BackendObject,
const context &TargetContext, bool KeepOwnership,
const async_handler Handler = {}) {
return detail::make_queue(detail::pi::cast<pi_native_handle>(BackendObject),
TargetContext, KeepOwnership, Handler, Backend);
}

// TODO: remove this version (without ownership) when allowed to break ABI.
template <backend Backend>
typename std::enable_if<
detail::InteropFeatureSupportMap<Backend>::MakeQueue == true, queue>::type
Expand All @@ -178,11 +179,13 @@ make_event(const typename backend_traits<Backend>::template input_type<event>
}

template <backend Backend>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_event free function")
typename std::enable_if<
detail::InteropFeatureSupportMap<Backend>::MakeEvent == true, event>::type
make_event(const typename backend_traits<Backend>::template input_type<event>
&BackendObject,
const context &TargetContext, bool KeepOwnership) {
make_event(
const typename backend_traits<Backend>::template input_type<event>
&BackendObject,
const context &TargetContext, bool KeepOwnership) {
return detail::make_event(detail::pi::cast<pi_native_handle>(BackendObject),
TargetContext, KeepOwnership, Backend);
}
Expand Down
242 changes: 242 additions & 0 deletions sycl/include/CL/sycl/backend/level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,246 @@
__SYCL_WARNING("CL/sycl/backend/level_zero.hpp usage is deprecated, include "
"sycl/ext/oneapi/backend/level_zero.hpp instead")

<<<<<<< HEAD
#include <sycl/ext/oneapi/backend/level_zero.hpp>
=======
template <> struct interop<backend::level_zero, platform> {
using type = ze_driver_handle_t;
};

template <> struct interop<backend::level_zero, device> {
using type = ze_device_handle_t;
};

template <> struct interop<backend::level_zero, context> {
using type = ze_context_handle_t;
};

template <> struct interop<backend::level_zero, queue> {
using type = ze_command_queue_handle_t;
};

template <> struct interop<backend::level_zero, event> {
using type = ze_event_handle_t;
};

template <> struct interop<backend::level_zero, program> {
using type = ze_module_handle_t;
};

template <typename DataT, int Dimensions, access::mode AccessMode>
struct interop<backend::level_zero, accessor<DataT, Dimensions, AccessMode,
access::target::global_buffer,
access::placeholder::false_t>> {
using type = char *;
};

template <typename DataT, int Dimensions, access::mode AccessMode>
struct interop<backend::level_zero, accessor<DataT, Dimensions, AccessMode,
access::target::constant_buffer,
access::placeholder::false_t>> {
using type = char *;
};

template <typename DataT, int Dimensions, access::mode AccessMode>
struct interop<backend::level_zero,
accessor<DataT, Dimensions, AccessMode, access::target::image,
access::placeholder::false_t>> {
using type = ze_image_handle_t;
};

namespace level_zero {
// Since Level-Zero is not doing any reference counting itself, we have to
// be explicit about the ownership of the native handles used in the
// interop functions below.
//
enum class ownership { transfer, keep };
} // namespace level_zero

namespace detail {

template <> struct BackendInput<backend::level_zero, context> {
using type = struct {
interop<backend::level_zero, context>::type NativeHandle;
std::vector<device> DeviceList;
level_zero::ownership Ownership;
};
};

template <> struct BackendInput<backend::level_zero, queue> {
using type = struct {
interop<backend::level_zero, queue>::type NativeHandle;
level_zero::ownership Ownership;
};
};

template <> struct BackendInput<backend::level_zero, event> {
using type = struct {
interop<backend::level_zero, event>::type NativeHandle;
level_zero::ownership Ownership;
};
};

template <bundle_state State>
struct BackendInput<backend::level_zero, kernel_bundle<State>> {
using type = ze_module_handle_t;
};

template <bundle_state State>
struct BackendReturn<backend::level_zero, kernel_bundle<State>> {
using type = std::vector<ze_module_handle_t>;
};

template <> struct BackendReturn<backend::level_zero, kernel> {
using type = ze_kernel_handle_t;
};

template <> struct InteropFeatureSupportMap<backend::level_zero> {
static constexpr bool MakePlatform = true;
static constexpr bool MakeDevice = true;
static constexpr bool MakeContext = true;
static constexpr bool MakeQueue = true;
static constexpr bool MakeEvent = true;
static constexpr bool MakeKernelBundle = true;
static constexpr bool MakeBuffer = false;
static constexpr bool MakeKernel = false;
};
} // namespace detail

namespace level_zero {
// Implementation of various "make" functions resides in libsycl.so and thus
// their interface needs to be backend agnostic.
// TODO: remove/merge with similar functions in sycl::detail
__SYCL_EXPORT platform make_platform(pi_native_handle NativeHandle);
__SYCL_EXPORT device make_device(const platform &Platform,
pi_native_handle NativeHandle);
__SYCL_EXPORT context make_context(const std::vector<device> &DeviceList,
pi_native_handle NativeHandle,
bool keep_ownership = false);
__SYCL_EXPORT program make_program(const context &Context,
pi_native_handle NativeHandle);
__SYCL_EXPORT queue make_queue(const context &Context,
pi_native_handle InteropHandle,
bool keep_ownership = false);
__SYCL_EXPORT event make_event(const context &Context,
pi_native_handle InteropHandle,
bool keep_ownership = false);

// Construction of SYCL platform.
template <typename T, typename detail::enable_if_t<
std::is_same<T, platform>::value> * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_platform free function")
T make(typename interop<backend::level_zero, T>::type Interop) {
return make_platform(reinterpret_cast<pi_native_handle>(Interop));
}

// Construction of SYCL device.
template <typename T, typename detail::enable_if_t<
std::is_same<T, device>::value> * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_device free function")
T make(const platform &Platform,
typename interop<backend::level_zero, T>::type Interop) {
return make_device(Platform, reinterpret_cast<pi_native_handle>(Interop));
}

/// Construction of SYCL context.
/// \param DeviceList is a vector of devices which must be encapsulated by
/// created SYCL context. Provided devices and native context handle must
/// be associated with the same platform.
/// \param Interop is a Level Zero native context handle.
/// \param Ownership (optional) specifies who will assume ownership of the
/// native context handle. Default is that SYCL RT does, so it destroys
/// the native handle when the created SYCL object goes out of life.
///
template <typename T, typename std::enable_if<
std::is_same<T, context>::value>::type * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_context free function")
T make(const std::vector<device> &DeviceList,
typename interop<backend::level_zero, T>::type Interop,
ownership Ownership = ownership::transfer) {
return make_context(DeviceList, detail::pi::cast<pi_native_handle>(Interop),
Ownership == ownership::keep);
}

// Construction of SYCL program.
template <typename T, typename detail::enable_if_t<
std::is_same<T, program>::value> * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_kernel_bundle free function")
T make(const context &Context,
typename interop<backend::level_zero, T>::type Interop) {
return make_program(Context, reinterpret_cast<pi_native_handle>(Interop));
}

// Construction of SYCL queue.
template <typename T, typename detail::enable_if_t<
std::is_same<T, queue>::value> * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_queue free function")
T make(const context &Context,
typename interop<backend::level_zero, T>::type Interop,
ownership Ownership = ownership::transfer) {
return make_queue(Context, reinterpret_cast<pi_native_handle>(Interop),
Ownership == ownership::keep);
}

// Construction of SYCL event.
template <typename T, typename detail::enable_if_t<
std::is_same<T, event>::value> * = nullptr>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::make_event free function")
T make(const context &Context,
typename interop<backend::level_zero, T>::type Interop,
ownership Ownership = ownership::transfer) {
return make_event(Context, reinterpret_cast<pi_native_handle>(Interop),
Ownership == ownership::keep);
}
} // namespace level_zero

// Specialization of sycl::make_context for Level-Zero backend.
template <>
context make_context<backend::level_zero>(
const backend_input_t<backend::level_zero, context> &BackendObject,
const async_handler &Handler) {
return level_zero::make_context(
BackendObject.DeviceList,
detail::pi::cast<pi_native_handle>(BackendObject.NativeHandle),
BackendObject.Ownership == level_zero::ownership::keep);
}

// Specialization of sycl::make_queue for Level-Zero backend.
template <>
queue make_queue<backend::level_zero>(
const backend_input_t<backend::level_zero, queue> &BackendObject,
const context &TargetContext, const async_handler Handler) {
return level_zero::make_queue(
TargetContext,
detail::pi::cast<pi_native_handle>(BackendObject.NativeHandle),
BackendObject.Ownership == level_zero::ownership::keep);
}

// Specialization of sycl::make_event for Level-Zero backend.
template <>
event make_event<backend::level_zero>(
const backend_input_t<backend::level_zero, event> &BackendObject,
const context &TargetContext) {
return level_zero::make_event(
TargetContext,
detail::pi::cast<pi_native_handle>(BackendObject.NativeHandle),
BackendObject.Ownership == level_zero::ownership::keep);
}

// TODO: remove this specialization when generic is changed to call
// .GetNative() instead of .get_native() member of kernel_bundle.
template <>
auto get_native<backend::level_zero>(
const kernel_bundle<bundle_state::executable> &Obj)
-> backend_return_t<backend::level_zero,
kernel_bundle<bundle_state::executable>> {
// TODO use SYCL 2020 exception when implemented
if (Obj.get_backend() != backend::level_zero)
throw runtime_error("Backends mismatch", PI_INVALID_OPERATION);

return Obj.template getNative<backend::level_zero>();
}

} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
>>>>>>> 6c9a8addf701 ([SYCL] Make Level-Zero interop API SYCL-2020 compliant for queue, event, and kernel_bundle(was program).)
1 change: 1 addition & 0 deletions sycl/include/CL/sycl/backend/opencl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ struct BackendInput<backend::opencl, kernel_bundle<State>> {

template <bundle_state State>
struct BackendReturn<backend::opencl, kernel_bundle<State>> {
// TODO: Per SYCL 2020 this should be std::vector<cl_program>
using type = cl_program;
};

Expand Down
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ class __SYCL_EXPORT context {
///
/// \return a native handle, the type of which defined by the backend.
template <backend BackendName>
__SYCL_DEPRECATED("Use SYCL-2020 sycl::get_native free function")
__SYCL_DEPRECATED("Use SYCL 2020 sycl::get_native free function")
auto get_native() const -> typename interop<BackendName, context>::type {
return reinterpret_cast<typename interop<BackendName, context>::type>(
getNative());
Expand Down
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/device.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ class __SYCL_EXPORT device {
///
/// \return a native handle, the type of which defined by the backend.
template <backend BackendName>
__SYCL_DEPRECATED("Use SYCL-2020 sycl::get_native free function")
__SYCL_DEPRECATED("Use SYCL 2020 sycl::get_native free function")
auto get_native() const -> typename interop<BackendName, device>::type {
return (typename interop<BackendName, device>::type)getNative();
}
Expand Down
2 changes: 2 additions & 0 deletions sycl/include/CL/sycl/event.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,12 @@ class __SYCL_EXPORT event {
///
/// \return a native handle, the type of which defined by the backend.
template <backend BackendName>
__SYCL_DEPRECATED("Use SYCL 2020 sycl::get_native free function")
auto get_native() const -> typename interop<BackendName, event>::type {
return reinterpret_cast<typename interop<BackendName, event>::type>(
getNative());
}

private:
event(std::shared_ptr<detail::event_impl> EventImpl);

Expand Down
6 changes: 3 additions & 3 deletions sycl/include/CL/sycl/interop_handle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class interop_handle {
template <backend Backend = backend::opencl>
backend_return_t<Backend, queue> get_native_queue() const {
#ifndef __SYCL_DEVICE_ONLY__
// TODO: replace the exception thrown below with the SYCL-2020 exception
// TODO: replace the exception thrown below with the SYCL 2020 exception
// with the error code 'errc::backend_mismatch' when those new exceptions
// are ready to be used.
if (Backend != get_backend())
Expand All @@ -107,7 +107,7 @@ class interop_handle {
template <backend Backend = backend::opencl>
backend_return_t<Backend, device> get_native_device() const {
#ifndef __SYCL_DEVICE_ONLY__
// TODO: replace the exception thrown below with the SYCL-2020 exception
// TODO: replace the exception thrown below with the SYCL 2020 exception
// with the error code 'errc::backend_mismatch' when those new exceptions
// are ready to be used.
if (Backend != get_backend())
Expand All @@ -129,7 +129,7 @@ class interop_handle {
template <backend Backend = backend::opencl>
backend_return_t<Backend, context> get_native_context() const {
#ifndef __SYCL_DEVICE_ONLY__
// TODO: replace the exception thrown below with the SYCL-2020 exception
// TODO: replace the exception thrown below with the SYCL 2020 exception
// with the error code 'errc::backend_mismatch' when those new exceptions
// are ready to be used.
if (Backend != get_backend())
Expand Down
Loading