Loading...
Searching...
No Matches
loop.hh
Go to the documentation of this file.
// SPDX-FileCopyrightInfo: Copyright © DUNE Project contributors, see file LICENSE.md in module root
// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
#ifndef DUNE_COMMON_SIMD_LOOP_HH
#define DUNE_COMMON_SIMD_LOOP_HH
#include <array>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <cstdint>
#include <ostream>
#include <dune/common/math.hh>
#include <dune/common/simd/simd.hh>
#include <dune/common/typetraits.hh>
namespace Dune {
/*
* silence warnings from GCC about using integer operands on a bool
* (when instantiated for T=bool)
*/
#if __GNUC__ >= 7
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wbool-operation"
# pragma GCC diagnostic ignored "-Wint-in-bool-context"
# define GCC_WARNING_DISABLED
#endif
/*
* silence warnings from Clang about using bitwise operands on
* a bool (when instantiated for T=bool)
*/
#ifdef __clang__
#if __has_warning("-Wbitwise-instead-of-logical")
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wbitwise-instead-of-logical"
# define CLANG_WARNING_DISABLED
#endif
#endif
/*
* Introduce a simd pragma if OpenMP is available in standard version >= 4
*/
#if _OPENMP >= 201307
#define DUNE_PRAGMA_OMP_SIMD _Pragma("omp simd")
#else
#define DUNE_PRAGMA_OMP_SIMD
#endif
template<class T, std::size_t S, std::size_t A = 0>
class alignas(A==0?alignof(T):A) LoopSIMD : public std::array<T,S> {
public:
//default constructor
LoopSIMD() {
assert(reinterpret_cast<uintptr_t>(this) % std::min(alignof(LoopSIMD<T,S,A>),alignof(std::max_align_t)) == 0);
}
// broadcast constructor initializing the content with a given value
LoopSIMD(Simd::Scalar<T> i) : LoopSIMD() {
this->fill(i);
}
template<std::size_t OA>
explicit LoopSIMD(const LoopSIMD<T,S,OA>& other)
: std::array<T,S>(other)
{
assert(reinterpret_cast<uintptr_t>(this) % std::min(alignof(LoopSIMD<T,S,A>),alignof(std::max_align_t)) == 0);
}
/*
* Definition of basic operators
*/
//Prefix operators
#define DUNE_SIMD_LOOP_PREFIX_OP(SYMBOL) \
auto operator SYMBOL() { \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
SYMBOL(*this)[i]; \
} \
return *this; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_PREFIX_OP(++);
DUNE_SIMD_LOOP_PREFIX_OP(--);
#undef DUNE_SIMD_LOOP_PREFIX_OP
//Unary operators
#define DUNE_SIMD_LOOP_UNARY_OP(SYMBOL) \
auto operator SYMBOL() const { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = SYMBOL((*this)[i]); \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_UNARY_OP(+);
DUNE_SIMD_LOOP_UNARY_OP(-);
DUNE_SIMD_LOOP_UNARY_OP(~);
auto operator!() const {
Simd::Mask<LoopSIMD<T,S,A>> out;
DUNE_PRAGMA_OMP_SIMD
for(std::size_t i=0; i<S; i++){
out[i] = !((*this)[i]);
}
return out;
}
#undef DUNE_SIMD_LOOP_UNARY_OP
//Postfix operators
#define DUNE_SIMD_LOOP_POSTFIX_OP(SYMBOL) \
auto operator SYMBOL(int){ \
LoopSIMD<T,S,A> out = *this; \
SYMBOL(*this); \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_POSTFIX_OP(++);
DUNE_SIMD_LOOP_POSTFIX_OP(--);
#undef DUNE_SIMD_LOOP_POSTFIX_OP
//Assignment operators
#define DUNE_SIMD_LOOP_ASSIGNMENT_OP(SYMBOL) \
auto operator SYMBOL(const Simd::Scalar<T> s) { \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
(*this)[i] SYMBOL s; \
} \
return *this; \
} \
\
auto operator SYMBOL(const LoopSIMD<T,S,A> &v) { \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
(*this)[i] SYMBOL v[i]; \
} \
return *this; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_ASSIGNMENT_OP(+=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(-=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(*=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(/=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(%=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(<<=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(>>=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(&=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(|=);
DUNE_SIMD_LOOP_ASSIGNMENT_OP(^=);
#undef DUNE_SIMD_LOOP_ASSIGNMENT_OP
};
//Arithmetic operators
#define DUNE_SIMD_LOOP_BINARY_OP(SYMBOL) \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, const Simd::Scalar<T> s) { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL s; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const Simd::Scalar<T> s, const LoopSIMD<T,S,A> &v) { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = s SYMBOL v[i]; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, \
const LoopSIMD<T,S,A> &w) { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL w[i]; \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_BINARY_OP(+);
DUNE_SIMD_LOOP_BINARY_OP(-);
DUNE_SIMD_LOOP_BINARY_OP(*);
DUNE_SIMD_LOOP_BINARY_OP(/);
DUNE_SIMD_LOOP_BINARY_OP(%);
DUNE_SIMD_LOOP_BINARY_OP(&);
DUNE_SIMD_LOOP_BINARY_OP(|);
DUNE_SIMD_LOOP_BINARY_OP(^);
#undef DUNE_SIMD_LOOP_BINARY_OP
//Bitshift operators
#define DUNE_SIMD_LOOP_BITSHIFT_OP(SYMBOL) \
template<class T, std::size_t S, std::size_t A, class U> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, const U s) { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL s; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A, class U, std::size_t AU> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, \
const LoopSIMD<U,S,AU> &w) { \
LoopSIMD<T,S,A> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL w[i]; \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_BITSHIFT_OP(<<);
DUNE_SIMD_LOOP_BITSHIFT_OP(>>);
#undef DUNE_SIMD_LOOP_BITSHIFT_OP
//Comparison operators
#define DUNE_SIMD_LOOP_COMPARISON_OP(SYMBOL) \
template<class T, std::size_t S, std::size_t A, class U> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, const U s) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL s; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const Simd::Scalar<T> s, const LoopSIMD<T,S,A> &v) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = s SYMBOL v[i]; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, \
const LoopSIMD<T,S,A> &w) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL w[i]; \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_COMPARISON_OP(<);
DUNE_SIMD_LOOP_COMPARISON_OP(>);
DUNE_SIMD_LOOP_COMPARISON_OP(<=);
DUNE_SIMD_LOOP_COMPARISON_OP(>=);
DUNE_SIMD_LOOP_COMPARISON_OP(==);
DUNE_SIMD_LOOP_COMPARISON_OP(!=);
#undef DUNE_SIMD_LOOP_COMPARISON_OP
//Boolean operators
#define DUNE_SIMD_LOOP_BOOLEAN_OP(SYMBOL) \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, const Simd::Scalar<T> s) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL s; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const Simd::Mask<T>& s, const LoopSIMD<T,S,A> &v) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = s SYMBOL v[i]; \
} \
return out; \
} \
template<class T, std::size_t S, std::size_t A> \
auto operator SYMBOL(const LoopSIMD<T,S,A> &v, \
const LoopSIMD<T,S,A> &w) { \
Simd::Mask<LoopSIMD<T,S,A>> out; \
DUNE_PRAGMA_OMP_SIMD \
for(std::size_t i=0; i<S; i++){ \
out[i] = v[i] SYMBOL w[i]; \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_BOOLEAN_OP(&&);
DUNE_SIMD_LOOP_BOOLEAN_OP(||);
#undef DUNE_SIMD_LOOP_BOOLEAN_OP
//prints a given LoopSIMD
template<class T, std::size_t S, std::size_t A>
std::ostream& operator<< (std::ostream &os, const LoopSIMD<T,S,A> &v) {
os << "[";
for(std::size_t i=0; i<S-1; i++) {
os << v[i] << ", ";
}
os << v[S-1] << "]";
return os;
}
namespace Simd {
namespace Overloads {
/*
* Implementation/Overloads of the functions needed for
* SIMD-interface-compatibility
*/
//Implementation of SIMD-interface-types
template<class T, std::size_t S, std::size_t A>
struct ScalarType<LoopSIMD<T,S,A>> {
using type = Simd::Scalar<T>;
};
template<class U, class T, std::size_t S, std::size_t A>
struct RebindType<U, LoopSIMD<T,S,A>> {
using type = LoopSIMD<Simd::Rebind<U, T>,S,A>;
};
//Implementation of SIMD-interface-functionality
template<class T, std::size_t S, std::size_t A>
struct LaneCount<LoopSIMD<T,S,A>> : index_constant<S*lanes<T>()> {};
template<class T, std::size_t S, std::size_t A>
auto lane(ADLTag<5>, std::size_t l, LoopSIMD<T,S,A> &&v)
-> decltype(std::move(Simd::lane(l%lanes<T>(), v[l/lanes<T>()])))
{
return std::move(Simd::lane(l%lanes<T>(), v[l/lanes<T>()]));
}
template<class T, std::size_t S, std::size_t A>
auto lane(ADLTag<5>, std::size_t l, const LoopSIMD<T,S,A> &v)
-> decltype(Simd::lane(l%lanes<T>(), v[l/lanes<T>()]))
{
return Simd::lane(l%lanes<T>(), v[l/lanes<T>()]);
}
template<class T, std::size_t S, std::size_t A>
auto lane(ADLTag<5>, std::size_t l, LoopSIMD<T,S,A> &v)
-> decltype(Simd::lane(l%lanes<T>(), v[l/lanes<T>()]))
{
return Simd::lane(l%lanes<T>(), v[l/lanes<T>()]);
}
template<class T, std::size_t S, std::size_t AM, std::size_t AD>
auto cond(ADLTag<5>, const Simd::Mask<LoopSIMD<T,S,AM>>& mask,
const LoopSIMD<T,S,AD>& ifTrue, const LoopSIMD<T,S,AD>& ifFalse) {
LoopSIMD<T,S,AD> out;
for(std::size_t i=0; i<S; i++) {
out[i] = Simd::cond(mask[i], ifTrue[i], ifFalse[i]);
}
return out;
}
template<class M, class T, std::size_t S, std::size_t A>
auto cond(ADLTag<5, std::is_same<bool, Simd::Scalar<M> >::value
&& Simd::lanes<M>() == Simd::lanes<LoopSIMD<T,S,A> >()>,
const M& mask, const LoopSIMD<T,S,A>& ifTrue, const LoopSIMD<T,S,A>& ifFalse)
{
LoopSIMD<T,S,A> out;
for(auto l : range(Simd::lanes(mask)))
Simd::lane(l, out) = Simd::lane(l, mask) ? Simd::lane(l, ifTrue) : Simd::lane(l, ifFalse);
return out;
}
template<class M, std::size_t S, std::size_t A>
bool anyTrue(ADLTag<5>, const LoopSIMD<M,S,A>& mask) {
bool out = false;
for(std::size_t i=0; i<S; i++) {
out |= Simd::anyTrue(mask[i]);
}
return out;
}
template<class M, std::size_t S, std::size_t A>
bool allTrue(ADLTag<5>, const LoopSIMD<M,S,A>& mask) {
bool out = true;
for(std::size_t i=0; i<S; i++) {
out &= Simd::allTrue(mask[i]);
}
return out;
}
template<class M, std::size_t S, std::size_t A>
bool anyFalse(ADLTag<5>, const LoopSIMD<M,S,A>& mask) {
bool out = false;
for(std::size_t i=0; i<S; i++) {
out |= Simd::anyFalse(mask[i]);
}
return out;
}
template<class M, std::size_t S, std::size_t A>
bool allFalse(ADLTag<5>, const LoopSIMD<M,S,A>& mask) {
bool out = true;
for(std::size_t i=0; i<S; i++) {
out &= Simd::allFalse(mask[i]);
}
return out;
}
} //namespace Overloads
} //namespace Simd
/*
* Overloads the unary cmath-operations. Operations requiring
* or returning more than one argument are not supported.
* Due to inconsistency with the return values, cmath-operations
* on integral types are also not supported-
*/
#define DUNE_SIMD_LOOP_CMATH_UNARY_OP(expr) \
template<class T, std::size_t S, std::size_t A, typename Sfinae = \
typename std::enable_if_t<!std::is_integral<Simd::Scalar<T>>::value> > \
auto expr(const LoopSIMD<T,S,A> &v) { \
using std::expr; \
LoopSIMD<T,S,A> out; \
for(std::size_t i=0; i<S; i++) { \
out[i] = expr(v[i]); \
} \
return out; \
} \
static_assert(true, "expecting ;")
#define DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(expr, returnType) \
template<class T, std::size_t S, std::size_t A, typename Sfinae = \
typename std::enable_if_t<!std::is_integral<Simd::Scalar<T>>::value> > \
auto expr(const LoopSIMD<T,S,A> &v) { \
using std::expr; \
LoopSIMD<returnType,S> out; \
for(std::size_t i=0; i<S; i++) { \
out[i] = expr(v[i]); \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_CMATH_UNARY_OP(cos);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(sin);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(tan);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(acos);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(asin);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(atan);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(cosh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(sinh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(tanh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(acosh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(asinh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(atanh);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(exp);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(log);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(log10);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(exp2);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(expm1);
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(ilogb, int);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(log1p);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(log2);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(logb);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(sqrt);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(cbrt);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(erf);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(erfc);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(tgamma);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(lgamma);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(ceil);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(floor);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(trunc);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(round);
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(lround, long);
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(llround, long long);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(rint);
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(lrint, long);
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(llrint, long long);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(nearbyint);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(fabs);
DUNE_SIMD_LOOP_CMATH_UNARY_OP(abs);
#undef DUNE_SIMD_LOOP_CMATH_UNARY_OP
#undef DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN
/* not implemented cmath-functions:
* atan2
* frexp, idexp
* modf
* scalbn, scalbln
* pow
* hypot
* remainder, remquo
* copysign
* nan
* nextafter, nexttoward
* fdim, fmax, fmin
*/
/*
* Overloads specific functions usually provided by the std library
* More overloads will be provided should the need arise.
*/
#define DUNE_SIMD_LOOP_STD_UNARY_OP(expr) \
template<class T, std::size_t S, std::size_t A> \
auto expr(const LoopSIMD<T,S,A> &v) { \
using std::expr; \
LoopSIMD<T,S,A> out; \
for(std::size_t i=0; i<S; i++) { \
out[i] = expr(v[i]); \
} \
return out; \
} \
\
template<class T, std::size_t S, std::size_t A> \
auto expr(const LoopSIMD<std::complex<T>,S,A> &v) { \
using std::expr; \
LoopSIMD<T,S,A> out; \
for(std::size_t i=0; i<S; i++) { \
out[i] = expr(v[i]); \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_STD_UNARY_OP(real);
DUNE_SIMD_LOOP_STD_UNARY_OP(imag);
#undef DUNE_SIMD_LOOP_STD_UNARY_OP
#define DUNE_SIMD_LOOP_STD_BINARY_OP(expr) \
template<class T, std::size_t S, std::size_t A> \
auto expr(const LoopSIMD<T,S,A> &v, const LoopSIMD<T,S,A> &w) { \
using std::expr; \
LoopSIMD<T,S,A> out; \
for(std::size_t i=0; i<S; i++) { \
out[i] = expr(v[i],w[i]); \
} \
return out; \
} \
static_assert(true, "expecting ;")
DUNE_SIMD_LOOP_STD_BINARY_OP(max);
DUNE_SIMD_LOOP_STD_BINARY_OP(min);
#undef DUNE_SIMD_LOOP_STD_BINARY_OP
namespace MathOverloads {
template<class T, std::size_t S, std::size_t A>
auto isNaN(const LoopSIMD<T,S,A> &v, PriorityTag<3>, ADLTag) {
Simd::Mask<LoopSIMD<T,S,A>> out;
for(auto l : range(S))
out[l] = Dune::isNaN(v[l]);
return out;
}
template<class T, std::size_t S, std::size_t A>
auto isInf(const LoopSIMD<T,S,A> &v, PriorityTag<3>, ADLTag) {
Simd::Mask<LoopSIMD<T,S,A>> out;
for(auto l : range(S))
out[l] = Dune::isInf(v[l]);
return out;
}
template<class T, std::size_t S, std::size_t A>
auto isFinite(const LoopSIMD<T,S,A> &v, PriorityTag<3>, ADLTag) {
Simd::Mask<LoopSIMD<T,S,A>> out;
for(auto l : range(S))
out[l] = Dune::isFinite(v[l]);
return out;
}
} //namespace MathOverloads
template<class T, std::size_t S, std::size_t A>
struct IsNumber<LoopSIMD<T,S,A>> :
public std::integral_constant<bool, IsNumber<T>::value>{
};
#ifdef CLANG_WARNING_DISABLED
# pragma clang diagnostic pop
# undef CLANG_WARNING_DISABLED
#endif
#ifdef GCC_WARNING_DISABLED
# pragma GCC diagnostic pop
# undef GCC_WARNING_DISABLED
#endif
} //namespace Dune
#endif
typetraits.hh
Traits for type conversions and type information.
DUNE_SIMD_LOOP_BINARY_OP
#define DUNE_SIMD_LOOP_BINARY_OP(SYMBOL)
Definition loop.hh:177
DUNE_SIMD_LOOP_BOOLEAN_OP
#define DUNE_SIMD_LOOP_BOOLEAN_OP(SYMBOL)
Definition loop.hh:289
DUNE_SIMD_LOOP_STD_BINARY_OP
#define DUNE_SIMD_LOOP_STD_BINARY_OP(expr)
Definition loop.hh:567
DUNE_SIMD_LOOP_STD_UNARY_OP
#define DUNE_SIMD_LOOP_STD_UNARY_OP(expr)
Definition loop.hh:540
DUNE_SIMD_LOOP_BITSHIFT_OP
#define DUNE_SIMD_LOOP_BITSHIFT_OP(SYMBOL)
Definition loop.hh:221
DUNE_SIMD_LOOP_CMATH_UNARY_OP
#define DUNE_SIMD_LOOP_CMATH_UNARY_OP(expr)
Definition loop.hh:446
DUNE_PRAGMA_OMP_SIMD
#define DUNE_PRAGMA_OMP_SIMD
Definition loop.hh:49
DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN
#define DUNE_SIMD_LOOP_CMATH_UNARY_OP_WITH_RETURN(expr, returnType)
Definition loop.hh:459
DUNE_SIMD_LOOP_ASSIGNMENT_OP
#define DUNE_SIMD_LOOP_ASSIGNMENT_OP(SYMBOL)
Definition loop.hh:145
math.hh
Some useful basic math stuff.
Dune::index_constant
std::integral_constant< std::size_t, i > index_constant
An index constant with value i.
Definition indices.hh:29
Dune::range
static constexpr IntegralRange< std::decay_t< T > > range(T &&from, U &&to) noexcept
free standing function for setting up a range based for loop over an integer range for (auto i: range...
Definition rangeutilities.hh:288
Dune::operator<<
std::ostream & operator<<(std::ostream &s, const bigunsignedint< k > &x)
Definition bigunsignedint.hh:301
Dune::Simd::anyTrue
bool anyTrue(const Mask &mask)
Whether any entry is true.
Definition simd/interface.hh:429
Dune::Simd::cond
V cond(M &&mask, const V &ifTrue, const V &ifFalse)
Like the ?: operator.
Definition simd/interface.hh:386
Dune::Simd::allTrue
bool allTrue(const Mask &mask)
Whether all entries are true.
Definition simd/interface.hh:439
Dune::Simd::Scalar
typename Overloads::ScalarType< std::decay_t< V > >::type Scalar
Element type of some SIMD type.
Definition simd/interface.hh:235
Dune::Simd::anyFalse
bool anyFalse(const Mask &mask)
Whether any entry is false.
Definition simd/interface.hh:449
Dune::Simd::Mask
Rebind< bool, V > Mask
Mask type type of some SIMD type.
Definition simd/interface.hh:289
Dune::Simd::lanes
constexpr std::size_t lanes()
Number of lanes in a SIMD type.
Definition simd/interface.hh:305
Dune::Simd::lane
decltype(auto) lane(std::size_t l, V &&v)
Extract an element of a SIMD type.
Definition simd/interface.hh:324
Dune::Simd::allFalse
bool allFalse(const Mask &mask)
Whether all entries are false.
Definition simd/interface.hh:459
Dune::Simd::Overloads::mask
Mask< V > mask(ADLTag< 0, std::is_same< V, Mask< V > >::value >, const V &v)
implements Simd::mask()
Definition defaults.hh:153
Dune::Simd::Overloads::allFalse
bool allFalse(ADLTag< 0 >, const Mask &mask)
implements Simd::allFalse()
Definition defaults.hh:124
Dune::Simd::Overloads::allTrue
bool allTrue(ADLTag< 0 >, const Mask &mask)
implements Simd::allTrue()
Definition defaults.hh:104
Dune::Simd::Overloads::anyFalse
bool anyFalse(ADLTag< 0 >, const Mask &mask)
implements Simd::anyFalse()
Definition defaults.hh:114
std
STL namespace.
Dune
Dune namespace
Definition alignedallocator.hh:13
Dune::DUNE_SIMD_LOOP_COMPARISON_OP
DUNE_SIMD_LOOP_COMPARISON_OP(<)
Dune::Simd
Namespace for vectorization interface functions used by library developers.
Definition debugalign.hh:518
Dune::Simd::Overloads
Namespace for the overloads and specializations that make up a SIMD implementation.
Definition debugalign.hh:519
Dune::Simd::Overloads::anyTrue
bool anyTrue(ADLTag< 5 >, const AlignedNumber< bool, align > &mask)
Definition debugalign.hh:556
Dune::Simd::Overloads::cond
const AlignedNumber< T, align > & cond(ADLTag< 5 >, AlignedNumber< bool, align > mask, const AlignedNumber< T, align > &ifTrue, const AlignedNumber< T, align > &ifFalse)
Definition debugalign.hh:548
Dune::Simd::Overloads::lane
T & lane(ADLTag< 5 >, std::size_t l, AlignedNumber< T, align > &v)
Definition debugalign.hh:533
Dune::MathOverloads
namespace for customization of math functions with Dune-Semantics
Definition fvector.hh:431
Dune::MathOverloads::isNaN
bool isNaN(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is NaN.
Definition fvector.hh:458
Dune::MathOverloads::isInf
bool isInf(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether any entry is infinite.
Definition fvector.hh:446
Dune::MathOverloads::isFinite
auto isFinite(const FieldVector< K, SIZE > &b, PriorityTag< 2 >, ADLTag)
Returns whether all entries are finite.
Definition fvector.hh:435
Dune::IsNumber
Whether this type acts as a scalar in the context of (hierarchically blocked) containers.
Definition typetraits.hh:194
Dune::MathOverloads::ADLTag
Tag to make sure the functions in this namespace can be found by ADL.
Definition math.hh:212
Dune::Simd::Overloads::ADLTag
Tag used to force late-binding lookup in Dune::Simd::Overloads.
Definition base.hh:182
Dune::Simd::Overloads::ScalarType
should have a member type type
Definition standard.hh:60
Dune::Simd::Overloads::RebindType
should have a member type type
Definition standard.hh:67
Dune::Simd::Overloads::LaneCount
should be derived from a Dune::index_constant
Definition standard.hh:74
Dune::LoopSIMD
Definition loop.hh:65
Dune::LoopSIMD::LoopSIMD
LoopSIMD(Simd::Scalar< T > i)
Definition loop.hh:75
Dune::LoopSIMD::DUNE_SIMD_LOOP_PREFIX_OP
DUNE_SIMD_LOOP_PREFIX_OP(++)
Dune::LoopSIMD::operator!
auto operator!() const
Definition loop.hh:121
Dune::LoopSIMD::DUNE_SIMD_LOOP_POSTFIX_OP
DUNE_SIMD_LOOP_POSTFIX_OP(--)
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP * DUNE_SIMD_LOOP_ASSIGNMENT_OP(/=);DUNE_SIMD_LOOP_ASSIGNMENT_OP(%=
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP & DUNE_SIMD_LOOP_ASSIGNMENT_OP(|=);DUNE_SIMD_LOOP_ASSIGNMENT_OP(^=
Dune::LoopSIMD::DUNE_SIMD_LOOP_UNARY_OP
DUNE_SIMD_LOOP_UNARY_OP(-)
Dune::LoopSIMD::DUNE_SIMD_LOOP_PREFIX_OP
DUNE_SIMD_LOOP_PREFIX_OP(--)
Dune::LoopSIMD::DUNE_SIMD_LOOP_POSTFIX_OP
DUNE_SIMD_LOOP_POSTFIX_OP(++)
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP(-=)
Dune::LoopSIMD::LoopSIMD
LoopSIMD(const LoopSIMD< T, S, OA > &other)
Definition loop.hh:80
Dune::LoopSIMD::LoopSIMD
LoopSIMD()
Definition loop.hh:70
Dune::LoopSIMD::DUNE_SIMD_LOOP_UNARY_OP
DUNE_SIMD_LOOP_UNARY_OP(~)
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP(+=)
Dune::LoopSIMD::DUNE_SIMD_LOOP_UNARY_OP
DUNE_SIMD_LOOP_UNARY_OP(+)
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP(<<=)
Dune::LoopSIMD::DUNE_SIMD_LOOP_ASSIGNMENT_OP
DUNE_SIMD_LOOP_ASSIGNMENT_OP(> >=)
Dune::Simd::Overloads::ScalarType< LoopSIMD< T, S, A > >::type
Simd::Scalar< T > type
Definition loop.hh:345
Dune::Simd::Overloads::RebindType< U, LoopSIMD< T, S, A > >::type
LoopSIMD< Simd::Rebind< U, T >, S, A > type
Definition loop.hh:350
Dune::PriorityTag
Helper class for tagging priorities.
Definition typeutilities.hh:73
simd.hh
Include file for users of the SIMD abstraction layer.