Skip to content

Commit 3772cc2

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 3772cc2

File tree

16 files changed

+1275
-265
lines changed

16 files changed

+1275
-265
lines changed

llvm/include/llvm/SYCLLowerIR/ModuleSplitter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,11 @@ std::unique_ptr<ModuleSplitterBase>
301301
getDeviceCodeSplitter(ModuleDesc &&MD, IRSplitMode Mode, bool IROutputOnly,
302302
bool EmitOnlyKernelsAsEntryPoints);
303303

304+
std::unique_ptr<ModuleSplitterBase>
305+
getDeviceCodeSplitter(ModuleDesc &&MD, IRSplitMode Mode, bool IROutputOnly,
306+
bool EmitOnlyKernelsAsEntryPoints,
307+
bool OverwriteAllowDeviceImageDependencies);
308+
304309
#ifndef NDEBUG
305310
void dumpEntryPoints(const EntryPointSet &C, const char *Msg = "", int Tab = 0);
306311
void dumpEntryPoints(const Module &M, bool OnlyKernelsAreEntryPoints = false,

llvm/lib/SYCLLowerIR/ModuleSplitter.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,8 +1129,19 @@ std::string FunctionsCategorizer::computeCategoryFor(Function *F) const {
11291129
std::unique_ptr<ModuleSplitterBase>
11301130
getDeviceCodeSplitter(ModuleDesc &&MD, IRSplitMode Mode, bool IROutputOnly,
11311131
bool EmitOnlyKernelsAsEntryPoints) {
1132+
return getDeviceCodeSplitter(std::move(MD), Mode, IROutputOnly,
1133+
EmitOnlyKernelsAsEntryPoints,
1134+
AllowDeviceImageDependencies);
1135+
}
1136+
1137+
std::unique_ptr<ModuleSplitterBase>
1138+
getDeviceCodeSplitter(ModuleDesc &&MD, IRSplitMode Mode, bool IROutputOnly,
1139+
bool EmitOnlyKernelsAsEntryPoints,
1140+
bool OverwriteAllowDeviceImageDependencies) {
11321141
FunctionsCategorizer Categorizer;
11331142

1143+
AllowDeviceImageDependencies = OverwriteAllowDeviceImageDependencies;
1144+
11341145
EntryPointsGroupScope Scope =
11351146
selectDeviceCodeGroupScope(MD.getModule(), Mode, IROutputOnly);
11361147

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -618,10 +618,16 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
618618

619619
const auto SplitMode = getDeviceCodeSplitMode(UserArgList);
620620

621+
const bool AllowDeviceImageDependencies = UserArgList.hasFlag(
622+
options::OPT_fsycl_allow_device_image_dependencies,
623+
options::OPT_fno_sycl_allow_device_image_dependencies, false);
624+
621625
// TODO: EmitOnlyKernelsAsEntryPoints is controlled by
622626
// `shouldEmitOnlyKernelsAsEntryPoints` in
623627
// `clang/lib/Driver/ToolChains/Clang.cpp`.
624-
const bool EmitOnlyKernelsAsEntryPoints = true;
628+
// If we allow device image dependencies, we should definitely not only emit
629+
// kernels as entry points.
630+
const bool EmitOnlyKernelsAsEntryPoints = !AllowDeviceImageDependencies;
625631

626632
// TODO: The optlevel passed to `sycl-post-link` is determined by
627633
// `getSYCLPostLinkOptimizationLevel` in
@@ -654,7 +660,8 @@ jit_compiler::performPostLink(std::unique_ptr<llvm::Module> Module,
654660

655661
std::unique_ptr<ModuleSplitterBase> Splitter = getDeviceCodeSplitter(
656662
ModuleDesc{std::move(Module)}, SplitMode,
657-
/*IROutputOnly=*/false, EmitOnlyKernelsAsEntryPoints);
663+
/*IROutputOnly=*/false, EmitOnlyKernelsAsEntryPoints,
664+
AllowDeviceImageDependencies);
658665
assert(Splitter->hasMoreSplits());
659666

660667
// TODO: Call `verifyNoCrossModuleDeviceGlobalUsage` if device globals shall

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)