Skip to content

Commit cc05fe9

Browse files
committed
[SYCL][UR][Docs] Add fast-link option for SYCLBIN
This commit adds the ability for doing "fast linking" of kernel bundles. Fast linking lets the implementation use AOT binaries from the underlying SYCLBIN files to dynamically link the images in the kernel bundles. Signed-off-by: Larsen, Steffen <[email protected]>
1 parent c7ff661 commit cc05fe9

Some content is hidden

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

60 files changed

+1661
-247
lines changed

sycl/doc/extensions/proposed/sycl_ext_oneapi_syclbin.asciidoc

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,3 +242,142 @@ _{endnote}_]
242242

243243
|====
244244

245+
=== New free function for linking
246+
247+
This extension adds the following new free functions to create and build a
248+
kernel bundle in `ext_oneapi_source` state.
249+
250+
|====
251+
a|
252+
[frame=all,grid=none]
253+
!====
254+
a!
255+
[source,c++]
256+
----
257+
namespace sycl::ext::oneapi::experimental {
258+
259+
template<typename PropertyListT = empty_properties_t>
260+
kernel_bundle<bundle_state::executable>
261+
link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,
262+
const std::vector<device>& devs, PropertyListT props = {});
263+
264+
} // namespace sycl::ext::oneapi::experimental
265+
----
266+
!====
267+
268+
_Constraints:_ Available only when `PropertyListT` is an instance of
269+
`sycl::ext::oneapi::experimental::properties` which contains no properties
270+
other than those listed below in the section "New properties for the
271+
`link` function".
272+
273+
_Effects:_ Duplicate device images from `objectBundles` are eliminated as though
274+
they were joined via `join()`, then the remaining device images are translated
275+
into one or more new device images of state `bundle_state::executable`, and a
276+
new kernel bundle is created to contain these new device images. The new bundle
277+
represents all of the kernels in `objectBundles` that are compatible with at
278+
least one of the devices in `devs`. Any remaining kernels (those that are not
279+
compatible with any of the devices in `devs`) are not linked and not represented
280+
in the new bundle.
281+
282+
The new bundle has the same associated context as those in `objectBundles`, and
283+
the new bundle’s set of associated devices is `devs` (with duplicate devices
284+
removed).
285+
286+
_Returns:_ The new kernel bundle.
287+
288+
_Throws:_
289+
290+
* An `exception` with the `errc::invalid` error code if the bundles in
291+
`objectBundles` do not all have the same associated context.
292+
293+
* An `exception` with the `errc::invalid` error code if any of the devices in
294+
`devs` are not in the set of associated devices for any of the bundles in
295+
`objectBundles` (as defined by `kernel_bundle::get_devices()`) or if the `devs`
296+
vector is empty.
297+
298+
* An `exception` with the `errc::build` error code if the online link operation
299+
fails.
300+
301+
302+
a|
303+
[frame=all,grid=none]
304+
!====
305+
a!
306+
[source]
307+
----
308+
309+
namespace sycl::ext::oneapi::experimental {
310+
311+
template<typename PropertyListT = empty_properties_t> (1)
312+
kernel_bundle<bundle_state::executable>
313+
link(const kernel_bundle<bundle_state::object>& objectBundle,
314+
const std::vector<device>& devs, PropertyListT props = {});
315+
316+
template<typename PropertyListT = empty_properties_t> (2)
317+
kernel_bundle<bundle_state::executable>
318+
link(const std::vector<kernel_bundle<bundle_state::object>>& objectBundles,
319+
PropertyListT props = {});
320+
321+
template<typename PropertyListT = empty_properties_t> (3)
322+
kernel_bundle<bundle_state::executable>
323+
link(const kernel_bundle<bundle_state::object>& objectBundle,
324+
PropertyListT props = {});
325+
326+
} // namespace sycl::ext::oneapi::experimental
327+
----
328+
!====
329+
330+
_Effects (1):_ Equivalent to `link({objectBundle}, devs, props)`.
331+
332+
_Effects (2):_ Equivalent to `link(objectBundles, devs, props)`, where `devs` is
333+
the intersection of associated devices in common for all bundles in
334+
`objectBundles`.
335+
336+
_Effects (3):_ Equivalent to
337+
`link({objectBundle}, objectBundle.get_devices(), props)`.
338+
339+
340+
|====
341+
342+
=== New properties for the `link` function
343+
344+
This extension adds the following properties, which can be used in conjunction
345+
with the `link` function that is defined above:
346+
347+
|====
348+
a|
349+
[frame=all,grid=none]
350+
!====
351+
a!
352+
[source,c++]
353+
----
354+
namespace sycl::ext::oneapi::experimental {
355+
356+
struct fast_link {
357+
fast_link(bool do_fast_link = true); (1)
358+
359+
bool value;
360+
};
361+
using fast_link_key = fast_link;
362+
363+
template<> struct is_property_key<fast_link_key> : std::true_type {};
364+
365+
} // namespace sycl::ext::oneapi::experimental
366+
----
367+
!====
368+
369+
This property instructs the `link` operation to do "fast linking". Enabling this
370+
instructs the implementation to use device binary images that have been
371+
pre-compiled.
372+
373+
For example, SYCLBIN files may contain ahead-of-time compiled binary images
374+
together with just-in-time compiled binary images, with the kernels and exported
375+
functions potentially overlapping. When fast-linking is enabled, the
376+
implementation will try to use the ahead-of-time compiled binary images over
377+
their just-in-time compiled counterparts.
378+
379+
_Effects (1):_ Creates a new `fast_link` property with a boolean value
380+
indicating whether the `link` operation should do fast-linking.
381+
382+
|====
383+

sycl/include/sycl/ext/oneapi/experimental/syclbin_kernel_bundle.hpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#pragma once
1010

11+
#include <sycl/ext/oneapi/experimental/syclbin_properties.hpp>
1112
#include <sycl/ext/oneapi/properties/properties.hpp>
1213
#include <sycl/kernel_bundle.hpp>
1314

@@ -24,6 +25,13 @@
2425

2526
namespace sycl {
2627
inline namespace _V1 {
28+
29+
namespace detail {
30+
__SYCL_EXPORT std::shared_ptr<detail::kernel_bundle_impl>
31+
link_impl(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
32+
const std::vector<device> &Devs, bool FastLink);
33+
}
34+
2735
namespace ext::oneapi::experimental {
2836

2937
template <bundle_state State, typename PropertyListT = empty_properties_t>
@@ -77,6 +85,58 @@ get_kernel_bundle(const context &Ctxt, const std::filesystem::path &Filename,
7785
}
7886
#endif
7987

88+
template <typename PropertyListT = empty_properties_t,
89+
typename = std::enable_if_t<detail::all_are_properties_of_v<
90+
sycl::detail::link_props, PropertyListT>>>
91+
kernel_bundle<bundle_state::executable>
92+
link(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
93+
const std::vector<device> &Devs, PropertyListT Props = {}) {
94+
std::vector<device> UniqueDevices =
95+
sycl::detail::removeDuplicateDevices(Devs);
96+
97+
bool UseFastLink = [&]() {
98+
if constexpr (Props.template has_property<fast_link>())
99+
return Props.template get_property<fast_link>().value;
100+
return false;
101+
}();
102+
103+
sycl::detail::KernelBundleImplPtr Impl =
104+
sycl::detail::link_impl(ObjectBundles, UniqueDevices, UseFastLink);
105+
return detail::createSyclObjFromImpl<
106+
kernel_bundle<sycl::bundle_state::executable>>(std::move(Impl));
107+
}
108+
109+
template <typename PropertyListT = empty_properties_t,
110+
typename = std::enable_if_t<detail::all_are_properties_of_v<
111+
sycl::detail::link_props, PropertyListT>>>
112+
kernel_bundle<bundle_state::executable>
113+
link(const kernel_bundle<bundle_state::object> &ObjectBundle,
114+
const std::vector<device> &Devs, PropertyListT Props = {}) {
115+
return link(std::vector<kernel_bundle<bundle_state::object>>{ObjectBundle},
116+
Devs, Props);
117+
}
118+
119+
template <typename PropertyListT = empty_properties_t,
120+
typename = std::enable_if_t<detail::all_are_properties_of_v<
121+
sycl::detail::link_props, PropertyListT>>>
122+
kernel_bundle<bundle_state::executable>
123+
link(const std::vector<kernel_bundle<bundle_state::object>> &ObjectBundles,
124+
PropertyListT Props = {}) {
125+
std::vector<sycl::device> IntersectDevices =
126+
sycl::detail::find_device_intersection(ObjectBundles);
127+
return link(ObjectBundles, IntersectDevices, Props);
128+
}
129+
130+
template <typename PropertyListT = empty_properties_t,
131+
typename = std::enable_if_t<detail::all_are_properties_of_v<
132+
sycl::detail::link_props, PropertyListT>>>
133+
kernel_bundle<bundle_state::executable>
134+
link(const kernel_bundle<bundle_state::object> &ObjectBundle,
135+
PropertyListT Props = {}) {
136+
return link(std::vector<kernel_bundle<bundle_state::object>>{ObjectBundle},
137+
ObjectBundle.get_devices(), Props);
138+
}
139+
80140
} // namespace ext::oneapi::experimental
81141
} // namespace _V1
82142
} // namespace sycl
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//==-------- syclbin_properties.hpp - SYCLBIN and tooling properties -------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#pragma once
10+
11+
#include <sycl/ext/oneapi/properties/properties.hpp>
12+
#include <sycl/kernel_bundle.hpp>
13+
14+
namespace sycl {
15+
inline namespace _V1 {
16+
17+
namespace detail {
18+
struct link_props;
19+
} // namespace detail
20+
21+
namespace ext::oneapi::experimental {
22+
23+
/////////////////////////
24+
// PropertyT syclex::fast_link
25+
/////////////////////////
26+
struct fast_link
27+
: detail::run_time_property_key<fast_link, detail::PropKind::FastLink> {
28+
fast_link(bool DoFastLink = true) : value(DoFastLink) {}
29+
30+
bool value;
31+
};
32+
using fast_link_key = fast_link;
33+
34+
template <>
35+
struct is_property_key_of<fast_link_key, sycl::detail::link_props>
36+
: std::true_type {};
37+
} // namespace ext::oneapi::experimental
38+
} // namespace _V1
39+
} // namespace sycl

sycl/include/sycl/ext/oneapi/properties/property.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,9 @@ enum PropKind : uint32_t {
228228
InitialThreshold = 83,
229229
MaximumSize = 84,
230230
ZeroInit = 85,
231+
FastLink = 86,
231232
// PropKindSize must always be the last value.
232-
PropKindSize = 86,
233+
PropKindSize = 87,
233234
};
234235

235236
template <typename PropertyT> struct PropertyToKind {

sycl/include/sycl/sycl.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ can be disabled by setting SYCL_DISABLE_FSYCL_SYCLHPP_WARNING macro.")
133133
#include <sycl/ext/oneapi/experimental/reduction_properties.hpp>
134134
#include <sycl/ext/oneapi/experimental/root_group.hpp>
135135
#include <sycl/ext/oneapi/experimental/syclbin_kernel_bundle.hpp>
136+
#include <sycl/ext/oneapi/experimental/syclbin_properties.hpp>
136137
#include <sycl/ext/oneapi/experimental/tangle.hpp>
137138
#include <sycl/ext/oneapi/experimental/work_group_memory.hpp>
138139
#include <sycl/ext/oneapi/filter_selector.hpp>

sycl/source/backend.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ make_kernel_bundle(ur_native_handle_t NativeHandle,
231231
case (UR_PROGRAM_BINARY_TYPE_NONE):
232232
if (State == bundle_state::object) {
233233
auto Res = Adapter.call_nocheck<UrApiKind::urProgramCompileExp>(
234-
UrProgram, 1u, &Dev, nullptr);
234+
UrProgram, 1u, &Dev, ur_exp_program_flags_t{}, nullptr);
235235
if (Res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
236236
Res = Adapter.call_nocheck<UrApiKind::urProgramCompile>(
237237
ContextImpl.getHandleRef(), UrProgram, nullptr);
@@ -241,7 +241,7 @@ make_kernel_bundle(ur_native_handle_t NativeHandle,
241241

242242
else if (State == bundle_state::executable) {
243243
auto Res = Adapter.call_nocheck<UrApiKind::urProgramBuildExp>(
244-
UrProgram, 1u, &Dev, nullptr);
244+
UrProgram, 1u, &Dev, ur_exp_program_flags_t{}, nullptr);
245245
if (Res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
246246
Res = Adapter.call_nocheck<UrApiKind::urProgramBuild>(
247247
ContextImpl.getHandleRef(), UrProgram, nullptr);
@@ -261,8 +261,8 @@ make_kernel_bundle(ur_native_handle_t NativeHandle,
261261
Managed<ur_program_handle_t> UrLinkedProgram{Adapter};
262262
ur_program_handle_t ProgramsToLink[] = {UrProgram};
263263
auto Res = Adapter.call_nocheck<UrApiKind::urProgramLinkExp>(
264-
ContextImpl.getHandleRef(), 1u, &Dev, 1u, ProgramsToLink, nullptr,
265-
&UrLinkedProgram);
264+
ContextImpl.getHandleRef(), 1u, &Dev, ur_exp_program_flags_t{}, 1u,
265+
ProgramsToLink, nullptr, &UrLinkedProgram);
266266
if (Res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
267267
Res = Adapter.call_nocheck<UrApiKind::urProgramLink>(
268268
ContextImpl.getHandleRef(), 1u, ProgramsToLink, nullptr,

sycl/source/detail/device_image_impl.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -761,7 +761,8 @@ class device_image_impl
761761

762762
std::string XsFlags = extractXsFlags(BuildOptions, MRTCBinInfo->MLanguage);
763763
auto Res = Adapter.call_nocheck<UrApiKind::urProgramBuildExp>(
764-
UrProgram, DeviceVec.size(), DeviceVec.data(), XsFlags.c_str());
764+
UrProgram, DeviceVec.size(), DeviceVec.data(), ur_exp_program_flags_t{},
765+
XsFlags.c_str());
765766
if (Res == UR_RESULT_ERROR_UNSUPPORTED_FEATURE) {
766767
Res = Adapter.call_nocheck<UrApiKind::urProgramBuild>(
767768
ContextImpl.getHandleRef(), UrProgram, XsFlags.c_str());

0 commit comments

Comments
 (0)