-
Notifications
You must be signed in to change notification settings - Fork 787
[SYCL] Implement loading SYCLBIN into kernel_bundle #18949
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
steffenlarsen
merged 30 commits into
intel:sycl
from
steffenlarsen:steffen/load_syclbin_kb
Jun 26, 2025
Merged
Changes from all commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
7b3873c
[SYCL] Implement loading SYCLBIN into kernel_bundle
steffenlarsen ec21a10
Fix formatting
steffenlarsen 7061d2c
Address formatting and warnings
steffenlarsen 9bb13aa
Even more pedantic formatting and errors
steffenlarsen c9f17c2
Merge remote-tracking branch 'intel/sycl' into steffen/load_syclbin_kb
steffenlarsen 258ecee
Rebase and fix warning
steffenlarsen 4700308
Fix the right file
steffenlarsen 2130901
Fix windows build failure
steffenlarsen c49ddf4
Revert tooling changes
steffenlarsen af8e38e
Exclude CUDA and HIP for now
steffenlarsen 9b632ba
Avoid charconv for RHEL builds
steffenlarsen fcebf1f
Add windows symbol
steffenlarsen af1040c
Avoid warning on RHEL
steffenlarsen c761fe8
Enable link tests for all targets
steffenlarsen a927f73
Switch kernel prefix to string_view
steffenlarsen c3a7a09
Avoid using filesystem on systems that don't support them
steffenlarsen a8b6ceb
Merge remote-tracking branch 'intel/sycl' into steffen/load_syclbin_kb
steffenlarsen f27d08b
Gather kernel names from new property set
steffenlarsen 36f9204
Pass targets to tests
steffenlarsen 5a2f313
Disable on CUDA due to known regression
steffenlarsen bffcbc8
Change requirement to avoid building for nvptx for now
steffenlarsen 76b07eb
Merge remote-tracking branch 'intel/sycl' into steffen/load_syclbin_kb
steffenlarsen d7ad2b7
Fix wrong size timing and image ID
steffenlarsen f2b7fea
Lazily init compressed size
steffenlarsen ab7a19a
Fix def
steffenlarsen 8d96fb3
Mutable image size
steffenlarsen abc3a2b
Revert lazy image size change
steffenlarsen f333fbe
Merge remote-tracking branch 'intel/sycl' into steffen/load_syclbin_kb
steffenlarsen e9dd9a9
Merge remote-tracking branch 'intel/sycl' into steffen/load_syclbin_kb
steffenlarsen b248a6f
Address comments
steffenlarsen File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
82 changes: 82 additions & 0 deletions
82
sycl/include/sycl/ext/oneapi/experimental/syclbin_kernel_bundle.hpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
//==---- syclbin_kernel_bundle.hpp - SYCLBIN-based kernel_bundle tooling ---==// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
#pragma once | ||
|
||
#include <sycl/ext/oneapi/properties/properties.hpp> | ||
#include <sycl/kernel_bundle.hpp> | ||
|
||
#include <fstream> | ||
#include <string> | ||
|
||
#if __has_include(<filesystem>) | ||
#include <filesystem> | ||
#endif | ||
|
||
#if __has_include(<span>) | ||
#include <span> | ||
#endif | ||
|
||
namespace sycl { | ||
inline namespace _V1 { | ||
namespace ext::oneapi::experimental { | ||
|
||
template <bundle_state State, typename PropertyListT = empty_properties_t> | ||
std::enable_if_t<State != bundle_state::ext_oneapi_source, kernel_bundle<State>> | ||
get_kernel_bundle(const context &Ctxt, const std::vector<device> &Devs, | ||
const sycl::span<char> &Bytes, PropertyListT = {}) { | ||
std::vector<device> UniqueDevices = | ||
sycl::detail::removeDuplicateDevices(Devs); | ||
|
||
dm-vodopyanov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
sycl::detail::KernelBundleImplPtr Impl = | ||
sycl::detail::get_kernel_bundle_impl(Ctxt, UniqueDevices, Bytes, State); | ||
return sycl::detail::createSyclObjFromImpl<kernel_bundle<State>>(Impl); | ||
} | ||
|
||
#if __cpp_lib_span | ||
template <bundle_state State, typename PropertyListT = empty_properties_t> | ||
std::enable_if_t<State != bundle_state::ext_oneapi_source, kernel_bundle<State>> | ||
get_kernel_bundle(const context &Ctxt, const std::vector<device> &Devs, | ||
const std::span<char> &Bytes, PropertyListT Props = {}) { | ||
return experimental::get_kernel_bundle( | ||
Ctxt, Devs, sycl::span<char>(Bytes.data(), Bytes.size()), Props); | ||
} | ||
#endif | ||
|
||
#if __cpp_lib_filesystem | ||
template <bundle_state State, typename PropertyListT = empty_properties_t> | ||
std::enable_if_t<State != bundle_state::ext_oneapi_source, kernel_bundle<State>> | ||
get_kernel_bundle(const context &Ctxt, const std::vector<device> &Devs, | ||
const std::filesystem::path &Filename, | ||
PropertyListT Props = {}) { | ||
std::vector<char> RawSYCLBINData; | ||
{ | ||
std::ifstream FileStream{Filename, std::ios::binary}; | ||
if (!FileStream.is_open()) | ||
throw std::ios_base::failure("Failed to open SYCLBIN file: " + | ||
Filename.string()); | ||
RawSYCLBINData = | ||
std::vector<char>{std::istreambuf_iterator<char>(FileStream), | ||
std::istreambuf_iterator<char>()}; | ||
} | ||
return experimental::get_kernel_bundle<State>( | ||
Ctxt, Devs, sycl::span<char>{RawSYCLBINData}, Props); | ||
} | ||
|
||
template <bundle_state State, typename PropertyListT = empty_properties_t> | ||
std::enable_if_t<State != bundle_state::ext_oneapi_source, kernel_bundle<State>> | ||
get_kernel_bundle(const context &Ctxt, const std::filesystem::path &Filename, | ||
PropertyListT Props = {}) { | ||
return experimental::get_kernel_bundle<State>(Ctxt, Ctxt.get_devices(), | ||
Filename, Props); | ||
} | ||
#endif | ||
|
||
} // namespace ext::oneapi::experimental | ||
} // namespace _V1 | ||
} // namespace sycl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
//===--- Base64.h - Base64 Encoder/Decoder ----------------------*- C++ -*-===// | ||
// | ||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
// See https://llvm.org/LICENSE.txt for license information. | ||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// Adjusted copy of llvm/include/llvm/Support/Base64.h. | ||
// TODO: Remove once we can consistently link the SYCL runtime library with | ||
// LLVMSupport. | ||
|
||
#pragma once | ||
|
||
#include <cstdint> | ||
#include <memory> | ||
#include <string> | ||
#include <vector> | ||
|
||
namespace sycl { | ||
inline namespace _V1 { | ||
namespace detail { | ||
|
||
class Base64 { | ||
private: | ||
// Decode a single character. | ||
static inline int decode(char Ch) { | ||
if (Ch >= 'A' && Ch <= 'Z') // 0..25 | ||
return Ch - 'A'; | ||
else if (Ch >= 'a' && Ch <= 'z') // 26..51 | ||
return Ch - 'a' + 26; | ||
else if (Ch >= '0' && Ch <= '9') // 52..61 | ||
return Ch - '0' + 52; | ||
else if (Ch == '+') // 62 | ||
return 62; | ||
else if (Ch == '/') // 63 | ||
return 63; | ||
return -1; | ||
} | ||
|
||
// Decode a quadruple of characters. | ||
static inline void decode4(const char *Src, byte *Dst) { | ||
int BadCh = -1; | ||
|
||
for (auto I = 0; I < 4; ++I) { | ||
char Ch = Src[I]; | ||
int Byte = decode(Ch); | ||
|
||
if (Byte < 0) { | ||
BadCh = Ch; | ||
break; | ||
} | ||
Dst[I] = (byte)Byte; | ||
} | ||
if (BadCh != -1) | ||
throw sycl::exception(make_error_code(errc::invalid), | ||
"Invalid char in base 64 encoding."); | ||
} | ||
|
||
public: | ||
using byte = uint8_t; | ||
|
||
// Get the size of the encoded byte sequence of given size. | ||
static size_t getDecodedSize(size_t SrcSize) { return (SrcSize * 3 + 3) / 4; } | ||
|
||
// Decode a sequence of given size into a pre-allocated memory. | ||
// Returns the number of bytes in the decoded result or 0 in case of error. | ||
static size_t decode(const char *Src, byte *Dst, size_t SrcSize) { | ||
size_t SrcOff = 0; | ||
size_t DstOff = 0; | ||
|
||
// decode full quads | ||
for (size_t Qch = 0; Qch < SrcSize / 4; ++Qch, SrcOff += 4, DstOff += 3) { | ||
byte Ch[4] = {0, 0, 0, 0}; | ||
decode4(Src + SrcOff, Ch); | ||
|
||
// each quad of chars produces three bytes of output | ||
Dst[DstOff + 0] = Ch[0] | (Ch[1] << 6); | ||
Dst[DstOff + 1] = (Ch[1] >> 2) | (Ch[2] << 4); | ||
Dst[DstOff + 2] = (Ch[2] >> 4) | (Ch[3] << 2); | ||
} | ||
auto RemChars = SrcSize - SrcOff; | ||
|
||
if (RemChars == 0) | ||
return DstOff; | ||
// decode the remainder; variants: | ||
// 2 chars remain - produces single byte | ||
// 3 chars remain - produces two bytes | ||
|
||
if (RemChars != 2 && RemChars != 3) | ||
throw sycl::exception(make_error_code(errc::invalid), | ||
"Invalid encoded sequence length."); | ||
|
||
int Ch0 = decode(Src[SrcOff++]); | ||
int Ch1 = decode(Src[SrcOff++]); | ||
int Ch2 = RemChars == 3 ? decode(Src[SrcOff]) : 0; | ||
|
||
if (Ch0 < 0 || Ch1 < 0 || Ch2 < 0) | ||
throw sycl::exception( | ||
make_error_code(errc::invalid), | ||
"Invalid characters in the encoded sequence remainder."); | ||
Dst[DstOff++] = Ch0 | (Ch1 << 6); | ||
|
||
if (RemChars == 3) | ||
Dst[DstOff++] = (Ch1 >> 2) | (Ch2 << 4); | ||
return DstOff; | ||
} | ||
|
||
// Allocate minimum required amount of memory and decode a sequence of given | ||
// size into it. | ||
// Returns the decoded result. The size can be obtained via getDecodedSize. | ||
static std::unique_ptr<byte[]> decode(const char *Src, size_t SrcSize) { | ||
size_t DstSize = getDecodedSize(SrcSize); | ||
std::unique_ptr<byte[]> Dst(new byte[DstSize]); | ||
decode(Src, Dst.get(), SrcSize); | ||
return Dst; | ||
} | ||
}; | ||
|
||
} // namespace detail | ||
} // namespace _V1 | ||
} // namespace sycl |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't these need an #else ? What will happen if the compiler doesn't have filesystem or span? IIRC, we are still trying to support GCC 7.5 whose support of C++17 filesystem feature is not complete. Take a look at what is done in os_util.cpp, where the fallback includes experimental/filesystem.
Also, std::span is C++20, iirc. But we have
sycl::span
, so maybe use that?OR if I'm operating on yesterdays information and this is no longer a problem, let me know.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The filesystem functionality is part of the public interface. Similar to how the
std::span
interface isn't available, we can't offer those interfaces if the user doesn't have the headers available.Indeed! There is an overload of the new interfaces with
sycl::span
, but one of the interfaces take astd::span
directly, so we need to optionally include it to offer that interface.Definitely still a problem, but in this case the
sycl::span
interface will always be available and the rest are cases of "too bad, you can't use those. Update your compiler."