Skip to content

Commit f3b040c

Browse files
[SYCL][Docs] Implement compile and link for source-based kernel bundles (#17442)
Implements a new `compile` variant for source-based `kernel_bundle` and the corresponding linking functionality. --------- Signed-off-by: Larsen, Steffen <steffen.larsen@intel.com> Co-authored-by: Sergey Semenov <sergey.semenov@intel.com>
1 parent e73f1f6 commit f3b040c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2121
-440
lines changed

sycl/doc/extensions/experimental/sycl_ext_oneapi_kernel_compiler.asciidoc

Lines changed: 107 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -157,14 +157,34 @@ a!
157157
----
158158
class device {
159159
160+
bool ext_oneapi_can_build(ext::oneapi::experimental::source_language lang);
161+
162+
};
163+
----
164+
!====
165+
166+
_Returns:_ The value `true` only if the device supports the
167+
`ext::oneapi::experimental::build` function on kernel bundles written in the
168+
source language `lang`.
169+
170+
a|
171+
[frame=all,grid=none]
172+
!====
173+
a!
174+
[source,c++]
175+
----
176+
class device {
177+
160178
bool ext_oneapi_can_compile(ext::oneapi::experimental::source_language lang);
161179
162180
};
163181
----
164182
!====
165183

166-
_Returns:_ The value `true` only if the device supports kernel bundles written
167-
in the source language `lang`.
184+
_Returns:_ The value `true` only if the device supports the
185+
`ext::oneapi::experimental::compile` function on kernel bundles written in the
186+
source language `lang`.
187+
168188
|====
169189

170190
=== New free functions to create and build kernel bundles
@@ -226,8 +246,6 @@ state.
226246

227247
_Throws:_
228248

229-
* An `exception` with the `errc::invalid` error code if the source language
230-
`lang` is not supported by any device contained by the context `ctxt`.
231249
* An `exception` with the `errc::invalid` error code if the source language
232250
`lang` does not support one of the properties in `PropertyListT`.
233251
* Overload (1) throws an `exception` with the `errc::invalid` error code if the
@@ -241,9 +259,11 @@ function.
241259

242260
This function succeeds even if some devices in `ctxt` do not support the source
243261
language `lang`.
244-
However, the `build` function fails unless _all_ of its devices support `lang`.
245-
Therefore, applications should take care to omit devices that do not support
246-
`lang` when calling `build`.
262+
However, the `build` and `compile` functions will fail if any of its devices
263+
return `false` for `ext_oneapi_can_build(lang)` and
264+
`ext_oneapi_can_compile(lang)` respectively. Therefore, applications should take
265+
care to omit devices that do not support `lang` for the functions they intend on
266+
calling.
247267
_{endnote}_]
248268

249269
a|
@@ -271,8 +291,8 @@ kernel_bundle<bundle_state::executable> build(
271291

272292
_Constraints:_ Available only when `PropertyListT` is an instance of
273293
`sycl::ext::oneapi::experimental::properties` which contains no properties
274-
other than those listed below in the section "New properties for the `build`
275-
function".
294+
other than those listed below in the section "New properties for the `build` and
295+
`compile` functions".
276296

277297
_Effects (1):_ The source code from `sourceBundle` is translated into one or more
278298
device images of state `bundle_state::executable`, and a new kernel bundle is
@@ -293,16 +313,16 @@ _Returns:_ The newly created kernel bundle, which has `executable` state.
293313
_Throws:_
294314

295315
* An `exception` with the `errc::invalid` error code if any of the devices in
296-
`devs` is not contained by the context associated with `sourceBundle`.
316+
`devs` return `false` for `ext_oneapi_can_build` with the source language of
317+
`sourceBundle`.
297318

298319
* An `exception` with the `errc::invalid` error code if any of the devices in
299-
`devs` does not support compilation of kernels in the source language of
300-
`sourceBundle`.
320+
`devs` is not contained by the context associated with `sourceBundle`.
301321

302322
* An `exception` with the `errc::invalid` error code if the source language
303323
`lang` does not support one of the properties in `PropertyListT` or if
304324
`props` contains a `build_options` property that contains an option that is
305-
not supported by `lang`.
325+
not supported when building `lang`.
306326

307327
* An `exception` with the `errc::build` error code if the compilation or
308328
linking operations fail.
@@ -317,6 +337,78 @@ source code used to create the kernel bundle being printed to the terminal.
317337
In situations where this is undesirable, developers must ensure that the
318338
exception is caught and handled appropriately.
319339
_{endnote}_]
340+
341+
a|
342+
[frame=all,grid=none]
343+
!====
344+
a!
345+
[source]
346+
----
347+
namespace sycl::ext::oneapi::experimental {
348+
349+
template<typename PropertyListT = empty_properties_t> (1)
350+
kernel_bundle<bundle_state::object> compile(
351+
const kernel_bundle<bundle_state::ext_oneapi_source>& sourceBundle,
352+
const std::vector<device>& devs, PropertyListT props={})
353+
354+
template<typename PropertyListT = empty_properties_t> (2)
355+
kernel_bundle<bundle_state::object> compile(
356+
const kernel_bundle<bundle_state::ext_oneapi_source>& sourceBundle,
357+
PropertyListT props = {})
358+
359+
} // namespace sycl::ext::oneapi::experimental
360+
----
361+
!====
362+
363+
364+
_Constraints:_ Available only when `PropertyListT` is an instance of
365+
`sycl::ext::oneapi::experimental::properties` which contains no properties
366+
other than those listed below in the section "New properties for the `build` and
367+
`compile` functions".
368+
369+
_Effects (1):_ The source code from `sourceBundle` is translated into one or
370+
more device images of state `bundle_state::object`, and a new kernel bundle is
371+
created to contain these device images.
372+
The new bundle represents all of the kernels in `sourceBundle` that are
373+
compatible with at least one of the devices in `devs`.
374+
Any remaining kernels (those that are not compatible with any of the devices in
375+
`devs`) are not represented in the new kernel bundle.
376+
377+
The new bundle has the same associated context as `sourceBundle`, and the new
378+
bundle's set of associated devices is `devs` (with duplicate devices removed).
379+
380+
_Effects (2)_: Equivalent to
381+
`compile(sourceBundle, sourceBundle.get_devices(), props)`.
382+
383+
_Returns:_ The newly created kernel bundle, which has `object` state.
384+
385+
_Throws:_
386+
387+
* An `exception` with the `errc::invalid` error code if any of the devices in
388+
`devs` return `false` for `ext_oneapi_can_compile` with the source language of
389+
`sourceBundle`.
390+
391+
* An `exception` with the `errc::invalid` error code if any of the devices in
392+
`devs` is not contained by the context associated with `sourceBundle`.
393+
394+
* An `exception` with the `errc::invalid` error code if the source language
395+
`lang` does not support one of the properties in `PropertyListT` or if
396+
`props` contains a `build_options` property that contains an option that is
397+
not supported when compiling `lang`.
398+
399+
* An `exception` with the `errc::build` error code if the compilation operation
400+
fails. In this case, the exception `what` string provides a full build log,
401+
including descriptions of any errors, warning messages, and other
402+
diagnostics.
403+
This string is intended for human consumption, and the format may not be
404+
stable across implementations of this extension.
405+
406+
[_Note:_ An uncaught `errc::build` exception may result in some or all of the
407+
source code used to create the kernel bundle being printed to the terminal.
408+
In situations where this is undesirable, developers must ensure that the
409+
exception is caught and handled appropriately.
410+
_{endnote}_]
411+
320412
|====
321413

322414
=== New properties for the `create_kernel_bundle_from_source` function
@@ -384,10 +476,10 @@ _Throws (3):_
384476
entry with `name` in this property.
385477
|====
386478

387-
=== New properties for the `build` function
479+
=== New properties for the `build` and `compile` functions
388480

389481
This extension adds the following properties, which can be used in conjunction
390-
with the `build` function that is defined above:
482+
with the `build` and `compile` function that is defined above:
391483

392484
|====
393485
a|

sycl/doc/extensions/experimental/sycl_ext_oneapi_kernel_compiler_opencl.asciidoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ int main() {
461461
sycl::queue q;
462462
sycl::device d = q.get_device();
463463
464-
if (d.ext_oneapi_can_compile(syclex::source_language::opencl))
464+
if (d.ext_oneapi_can_build(syclex::source_language::opencl))
465465
std::cout << "Device supports online compilation of OpenCL C kernels\n";
466466
467467
if (d.ext_oneapi_supports_cl_c_version(syclex::opencl_c_3_0))

sycl/include/sycl/device.hpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -299,14 +299,27 @@ class __SYCL_EXPORT device : public detail::OwnerLessBase<device> {
299299

300300
/// kernel_compiler extension
301301

302+
/// Indicates if the device can build a kernel for the given language.
303+
///
304+
/// \param Language is one of the values from the
305+
/// kernel_bundle::source_language enumeration described in the
306+
/// sycl_ext_oneapi_kernel_compiler specification
307+
///
308+
/// \return The value true only if the device supports the
309+
/// ext::oneapi::experimental::build function on kernel bundles written in
310+
/// the source language \p Language.
311+
bool
312+
ext_oneapi_can_build(ext::oneapi::experimental::source_language Language);
313+
302314
/// Indicates if the device can compile a kernel for the given language.
303315
///
304316
/// \param Language is one of the values from the
305317
/// kernel_bundle::source_language enumeration described in the
306318
/// sycl_ext_oneapi_kernel_compiler specification
307319
///
308-
/// \return true only if the device supports kernel bundles written in the
309-
/// source language `lang`.
320+
/// \return The value true only if the device supports the
321+
/// ext::oneapi::experimental::compile function on kernel bundles written in
322+
/// the source language \p Language.
310323
bool
311324
ext_oneapi_can_compile(ext::oneapi::experimental::source_language Language);
312325

sycl/include/sycl/kernel_bundle.hpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,7 @@ build_from_source(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
11651165
std::string *LogPtr,
11661166
const std::vector<std::string> &RegisteredKernelNames) {
11671167
std::vector<sycl::detail::string_view> Options;
1168+
Options.reserve(BuildOptions.size());
11681169
for (const std::string &opt : BuildOptions)
11691170
Options.push_back(sycl::detail::string_view{opt});
11701171

@@ -1181,6 +1182,38 @@ build_from_source(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
11811182
}
11821183
return build_from_source(SourceKB, Devices, Options, nullptr, KernelNames);
11831184
}
1185+
1186+
__SYCL_EXPORT kernel_bundle<bundle_state::object> compile_from_source(
1187+
kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1188+
const std::vector<device> &Devices,
1189+
const std::vector<sycl::detail::string_view> &CompileOptions,
1190+
sycl::detail::string *LogPtr,
1191+
const std::vector<sycl::detail::string_view> &RegisteredKernelNames);
1192+
1193+
inline kernel_bundle<bundle_state::object>
1194+
compile_from_source(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1195+
const std::vector<device> &Devices,
1196+
const std::vector<std::string> &CompileOptions,
1197+
std::string *LogPtr,
1198+
const std::vector<std::string> &RegisteredKernelNames) {
1199+
std::vector<sycl::detail::string_view> Options;
1200+
Options.reserve(CompileOptions.size());
1201+
for (const std::string &opt : CompileOptions)
1202+
Options.push_back(sycl::detail::string_view{opt});
1203+
1204+
std::vector<sycl::detail::string_view> KernelNames;
1205+
KernelNames.reserve(RegisteredKernelNames.size());
1206+
for (const std::string &name : RegisteredKernelNames)
1207+
KernelNames.push_back(sycl::detail::string_view{name});
1208+
1209+
sycl::detail::string Log;
1210+
auto result = compile_from_source(SourceKB, Devices, Options,
1211+
LogPtr ? &Log : nullptr, KernelNames);
1212+
if (LogPtr)
1213+
*LogPtr = Log.c_str();
1214+
return result;
1215+
}
1216+
11841217
} // namespace detail
11851218

11861219
/////////////////////////
@@ -1218,6 +1251,39 @@ kernel_bundle<bundle_state::ext_oneapi_source> create_kernel_bundle_from_source(
12181251
}
12191252
#endif
12201253

1254+
/////////////////////////
1255+
// syclex::compile(source_kb) => obj_kb
1256+
/////////////////////////
1257+
1258+
template <typename PropertyListT = empty_properties_t,
1259+
typename = std::enable_if_t<detail::all_are_properties_of_v<
1260+
detail::build_source_bundle_props, PropertyListT>>>
1261+
kernel_bundle<bundle_state::object>
1262+
compile(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1263+
const std::vector<device> &Devices, PropertyListT props = {}) {
1264+
std::vector<std::string> CompileOptionsVec;
1265+
std::string *LogPtr = nullptr;
1266+
std::vector<std::string> RegisteredKernelNamesVec;
1267+
if constexpr (props.template has_property<build_options>())
1268+
CompileOptionsVec = props.template get_property<build_options>().opts;
1269+
if constexpr (props.template has_property<save_log>())
1270+
LogPtr = props.template get_property<save_log>().log;
1271+
if constexpr (props.template has_property<registered_names>())
1272+
RegisteredKernelNamesVec =
1273+
props.template get_property<registered_names>().names;
1274+
return detail::compile_from_source(SourceKB, Devices, CompileOptionsVec,
1275+
LogPtr, RegisteredKernelNamesVec);
1276+
}
1277+
1278+
template <typename PropertyListT = empty_properties_t,
1279+
typename = std::enable_if_t<detail::all_are_properties_of_v<
1280+
detail::build_source_bundle_props, PropertyListT>>>
1281+
kernel_bundle<bundle_state::object>
1282+
compile(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1283+
PropertyListT props = {}) {
1284+
return compile<PropertyListT>(SourceKB, SourceKB.get_devices(), props);
1285+
}
1286+
12211287
/////////////////////////
12221288
// syclex::build(source_kb) => exe_kb
12231289
/////////////////////////

0 commit comments

Comments
 (0)