3#ifndef DUNE_COMMON_SIMD_VC_HH
4#define DUNE_COMMON_SIMD_VC_HH
15#include <dune/common/indices.hh>
18#include <dune/common/simd/loop.hh>
158 template<
class V,
class SFINAE =
void>
161 template<
typename T,
typename A>
162 struct IsMask<Vc::
Mask<T, A> > : std::true_type {};
164 template<
typename T, std::
size_t n,
typename V, std::
size_t m>
165 struct IsMask<Vc::SimdMaskArray<T, n, V, m> > : std::true_type {};
168 template<
class V,
class SFINAE =
void>
171 template<
typename T,
typename A>
172 struct IsVector<Vc::Vector<T, A> > : std::true_type {};
174 template<
typename T, std::
size_t n,
typename V, std::
size_t m>
175 struct IsVector<Vc::SimdArray<T, n, V, m> > : std::true_type {};
177 template<
typename T>
struct IsVectorizable : std::false_type {};
178 template<>
struct IsVectorizable<double> : std::true_type {};
179 template<>
struct IsVectorizable<float> : std::true_type {};
180 template<>
struct IsVectorizable<
std::int32_t> : std::true_type {};
181 template<>
struct IsVectorizable<
std::uint32_t> : std::true_type {};
182 template<>
struct IsVectorizable<
std::int16_t> : std::true_type {};
183 template<>
struct IsVectorizable<
std::uint16_t> : std::true_type {};
201 static_assert(std::is_same<V, std::decay_t<V> >::value,
"Class Proxy "
202 "may only be instantiated with unqualified types");
204 using value_type =
typename V::value_type;
207 static_assert(std::is_arithmetic<value_type>::value,
208 "Only arithmetic types are supported");
213 Proxy(std::size_t idx, V &vec)
214 : vec_(vec), idx_(idx)
221 operator value_type()
const {
return vec_[idx_]; }
224#define DUNE_SIMD_VC_ASSIGNMENT(OP) \
226 class = decltype(std::declval<value_type&>() OP \
227 autoCopy(std::declval<T>()) )> \
228 Proxy operator OP(T &&o) && \
230 vec_[idx_] OP autoCopy(std::forward<T>(o)); \
231 return { idx_, vec_ }; \
233 DUNE_SIMD_VC_ASSIGNMENT(=);
234 DUNE_SIMD_VC_ASSIGNMENT(*=);
235 DUNE_SIMD_VC_ASSIGNMENT(/=);
236 DUNE_SIMD_VC_ASSIGNMENT(%=);
237 DUNE_SIMD_VC_ASSIGNMENT(+=);
238 DUNE_SIMD_VC_ASSIGNMENT(-=);
239 DUNE_SIMD_VC_ASSIGNMENT(<<=);
240 DUNE_SIMD_VC_ASSIGNMENT(>>=);
241 DUNE_SIMD_VC_ASSIGNMENT(&=);
242 DUNE_SIMD_VC_ASSIGNMENT(^=);
243 DUNE_SIMD_VC_ASSIGNMENT(|=);
244#undef DUNE_SIMD_VC_ASSIGNMENT
247 template<
class T = value_type,
248 class = std::enable_if_t<!std::is_same<T, bool>::value> >
249 Proxy operator++() { ++(vec_[idx_]);
return *
this; }
250 template<
class T = value_type,
251 class = std::enable_if_t<!std::is_same<T, bool>::value> >
252 Proxy operator--() { --(vec_[idx_]);
return *
this; }
255 template<
class T = value_type,
256 class = std::enable_if_t<!std::is_same<T, bool>::value> >
257 value_type operator++(
int) {
return vec_[idx_]++; }
258 template<
class T = value_type,
259 class = std::enable_if_t<!std::is_same<T, bool>::value> >
260 value_type operator--(
int) {
return vec_[idx_]--; }
265 friend void swap(
const Proxy &a,
const Proxy &b) {
268 value_type tmp = std::move(a.vec_[a.idx_]);
269 a.vec_[a.idx_] = std::move(b.vec_[b.idx_]);
270 b.vec_[b.idx_] = std::move(tmp);
272 friend void swap(value_type &a,
const Proxy &b) {
275 value_type tmp = std::move(a);
276 a = std::move(b.vec_[b.idx_]);
277 b.vec_[b.idx_] = std::move(tmp);
279 friend void swap(
const Proxy &a, value_type &b) {
282 value_type tmp = std::move(a.vec_[a.idx_]);
283 a.vec_[a.idx_] = std::move(b);
346#define DUNE_SIMD_VC_BINARY(OP) \
347 template<class T, class Abi> \
348 friend auto operator OP(const Vc::Vector<T, Abi> &l, Proxy&& r) \
349 -> decltype(l OP std::declval<value_type>()) \
351 return l OP value_type(r); \
353 template<class T, class Abi> \
354 auto operator OP(const Vc::Vector<T, Abi> &r) && \
355 -> decltype(std::declval<value_type>() OP r) \
357 return value_type(*this) OP r; \
359 template<class T, std::size_t n, class Vec, std::size_t m> \
361 operator OP(const Vc::SimdArray<T, n, Vec, m> &l, Proxy&& r) \
362 -> decltype(l OP std::declval<value_type>()) \
364 return l OP value_type(r); \
366 template<class T, std::size_t n, class Vec, std::size_t m> \
367 auto operator OP(const Vc::SimdArray<T, n, Vec, m> &r) && \
368 -> decltype(std::declval<value_type>() OP r) \
370 return value_type(*this) OP r; \
373 DUNE_SIMD_VC_BINARY(*);
374 DUNE_SIMD_VC_BINARY(/);
375 DUNE_SIMD_VC_BINARY(%);
376 DUNE_SIMD_VC_BINARY(+);
377 DUNE_SIMD_VC_BINARY(-);
378 DUNE_SIMD_VC_BINARY(<<);
379 DUNE_SIMD_VC_BINARY(>>);
380 DUNE_SIMD_VC_BINARY(&);
381 DUNE_SIMD_VC_BINARY(^);
382 DUNE_SIMD_VC_BINARY(|);
383 DUNE_SIMD_VC_BINARY(<);
384 DUNE_SIMD_VC_BINARY(>);
385 DUNE_SIMD_VC_BINARY(<=);
386 DUNE_SIMD_VC_BINARY(>=);
387 DUNE_SIMD_VC_BINARY(==);
388 DUNE_SIMD_VC_BINARY(!=);
389#undef DUNE_SIMD_VC_BINARY
393 template<
class T,
class Abi,
394 class = std::enable_if_t<std::is_convertible<value_type,
396 operator Vc::Vector<T, Abi>() &&
398 return value_type(*
this);
400 template<
class T, std::size_t n,
class Vec, std::size_t m,
401 class = std::enable_if_t<std::is_convertible<value_type,
403 operator Vc::SimdArray<T, n, Vec, m>() &&
405 return value_type(*
this);
408#define DUNE_SIMD_VC_ASSIGN(OP) \
409 template<class T, class Abi> \
410 friend auto operator OP(Vc::Vector<T, Abi> &l, Proxy&& r) \
411 -> decltype(l OP std::declval<value_type>()) \
413 return l OP value_type(r); \
416 DUNE_SIMD_VC_ASSIGN(*=);
417 DUNE_SIMD_VC_ASSIGN(/=);
418 DUNE_SIMD_VC_ASSIGN(%=);
419 DUNE_SIMD_VC_ASSIGN(+=);
420 DUNE_SIMD_VC_ASSIGN(-=);
421 DUNE_SIMD_VC_ASSIGN(&=);
422 DUNE_SIMD_VC_ASSIGN(^=);
423 DUNE_SIMD_VC_ASSIGN(|=);
429 DUNE_SIMD_VC_ASSIGN(<<=);
430 DUNE_SIMD_VC_ASSIGN(>>=);
431#undef DUNE_SIMD_VC_ASSIGN
436 namespace Overloads {
450 using type =
typename V::value_type;
463 std::enable_if_t<VcImpl::IsVector<V>::value> >
477 !VcImpl::IsMask<V>::value>>
479 using type =
typename V::mask_type;
491 std::enable_if_t<VcImpl::IsMask<M>::value>>
493 using type =
typename M::Vector;
503 template<
class S,
class M>
506 VcImpl::IsMask<M>::value &&
507 VcImpl::IsVectorizable<S>::value &&
508 !std::is_same<S, Scalar<typename M::Vector> >::value
511 using type = Vc::SimdArray<S, Simd::lanes<M>()>;
521 template<
class S,
class V>
523 std::enable_if_t<VcImpl::IsVector<V>::value &&
524 !VcImpl::IsMask<V>::value &&
525 VcImpl::IsVectorizable<S>::value &&
526 !std::is_same<S, Scalar<V> >::value> >
528 using type = Vc::SimdArray<S, Simd::lanes<V>()>;
539 template<
class S,
class V>
541 std::enable_if_t<VcImpl::IsVector<V>::value &&
542 !VcImpl::IsVectorizable<S>::value &&
543 !std::is_same<S, bool>::value &&
544 !std::is_same<S, Scalar<V> >::value> >
569 std::size_t l,
const V &v)
583 class = std::enable_if_t<!std::is_reference<V>::value> >
585 std::size_t l, V &&v)
587 return std::forward<V>(v)[l];
594 const Mask<V> &
mask,
const V &ifTrue,
const V &ifFalse)
596 return Vc::iif(
mask, ifTrue, ifFalse);
605 const V &
mask,
const V &ifTrue,
const V &ifFalse)
607 return (
mask && ifTrue) || (!
mask && ifFalse);
614 const V &v1,
const V &v2)
622 const M &m1,
const M &m2)
631 const V &v1,
const V &v2)
639 const M &m1,
const M &m2)
648 return Vc::any_of(
mask);
655 return Vc::all_of(
mask);
664 return Vc::none_of(
mask);
680 return Vc::any_of(
mask);
696 return !Vc::any_of(!
mask);
700 template<
class S1,
class V2>
703 const S1 &s1,
const V2 &v2)
709 template<
class V1,
class S2>
711 std::is_same<
Mask<S2>,
bool>::value>,
712 const V1 &v1,
const S2 &s2)
718 template<
class S1,
class V2>
721 const S1 &s1,
const V2 &v2)
727 template<
class V1,
class S2>
729 std::is_same<
Mask<S2>,
bool>::value>,
730 const V1 &v1,
const S2 &s2)
745 template <
typename T, std::
size_t N,
class V,
size_t Wt>
746 struct IsNumber<Vc::SimdArray<T, N, V, Wt>>
747 :
public std::integral_constant<bool, IsNumber<T>::value> {
750 template <
typename T,
typename Abi>
751 struct IsNumber<Vc::Vector<T, Abi>>
752 :
public std::integral_constant<bool, IsNumber<T>::value> {
Basic definitions for SIMD Implementations.
A reference-like proxy for elements of random-access vectors.
Definition: vc.hh:200
Default implementations for SIMD Implementations.
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition: indices.hh:30
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition: defaults.hh:153
bool allFalse(ADLTag< 0 >, const Mask &mask)
implements Simd::allFalse()
Definition: defaults.hh:124
bool allTrue(ADLTag< 0 >, const Mask &mask)
implements Simd::allTrue()
Definition: defaults.hh:104
auto maskAnd(ADLTag< 0 >, const V1 &v1, const V2 &v2)
implements Simd::maskAnd()
Definition: defaults.hh:177
auto maskOr(ADLTag< 0 >, const V1 &v1, const V2 &v2)
implements Simd::maskOr()
Definition: defaults.hh:170
auto min(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::min()
Definition: defaults.hh:89
auto max(ADLTag< 0 >, const V &v1, const V &v2)
implements binary Simd::max()
Definition: defaults.hh:81
V cond(M &&mask, const V &ifTrue, const V &ifFalse)
Like the ?: operator.
Definition: interface.hh:386
auto mask(const V &v)
Convert to mask, analogue of bool(s) for scalars.
Definition: interface.hh:489
Rebind< bool, V > Mask
Mask type type of some SIMD type.
Definition: interface.hh:289
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition: interface.hh:235
Dune namespace.
Definition: alignedallocator.hh:13
const T1 cond(bool b, const T1 &v1, const T2 &v2)
conditional evaluate
Definition: conditional.hh:28
Type free of internal references that T can be converted to.
Definition: typetraits.hh:501
Tag used to force late-binding lookup in Dune::Simd::Overloads.
Definition: base.hh:182
should be derived from a Dune::index_constant
Definition: standard.hh:74
should have a member type type
Definition: standard.hh:67
should have a member type type
Definition: standard.hh:60
specialized to true for Vc mask types
Definition: vc.hh:159
specialized to true for Vc vector and mask types
Definition: vc.hh:169
Traits for type conversions and type information.
Compatibility header for including <Vc/Vc>