diff --git a/libcxx/docs/Status/ParallelismProjects.csv b/libcxx/docs/Status/ParallelismProjects.csv --- a/libcxx/docs/Status/ParallelismProjects.csv +++ b/libcxx/docs/Status/ParallelismProjects.csv @@ -8,14 +8,16 @@ | `[parallel.simd.traits] `_, "`simd type traits is_simd[_v] `_", [parallel.simd.class] declaration and alias, Yin Zhang, |Complete| | `[parallel.simd.traits] `_, "`simd type traits is_simd_mask[_v] `_", [parallel.simd.mask.class] declaration and alias, Yin Zhang, |Complete| | `[parallel.simd.traits] `_, "simd type traits is_simd_flag_type", None, Yin Zhang, |In Progress| -| `[parallel.simd.traits] `_, "simd type traits simd_size", None, Yin Zhang, |In Progress| +| `[parallel.simd.traits] `_, "`simd type traits simd_size[_v] `_", [parallel.simd.traits] is_abi_tag[_v], Yin Zhang, |Complete| | `[parallel.simd.traits] `_, "simd type traits memory_alignment", None, Yin Zhang, |In Progress| | `[parallel.simd.traits] `_, "simd type traits rebind_simd", None, Yin Zhang, |In Progress| | `[parallel.simd.traits] `_, "simd type traits resize_simd", None, Yin Zhang, |In Progress| | `[parallel.simd.whereexpr] `_, "Where expression class templates", None, Yin Zhang, |In Progress| | `[parallel.simd.class] `_, "`Class template simd declaration and alias `_", [parallel.simd.abi], Yin Zhang, |Complete| +| `[parallel.simd.class] `_, "`Class template simd width function `_", [parallel.simd.traits] simd_size[_v], Yin Zhang, |Complete| | `[parallel.simd.class] `_, "Class template simd implementation", None, Yin Zhang, |In Progress| | `[parallel.simd.nonmembers] `_, "simd non-member operations", None, Yin Zhang, |In Progress| | `[parallel.simd.mask.class] `_, "`Class template simd_mask declaration and alias `_", [parallel.simd.abi], Yin Zhang, |Complete| +| `[parallel.simd.mask.class] `_, "`Class template simd_mask width function `_", [parallel.simd.class] width function, Yin Zhang, |Complete| | `[parallel.simd.mask.class] `_, "Class template simd_mask implementation", None, Yin Zhang, |In Progress| | `[parallel.simd.mask.nonmembers] `_, "simd_mask non-member operations", None, Yin Zhang, |In Progress| diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -886,10 +886,12 @@ experimental/__config experimental/__memory experimental/__simd/abi_tag.h + experimental/__simd/declaration.h experimental/__simd/scalar.h experimental/__simd/simd.h experimental/__simd/simd_mask.h experimental/__simd/traits.h + experimental/__simd/utility.h experimental/__simd/vec_ext.h experimental/deque experimental/forward_list diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/declaration.h copy from libcxx/include/experimental/__simd/simd.h copy to libcxx/include/experimental/__simd/declaration.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/declaration.h @@ -7,29 +7,22 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H -#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H - -#include +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H +#define _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { -// class template simd [simd.class] -// TODO: implement simd class template > class simd; -template -using native_simd = simd<_Tp, simd_abi::native<_Tp>>; - -template -using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; +template > +class simd_mask; } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) -#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#endif // _LIBCPP_EXPERIMENTAL___SIMD_DECLARATION_H diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/simd.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/simd.h @@ -11,6 +11,8 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H #include +#include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -19,8 +21,15 @@ // class template simd [simd.class] // TODO: implement simd class -template > -class simd; +template +class simd { +public: + using value_type = _Tp; + using mask_type = simd_mask<_Tp, _Abi>; + using abi_type = _Abi; + + static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_size_v; } +}; template using native_simd = simd<_Tp, simd_abi::native<_Tp>>; diff --git a/libcxx/include/experimental/__simd/simd_mask.h b/libcxx/include/experimental/__simd/simd_mask.h --- a/libcxx/include/experimental/__simd/simd_mask.h +++ b/libcxx/include/experimental/__simd/simd_mask.h @@ -11,6 +11,7 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_MASK_H #include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -19,8 +20,15 @@ // class template simd_mask [simd.mask.class] // TODO: implement simd_mask class -template > -class simd_mask; +template +class simd_mask { +public: + using value_type = bool; + using simd_type = simd<_Tp, _Abi>; + using abi_type = _Abi; + + static _LIBCPP_HIDE_FROM_ABI constexpr size_t size() noexcept { return simd_type::size(); } +}; template using native_simd_mask = simd_mask<_Tp, simd_abi::native<_Tp>>; diff --git a/libcxx/include/experimental/__simd/traits.h b/libcxx/include/experimental/__simd/traits.h --- a/libcxx/include/experimental/__simd/traits.h +++ b/libcxx/include/experimental/__simd/traits.h @@ -11,8 +11,8 @@ #define _LIBCPP_EXPERIMENTAL___SIMD_TRAITS_H #include -#include -#include +#include +#include #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) @@ -50,6 +50,14 @@ template struct is_simd_mask : bool_constant> {}; +template , + class = enable_if_t<__is_vectorizable<_Tp>() && is_abi_tag_v<_Abi>>> +inline constexpr size_t simd_size_v = _Abi::__simd_size; + +template > +struct simd_size : integral_constant> {}; + } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL diff --git a/libcxx/include/experimental/__simd/simd.h b/libcxx/include/experimental/__simd/utility.h copy from libcxx/include/experimental/__simd/simd.h copy to libcxx/include/experimental/__simd/utility.h --- a/libcxx/include/experimental/__simd/simd.h +++ b/libcxx/include/experimental/__simd/utility.h @@ -7,29 +7,24 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H -#define _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#ifndef _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H +#define _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H -#include +#include <__type_traits/is_arithmetic.h> +#include <__type_traits/is_const.h> +#include <__type_traits/is_same.h> +#include <__type_traits/is_volatile.h> #if _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) _LIBCPP_BEGIN_NAMESPACE_EXPERIMENTAL inline namespace parallelism_v2 { - -// class template simd [simd.class] -// TODO: implement simd class -template > -class simd; - template -using native_simd = simd<_Tp, simd_abi::native<_Tp>>; - -template -using fixed_size_simd = simd<_Tp, simd_abi::fixed_size<_Np>>; - +_LIBCPP_HIDE_FROM_ABI constexpr bool __is_vectorizable() { + return is_arithmetic_v<_Tp> && !is_const_v<_Tp> && !is_volatile_v<_Tp> && !is_same_v<_Tp, bool>; +} } // namespace parallelism_v2 _LIBCPP_END_NAMESPACE_EXPERIMENTAL #endif // _LIBCPP_STD_VER >= 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL) -#endif // _LIBCPP_EXPERIMENTAL___SIMD_SIMD_H +#endif // _LIBCPP_EXPERIMENTAL___SIMD_UTILITY_H diff --git a/libcxx/include/experimental/simd b/libcxx/include/experimental/simd --- a/libcxx/include/experimental/simd +++ b/libcxx/include/experimental/simd @@ -47,6 +47,10 @@ template struct is_simd_mask; template inline constexpr bool is_simd_mask_v = is_simd_mask::value; + template> struct simd_size; + template> + inline constexpr size_t simd_size_v = simd_size::value; + } // namespace parallelism_v2 } // namespace std::experimental diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/unordered_map algorithm diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/unordered_map algorithm diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -262,6 +262,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -269,6 +269,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -175,6 +175,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -175,6 +175,7 @@ experimental/set experimental/memory_resource experimental/set set experimental/simd cstddef +experimental/simd type_traits experimental/string experimental/memory_resource experimental/string string experimental/type_traits initializer_list diff --git a/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp b/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.class/simd_width.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.class] +// static constexpr std::size_t size() noexcept; + +#include "../test_utils.h" + +namespace ex = std::experimental::parallelism_v2; + +template +struct CheckSimdWidth { + template + void operator()() { + static_assert(ex::simd::size() == ex::simd_size_v); + } +}; + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.mask.class/simd_mask_width.pass.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.mask.class] +// static constexpr std::size_t size() noexcept; + +#include "../test_utils.h" + +namespace ex = std::experimental::parallelism_v2; + +template +struct CheckSimdMaskWidth { + template + void operator()() { + static_assert(ex::simd_mask::size() == ex::simd_size_v); + } +}; + +int main(int, char**) { + test_all_simd_abi(); + return 0; +} diff --git a/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp b/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/std/experimental/simd/simd.traits/simd_size.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14 + +// +// +// [simd.traits] +//template > struct simd_size; +//template > +//inline constexpr std::size_t ex::simd_size_v = ex::simd_size::value; + +#include "../test_utils.h" + +namespace ex = std::experimental::parallelism_v2; + +struct CheckSimdSizeFixedDeduce { + template + void check() { + static_assert(ex::simd_size_v> == N, "Simd size mismatch with abi fixed_size"); + static_assert(ex::simd_size>::value == N, "Simd size mismatch with abi fixed_size"); + + static_assert(ex::simd_size_v> == N, "Simd size mismatch with abi deduce"); + static_assert(ex::simd_size>::value == N, "Simd size mismatch with abi deduce"); + } + + template + void performChecks(std::index_sequence) { + (check(), ...); + } + + template + void operator()() { + performChecks(std::make_index_sequence{}); + } +}; + +struct CheckSimdSizeScalarNativeCompatible { + template + void operator()() { + static_assert(ex::simd_size_v == 1); + static_assert(ex::simd_size::value == 1); + + LIBCPP_STATIC_ASSERT(ex::simd_size>::value == 16 / sizeof(T)); + LIBCPP_STATIC_ASSERT(ex::simd_size_v> == 16 / sizeof(T)); + + LIBCPP_STATIC_ASSERT( + ex::simd_size>::value == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(T)); + LIBCPP_STATIC_ASSERT(ex::simd_size_v> == _LIBCPP_NATIVE_SIMD_WIDTH_IN_BYTES / sizeof(T)); + } +}; + +int main(int, char**) { + types::for_each(arithmetic_no_bool_types(), CheckSimdSizeFixedDeduce()); + types::for_each(arithmetic_no_bool_types(), CheckSimdSizeScalarNativeCompatible()); + return 0; +}