Project
Loading...
Searching...
No Matches
VcShim.h
Go to the documentation of this file.
1// Copyright 2020-2025 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
17#ifndef GPU_UTILS_VCSHIM_H
18#define GPU_UTILS_VCSHIM_H
19
20#ifndef GPUCA_NO_VC
21
22#include <Vc/Vc> // IWYU pragma: export
23
24#else
25
26#include <algorithm>
27#include <array>
28#include <bitset>
29#include <cstddef>
30#include <type_traits>
31
32namespace Vc
33{
34
35constexpr struct VectorSpecialInitializerZero {
36} Zero;
37constexpr struct AlignedTag {
38} Aligned;
39
40template <typename T>
41typename T::vector_type& internal_data(T& v)
42{
43 return v.mData;
44}
45
46template <typename T>
47const typename T::vector_type& internal_data(const T& v)
48{
49 return v.mData;
50}
51
52namespace Common
53{
54
55template <typename V, typename M>
56class WriteMaskVector
57{
58 private:
59 const M& mMask;
60 V& mVec;
61
62 public:
63 using vector_type = V;
64 using value_type = typename V::value_type;
65
66 WriteMaskVector(V& v, const M& m) : mMask(m), mVec(v) {}
67
68 WriteMaskVector& operator++(int)
69 {
70 for (size_t i = 0; i < mVec.size(); i++)
71 mVec[i] += value_type(mMask[i]);
72 return *this;
73 }
74
75 WriteMaskVector& operator=(const value_type& v)
76 {
77 for (size_t i = 0; i < mVec.size(); i++) {
78 if (mMask[i])
79 mVec[i] = v;
80 }
81 return *this;
82 }
83
84 WriteMaskVector& operator=(const vector_type& v)
85 {
86 for (size_t i = 0; i < mVec.size(); i++) {
87 if (mMask[i])
88 mVec[i] = v[i];
89 }
90 return *this;
91 }
92};
93
94inline void prefetchMid(const void*) {}
95inline void prefetchFar(const void*) {}
96inline void prefetchForOneRead(const void*) {}
97
98} // namespace Common
99
100template <size_t N>
101class fixed_size_simd_mask
102{
103 private:
104 std::bitset<N> mData;
105
106 public:
107 bool isNotEmpty() const { return mData.any(); }
108
109 typename std::bitset<N>::reference operator[](size_t i) { return mData[i]; }
110 bool operator[](size_t i) const { return mData[i]; }
111
112 fixed_size_simd_mask operator!() const
113 {
114 auto o = *this;
115 o.mData.flip();
116 return o;
117 }
118
119 fixed_size_simd_mask operator&&(const fixed_size_simd_mask& o) const
120 {
121 auto r = *this;
122 r.mData &= o.mData;
123 return r;
124 }
125};
126
127template <typename T, size_t N>
128class fixed_size_simd
129{
130 private:
131 std::array<T, N> mData;
132
133 public:
134 using vector_type = std::array<T, N>;
135 using value_type = T;
136 using mask_type = fixed_size_simd_mask<N>;
137
138 static constexpr size_t size() { return N; }
139
140 fixed_size_simd() = default;
141 explicit fixed_size_simd(VectorSpecialInitializerZero) { mData = {}; }
142
143 template <typename U>
144 fixed_size_simd(const fixed_size_simd<U, N>& w)
145 {
146 std::copy_n(internal_data(w).begin(), N, mData.begin());
147 }
148
149 fixed_size_simd(const T* d, AlignedTag) { std::copy_n(d, N, mData.begin()); }
150
151 fixed_size_simd(const T& x) { mData.fill(x); }
152
153 T& operator[](size_t i) { return mData[i]; }
154 const T& operator[](size_t i) const { return mData[i]; }
155
156 Common::WriteMaskVector<fixed_size_simd, mask_type> operator()(const mask_type& m) { return {*this, m}; }
157
158 fixed_size_simd& operator=(const T& v)
159 {
160 for (auto& x : mData)
161 x = v;
162 return *this;
163 }
164
165 fixed_size_simd& operator+=(const T& v)
166 {
167 for (auto& x : mData)
168 x += v;
169 return *this;
170 }
171
172 template <typename U>
173 fixed_size_simd& operator+=(const fixed_size_simd<U, N>& v)
174 {
175 for (size_t i = 0; i < N; i++)
176 mData[i] += v[i];
177 return *this;
178 }
179
180 fixed_size_simd& operator-=(const T& v)
181 {
182 for (auto& x : mData)
183 x -= v;
184 return *this;
185 }
186
187 template <typename U>
188 fixed_size_simd& operator-=(const fixed_size_simd<U, N>& v)
189 {
190 for (size_t i = 0; i < N; i++)
191 mData[i] -= v[i];
192 return *this;
193 }
194
195 fixed_size_simd& operator*=(const T& v)
196 {
197 for (auto& x : mData)
198 x *= v;
199 return *this;
200 }
201
202 template <typename U>
203 fixed_size_simd& operator*=(const fixed_size_simd<U, N>& v)
204 {
205 for (size_t i = 0; i < N; i++)
206 mData[i] *= v[i];
207 return *this;
208 }
209
210 fixed_size_simd& operator/=(const T& v)
211 {
212 for (auto& x : mData)
213 x /= v;
214 return *this;
215 }
216
217 template <typename U>
218 fixed_size_simd& operator/=(const fixed_size_simd<U, N>& v)
219 {
220 for (size_t i = 0; i < N; i++)
221 mData[i] /= v[i];
222 return *this;
223 }
224
225 mask_type operator==(const T& v) const
226 {
227 mask_type m;
228 for (size_t i = 0; i < N; i++)
229 m[i] = mData[i] == v;
230 return m;
231 }
232
233 mask_type operator!=(const T& v) const { return !(*this == v); }
234
235 mask_type operator>(const T& v) const
236 {
237 mask_type m;
238 for (size_t i = 0; i < N; i++)
239 m[i] = mData[i] > v;
240 return m;
241 }
242
243 mask_type operator>=(const T& v) const
244 {
245 mask_type m;
246 for (size_t i = 0; i < N; i++)
247 m[i] = mData[i] >= v;
248 return m;
249 }
250
251 mask_type operator<(const T& v) const
252 {
253 mask_type m;
254 for (size_t i = 0; i < N; i++)
255 m[i] = mData[i] < v;
256 return m;
257 }
258
259 friend vector_type& internal_data<>(fixed_size_simd& x);
260 friend const vector_type& internal_data<>(const fixed_size_simd& x);
261};
262
263template <typename>
264struct is_fixed_size_simd : std::false_type {
265};
266
267template <typename T, size_t N>
268struct is_fixed_size_simd<fixed_size_simd<T, N>> : std::true_type {
269};
270
271template <typename S, typename T>
272using EnableIfScalar = typename std::enable_if_t<
273 !is_fixed_size_simd<typename std::decay_t<S>>::value && std::is_convertible_v<S, T>, int>;
274
275template <typename T, typename U, size_t N>
276fixed_size_simd<T, N> operator+(fixed_size_simd<T, N> a, const fixed_size_simd<U, N>& b)
277{
278 return a += b;
279}
280
281template <typename T, size_t N, typename S, EnableIfScalar<S, T> = 0>
282fixed_size_simd<T, N> operator+(fixed_size_simd<T, N> a, const S& b)
283{
284 return a += static_cast<T>(b);
285}
286
287template <typename S, typename T, size_t N, EnableIfScalar<S, T> = 0>
288fixed_size_simd<T, N> operator+(const S& a, fixed_size_simd<T, N> b)
289{
290 return b += static_cast<T>(a);
291}
292
293template <typename T, typename U, size_t N>
294fixed_size_simd<T, N> operator-(fixed_size_simd<T, N> a, const fixed_size_simd<U, N>& b)
295{
296 return a -= b;
297}
298
299template <typename T, size_t N, typename S, EnableIfScalar<S, T> = 0>
300fixed_size_simd<T, N> operator-(fixed_size_simd<T, N> a, const S& b)
301{
302 return a -= static_cast<T>(b);
303}
304
305template <typename S, typename T, size_t N, EnableIfScalar<S, T> = 0>
306fixed_size_simd<T, N> operator-(const S& a, const fixed_size_simd<T, N>& b)
307{
308 fixed_size_simd<T, N> o;
309 for (size_t i = 0; i < N; i++)
310 o[i] = static_cast<T>(a) - b[i];
311 return o;
312}
313
314template <typename T, typename U, size_t N>
315fixed_size_simd<T, N> operator*(fixed_size_simd<T, N> a, const fixed_size_simd<U, N>& b)
316{
317 return a *= b;
318}
319
320template <typename T, size_t N, typename S, EnableIfScalar<S, T> = 0>
321fixed_size_simd<T, N> operator*(fixed_size_simd<T, N> a, const S& b)
322{
323 return a *= static_cast<T>(b);
324}
325
326template <typename S, typename T, size_t N, EnableIfScalar<S, T> = 0>
327fixed_size_simd<T, N> operator*(const S& a, fixed_size_simd<T, N> b)
328{
329 return b *= static_cast<T>(a);
330}
331
332template <typename T, typename U, size_t N>
333fixed_size_simd<T, N> operator/(fixed_size_simd<T, N> a, const fixed_size_simd<U, N>& b)
334{
335 return a /= b;
336}
337
338template <typename T, size_t N, typename S, EnableIfScalar<S, T> = 0>
339fixed_size_simd<T, N> operator/(fixed_size_simd<T, N> a, const S& b)
340{
341 return a /= static_cast<T>(b);
342}
343
344template <typename S, typename T, size_t N, EnableIfScalar<S, T> = 0>
345fixed_size_simd<T, N> operator/(const S& a, const fixed_size_simd<T, N>& b)
346{
347 fixed_size_simd<T, N> o;
348 for (size_t i = 0; i < N; i++)
349 o[i] = static_cast<T>(a) / b[i];
350 return o;
351}
352
353template <typename V>
354V max(const V& a, const V& b)
355{
356 V o;
357 for (size_t i = 0; i < a.size(); i++)
358 o[i] = std::max(a[i], b[i]);
359 return o;
360}
361
362} // namespace Vc
363
364#endif // ifndef GPUCA_NO_VC
365
366#endif
Hit operator+(const Hit &lhs, const Hit &rhs)
Definition Hit.cxx:46
int32_t i
GLint GLenum GLint x
Definition glcorearb.h:403
const GLfloat * m
Definition glcorearb.h:4066
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei const GLfloat * value
Definition glcorearb.h:819
GLboolean r
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
auto operator+=(std::string &lhs, StringRef rhs) -> std::string &
bool operator<(EntryPM const &entryPM1, EntryPM const &entryPM2)
Definition LookUpTable.h:91
constexpr int Zero
MultPolicyGPU< T, R1, R2 >::RepType operator*(const SMatrixGPU< T, D1, D, R1 > &lhs, const SMatrixGPU< T, D, D2, R2 > &rhs)
Definition SMatrixGPU.h:750
Vertex< T > operator-(const Vertex< T > &a, const Vertex< T > &b)
Definition Vertex.h:98
bool operator>=(const DsChannelId &a, const DsChannelId &b)
Definition DsChannelId.h:70
bool operator>(const DsChannelId &a, const DsChannelId &b)
Definition DsChannelId.h:68
bool operator!=(const DsChannelId &a, const DsChannelId &b)
Definition DsChannelId.h:66
Enum< T >::Iterator begin(Enum< T >)
Definition Defs.h:156
bool operator==(const CoarseLocation &a, const CoarseLocation &b)
constexpr size_t max