1#ifndef DUNE_COMMON_SIMD_HH
2#define DUNE_COMMON_SIMD_HH
25#include <dune/common/conditional.hh>
27#include <dune/common/vc.hh>
47 static_assert(std::is_same<V, std::decay_t<V> >::value,
"Class Proxy "
48 "may only be instantiated with unqualified types");
50 using value_type =
typename V::value_type;
53 static_assert(std::is_arithmetic<value_type>::value,
54 "Only artihmetic types are supported");
59 Proxy(std::size_t idx, V &vec)
60 : vec_(vec), idx_(idx)
63 operator value_type()
const {
return vec_[idx_]; }
67 template<
class T = value_type,
68 class = std::enable_if_t<!std::is_same<T, bool>::value> >
69 value_type operator++(
int) {
return vec_[idx_]++; }
70 template<
class T = value_type,
71 class = std::enable_if_t<!std::is_same<T, bool>::value> >
72 value_type operator--(
int) {
return vec_[idx_]--; }
75 template<
class T = value_type,
76 class = std::enable_if_t<!std::is_same<T, bool>::value> >
77 Proxy &operator++() { ++(vec_[idx_]);
return *
this; }
78 template<
class T = value_type,
79 class = std::enable_if_t<!std::is_same<T, bool>::value> >
80 Proxy &operator--() { --(vec_[idx_]);
return *
this; }
81 decltype(
auto)
operator!()
const {
return !(vec_[idx_]); }
82 decltype(
auto)
operator+()
const {
return +(vec_[idx_]); }
83 decltype(
auto)
operator-()
const {
return -(vec_[idx_]); }
84 template<
class T = value_type,
85 class = std::enable_if_t<std::is_integral<T>::value> >
86 decltype(
auto)
operator~()
const {
return ~(vec_[idx_]); }
89#define DUNE_SIMD_VC_BINARY_OP(OP) \
91 auto operator OP(T &&o) const \
92 -> decltype(vec_[idx_] OP valueCast(std::forward<T>(o))) \
94 return vec_[idx_] OP valueCast(std::forward<T>(o)); \
97 DUNE_SIMD_VC_BINARY_OP(*);
98 DUNE_SIMD_VC_BINARY_OP(/);
99 DUNE_SIMD_VC_BINARY_OP(%);
101 DUNE_SIMD_VC_BINARY_OP(+);
102 DUNE_SIMD_VC_BINARY_OP(-);
104 DUNE_SIMD_VC_BINARY_OP(<<);
105 DUNE_SIMD_VC_BINARY_OP(>>);
107 DUNE_SIMD_VC_BINARY_OP(<);
108 DUNE_SIMD_VC_BINARY_OP(>);
109 DUNE_SIMD_VC_BINARY_OP(<=);
110 DUNE_SIMD_VC_BINARY_OP(>=);
112 DUNE_SIMD_VC_BINARY_OP(==);
113 DUNE_SIMD_VC_BINARY_OP(!=);
115 DUNE_SIMD_VC_BINARY_OP(&);
116 DUNE_SIMD_VC_BINARY_OP(^);
117 DUNE_SIMD_VC_BINARY_OP(|);
119 DUNE_SIMD_VC_BINARY_OP(&&);
120 DUNE_SIMD_VC_BINARY_OP(||);
121#undef DUNE_SIMD_VC_BINARY_OP
123#define DUNE_SIMD_VC_ASSIGNMENT(OP) \
125 auto operator OP(T &&o) \
126 -> std::enable_if_t<AlwaysTrue<decltype( \
127 vec_[idx_] OP valueCast(std::forward<T>(o)) \
130 vec_[idx_] OP valueCast(std::forward<T>(o)); \
134 DUNE_SIMD_VC_ASSIGNMENT(=);
135 DUNE_SIMD_VC_ASSIGNMENT(*=);
136 DUNE_SIMD_VC_ASSIGNMENT(/=);
137 DUNE_SIMD_VC_ASSIGNMENT(%=);
138 DUNE_SIMD_VC_ASSIGNMENT(+=);
139 DUNE_SIMD_VC_ASSIGNMENT(-=);
140 DUNE_SIMD_VC_ASSIGNMENT(<<=);
141 DUNE_SIMD_VC_ASSIGNMENT(>>=);
142 DUNE_SIMD_VC_ASSIGNMENT(&=);
143 DUNE_SIMD_VC_ASSIGNMENT(^=);
144 DUNE_SIMD_VC_ASSIGNMENT(|=);
145#undef DUNE_SIMD_VC_ASSIGNMENT
149 template<
class V1,
class V2>
150 friend void swap(Proxy<V1>, Proxy<V2>);
153 friend void swap(Proxy p1, T& s2)
157 T tmp = p1.vec_[p1.idx_];
158 p1.vec_[p1.idx_] = s2;
163 friend void swap(T& s1, Proxy p2)
166 s1 = p2.vec_[p2.idx_];
167 p2.vec_[p2.idx_] = tmp;
171 template<
class V1,
class V2>
172 void swap(Proxy<V1> p1, Proxy<V2> p2)
174 typename V1::value_type tmp = p1.vec_[p1.idx_];
175 p1.vec_[p1.idx_] = p2.vec_[p2.idx_];
176 p2.vec_[p2.idx_] = tmp;
182 struct SimdScalarTypeTraits
188 using SimdScalar =
typename SimdScalarTypeTraits<T>::type;
194 template<
typename T,
typename A>
195 struct SimdScalarTypeTraits< Vc::Vector<T,A> >
200 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
201 struct SimdScalarTypeTraits< Vc::SimdArray<T,N,V,M> >
207 template<
typename V,
typename =
void>
208 struct SimdIndexTypeTraits {
209 using type = std::size_t;
220 using SimdIndex =
typename SimdIndexTypeTraits<V>::type;
223 template<
typename T,
typename A>
224 struct SimdIndexTypeTraits<Vc::Vector<T, A> > {
225 using type =
typename Vc::Vector<T, A>::index_type;
228 template<
typename T, std::
size_t n,
typename V>
229 struct SimdIndexTypeTraits<Vc::SimdArray<T, n, V> > {
230 using type =
typename Vc::SimdArray<T, n, V>::index_type;
234 template<
typename V,
typename =
void>
235 struct SimdMaskTypeTraits {
244 using SimdMask =
typename SimdMaskTypeTraits<V>::type;
247 template<
typename T,
typename A>
248 struct SimdMaskTypeTraits<Vc::Vector<T, A> > {
249 using type =
typename Vc::Vector<T, A>::mask_type;
252 template<
typename T, std::
size_t n,
typename V>
253 struct SimdMaskTypeTraits<Vc::SimdArray<T, n, V> > {
254 using type =
typename Vc::SimdArray<T, n, V>::mask_type;
262 template<
typename T,
typename A>
263 Vc::Vector<T,A>
cond(
const Vc::Mask<T,A> & b,
264 const Vc::Vector<T,A> & v1,
265 const Vc::Vector<T,A> & v2)
267 return std::move(Vc::iif(b, v1, v2));
270 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
271 Vc::SimdArray<T,N,V,M>
cond(
const typename Vc::SimdArray<T,N,V,M>::mask_type & b,
272 const Vc::SimdArray<T,N,V,M> & v1,
273 const Vc::SimdArray<T,N,V,M> & v2)
275 return std::move(Vc::iif(b, v1, v2));
285 template<
typename T,
typename A>
286 T max_value(
const Vc::Vector<T,A> & v)
291 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
292 double max_value(
const Vc::SimdArray<T,N,V,M> & v)
297 template<
typename T,
typename A>
298 T min_value(
const Vc::Vector<T,A> & v)
303 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
304 double min_value(
const Vc::SimdArray<T,N,V,M> & v)
309 template<
typename T,
typename A>
310 bool any_true(
const Vc::Mask<T,A> & v)
312 return Vc::any_of(v);
315 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
316 bool any_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
318 return Vc::any_of(v);
321 template<
typename T,
typename A>
322 bool all_true(
const Vc::Mask<T,A> & v)
324 return Vc::all_of(v);
327 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
328 bool all_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
330 return Vc::all_of(v);
336 std::size_t
lanes(
const T &) {
return 1; }
340 T
lane(std::size_t l,
const T &v)
355 template<
class T,
class A>
356 std::size_t
lanes(
const Vc::Vector<T, A> &)
358 return Vc::Vector<T, A>::size();
361 template<
class T,
class A>
362 T
lane(std::size_t l,
const Vc::Vector<T, A> &v)
364 assert(l <
lanes(v));
368 template<
class T,
class A>
369 auto lane(std::size_t l, Vc::Vector<T, A> &v)
371 assert(l <
lanes(v));
372 return VcImpl::Proxy<Vc::Vector<T, A> >{l, v};
375 template<
class T, std::
size_t n,
class V>
376 std::size_t
lanes(
const Vc::SimdArray<T, n, V> &)
381 template<
class T, std::
size_t n,
class V>
382 T
lane(std::size_t l,
const Vc::SimdArray<T, n, V> &v)
388 template<
class T, std::
size_t n,
class V>
389 auto lane(std::size_t l, Vc::SimdArray<T, n, V> &v)
392 return VcImpl::Proxy<Vc::SimdArray<T, n, V> >{l, v};
395 template<
class T, std::
size_t n,
class V>
396 std::size_t
lanes(
const Vc::SimdMaskArray<T, n, V> &)
401 template<
class T, std::
size_t n,
class V>
402 const bool lane(std::size_t l,
const Vc::SimdMaskArray<T, n, V> &v)
408 template<
class T, std::
size_t n,
class V>
409 auto lane(std::size_t l, Vc::SimdMaskArray<T, n, V> &v)
412 return VcImpl::Proxy<Vc::SimdMaskArray<T, n, V> >{l, v};
421 void assign(T &dst,
const T &src,
bool mask)
430 template<
class T,
class A>
431 void assign(Vc::Vector<T, A> &dst,
const Vc::Vector<T, A> &src,
432 typename Vc::Vector<T, A>::mask_type mask)
437 template<
class T, std::
size_t n,
class V>
438 void assign(Vc::SimdArray<T, n, V> &dst,
const Vc::SimdArray<T, n, V> &src,
439 typename Vc::SimdArray<T, n, V>::mask_type mask)
446 void swap(T &v1, T &v2,
bool mask)
449 if(mask) swap(v1, v2);
456 template<
class T,
class A>
457 void swap(Vc::Vector<T, A> &v1, Vc::Vector<T, A> &v2,
458 typename Vc::Vector<T, A>::mask_type mask)
465 template<
class T, std::
size_t n,
class V>
466 void swap(Vc::SimdArray<T, n, V> &v1, Vc::SimdArray<T, n, V> &v2,
467 typename Vc::SimdArray<T, n, V>::mask_type mask)
Dune namespace.
Definition: alignedallocator.hh:10
typename SimdIndexTypeTraits< V >::type SimdIndex
An simd vector of indices corresponding to a simd vector V.
Definition: simd.hh:220
typename SimdMaskTypeTraits< V >::type SimdMask
A simd vector of truth values corresponding to a simd vector V.
Definition: simd.hh:244
T lane(std::size_t l, const T &v)
access a lane of a simd vector (scalar version)
Definition: simd.hh:340
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:421
const T1 cond(bool b, const T1 &v1, const T2 &v2)
conditional evaluate
Definition: conditional.hh:26
std::size_t lanes(const T &)
get the number of lanes of a simd vector (scalar version)
Definition: simd.hh:336
Utilities for reduction like operations on ranges.