/src/WasmEdge/include/experimental/simd/functions.hpp
Line | Count | Source |
1 | | // SPDX-License-Identifier: CC0-1.0 |
2 | | /// |
3 | | // simd - A C++17 implementation of a subset of the C++26 std::simd library |
4 | | // |
5 | | // To the extent possible under law, the author(s) have dedicated all |
6 | | // copyright and related and neighboring rights to this software to the |
7 | | // public domain worldwide. This software is distributed without any warranty. |
8 | | // |
9 | | // You should have received a copy of the CC0 Public Domain Dedication |
10 | | // along with this software. If not, see |
11 | | // <http://creativecommons.org/publicdomain/zero/1.0/>. |
12 | | /// |
13 | | |
14 | | #pragma once |
15 | | |
16 | | #include "experimental/bit.hpp" |
17 | | #include "experimental/simd/detail.hpp" |
18 | | #include "experimental/simd/vec.hpp" |
19 | | #include "experimental/simd/vector_ext_intrinsics.hpp" |
20 | | |
21 | | #include <array> |
22 | | |
23 | | namespace cxx26 { |
24 | | namespace simd { |
25 | | |
26 | | template <class V, class U = typename V::value_type> struct alignment; |
27 | | template <class T, class Abi> |
28 | | struct alignment<basic_vec<T, Abi>, T> |
29 | | : std::integral_constant<std::size_t, alignof(basic_vec<T, Abi>)> {}; |
30 | | template <class V, class U = typename V::value_type> |
31 | | inline constexpr std::size_t alignment_v = alignment<V, U>::value; |
32 | | |
33 | | template <class T, class Abi> |
34 | | constexpr basic_vec<T, Abi> select(const basic_mask<sizeof(T), Abi> &M, |
35 | | const basic_vec<T, Abi> &A, |
36 | 0 | const basic_vec<T, Abi> &B) noexcept { |
37 | 0 | using backend = detail::simd_backend<T, Abi>; |
38 | 0 | return detail::access::make<basic_vec<T, Abi>>( |
39 | 0 | backend::select(detail::access::data(M), detail::access::data(A), |
40 | 0 | detail::access::data(B))); |
41 | 0 | } Unexecuted instantiation: cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> > cxx26::simd::select<unsigned char, cxx26::simd::detail::vector_ext_abi<16> >(cxx26::simd::basic_mask<sizeof (unsigned char), cxx26::simd::detail::vector_ext_abi<16> > const&, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> > const&, cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<8> > cxx26::simd::select<int, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_mask<sizeof (int), cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> > cxx26::simd::select<signed char, cxx26::simd::detail::vector_ext_abi<16> >(cxx26::simd::basic_mask<sizeof (signed char), cxx26::simd::detail::vector_ext_abi<16> > const&, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> > const&, cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> > cxx26::simd::select<short, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_mask<sizeof (short), cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> > cxx26::simd::select<int, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_mask<sizeof (int), cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> > cxx26::simd::select<unsigned short, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_mask<sizeof (unsigned short), cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> > const&, cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> > cxx26::simd::select<unsigned int, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_mask<sizeof (unsigned int), cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> > cxx26::simd::select<long, cxx26::simd::detail::vector_ext_abi<2> >(cxx26::simd::basic_mask<sizeof (long), cxx26::simd::detail::vector_ext_abi<2> > const&, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> > const&, cxx26::simd::basic_vec<long, cxx26::simd::detail::vector_ext_abi<2> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> > cxx26::simd::select<float, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_mask<sizeof (float), cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> > const&, cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> > cxx26::simd::select<double, cxx26::simd::detail::vector_ext_abi<2> >(cxx26::simd::basic_mask<sizeof (double), cxx26::simd::detail::vector_ext_abi<2> > const&, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> > const&, cxx26::simd::basic_vec<double, cxx26::simd::detail::vector_ext_abi<2> > const&) |
42 | | |
43 | | template <std::size_t Bytes, class Abi> |
44 | 0 | constexpr bool all_of(const basic_mask<Bytes, Abi> &M) noexcept { |
45 | 0 | constexpr simd_size_type N = basic_mask<Bytes, Abi>::size; |
46 | 0 | if constexpr (N <= 64) { |
47 | 0 | constexpr unsigned long long All = N == 64 ? ~0ULL : (1ULL << N) - 1ULL; |
48 | 0 | return M.to_ullong() == All; |
49 | | } else { |
50 | | bool R = true; |
51 | | for (simd_size_type I = 0; I < N; ++I) { |
52 | | R = R && M[I]; |
53 | | } |
54 | | return R; |
55 | | } |
56 | 0 | } Unexecuted instantiation: bool cxx26::simd::all_of<1ul, cxx26::simd::detail::vector_ext_abi<16> >(cxx26::simd::basic_mask<1ul, cxx26::simd::detail::vector_ext_abi<16> > const&) Unexecuted instantiation: bool cxx26::simd::all_of<2ul, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_mask<2ul, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: bool cxx26::simd::all_of<4ul, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_mask<4ul, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: bool cxx26::simd::all_of<8ul, cxx26::simd::detail::vector_ext_abi<2> >(cxx26::simd::basic_mask<8ul, cxx26::simd::detail::vector_ext_abi<2> > const&) |
57 | | |
58 | | template <std::size_t Bytes, class Abi> |
59 | | constexpr bool any_of(const basic_mask<Bytes, Abi> &M) noexcept { |
60 | | constexpr simd_size_type N = basic_mask<Bytes, Abi>::size; |
61 | | if constexpr (N <= 64) { |
62 | | return M.to_ullong() != 0; |
63 | | } else { |
64 | | bool R = false; |
65 | | for (simd_size_type I = 0; I < N; ++I) { |
66 | | R = R || M[I]; |
67 | | } |
68 | | return R; |
69 | | } |
70 | | } |
71 | | |
72 | | template <std::size_t Bytes, class Abi> |
73 | | constexpr bool none_of(const basic_mask<Bytes, Abi> &M) noexcept { |
74 | | return !any_of(M); |
75 | | } |
76 | | |
77 | | template <class V, class T, class Abi> |
78 | 0 | constexpr auto chunk(const basic_vec<T, Abi> &X) noexcept { |
79 | 0 | static_assert(std::is_same_v<typename V::value_type, T>); |
80 | 0 | constexpr simd_size_type N = basic_vec<T, Abi>::size; |
81 | 0 | constexpr simd_size_type M = V::size; |
82 | 0 | static_assert(N % M == 0); |
83 | 0 | static_assert(sizeof(V) == M * sizeof(T)); |
84 | 0 | return cxx20::bit_cast<std::array<V, static_cast<std::size_t>(N / M)>>(X); |
85 | 0 | } Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<2> >, float, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_vec<float, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<8> >, signed char, cxx26::simd::detail::vector_ext_abi<16> >(cxx26::simd::basic_vec<signed char, cxx26::simd::detail::vector_ext_abi<16> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<8> >, unsigned char, cxx26::simd::detail::vector_ext_abi<16> >(cxx26::simd::basic_vec<unsigned char, cxx26::simd::detail::vector_ext_abi<16> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<4> >, short, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_vec<short, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<4> >, unsigned short, cxx26::simd::detail::vector_ext_abi<8> >(cxx26::simd::basic_vec<unsigned short, cxx26::simd::detail::vector_ext_abi<8> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<2> >, int, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_vec<int, cxx26::simd::detail::vector_ext_abi<4> > const&) Unexecuted instantiation: auto cxx26::simd::chunk<cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<2> >, unsigned int, cxx26::simd::detail::vector_ext_abi<4> >(cxx26::simd::basic_vec<unsigned int, cxx26::simd::detail::vector_ext_abi<4> > const&) |
86 | | |
87 | | template < |
88 | | class T, class Abi, class... Rest, |
89 | | std::enable_if_t<(std::is_same_v<Rest, basic_vec<T, Abi>> && ...), int> = 0> |
90 | 0 | constexpr auto cat(const basic_vec<T, Abi> &X, const Rest &...Xs) noexcept { |
91 | 0 | constexpr simd_size_type N = basic_vec<T, Abi>::size; |
92 | 0 | constexpr std::size_t Count = 1 + sizeof...(Rest); |
93 | 0 | using R = vec<T, N *static_cast<simd_size_type>(Count)>; |
94 | 0 | static_assert(sizeof(R) == sizeof(basic_vec<T, Abi>) * Count); |
95 | 0 | return cxx20::bit_cast<R>(std::array<basic_vec<T, Abi>, Count>{X, Xs...}); |
96 | 0 | } Unexecuted instantiation: _ZN5cxx264simd3catIfNS0_6detail14vector_ext_abiILi2EEEJNS0_9basic_vecIfS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catIaNS0_6detail14vector_ext_abiILi8EEEJNS0_9basic_vecIaS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catIhNS0_6detail14vector_ext_abiILi8EEEJNS0_9basic_vecIhS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catIsNS0_6detail14vector_ext_abiILi4EEEJNS0_9basic_vecIsS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catItNS0_6detail14vector_ext_abiILi4EEEJNS0_9basic_vecItS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catIiNS0_6detail14vector_ext_abiILi2EEEJNS0_9basic_vecIiS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ Unexecuted instantiation: _ZN5cxx264simd3catIjNS0_6detail14vector_ext_abiILi2EEEJNS0_9basic_vecIjS4_EEETnNSt3__19enable_ifIXfraasr3stdE9is_same_vIT1_NS5_IT_T0_EEEEiE4typeELi0EEEDaRKSC_DpRKS9_ |
97 | | |
98 | | template <class T, class Abi, class F, |
99 | | std::enable_if_t<std::is_invocable_v< |
100 | | F &, std::integral_constant<simd_size_type, 0>>, |
101 | | int> = 0> |
102 | | constexpr basic_vec<T, Abi> permute(const basic_vec<T, Abi> &X, F &&IdxMap) { |
103 | | using backend = detail::simd_backend<T, Abi>; |
104 | | return detail::access::make<basic_vec<T, Abi>>(backend::generate( |
105 | | [&](auto I) { return X[static_cast<simd_size_type>(IdxMap(I))]; })); |
106 | | } |
107 | | |
108 | | template < |
109 | | class T, class Abi, class I, class IAbi, |
110 | | std::enable_if_t<std::is_integral_v<I> && basic_vec<I, IAbi>::size() == |
111 | | basic_vec<T, Abi>::size(), |
112 | | int> = 0> |
113 | | constexpr basic_vec<T, Abi> |
114 | | permute(const basic_vec<T, Abi> &X, |
115 | 0 | const basic_vec<I, IAbi> &Indices) noexcept { |
116 | 0 | using backend = detail::simd_backend<T, Abi>; |
117 | 0 | if constexpr (std::is_same_v<I, T> && std::is_same_v<IAbi, Abi>) { |
118 | 0 | return detail::access::make<basic_vec<T, Abi>>(backend::permute( |
119 | 0 | detail::access::data(X), detail::access::data(Indices))); |
120 | | } else { |
121 | | return detail::access::make<basic_vec<T, Abi>>( |
122 | | backend::generate([&](auto J) { |
123 | | return X[static_cast<simd_size_type>( |
124 | | static_cast<std::size_t>(Indices[J]) % |
125 | | static_cast<std::size_t>(X.size()))]; |
126 | | })); |
127 | | } |
128 | 0 | } |
129 | | |
130 | | #define CXX26_SIMD_MATH(NAME) \ |
131 | | template <class T, class Abi, \ |
132 | | std::enable_if_t<std::is_floating_point_v<T>, int> = 0> \ |
133 | 0 | basic_vec<T, Abi> NAME(const basic_vec<T, Abi> &X) noexcept { \ |
134 | 0 | using backend = detail::simd_backend<T, Abi>; \ |
135 | 0 | return detail::access::make<basic_vec<T, Abi>>( \ |
136 | 0 | backend::NAME(detail::access::data(X))); \ |
137 | 0 | } Unexecuted instantiation: _ZN5cxx264simd4sqrtIfNS0_6detail14vector_ext_abiILi4EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd4sqrtIdNS0_6detail14vector_ext_abiILi2EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd5truncIfNS0_6detail14vector_ext_abiILi4EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd5truncIdNS0_6detail14vector_ext_abiILi2EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd4ceilIfNS0_6detail14vector_ext_abiILi4EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd5floorIfNS0_6detail14vector_ext_abiILi4EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd4ceilIdNS0_6detail14vector_ext_abiILi2EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ Unexecuted instantiation: _ZN5cxx264simd5floorIdNS0_6detail14vector_ext_abiILi2EEETnNSt3__19enable_ifIXsr3stdE19is_floating_point_vIT_EEiE4typeELi0EEENS0_9basic_vecIS7_T0_EERKSC_ |
138 | | CXX26_SIMD_MATH(sqrt) |
139 | | CXX26_SIMD_MATH(ceil) |
140 | | CXX26_SIMD_MATH(floor) |
141 | | CXX26_SIMD_MATH(trunc) |
142 | | #undef CXX26_SIMD_MATH |
143 | | |
144 | | } // namespace simd |
145 | | } // namespace cxx26 |