1#ifndef DUNE_COMMON_SIMD_HH
2#define DUNE_COMMON_SIMD_HH
4#warning dune/common/simd.hh is deprecated.
5#warning Use the new infrastructure from dune/common/simd/simd.h instead.
33#include <dune/common/conditional.hh>
34#include <dune/common/debugalign.hh>
62 static_assert(std::is_same<V, std::decay_t<V> >::value,
"Class Proxy "
63 "may only be instantiated with unqualified types");
65 using value_type =
typename V::value_type;
68 static_assert(std::is_arithmetic<value_type>::value,
69 "Only artihmetic types are supported");
74 Proxy(std::size_t idx, V &vec)
75 : vec_(vec), idx_(idx)
78 operator value_type()
const {
return vec_[idx_]; }
82 template<
class T = value_type,
83 class = std::enable_if_t<!std::is_same<T, bool>::value> >
84 value_type operator++(
int) {
return vec_[idx_]++; }
85 template<
class T = value_type,
86 class = std::enable_if_t<!std::is_same<T, bool>::value> >
87 value_type operator--(
int) {
return vec_[idx_]--; }
90 template<
class T = value_type,
91 class = std::enable_if_t<!std::is_same<T, bool>::value> >
92 Proxy &operator++() { ++(vec_[idx_]);
return *
this; }
93 template<
class T = value_type,
94 class = std::enable_if_t<!std::is_same<T, bool>::value> >
95 Proxy &operator--() { --(vec_[idx_]);
return *
this; }
96 decltype(
auto)
operator!()
const {
return !(vec_[idx_]); }
97 decltype(
auto)
operator+()
const {
return +(vec_[idx_]); }
98 decltype(
auto)
operator-()
const {
return -(vec_[idx_]); }
99 template<
class T = value_type,
100 class = std::enable_if_t<std::is_integral<T>::value> >
101 decltype(
auto)
operator~()
const {
return ~(vec_[idx_]); }
104#define DUNE_SIMD_VC_BINARY_OP(OP) \
106 auto operator OP(T &&o) const \
107 -> decltype(vec_[idx_] OP valueCast(std::forward<T>(o))) \
109 return vec_[idx_] OP valueCast(std::forward<T>(o)); \
111 static_assert(true, "Require semicolon to unconfuse editors")
113 DUNE_SIMD_VC_BINARY_OP(*);
114 DUNE_SIMD_VC_BINARY_OP(/);
115 DUNE_SIMD_VC_BINARY_OP(%);
117 DUNE_SIMD_VC_BINARY_OP(+);
118 DUNE_SIMD_VC_BINARY_OP(-);
120 DUNE_SIMD_VC_BINARY_OP(<<);
121 DUNE_SIMD_VC_BINARY_OP(>>);
123 DUNE_SIMD_VC_BINARY_OP(<);
124 DUNE_SIMD_VC_BINARY_OP(>);
125 DUNE_SIMD_VC_BINARY_OP(<=);
126 DUNE_SIMD_VC_BINARY_OP(>=);
128 DUNE_SIMD_VC_BINARY_OP(==);
129 DUNE_SIMD_VC_BINARY_OP(!=);
131 DUNE_SIMD_VC_BINARY_OP(&);
132 DUNE_SIMD_VC_BINARY_OP(^);
133 DUNE_SIMD_VC_BINARY_OP(|);
135 DUNE_SIMD_VC_BINARY_OP(&&);
136 DUNE_SIMD_VC_BINARY_OP(||);
137#undef DUNE_SIMD_VC_BINARY_OP
139#define DUNE_SIMD_VC_ASSIGNMENT(OP) \
141 auto operator OP(T &&o) \
142 -> std::enable_if_t<AlwaysTrue<decltype( \
143 vec_[idx_] OP valueCast(std::forward<T>(o)) \
146 vec_[idx_] OP valueCast(std::forward<T>(o)); \
149 static_assert(true, "Require semicolon to unconfuse editors")
151 DUNE_SIMD_VC_ASSIGNMENT(=);
152 DUNE_SIMD_VC_ASSIGNMENT(*=);
153 DUNE_SIMD_VC_ASSIGNMENT(/=);
154 DUNE_SIMD_VC_ASSIGNMENT(%=);
155 DUNE_SIMD_VC_ASSIGNMENT(+=);
156 DUNE_SIMD_VC_ASSIGNMENT(-=);
157 DUNE_SIMD_VC_ASSIGNMENT(<<=);
158 DUNE_SIMD_VC_ASSIGNMENT(>>=);
159 DUNE_SIMD_VC_ASSIGNMENT(&=);
160 DUNE_SIMD_VC_ASSIGNMENT(^=);
161 DUNE_SIMD_VC_ASSIGNMENT(|=);
162#undef DUNE_SIMD_VC_ASSIGNMENT
166 template<
class V1,
class V2>
167 friend void swap(Proxy<V1>, Proxy<V2>);
170 friend void swap(Proxy p1, T& s2)
174 T tmp = p1.vec_[p1.idx_];
175 p1.vec_[p1.idx_] = s2;
180 friend void swap(T& s1, Proxy p2)
183 s1 = p2.vec_[p2.idx_];
184 p2.vec_[p2.idx_] = tmp;
188 template<
class V1,
class V2>
189 void swap(Proxy<V1> p1, Proxy<V2> p2)
191 typename V1::value_type tmp = p1.vec_[p1.idx_];
192 p1.vec_[p1.idx_] = p2.vec_[p2.idx_];
193 p2.vec_[p2.idx_] = tmp;
199 struct SimdScalarTypeTraits
205 using SimdScalar =
typename SimdScalarTypeTraits<T>::type;
211 template<
typename T,
typename A>
212 struct SimdScalarTypeTraits< Vc::Vector<T,A> >
217 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
218 struct SimdScalarTypeTraits< Vc::SimdArray<T,N,V,M> >
225 template<
typename T, std::
size_t align>
231 template<
typename V,
typename =
void>
232 struct SimdIndexTypeTraits {
233 using type = std::size_t;
244 using SimdIndex =
typename SimdIndexTypeTraits<V>::type;
247 template<
typename T,
typename A>
248 struct SimdIndexTypeTraits<Vc::Vector<T, A> > {
249 using type =
typename Vc::Vector<T, A>::index_type;
252 template<
typename T, std::
size_t n,
typename V>
253 struct SimdIndexTypeTraits<Vc::SimdArray<T, n, V> > {
254 using type =
typename Vc::SimdArray<T, n, V>::index_type;
258 template<
typename V,
typename =
void>
259 struct SimdMaskTypeTraits {
268 using SimdMask =
typename SimdMaskTypeTraits<V>::type;
271 template<
typename T,
typename A>
272 struct SimdMaskTypeTraits<Vc::Vector<T, A> > {
273 using type =
typename Vc::Vector<T, A>::mask_type;
276 template<
typename T, std::
size_t n,
typename V>
277 struct SimdMaskTypeTraits<Vc::SimdArray<T, n, V> > {
278 using type =
typename Vc::SimdArray<T, n, V>::mask_type;
286 template<
typename T,
typename A>
287 Vc::Vector<T,A>
cond(
const Vc::Mask<T,A> & b,
288 const Vc::Vector<T,A> & v1,
289 const Vc::Vector<T,A> & v2)
291 return std::move(Vc::iif(b, v1, v2));
294 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
295 Vc::SimdArray<T,N,V,M>
cond(
const typename Vc::SimdArray<T,N,V,M>::mask_type & b,
296 const Vc::SimdArray<T,N,V,M> & v1,
297 const Vc::SimdArray<T,N,V,M> & v2)
299 return std::move(Vc::iif(b, v1, v2));
309 template<
typename T,
typename A>
310 T max_value(
const Vc::Vector<T,A> & v)
315 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
316 double max_value(
const Vc::SimdArray<T,N,V,M> & v)
321 template<
typename T,
typename A>
322 T min_value(
const Vc::Vector<T,A> & v)
327 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
328 double min_value(
const Vc::SimdArray<T,N,V,M> & v)
333 template<
typename T,
typename A>
334 bool any_true(
const Vc::Mask<T,A> & v)
336 return Vc::any_of(v);
339 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
340 bool any_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
342 return Vc::any_of(v);
345 template<
typename T,
typename A>
346 bool all_true(
const Vc::Mask<T,A> & v)
348 return Vc::all_of(v);
351 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
352 bool all_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
354 return Vc::all_of(v);
360 std::size_t
lanes(
const T &) {
return 1; }
364 T
lane(std::size_t l,
const T &v)
379 template<
class T,
class A>
380 std::size_t
lanes(
const Vc::Vector<T, A> &)
382 return Vc::Vector<T, A>::size();
385 template<
class T,
class A>
386 T
lane(std::size_t l,
const Vc::Vector<T, A> &v)
388 assert(l <
lanes(v));
392 template<
class T,
class A>
393 auto lane(std::size_t l, Vc::Vector<T, A> &v)
395 assert(l <
lanes(v));
396 return VcImpl::Proxy<Vc::Vector<T, A> >{l, v};
399 template<
class T, std::
size_t n,
class V>
400 std::size_t
lanes(
const Vc::SimdArray<T, n, V> &)
405 template<
class T, std::
size_t n,
class V>
406 T
lane(std::size_t l,
const Vc::SimdArray<T, n, V> &v)
412 template<
class T, std::
size_t n,
class V>
413 auto lane(std::size_t l, Vc::SimdArray<T, n, V> &v)
416 return VcImpl::Proxy<Vc::SimdArray<T, n, V> >{l, v};
419 template<
class T, std::
size_t n,
class V>
420 std::size_t
lanes(
const Vc::SimdMaskArray<T, n, V> &)
425 template<
class T, std::
size_t n,
class V>
426 bool lane(std::size_t l,
const Vc::SimdMaskArray<T, n, V> &v)
432 template<
class T, std::
size_t n,
class V>
433 auto lane(std::size_t l, Vc::SimdMaskArray<T, n, V> &v)
436 return VcImpl::Proxy<Vc::SimdMaskArray<T, n, V> >{l, v};
454 template<
class T,
class A>
455 void assign(Vc::Vector<T, A> &dst,
const Vc::Vector<T, A> &src,
456 typename Vc::Vector<T, A>::mask_type
mask)
461 template<
class T, std::
size_t n,
class V>
462 void assign(Vc::SimdArray<T, n, V> &dst,
const Vc::SimdArray<T, n, V> &src,
463 typename Vc::SimdArray<T, n, V>::mask_type
mask)
470 void swap(T &v1, T &v2,
bool mask)
473 if(
mask) swap(v1, v2);
480 template<
class T,
class A>
481 void swap(Vc::Vector<T, A> &v1, Vc::Vector<T, A> &v2,
482 typename Vc::Vector<T, A>::mask_type
mask)
489 template<
class T, std::
size_t n,
class V>
490 void swap(Vc::SimdArray<T, n, V> &v1, Vc::SimdArray<T, n, V> &v2,
491 typename Vc::SimdArray<T, n, V>::mask_type
mask)
aligned wrappers for arithmetic types
Definition: debugalign.hh:109
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition: defaults.hh:151
Dune namespace.
Definition: alignedallocator.hh:14
typename SimdIndexTypeTraits< V >::type SimdIndex
An simd vector of indices corresponding to a simd vector V.
Definition: simd.hh:244
typename SimdMaskTypeTraits< V >::type SimdMask
A simd vector of truth values corresponding to a simd vector V.
Definition: simd.hh:268
T lane(std::size_t l, const T &v)
access a lane of a simd vector (scalar version)
Definition: simd.hh:364
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:445
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:360
Utilities for reduction like operations on ranges.
SIMD abstractions for Vc.
Traits for type conversions and type information.
Compatibility header for including <Vc/Vc>