Skip to content

Commit 4b6bd14

Browse files
tiwaria1GarveyJoe
andauthored
[SYCL][DOC] Add extension for FPGA kernel interface properties (#5715)
## SYCL extension contains the following new kernel properties - `streaming_interface<...>` - `register_map_interface<...>` The first two properties take enum arguments that provide the compiler information about whether the logic downstream to the kernel will back-pressure the kernel or not. - `pipelined<N>` Takes an integer, non-zero values specify minimum cycles between kernel invocations, and 0 specifies that pipelining should be disabled. Co-authored-by: GarveyJoe <[email protected]>
1 parent 084f34c commit 4b6bd14

File tree

1 file changed

+290
-0
lines changed

1 file changed

+290
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
= sycl_ext_intel_fpga_kernel_interface_properties
2+
:source-highlighter: coderay
3+
:coderay-linenums-mode: table
4+
5+
// This section needs to be after the document title.
6+
:doctype: book
7+
:toc2:
8+
:toc: left
9+
:encoding: utf-8
10+
:lang: en
11+
12+
:blank: pass:[ +]
13+
14+
// Set the default source code type in this document to C++,
15+
// for syntax highlighting purposes. This is needed because
16+
// docbook uses c++ and html5 uses cpp.
17+
:language: {basebackend@docbook:c++:cpp}
18+
19+
== Notice
20+
21+
[%hardbreaks]
22+
Copyright (c) 2021-2022 Intel Corporation. All rights reserved.
23+
24+
Khronos(R) is a registered trademark and SYCL(TM) and SPIR(TM) are trademarks
25+
of The Khronos Group Inc. OpenCL(TM) is a trademark of Apple Inc. used by
26+
permission by Khronos.
27+
28+
== Contact
29+
30+
To report problems with this extension, please open a new issue at:
31+
https://github.com/intel/llvm/issues
32+
33+
== Contributors
34+
35+
Joe Garvey, Intel +
36+
Abhishek Tiwari, Intel
37+
38+
== Dependencies
39+
40+
This extension is written against the SYCL 2020 specification, Revision 4 and
41+
the following extensions:
42+
43+
- link:../experimental/sycl_ext_oneapi_properties.asciidoc[sycl_ext_oneapi_properties]
44+
- link:sycl_ext_oneapi_kernel_properties.asciidoc[sycl_ext_oneapi_kernel_properties]
45+
46+
== Status
47+
48+
This is a proposed extension specification, intended to gather community
49+
feedback. Interfaces defined in this specification may not be implemented yet
50+
or may be in a preliminary state. The specification itself may also change in
51+
incompatible ways before it is finalized. *Shipping software products should not
52+
rely on APIs defined in this specification.*
53+
54+
== Overview
55+
56+
This extension introduces kernel properties to specify how or when control and
57+
data signals can be passed into or out of an FPGA kernel. These properties are
58+
meaningless on non-FPGA devices and can be ignored on such devices.
59+
60+
== Specification
61+
62+
=== Feature Test Macro
63+
64+
This extension provides a feature-test macro as described in the core SYCL
65+
specification section 6.3.3 "Feature test macros". Therefore, an
66+
implementation supporting this extension must predefine the macro
67+
`SYCL_EXT_INTEL_FPGA_KERNEL_INTERFACE_PROPERTIES` to one of the values defined
68+
in the table below. Applications can test for the existence of this macro to
69+
determine if the implementation supports this feature, or applications can test
70+
the macro's value to determine which of the extension's APIs the implementation
71+
supports.
72+
73+
[%header,cols="1,5"]
74+
|===
75+
|Value |Description
76+
|1 |Initial extension version. Base features are supported.
77+
|===
78+
79+
=== Introduction
80+
81+
This extension introduces new kernel properties that can be applied to kernels
82+
using the mechanism defined in sycl_ext_oneapi_kernel_properties.
83+
84+
=== Kernel Interface Properties
85+
86+
```c++
87+
namespace sycl::ext::intel::experimental {
88+
89+
enum class streaming_interface_options_enum {
90+
accept_downstream_stall,
91+
remove_downstream_stall
92+
};
93+
94+
enum class register_map_interface_options_enum {
95+
wait_for_done_write,
96+
do_not_wait_for_done_write
97+
};
98+
99+
struct streaming_interface_key {
100+
template <streaming_interface_options_enum option>
101+
using value_t = sycl::ext::oneapi::properties::property_value<
102+
streaming_interface_key,
103+
std::integral_constant<streaming_interface_options_enum, option>>;
104+
};
105+
106+
struct register_map_interface_key {
107+
template <register_map_interface_options_enum option>
108+
using value_t = sycl::ext::oneapi::properties::property_value<
109+
register_map_interface_key,
110+
std::integral_constant<register_map_interface_options_enum, option>>;
111+
};
112+
113+
struct pipelined_key {
114+
template <size_t pipeline_directive_or_initiation_interval>
115+
using value_t = sycl::ext::oneapi::properties::property_value<
116+
pipelined_key,
117+
std::integral_constant<size_t, pipeline_directive_or_initiation_interval>>;
118+
};
119+
120+
template <streaming_interface_options_enum option>
121+
inline constexpr streaming_interface_key::value_t<option> streaming_interface;
122+
123+
inline constexpr streaming_interface_key::value_t<
124+
streaming_interface_options_enum::accept_downstream_stall>
125+
streaming_interface_accept_downstream_stall;
126+
127+
inline constexpr streaming_interface_key::value_t<
128+
streaming_interface_options_enum::remove_downstream_stall>
129+
streaming_interface_remove_downstream_stall;
130+
131+
template <register_map_interface_options_enum option>
132+
inline constexpr register_map_interface_key::value_t<option>
133+
register_map_interface;
134+
135+
inline constexpr register_map_interface_key::value_t<
136+
register_map_interface_options_enum::wait_for_done_write>
137+
register_map_interface_wait_for_done_write;
138+
139+
inline constexpr register_map_interface_key::value_t<
140+
register_map_interface_options_enum::do_not_wait_for_done_write>
141+
register_map_interface_do_not_wait_for_done_write;
142+
143+
template<size_t pipeline_directive_or_initiation_interval>
144+
inline constexpr pipelined_key::value_t<
145+
pipeline_directive_or_initiation_interval> pipelined;
146+
147+
} // namespace sycl::ext::intel::experimental
148+
```
149+
150+
|===
151+
|Property|Description
152+
|`streaming_interface`
153+
|The `streaming_interface` property adds the requirement that the kernel must
154+
have dedicated ports for input / output signals. This applies for both
155+
control, and kernel argument data signals. The following values are supported:
156+
157+
* `accept_downstream_stall`: Directs the compiler to generate a kernel
158+
interface that can accept a back-pressure signal.
159+
160+
* `remove_downstream_stall`: Directs the compiler to generate a kernel
161+
interface that does not accept a back-pressure signal.
162+
163+
If the `streaming_interface` property is not specified, the default behavior is
164+
equivalent to one of the values listed above, but the choice is implementation
165+
defined.
166+
167+
The following properties have been provided for convenience:
168+
`streaming_interface_accept_downstream_stall`,
169+
`streaming_interface_remove_downstream_stall`.
170+
171+
|`register_map_interface`
172+
|The `register_map_interface` property adds the requirement that the kernel must
173+
have its input / output control and kernel argument data signals placed in a
174+
shared Control and Status Register (CSR) map. The following values are
175+
supported:
176+
177+
* `wait_for_done_write`: Directs the compiler to generate logic that
178+
back-pressures the kernel until the kernel is notified that its completion
179+
has been detected. The kernel will be notified when the register it writes
180+
its completion signal to is set to 0.
181+
182+
* `do_not_wait_for_done_write`: Directs the compiler to not generate logic that
183+
would back-pressure the kernel until the kernel is notified of its
184+
completion being detected.
185+
186+
If the `register_map_interface` property is not specified, the default behavior
187+
is equivalent to one of the values listed above, but the choice is
188+
implementation defined.
189+
190+
The following properties have been provided for convenience:
191+
`register_map_interface_wait_for_done_write`,
192+
`register_map_interface_do_not_wait_for_done_write`.
193+
194+
|`pipelined`
195+
|An unsigned integer value is accepted as property parameter.
196+
197+
When the parameter is set to a non zero value, the property directs the
198+
compiler to pipeline calls to the kernel such that multiple invocations of the
199+
kernel can be in flight simultaneously. The parameter value also specifies the
200+
minimum number of cycles between successive invocations of the kernel. Example:
201+
202+
* `pipelined<N>` - The compiler will pipeline multiple kernel invocations such
203+
that an invocation can be launched every `N` cycles if one is available.
204+
205+
When the parameter is set to `0`, the compiler will not pipeline kernel
206+
invocations.
207+
208+
If the `pipelined` property is not specified, the default behavior is
209+
equivalent to a combination of the property parameter values listed above, but
210+
the choice is implementation defined.
211+
|===
212+
213+
Device compilers that do not support this extension may accept and ignore these
214+
properties.
215+
216+
=== Adding a Property List to a Kernel Launch
217+
218+
A simple example of using this extension to launch a kernel with a streaming
219+
interface is shown below.
220+
221+
The example assumes that the kernel will not accept a signal that can
222+
back-pressure it and hence uses the property
223+
`streaming_interface_remove_downstream_stall`:
224+
225+
```c++
226+
using sycl::ext::intel::experimental;
227+
{
228+
...
229+
properties kernel_properties{streaming_interface_remove_downstream_stall};
230+
231+
q.single_task(kernel_properties, [=] {
232+
*a = *b + *c;
233+
}).wait();
234+
}
235+
```
236+
237+
The example below shows how to launch a pipelined kernel with a streaming
238+
interface, and with a new kernel invocation being launched every 2 cycles.
239+
240+
```c++
241+
using sycl::ext::intel::experimental;
242+
{
243+
...
244+
properties kernel_properties{
245+
streaming_interface_accept_downstream_stall, pipelined<2>};
246+
247+
q.single_task(kernel_properties, [=] {
248+
*a = *b + *c;
249+
}).wait();
250+
}
251+
```
252+
253+
=== Embedding Properties into a Kernel
254+
255+
The example below shows how the kernel from the previous section could be
256+
rewritten to leverage an embedded property list:
257+
258+
```c++
259+
using sycl::ext::intel::experimental;
260+
struct KernelFunctor {
261+
262+
KernelFunctor(int* a, int* b, int* c) : a(a), b(b), c(c) {}
263+
264+
void operator()() const {
265+
*a = *b + *c;
266+
}
267+
268+
auto get(properties_tag) {
269+
return properties{streaming_interface_accept_downstream_stall};
270+
}
271+
272+
int* a;
273+
int* b;
274+
int* c;
275+
};
276+
277+
...
278+
279+
q.single_task(KernelFunctor{a, b, c}).wait();
280+
```
281+
282+
== Revision History
283+
284+
[cols="5,15,15,70"]
285+
[grid="rows"]
286+
[options="header"]
287+
|========================================
288+
|Rev|Date|Author|Changes
289+
|1|2022-03-01|Abhishek Tiwari|*Initial public working draft*
290+
|========================================

0 commit comments

Comments
 (0)