4
4
| -------------| --------|
5
5
| Name | Default placeholders |
6
6
| 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 |
9
9
| Target | SYCL Next (after 1.2.1) |
10
10
| Current Status | _ Work in Progress_ |
11
11
| Reply-to
| Peter Žužek
< [email protected] > |
@@ -48,7 +48,7 @@ but hasn't been registered with a command group
48
48
is more like a fancy pointer:
49
49
the user doesn't own the data
50
50
until 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.
52
52
53
53
Having this type separation between full accessors and placeholders
54
54
might be useful from a type safety perspective,
@@ -123,11 +123,43 @@ class handler {
123
123
};
124
124
```
125
125
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
+
126
132
### Deprecate `is_placeholder`
127
133
128
134
The function `accessor::is_placeholder` doesn't make sense anymore,
129
135
we propose deprecating it.
130
136
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
+
131
163
### New constructors
132
164
133
165
We propose adding new constructors to the accessors class
@@ -144,6 +176,17 @@ to allow placeholder construction.
144
176
normally an accessor constructor requires a buffer and a handler,
145
177
we propose making the handler optional.
146
178
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.
147
190
148
191
``` cpp
149
192
template <typename dataT,
@@ -162,19 +205,29 @@ class accessor {
162
205
163
206
// 2
164
207
// 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)) &&
167
209
// (dimensions == 0)
168
210
accessor(buffer<dataT, 1> &bufferRef);
169
211
170
212
// 3
171
213
// 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)) &&
174
215
// (dimensions > 0)
175
216
accessor(buffer<dataT, dimensions> &bufferRef,
176
217
range<dimensions > accessRange,
177
218
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);
178
231
};
179
232
```
180
233
@@ -186,10 +239,16 @@ we propose new member functions to the `accessor class`:
186
239
1. `is_null` - returns `true` if the accessor has been default constructed,
187
240
which is only possible with placeholders.
188
241
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.
189
244
1. `has_handler` - returns `true` if the accessor is associated
190
245
with a command group `handler`.
191
246
Will only be `false` with host accessors and placeholder accessors.
192
247
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.
193
252
194
253
```cpp
195
254
template <typename dataT,
@@ -206,6 +265,16 @@ class accessor {
206
265
207
266
// 2
208
267
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;
209
278
};
210
279
```
211
280
@@ -256,7 +325,6 @@ myQueue.submit([&](handler &cgh) {
256
325
});
257
326
258
327
// Submit kernel that writes to output buffer
259
- // Use constant buffer accessors
260
328
buffer<int > bufC{bufRange};
261
329
accC = read_acc{bufC};
262
330
myQueue.submit([ &] (handler &cgh) {
0 commit comments