-
Notifications
You must be signed in to change notification settings - Fork 15.6k
[SYCL] Add platform enumeration and info query using liboffload #166927
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
base: main
Are you sure you want to change the base?
[SYCL] Add platform enumeration and info query using liboffload #166927
Conversation
This is part of the SYCL support upstreaming effort. The relevant RFCs can be found here: https://discourse.llvm.org/t/rfc-add-full-support-for-the-sycl-programming-model/74080 https://discourse.llvm.org/t/rfc-sycl-runtime-upstreaming/74479 The SYCL runtime is device-agnostic and uses liboffload for offloading to GPU. This commit adds a dependency on liboffload, implementation of platform::get_platforms, platform::get_backend and platform::get_info methods, initial implementation of sycl-ls tool for manual testing of added functionality. Plan for next PR: device/context impl, rest of platform test infrastructure (depends on L0 liboffload plugin CI, our effort is joined) ABI tests
|
@tahonermann, @dvrogozh, @asudarsa, @aelovikov-intel, @sergey-semenov, @bader, @againull, @YuriPlyakhin, @vinser52 FYI, published for review. |
| typename backend_traits<Backend>::template return_type<SYCLObjectT>; | ||
|
|
||
| namespace detail { | ||
| inline std::string_view get_backend_name(const backend &Backend) { |
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.
I think we need to use something like _LIBCPP_HIDE_FROM_ABI here, if I understand the idea behind it correctly.
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.
I would leave questions about ABI till the time I will add ABI tests
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.
If I understand correctly, in intel/llvm this function is defined in headers only because we want to use it in the sycl-ls tool so the tool is always aligned on "known" backend with the SYCL RT.
If this intent still stands, I would add a comment about it, or otherwise this function should not exist here at all, because we don't use it anywhere else in the headers
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.
it is still used in sycl-ls.
added tiny comment
b15b6c0
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.
I recommend addressing ABI exposures as soon as possible. The code should be designed around ABI concerns if a stable ABI is to be supported. Delay could make handling ABI more complicated 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.
- I will remove this function form public headers
- although I don't understand why inline detail fully defined in header function should have any specific ABI related handling. What case do we consider?
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.
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.
@KseniyaTikhomirova, the concern with inline functions is that they might not be inlined. If the inline function definition is changed such that two translation units observe different definitions and those definitions are not inlined, then the program will contain two distinct definitions, one of which will be selected by the linker or loader and used to satisfy all non-inlined references.
| typename backend_traits<Backend>::template return_type<SYCLObjectT>; | ||
|
|
||
| namespace detail { | ||
| inline std::string_view get_backend_name(const backend &Backend) { |
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.
If I understand correctly, in intel/llvm this function is defined in headers only because we want to use it in the sycl-ls tool so the tool is always aligned on "known" backend with the SYCL RT.
If this intent still stands, I would add a comment about it, or otherwise this function should not exist here at all, because we don't use it anywhere else in the headers
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Various offload APIs `olGet*Info` are essentially untyped because they "return" value via `void *PropValue` output parameter. However, for C++ consumers (e.g., [SYCL][1] in llvm#166927) it would be beneficial if we could recover that type information. Before this PR it was only encoded in the comments near corresponding information info descriptors, e.g., ```c++ /////////////////////////////////////////////////////////////////////////////// /// @brief Supported event info. typedef enum ol_event_info_t { /// [ol_queue_handle_t] The handle of the queue associated with the device. OL_EVENT_INFO_QUEUE = 0, /// [bool] True if and only if the event is complete. OL_EVENT_INFO_IS_COMPLETE = 1, /// @cond OL_EVENT_INFO_LAST = 2, OL_EVENT_INFO_FORCE_UINT32 = 0x7fffffff /// @endcond } ol_event_info_t; ``` so was imposible for consumers to recover programmatically. [1] https://github.com/llvm/llvm-project/blob/b22192afdcbda7441e7a8fe7cbc9a06903e9e6ea/libsycl/src/detail/platform_impl.hpp#L78-L90
Various offload APIs `olGet*Info` are essentially untyped because they "return" value via `void *PropValue` output parameter. However, for C++ consumers (e.g., [SYCL][1] in llvm#166927) it would be beneficial if we could recover that type information. Before this PR it was only encoded in the comments near corresponding information info descriptors, e.g., ```c++ /////////////////////////////////////////////////////////////////////////////// /// @brief Supported event info. typedef enum ol_event_info_t { /// [ol_queue_handle_t] The handle of the queue associated with the device. OL_EVENT_INFO_QUEUE = 0, /// [bool] True if and only if the event is complete. OL_EVENT_INFO_IS_COMPLETE = 1, /// @cond OL_EVENT_INFO_LAST = 2, OL_EVENT_INFO_FORCE_UINT32 = 0x7fffffff /// @endcond } ol_event_info_t; ``` so was imposible for consumers to recover programmatically. [1] https://github.com/llvm/llvm-project/blob/b22192afdcbda7441e7a8fe7cbc9a06903e9e6ea/libsycl/src/detail/platform_impl.hpp#L78-L90
Various offload APIs `olGet*Info` are essentially untyped because they "return" value via `void *PropValue` output parameter. However, for C++ consumers (e.g., SYCL in llvm#166927) it would be beneficial if we could recover that type information. Before this PR it was only encoded in the comments near corresponding information info descriptors, e.g., ```c++ /////////////////////////////////////////////////////////////////////////////// /// @brief Supported event info. typedef enum ol_event_info_t { /// [ol_queue_handle_t] The handle of the queue associated with the device. OL_EVENT_INFO_QUEUE = 0, /// [bool] True if and only if the event is complete. OL_EVENT_INFO_IS_COMPLETE = 1, /// @cond OL_EVENT_INFO_LAST = 2, OL_EVENT_INFO_FORCE_UINT32 = 0x7fffffff /// @endcond } ol_event_info_t; ``` and not accessible programmatically.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
| _LIBSYCL_BEGIN_NAMESPACE_SYCL | ||
| namespace detail { | ||
|
|
||
| const char *stringifyErrorCode(int32_t error) { |
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.
I think this API should become an liboffload entry point. I'll add that to my TODO list.
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.
There is allready API in liboffload. There are << operator for enum ol_errc_t
Check OffloadPrint.hpp (note this is tablegen generated file)
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.
Kseniya to check if we can reuse it
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.
update: can't reuse since we won't use llvmSupport lib for SYCl RT but operator returns llvm::raw_stream
| #ifndef __SYCL_PARAM_TRAITS_SPEC | ||
| static_assert(false, "__SYCL_PARAM_TRAITS_SPEC is required but not defined"); | ||
| #endif | ||
|
|
||
| // 4.6.2.4. Information descriptors | ||
| __SYCL_PARAM_TRAITS_SPEC(platform, version, std::string, OL_PLATFORM_INFO_VERSION) | ||
| __SYCL_PARAM_TRAITS_SPEC(platform, name, std::string, OL_PLATFORM_INFO_NAME) | ||
| __SYCL_PARAM_TRAITS_SPEC(platform, vendor, std::string, OL_PLATFORM_INFO_VENDOR_NAME) |
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.
Subjective, but I'm not a fan of this approach for two reasons:
- Smart use of preprocessor in distributable header files (i.e.,
libsycl/includeinstead oflibsycl/source/**). OL_*are implementation details and don't need to be present in those distributable headers.
I think avoiding it doesn't result in too much code duplication: 823c765, but I understand that this is subjective.
Macro in exports can be avoided too, but that's probably too much magic:
// sycl.hpp
#define _EXPORT __attribute__((visibility("default")))
struct S {
template <typename> _EXPORT void foo();
};
// libsycl.so
template <typename> [[gnu::used]] _EXPORT void S::foo() {}
template _EXPORT void S::foo<char>(); // current approach
// "Clever" helper, needs `[[gnu::used]]` above.
template <typename... Ts> void instantiate_helper() {
(((void)(&S::foo<Ts>), ...));
}
static void instantiate() { instantiate_helper<int, float, double>(); }$ clang++ a.cpp -c -fvisibility=hidden -fvisibility-inlines-hidden -O0 ; nm a.o | c++filt
0000000000000000 W void S::foo<char>()
0000000000000000 W void S::foo<double>()
0000000000000000 W void S::foo<float>()
0000000000000000 W void S::foo<int>()
$ clang++ a.cpp -c -fvisibility=hidden -fvisibility-inlines-hidden -O3 ; nm a.o | c++filt
0000000000000000 W void foo<char>()
0000000000000000 W void foo<double>()
0000000000000000 W void foo<float>()
0000000000000000 W void foo<int>()
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.
I'd like to ask other folks for opinion here. The benefit that .def file provides is necessity in update of only one place in the code to add info or property (we use the same approach there) if there is no special handling.
@sergey-semenov, @bader, @vinser52, @tahonermann, @AlexeySachkov do you have any preference?
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.
Subjective, but I'm not a fan of this approach for two reasons:
- Smart use of preprocessor in distributable header files (i.e.,
libsycl/includeinstead oflibsycl/source/**).OL_*are implementation details and don't need to be present in those distributable headers.
I don't understand the problem with using pre-processor in distributed header files, but I agree that mapping from SYCL API to liboffload API should be done in the library source code.
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.
I am going to apply Andrey's proposal. Please let me know if anyone has objections.
the reason is:
I wanted info descriptors declaration to be independent for SYCL obj in terms of header files (the opposite to what we have in https://github.com/intel/llvm/blob/sycl/sycl/include/sycl/detail/info_desc_helpers.hpp).
With macro it means pretty low level of unification for helpers. Base class for info desc as proposed by Andrey gives opportunities to achieve the goal I wanted. Plus 3 people agreed that Offload RT codes should be hidden in SYCL RT that already weakens approach with macros.
I have started implementation of 'device' and there we will be able to check & see how it fits into our code base.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
|
I'd like to define naming style for the upstreaming code base. Given:
and
SYCL 2020 declare types in STL's style with snake case. LLVM guide has no requirements about file names so I suggest:
changes comparing to impl/llvm:
Apply CamelCase to our impl and service classes in snake_case, for example platform_impl should become PlatformImpl and so on: @bader @tahonermann could you please provide your opinion:
|
@KseniyaTikhomirova, please, create a libsycl/docs/CodingGuidelines.rst file and put your suggestion there. Let's separate this discussion from adding SYCL platform.
What is impl/llvm? Do you mean intel/llvm repository? |
tahonermann
left a comment
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.
I got part of the way through the PR today. I'll review more tomorrow.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
thanks for suggestion, done #171867 |
tahonermann
left a comment
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.
A few additional comments and some responses to previous ones.
| #ifdef __SYCL_DEVICE_ONLY__ | ||
| (void)Obj; | ||
| return 0; |
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.
If this function won't implement useful semantics when compiled for the device, can we at least have it trap at run-time instead of returning a valid object that doesn't satisfy the function postconditions? E.g., __builtin_unreachable()?
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.
can we at least have it trap at run-time instead of returning a valid object that doesn't satisfy the function postconditions? E.g.,
__builtin_unreachable()?
This automatically assumes, that the underlying device compiler (and any formats for representing device code) support such semantics. That is not the case for SPIR-V, as far as I know, for example.
What is the reason for having the macro in the first place here? I can't imagine hash APIs being used from device code without violating some other restrictions or simply being a UB.
As such, triggering a compilation/link failure through an unresolved symbol wouldn't be a bad idea. We can just leave this function as a declaration-only for device code as well.
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.
That is not the case for SPIR-V, as far as I know, for example.
https://godbolt.org/z/qd8fGTMrG . Shouldn't we see llvm-spirv fail here then?
This automatically assumes, that the underlying device compiler (and any formats for representing device code) support such semantics.
That is still a good point though, we don't know about other targets like PTX.
What is the reason for having the macro in the first place here?
Not an expert in std headers implementation but it fails to compile https://godbolt.org/z/Eb94KMMed
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.
I removed the macro completely for this code. the best case - we rely on compiler diagnostic, worst case - UB, since "implementations are not required to support device code that calls library functions from the C++ core language"
done in 002eeb3
| # define _LIBSYCL_DLL_LOCAL __attribute__((visibility("hidden"))) | ||
| # define _LIBSYCL_EXPORT __attribute__((visibility("default"))) |
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.
That's right; the C++11 attribute syntax is more restrictive in where it can be placed. Can we not use use the C++11 placement everywhere though? Or would that conflict with the syntax location required for Microsoft's __declspex(X) syntax? It would be great if we can standardize on the C++11 attribute placement requirements.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
20d562d to
9653e23
Compare
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
Fznamznon
left a comment
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.
Can we add a test on this stage?
Also some dumb comments from a brief look
| }, | ||
| &Mapping); | ||
| // Now register all platforms and devices into the topologies | ||
| auto &OffloadTopologies = getOffloadTopologies(); |
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.
LLVM coding guidelines suggest using auto only when the type is obvious, i.e. cases like auto* a = dyn_cast<type>(b), will that be the case for libsycl?
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.
Honestly I don't think it is important to show exact type here. it is pretty obvious from code that it is a container and we have exact element type shown 2 lines below.
| // case OL_PLATFORM_BACKEND_LEVEL_ZERO: | ||
| // return backend::level_zero; |
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.
Is there plans for level 0?
Perhaps it makes sense to leave a comment saying coming soon.
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.
yes, I expected this PR with L0 support to be merged much faster #158900 but it is still on review. Once it's merged these lines much be uncommented. May be I will be able to uncomment them before the merge of my PR.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
I'd like to but we don't have CI ready. |
tahonermann
left a comment
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.
I got through much of the rest of the code today. I hope to get through the rest tomorrow.
| namespace detail { | ||
| template <typename T> struct is_backend_info_desc : std::false_type {}; | ||
| } // namespace detail |
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.
detail::is_backend_info_desc doesn't appear to be used in this PR. Should it be omitted for now? I see platform::get_backend_info() isn't implemented yet.
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.
that's intentional and aligned with intel/llvm.
SYCl 2020 spec declare get_backend_info method but doesn't specify anything that can be queried via this method.
So now it is declared but not defined and there is no such type T that can be used for compilation of this code.
| #ifndef _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP | ||
| #define _LIBSYCL___IMPL_DETAIL_MACRO_DEFINITIONS_HPP | ||
|
|
||
| static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or 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.
Testing the value of __cplusplus will require compilation with the /Zc:__cplusplus option when compiling with MSVC (documentation). We can avoid pushing that requirement on users by checking the _MSVC_LANG predefined macro when compiling with MSVC instead (documentation).
| static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); | |
| #if defined(_MSC_VER) | |
| static_assert(_MSVC_LANG >= 201703L, "Libsycl requires C++17 or later."); | |
| #else | |
| static_assert(__cplusplus >= 201703L, "Libsycl requires C++17 or later."); | |
| #endif |
Yes, this is super annoying.
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.
thank you, done 9b4b779
| // Note! This class relies on the fact that all SYCL interface | ||
| // classes contain "impl" field that points to implementation object. "impl" | ||
| // field should be accessible from this class. |
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.
Why is the pointer-to-impl idiom being used so extensively? I'm personally not a fan of it for performance reasons. If the reason is to create an ABI boundary, I think there are better ways to do that.
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.
I believe that main justification is that pimpl idiom fits into common reference semantics really well https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#sec:reference-semantics.
| }; | ||
| struct vendor : detail::info_desc_tag<vendor, sycl::platform> { | ||
| using return_type = std::string; | ||
| }; |
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.
No support for platform::extensions? Or just not yet? I understand that interface is deprecated.
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.
I expect it to be "not just yet". I am temporally skipping deprecated features or features that are not needed for Phase 0.
Plus I expect it to be dependent on device impl.
platform``: deprecated info descriptor is not implemented (info::platform::extensions), to implement on RT level with ``device::get_info<info::device::aspects>()
| /// Constructs a SYCL platform which contains the default device. | ||
| platform(); |
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.
Why remove the default constructor for platform()? SYCL 2020 requires one. I guess it is because default_selector_v isn't yet implemented?
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.
yes, that's correct
| if (PlatformId >= MDevRangePerPlatformId.size()) | ||
| return {nullptr, 0}; |
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.
Perhaps an assert would be appropriate here as well?
| std::vector<range_view<const ol_device_handle_t>> | ||
| MDevRangePerPlatformId; // PlatformDevices.size() == Platforms.size() |
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.
Should PlatformDevices and Platforms be MDevices and MPlatforms respectively?
| #undef _OFFLOAD_ERRC | ||
|
|
||
| default: | ||
| return "Unknown error code"; |
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.
Perhaps there should be an assertion here? Or this should be unreachable?
| /// | ||
| /// \returns liboffload error code returned by API call. | ||
| template <typename FunctionType, typename... ArgsT> | ||
| ol_result_t call_nocheck(FunctionType &Function, ArgsT &&...Args) { |
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.
Perhaps rename to callNoCheck() for consistency?
| /// | ||
| /// \throw sycl::runtime_exception if the call was not successful. | ||
| template <typename FunctionType, typename... ArgsT> | ||
| void call_and_throw(FunctionType &Function, ArgsT &&...Args) { |
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.
Perhaps rename to callAndThrow() for consistency?
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.
could you please review style guideline I proposed for libsycl? #171867
once we align on it, I will walk through all code and align all names with it.
Signed-off-by: Tikhomirova, Kseniya <kseniya.tikhomirova@intel.com>
This is part of the SYCL support upstreaming effort. The relevant RFCs can be found here:
https://discourse.llvm.org/t/rfc-add-full-support-for-the-sycl-programming-model/74080 https://discourse.llvm.org/t/rfc-sycl-runtime-upstreaming/74479
The SYCL runtime is device-agnostic and uses liboffload for offloading to GPU. This commit adds a dependency on liboffload, implementation of platform::get_platforms, platform::get_backend and platform::get_info methods, initial implementation of sycl-ls tool for manual testing of added functionality.
Plan for next PR:
device/context impl, rest of platform
test infrastructure (depends on L0 liboffload plugin CI, our effort is joined) ABI tests