@@ -41,6 +41,11 @@ This extension is written against the SYCL 2020 revision 8 specification.
41
41
All references below to the "core SYCL specification" or to section numbers in
42
42
the SYCL specification refer to that revision.
43
43
44
+ This extension references sections of the OpenCL specification version 3.0.14.
45
+ References below to the "OpenCL specification" refer to that version.
46
+ It also references sections of the OpenCL C specification version 3.0.14.
47
+ References below to the "OpenCL C specification" refer to that version.
48
+
44
49
This extension also depends on the following other SYCL extensions:
45
50
46
51
* link:../experimental/sycl_ext_oneapi_kernel_compiler.asciidoc[
@@ -114,6 +119,140 @@ As a result, the application must use the overload of
114
119
`create_kernel_bundle_from_source` taking `std::string` when creating a kernel
115
120
bundle from this language.
116
121
122
+ === Queries
123
+
124
+ ==== Version type
125
+
126
+ This extension adds the following type and constant definitions, which help
127
+ identify the version of OpenCL and its extensions.
128
+
129
+ |====
130
+ a|
131
+ [frame=all,grid=none]
132
+ !====
133
+ a!
134
+ [source]
135
+ ----
136
+ namespace sycl::ext::oneapi::experimental {
137
+
138
+ struct cl_version {
139
+ unsigned major:10;
140
+ unsigned minor:10;
141
+ unsigned patch:12;
142
+ };
143
+
144
+ inline constexpr cl_version opencl_c_1_0 = {1,0,0};
145
+ inline constexpr cl_version opencl_c_1_1 = {1,1,0};
146
+ inline constexpr cl_version opencl_c_1_2 = {1,2,0};
147
+ inline constexpr cl_version opencl_c_2_0 = {2,0,0};
148
+ inline constexpr cl_version opencl_c_3_0 = {3,0,0};
149
+
150
+ } // namespace ext::oneapi::experimental
151
+ ----
152
+ !====
153
+
154
+ The meaning of the `major`, `minor`, and `patch` values are defined by section
155
+ 3.4.3.1 "Versions" of the OpenCL specification.
156
+
157
+ The constant values (e.g. `opencl_c_1_0`) are shorthands that identify various
158
+ OpenCL C versions.
159
+
160
+ [_Note:_ The OpenCL C version is not the same as the the OpenCL version because
161
+ some minor releases of OpenCL did not change the OpenCL C language.
162
+ For example, there is no version of OpenCL C named "2.1" even though there is
163
+ an OpenCL version named "2.1".
164
+ _{endnote}_]
165
+ |====
166
+
167
+ ==== New member functions for the device class
168
+
169
+ This extension also adds the following member functions to the `device` class,
170
+ which allow the application to query which OpenCL features and extensions the
171
+ device supports.
172
+
173
+ |====
174
+ a|
175
+ [frame=all,grid=none]
176
+ !====
177
+ a!
178
+ [source]
179
+ ----
180
+ class device {
181
+ bool ext_oneapi_supports_cl_c_version(
182
+ const ext::oneapi::experimental::cl_version &version) const;
183
+ };
184
+ ----
185
+ !====
186
+
187
+ _Returns:_ The value `true` only if the device supports kernel bundles written
188
+ in the OpenCL C version identified by `version`.
189
+ Returns `false` if the device does not support kernel bundles written in
190
+ `source_language::opencl`.
191
+
192
+ a|
193
+ [frame=all,grid=none]
194
+ !====
195
+ a!
196
+ [source]
197
+ ----
198
+ class device {
199
+ bool ext_oneapi_supports_cl_c_feature(const std::string &name) const;
200
+ };
201
+ ----
202
+ !====
203
+
204
+ _Returns:_ The value `true` only if the device supports kernel bundles using
205
+ the OpenCL C feature whose feature macro is `name`.
206
+ The set of possible feature macros are defined in section 6.2.1 "Features" of
207
+ the OpenCL C specification.
208
+ Returns `false` if the device does not support kernel bundles written in
209
+ `source_language::opencl`.
210
+
211
+ a|
212
+ [frame=all,grid=none]
213
+ !====
214
+ a!
215
+ [source]
216
+ ----
217
+ class device {
218
+ bool ext_oneapi_supports_cl_extension(const std::string &name,
219
+ ext::oneapi::experimental::cl_version *version = nullptr) const;
220
+ };
221
+ ----
222
+ !====
223
+
224
+ _Effects:_ If the device supports kernel bundles using the OpenCL extension
225
+ identified by `name` and if `version` is not a null pointer, the supported
226
+ version of the extension is written to `version`.
227
+
228
+ _Returns:_ The value `true` only if the device supports kernel bundles using
229
+ the OpenCL extension identified by `name`.
230
+ Returns `false` if the device does not support kernel bundles written in
231
+ `source_language::opencl`.
232
+
233
+ a|
234
+ [frame=all,grid=none]
235
+ !====
236
+ a!
237
+ [source]
238
+ ----
239
+ class device {
240
+ std::string ext_oneapi_cl_profile() const;
241
+ };
242
+ ----
243
+ !====
244
+
245
+ _Returns:_ If the device supports kernel bundles written in
246
+ `source_language::opencl`, returns the name of the OpenCL profile that is
247
+ supported.
248
+ The profile name is the same string that is returned by the query
249
+ `CL_DEVICE_PROFILE`, as defined in section 4.2 "Querying Devices" of the OpenCL
250
+ specification.
251
+ If the device does not support kernel bundles written in
252
+ `source_language::opencl`, returns the empty string.
253
+
254
+ |====
255
+
117
256
=== Build options
118
257
119
258
The `build_options` property accepts any of the compiler or linker options
@@ -122,6 +261,13 @@ creating an OpenCL library.
122
261
The kernel compiler can be used to create an OpenCL program, but not an OpenCL
123
262
library.
124
263
264
+ The `-cl-std=` option is required when compiling kernels that use OpenCL C 2.0
265
+ or OpenCL C 3.0 features.
266
+ Otherwise, the implementation defaults to the highest OpenCL C 1.x language
267
+ version that each device supports.
268
+ See section 5.8.6.5 "Options Controlling the OpenCL C version" of the OpenCL
269
+ specification for details.
270
+
125
271
=== Obtaining a kernel
126
272
127
273
OpenCL C kernel functions do not support {cpp} features like overloads or
@@ -187,7 +333,9 @@ _{endnote}_]
187
333
|===
188
334
189
335
190
- == Example
336
+ == Examples
337
+
338
+ === Simple example
191
339
192
340
The following example shows a simple SYCL program that defines an OpenCL C
193
341
kernel as a string and then compiles and launches it.
@@ -243,52 +391,45 @@ int main() {
243
391
}
244
392
```
245
393
394
+ === Querying supported features and extensions
246
395
247
- == Issues
248
-
249
- * How should we expose the difference between OpenCL C versions?
250
- It seems like there are two aspects to the problem.
251
- Applications need some way to query which versions the backend (or device)
252
- supports.
253
- Applications also need some way to tell the runtime which version the kernel
254
- is written in.
255
- +
256
- --
257
- One option is to define separate enumerators in `source_language` for each
258
- version like this:
396
+ This example demonstrates how to query the version of OpenCL C that is
397
+ supported, how to query the supported features, and how to query the
398
+ supported extensions.
259
399
260
400
```
261
- enum class source_language : /*unspecified*/ {
262
- opencl_1_0,
263
- opencl_1_1,
264
- opencl_2_0,
265
- opencl_3_0,
266
- };
401
+ #include <iostream>
402
+ #include <sycl/sycl.hpp>
403
+ namespace syclex = sycl::ext::oneapi::experimental;
404
+
405
+ int main() {
406
+ sycl::queue q;
407
+ sycl::device d = q.get_device();
408
+
409
+ if (d.ext_oneapi_can_compile(syclex::source_language::opencl))
410
+ std::cout << "Device supports online compilation of OpenCL C kernels\n";
411
+
412
+ if (d.ext_oneapi_supports_cl_c_version(syclex::opencl_c_3_0))
413
+ std::cout << "Device supports online compilation with OpenCL C 3.0\n";
414
+
415
+ if (d.ext_oneapi_supports_cl_c_feature("__opencl_c_fp64"))
416
+ std::cout << "Device supports online compilation with 64-bit FP in OpenCL C\n";
417
+
418
+ syclex::cl_version version;
419
+ if (d.ext_oneapi_supports_cl_extension("cl_intel_bfloat16_conversions", &version)) {
420
+ std::cout << "Device supports online compilation of OpenCL C with bfloat16 "
421
+ "conversions (version: " << version.major << "." << version.minor << "." <<
422
+ version.patch << ")\n";
423
+ }
424
+
425
+ if (d.ext_oneapi_cl_profile() == "FULL_PROFILE")
426
+ std::cout << "Device supports online compilation with the OpenCL full profile\n";
427
+
428
+ }
267
429
```
268
430
269
- Applications could then query the supported versions via
270
- `is_source_kernel_bundle_supported`, and applications would identify the
271
- version of their kernel string via the `lang` parameter to
272
- `create_kernel_bundle_from_source`.
273
-
274
- Alternatively, this extension could define just a single language enumerator
275
- (`opencl`), but also provide as separate query to get the supported OpenCL C
276
- versions.
277
- When building a kernel bundle, applications would be required to pass "-cl-std"
278
- via the `build_options` property in order to identify the OpenCL C version of
279
- their source string.
280
- --
281
-
282
- * How can an application determine the OpenCL C optional features that are
283
- supported and the extensions that are supported?
284
- One option is to require the application to use OpenCL APIs for these
285
- queries.
286
- This seems better than duplicating these queries into this extension.
287
- However, this assumes the application is running with an OpenCL backend.
288
- Do we want to support the use of OpenCL C kernels also with the Level Zero
289
- backend?
290
- Currently, the online_compiler does support this case (but it provides no way
291
- to query about optional features or extensions).
431
+
432
+ == Issues
292
433
293
434
* Do we need to document some restrictions on the OpenCL C
294
435
https://registry.khronos.org/OpenCL/specs/3.0-unified/html/OpenCL_C.html#work-item-functions[
0 commit comments