3#ifndef DUNE_COMMON_SIMD_HH
4#define DUNE_COMMON_SIMD_HH
6#warning dune/common/simd.hh is deprecated.
7#warning Use the new infrastructure from dune/common/simd/simd.h instead.
35#include <dune/common/conditional.hh>
36#include <dune/common/debugalign.hh>
64 static_assert(std::is_same<V, std::decay_t<V> >::value,
"Class Proxy "
65 "may only be instantiated with unqualified types");
67 using value_type =
typename V::value_type;
70 static_assert(std::is_arithmetic<value_type>::value,
71 "Only arithmetic types are supported");
76 Proxy(std::size_t idx, V &vec)
77 : vec_(vec), idx_(idx)
80 operator value_type()
const {
return vec_[idx_]; }
84 template<
class T = value_type,
85 class = std::enable_if_t<!std::is_same<T, bool>::value> >
86 value_type operator++(
int) {
return vec_[idx_]++; }
87 template<
class T = value_type,
88 class = std::enable_if_t<!std::is_same<T, bool>::value> >
89 value_type operator--(
int) {
return vec_[idx_]--; }
92 template<
class T = value_type,
93 class = std::enable_if_t<!std::is_same<T, bool>::value> >
94 Proxy &operator++() { ++(vec_[idx_]);
return *
this; }
95 template<
class T = value_type,
96 class = std::enable_if_t<!std::is_same<T, bool>::value> >
97 Proxy &operator--() { --(vec_[idx_]);
return *
this; }
98 decltype(
auto)
operator!()
const {
return !(vec_[idx_]); }
99 decltype(
auto)
operator+()
const {
return +(vec_[idx_]); }
100 decltype(
auto)
operator-()
const {
return -(vec_[idx_]); }
101 template<
class T = value_type,
102 class = std::enable_if_t<std::is_integral<T>::value> >
103 decltype(
auto)
operator~()
const {
return ~(vec_[idx_]); }
106#define DUNE_SIMD_VC_BINARY_OP(OP) \
108 auto operator OP(T &&o) const \
109 -> decltype(vec_[idx_] OP valueCast(std::forward<T>(o))) \
111 return vec_[idx_] OP valueCast(std::forward<T>(o)); \
113 static_assert(true, "Require semicolon to unconfuse editors")
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(-);
122 DUNE_SIMD_VC_BINARY_OP(<<);
123 DUNE_SIMD_VC_BINARY_OP(>>);
125 DUNE_SIMD_VC_BINARY_OP(<);
126 DUNE_SIMD_VC_BINARY_OP(>);
127 DUNE_SIMD_VC_BINARY_OP(<=);
128 DUNE_SIMD_VC_BINARY_OP(>=);
130 DUNE_SIMD_VC_BINARY_OP(==);
131 DUNE_SIMD_VC_BINARY_OP(!=);
133 DUNE_SIMD_VC_BINARY_OP(&);
134 DUNE_SIMD_VC_BINARY_OP(^);
135 DUNE_SIMD_VC_BINARY_OP(|);
137 DUNE_SIMD_VC_BINARY_OP(&&);
138 DUNE_SIMD_VC_BINARY_OP(||);
139#undef DUNE_SIMD_VC_BINARY_OP
141#define DUNE_SIMD_VC_ASSIGNMENT(OP) \
143 auto operator OP(T &&o) \
144 -> std::enable_if_t<AlwaysTrue<decltype( \
145 vec_[idx_] OP valueCast(std::forward<T>(o)) \
148 vec_[idx_] OP valueCast(std::forward<T>(o)); \
151 static_assert(true, "Require semicolon to unconfuse editors")
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 DUNE_SIMD_VC_ASSIGNMENT(^=);
163 DUNE_SIMD_VC_ASSIGNMENT(|=);
164#undef DUNE_SIMD_VC_ASSIGNMENT
168 template<
class V1,
class V2>
169 friend void swap(Proxy<V1>, Proxy<V2>);
172 friend void swap(Proxy p1, T& s2)
176 T tmp = p1.vec_[p1.idx_];
177 p1.vec_[p1.idx_] = s2;
182 friend void swap(T& s1, Proxy p2)
185 s1 = p2.vec_[p2.idx_];
186 p2.vec_[p2.idx_] = tmp;
190 template<
class V1,
class V2>
191 void swap(Proxy<V1> p1, Proxy<V2> p2)
193 typename V1::value_type tmp = p1.vec_[p1.idx_];
194 p1.vec_[p1.idx_] = p2.vec_[p2.idx_];
195 p2.vec_[p2.idx_] = tmp;
201 struct SimdScalarTypeTraits
207 using SimdScalar =
typename SimdScalarTypeTraits<T>::type;
213 template<
typename T,
typename A>
214 struct SimdScalarTypeTraits< Vc::Vector<T,A> >
219 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
220 struct SimdScalarTypeTraits< Vc::SimdArray<T,N,V,M> >
227 template<
typename T, std::
size_t align>
233 template<
typename V,
typename =
void>
234 struct SimdIndexTypeTraits {
235 using type = std::size_t;
246 using SimdIndex =
typename SimdIndexTypeTraits<V>::type;
249 template<
typename T,
typename A>
250 struct SimdIndexTypeTraits<Vc::Vector<T, A> > {
251 using type =
typename Vc::Vector<T, A>::index_type;
254 template<
typename T, std::
size_t n,
typename V>
255 struct SimdIndexTypeTraits<Vc::SimdArray<T, n, V> > {
256 using type =
typename Vc::SimdArray<T, n, V>::index_type;
260 template<
typename V,
typename =
void>
261 struct SimdMaskTypeTraits {
270 using SimdMask =
typename SimdMaskTypeTraits<V>::type;
273 template<
typename T,
typename A>
274 struct SimdMaskTypeTraits<Vc::Vector<T, A> > {
275 using type =
typename Vc::Vector<T, A>::mask_type;
278 template<
typename T, std::
size_t n,
typename V>
279 struct SimdMaskTypeTraits<Vc::SimdArray<T, n, V> > {
280 using type =
typename Vc::SimdArray<T, n, V>::mask_type;
288 template<
typename T,
typename A>
289 Vc::Vector<T,A>
cond(
const Vc::Mask<T,A> & b,
290 const Vc::Vector<T,A> & v1,
291 const Vc::Vector<T,A> & v2)
293 return std::move(Vc::iif(b, v1, v2));
296 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
297 Vc::SimdArray<T,N,V,M>
cond(
const typename Vc::SimdArray<T,N,V,M>::mask_type & b,
298 const Vc::SimdArray<T,N,V,M> & v1,
299 const Vc::SimdArray<T,N,V,M> & v2)
301 return std::move(Vc::iif(b, v1, v2));
311 template<
typename T,
typename A>
312 T max_value(
const Vc::Vector<T,A> & v)
317 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
318 double max_value(
const Vc::SimdArray<T,N,V,M> & v)
323 template<
typename T,
typename A>
324 T min_value(
const Vc::Vector<T,A> & v)
329 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
330 double min_value(
const Vc::SimdArray<T,N,V,M> & v)
335 template<
typename T,
typename A>
336 bool any_true(
const Vc::Mask<T,A> & v)
338 return Vc::any_of(v);
341 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
342 bool any_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
344 return Vc::any_of(v);
347 template<
typename T,
typename A>
348 bool all_true(
const Vc::Mask<T,A> & v)
350 return Vc::all_of(v);
353 template<
typename T, std::
size_t N,
typename V, std::
size_t M>
354 bool all_true(
const Vc::SimdMaskArray<T,N,V,M> & v)
356 return Vc::all_of(v);
362 std::size_t
lanes(
const T &) {
return 1; }
366 T
lane(std::size_t l,
const T &v)
381 template<
class T,
class A>
382 std::size_t
lanes(
const Vc::Vector<T, A> &)
384 return Vc::Vector<T, A>::size();
387 template<
class T,
class A>
388 T
lane(std::size_t l,
const Vc::Vector<T, A> &v)
390 assert(l <
lanes(v));
394 template<
class T,
class A>
395 auto lane(std::size_t l, Vc::Vector<T, A> &v)
397 assert(l <
lanes(v));
398 return VcImpl::Proxy<Vc::Vector<T, A> >{l, v};
401 template<
class T, std::
size_t n,
class V>
402 std::size_t
lanes(
const Vc::SimdArray<T, n, V> &)
407 template<
class T, std::
size_t n,
class V>
408 T
lane(std::size_t l,
const Vc::SimdArray<T, n, V> &v)
414 template<
class T, std::
size_t n,
class V>
415 auto lane(std::size_t l, Vc::SimdArray<T, n, V> &v)
418 return VcImpl::Proxy<Vc::SimdArray<T, n, V> >{l, v};
421 template<
class T, std::
size_t n,
class V>
422 std::size_t
lanes(
const Vc::SimdMaskArray<T, n, V> &)
427 template<
class T, std::
size_t n,
class V>
428 bool lane(std::size_t l,
const Vc::SimdMaskArray<T, n, V> &v)
434 template<
class T, std::
size_t n,
class V>
435 auto lane(std::size_t l, Vc::SimdMaskArray<T, n, V> &v)
438 return VcImpl::Proxy<Vc::SimdMaskArray<T, n, V> >{l, v};
456 template<
class T,
class A>
457 void assign(Vc::Vector<T, A> &dst,
const Vc::Vector<T, A> &src,
458 typename Vc::Vector<T, A>::mask_type
mask)
463 template<
class T, std::
size_t n,
class V>
464 void assign(Vc::SimdArray<T, n, V> &dst,
const Vc::SimdArray<T, n, V> &src,
465 typename Vc::SimdArray<T, n, V>::mask_type
mask)
472 void swap(T &v1, T &v2,
bool mask)
475 if(
mask) swap(v1, v2);
482 template<
class T,
class A>
483 void swap(Vc::Vector<T, A> &v1, Vc::Vector<T, A> &v2,
484 typename Vc::Vector<T, A>::mask_type
mask)
491 template<
class T, std::
size_t n,
class V>
492 void swap(Vc::SimdArray<T, n, V> &v1, Vc::SimdArray<T, n, V> &v2,
493 typename Vc::SimdArray<T, n, V>::mask_type
mask)
aligned wrappers for arithmetic types
Definition: debugalign.hh:128
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition: defaults.hh:153
Dune namespace.
Definition: alignedallocator.hh:13
typename SimdIndexTypeTraits< V >::type SimdIndex
An simd vector of indices corresponding to a simd vector V.
Definition: simd.hh:246
typename SimdMaskTypeTraits< V >::type SimdMask
A simd vector of truth values corresponding to a simd vector V.
Definition: simd.hh:270
T lane(std::size_t l, const T &v)
access a lane of a simd vector (scalar version)
Definition: simd.hh:366
void assign(T &dst, const T &src, bool mask)
masked Simd assignment (scalar version)
Definition: simd.hh:447
const T1 cond(bool b, const T1 &v1, const T2 &v2)
conditional evaluate
Definition: conditional.hh:28
std::size_t lanes(const T &)
get the number of lanes of a simd vector (scalar version)
Definition: simd.hh:362
Utilities for reduction like operations on ranges.
SIMD abstractions for Vc.
Traits for type conversions and type information.
Compatibility header for including <Vc/Vc>