batmat 0.0.16
Batched linear algebra routines
Loading...
Searching...
No Matches
simd.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <batmat/config.hpp>
4#include <batmat/unroll.h>
5
6#if BATMAT_WITH_GSI_HPC_SIMD
7
8#include <cstddef>
9#include <simd>
10
11namespace batmat::datapar {
12
13template <class Tp, class Abi>
14using simd = std::datapar::basic_simd<Tp, Abi>;
15template <class Tp, std::size_t Np>
16using deduced_simd = std::datapar::simd<Tp, Np>;
17template <class Tp, std::size_t Np>
19template <class Tp>
21
22template <class V>
23V unaligned_load(const typename V::value_type *p) {
24 std::span<typename V::value_type, V::size()> sp{const_cast<V::value_type *>(p), V::size()};
25 return std::datapar::unchecked_load<V>(sp);
26}
27
28template <class V>
29V aligned_load(const typename V::value_type *p) {
30 std::span<typename V::value_type, V::size()> sp{const_cast<V::value_type *>(p), V::size()};
31 return std::datapar::unchecked_load<V>(sp, std::datapar::flag_aligned);
32}
33
34template <class V>
35void unaligned_store(V v, typename V::value_type *p) {
36 std::datapar::unchecked_store(v, p, V::size());
37}
38
39template <class V>
40void aligned_store(V v, typename V::value_type *p) {
41 std::span<typename V::value_type, V::size()> sp{p, V::size()};
42 std::datapar::unchecked_store(v, sp, std::datapar::flag_aligned);
43}
44
45template <class V>
46void masked_aligned_store(V v, typename V::mask_type m, typename V::value_type *p) {
47 std::span<typename V::value_type, V::size()> sp{p, V::size()};
48 if constexpr (V::size() == 1) {
49 if (m[0])
50 std::datapar::unchecked_store(v, sp, std::datapar::flag_aligned);
51 } else {
52 std::datapar::unchecked_store(v, sp, m, std::datapar::flag_aligned);
53 }
54}
55
56#if defined(__x86_64__) || defined(_M_X64)
57template <class V>
58auto to_intrin(V v) {
59 return std::__detail::__to_x86_intrin(v);
60}
61#define BATMAT_HAVE_SIMD_TO_INTRIN 1
62#endif
63
64template <class Tp, class Abi>
65using simd_size = std::remove_cvref_t<decltype(simd<Tp, Abi>::size)>;
66template <class Tp, class Abi>
67using simd_align = std::datapar::alignment<simd<Tp, Abi>>;
68template <class T, class V>
69using rebind_simd_t = deduced_simd<T, V::size()>;
70
71template <class V>
72auto hmax(V v) { // TODO
73 using value_type = V::value_type;
74 value_type m = v[0];
75 BATMAT_FULLY_UNROLLED_FOR (int i = 1; i < v.size(); ++i)
76 m = std::max(v[i], m);
77 return m;
78}
79template <class V>
80auto hmin(V v) { // TODO
81 using value_type = V::value_type;
82 value_type m = v[0];
83 BATMAT_FULLY_UNROLLED_FOR (int i = 1; i < v.size(); ++i)
84 m = std::min(v[i], m);
85 return m;
86}
87
88} // namespace batmat::datapar
89
90#else
91
92#include <experimental/simd>
93#include <cstddef>
94
95namespace batmat::datapar {
96namespace stdx = std::experimental;
97
98template <class Tp, class Abi>
99using simd = stdx::simd<Tp, Abi>;
100template <class Tp, std::size_t Np>
101using deduced_abi = stdx::simd_abi::deduce_t<Tp, Np>;
102template <class Tp, std::size_t Np>
104
105template <class V>
106V unaligned_load(const typename V::value_type *p) {
107 return V{p, stdx::element_aligned};
108}
109
110template <class V>
111V aligned_load(const typename V::value_type *p) {
112 return V{p, stdx::vector_aligned};
113}
114
115template <class V>
116void unaligned_store(V v, typename V::value_type *p) {
117 v.copy_to(p, stdx::element_aligned);
118}
119
120template <class V>
121void aligned_store(V v, typename V::value_type *p) {
122 v.copy_to(p, stdx::vector_aligned);
123}
124
125template <class V>
126void masked_aligned_store(V v, typename V::mask_type m, typename V::value_type *p) {
127 where(m, v).copy_to(p, stdx::vector_aligned);
128}
129
130template <class V>
131auto to_intrin(V v) {
132 return static_cast<stdx::__intrinsic_type_t<V, v.size()>>(v);
133}
134#define BATMAT_HAVE_SIMD_TO_INTRIN 1
135
136template <class Tp, class Abi>
137using simd_size = stdx::simd_size<Tp, Abi>;
138template <class Tp, class Abi>
139using simd_align = stdx::memory_alignment<simd<Tp, Abi>>;
140template <class T, class V>
141using rebind_simd_t = stdx::rebind_simd_t<T, V>;
142template <class Tp>
144
145using stdx::hmax;
146using stdx::hmin;
147
148} // namespace batmat::datapar
149
150#endif
151
152namespace batmat::datapar {
153
154template <class V>
155constexpr V from_values(auto... values) {
157 const typename V::value_type data[]{values...};
158 return aligned_load<V>(data);
159}
160
161} // namespace batmat::datapar
V unaligned_load(const typename V::value_type *p)
Definition simd.hpp:106
void aligned_store(V v, typename V::value_type *p)
Definition simd.hpp:121
stdx::memory_alignment< simd< Tp, Abi > > simd_align
Definition simd.hpp:139
stdx::simd_size< Tp, Abi > simd_size
Definition simd.hpp:137
auto to_intrin(V v)
Definition simd.hpp:131
deduced_abi< Tp, 1 > scalar_abi
Definition simd.hpp:143
stdx::rebind_simd_t< T, V > rebind_simd_t
Definition simd.hpp:141
V aligned_load(const typename V::value_type *p)
Definition simd.hpp:111
stdx::simd_abi::deduce_t< Tp, Np > deduced_abi
Definition simd.hpp:101
void unaligned_store(V v, typename V::value_type *p)
Definition simd.hpp:116
simd< Tp, deduced_abi< Tp, Np > > deduced_simd
Definition simd.hpp:103
void masked_aligned_store(V v, typename V::mask_type m, typename V::value_type *p)
Definition simd.hpp:126
constexpr V from_values(auto... values)
Definition simd.hpp:155
stdx::simd< Tp, Abi > simd
Definition simd.hpp:99
#define BATMAT_FULLY_UNROLLED_FOR(...)
Definition unroll.h:27