-
Notifications
You must be signed in to change notification settings - Fork 803
[SYCL] Extends support for SYCL 2020 implicitly device copyable types #8195
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
Changes from 12 commits
cbf6abe
cd4b93d
6b02640
80c8fc6
e36f4b8
7fcac67
61c6e12
918c61a
8804479
290c72e
982208a
10913de
ad1a710
d8e5c39
7e61201
c82955e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| // RUN: %clangxx -fsycl -fsycl-targets=%sycl_triple %s -o %t.out | ||
|
|
||
| #include <sycl/sycl.hpp> | ||
| #include <variant> | ||
|
|
||
| struct ACopyable { | ||
| int i; | ||
| ACopyable() = default; | ||
| ACopyable(int _i) : i(_i) {} | ||
| ACopyable(const ACopyable &x) : i(x.i) {} | ||
| }; | ||
|
|
||
| template <> struct sycl::is_device_copyable<ACopyable> : std::true_type {}; | ||
|
|
||
| int main() { | ||
| static_assert(sycl::is_device_copyable_v<std::pair<int, float>>); | ||
| static_assert(sycl::is_device_copyable_v<std::pair<ACopyable, float>>); | ||
| static_assert(sycl::is_device_copyable_v<std::tuple<int, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v<std::tuple<ACopyable, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v<std::variant<int, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v<std::variant<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<std::array<int, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<std::array<ACopyable, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<std::optional<int>>); | ||
| static_assert(sycl::is_device_copyable_v<std::optional<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<std::string_view>); | ||
| #if __cpp_lib_span >= 202002 | ||
| static_assert(sycl::is_device_copyable_v<std::span<int>>); | ||
| #endif | ||
| static_assert(sycl::is_device_copyable_v<const sycl::span<int>>); | ||
|
|
||
| // const | ||
| static_assert(sycl::is_device_copyable_v<const std::pair<int, float>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::pair<ACopyable, float>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::tuple<int, float, bool>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const std::tuple<ACopyable, float, bool>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const std::variant<int, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::variant<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::array<int, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::array<ACopyable, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::optional<int>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::optional<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<const std::string_view>); | ||
| #if __cpp_lib_span >= 202002 | ||
| static_assert(sycl::is_device_copyable_v<const std::span<int>>); | ||
| #endif | ||
| static_assert(sycl::is_device_copyable_v<const sycl::span<int>>); | ||
|
|
||
| // volatile | ||
| static_assert(sycl::is_device_copyable_v<volatile std::pair<int, float>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<volatile std::pair<ACopyable, float>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<volatile std::tuple<int, float, bool>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<volatile std::tuple<ACopyable, float, bool>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<volatile std::variant<int, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v<volatile std::variant<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<volatile std::array<int, 513>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<volatile std::array<ACopyable, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<volatile std::optional<int>>); | ||
| static_assert(sycl::is_device_copyable_v<volatile std::optional<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<volatile std::string_view>); | ||
| #if __cpp_lib_span >= 202002 | ||
| static_assert(sycl::is_device_copyable_v<volatile std::span<int>>); | ||
| #endif | ||
| static_assert(sycl::is_device_copyable_v<volatile sycl::span<int>>); | ||
|
|
||
| // const volatile | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::pair<int, float>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::pair<ACopyable, float>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::tuple<int, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v< | ||
| const volatile std::tuple<ACopyable, float, bool>>); | ||
| static_assert(sycl::is_device_copyable_v< | ||
| const volatile std::variant<int, float, bool>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::variant<ACopyable>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::array<int, 513>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::array<ACopyable, 513>>); | ||
| static_assert(sycl::is_device_copyable_v<const volatile std::optional<int>>); | ||
| static_assert( | ||
| sycl::is_device_copyable_v<const volatile std::optional<ACopyable>>); | ||
| static_assert(sycl::is_device_copyable_v<const volatile std::string_view>); | ||
| #if __cpp_lib_span >= 202002 | ||
| static_assert(sycl::is_device_copyable_v<const volatile std::span<int>>); | ||
| #endif | ||
| static_assert(sycl::is_device_copyable_v<const volatile sycl::span<int>>); | ||
|
|
||
| #if COMPILE_ONLY | ||
| sycl::queue q; | ||
| { | ||
| std::variant<ACopyable> variant_arr[5]; | ||
| std::variant<ACopyable> variant; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.single_task([=]() { | ||
| // std::variant with complex types relies on virtual functions, so | ||
| // they cannot be used within sycl kernels | ||
|
||
| auto size = sizeof(variant_arr[0]); | ||
| size = sizeof(variant); | ||
| }); | ||
| }).wait_and_throw(); | ||
| } | ||
| { | ||
| const std::variant<ACopyable> variant_arr[5]; | ||
| const std::variant<ACopyable> variant; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.single_task([=]() { | ||
| // std::variant with complex types relies on virtual functions, so | ||
| // they cannot be used within sycl kernels | ||
| auto size = sizeof(variant_arr[0]); | ||
| size = sizeof(variant); | ||
| }); | ||
| }).wait_and_throw(); | ||
| } | ||
| { | ||
| volatile std::variant<ACopyable> variant_arr[5]; | ||
| volatile std::variant<ACopyable> variant; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.single_task([=]() { | ||
| // std::variant with complex types relies on virtual functions, so | ||
| // they cannot be used within sycl kernels | ||
| auto size = sizeof(variant_arr[0]); | ||
| size = sizeof(variant); | ||
| }); | ||
| }).wait_and_throw(); | ||
| } | ||
| { | ||
| const volatile std::variant<ACopyable> variant_arr[5]; | ||
| const volatile std::variant<ACopyable> variant; | ||
| q.submit([&](sycl::handler &cgh) { | ||
| cgh.single_task([=]() { | ||
| // std::variant with complex types relies on virtual functions, so | ||
| // they cannot be used within sycl kernels | ||
| auto size = sizeof(variant_arr[0]); | ||
| size = sizeof(variant); | ||
| }); | ||
| }).wait_and_throw(); | ||
| } | ||
| #endif | ||
|
|
||
| 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.
I'd like to have more runtime checks that the values of those types actually match between host/device, i.e. check the content of pair.first and/or pair.second.
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.
Just to clarify - this is my main concern, two other comments are more subjective in nature and thus optional to implement.
Uh oh!
There was an error while loading. Please reload this page.
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 suggest that we perhaps have two test cases: one which simply contains a bunch of
static_assert(sycl::is_device_copyable_v<some_type_here>)to check that we properly specialize the trait and another one, which checks runtime behavior, i.e. that we are actually able to properly copy values of those types to kernels and read them back.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 have submitted a PR to llvm-test-suite repo adding tests that check the runtime behavior for this.
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 test is supposed to be compile-only, then I suggest to remove
-o %t.outand add-fsyntax-only, see docs for some BKMs. You can also remove any code which submits kernels, because that will be checked in the E2E test you have