Skip to content

Commit f6581d6

Browse files
committed
[SYCL][Doc] Add kernel_function lambda wrapper
We previously removed the ability to pass properties directly to functions like single_task, parallel_for, etc, in favor of requiring them to be attached to the kernel. By introducing a new kernel_function wrapper that attaches properties to a kernel function, we remove the need for (most) developers to write such wrappers themselves. Signed-off-by: John Pennycook <[email protected]>
1 parent 03c2469 commit f6581d6

File tree

1 file changed

+57
-1
lines changed

1 file changed

+57
-1
lines changed

sycl/doc/extensions/experimental/sycl_ext_oneapi_kernel_properties.asciidoc

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ by the property, the implementation must throw a synchronous exception with the
287287

288288
|===
289289

290-
== Embedding Properties into a Kernel
290+
=== Embedding Properties into a Kernel
291291

292292
In other situations it may be useful to embed a kernel's properties directly
293293
into its type, to ensure that a kernel cannot be launched without a property
@@ -363,6 +363,62 @@ diagnostic; invalid combinations that can only be detected at run-time should
363363
result in an implementation throwing an `exception` with the `errc::invalid`
364364
error code.
365365

366+
=== Using Properties with Lambda Expressions
367+
368+
When a SYCL kernel is defined via a lambda expression, there is no way to
369+
define a `get` member function and subsequently no way to embed kernel
370+
properties. Instead, developers must wrap the lambda expression in an object.
371+
372+
To simplify this usage pattern, this extension defines a `kernel_function`
373+
that encapsulates a kernel function (which may be a lambda expression) and a
374+
property list.
375+
376+
NOTE: Developers are free to extend `kernel_function` or define their own
377+
wrapper classes (e.g., to attach commonly used property lists).
378+
379+
```c++
380+
namespace sycl::ext::oneapi::experimental {
381+
382+
template <typename Function, typename Properties = empty_properties_t>
383+
struct kernel_function {
384+
385+
kernel_function(Function f, Properties p = syclx::properties{});
386+
387+
// Available only if Function is invocable with Args
388+
template <typename... Args>
389+
void operator()(Args... args) const {
390+
f(std::forward<Args>(args)...);
391+
}
392+
393+
auto get(syclx::properties_tag) {
394+
return Properties{};
395+
}
396+
397+
private:
398+
const Function f; // exposition only
399+
400+
} // namespace sycl::ext::oneapi::experimental
401+
```
402+
403+
The example below shows how the `KernelFunctor` example from the previous
404+
section can be written using this wrapper:
405+
406+
```c++
407+
namespace syclx = sycl::ext::oneapi::experimental;
408+
409+
...
410+
411+
auto lambda = [=](id<1> i) const {
412+
a[i] = b[i] + c[i];
413+
}
414+
auto props = syclx::properties{syclx::work_group_size<8, 8>, syclx::sub_group_size<8>};
415+
auto kernel = syclx::kernel_function(lambda, props);
416+
417+
...
418+
419+
q.parallel_for(range<2>{16, 16}, kernel).wait();
420+
```
421+
366422
=== Querying Properties in a Compiled Kernel
367423

368424
Any properties embedded into a kernel type via a property list are reflected

0 commit comments

Comments
 (0)