1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
#ifndef VECCORE_BACKEND_VC_VECTOR_H
#define VECCORE_BACKEND_VC_VECTOR_H
namespace vecCore {
template <typename T, class Abi>
struct TypeTraits<Vc::Mask<T, Abi>> {
using IndexType = size_t;
using ScalarType = bool;
static constexpr size_t Size = Vc::Mask<T, Abi>::Size;
};
template <typename T, class Abi>
struct TypeTraits<Vc::Vector<T, Abi>> {
using ScalarType = T;
using MaskType = typename Vc::Vector<T, Abi>::MaskType;
using IndexType = typename Vc::Vector<T, Abi>::IndexType;
static constexpr size_t Size = Vc::Vector<T, Abi>::Size;
};
namespace backend {
template <typename T = Real_s, class Abi = Vc::VectorAbi::Best<T>>
class VcVectorT {
public:
using Real_v = Vc::Vector<T, Abi>;
using Float_v = Vc::Vector<float, Abi>;
using Double_v = Vc::Vector<double, Abi>;
using Int_v = Vc::Vector<int, Abi>;
using Int16_v = Vc::Vector<int16_t, Abi>;
using Int32_v = Vc::Vector<int32_t, Abi>;
using Int64_v = Vc::Vector<int64_t, Abi>;
using UInt_v = Vc::Vector<unsigned int, Abi>;
using UInt16_v = Vc::Vector<uint16_t, Abi>;
using UInt32_v = Vc::Vector<uint32_t, Abi>;
using UInt64_v = Vc::Vector<uint64_t, Abi>;
};
using VcVector = VcVectorT<>;
} // namespace backend
template <typename T, class Abi>
VECCORE_FORCE_INLINE
bool MaskEmpty(const Vc::Mask<T, Abi> &mask)
{
return mask.isEmpty();
}
template <typename T, class Abi>
VECCORE_FORCE_INLINE
bool MaskFull(const Vc::Mask<T, Abi> &mask)
{
return mask.isFull();
}
template <typename T, class Abi>
struct IndexingImplementation<Vc::Mask<T, Abi>> {
using M = Vc::Mask<T, Abi>;
static inline bool Get(const M &mask, size_t i) { return mask[i]; }
static inline void Set(M &mask, size_t i, const bool val) { mask[i] = val; }
};
template <typename T, class Abi>
struct LoadStoreImplementation<Vc::Vector<T, Abi>> {
using V = Vc::Vector<T, Abi>;
template <typename S = Scalar<V>>
static inline void Load(V &v, S const *ptr)
{
v.load(ptr);
}
template <typename S = Scalar<V>>
static inline void Store(V const &v, S *ptr)
{
v.store(ptr);
}
};
template <typename T, class Abi>
struct LoadStoreImplementation<Vc::Mask<T, Abi>> {
using M = Vc::Mask<T, Abi>;
template <typename S = Scalar<T>>
static inline void Load(M &mask, bool const *ptr)
{
mask.load(ptr);
}
template <typename S = Scalar<T>>
static inline void Store(M const &mask, S *ptr)
{
mask.store(ptr);
}
};
template <typename T, class Abi>
struct MaskingImplementation<Vc::Vector<T, Abi>> {
using M = Vc::Mask<T, Abi>;
using V = Vc::Vector<T, Abi>;
static inline void Assign(V &dst, M const &mask, V const &src) { dst(mask) = src; }
static inline void Blend(V &dst, M const &mask, V const &src1, V const src2)
{
dst = src2;
dst(mask) = src1;
}
};
inline namespace math {
template <typename T, class Abi>
VECCORE_FORCE_INLINE
Vc::Vector<T, Abi> CopySign(const Vc::Vector<T, Abi> &x, const Vc::Vector<T, Abi> &y)
{
return Vc::copysign(x, y);
}
#define VC_MATH_UNARY_FUNCTION(F, f) \
template <typename T, class Abi> \
VECCORE_FORCE_INLINE \
Vc::Vector<T, Abi> F(const Vc::Vector<T, Abi> &x) \
{ return Vc::f(x); } \
VC_MATH_UNARY_FUNCTION(Abs, abs)
VC_MATH_UNARY_FUNCTION(Exp, exp)
VC_MATH_UNARY_FUNCTION(Log, log)
VC_MATH_UNARY_FUNCTION(Log2, log2)
VC_MATH_UNARY_FUNCTION(Log10, log10)
VC_MATH_UNARY_FUNCTION(Sqrt, sqrt)
VC_MATH_UNARY_FUNCTION(Rsqrt, rsqrt)
VC_MATH_UNARY_FUNCTION(Sin, sin)
VC_MATH_UNARY_FUNCTION(Cos, cos)
VC_MATH_UNARY_FUNCTION(ASin, asin)
// VC_MATH_UNARY_FUNCTION(ATan, atan) // slower than std::atan()
// VC_MATH_UNARY_FUNCTION(Floor, floor) // broken
// VC_MATH_UNARY_FUNCTION(Ceil, ceil) // broken
// VC_MATH_UNARY_FUNCTION(Trunc, trunc) // broken
#undef VC_MATH_UNARY_FUNCTION
template <typename T, class Abi>
VECCORE_FORCE_INLINE
Vc::Vector<T, Abi> Tan(const Vc::Vector<T, Abi> &x)
{
Vc::Vector<T, Abi> s, c;
Vc::sincos(x, &s, &c);
return s / c;
}
template <typename T, class Abi>
VECCORE_FORCE_INLINE
Vc::Mask<T, Abi> IsInf(const Vc::Vector<T, Abi> &x)
{
return Vc::isinf(x);
}
}
} // namespace vecCore
#endif
|