Skip to content

[SYCL][PI][CUDA] Implements get_native interoperability #1332

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 4 commits into from
Apr 14, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions sycl/include/CL/sycl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <CL/sycl/accessor.hpp>
#include <CL/sycl/atomic.hpp>
#include <CL/sycl/backend.hpp>
#include <CL/sycl/backend/opencl.hpp>
#include <CL/sycl/buffer.hpp>
#include <CL/sycl/builtins.hpp>
#include <CL/sycl/context.hpp>
Expand Down
34 changes: 34 additions & 0 deletions sycl/include/CL/sycl/backend.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
//==---------------- backend.hpp - SYCL PI backends ------------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

#include <CL/sycl/accessor.hpp>
#include <CL/sycl/backend_types.hpp>

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {

template <backend BackendName, class SyclObjectT>
auto get_native(const SyclObjectT &Obj) ->
typename interop<BackendName, SyclObjectT>::type {
return Obj.template get_native<BackendName>();
}

// Native handle of an accessor should be accessed through interop_handler
template <backend BackendName, typename DataT, int Dimensions,
access::mode AccessMode, access::target AccessTarget,
access::placeholder IsPlaceholder>
auto get_native(const accessor<DataT, Dimensions, AccessMode, AccessTarget,
IsPlaceholder> &Obj) ->
typename interop<BackendName, accessor<DataT, Dimensions, AccessMode,
AccessTarget, IsPlaceholder>>::type =
delete;

} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
57 changes: 37 additions & 20 deletions sycl/include/CL/sycl/backend/cuda.hpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

//==---------------- cuda.hpp - SYCL CUDA backend --------------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
Expand All @@ -6,29 +7,45 @@
//
//===----------------------------------------------------------------------===//

#pragma once

#include <CL/sycl/accessor.hpp>
#include <CL/sycl/backend_types.hpp>
#include <CL/sycl/context.hpp>
#include <CL/sycl/detail/defines.hpp>
#include <CL/sycl/device.hpp>
#include <CL/sycl/event.hpp>
#include <CL/sycl/queue.hpp>

typedef int CUdevice;
typedef struct CUctx_st *CUcontext;
typedef struct CUstream_st *CUstream;
typedef struct CUevent_st *CUevent;

// As defined in the CUDA 10.1 header file. This requires CUDA version > 3.2
#if defined(_WIN64) || defined(__LP64__)
typedef unsigned long long CUdeviceptr;
#else
typedef unsigned int CUdeviceptr;
#endif

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {
namespace backend {
namespace cuda {

// CUDA backend specific options
// TODO: Use values that won't overlap with others

// Mem Object info: Retrieve the raw CUDA pointer from a cl_mem
#define PI_CUDA_RAW_POINTER (0xFF01)
// Context creation: Use a primary CUDA context instead of a custom one by
// providing a property value of PI_TRUE for the following
// property ID.
#define PI_CONTEXT_PROPERTIES_CUDA_PRIMARY (0xFF02)

// PI Command Queue using Default stream
#define PI_CUDA_USE_DEFAULT_STREAM (0xFF03)
// PI Command queue will sync with default stream
#define PI_CUDA_SYNC_WITH_DEFAULT (0xFF04)

} // namespace cuda
} // namespace backend

template <> struct interop<backend::cuda, device> { using type = CUdevice; };

template <> struct interop<backend::cuda, context> { using type = CUcontext; };

template <> struct interop<backend::cuda, queue> { using type = CUstream; };

template <> struct interop<backend::cuda, event> { using type = CUevent; };

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

} // namespace sycl
} // namespace cl
31 changes: 31 additions & 0 deletions sycl/include/CL/sycl/backend/opencl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

//==---------------- opencl.hpp - SYCL OpenCL backend ----------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

#include <CL/cl.h>
#include <CL/sycl/accessor.hpp>
#include <CL/sycl/backend_types.hpp>

__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {

template <> struct interop<backend::opencl, queue> {
using type = cl_command_queue;
};

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

} // namespace sycl
} // __SYCL_INLINE_NAMESPACE(cl)
19 changes: 19 additions & 0 deletions sycl/include/CL/sycl/backend_types.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//==-------------- backend_types.hpp - SYCL backend types ------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

namespace cl {
namespace sycl {

enum class backend { host, opencl, cuda };

template <backend name, typename SYCLObjectT> struct interop;

} // namespace sycl
} // namespace cl
13 changes: 13 additions & 0 deletions sycl/include/CL/sycl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//

#pragma once

#include <CL/sycl/backend_types.hpp>
#include <CL/sycl/detail/common.hpp>
#include <CL/sycl/detail/export.hpp>
#include <CL/sycl/exception_list.hpp>
Expand Down Expand Up @@ -135,10 +137,21 @@ class __SYCL_EXPORT context {
/// \return a vector of valid SYCL device instances.
vector_class<device> get_devices() const;

/// Gets the native handle of the SYCL context.
///
/// \return a native handle, the type of which defined by the backend.
template <backend BackendName>
auto get_native() const -> typename interop<BackendName, context>::type {
return reinterpret_cast<typename interop<BackendName, context>::type>(
getNative());
}

private:
/// Constructs a SYCL context object from a valid context_impl instance.
context(shared_ptr_class<detail::context_impl> Impl);

pi_native_handle getNative() const;

shared_ptr_class<detail::context_impl> impl;
template <class Obj>
friend decltype(Obj::impl) detail::getSyclObjImpl(const Obj &SyclObject);
Expand Down
54 changes: 43 additions & 11 deletions sycl/include/CL/sycl/detail/cg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#pragma once

#include <CL/sycl/backend_types.hpp>
#include <CL/sycl/detail/accessor_impl.hpp>
#include <CL/sycl/detail/common.hpp>
#include <CL/sycl/detail/export.hpp>
Expand All @@ -29,6 +30,12 @@
__SYCL_INLINE_NAMESPACE(cl) {
namespace sycl {

// Forward declaration
class queue;
namespace detail {
class queue_impl;
} // namespace detail

// Interoperability handler
//
class interop_handler {
Expand All @@ -37,26 +44,51 @@ class interop_handler {
access::target AccTarget, access::placeholder isPlaceholder>
friend class accessor;
public:
using QueueImplPtr = std::shared_ptr<detail::queue_impl>;
using ReqToMem = std::pair<detail::Requirement*, pi_mem>;

interop_handler(std::vector<ReqToMem> MemObjs, cl_command_queue PiQueue) :
MQueue(PiQueue), MMemObjs(MemObjs) {}
interop_handler(std::vector<ReqToMem> MemObjs, QueueImplPtr Queue)
: MQueue(std::move(Queue)), MMemObjs(std::move(MemObjs)) {}

cl_command_queue get_queue() const noexcept { return MQueue; };
template <backend BackendName = backend::opencl>
auto get_queue() const -> typename interop<BackendName, queue>::type {
return reinterpret_cast<typename interop<BackendName, queue>::type>(
GetNativeQueue());
}

template <typename DataT, int Dims, access::mode AccessMode,
access::target AccessTarget,
template <backend BackendName = backend::opencl, typename DataT, int Dims,
access::mode AccessMode, access::target AccessTarget,
access::placeholder IsPlaceholder = access::placeholder::false_t>
cl_mem get_mem(accessor<DataT, Dims, AccessMode, AccessTarget,
access::placeholder::false_t>
Acc) const {
auto get_mem(accessor<DataT, Dims, AccessMode, AccessTarget,
access::placeholder::false_t>
Acc) const ->
typename interop<BackendName,
accessor<DataT, Dims, AccessMode, AccessTarget,
access::placeholder::false_t>>::type {
detail::AccessorBaseHost *AccBase = (detail::AccessorBaseHost *)&Acc;
return getMemImpl(detail::getSyclObjImpl(*AccBase).get());
return getMemImpl<BackendName, DataT, Dims, AccessMode, AccessTarget,
access::placeholder::false_t>(
detail::getSyclObjImpl(*AccBase).get());
}

private:
cl_command_queue MQueue;
QueueImplPtr MQueue;
std::vector<ReqToMem> MMemObjs;
__SYCL_EXPORT cl_mem getMemImpl(detail::Requirement *Req) const;

template <backend BackendName, typename DataT, int Dims,
access::mode AccessMode, access::target AccessTarget,
access::placeholder IsPlaceholder>
__SYCL_EXPORT auto
getMemImpl(detail::Requirement *Req) const -> typename interop<
BackendName,
accessor<DataT, Dims, AccessMode, AccessTarget, IsPlaceholder>>::type {
return (typename interop<BackendName,
accessor<DataT, Dims, AccessMode, AccessTarget,
IsPlaceholder>>::type)GetNativeMem(Req);
}

__SYCL_EXPORT pi_native_handle GetNativeMem(detail::Requirement *Req) const;
__SYCL_EXPORT pi_native_handle GetNativeQueue() const;
};

namespace detail {
Expand Down
24 changes: 24 additions & 0 deletions sycl/include/CL/sycl/detail/cuda_definitions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//==------------ cuda_definitions.hpp - SYCL CUDA backend ------------------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#pragma once

// CUDA backend specific options
// TODO: Use values that won't overlap with others

// Mem Object info: Retrieve the raw CUDA pointer from a cl_mem
#define PI_CUDA_RAW_POINTER (0xFF01)
// Context creation: Use a primary CUDA context instead of a custom one by
// providing a property value of PI_TRUE for the following
// property ID.
#define PI_CONTEXT_PROPERTIES_CUDA_PRIMARY (0xFF02)

// PI Command Queue using Default stream
#define PI_CUDA_USE_DEFAULT_STREAM (0xFF03)
// PI Command queue will sync with default stream
#define PI_CUDA_SYNC_WITH_DEFAULT (0xFF04)
14 changes: 12 additions & 2 deletions sycl/include/CL/sycl/detail/pi.def
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,31 @@
_PI_API(piPlatformsGet)
_PI_API(piPlatformGetInfo)
// Device
_PI_API(piextDeviceConvert)
_PI_API(piDevicesGet)
_PI_API(piDeviceGetInfo)
_PI_API(piDevicePartition)
_PI_API(piDeviceRetain)
_PI_API(piDeviceRelease)
_PI_API(piextDeviceSelectBinary)
_PI_API(piextGetDeviceFunctionPointer)
_PI_API(piextDeviceGetNativeHandle)
_PI_API(piextDeviceCreateWithNativeHandle)
// Context
_PI_API(piContextCreate)
_PI_API(piContextGetInfo)
_PI_API(piContextRetain)
_PI_API(piContextRelease)
_PI_API(piextContextSetExtendedDeleter)
_PI_API(piextContextGetNativeHandle)
_PI_API(piextContextCreateWithNativeHandle)
// Queue
_PI_API(piQueueCreate)
_PI_API(piQueueGetInfo)
_PI_API(piQueueFinish)
_PI_API(piQueueRetain)
_PI_API(piQueueRelease)
_PI_API(piextQueueGetNativeHandle)
_PI_API(piextQueueCreateWithNativeHandle)
// Memory
_PI_API(piMemBufferCreate)
_PI_API(piMemImageCreate)
Expand All @@ -46,8 +51,9 @@ _PI_API(piMemImageGetInfo)
_PI_API(piMemRetain)
_PI_API(piMemRelease)
_PI_API(piMemBufferPartition)
_PI_API(piextMemGetNativeHandle)
_PI_API(piextMemCreateWithNativeHandle)
// Program
_PI_API(piextProgramConvert)
_PI_API(piProgramCreate)
_PI_API(piclProgramCreateWithSource)
_PI_API(piclProgramCreateWithBinary)
Expand All @@ -59,6 +65,8 @@ _PI_API(piProgramGetBuildInfo)
_PI_API(piProgramRetain)
_PI_API(piProgramRelease)
_PI_API(piextProgramSetSpecializationConstant)
_PI_API(piextProgramGetNativeHandle)
_PI_API(piextProgramCreateWithNativeHandle)
// Kernel
_PI_API(piKernelCreate)
_PI_API(piKernelSetArg)
Expand All @@ -78,6 +86,8 @@ _PI_API(piEventSetCallback)
_PI_API(piEventSetStatus)
_PI_API(piEventRetain)
_PI_API(piEventRelease)
_PI_API(piextEventGetNativeHandle)
_PI_API(piextEventCreateWithNativeHandle)
// Sampler
_PI_API(piSamplerCreate)
_PI_API(piSamplerGetInfo)
Expand Down
Loading