CbmRoot
Loading...
Searching...
No Matches
KfUtils.h
Go to the documentation of this file.
1/* Copyright (C) 2022-2023 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
2 SPDX-License-Identifier: GPL-3.0-only
3 Authors: Sergey Gorbunov, Sergei Zharko [committer] */
4
9
10#pragma once // include this header only once per compilation unit
11
12#include "KfDefs.h"
13#include "KfSimd.h"
14
15#include <array>
16#include <sstream>
17
21{
22
23 template<typename T>
24 using scaltype = typename std::conditional<std::is_same<T, fvec>::value, fscal, T>::type;
25
26 template<typename T>
27 using masktype = typename std::conditional<std::is_same<T, fvec>::value, fmask, bool>::type;
28
29 inline fvec iif(const fmask& m, const fvec& t, const fvec& f) { return Vc::iif(m, t, f); }
30 inline fvec fabs(const fvec& v) { return Vc::abs(v); }
31
32 template<typename T>
33 inline T iif(bool b, T t, T f)
34 {
35 return b ? t : f;
36 }
37
38 template<typename T>
39 inline T fabs(const T& v)
40 {
41 return std::fabs(v);
42 }
43
44 template<typename T>
45 inline bool isFull(const T& m)
46 {
47 if constexpr (std::is_same_v<T, fmask>) {
48 return m.isFull();
49 }
50 else {
51 return m;
52 }
53 }
54
55 template<typename T>
56 inline T max(const T& a, const T& b)
57 {
58 if constexpr (std::is_same_v<T, fvec>) {
59 return Vc::max(a, b);
60 }
61 else {
62 return std::max(a, b);
63 }
64 }
65
67#if defined(__GNUC__) && __GNUC__ - 0 >= 3
68 __attribute__((always_inline)) inline bool IsLikely(bool b) { return __builtin_expect(!!(b), 1); }
69 __attribute__((always_inline)) inline bool IsUnlikely(bool b) { return __builtin_expect(!!(b), 0); }
70#else
71 inline bool IsLikely(bool b) { return b; }
72 inline bool IsUnlikely(bool b) { return b; }
73#endif
74
77 template<typename T>
78 inline bool IsUndefined(const T& val)
79 {
80 if constexpr (std::is_same_v<T, float>) {
81 return std::isnan(val);
82 }
83 else if constexpr (std::is_same_v<T, double>) {
84 return std::isnan(val);
85 }
86 else if constexpr (std::is_same_v<T, fscal>) {
87 return std::isnan(val);
88 }
89 else if constexpr (std::is_same_v<T, fvec>) {
90 return isnan(val).isNotEmpty();
91 }
92 else {
94 }
95 }
96
99 template<typename T>
100 inline bool IsFinite(const T& val)
101 {
102 if constexpr (std::is_same_v<T, float>) {
103 return std::isfinite(val);
104 }
105 else if constexpr (std::is_same_v<T, double>) {
106 return std::isfinite(val);
107 }
108 else if constexpr (std::is_same_v<T, fscal>) {
109 return std::isfinite(val);
110 }
111 else if constexpr (std::is_same_v<T, fvec>) {
112 return isfinite(val).isFull();
113 }
114 else {
115 return val != cbm::algo::kf::defs::Undef<T>;
116 }
117 }
118
120 template<typename DataT>
121 void PrintSIMDmsg(std::stringstream& msg, DataT& v);
122
124 template<typename DataT>
125 inline void CheckSimdVectorEquality(DataT /*v*/, const char* /*name*/)
126 {
127 }
128
132 template<>
133 void CheckSimdVectorEquality(fvec v, const char* name);
134
135 template<typename TdataA, typename TdataB, bool TDoAllA, bool TDoAllB>
137 public:
138 [[gnu::always_inline]] static void CopyEntries(TdataA& a, int ia, const TdataB& b, int ib);
139 };
140
141 template<typename TdataA, typename TdataB>
142 class VecCopySpec<TdataA, TdataB, true, true> {
143 public:
144 [[gnu::always_inline]] static void CopyEntries(TdataA& a, int, const TdataB& b, int) { a = b; }
145 };
146
147 template<typename TdataA, typename TdataB>
148 class VecCopySpec<TdataA, TdataB, true, false> {
149 public:
150 [[gnu::always_inline]] static void CopyEntries(TdataA& a, int, const TdataB& b, int ib) { a = b[ib]; }
151 };
152
153 template<typename TdataA, typename TdataB>
154 class VecCopySpec<TdataA, TdataB, false, true> {
155 public:
156 [[gnu::always_inline]] static void CopyEntries(TdataA& a, int ia, const TdataB& b, int) { a[ia] = b; }
157 };
158
159 template<typename TdataA, typename TdataB>
160 class VecCopySpec<TdataA, TdataB, false, false> {
161 public:
162 [[gnu::always_inline]] static void CopyEntries(TdataA& a, int ia, const TdataB& b, int ib) { a[ia] = b[ib]; }
163 };
164
165
178 template<typename TdataA, typename TdataB, bool TDoAllA, bool TDoAllB>
179 class VecCopy {
180 public:
181 static void CopyEntries(TdataA& a, int ia, const TdataB& b, int ib)
182 {
183 constexpr bool allA{TDoAllA || !std::is_same<TdataA, fvec>::value};
184 constexpr bool allB{TDoAllB || !std::is_same<TdataB, fvec>::value};
186 }
187 };
188
192 template<typename T>
193 int operator()(T t) const
194 {
195 return static_cast<int>(t);
196 }
197 };
198} // namespace cbm::algo::kf::utils
199
204{
211 template<typename DataT, typename DataOut>
212 inline DataOut Cast(const DataT& val)
213 {
214 return static_cast<DataOut>(val);
215 }
216
221 template<>
222 inline float Cast(const fvec& val)
223 {
224 return val[0];
225 }
226
231 template<>
232 inline double Cast(const fvec& val)
233 {
234 return static_cast<double>(val[0]);
235 }
236
244 template<typename DataT, typename DataOut>
245 inline DataOut Cast(const DataT& val, size_t /*i*/)
246 {
247 return static_cast<DataOut>(val);
248 }
249
250 template<typename DataT, typename DataOut, size_t N>
251 inline std::array<DataOut, N> Cast(const std::array<DataT, N>& arr, size_t i)
252 {
253 std::array<DataOut, N> res;
254 for (size_t iEl = 0; iEl < arr.size(); ++iEl) {
255 res[iEl] = Cast<DataT, DataOut>(arr[iEl], i);
256 }
257 return res;
258 }
259
260 template<typename DataT, typename DataOut, size_t N>
261 inline std::array<DataOut, N> Cast(const std::array<DataT, N>& arr)
262 {
263 std::array<DataOut, N> res;
264 for (size_t iEl = 0; iEl < arr.size(); ++iEl) {
265 res[iEl] = Cast<DataT, DataOut>(arr[iEl]);
266 }
267 return res;
268 }
269
275 template<>
276 inline float Cast(const fvec& val, size_t i)
277 {
278 return val[i];
279 }
280
286 template<>
287 inline double Cast(const fvec& val, size_t i)
288 {
289 return static_cast<double>(val[i]);
290 }
291
296 template<typename DataT>
297 inline size_t Size()
298 {
299 return 1;
300 }
301
305 template<>
306 inline size_t Size<fvec>()
307 {
308 return fvec::size();
309 }
310
315 template<typename DataT>
316 inline DataT One()
317 {
318 return static_cast<DataT>(1);
319 }
320
324 template<>
326 {
327 return fvec::One();
328 }
329
337 template<typename DataT, typename DataIn>
338 inline void SetEntry(DataT& out, DataIn in, size_t /*i*/)
339 {
340 out = static_cast<DataT>(in);
341 }
342
348 template<typename DataIn>
349 inline void SetEntry(fvec& out, DataIn in, size_t i)
350 {
351 out[i] = in;
352 }
353} // namespace cbm::algo::kf::utils::simd
354
355
356// TODO: SZh 06.06.2024:
357// There is nothing to do with SIMD in the funcitons below. Thus, we should move them into KfMath.h
362{
363
364 void CholeskyFactorization(const double a[], const int n, int nn, double u[], int* nullty, int* ifault);
365
366 void SymInv(const double a[], const int n, double c[], double w[], int* nullty, int* ifault);
367
368} // namespace cbm::algo::kf::utils::math
Common constant definitions for the Kalman Filter library.
friend fmask isnan(const fvec &a)
fscal v[fmask::Size]
Definition KfSimdPseudo.h:4
Implementation selection for the SIMD utilities (VS or pseudo)
static void CopyEntries(TdataA &a, int ia, const TdataB &b, int ib)
Definition KfUtils.h:162
static void CopyEntries(TdataA &a, int ia, const TdataB &b, int)
Definition KfUtils.h:156
static void CopyEntries(TdataA &a, int, const TdataB &b, int ib)
Definition KfUtils.h:150
static void CopyEntries(TdataA &a, int, const TdataB &b, int)
Definition KfUtils.h:144
static void CopyEntries(TdataA &a, int ia, const TdataB &b, int ib)
Copies all/one SIMD entries from one class to the other class.
Definition KfUtils.h:179
static void CopyEntries(TdataA &a, int ia, const TdataB &b, int ib)
Definition KfUtils.h:181
constexpr T2 Undef
Undefined values.
Definition KfDefs.h:115
void SymInv(const double a[], const int n, double c[], double w[], int *nullty, int *ifault)
Definition KfUtils.cxx:212
void CholeskyFactorization(const double a[], const int n, int nn, double u[], int *nullty, int *ifault)
Definition KfUtils.cxx:48
size_t Size()
Returns the number of elements available for a given data type.
Definition KfUtils.h:297
DataOut Cast(const DataT &val)
Converts a value of type DataT to type DataOut.
Definition KfUtils.h:212
DataT One()
Returns a value of the data type set to one.
Definition KfUtils.h:316
void SetEntry(DataT &out, DataIn in, size_t)
Sets a value at a specific index in the output data.
Definition KfUtils.h:338
fvec One< fvec >()
Returns a value of the data type set to one.
Definition KfUtils.h:325
size_t Size< fvec >()
Returns the number of elements available for a given data type.
Definition KfUtils.h:306
void PrintSIMDmsg(std::stringstream &msg, DataT &v)
Stingstream output operation for simd data.
Definition KfUtils.cxx:13
typename std::conditional< std::is_same< T, fvec >::value, fmask, bool >::type masktype
Definition KfUtils.h:27
void CheckSimdVectorEquality(fvec v, const char *name)
Checks, if a SIMD vector horizontally equal TODO: Find this method in the VC!
Definition KfUtils.cxx:29
typename std::conditional< std::is_same< T, fvec >::value, fscal, T >::type scaltype
Definition KfUtils.h:24
bool IsLikely(bool b)
tell the CPU that the bool condition is likely to be true
Definition KfUtils.h:71
T max(const T &a, const T &b)
Definition KfUtils.h:56
fvec iif(const fmask &m, const fvec &t, const fvec &f)
Definition KfUtils.h:29
bool IsFinite(const T &val)
Checks whether a variable of a particular type is finite.
Definition KfUtils.h:100
bool IsUnlikely(bool b)
Definition KfUtils.h:72
bool IsUndefined(const T &val)
Checks whether a variable of a particular type defined.
Definition KfUtils.h:78
fvec fabs(const fvec &v)
Definition KfUtils.h:30
bool isFull(const T &m)
Definition KfUtils.h:45
class cbm::algo::kf::fvec __attribute__((aligned(16)))
fvec::MaskType fmask
Definition KfSimdVc.h:21
Hash for unordered_map with enum class keys.
Definition KfUtils.h:191