File: VcVector.h

package info (click to toggle)
veccore 0.8.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 13,968 kB
  • sloc: cpp: 2,894; ansic: 1,332; makefile: 2
file content (168 lines) | stat: -rw-r--r-- 4,217 bytes parent folder | download | duplicates (3)
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