1 //===----------------------------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LIBCXX_TEST_STD_EXPERIMENTAL_SIMD_TEST_UTILS_H
10 #define LIBCXX_TEST_STD_EXPERIMENTAL_SIMD_TEST_UTILS_H
15 #include <experimental/simd>
16 #include <type_traits>
19 #include "type_algorithms.h"
21 namespace ex
= std::experimental::parallelism_v2
;
23 constexpr std::size_t max_simd_size
= 32;
25 template <template <class T
, std::size_t N
> class F
>
26 struct TestAllSimdAbiFunctor
{
27 template <class T
, std::size_t N
>
28 using sized_abis
= types::type_list
<ex::simd_abi::fixed_size
<N
>, ex::simd_abi::deduce_t
<T
, N
>>;
30 template <class T
, std::size_t... Ns
>
31 void instantiate_with_n(std::index_sequence
<Ns
...>) {
32 (types::for_each(sized_abis
<T
, Ns
>{}, F
<T
, Ns
>{}), ...);
37 using abis
= types::type_list
<ex::simd_abi::scalar
, ex::simd_abi::native
<T
>, ex::simd_abi::compatible
<T
>>;
38 types::for_each(abis
{}, F
<T
, 1>());
40 instantiate_with_n
<T
>(
41 std::index_sequence
<1, 2, 3, 4, 8, 16, max_simd_size
- 2, max_simd_size
- 1, max_simd_size
>{});
45 // TODO: Support long double (12 bytes) for 32-bits x86
47 using arithmetic_no_bool_types
= types::concatenate_t
<types::integer_types
, types::type_list
<float, double>>;
49 using arithmetic_no_bool_types
= types::concatenate_t
<types::integer_types
, types::floating_point_types
>;
52 // For interfaces with vectorizable type template parameters, we only use some common or boundary types
53 // as template parameters for testing to ensure that the compilation time of a single test does not exceed.
54 using simd_test_integer_types
=
55 types::type_list
<char,
58 #ifndef TEST_HAS_NO_INT128
63 using simd_test_types
= types::concatenate_t
<simd_test_integer_types
, types::type_list
<float, double>>;
65 template <template <class T
, std::size_t N
> class Func
>
66 void test_all_simd_abi() {
67 types::for_each(arithmetic_no_bool_types(), TestAllSimdAbiFunctor
<Func
>());
70 constexpr size_t bit_ceil(size_t val
) {
77 template <class From
, class To
, class = void>
78 inline constexpr bool is_non_narrowing_convertible_v
= false;
80 template <class From
, class To
>
81 inline constexpr bool is_non_narrowing_convertible_v
<From
, To
, std::void_t
<decltype(To
{std::declval
<From
>()})>> = true;
83 template <std::size_t ArraySize
, class SimdAbi
, class T
, class U
= T
>
84 void assert_simd_values_equal(const ex::simd
<T
, SimdAbi
>& origin_simd
, const std::array
<U
, ArraySize
>& expected_value
) {
85 for (std::size_t i
= 0; i
< origin_simd
.size(); ++i
)
86 assert(origin_simd
[i
] == static_cast<T
>(expected_value
[i
]));
89 template <std::size_t ArraySize
, class T
, class SimdAbi
>
90 void assert_simd_mask_values_equal(const ex::simd_mask
<T
, SimdAbi
>& origin_mask
,
91 const std::array
<bool, ArraySize
>& expected_value
) {
92 for (std::size_t i
= 0; i
< origin_mask
.size(); ++i
)
93 assert(origin_mask
[i
] == expected_value
[i
]);
96 template <class SimdAbi
, class T
, class U
= T
>
97 void assert_simd_values_equal(const ex::simd
<T
, SimdAbi
>& origin_simd
, U
* expected_value
) {
98 for (size_t i
= 0; i
< origin_simd
.size(); ++i
)
99 assert(origin_simd
[i
] == static_cast<T
>(expected_value
[i
]));
102 template <class SimdAbi
, class T
>
103 void assert_simd_mask_values_equal(const ex::simd_mask
<T
, SimdAbi
>& origin_mask
, bool* expected_value
) {
104 for (size_t i
= 0; i
< origin_mask
.size(); ++i
)
105 assert(origin_mask
[i
] == expected_value
[i
]);
108 #endif // LIBCXX_TEST_STD_EXPERIMENTAL_SIMD_TEST_UTILS_H