Skip to content

Commit f84e78e

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 df025ac commit f84e78e

File tree

15 files changed

+578
-97
lines changed

15 files changed

+578
-97
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
@@ -137,6 +137,7 @@ can be disabled by setting SYCL_DISABLE_FSYCL_SYCLHPP_WARNING macro.")
137137
#include <sycl/ext/oneapi/experimental/reduction_properties.hpp>
138138
#include <sycl/ext/oneapi/experimental/root_group.hpp>
139139
#include <sycl/ext/oneapi/experimental/syclbin_kernel_bundle.hpp>
140+
#include <sycl/ext/oneapi/experimental/syclbin_properties.hpp>
140141
#include <sycl/ext/oneapi/experimental/tangle.hpp>
141142
#include <sycl/ext/oneapi/experimental/work_group_memory.hpp>
142143
#include <sycl/ext/oneapi/filter_selector.hpp>

0 commit comments

Comments
 (0)