44| -------------| --------|
55| Name | Default placeholders |
66| Date of Creation | 9 March 2019 |
7- | Revision | 0.1 |
8- | Latest Update | 9 March 2020 |
7+ | Revision | 0.2 |
8+ | Latest Update | 17 March 2020 |
99| Target | SYCL Next (after 1.2.1) |
1010| Current Status | _ Work in Progress_ |
1111| Reply-to
| Peter Žužek
< [email protected] > | @@ -48,7 +48,7 @@ but hasn't been registered with a command group
4848is more like a fancy pointer:
4949the user doesn't own the data
5050until the accessor is registered and used in a kernel,
51- where is becomes more similar to a regular pointer.
51+ where it becomes more similar to a regular pointer.
5252
5353Having this type separation between full accessors and placeholders
5454might be useful from a type safety perspective,
@@ -123,11 +123,43 @@ class handler {
123123};
124124```
125125
126+ `handler::require` has to be called on a placeholder accessor
127+ in order to register it with the command group submission.
128+ It is valid to call the function more than once,
129+ even on non-placeholder accessors.
130+ Calling the function on a null accessor throws `cl::sycl::invalid_object_error`.
131+
126132### Deprecate `is_placeholder`
127133
128134The function `accessor::is_placeholder` doesn't make sense anymore,
129135we propose deprecating it.
130136
137+ ### Allow constructing host accessors from placeholders
138+
139+ Consider the following example:
140+
141+ ```cpp
142+ template<typename AccTypeA, typename AccTypeB>
143+ void some_library_function(AccTypeA accA, AccTypeB accB) {
144+ ...
145+ myQueue.submit([&](handler &cgh) {
146+ cgh.require(accA);
147+ cgh.require(accB);
148+ cgh.copy(accA, accB);
149+ });
150+ ...
151+ // We want to be able to access host data now
152+ }
153+ ```
154+
155+ ` some_library_function ` in the example takes in two placeholder accessors
156+ and performs a copy from one to another.
157+ However, there is no way any of the data associated with the accessors
158+ can be accessed on the host.
159+ The placeholders are not bound to a command group anyway,
160+ so we believe it should be possible to explicitly construct a host accessor
161+ from a placeholder accessor.
162+
131163### New constructors
132164
133165We propose adding new constructors to the accessors class
@@ -144,6 +176,17 @@ to allow placeholder construction.
144176 normally an accessor constructor requires a buffer and a handler,
145177 we propose making the handler optional.
146178 This is the same constructor currently allowed for host buffers.
179+ 1 . Construct a host accessor from a placeholder one (` placeholderAcc ` ).
180+ Not valid to call in kernel code.
181+ Throws ` cl::sycl::runtime_error ` when called
182+ if ` placeholderAcc.has_handler() == true ` .
183+ Requesting host access is a synchronization point,
184+ and host accessors act as locks,
185+ meaning that the placeholder cannot be used
186+ while the host accessor is in scope.
187+ Even after host access is released,
188+ the programmer is required to call ` require ` again on the placeholder
189+ before it can be used in a kernel.
147190
148191``` cpp
149192template <typename dataT,
@@ -162,19 +205,29 @@ class accessor {
162205
163206 // 2
164207 // Only available when: ((accessTarget == access::target::global_buffer) ||
165- // (accessTarget == access::target::constant_buffer) ||
166- // (accessTarget == access::target::host_buffer)) &&
208+ // (accessTarget == access::target::constant_buffer)) &&
167209 // (dimensions == 0)
168210 accessor(buffer<dataT, 1> &bufferRef);
169211
170212 // 3
171213 // Only available when: ((accessTarget == access::target::global_buffer) ||
172- // (accessTarget == access::target::constant_buffer) ||
173- // (accessTarget == access::target::host_buffer)) &&
214+ // (accessTarget == access::target::constant_buffer)) &&
174215 // (dimensions > 0)
175216 accessor(buffer<dataT, dimensions> &bufferRef,
176217 range<dimensions > accessRange,
177218 id<dimensions > accessOffset = {});
219+
220+ // 4
221+ // Only available when (accessTarget == access::target::host_buffer) &&
222+ // ((otherTarget == access::target::global_buffer) ||
223+ // (otherTarget == access::target::constant_buffer))
224+ template <access::target otherTarget, access::placeholder otherPlaceholder>
225+ accessor(accessor<dataT,
226+ dimensions,
227+ accessMode,
228+ otherTarget,
229+ otherPlaceholder>&
230+ placeholderAcc);
178231};
179232```
180233
@@ -186,10 +239,16 @@ we propose new member functions to the `accessor class`:
1862391. `is_null` - returns `true` if the accessor has been default constructed,
187240 which is only possible with placeholders.
188241 Not having an associated buffer is analogous to a null pointer.
242+ Available in both application code and kernel code,
243+ it is valid to pass a null accessor to a kernel.
1892441. `has_handler` - returns `true` if the accessor is associated
190245 with a command group `handler`.
191246 Will only be `false` with host accessors and placeholder accessors.
192247 This replaces the `is_placeholder` member function.
248+ Mainly meant as a way to enquire about whether this is a placeholder or not,
249+ this doesn't have to be checked before `require` is called.
250+ 1. `get_host_access` - constructs a host accessor from a placeholder accessor.
251+ Not valid to call in kernel code.
193252
194253```cpp
195254template <typename dataT,
@@ -206,6 +265,16 @@ class accessor {
206265
207266 // 2
208267 bool has_handler() const noexcept;
268+
269+ // 3
270+ // Only available when ((accessTarget == access::target::global_buffer) ||
271+ // (accessTarget == access::target::constant_buffer))
272+ accessor<dataT,
273+ dimensions,
274+ accessMode,
275+ access::target::host_buffer,
276+ access::placeholder::false_t>
277+ get_host_access() const;
209278};
210279```
211280
@@ -256,7 +325,6 @@ myQueue.submit([&](handler &cgh) {
256325});
257326
258327// Submit kernel that writes to output buffer
259- // Use constant buffer accessors
260328buffer<int > bufC{bufRange};
261329accC = read_acc{bufC};
262330myQueue.submit([ &] (handler &cgh) {
0 commit comments