Project
Loading...
Searching...
No Matches
GPUCommonMath.h
Go to the documentation of this file.
1// Copyright 2019-2020 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
14
15#ifndef GPUCOMMONMATH_H
16#define GPUCOMMONMATH_H
17
18#include "GPUCommonDef.h"
19
20#if defined(__CUDACC__) && !defined(__clang__) && !defined(GPUCA_GPUCODE_COMPILEKERNELS) && !defined(GPUCA_GPUCODE_HOSTONLY)
21#include <sm_20_atomic_functions.h>
22#endif
23
24#if !defined(GPUCA_GPUCODE_DEVICE)
25#include <cmath>
26#include <algorithm>
27#include <atomic>
28#include <limits>
29#include <cstring>
30#endif
31
32#if !defined(GPUCA_GPUCODE_COMPILEKERNELS) && (!defined(GPUCA_GPUCODE_DEVICE) || defined(__CUDACC__) || defined(__HIPCC__))
33#include <cstdint>
34#endif
35
36// GPUCA_CHOICE Syntax: GPUCA_CHOICE(Host, CUDA&HIP, OpenCL&Metal)
37#if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__)) // clang-format off
38 #define GPUCA_CHOICE(c1, c2, c3) (c2) // Select second option for CUDA and HIP
39#elif defined(GPUCA_GPUCODE_DEVICE) && (defined(__OPENCL__) || defined(__METAL__))
40 #define GPUCA_CHOICE(c1, c2, c3) (c3) // Select third option for OpenCL and Metal
41#else
42 #define GPUCA_CHOICE(c1, c2, c3) (c1) // Select first option for Host
43#endif // clang-format on
44
45namespace o2::gpu
46{
47
49{
50 public:
51 GPUd() static float2 MakeFloat2(float x, float y); // TODO: Find better appraoch that is constexpr
52
53 template <class T>
54 GPUhd() constexpr static T Min(const T x, const T y)
55 {
56 return GPUCA_CHOICE(std::min(x, y), min(x, y), min(x, y));
57 }
58 template <class T>
59 GPUhd() constexpr static T Max(const T x, const T y)
60 {
61 return GPUCA_CHOICE(std::max(x, y), max(x, y), max(x, y));
62 }
63 template <class T, class S, class R>
64 GPUd() static T MinWithRef(T x, T y, S refX, S refY, R& r);
65 template <class T, class S, class R>
66 GPUd() static T MaxWithRef(T x, T y, S refX, S refY, R& r);
67 template <class T, class S, class R>
68 GPUd() static T MaxWithRef(T x, T y, T z, T w, S refX, S refY, S refZ, S refW, R& r);
69 template <class T>
70 GPUdi() constexpr static T Clamp(const T v, const T lo, const T hi)
71 {
72 return Max(lo, Min(v, hi));
73 }
74 GPUhdni() constexpr static float Sqrt(float x);
75 GPUd() constexpr static double Sqrtd(double x);
76 GPUd() static float InvSqrt(float x);
77 template <class T>
78 GPUdi() constexpr static T Square(T x)
79 {
80 return x * x;
81 }
82 template <class T>
83 GPUhd() constexpr static T Abs(T x);
84 GPUd() constexpr static float ASin(float x);
85 GPUd() constexpr static double ASind(double x);
86 GPUd() constexpr static float ACos(float x);
87 GPUd() constexpr static double ACosd(double x);
88 GPUd() constexpr static float ATan(float x);
89 GPUd() constexpr static double ATand(double x);
90 GPUhd() constexpr static float ATan2(float y, float x);
91 GPUd() constexpr static double ATan2d(double y, double x);
92 GPUd() constexpr static float Sin(float x);
93 GPUd() constexpr static double Sind(double x);
94 GPUd() constexpr static float Cos(float x);
95 GPUd() constexpr static double Cosd(double x);
96 GPUhdni() static void SinCos(float x, float& s, float& c);
97 GPUhdni() static void SinCosd(double x, double& s, double& c);
98 GPUd() constexpr static float Tan(float x);
99 GPUd() constexpr static double Tand(double x);
100 GPUd() constexpr static float Pow(float x, float y);
101 GPUd() constexpr static float Log(float x);
102 GPUd() constexpr static double Logd(double x);
103 GPUd() constexpr static float Exp(float x);
104 GPUd() constexpr static double Expd(double x);
105 GPUhdni() constexpr static float Copysign(float x, float y) { return GPUCA_CHOICE(std::copysignf(x, y), copysignf(x, y), copysign(x, y)); }
106 GPUd() constexpr static double Copysignd(double x, double y);
107 GPUd() constexpr static float TwoPi() { return 6.2831853f; }
108 GPUd() constexpr static float Pi() { return 3.1415927f; }
109 GPUd() constexpr static float Round(float x);
110 GPUd() constexpr static float Floor(float x) { return GPUCA_CHOICE(floorf(x), floorf(x), floor(x)); }
111 GPUd() static uint32_t Float2UIntReint(const float& x);
112 GPUd() constexpr static uint32_t Float2UIntRn(float x) { return (uint32_t)(int32_t)(x + 0.5f); }
113 GPUd() constexpr static int32_t Float2IntRn(float x);
114 GPUd() constexpr static float Modf(float x, float y);
115 GPUhdi() static float Remainderf(float x, float y);
116 GPUd() constexpr static bool Finite(float x);
117 GPUd() constexpr static bool IsNaN(float x);
118#ifndef __FAST_MATH__
119 GPUd() constexpr static float QuietNaN() { return GPUCA_CHOICE(std::numeric_limits<float>::quiet_NaN(), __builtin_nanf(""), NAN); }
120#endif
121 GPUd() constexpr static uint32_t Clz(uint32_t val);
122 GPUd() constexpr static uint32_t Ctz(uint32_t val);
123 GPUd() constexpr static uint32_t Popcount(uint32_t val);
124 GPUd() constexpr static uint32_t Clz64(uint64_t val);
125 GPUd() constexpr static uint32_t Ctz64(uint64_t val);
126 GPUd() constexpr static uint32_t Popcount64(uint64_t val);
127
128 GPUd() static void memcpy(void* dst, const void* src, size_t size);
129
130 GPUhdi() constexpr static float Hypot(float x, float y) { return Sqrt(x * x + y * y); }
131 GPUhdi() constexpr static float Hypot(float x, float y, float z) { return Sqrt(x * x + y * y + z * z); }
132 GPUhdi() constexpr static float Hypot(float x, float y, float z, float w) { return Sqrt(x * x + y * y + z * z + w * w); }
133
134 template <typename T>
135 GPUhd() constexpr static void Swap(T& a, T& b);
136
137 template <class T>
138 GPUdi() static T AtomicExch(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val)
139 {
140 return GPUCommonMath::AtomicExchInternal(addr, val);
141 }
142
143 template <class T>
144 GPUdi() static bool AtomicCAS(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T cmp, T val)
145 {
146 return GPUCommonMath::AtomicCASInternal(addr, cmp, val);
147 }
148
149 template <class T>
150 GPUdi() static T AtomicAdd(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val)
151 {
152 return GPUCommonMath::AtomicAddInternal(addr, val);
153 }
154 template <class T>
155 GPUdi() static void AtomicMax(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val)
156 {
157 GPUCommonMath::AtomicMaxInternal(addr, val);
158 }
159 template <class T>
160 GPUdi() static void AtomicMin(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val)
161 {
162 GPUCommonMath::AtomicMinInternal(addr, val);
163 }
164 template <class T>
165 GPUdi() static T AtomicLoad(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr)
166 {
167 return GPUCommonMath::AtomicLoadInternal<T>(addr);
168 }
169 template <class T>
170 GPUdi() static void AtomicStore(GPUglobalref() GPUgeneric() GPUAtomic(T) * addr, T val)
171 {
172 GPUCommonMath::AtomicStoreInternal(addr, val);
173 }
174 template <class T>
175 GPUdi() static T AtomicExchShared(GPUsharedref() GPUgeneric() GPUAtomic(T) * addr, T val)
176 {
177 return GPUCommonMath::AtomicExchInternal(addr, val);
178 }
179 template <class T>
180 GPUdi() static T AtomicAddShared(GPUsharedref() GPUgeneric() GPUAtomic(T) * addr, T val)
181 {
182 return GPUCommonMath::AtomicAddInternal(addr, val);
183 }
184 template <class T>
185 GPUdi() static void AtomicMaxShared(GPUsharedref() GPUgeneric() GPUAtomic(T) * addr, T val)
186 {
187 GPUCommonMath::AtomicMaxInternal(addr, val);
188 }
189 template <class T>
190 GPUdi() static void AtomicMinShared(GPUsharedref() GPUgeneric() GPUAtomic(T) * addr, T val)
191 {
192 GPUCommonMath::AtomicMinInternal(addr, val);
193 }
194 GPUd() constexpr static int32_t Mul24(int32_t a, int32_t b);
195 GPUd() constexpr static float FMulRZ(float a, float b);
196
197 template <int32_t I, class T>
198 GPUd() constexpr static T nextMultipleOf(T val);
199
200 template <typename... Args>
201 GPUhdni() constexpr static float Sum2(float w, Args... args);
202
203 private:
204 template <class S, class T>
205 GPUd() static uint32_t AtomicExchInternal(S* addr, T val);
206 template <class S, class T>
207 GPUd() static bool AtomicCASInternal(S* addr, T cmp, T val);
208 template <class S, class T>
209 GPUd() static uint32_t AtomicAddInternal(S* addr, T val);
210 template <class S, class T>
211 GPUd() static void AtomicMaxInternal(S* addr, T val);
212 template <class S, class T>
213 GPUd() static void AtomicMinInternal(S* addr, T val);
214 template <class T, class S>
215 GPUd() static T AtomicLoadInternal(S* addr);
216 template <class S, class T>
217 GPUd() static void AtomicStoreInternal(S* addr, T val);
218};
219
221
222template <typename... Args>
223GPUhdi() constexpr float GPUCommonMath::Sum2(float w, Args... args)
224{
225 if constexpr (sizeof...(Args) == 0) {
226 return w * w;
227 } else {
228 return w * w + Sum2(args...);
229 }
230 return 0;
231}
232
233GPUdi() void GPUCommonMath::memcpy(void* dst, const void* src, size_t size)
234{
235#ifndef GPUCA_GPUCODE_DEVICE
236 std::memcpy(dst, src, size);
237#elif defined(__CUDACC__) || defined(__HIPCC__)
238 ::memcpy(dst, src, size);
239#elif defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
240 __builtin_memcpy(dst, src, size);
241#else
242 char* d = (char*)dst;
243 const char* s = (const char*)src;
244 for (size_t i = 0; i < size; i++) {
245 d[i] = s[i];
246 }
247#endif
248}
249
250template <int32_t I, class T>
251GPUdi() constexpr T GPUCommonMath::nextMultipleOf(T val)
252{
253 if constexpr (I & (I - 1)) {
254 T tmp = val % I;
255 if (tmp) {
256 val += I - tmp;
257 }
258 return val;
259 } else {
260 return (val + I - 1) & ~(T)(I - 1);
261 }
262 return 0; // BUG: Cuda complains about missing return value with constexpr if
263}
264
265GPUdi() float2 GPUCommonMath::MakeFloat2(float x, float y)
266{
267#if !defined(GPUCA_GPUCODE) || defined(__OPENCL__) || defined(__OPENCL_HOST__) || defined(__METAL__) || defined(__METAL_HOST__) || defined(__CPUDEVICE__)
268 float2 ret = {x, y};
269 return ret;
270#else
271 return make_float2(x, y);
272#endif // GPUCA_GPUCODE
273}
274
275GPUdi() constexpr float GPUCommonMath::Modf(float x, float y) { return GPUCA_CHOICE(fmodf(x, y), fmodf(x, y), fmod(x, y)); }
276GPUhdi() float GPUCommonMath::Remainderf(float x, float y)
277{
278#ifdef __METAL__ // MSL has no remainder(), so reduce with fmod, which is exact
279 const float r = fmod(x, y), h = 0.5f * fabs(y), a = fabs(r);
280 if (a > h) {
281 return r - copysign(y, r);
282 }
283 if (a == h && fmod((x - r) / y, 2.f) != 0.f) { // the quotient of a tie is rounded to even
284 return r - copysign(y, r);
285 }
286 return r;
287#else
288 return GPUCA_CHOICE(std::remainderf(x, y), remainderf(x, y), remainder(x, y));
289#endif
290}
291
292GPUdi() uint32_t GPUCommonMath::Float2UIntReint(const float& x)
293{
294#if defined(GPUCA_GPUCODE_DEVICE) && (defined(__CUDACC__) || defined(__HIPCC__))
295 return __float_as_uint(x);
296#elif defined(GPUCA_GPUCODE_DEVICE) && defined(__OPENCL__)
297 return as_uint(x);
298#elif !defined(GPUCA_GPUCODE_DEVICE)
299 return __builtin_bit_cast(uint32_t, x);
300#else
301 return reinterpret_cast<const uint32_t&>(x);
302#endif
303}
304
305GPUCA_DETERMINISTIC_CODE( // clang-format off
306GPUdi() constexpr float GPUCommonMath::Round(float x) { return GPUCA_CHOICE(roundf(x), roundf(x), round(x)); }
307GPUdi() constexpr int32_t GPUCommonMath::Float2IntRn(float x) { return (int32_t)Round(x); }
308GPUhdi() constexpr float GPUCommonMath::Sqrt(float x) { return GPUCA_CHOICE(sqrtf(x), (float)sqrt((double)x), sqrt(x)); }
309GPUdi() constexpr float GPUCommonMath::ATan(float x) { return GPUCA_CHOICE((float)atan((double)x), (float)atan((double)x), atan(x)); }
310GPUhdi() constexpr float GPUCommonMath::ATan2(float y, float x) { return GPUCA_CHOICE((float)atan2((double)y, (double)x), (float)atan2((double)y, (double)x), atan2(y, x)); }
311GPUdi() constexpr float GPUCommonMath::Sin(float x) { return GPUCA_CHOICE((float)sin((double)x), (float)sin((double)x), sin(x)); }
312GPUdi() constexpr float GPUCommonMath::Cos(float x) { return GPUCA_CHOICE((float)cos((double)x), (float)cos((double)x), cos(x)); }
313GPUdi() constexpr float GPUCommonMath::Tan(float x) { return GPUCA_CHOICE((float)tanf((double)x), (float)tanf((double)x), tan(x)); }
314GPUdi() constexpr float GPUCommonMath::Pow(float x, float y) { return GPUCA_CHOICE((float)pow((double)x, (double)y), pow((double)x, (double)y), pow(x, y)); }
315GPUdi() constexpr float GPUCommonMath::ASin(float x) { return GPUCA_CHOICE((float)asin((double)x), (float)asin((double)x), asin(x)); }
316GPUdi() constexpr float GPUCommonMath::ACos(float x) { return GPUCA_CHOICE((float)acos((double)x), (float)acos((double)x), acos(x)); }
317GPUdi() constexpr float GPUCommonMath::Log(float x) { return GPUCA_CHOICE((float)log((double)x), (float)log((double)x), log(x)); }
318GPUdi() constexpr float GPUCommonMath::Exp(float x) { return GPUCA_CHOICE((float)exp((double)x), (float)exp((double)x), exp(x)); }
319GPUdi() constexpr bool GPUCommonMath::Finite(float x) { return GPUCA_CHOICE(std::isfinite(x), isfinite(x), isfinite(x)); }
320GPUdi() constexpr bool GPUCommonMath::IsNaN(float x) { return GPUCA_CHOICE(std::isnan(x), isnan(x), isnan(x)); }
321, // !GPUCA_DETERMINISTIC_CODE
322GPUdi() constexpr float GPUCommonMath::Round(float x) { return GPUCA_CHOICE(roundf(x), rintf(x), rint(x)); }
323GPUdi() constexpr int32_t GPUCommonMath::Float2IntRn(float x) { return GPUCA_CHOICE((int32_t)Round(x), __float2int_rn(x), (int32_t)Round(x)); }
324GPUhdi() constexpr float GPUCommonMath::Sqrt(float x) { return GPUCA_CHOICE(sqrtf(x), sqrtf(x), sqrt(x)); }
325GPUdi() constexpr float GPUCommonMath::ATan(float x) { return GPUCA_CHOICE(atanf(x), atanf(x), atan(x)); }
326GPUhdi() constexpr float GPUCommonMath::ATan2(float y, float x) { return GPUCA_CHOICE(atan2f(y, x), atan2f(y, x), atan2(y, x)); }
327GPUdi() constexpr float GPUCommonMath::Sin(float x) { return GPUCA_CHOICE(sinf(x), sinf(x), sin(x)); }
328GPUdi() constexpr float GPUCommonMath::Cos(float x) { return GPUCA_CHOICE(cosf(x), cosf(x), cos(x)); }
329GPUdi() constexpr float GPUCommonMath::Tan(float x) { return GPUCA_CHOICE(tanf(x), tanf(x), tan(x)); }
330GPUdi() constexpr float GPUCommonMath::Pow(float x, float y) { return GPUCA_CHOICE(powf(x, y), powf(x, y), pow(x, y)); }
331GPUdi() constexpr float GPUCommonMath::ASin(float x) { return GPUCA_CHOICE(asinf(x), asinf(x), asin(x)); }
332GPUdi() constexpr float GPUCommonMath::ACos(float x) { return GPUCA_CHOICE(acosf(x), acosf(x), acos(x)); }
333GPUdi() constexpr float GPUCommonMath::Log(float x) { return GPUCA_CHOICE(logf(x), logf(x), log(x)); }
334GPUdi() constexpr float GPUCommonMath::Exp(float x) { return GPUCA_CHOICE(expf(x), expf(x), exp(x)); }
335GPUdi() constexpr bool GPUCommonMath::Finite(float x) { return true; }
336GPUdi() constexpr bool GPUCommonMath::IsNaN(float x) { return false; }
337) // clang-format on
338
339GPUhdi() void GPUCommonMath::SinCos(float x, float& s, float& c)
340{
341 GPUCA_DETERMINISTIC_CODE( // clang-format off
342 s = sin((double)x);
343 c = cos((double)x);
344 , // !GPUCA_DETERMINISTIC_CODE
345#if !defined(GPUCA_GPUCODE_DEVICE) && defined(__APPLE__)
346 __sincosf(x, &s, &c);
347#elif !defined(GPUCA_GPUCODE_DEVICE) && (defined(__GNU_SOURCE__) || defined(_GNU_SOURCE) || defined(GPUCA_GPUCODE))
348 sincosf(x, &s, &c);
349#elif defined(__METAL__) // MSL's sincos returns sin and takes cos by thread
350 // reference, so it cannot write through a generic one
351 float metalCos;
352 s = sincos(x, metalCos);
353 c = metalCos;
354#else
355 GPUCA_CHOICE((void)((s = sinf(x)) + (c = cosf(x))), sincosf(x, &s, &c), s = sincos(x, &c));
356#endif
357 ) // clang-format on
358}
359
360#ifndef __METAL__ // MSL has no double; math_utils::sincosd is excluded there, as it is for OpenCL
361GPUhdi() void GPUCommonMath::SinCosd(double x, double& s, double& c)
362{
363#if !defined(GPUCA_GPUCODE_DEVICE) && defined(__APPLE__)
364 __sincos(x, &s, &c);
365#elif !defined(GPUCA_GPUCODE_DEVICE) && (defined(__GNU_SOURCE__) || defined(_GNU_SOURCE) || defined(GPUCA_GPUCODE))
366 sincos(x, &s, &c);
367#else
368 GPUCA_CHOICE((void)((s = sin(x)) + (c = cos(x))), sincos(x, &s, &c), s = sincos(x, &c));
369#endif
370}
371
372GPUdi() constexpr double GPUCommonMath::Sqrtd(double x) { return GPUCA_CHOICE(std::sqrt(x), sqrt(x), sqrt(x)); }
373GPUdi() constexpr double GPUCommonMath::ASind(double x) { return GPUCA_CHOICE(std::asin(x), asin(x), asin(x)); }
374GPUdi() constexpr double GPUCommonMath::ACosd(double x) { return GPUCA_CHOICE(std::acos(x), acos(x), acos(x)); }
375GPUdi() constexpr double GPUCommonMath::ATand(double x) { return GPUCA_CHOICE(std::atan(x), atan(x), atan(x)); }
376GPUdi() constexpr double GPUCommonMath::ATan2d(double y, double x) { return GPUCA_CHOICE(std::atan2(y, x), atan2(y, x), atan2(y, x)); }
377GPUdi() constexpr double GPUCommonMath::Sind(double x) { return GPUCA_CHOICE(std::sin(x), sin(x), sin(x)); }
378GPUdi() constexpr double GPUCommonMath::Cosd(double x) { return GPUCA_CHOICE(std::cos(x), cos(x), cos(x)); }
379GPUdi() constexpr double GPUCommonMath::Tand(double x) { return GPUCA_CHOICE(std::tan(x), tan(x), tan(x)); }
380GPUdi() constexpr double GPUCommonMath::Logd(double x) { return GPUCA_CHOICE(std::log(x), log(x), log(x)); }
381GPUdi() constexpr double GPUCommonMath::Expd(double x) { return GPUCA_CHOICE(std::exp(x), exp(x), exp(x)); }
382GPUdi() constexpr double GPUCommonMath::Copysignd(double x, double y) { return GPUCA_CHOICE(std::copysign(x, y), copysign(x, y), copysign(x, y)); }
383#endif
384
385GPUdi() constexpr uint32_t GPUCommonMath::Clz(uint32_t x)
386{
387#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__))
388 return x == 0 ? 32 : GPUCA_CHOICE(__builtin_clz(x), __clz(x), __builtin_clz(x)); // use builtin if available
389#else
390 for (int32_t i = 31; i >= 0; i--) {
391 if (x & (1u << i)) {
392 return (31 - i);
393 }
394 }
395 return 32;
396#endif
397}
398
399GPUdi() constexpr uint32_t GPUCommonMath::Ctz(uint32_t x)
400{
401#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__))
402 return x == 0 ? 32 : GPUCA_CHOICE(__builtin_ctz(x), __ffs(x) - 1, __builtin_ctz(x));
403#else
404 for (uint32_t i = 0; i < 32; ++i) {
405 if (x & (1u << i)) {
406 return i;
407 }
408 }
409 return 32;
410#endif
411}
412
413GPUdi() constexpr uint32_t GPUCommonMath::Popcount(uint32_t x)
414{
415#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && !defined(__OPENCL__) // TODO: remove OPENCL when reported SPIR-V bug is fixed
416 // use builtin if available
417 return GPUCA_CHOICE(__builtin_popcount(x), __popc(x), __builtin_popcount(x));
418#else
419 x = x - ((x >> 1) & 0x55555555);
420 x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
421 return (((x + (x >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
422#endif
423}
424
425GPUdi() constexpr uint32_t GPUCommonMath::Clz64(uint64_t x)
426{
427#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__))
428 return x == 0 ? 64 : GPUCA_CHOICE(__builtin_clzll(x), __clzll(x), __builtin_clzll(x)); // use builtin if available
429#else
430 for (int32_t i = 63; i >= 0; i--) {
431 if (x & (1ull << i)) {
432 return (63 - i);
433 }
434 }
435 return 64;
436#endif
437}
438
439GPUdi() constexpr uint32_t GPUCommonMath::Ctz64(uint64_t x)
440{
441#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__))
442 return x == 0 ? 64 : GPUCA_CHOICE(__builtin_ctzll(x), __ffsll((long long)x) - 1, __builtin_ctzll(x));
443#else
444 for (uint32_t i = 0; i < 64; ++i) {
445 if (x & (1ull << i)) {
446 return i;
447 }
448 }
449 return 64;
450#endif
451}
452
453GPUdi() constexpr uint32_t GPUCommonMath::Popcount64(uint64_t x)
454{
455#if (defined(__GNUC__) || defined(__clang__) || defined(__CUDACC__) || defined(__HIPCC__)) && !defined(__OPENCL__) // TODO: remove OPENCL when reported SPIR-V bug is fixed
456 // use builtin if available
457 return GPUCA_CHOICE(__builtin_popcountll(x), __popcll(x), __builtin_popcountll(x));
458#else
459 return Popcount((uint32_t)x) + Popcount((uint32_t)(x >> 32));
460#endif
461}
462
463template <typename T>
464GPUhdi() constexpr void GPUCommonMath::Swap(T& a, T& b)
465{
466#ifndef GPUCA_GPUCODE_DEVICE
467 std::swap(a, b);
468#else
469 T tmp = a;
470 a = b;
471 b = tmp;
472#endif
473}
474
475template <class T, class S, class R>
476GPUdi() T GPUCommonMath::MinWithRef(T x, T y, S refX, S refY, R& r)
477{
478 if (x < y) {
479 r = refX;
480 return x;
481 }
482 r = refY;
483 return y;
484}
485
486template <class T, class S, class R>
487GPUdi() T GPUCommonMath::MaxWithRef(T x, T y, S refX, S refY, R& r)
488{
489 if (x > y) {
490 r = refX;
491 return x;
492 }
493 r = refY;
494 return y;
495}
496
497template <class T, class S, class R>
498GPUdi() T GPUCommonMath::MaxWithRef(T x, T y, T z, T w, S refX, S refY, S refZ, S refW, R& r)
499{
500 T retVal = x;
501 S retRef = refX;
502 if (y > retVal) {
503 retVal = y;
504 retRef = refY;
505 }
506 if (z > retVal) {
507 retVal = z;
508 retRef = refZ;
509 }
510 if (w > retVal) {
511 retVal = w;
512 retRef = refW;
513 }
514 r = retRef;
515 return retVal;
516}
517
518GPUdi() float GPUCommonMath::InvSqrt(float _x)
519{
520 GPUCA_DETERMINISTIC_CODE( // clang-format off
521 return 1.f / Sqrt(_x);
522 , // !GPUCA_DETERMINISTIC_CODE
523#if defined(__CUDACC__) || defined(__HIPCC__)
524 return __frsqrt_rn(_x);
525#elif (defined(__OPENCL__) || defined(__METAL__)) && defined(__clang__)
526 return 1.f / sqrt(_x);
527#elif !defined(__OPENCL__) && (defined(__FAST_MATH__) || defined(__clang__))
528 return 1.f / sqrtf(_x);
529#else
530 union {
531 float f;
532 int32_t i;
533 } x = {_x};
534 const float xhalf = 0.5f * x.f;
535 x.i = 0x5f3759df - (x.i >> 1);
536 x.f = x.f * (1.5f - xhalf * x.f * x.f);
537 return x.f;
538#endif
539 ) // clang-format on
540}
541
542template <>
543GPUhdi() constexpr float GPUCommonMath::Abs<float>(float x)
544{
545 return GPUCA_CHOICE(fabsf(x), fabsf(x), fabs(x));
546}
547
548#ifdef __METAL__ // MSL has no double, so the keyword names the emulated binary64 and fabs does not apply
549template <>
550GPUhdi() constexpr double GPUCommonMath::Abs<double>(double x)
551{
552 return GPUdoubleBinary64::fromBits(x.bits() & ~GPUCA_B64_SIGN);
553}
554// metal::fabs is not constant-evaluable, so this also fails to compile if the
555// specialisation above is ever dropped and the call falls back to it in float
556static_assert(GPUCommonMath::Abs<double>(GPUdoubleBinary64::fromBits(0xBFF0000000000001ULL)).bits() == 0x3FF0000000000001ULL,
557 "Abs on the emulated double must clear the sign bit and keep every other one");
558#else
559template <>
560GPUhdi() constexpr double GPUCommonMath::Abs<double>(double x)
561{
562 return GPUCA_CHOICE(fabs(x), fabs(x), fabs(x));
563}
564#endif
565
566template <>
568{
569 return GPUCA_CHOICE(abs(x), abs(x), abs(x));
570}
571
572#ifdef __METAL__
573// The counters these operate on are plain integers in the transferred structures,
574// as they are for CUDA and HIP. MSL's atomic operations want metal::atomic, which
575// has the same size and alignment. The overload is picked by address space, and a
576// threadgroup pointer has to keep its own: casting one to a device atomic is an
577// error while the qualifier is visible, but a generic pointer resolves here to
578// device and the cast then goes through silently.
579template <class T>
580GPUdi() threadgroup metal::atomic<T>* GPUCommonMathMetalAtomic(threadgroup T* p)
581{
582 return reinterpret_cast<threadgroup metal::atomic<T>*>(p);
583}
584template <class T>
585GPUdi() device metal::atomic<T>* GPUCommonMathMetalAtomic(T* p)
586{
587 return (device metal::atomic<T>*)p;
588}
589#endif
590
591template <class S, class T>
592GPUdi() uint32_t GPUCommonMath::AtomicExchInternal(S* addr, T val)
593{
594#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
595 return ::atomic_exchange(addr, val);
596#elif defined(GPUCA_GPUCODE) && defined(__OPENCL__)
597 return ::atomic_xchg(addr, val);
598#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
599 return ::atomicExch(addr, val);
600#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
601 return atomic_exchange_explicit(GPUCommonMathMetalAtomic(addr), val, memory_order_relaxed);
602#elif defined(WITH_OPENMP)
603 uint32_t old;
604 __atomic_exchange(addr, &val, &old, __ATOMIC_SEQ_CST);
605 return old;
606#else
607 return reinterpret_cast<std::atomic<T>*>(addr)->exchange(val);
608#endif
609}
610
611template <class S, class T>
612GPUdi() bool GPUCommonMath::AtomicCASInternal(S* addr, T cmp, T val)
613{
614#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
615 return ::atomic_compare_exchange(addr, cmp, val) == cmp;
616#elif defined(GPUCA_GPUCODE) && defined(__OPENCL__)
617 return ::atomic_cmpxchg(addr, cmp, val) == cmp;
618#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
619 return ::atomicCAS(addr, cmp, val) == cmp;
620#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
621 return atomic_compare_exchange_weak_explicit(GPUCommonMathMetalAtomic(addr), &cmp, val, memory_order_relaxed, memory_order_relaxed);
622#elif defined(WITH_OPENMP)
623 return __atomic_compare_exchange(addr, &cmp, &val, true, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
624#else
625 return reinterpret_cast<std::atomic<T>*>(addr)->compare_exchange_strong(cmp, val);
626#endif
627}
628
629template <class S, class T>
630GPUdi() uint32_t GPUCommonMath::AtomicAddInternal(S* addr, T val)
631{
632#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
633 return ::atomic_fetch_add(addr, val);
634#elif defined(GPUCA_GPUCODE) && defined(__OPENCL__)
635 return ::atomic_add(addr, val);
636#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
637 return ::atomicAdd(addr, val);
638#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
639 return atomic_fetch_add_explicit(GPUCommonMathMetalAtomic(addr), val, memory_order_relaxed);
640#elif defined(WITH_OPENMP)
641 return __atomic_add_fetch(addr, val, __ATOMIC_SEQ_CST) - val;
642#else
643 return reinterpret_cast<std::atomic<T>*>(addr)->fetch_add(val);
644#endif
645}
646
647template <class S, class T>
648GPUdi() void GPUCommonMath::AtomicMaxInternal(S* addr, T val)
649{
650#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
651 ::atomic_fetch_max(addr, val);
652#elif defined(GPUCA_GPUCODE) && defined(__OPENCL__)
653 ::atomic_max(addr, val);
654#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
655 ::atomicMax(addr, val);
656#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
657 atomic_fetch_max_explicit(GPUCommonMathMetalAtomic(addr), val, memory_order_relaxed);
658#else
659 S current;
660 while ((current = *(volatile S*)addr) < val && !AtomicCASInternal(addr, current, val)) {
661 }
662#endif // GPUCA_GPUCODE
663}
664
665template <class S, class T>
666GPUdi() void GPUCommonMath::AtomicMinInternal(S* addr, T val)
667{
668#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
669 ::atomic_fetch_min(addr, val);
670#elif defined(GPUCA_GPUCODE) && defined(__OPENCL__)
671 ::atomic_min(addr, val);
672#elif defined(GPUCA_GPUCODE) && (defined(__CUDACC__) || defined(__HIPCC__))
673 ::atomicMin(addr, val);
674#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
675 atomic_fetch_min_explicit(GPUCommonMathMetalAtomic(addr), val, memory_order_relaxed);
676#else
677 S current;
678 while ((current = *(volatile S*)addr) > val && !AtomicCASInternal(addr, current, val)) {
679 }
680#endif // GPUCA_GPUCODE
681}
682
683// Relaxed, as the device atomics above
684template <class T, class S>
685GPUdi() T GPUCommonMath::AtomicLoadInternal(S* addr)
686{
687#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
688 return ::atomic_load_explicit(addr, memory_order_relaxed);
689#elif defined(GPUCA_GPUCODE) && (defined(__OPENCL__) || defined(__CUDACC__) || defined(__HIPCC__))
690 return *(volatile S*)addr;
691#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
692 return atomic_load_explicit(GPUCommonMathMetalAtomic(addr), memory_order_relaxed);
693#elif defined(WITH_OPENMP)
694 T ret;
695 __atomic_load(addr, &ret, __ATOMIC_RELAXED);
696 return ret;
697#else
698 return reinterpret_cast<std::atomic<T>*>(addr)->load(std::memory_order_relaxed);
699#endif
700}
701
702template <class S, class T>
703GPUdi() void GPUCommonMath::AtomicStoreInternal(S* addr, T val)
704{
705#if defined(GPUCA_GPUCODE) && defined(__OPENCL__) && (!defined(__clang__) || defined(GPUCA_OPENCL_CLANG_C11_ATOMICS))
706 ::atomic_store_explicit(addr, val, memory_order_relaxed);
707#elif defined(GPUCA_GPUCODE) && (defined(__OPENCL__) || defined(__CUDACC__) || defined(__HIPCC__))
708 *(volatile S*)addr = val;
709#elif defined(GPUCA_GPUCODE) && defined(__METAL__)
710 atomic_store_explicit(GPUCommonMathMetalAtomic(addr), val, memory_order_relaxed);
711#elif defined(WITH_OPENMP)
712 __atomic_store(addr, &val, __ATOMIC_RELAXED);
713#else
714 reinterpret_cast<std::atomic<T>*>(addr)->store(val, std::memory_order_relaxed);
715#endif
716}
717
718#if (defined(__CUDACC__) || defined(__HIPCC__)) && !defined(G__ROOT) && !defined(__CLING__)
719#define GPUCA_HAVE_ATOMIC_MINMAX_FLOAT
720template <>
721GPUdii() void GPUCommonMath::AtomicMaxInternal(GPUglobalref() GPUgeneric() GPUAtomic(float) * addr, float val)
722{
723 if (val == -0.f) {
724 val = 0.f;
725 }
726 if (val >= 0) {
727 AtomicMaxInternal((GPUAtomic(int32_t)*)addr, __float_as_int(val));
728 } else {
729 AtomicMinInternal((GPUAtomic(uint32_t)*)addr, __float_as_uint(val));
730 }
731}
732template <>
733GPUdii() void GPUCommonMath::AtomicMinInternal(GPUglobalref() GPUgeneric() GPUAtomic(float) * addr, float val)
734{
735 if (val == -0.f) {
736 val = 0.f;
737 }
738 if (val >= 0) {
739 AtomicMinInternal((GPUAtomic(int32_t)*)addr, __float_as_int(val));
740 } else {
741 AtomicMaxInternal((GPUAtomic(uint32_t)*)addr, __float_as_uint(val));
742 }
743}
744#endif
745
746#undef GPUCA_CHOICE
747
748} // namespace o2::gpu
749
750#endif // GPUCOMMONMATH_H
uint64_t exp(uint64_t base, uint8_t exp) noexcept
unsigned int uint32_t
int32_t i
#define GPUsharedref()
#define GPUdii()
#define GPUAtomic(type)
#define GPUgeneric()
#define GPUglobalref()
#define GPUCA_DETERMINISTIC_CODE(det, indet)
#define GPUCA_B64_SIGN
#define GPUCA_CHOICE(c1, c2, c3)
int32_t retVal
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events d
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc bool
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in tan(phi) dependence of tracklet error due to radial misalignment(centered at 0 angle)") AddOptionRTC(maxChi2Red
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder Print launch bounds used for RTC code as debugging for exit after Allow RTC with slave GPUReconstruction instances with optConstexpr and optSpecialcode Maximum number of RTC cache files per backend in the cache the oldest are Prepend RTC compilation commands by this string Load a parameter object containing the launch bounds from a file h configStandalone Processing proc_param TPC Cluster Z Error Parameterization h configStandalone Processing settings for neural network proc_nn std::string Specify inference device(cpu(default), rocm, cuda)") AddOption(nnInferenceDeviceId
configStandalone Reconstruction rec_tpc float
Class for time synchronization of RawReader instances.
GPUd() const expr static float Pi()
GPUdi() static void AtomicStore(GPUglobalref() GPUgeneric() GPUAtomic(T) *addr
GPUhd() const expr static T Min(const T x
GPUd() const expr static float QuietNaN()
GPUdi() static void AtomicMax(GPUglobalref() GPUgeneric() GPUAtomic(T) *addr
GPUd() const expr static int32_t Float2IntRn(float x)
GPUd() const expr static float Round(float x)
GPUhdni() const expr static float Sqrt(float x)
GPUdi() static void AtomicMin(GPUglobalref() GPUgeneric() GPUAtomic(T) *addr
GPUdi() const expr static T Clamp(const T v
GPUd() static float2 MakeFloat2(float x
GPUhd() const expr static T Max(const T x
GPUdi() static T AtomicAddShared(GPUsharedref() GPUgeneric() GPUAtomic(T) *addr
GPUhd() const expr static T Abs(T x)
GPUdi() static T AtomicAdd(GPUglobalref() GPUgeneric() GPUAtomic(T) *addr
const void size_t size
GPUdi() static T AtomicExchShared(GPUsharedref() GPUgeneric() GPUAtomic(T) *addr
GPUd() static uint32_t Float2UIntReint(const float &x)
GPUd() static T MinWithRef(T x
GPUdi() static void AtomicMinShared(GPUsharedref() GPUgeneric() GPUAtomic(T) *addr
GPUhdi() static float Remainderf(float x
GPUdi() static T AtomicLoad(GPUglobalref() GPUgeneric() GPUAtomic(T) *addr)
GPUhdi() const expr static float Hypot(float x
GPUd() const expr static double Copysignd(double x
GPUd() const expr static uint32_t Clz(uint32_t val)
GPUdi() static void AtomicMaxShared(GPUsharedref() GPUgeneric() GPUAtomic(T) *addr
GLint GLenum GLint x
Definition glcorearb.h:403
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLint y
Definition glcorearb.h:270
GLenum GLenum dst
Definition glcorearb.h:1767
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLuint GLfloat * val
Definition glcorearb.h:1582
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
bool isnan(float f)
constexpr size_t min
constexpr size_t max