diff --git a/sycl/include/sycl/detail/type_traits/vec_marray_traits.hpp b/sycl/include/sycl/detail/type_traits/vec_marray_traits.hpp index 6ce39bf6a072a..7196a7ca4f868 100644 --- a/sycl/include/sycl/detail/type_traits/vec_marray_traits.hpp +++ b/sycl/include/sycl/detail/type_traits/vec_marray_traits.hpp @@ -13,6 +13,18 @@ #include +#ifndef __SYCL_USE_LIBSYCL8_VEC_IMPL +#if defined(__INTEL_PREVIEW_BREAKING_CHANGES) +// Several specification changes need to be implemented together to keep CTS +// passing. We'll switch to `0` once they all land. +// `__SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE` needs to be changed to use this +// `__SYCL_USE_LIBSYCL8_VEC_IMPL` at that time as well. +#define __SYCL_USE_LIBSYCL8_VEC_IMPL 1 +#else +#define __SYCL_USE_LIBSYCL8_VEC_IMPL 1 +#endif +#endif + namespace sycl { inline namespace _V1 { template class __SYCL_EBO vec; diff --git a/sycl/include/sycl/vector.hpp b/sycl/include/sycl/vector.hpp index a10a7445602f4..06458a38e3d90 100644 --- a/sycl/include/sycl/vector.hpp +++ b/sycl/include/sycl/vector.hpp @@ -137,19 +137,11 @@ inline constexpr bool is_fundamental_or_half_or_bfloat16 = std::is_fundamental_v || std::is_same_v, half> || std::is_same_v, ext::oneapi::bfloat16>; -// Proposed SYCL specification changes have sycl::vec having different ctors -// available based on the number of elements. Without C++20's concepts we'll -// have to use partial specialization to represent that. This is a helper to do -// that. An alternative could be to have different specializations of the -// `sycl::vec` itself but then we'd need to outline all the common interfaces to -// re-use them. -// -// Note: the functional changes haven't been implemented yet, we've split -// vec_base in advance as a way to make changes easier to review/verify. -// -// Another note: `vector_t` is going to be removed, so corresponding ctor was -// kept inside `sycl::vec` to have all `vector_t` functionality in a single -// place. +// Per SYCL specification sycl::vec has different ctors available based on the +// number of elements. Without C++20's concepts we'd have to use partial +// specialization to represent that. This is a helper to do that. An alternative +// could be to have different specializations of the `sycl::vec` itself but then +// we'd need to outline all the common interfaces to re-use them. template class vec_base { // https://registry.khronos.org/SYCL/specs/sycl-2020/html/sycl-2020.html#memory-layout-and-alignment // It is required by the SPEC to align vec with vec. @@ -271,6 +263,43 @@ template class vec_base { : vec_base{VecArgArrayCreator::Create(args...), std::make_index_sequence()} {} }; + +#if !__SYCL_USE_LIBSYCL8_VEC_IMPL +template class vec_base { + using DataType = std::conditional_t< +#if __SYCL_USE_PLAIN_ARRAY_AS_VEC_STORAGE + true, +#else + sizeof(std::array) == sizeof(DataT[1]) && + alignof(std::array) == alignof(DataT[1]), +#endif + DataT[1], std::array>; + +protected: + static constexpr int alignment = (std::min)((size_t)64, sizeof(DataType)); + alignas(alignment) DataType m_Data{}; + +public: + constexpr vec_base() = default; + constexpr vec_base(const vec_base &) = default; + constexpr vec_base(vec_base &&) = default; + constexpr vec_base &operator=(const vec_base &) = default; + constexpr vec_base &operator=(vec_base &&) = default; + + // Not `explicit` on purpose, differs from NumElements > 1. + constexpr vec_base(const DataT &arg) : m_Data{{arg}} {} + + // FIXME: Temporary workaround because swizzle's `operator DataT` is a + // template. + template >, + typename = std::enable_if_t, + typename = std::enable_if< + std::is_convertible_v>> + constexpr vec_base(const Swizzle &other) + : vec_base(static_cast(other)) {} +}; +#endif } // namespace detail ///////////////////////// class sycl::vec ///////////////////////// diff --git a/sycl/test/basic_tests/vectors/assign.cpp b/sycl/test/basic_tests/vectors/assign.cpp index ca8f185d7a296..67ed92971d022 100644 --- a/sycl/test/basic_tests/vectors/assign.cpp +++ b/sycl/test/basic_tests/vectors/assign.cpp @@ -1,4 +1,5 @@ -// RUN: %clangxx -fsycl -fsyntax-only %s -fpreview-breaking-changes +// TODO: Remove `__SYCL_USE_LIBSYCL8_VEC_IMPL` once it's auto-set. +// RUN: %clangxx -fsycl -fsyntax-only %s -fpreview-breaking-changes -D__SYCL_USE_LIBSYCL8_VEC_IMPL=0 // RUN: %clangxx -fsycl -fsyntax-only %s #include @@ -14,20 +15,23 @@ using sw_float_2 = decltype(std::declval>().swizzle<1, 2>()); using sw_double_1 = decltype(std::declval>().swizzle<1>()); using sw_double_2 = decltype(std::declval>().swizzle<1, 2>()); -// clang-format off +#if __INTEL_PREVIEW_BREAKING_CHANGES +#define EXCEPT_IN_PREVIEW ! +#else +#define EXCEPT_IN_PREVIEW +#endif -// NOTE: Empty space is for the future markup using NOT_IN_PREVIEW/PREVIEW_ONLY -// macros. +// clang-format off // IN_PREVIEW_ONLY condition<> // EXCEPT_IN_PREVIEW condition<> static_assert( std::is_assignable_v, half>); -static_assert( std::is_assignable_v, float>); -static_assert( std::is_assignable_v, double>); +static_assert(EXCEPT_IN_PREVIEW std::is_assignable_v, float>); +static_assert(EXCEPT_IN_PREVIEW std::is_assignable_v, double>); static_assert( std::is_assignable_v, vec>); -static_assert( std::is_assignable_v, vec>); -static_assert( std::is_assignable_v, vec>); +static_assert(EXCEPT_IN_PREVIEW std::is_assignable_v, vec>); +static_assert(EXCEPT_IN_PREVIEW std::is_assignable_v, vec>); static_assert( std::is_assignable_v, sw_half_1>); static_assert( std::is_assignable_v, sw_float_1>); static_assert( std::is_assignable_v, sw_double_1>); @@ -51,7 +55,11 @@ static_assert( !std::is_assignable_v, sw_double_2>) static_assert( std::is_assignable_v, half>); static_assert( std::is_assignable_v, float>); static_assert( std::is_assignable_v, double>); +#if __SYCL_DEVICE_ONLY__ static_assert( std::is_assignable_v, vec>); +#else +static_assert(EXCEPT_IN_PREVIEW std::is_assignable_v, vec>); +#endif static_assert( std::is_assignable_v, vec>); static_assert( std::is_assignable_v, vec>); static_assert( std::is_assignable_v, sw_half_1>); diff --git a/sycl/test/basic_tests/vectors/cxx_conversions.cpp b/sycl/test/basic_tests/vectors/cxx_conversions.cpp index fb337c0e09e56..4466533945668 100644 --- a/sycl/test/basic_tests/vectors/cxx_conversions.cpp +++ b/sycl/test/basic_tests/vectors/cxx_conversions.cpp @@ -1,4 +1,5 @@ -// RUN: %clangxx -fsycl -fsyntax-only %s -fpreview-breaking-changes +// TODO: Remove `__SYCL_USE_LIBSYCL8_VEC_IMPL` once it's auto-set. +// RUN: %clangxx -fsycl -fsyntax-only %s -fpreview-breaking-changes -D__SYCL_USE_LIBSYCL8_VEC_IMPL=0 // RUN: %clangxx -fsycl -fsyntax-only %s #include @@ -36,34 +37,36 @@ using sw_float_2 = decltype(std::declval>().swizzle<1, 2>()); using sw_double_1 = decltype(std::declval>().swizzle<1>()); using sw_double_2 = decltype(std::declval>().swizzle<1, 2>()); -// clang-format off - -// NOTE: Empty space is for the future markup using NOT_IN_PREVIEW/PREVIEW_ONLY -// macros. +#if __INTEL_PREVIEW_BREAKING_CHANGES +#define EXCEPT_IN_PREVIEW ! +#else +#define EXCEPT_IN_PREVIEW +#endif +// clang-format off // IN_PREVIEW_ONLY condition<> // EXCEPT_IN_PREVIEW condition<> static_assert( std::is_invocable_v); -static_assert( std::is_invocable_v); -static_assert( std::is_invocable_v); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v>); -static_assert( std::is_invocable_v>); -static_assert( std::is_invocable_v>); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v>); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v>); -static_assert( std::is_invocable_v); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); static_assert( std::is_invocable_v); -static_assert( std::is_invocable_v>); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v>); static_assert( std::is_invocable_v>); -static_assert( std::is_invocable_v>); +static_assert(EXCEPT_IN_PREVIEW std::is_invocable_v>); static_assert( !std::is_invocable_v); static_assert( !std::is_invocable_v);