Skip to content

Commit 8bbebf5

Browse files
[SYCL] Updated Level-Zero backend spec according to SYCL 2020 standard (#4560)
Signed-off-by: Sergey V Maslov <[email protected]> Co-authored-by: vladimirlaz <[email protected]>
1 parent 15e0ab1 commit 8bbebf5

File tree

1 file changed

+171
-32
lines changed

1 file changed

+171
-32
lines changed

sycl/doc/extensions/LevelZeroBackend/LevelZeroBackend.md

+171-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Level-Zero backend specification
1+
# Level-Zero backend specification
22

33
## 1. Introduction
44

@@ -7,8 +7,15 @@ It is built on top of Level-Zero runtime enabled with [Level-Zero API](https://s
77
The Level-Zero backend is aimed to provide the best possible performance of SYCL application on a variety of targets supported.
88
The currently supported targets are all Intel GPUs starting with Gen9.
99

10-
NOTE: This specification is a draft. While describing the currently implemented behaviors it is known to be not complete nor exhaustive.
11-
We shall continue to add more information, e.g. explain general mapping of SYCL programming model to Level-Zero API.
10+
This extension provides a feature-test macro as described in the core SYCL specification section 6.3.3 "Feature test macros". Therefore, an implementation supporting this extension must predefine the macro SYCL_EXT_ONEAPI_BACKEND_LEVEL_ZERO to one of the values defined in the table below. Applications can test for the existence of this macro to determine if the implementation supports this feature, or applications can test the macro’s value to determine which of the extension’s APIs the implementation supports.
11+
12+
13+
|Value|Description|
14+
|---|:---|
15+
|1|Initial extension version.
16+
17+
NOTE: This extension is following SYCL 2020 backend specification. Prior API for interoperability with Level-Zero is marked
18+
as deprecated and will be removed in the next release.
1219

1320
## 2. Prerequisites
1421

@@ -17,7 +24,7 @@ For further details see <https://software.intel.com/content/www/us/en/develop/ar
1724

1825
## 3. User-visible Level-Zero backend selection (and the default backend)
1926

20-
The Level-Zero backend is added to the cl::sycl::backend enumeration:
27+
The Level-Zero backend is added to the sycl::backend enumeration:
2128

2229
``` C++
2330
enum class backend {
@@ -44,7 +51,7 @@ programmatically select the Level-Zero backend.
4451
4552
When neither the environment variable nor the filtering device selector are used, the implementation chooses
4653
the Level-Zero backend for GPU devices supported by the installed Level-Zero runtime.
47-
The serving backend for a SYCL platform can be queried with the ```get_backend()``` member function of ```cl::sycl::platform```.
54+
The serving backend for a SYCL platform can be queried with the ```get_backend()``` member function of ```sycl::platform```.
4855
4956
## 4. Interoperability with the Level-Zero API
5057
@@ -58,39 +65,170 @@ and they must be included in the order shown:
5865
```
5966
### 4.1 Mapping of SYCL objects to Level-Zero handles
6067

61-
These SYCL objects encapsulate the corresponding Level-Zero handles:
62-
| SYCL object | Level-Zero handle |
63-
|-------------|:------------|
64-
|platform |ze_driver_handle_t|
65-
|device |ze_device_handle_t|
66-
|context |ze_context_handle_t|
67-
|queue |ze_command_queue_handle_t|
68-
|event |ze_event_handle_t|
69-
|program |ze_module_handle_t|
68+
SYCL objects encapsulate the corresponding Level-Zero handles and this extension provides the following specialization of the interoperability types:
69+
70+
<table>
71+
<tr>
72+
<th>SyclType</th>
73+
<th>
74+
75+
``` C++
76+
backend_return_t<backend::ext_oneapi_level_zero,
77+
SyclType>
78+
```
79+
</th>
80+
<th>
81+
82+
``` C++
83+
backend_input_t<backend::ext_oneapi_level_zero,
84+
SyclType>
85+
```
86+
</th>
87+
</tr><tr>
88+
<td>platform</td>
89+
<td><pre>ze_driver_handle_t</pre></td>
90+
<td><pre>ze_driver_handle_t</pre></td>
91+
</tr><tr>
92+
<td>device</td>
93+
<td><pre>ze_device_handle_t</pre></td>
94+
<td><pre>ze_device_handle_t</pre></td>
95+
</tr><tr>
96+
<td>context</td>
97+
<td><pre>ze_context_handle_t</pre></td>
98+
<td>
99+
100+
``` C++
101+
struct {
102+
ze_context_handle_t NativeHandle;
103+
std::vector<device> DeviceList;
104+
ext::oneapi::level_zero::ownership Ownership;
105+
}
106+
```
107+
</td>
108+
</tr><tr>
109+
<td>queue</td>
110+
<td><pre>ze_command_queue_handle_t</pre></td>
111+
<td>
112+
113+
``` C++
114+
struct {
115+
ze_command_queue_handle_t NativeHandle;
116+
ext::oneapi::level_zero::ownership Ownership;
117+
}
118+
```
119+
</td>
120+
</tr><tr>
121+
<td>event</td>
122+
<td><pre>ze_event_handle_t</pre></td>
123+
<td>
124+
125+
``` C++
126+
struct {
127+
ze_event_handle_t NativeHandle;
128+
ext::oneapi::level_zero::ownership Ownership;
129+
}
130+
```
131+
</td>
132+
</tr><tr>
133+
<td>kernel_bundle</td>
134+
<td>
135+
136+
``` C++
137+
std::vector<ze_module_handle_t>
138+
```
139+
</td>
140+
<td><pre>ze_module_handle_t</pre></td>
141+
</tr>
142+
</table>
70143

71144
### 4.2 Obtaining of native Level-Zero handles from SYCL objects
72145
73-
The ```get_native<cl::sycl::backend::ext_oneapi_level_zero>()``` member function is how a raw native Level-Zero handle can be obtained
74-
for a specific SYCL object. It is currently supported for SYCL ```platform```, ```device```, ```context```, ```queue```, ```event```
75-
and ```program``` classes. There is also a free-function defined in ```cl::sycl``` namespace that can be used instead of the member function:
146+
The ```sycl::get_native<backend::ext_oneapi_level_zero>``` free-function is how a raw native Level-Zero handle can be obtained
147+
for a specific SYCL object.
76148
``` C++
77149
template <backend BackendName, class SyclObjectT>
78-
auto get_native(const SyclObjectT &Obj) ->
79-
typename interop<BackendName, SyclObjectT>::type;
150+
auto get_native(const SyclObjectT &Obj)
151+
-> backend_return_t<BackendName, SyclObjectT>
80152
```
153+
It is currently supported for SYCL ```platform```, ```device```, ```context```, ```queue```, ```event```
154+
and ```kernel_bundle``` classes.
155+
81156
### 4.3 Construct a SYCL object from a Level-Zero handle
82157
83-
The following free functions defined in the ```cl::sycl::ext::oneapi::level_zero``` namespace allow an application to create
84-
a SYCL object that encapsulates a corresponding Level-Zero object:
85-
86-
| Level-Zero interoperability function |Description|
87-
|-------------|:------------|
88-
|``` make<platform>(ze_driver_handle_t);```|Constructs a SYCL platform instance from a Level-Zero ```ze_driver_handle_t```.|
89-
|``` make<device>(const platform &, ze_device_handle_t);```|Constructs a SYCL device instance from a Level-Zero ```ze_device_handle_t```. The platform argument gives a SYCL platform, encapsulating a Level-Zero driver supporting the passed Level-Zero device.|
90-
|``` make<context>(const std::vector<device> &, ze_context_handle_t, ownership = transfer);```| Constructs a SYCL context instance from a Level-Zero ```ze_context_handle_t```. The context is created against the devices passed in. There must be at least one device given and all the devices must be from the same SYCL platform and thus from the same Level-Zero driver. The ```ownership``` argument specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.|
91-
|``` make<queue>(const context &, ze_command_queue_handle_t, ownership = transfer);```| Constructs a SYCL queue instance from a Level-Zero ```ze_command_queue_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The queue is attached to the first device in the passed SYCL context. The ```ownership``` argument specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.|
92-
|``` make<event>(const context &, ze_event_handle_t, ownership = transfer);```| Constructs a SYCL event instance from a Level-Zero ```ze_event_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The Level-Zero event should be allocated from an event pool created in the same context. The ```ownership``` argument specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.|
93-
|``` make<program>(const context &, ze_module_handle_t);```| Constructs a SYCL program instance from a Level-Zero ```ze_module_handle_t```. The context argument must be a valid SYCL context encapsulating a Level-Zero context. The Level-Zero module must be fully linked (i.e. not require further linking through [```zeModuleDynamicLink```](https://spec.oneapi.com/level-zero/latest/core/api.html?highlight=zemoduledynamiclink#_CPPv419zeModuleDynamicLink8uint32_tP18ze_module_handle_tP28ze_module_build_log_handle_t)), and thus the SYCL program is created in the "linked" state.|
158+
The following free functions defined in the ```sycl``` namespace are specialized for Level-Zero backend to allow
159+
an application to create a SYCL object that encapsulates a corresponding Level-Zero object:
160+
161+
<table>
162+
<tr>
163+
<th>Level-Zero interoperability function</th>
164+
<th style="text-align:left"> Description</th>
165+
</tr><tr>
166+
<td>
167+
168+
``` C++
169+
make_platform<backend::ext_oneapi_level_zero>(
170+
const backend_input_t<
171+
backend::ext_oneapi_level_zero, platform> &)
172+
```
173+
</td>
174+
<td>Constructs a SYCL platform instance from a Level-Zero <code>ze_driver_handle_t</code>. The SYCL execution environment contains a fixed number of platforms that are enumerated via <code>sycl::platform::get_platforms()</code>. Calling this function does not create a new platform. Rather it merely creates a <code>sycl::platform</code> object that is a copy of one of the platforms from that enumeration.</td>
175+
</tr><tr>
176+
<td>
177+
178+
``` C++
179+
make_device<backend::ext_oneapi_level_zero>(
180+
const backend_input_t<
181+
backend::ext_oneapi_level_zero, device> &)
182+
```
183+
</td>
184+
<td>Constructs a SYCL device instance from a Level-Zero <code>ze_device_handle_t</code>. The SYCL execution environment for the Level Zero backend contains a fixed number of devices that are enumerated via <code>sycl::device::get_devices()</code> and a fixed number of sub-devices that are enumerated via <code>sycl::device::create_sub_devices(...)</code>. Calling this function does not create a new device. Rather it merely creates a <code>sycl::device</code> object that is a copy of one of the devices from those enumerations.</td>
185+
</tr><tr>
186+
<td>
187+
188+
``` C++
189+
make_context<backend::ext_oneapi_level_zero>(
190+
const backend_input_t<
191+
backend::ext_oneapi_level_zero, context> &)
192+
```
193+
</td>
194+
<td>Constructs a SYCL context instance from a Level-Zero <code>ze_context_handle_t</code>. The context is created against the devices passed in <code>DeviceList</code> structure member. There must be at least one device given and all the devices must be from the same SYCL platform and thus from the same Level-Zero driver. The <code>Ownership</code> input structure member specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.</td>
195+
</tr><tr>
196+
<td>
197+
198+
``` C++
199+
make_queue<backend::ext_oneapi_level_zero>(
200+
const backend_input_t<
201+
backend::ext_oneapi_level_zero, queue> &,
202+
const context &Context)
203+
```
204+
</td>
205+
<td>Constructs a SYCL queue instance from a Level-Zero <code>ze_command_queue_handle_t</code>. The <code>Context</code> argument must be a valid SYCL context encapsulating a Level-Zero context. The queue is attached to the first device in the passed SYCL context. The <code>Ownership</code> input structure member specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.</td>
206+
</tr><tr>
207+
<td>
208+
209+
``` C++
210+
make_event<backend::ext_oneapi_level_zero>(
211+
const backend_input_t<
212+
backend::ext_oneapi_level_zero, event> &,
213+
const context &Context)
214+
```
215+
</td>
216+
<td>Constructs a SYCL event instance from a Level-Zero <code>ze_event_handle_t</code>. The <code>Context</code> argument must be a valid SYCL context encapsulating a Level-Zero context. The Level-Zero event should be allocated from an event pool created in the same context. The <code>Ownership</code> input structure member specifies if the SYCL runtime should take ownership of the passed native handle. The default behavior is to transfer the ownership to the SYCL runtime. See section 4.4 for details.</td>
217+
</tr><tr>
218+
<td>
219+
220+
``` C++
221+
make_kernel_bundle<backend::ext_oneapi_level_zero,
222+
bundle_state::executable>(
223+
const backend_input_t<
224+
backend::ext_oneapi_level_zero,
225+
kernel_bundle<bundle_state::executable>> &,
226+
const context &Context)
227+
```
228+
</td>
229+
<td>Constructs a SYCL kernel_bundle instance from a Level-Zero <code>ze_module_handle_t</code>. The <code>Context</code> argument must be a valid SYCL context encapsulating a Level-Zero context. The Level-Zero module must be fully linked (i.e. not require further linking through <a href="https://spec.oneapi.com/level-zero/latest/core/api.html?highlight=zemoduledynamiclink#_CPPv419zeModuleDynamicLink8uint32_tP18ze_module_handle_tP28ze_module_build_log_handle_t"><code>zeModuleDynamicLink</code></a>), and thus the SYCL kernel_bundle is created in the "executable" state.</td>
230+
</tr>
231+
</table>
94232

95233
NOTE: We shall consider adding other interoperability as needed, if possible.
96234

@@ -116,7 +254,7 @@ enum class ownership { transfer, keep };
116254
117255
#### 4.4.1 SYCL runtime takes ownership (default)
118256
119-
Whenever the application creates a SYCL object from the corresponding Level-Zero handle via one of the ```make<T>()``` functions,
257+
Whenever the application creates a SYCL object from the corresponding Level-Zero handle via one of the ```make_*``` functions,
120258
the SYCL runtime takes ownership of the Level-Zero handle, if no explicit ```ownership::keep``` was specified.
121259
The application must not use the Level-Zero handle after the last host copy of the SYCL object is destroyed (
122260
as described in the core SYCL specification under "Common reference semantics"), and the application must not
@@ -132,7 +270,7 @@ handle before the last host copy of the SYCL object is destroyed (as described i
132270
133271
#### 4.4.3 Obtaining native handle does not change ownership
134272
135-
The application may call the ```get_native<T>()``` member function of a SYCL object to retrieve the underlying Level-Zero handle.
273+
The application may call the ```get_native<backend::ext_oneapi_level_zero>``` free function on a SYCL object to retrieve the underlying Level-Zero handle.
136274
Doing so does not change the ownership of the the Level-Zero handle. Therefore, the application may not use this
137275
handle after the last host copy of the SYCL object is destroyed (as described in the core SYCL specification under
138276
"Common reference semantics") unless the SYCL object was created by the application with ```ownership::keep```.
@@ -197,3 +335,4 @@ struct free_memory {
197335
|4|2021-07-06|Rehana Begam|Introduced explicit ownership for queue
198336
|5|2021-07-25|Sergey Maslov|Introduced SYCL interop for events
199337
|6|2021-08-30|Dmitry Vodopyanov|Updated according to SYCL 2020 reqs for extensions
338+
|7|2021-09-13|Sergey Maslov|Updated according to SYCL 2020 standard

0 commit comments

Comments
 (0)