Skip to content
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

[SYCL] Add Level-Zero interop with specification of ownership for Queue. #4066

Merged
merged 11 commits into from
Jul 16, 2021
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 2 additions & 2 deletions sycl/doc/extensions/LevelZeroBackend/LevelZeroBackend.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ a SYCL object that encapsulates a corresponding Level-Zero object:
|``` make<platform>(ze_driver_handle_t);```|Constructs a SYCL platform instance from a Level-Zero ```ze_driver_handle_t```.|
|``` make<device>(const platform &, ze_device_handle_t);```|Constructs a SYCL device instance from a Level-Zero ```ze_device_handle_t```. The platform argument gives a SYCL platform, encapsulating a Level-Zero driver supporting the passed Level-Zero device.|
|``` make<context>(const vector_class<device> &, ze_context_handle_t, ownership = transfer);```| Constructs a SYCL context instance from a Level-Zero ```ze_context_handle_t```. The context is created against the devices passed in. There must be at least one device given and all the devices must be from the same SYCL platform and thus from the same Level-Zero driver. The ```ownership``` argument specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.|
|``` make<queue>(const context &, ze_command_queue_handle_t);```| Constructs a SYCL queue instance from a Level-Zero ```ze_command_queue_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The queue is attached to the first device in the passed SYCL context.|
|``` make<queue>(const context &, ze_command_queue_handle_t, ownership = transfer);```| Constructs a SYCL queue instance from a Level-Zero ```ze_command_queue_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The queue is attached to the first device in the passed SYCL context. The ```ownership``` argument specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.|
|``` make<program>(const context &, ze_module_handle_t);```| Constructs a SYCL program instance from a Level-Zero ```ze_module_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The Level-Zero module must be fully linked (i.e. not require further linking through [```zeModuleDynamicLink```](https://spec.oneapi.com/level-zero/latest/core/api.html?highlight=zemoduledynamiclink#_CPPv419zeModuleDynamicLink8uint32_tP18ze_module_handle_tP28ze_module_build_log_handle_t)), and thus the SYCL program is created in the "linked" state.|

NOTE: We shall consider adding other interoperability as needed, if possible.
Expand Down Expand Up @@ -189,4 +189,4 @@ struct free_memory {
|1|2021-01-26|Sergey Maslov|Initial public working draft
|2|2021-02-22|Sergey Maslov|Introduced explicit ownership for context
|3|2021-04-13|James Brodman|Free Memory Query

|4|2021-07-06|Rehana Begam|Introduced explicit ownership for queue
2 changes: 1 addition & 1 deletion sycl/include/CL/sycl/backend.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ __SYCL_EXPORT context make_context(pi_native_handle NativeHandle,
const async_handler &Handler,
backend Backend);
__SYCL_EXPORT queue make_queue(pi_native_handle NativeHandle,
const context &TargetContext,
const context &TargetContext, bool KeepOwnership,
smaslov-intel marked this conversation as resolved.
Show resolved Hide resolved
const async_handler &Handler, backend Backend);
__SYCL_EXPORT event make_event(pi_native_handle NativeHandle,
const context &TargetContext, backend Backend);
Expand Down
9 changes: 6 additions & 3 deletions sycl/include/CL/sycl/backend/level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ __SYCL_EXPORT context make_context(const std::vector<device> &DeviceList,
__SYCL_EXPORT program make_program(const context &Context,
pi_native_handle NativeHandle);
__SYCL_EXPORT queue make_queue(const context &Context,
pi_native_handle InteropHandle);
pi_native_handle InteropHandle,
bool keep_ownership = false);

// Construction of SYCL platform.
template <typename T, typename detail::enable_if_t<
Expand Down Expand Up @@ -139,8 +140,10 @@ T make(const context &Context,
template <typename T, typename detail::enable_if_t<
std::is_same<T, queue>::value> * = nullptr>
T make(const context &Context,
typename interop<backend::level_zero, T>::type Interop) {
return make_queue(Context, reinterpret_cast<pi_native_handle>(Interop));
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);
}

} // namespace level_zero
Expand Down
10 changes: 7 additions & 3 deletions sycl/include/CL/sycl/detail/pi.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@
// 2. A number of types needed to define pi_device_binary_property_set added.
// 3. Added new ownership argument to piextContextCreateWithNativeHandle.
// 4. Add interoperability interfaces for kernel.
// 5. Added new ownership argument to piextQueueCreateWithNativeHandle.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The numbering (5.) is not in sync with PI versions

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should it match with the major/minor version? I've followed the inst from line#25 above and increased both by 1.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following instructions in line #25 is all fine. Just let's have the comments about the changes tell what was the version where it was made. So, in your case I'd say have "5" changed to "4.6". And, please add a comment about this numbering in the comment above.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done.

//
#include "CL/cl.h"
#define _PI_H_VERSION_MAJOR 3
#define _PI_H_VERSION_MINOR 5
#define _PI_H_VERSION_MAJOR 4
#define _PI_H_VERSION_MINOR 6

#define _PI_STRING_HELPER(a) #a
#define _PI_CONCAT(a, b) _PI_STRING_HELPER(a.b)
Expand Down Expand Up @@ -1042,9 +1043,12 @@ piextQueueGetNativeHandle(pi_queue queue, pi_native_handle *nativeHandle);
///
/// \param nativeHandle is the native handle to create PI queue from.
/// \param context is the PI context of the queue.
/// \param ownNativeHandle tells if SYCL RT should assume the ownership of
/// the native handle, if it can.
/// \param queue is the PI queue created from the native handle.
__SYCL_EXPORT pi_result piextQueueCreateWithNativeHandle(
pi_native_handle nativeHandle, pi_context context, pi_queue *queue);
pi_native_handle nativeHandle, pi_context context, bool ownNativeHandle,
pi_queue *queue);

//
// Memory
Expand Down
1 change: 1 addition & 0 deletions sycl/plugins/cuda/pi_cuda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2149,6 +2149,7 @@ pi_result cuda_piextQueueGetNativeHandle(pi_queue queue,
///
/// \return TBD
pi_result cuda_piextQueueCreateWithNativeHandle(pi_native_handle, pi_context,
bool ownNativeHandle,
rbegam marked this conversation as resolved.
Show resolved Hide resolved
pi_queue *) {
cl::sycl::detail::pi::die(
"Creation of PI queue from native handle not implemented");
Expand Down
2 changes: 1 addition & 1 deletion sycl/plugins/esimd_cpu/pi_esimd_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ pi_result piextQueueGetNativeHandle(pi_queue, pi_native_handle *) {
return PI_SUCCESS;
}

pi_result piextQueueCreateWithNativeHandle(pi_native_handle, pi_context,
pi_result piextQueueCreateWithNativeHandle(pi_native_handle, pi_context, bool,
pi_queue *) {
DIE_NO_IMPLEMENTATION;
return PI_SUCCESS;
Expand Down
9 changes: 5 additions & 4 deletions sycl/plugins/level_zero/pi_level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2411,7 +2411,7 @@ pi_result piQueueCreate(pi_context Context, pi_device Device,

try {
*Queue = new _pi_queue(ZeComputeCommandQueue, ZeCopyCommandQueue, Context,
Device, ZeCommandListBatchSize, Properties);
Device, ZeCommandListBatchSize, true, Properties);
} catch (const std::bad_alloc &) {
return PI_OUT_OF_HOST_MEMORY;
} catch (...) {
Expand Down Expand Up @@ -2471,7 +2471,7 @@ pi_result piQueueRelease(pi_queue Queue) {
std::lock_guard<std::mutex> Lock(Queue->PiQueueMutex);
Queue->RefCount--;
if (Queue->RefCount == 0)
RefCountZero = true;
RefCountZero = Queue->OwnZeCommandQueue ? true : false;
rbegam marked this conversation as resolved.
Show resolved Hide resolved

if (RefCountZero) {
// It is possible to get to here and still have an open command list
Expand Down Expand Up @@ -2546,6 +2546,7 @@ pi_result piextQueueGetNativeHandle(pi_queue Queue,

pi_result piextQueueCreateWithNativeHandle(pi_native_handle NativeHandle,
pi_context Context,
bool OwnNativeHandle,
pi_queue *Queue) {
PI_ASSERT(Context, PI_INVALID_CONTEXT);
PI_ASSERT(NativeHandle, PI_INVALID_VALUE);
Expand All @@ -2558,8 +2559,8 @@ pi_result piextQueueCreateWithNativeHandle(pi_native_handle NativeHandle,
pi_device Device = Context->Devices[0];
// TODO: see what we can do to correctly initialize PI queue for
// compute vs. copy Level-Zero queue.
*Queue =
new _pi_queue(ZeQueue, nullptr, Context, Device, ZeCommandListBatchSize);
*Queue = new _pi_queue(ZeQueue, nullptr, Context, Device,
ZeCommandListBatchSize, OwnNativeHandle);
return PI_SUCCESS;
}

Expand Down
7 changes: 6 additions & 1 deletion sycl/plugins/level_zero/pi_level_zero.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -434,12 +434,13 @@ const pi_uint32 DynamicBatchStartSize = 4;
struct _pi_queue : _pi_object {
_pi_queue(ze_command_queue_handle_t Queue,
ze_command_queue_handle_t CopyQueue, pi_context Context,
pi_device Device, pi_uint32 BatchSize,
pi_device Device, pi_uint32 BatchSize, bool OwnZeCommandQueue,
pi_queue_properties PiQueueProperties = 0)
: ZeComputeCommandQueue{Queue},
ZeCopyCommandQueue{CopyQueue}, Context{Context}, Device{Device},
QueueBatchSize{BatchSize > 0 ? BatchSize : DynamicBatchStartSize},
UseDynamicBatching{BatchSize == 0},
OwnZeCommandQueue{OwnZeCommandQueue},
PiQueueProperties(PiQueueProperties) {}

// Level Zero compute command queue handle.
Expand Down Expand Up @@ -497,6 +498,10 @@ struct _pi_queue : _pi_object {
// const for the life of the queue.
const bool UseDynamicBatching;

// Indicates if we own the ZeCommandQueue or it came from interop that
// asked to not transfer the ownership to SYCL RT.
bool OwnZeCommandQueue;

// These two members are used to keep track of how often the
// batching closes and executes a command list before reaching the
// QueueBatchSize limit, versus how often we reach the limit.
Expand Down
4 changes: 3 additions & 1 deletion sycl/plugins/opencl/pi_opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,8 +352,10 @@ pi_result piQueueCreate(pi_context context, pi_device device,
}

pi_result piextQueueCreateWithNativeHandle(pi_native_handle nativeHandle,
pi_context, pi_queue *piQueue) {
pi_context, bool ownNativeHandle,
pi_queue *piQueue) {
assert(piQueue != nullptr);
assert(ownNativeHandle == false);
*piQueue = reinterpret_cast<pi_queue>(nativeHandle);
return PI_SUCCESS;
}
Expand Down
4 changes: 2 additions & 2 deletions sycl/source/backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ __SYCL_EXPORT context make_context(pi_native_handle NativeHandle,
}

__SYCL_EXPORT queue make_queue(pi_native_handle NativeHandle,
const context &Context,
const context &Context, bool KeepOwnership,
const async_handler &Handler, backend Backend) {
const auto &Plugin = getPlugin(Backend);
const auto &ContextImpl = getSyclObjImpl(Context);
// Create PI queue first.
pi::PiQueue PiQueue = nullptr;
Plugin.call<PiApiKind::piextQueueCreateWithNativeHandle>(
NativeHandle, ContextImpl->getHandleRef(), &PiQueue);
NativeHandle, ContextImpl->getHandleRef(), !KeepOwnership, &PiQueue);
// Construct the SYCL queue from PI queue.
return detail::createSyclObjFromImpl<queue>(
std::make_shared<queue_impl>(PiQueue, ContextImpl, Handler));
Expand Down
5 changes: 3 additions & 2 deletions sycl/source/backend/level_zero.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ __SYCL_EXPORT program make_program(const context &Context,
//----------------------------------------------------------------------------
// Implementation of level_zero::make<queue>
__SYCL_EXPORT queue make_queue(const context &Context,
pi_native_handle NativeHandle) {
pi_native_handle NativeHandle,
bool KeepOwnership) {
const auto &ContextImpl = getSyclObjImpl(Context);
return detail::make_queue(NativeHandle, Context,
return detail::make_queue(NativeHandle, Context, KeepOwnership,
ContextImpl->get_async_handler(),
backend::level_zero);
}
Expand Down
2 changes: 1 addition & 1 deletion sycl/source/backend/opencl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ __SYCL_EXPORT program make_program(const context &Context,
__SYCL_EXPORT queue make_queue(const context &Context,
pi_native_handle NativeHandle) {
const auto &ContextImpl = getSyclObjImpl(Context);
return detail::make_queue(NativeHandle, Context,
return detail::make_queue(NativeHandle, Context, false,
ContextImpl->get_async_handler(), backend::opencl);
}
} // namespace opencl
Expand Down
4 changes: 2 additions & 2 deletions sycl/test/abi/sycl_symbols_linux.dump
Original file line number Diff line number Diff line change
Expand Up @@ -3590,7 +3590,7 @@ _ZN2cl10__host_std9u_sub_satEhh
_ZN2cl10__host_std9u_sub_satEjj
_ZN2cl10__host_std9u_sub_satEmm
_ZN2cl10__host_std9u_sub_satEtt
_ZN2cl4sycl10level_zero10make_queueERKNS0_7contextEm
_ZN2cl4sycl10level_zero10make_queueERKNS0_7contextEmb
_ZN2cl4sycl10level_zero11make_deviceERKNS0_8platformEm
_ZN2cl4sycl10level_zero12make_contextERKSt6vectorINS0_6deviceESaIS3_EEm
_ZN2cl4sycl10level_zero12make_contextERKSt6vectorINS0_6deviceESaIS3_EEmb
Expand Down Expand Up @@ -3741,7 +3741,7 @@ _ZN2cl4sycl6detail10image_implILi3EED0Ev
_ZN2cl4sycl6detail10image_implILi3EED1Ev
_ZN2cl4sycl6detail10image_implILi3EED2Ev
_ZN2cl4sycl6detail10make_eventEmRKNS0_7contextENS0_7backendE
_ZN2cl4sycl6detail10make_queueEmRKNS0_7contextERKSt8functionIFvNS0_14exception_listEEENS0_7backendE
_ZN2cl4sycl6detail10make_queueEmRKNS0_7contextEbRKSt8functionIFvNS0_14exception_listEEENS0_7backendE
_ZN2cl4sycl6detail10waitEventsESt6vectorINS0_5eventESaIS3_EE
_ZN2cl4sycl6detail11SYCLMemObjT10releaseMemESt10shared_ptrINS1_12context_implEEPv
_ZN2cl4sycl6detail11SYCLMemObjT16determineHostPtrERKSt10shared_ptrINS1_12context_implEEbRPvRb
Expand Down