-
Notifications
You must be signed in to change notification settings - Fork 769
[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
Open
steffenlarsen
wants to merge
16
commits into
intel:sycl
Choose a base branch
from
steffenlarsen:steffen/load_syclbin_kb
base: sycl
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
16 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 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
83 changes: 83 additions & 0 deletions
83
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,83 @@ | ||
//==---- 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); | ||
|
||
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 sycl::exception(make_error_code(errc::invalid), | ||
"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.