Skip to content

Commit c66a9a7

Browse files
Victor LomullerNaghasan
authored andcommitted
Add proposal for interop_task
This proposal add the possibility for a user to retrieve cl_mem object in a friendly way for SYCL data-flow model
1 parent 4a07c77 commit c66a9a7

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

interop_task/interop_task.md

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
| Proposal ID | TBC |
2+
|-------------|--------|
3+
| Name | |
4+
| Date of Creation | 16 January 2019 |
5+
| Target | SYCL 1.2.1 extension |
6+
| Current Status | _Work in progress_ |
7+
| Reply-to | Victor Lomüller <victor@codeplay.com> |
8+
| Original author | Victor Lomüller <victor@codeplay.com>, Gordon Brown <gordon@codeplay.com>, Peter Zuzek <peter@codeplay.com> |
9+
| Contributors | Victor Lomüller <victor@codeplay.com>, Gordon Brown <gordon@codeplay.com>, Peter Zuzek <peter@codeplay.com> |
10+
11+
# interop_task: Improving SYCL-OpenCL Interoperability
12+
13+
## Motivation
14+
15+
OpenCL applications often build around a set of of fixed function operations which take OpenCL buffers in order to run a hard-coded OpenCL kernels. However, because SYCL does not allow a user to access cl_mem object out of an cl::sycl::accessor, it difficult/impossible to integrate such library into a SYCL application, as the only current way to do this is to create all OpenCL buffers up-front, which is not always possible.
16+
17+
This proposal introduces a way for a user to retrieve the OpenCL buffer associate with a SYCL buffer and enqueue a host task that can execute an arbitrary portion of host code within the SYCL runtime, therefore taking advantage of SYCL dependency analysis and scheduling.
18+
19+
## Enqueuing host tasks on SYCL queues
20+
21+
We introduce a new type of handler, the **codeplay::handler**, which includes a new
22+
**interop\_task** method that executes a task on the host.
23+
By submitting this command group to the SYCL device queue, we guarantee it is
24+
executed in-order w.r.t the other command groups on the same queue.
25+
Simultaneously, we guarantee that this operation is performed
26+
asynchronously w.r.t to the user-thread (therefore, enabling the user
27+
thread to continue submitting command groups).
28+
Other command groups enqueued in the same or different queues
29+
can be executed following the sequential consistency by guaranteeing the
30+
satisfaction of the requisites of this command group.
31+
32+
The possibility of enqueuing host tasks on SYCL queues also enables the
33+
runtime to perform further optimizations when available.
34+
For example, a SYCL runtime may decide to map / unmap instead of copy operations,
35+
or performing asynchronous transfers while data is being computed.
36+
37+
### cl::sycl::codeplay::handler
38+
39+
```cpp
40+
namespace cl {
41+
namespace sycl {
42+
namespace codeplay {
43+
44+
class handler : public cl::sycl::handler {
45+
private:
46+
// implementation defined constructor
47+
handler(__unspecified__);
48+
49+
public:
50+
/* "Manually" enqueue a kernel */
51+
template <typename FunctorT>
52+
void interop_task(FunctorT hostFunction);
53+
};
54+
} // namespace codeplay
55+
} // namespace sycl
56+
} // namespace cl
57+
```
58+
59+
### codeplay::handler::interop_task
60+
61+
The `interop_task` allow the user to execute a task of the native host.
62+
Unlike `single_task`, `parallel_for` and `parallel_for_work_group`, the `interop_task` do not enqueue a kernel on the device but allow the user to execute a custom action when the prerequisites are satisfied on the device associate with the queue.
63+
The functor passed to the `interop_task` takes as input a const reference to a `cl::sycl::codeplay::interop_handle` which can be used to retrieve underlying OpenCL objects relative to the execution of the task.
64+
65+
It is not allowed to allocate new SYCL object inside an `interop_task`.
66+
It is the user responsibilities to ensure all asynchronous executions using SYCL provided resources finished before returning from the `interop_task`.
67+
68+
## Accessing Underlying OpenCL Object
69+
70+
We introduce the `interop_handle` class which provide access to underlying OpenCL objects during the execution of the `interop_task`.
71+
72+
The interface of the `interop_handle` is defined as follow:
73+
```cpp
74+
namespace cl {
75+
namespace sycl {
76+
namespace codeplay {
77+
78+
class interop_handle {
79+
private:
80+
// implementation defined constructor
81+
interop_handle(__unspecified__);
82+
83+
public:
84+
/* Return the context */
85+
cl_context get_context() const;
86+
87+
/* Return the device id */
88+
cl_device_id get_device() const;
89+
90+
/* Return the command queue associated with this task */
91+
cl_command_queue get_queue() const;
92+
93+
/*
94+
Returns the underlying cl_mem object associated with the accessor
95+
*/
96+
template <typename dataT, int dimensions, access::mode accessmode,
97+
access::target accessTarget,
98+
access::placeholder isPlaceholder>
99+
cl_mem get(const accessor<dataT, dimensions, accessmode, access::target accessTarget, access::placeholder isPlaceholder>&) const;
100+
};
101+
} // namespace codeplay
102+
} // namespace sycl
103+
} // namespace cl
104+
```
105+
106+
`interop_handle` objects are immutable object whose purpose is to allow the user to access objects relevant to the context.
107+
108+
## Example using regular accessor
109+
110+
```cpp
111+
auto cgH = [=] (codeplay::handler& cgh) {
112+
auto accA = bufA.get_access<access::mode::read>(cgh); // Get device accessor to SYCL buffer (cannot be dereference directly in interop_task).
113+
auto accB = bufB.get_access<access::mode::read_write>(cgh);
114+
115+
h.interop_task([=](codeplay::interop_handle &handle) {
116+
third_party_api(handle.get_queue(), // Get the OpenCL command queue to use, can be the fallback
117+
handle.get(accA), // Get the OpenCL mem object behind accA
118+
handle.get(accB)); // Get the OpenCL mem object behind accB
119+
// Assumes call has finish when exiting the task
120+
});
121+
};
122+
qA.submit(cgH);
123+
```

0 commit comments

Comments
 (0)