Skip to content

Commit f37a294

Browse files
author
Sergey Kanaev
committed
[SYCL] Introduce interop handle for host task
Signed-off-by: Sergey Kanaev <[email protected]>
1 parent 76eab93 commit f37a294

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//==------------ interop_handle.hpp --- SYCL interop handle ----------------==//
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/access/access.hpp>
12+
#include <CL/sycl/detail/accessor_impl.hpp>
13+
#include <CL/sycl/detail/common.hpp>
14+
#include <CL/sycl/detail/defines.hpp>
15+
#include <CL/sycl/detail/pi.hpp>
16+
17+
#include <memory>
18+
19+
__SYCL_INLINE_NAMESPACE(cl) {
20+
namespace sycl {
21+
22+
namespace detail {
23+
class AccessorBaseHost;
24+
class ExecCGCommand;
25+
class DispatchHostTask;
26+
} // namespace detail
27+
28+
template <typename DataT, int Dims, access::mode AccMode,
29+
access::target AccTarget, access::placeholder isPlaceholder>
30+
class accessor;
31+
32+
class interop_handle {
33+
public:
34+
/// Receives a SYCL accessor that has been defined is a requirement for the
35+
/// command group, and returns the underlying OpenCL memory object that is
36+
/// used by the SYCL runtime. If the accessor passed as parameter is not part
37+
/// of the command group requirements (e.g. it is an unregistered placeholder
38+
/// accessor), the exception `cl::sycl::invalid_object` is thrown
39+
/// asynchronously.
40+
template <typename dataT, int dimensions, access::mode accessmode,
41+
access::target accessTarget, access::placeholder isPlaceholder>
42+
typename std::enable_if<accessTarget != access::target::host_buffer,
43+
cl_mem>::type
44+
get_native_mem(const accessor<dataT, dimensions, accessmode, accessTarget,
45+
isPlaceholder> &Acc) const {
46+
#ifndef __SYCL_DEVICE_ONLY__
47+
// employ reinterpret_cast instead of static_cast due to cycle in includes
48+
// involving CL/sycl/accessor.hpp
49+
auto *AccBase = const_cast<detail::AccessorBaseHost *>(
50+
reinterpret_cast<const detail::AccessorBaseHost *>(&Acc));
51+
return getMemImpl(detail::getSyclObjImpl(*AccBase).get());
52+
#else
53+
(void)Acc;
54+
// we believe this won't be ever called on device side
55+
return static_cast<cl_mem>(0x0);
56+
#endif
57+
}
58+
59+
template <typename dataT, int dimensions, access::mode accessmode,
60+
access::target accessTarget, access::placeholder isPlaceholder>
61+
typename std::enable_if<accessTarget == access::target::host_buffer,
62+
cl_mem>::type
63+
get_native_mem(const accessor<dataT, dimensions, accessmode, accessTarget,
64+
isPlaceholder> &) const {
65+
throw invalid_object_error("Getting memory object out of host accessor is "
66+
"not allowed",
67+
PI_INVALID_MEM_OBJECT);
68+
}
69+
70+
/// Returns an underlying OpenCL queue for the SYCL queue used to submit the
71+
/// command group, or the fallback queue if this command-group is re-trying
72+
/// execution on an OpenCL queue. The OpenCL command queue returned is
73+
/// implementation-defined in cases where the SYCL queue maps to multiple
74+
/// underlying OpenCL objects. It is responsibility of the SYCL runtime to
75+
/// ensure the OpenCL queue returned is in a state that can be used to
76+
/// dispatch work, and that other potential OpenCL command queues associated
77+
/// with the same SYCL command queue are not executing commands while the host
78+
/// task is executing.
79+
cl_command_queue get_native_queue() const noexcept { return MQueue; }
80+
81+
/// Returns an underlying OpenCL device associated with the SYCL queue used
82+
/// to submit the command group, or the fallback queue if this command-group
83+
/// is re-trying execution on an OpenCL queue.
84+
cl_device_id get_native_device() const noexcept { return MDeviceId; }
85+
86+
/// Returns an underlying OpenCL context associated with the SYCL queue used
87+
/// to submit the command group, or the fallback queue if this command-group
88+
/// is re-trying execution on an OpenCL queue.
89+
cl_context get_native_context() const noexcept { return MContext; }
90+
91+
private:
92+
using ReqToMem = std::pair<detail::Requirement *, pi_mem>;
93+
94+
template <typename DataT, int Dims, access::mode AccMode,
95+
access::target AccTarget, access::placeholder isPlaceholder>
96+
friend class accessor;
97+
friend class detail::ExecCGCommand;
98+
friend class detail::DispatchHostTask;
99+
100+
public:
101+
// TODO set c-tor private
102+
interop_handle(std::vector<ReqToMem> MemObjs, cl_command_queue Queue,
103+
cl_device_id DeviceId, cl_context Context)
104+
: MQueue(Queue), MDeviceId(DeviceId), MContext(Context),
105+
MMemObjs(std::move(MemObjs)) {}
106+
107+
private:
108+
cl_mem getMemImpl(detail::Requirement *Req) const;
109+
110+
cl_command_queue MQueue;
111+
cl_device_id MDeviceId;
112+
cl_context MContext;
113+
std::vector<ReqToMem> MMemObjs;
114+
};
115+
116+
} // namespace sycl
117+
} // __SYCL_INLINE_NAMESPACE(cl)

sycl/source/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ set(SYCL_SOURCES
150150
"sampler.cpp"
151151
"stream.cpp"
152152
"spirv_ops.cpp"
153+
"interop_handle.cpp"
153154
"$<$<PLATFORM_ID:Windows>:detail/windows_pi.cpp>"
154155
"$<$<OR:$<PLATFORM_ID:Linux>,$<PLATFORM_ID:Darwin>>:detail/posix_pi.cpp>"
155156
)

sycl/source/interop_handle.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//==------------ interop_handle.cpp --- SYCL interop handle ----------------==//
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+
#include <CL/sycl/detail/accessor_impl.hpp>
10+
#include <CL/sycl/interop_handle.hpp>
11+
12+
#include <algorithm>
13+
14+
__SYCL_INLINE_NAMESPACE(cl) {
15+
namespace sycl {
16+
17+
cl_mem interop_handle::getMemImpl(detail::Requirement *Req) const {
18+
auto Iter = std::find_if(std::begin(MMemObjs), std::end(MMemObjs),
19+
[=](ReqToMem Elem) { return (Elem.first == Req); });
20+
21+
if (Iter == std::end(MMemObjs))
22+
throw("Invalid memory object used inside interop");
23+
24+
return detail::pi::cast<cl_mem>(Iter->second);
25+
}
26+
27+
} // namespace sycl
28+
} // __SYCL_INLINE_NAMESPACE(cl)

0 commit comments

Comments
 (0)