Skip to content

Commit 811f9e9

Browse files
committed
[SYCL] Implement compile and link for source-based kernel bundles
Implements a new `compile` variant for source-based `kernel_bundle` and the corresponding linking functionality. Signed-off-by: Larsen, Steffen <[email protected]>
1 parent c7ba34e commit 811f9e9

14 files changed

+1253
-264
lines changed

sycl-jit/jit-compiler/lib/rtc/DeviceCompilation.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,9 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
621621
// TODO: EmitOnlyKernelsAsEntryPoints is controlled by
622622
// `shouldEmitOnlyKernelsAsEntryPoints` in
623623
// `clang/lib/Driver/ToolChains/Clang.cpp`.
624-
const bool EmitOnlyKernelsAsEntryPoints = true;
624+
const bool EmitOnlyKernelsAsEntryPoints = !UserArgList.hasFlag(
625+
options::OPT_fsycl_allow_device_image_dependencies,
626+
options::OPT_fno_sycl_allow_device_image_dependencies, false);
625627

626628
// TODO: The optlevel passed to `sycl-post-link` is determined by
627629
// `getSYCLPostLinkOptimizationLevel` in

sycl/doc/extensions/experimental/sycl_ext_oneapi_kernel_compiler.asciidoc

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,8 +271,8 @@ kernel_bundle<bundle_state::executable> build(
271271

272272
_Constraints:_ Available only when `PropertyListT` is an instance of
273273
`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".
274+
other than those listed below in the section "New properties for the `build` and
275+
`compile` functions".
276276

277277
_Effects (1):_ The source code from `sourceBundle` is translated into one or more
278278
device images of state `bundle_state::executable`, and a new kernel bundle is
@@ -316,6 +316,81 @@ source code used to create the kernel bundle being printed to the terminal.
316316
In situations where this is undesirable, developers must ensure that the
317317
exception is caught and handled appropriately.
318318
_{endnote}_]
319+
320+
a|
321+
[frame=all,grid=none]
322+
!====
323+
a!
324+
[source]
325+
----
326+
namespace sycl::ext::oneapi::experimental {
327+
328+
template<typename PropertyListT = empty_properties_t> (1)
329+
kernel_bundle<bundle_state::object> compile(
330+
const kernel_bundle<bundle_state::ext_oneapi_source>& source,
331+
const std::vector<device>& devs, PropertyListT props={})
332+
333+
template<typename PropertyListT = empty_properties_t> (2)
334+
kernel_bundle<bundle_state::executable> build(
335+
const kernel_bundle<bundle_state::ext_oneapi_source>& sourceBundle,
336+
PropertyListT props = {})
337+
338+
} // namespace sycl::ext::oneapi::experimental
339+
----
340+
!====
341+
342+
343+
_Constraints:_ Available only when `PropertyListT` is an instance of
344+
`sycl::ext::oneapi::experimental::properties` which contains no properties
345+
other than those listed below in the section "New properties for the `build` and
346+
`compile` functions".
347+
348+
_Effects (1):_ The source code from `sourceBundle` is translated into one or
349+
more device images of state `bundle_state::object`, and a new kernel bundle is
350+
created to contain these device images.
351+
The new bundle represents all of the kernels in `sourceBundle` that are
352+
compatible with at least one of the devices in `devs`.
353+
Any remaining kernels (those that are not compatible with any of the devices in
354+
`devs`) are not represented in the new kernel bundle.
355+
356+
The new bundle has the same associated context as `sourceBundle`, and the new
357+
bundle's set of associated devices is `devs` (with duplicate devices removed).
358+
359+
_Effects (2)_: Equivalent to
360+
`compile(sourceBundle, sourceBundle.get_devices(), props)`.
361+
362+
_Returns:_ The newly created kernel bundle, which has `object` state.
363+
364+
_Throws:_
365+
366+
* An `exception` with the `errc::invalid` error code if `source` was not created
367+
with `source_language::sycl` or `source_language::sycl_jit` or was the result
368+
of `sycl::join` taking one or more `kernel_bundle` objects not created with
369+
`source_language::sycl` or `source_language::sycl_jit`.
370+
371+
* An `exception` with the `errc::invalid` error code if any of the devices in
372+
`devs` is not contained by the context associated with `sourceBundle`.
373+
374+
* An `exception` with the `errc::invalid` error code if any of the devices in
375+
`devs` does not support compilation of kernels in the source language of
376+
`sourceBundle`.
377+
378+
* An `exception` with the `errc::invalid` error code if `props` contains an
379+
`options` property that specifies an invalid option.
380+
381+
* An `exception` with the `errc::build` error code if the compilation operation
382+
fails. In this case, the exception `what` string provides a full build log,
383+
including descriptions of any errors, warning messages, and other
384+
diagnostics.
385+
This string is intended for human consumption, and the format may not be
386+
stable across implementations of this extension.
387+
388+
[_Note:_ An uncaught `errc::build` exception may result in some or all of the
389+
source code used to create the kernel bundle being printed to the terminal.
390+
In situations where this is undesirable, developers must ensure that the
391+
exception is caught and handled appropriately.
392+
_{endnote}_]
393+
319394
|====
320395

321396
=== New properties for the `create_kernel_bundle_from_source` function
@@ -383,10 +458,10 @@ _Throws (3):_
383458
entry with `name` in this property.
384459
|====
385460

386-
=== New properties for the `build` function
461+
=== New properties for the `build` and `compile` functions
387462

388463
This extension adds the following properties, which can be used in conjunction
389-
with the `build` function that is defined above:
464+
with the `build` and `compile` function that is defined above:
390465

391466
|====
392467
a|

sycl/include/sycl/kernel_bundle.hpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,36 @@ build_from_source(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
11121112
}
11131113
return build_from_source(SourceKB, Devices, Options, nullptr, KernelNames);
11141114
}
1115+
1116+
__SYCL_EXPORT kernel_bundle<bundle_state::object> compile_from_source(
1117+
kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1118+
const std::vector<device> &Devices,
1119+
const std::vector<sycl::detail::string_view> &CompileOptions,
1120+
sycl::detail::string *LogPtr,
1121+
const std::vector<sycl::detail::string_view> &RegisteredKernelNames);
1122+
1123+
inline kernel_bundle<bundle_state::object>
1124+
compile_from_source(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1125+
const std::vector<device> &Devices,
1126+
const std::vector<std::string> &CompileOptions,
1127+
std::string *LogPtr,
1128+
const std::vector<std::string> &RegisteredKernelNames) {
1129+
std::vector<sycl::detail::string_view> Options;
1130+
for (const std::string &opt : CompileOptions)
1131+
Options.push_back(sycl::detail::string_view{opt});
1132+
1133+
std::vector<sycl::detail::string_view> KernelNames;
1134+
for (const std::string &name : RegisteredKernelNames)
1135+
KernelNames.push_back(sycl::detail::string_view{name});
1136+
1137+
sycl::detail::string Log;
1138+
auto result = compile_from_source(SourceKB, Devices, Options,
1139+
LogPtr ? &Log : nullptr, KernelNames);
1140+
if (LogPtr)
1141+
*LogPtr = Log.c_str();
1142+
return result;
1143+
}
1144+
11151145
} // namespace detail
11161146

11171147
/////////////////////////
@@ -1155,6 +1185,39 @@ kernel_bundle<bundle_state::ext_oneapi_source> create_kernel_bundle_from_source(
11551185
}
11561186
#endif
11571187

1188+
/////////////////////////
1189+
// syclex::compile(source_kb) => obj_kb
1190+
/////////////////////////
1191+
1192+
template <typename PropertyListT = empty_properties_t,
1193+
typename = std::enable_if_t<detail::all_are_properties_of_v<
1194+
detail::build_source_bundle_props, PropertyListT>>>
1195+
kernel_bundle<bundle_state::object>
1196+
compile(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1197+
const std::vector<device> &Devices, PropertyListT props = {}) {
1198+
std::vector<std::string> CompileOptionsVec;
1199+
std::string *LogPtr = nullptr;
1200+
std::vector<std::string> RegisteredKernelNamesVec;
1201+
if constexpr (props.template has_property<build_options>())
1202+
CompileOptionsVec = props.template get_property<build_options>().opts;
1203+
if constexpr (props.template has_property<save_log>())
1204+
LogPtr = props.template get_property<save_log>().log;
1205+
if constexpr (props.template has_property<registered_names>())
1206+
RegisteredKernelNamesVec =
1207+
props.template get_property<registered_names>().names;
1208+
return detail::compile_from_source(SourceKB, Devices, CompileOptionsVec,
1209+
LogPtr, RegisteredKernelNamesVec);
1210+
}
1211+
1212+
template <typename PropertyListT = empty_properties_t,
1213+
typename = std::enable_if_t<detail::all_are_properties_of_v<
1214+
detail::build_source_bundle_props, PropertyListT>>>
1215+
kernel_bundle<bundle_state::object>
1216+
compile(kernel_bundle<bundle_state::ext_oneapi_source> &SourceKB,
1217+
PropertyListT props = {}) {
1218+
return compile<PropertyListT>(SourceKB, SourceKB.get_devices(), props);
1219+
}
1220+
11581221
/////////////////////////
11591222
// syclex::build(source_kb) => exe_kb
11601223
/////////////////////////

0 commit comments

Comments
 (0)