Project
Loading...
Searching...
No Matches
SplineSpec.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
16
17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
19
20#include "Spline1D.h"
21#include "FlatObject.h"
22#include "GPUCommonDef.h"
23#include "SplineUtil.h"
24
25#if !defined(__CLING__) && !defined(G__ROOT) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
26#include <Vc/Vc>
27#include <Vc/SimdArray>
28#endif
29
30class TFile;
31
32namespace o2::gpu
33{
34
44template <typename DataT>
46{
47 public:
49
51
53 GPUd() static constexpr int32_t getVersion() { return (1 << 16) + Spline1D<DataT>::getVersion(); }
54
56
58 SplineContainer() = default;
59
62
64 ~SplineContainer() = default;
65
67
68#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
70 void approximateFunction(const double xMin[/* mXdim */], const double xMax[/* mXdim */],
71 std::function<void(const double x[/* mXdim */], double f[/*mYdim*/])> F,
72 const int32_t nAuxiliaryDataPoints[/* mXdim */] = nullptr);
73#endif
74
76
77#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
79 int32_t writeToFile(TFile& outf, const char* name);
80
82 static SplineContainer* readFromFile(TFile& inpf, const char* name);
83#endif
84
86
88 GPUd() int32_t getXdimensions() const { return mXdim; }
89
91 GPUd() int32_t getYdimensions() const { return mYdim; }
92
94 GPUd() static constexpr size_t getParameterAlignmentBytes() { return 16; }
95
97 GPUd() int32_t getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); }
98
100 GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * this->getNumberOfParameters(); }
101
103 GPUd() int32_t getNumberOfKnots() const { return mNknots; }
104
106 GPUd() int32_t getNumberOfParametersPerKnot() const { return calcNumberOfParametersPerKnot(mYdim); }
107
109 GPUd() const Spline1D<DataT>& getGrid(int32_t dimX) const { return mGrid[dimX]; }
110
112 GPUd() void getKnotU(int32_t iKnot, int32_t u[/* mXdim */]) const;
113
115 GPUd() int32_t getKnotIndex(const int32_t iKnot[/* mXdim */]) const;
116
118 GPUd() DataT* getParameters() { return mParameters; }
119
121 GPUd() const DataT* getParameters() const { return mParameters; }
122
124
126 GPUd() size_t getGridOffset(int32_t dimX) const { return mGrid[dimX].getFlatBufferPtr() - mFlatBufferPtr; }
127
129 GPUd() void setXrange(const DataT xMin[/* mXdim */], const DataT xMax[/* mXdim */]);
130
132 void print() const;
133
135
137 GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const
138 {
139 return calcNumberOfParametersPerKnot(nYdim) * getNumberOfKnots();
140 }
141
143 GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const
144 {
145 return (1 << mXdim) * nYdim; // 2^mXdim parameters per Y dimension
146 }
147
149
150#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation
152 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
153#endif
154
156
159
160#if !defined(GPUCA_GPUCODE)
161 void cloneFromObject(const SplineContainer& obj, char* newFlatBufferPtr);
162 void moveBufferTo(char* newBufferPtr);
163#endif
164
166
167 void destroy();
168 void setActualBufferAddress(char* actualFlatBufferPtr);
169 void setFutureBufferAddress(char* futureFlatBufferPtr);
170
171 protected:
172#if !defined(GPUCA_GPUCODE)
174 void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */]);
175
177 void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */]);
178#endif
179
181
182 int32_t mXdim = 0;
183 int32_t mYdim = 0;
184 int32_t mNknots = 0;
185
187 DataT* mParameters;
188
190};
191
192template <typename DataT>
193GPUdi() void SplineContainer<DataT>::getKnotU(int32_t iKnot, int32_t u[/* mXdim */]) const
194{
196 for (int32_t dim = 0; dim < mXdim; dim++) {
197 int32_t n = mGrid[dim].getNumberOfKnots();
198 u[dim] = mGrid[dim].getKnot(iKnot % n).getU();
199 iKnot /= n;
200 }
201}
202
203template <typename DataT>
204GPUdi() int32_t SplineContainer<DataT>::getKnotIndex(const int32_t iKnot[/* mXdim */]) const
205{
207 int32_t ind = iKnot[0];
208 int32_t n = 1;
209 for (int32_t dim = 1; dim < mXdim; dim++) {
210 n *= mGrid[dim - 1].getNumberOfKnots();
211 ind += n * iKnot[dim];
212 }
213 return ind;
214}
215
216template <typename DataT>
217GPUdi() void SplineContainer<DataT>::
218 setXrange(const DataT xMin[/* mXdim */], const DataT xMax[/* mXdim */])
219{
221 for (int32_t i = 0; i < mXdim; i++) {
222 mGrid[i].setXrange(xMin[i], xMax[i]);
223 }
224}
225
248template <typename DataT, int32_t XdimT, int32_t YdimT, int32_t SpecT>
250
255template <typename DataT, int32_t XdimT, int32_t YdimT>
256class SplineSpec<DataT, XdimT, YdimT, 0> : public SplineContainer<DataT>
257{
259
260 public:
262
264
266 GPUd() void interpolate(const DataT x[/*mXdim*/], GPUgeneric() DataT S[/*mYdim*/]) const
267 {
268 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
269 const auto nXdim = nXdimTmp.get();
270 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
271 DataT u[maxXdimTmp.get()];
272 for (int32_t i = 0; i < nXdim; i++) {
273 u[i] = mGrid[i].convXtoU(x[i]);
274 }
275 interpolateAtU<SafetyLevel::kSafe>(mXdim, mYdim, mParameters, u, S);
276 }
277
279 template <SafetyLevel SafeT = SafetyLevel::kSafe>
280 GPUd() void interpolateAtU(int32_t inpXdim, int32_t inpYdim, GPUgeneric() const DataT Parameters[],
281 const DataT u[/*inpXdim*/], GPUgeneric() DataT S[/*inpYdim*/]) const
282 {
283 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
284 const auto nXdim = nXdimTmp.get();
285 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
286 const auto maxXdim = maxXdimTmp.get();
287 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(mYdim);
288 const auto nYdim = nYdimTmp.get();
289 const auto maxYdimTmp = SplineUtil::getMaxNdim<XdimT>(mYdim);
290 const auto maxYdim = maxYdimTmp.get();
291
292 // const auto nParameters = 1 << (2 * nXdim); //total Nr of Parameters necessary for one interpolation
293 const auto nKnotParametersPerY = 1 << nXdim; // Nr of Parameters per Knot per Y dimension
294 const auto nKnotParameters = (1 << nXdim) * nYdim; // Nr of Parameters per Knot
295
296 DataT iParameters[(1 << (2 * maxXdim)) * maxYdim]; // Array for all parameters
297
298 // get the indices of the "most left" Knot:
299
300 int32_t indices[maxXdim]; // indices of the 'most left' knot
301 for (int32_t i = 0; i < nXdim; i++) {
302 indices[i] = mGrid[i].getLeftKnotIndexForU(u[i]);
303 }
304 // get all the needed parameters into one array iParameters[nParameters]:
305 int32_t indicestmp[maxXdim];
306 for (int32_t i = 0; i < nKnotParametersPerY; i++) { // for every necessary Knot
307 for (int32_t k = 0; k < nXdim; k++) {
308 indicestmp[k] = indices[k] + (i / (1 << k)) % 2; // get the knot-indices in every dimension (mirrored order binary counting)
309 }
310 int32_t index = TBase::getKnotIndex(indicestmp); // get index of the current Knot
311
312 for (int32_t j = 0; j < nKnotParameters; j++) { // and fill the iparameter array with according parameters
313 iParameters[i * nKnotParameters + j] = Parameters[index * nKnotParameters + j];
314 }
315 }
316 // now start with the interpolation loop:
317
318 constexpr auto maxInterpolations = (1 << (2 * maxXdim - 2)) * maxYdim;
319
320 DataT S0[maxInterpolations];
321 DataT D0[maxInterpolations];
322 DataT S1[maxInterpolations];
323 DataT D1[maxInterpolations];
324
325 int32_t nInterpolations = (1 << (2 * nXdim - 2)) * nYdim;
326 int32_t nKnots = 1 << (nXdim);
327
328 for (int32_t d = 0; d < nXdim; d++) { // for every dimension
329 DataT* pointer[4] = {S0, D0, S1, D1}; // pointers for interpolation arrays S0, D0, S1, D1 point to Arraystart
330 for (int32_t i = 0; i < nKnots; i++) { // for every knot
331 for (int32_t j = 0; j < nKnots; j++) { // for every parametertype
332 int32_t pointernr = 2 * (i % 2) + (j % 2); // to which array should it be delivered
333 for (int32_t k = 0; k < nYdim; k++) {
334 pointer[pointernr][0] = iParameters[(i * nKnots + j) * nYdim + k];
335 pointer[pointernr]++;
336 }
337 } // end for j (every parametertype)
338 } // end for i (every knot)
339
340 const typename Spline1D<DataT>::KnotType& knotL = mGrid[d].getKnot(indices[d]);
341 DataT coordinate = u[d];
342 using GridXBase = Spline1DSpec<DataT, 0, 0>;
343 const GridXBase& gridX = *((const GridXBase*)&(mGrid[d]));
344 gridX.interpolateAtU(nInterpolations, knotL, S0, D0, S1, D1, coordinate, iParameters);
345 nInterpolations /= 4;
346 nKnots /= 2;
347 } // end d (every dimension)
348
349 for (int32_t i = 0; i < nYdim; i++) {
350 S[i] = iParameters[i]; // write into result-array
351 // LOG(info)<<iParameters[i] <<", ";
352 }
353 } // end interpolateAtU
354
355 protected:
356 using TBase::mGrid;
357 using TBase::mParameters;
358 using TBase::mXdim;
359 using TBase::mYdim;
360 using TBase::TBase; // inherit constructors and hide them
361};
362
367template <typename DataT, int32_t XdimT, int32_t YdimT>
368class SplineSpec<DataT, XdimT, YdimT, 1>
369 : public SplineSpec<DataT, XdimT, YdimT, 0>
370{
373
374 public:
375#if !defined(GPUCA_GPUCODE)
377 SplineSpec() : SplineSpec(nullptr) {}
378
380 SplineSpec(const int32_t nKnots[/*XdimT*/]) : TBase()
381 {
382 recreate(nKnots);
383 }
385 SplineSpec(const int32_t nKnots[/*XdimT*/], const int32_t* const knotU[/*XdimT*/])
386 : TBase()
387 {
388 recreate(nKnots, knotU);
389 }
392 {
393 TBase::cloneFromObject(v, nullptr);
394 }
396 void recreate(const int32_t nKnots[/*XdimT*/])
397 {
398 TBase::recreate(XdimT, YdimT, nKnots);
399 }
400
402 void recreate(const int32_t nKnots[/*XdimT*/], const int32_t* const knotU[/*XdimT*/])
403 {
404 TBase::recreate(XdimT, YdimT, nKnots, knotU);
405 }
406#endif
407
409 GPUd() constexpr int32_t getXdimensions() const { return XdimT; }
410
412 GPUd() constexpr int32_t getYdimensions() const { return YdimT; }
413
415
417 template <SafetyLevel SafeT = SafetyLevel::kSafe>
418 GPUd() void interpolateAtU(GPUgeneric() const DataT Parameters[],
419 const DataT u[/*XdimT*/], GPUgeneric() DataT S[/*YdimT*/]) const
420 {
421 TBase::template interpolateAtU<SafeT>(XdimT, YdimT, Parameters, u, S);
422 }
423
425 private:
426#if !defined(GPUCA_GPUCODE)
427 using TBase::recreate;
428#endif
429 using TBase::interpolateAtU;
430};
431
436template <typename DataT, int32_t XdimT, int32_t YdimT>
437class SplineSpec<DataT, XdimT, YdimT, 2>
438 : public SplineSpec<DataT, XdimT, YdimT, 0>
439{
442
443 public:
444#if !defined(GPUCA_GPUCODE)
446 SplineSpec() : SplineSpec((XdimT > 0 ? XdimT : 0), (YdimT > 0 ? YdimT : 0), nullptr) {}
447
449 SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */]) : TBase()
450 {
451 this->recreate(nXdim, nYdim, nKnots);
452 }
453
455 SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */])
456 : TBase()
457 {
458 this->recreate(nXdim, nYdim, nKnots, knotU);
459 }
460
463 {
464 cloneFromObject(v, nullptr);
465 }
466
468 void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */])
469 {
470 checkDimensions(nXdim, nYdim);
471 TBase::recreate(nXdim, nYdim, nKnots);
472 }
473
475 void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[/* nXdim */], const int32_t* const knotU[/* nXdim */])
476 {
477 checkDimensions(nXdim, nYdim);
478 TBase::recreate(nXdim, nYdim, nKnots, knotU);
479 }
480
481#endif
482
484
485 using TBase::interpolateAtU;
486
488 void checkDimensions(int32_t& nXdim, int32_t& nYdim)
489 {
490 if (XdimT > 0 && nXdim != XdimT) {
491 assert(0);
492 nXdim = XdimT;
493 }
494 if (XdimT < 0 && nXdim > abs(XdimT)) {
495 assert(0);
496 nXdim = abs(XdimT);
497 }
498 if (nXdim < 0) {
499 assert(0);
500 nXdim = 0;
501 }
502 if (YdimT > 0 && nYdim != YdimT) {
503 assert(0);
504 nYdim = YdimT;
505 }
506 if (YdimT < 0 && nYdim > abs(YdimT)) {
507 assert(0);
508 nYdim = abs(YdimT);
509 }
510 if (nYdim < 0) {
511 assert(0);
512 nYdim = 0;
513 }
514 }
515};
516
520template <typename DataT, int32_t XdimT>
521class SplineSpec<DataT, XdimT, 1, 3>
522 : public SplineSpec<DataT, XdimT, 1, SplineUtil::getSpec(XdimT, 999)>
523{
524 typedef SplineSpec<DataT, XdimT, 1, SplineUtil::getSpec(XdimT, 999)> TBase;
525
526 public:
527 using TBase::TBase; // inherit constructors
528
530 GPUd() DataT interpolate(const DataT x[]) const
531 {
532 DataT S = 0;
533 TBase::interpolate(x, &S);
534 return S;
535 }
536
537 // this parent method should be public anyhow,
538 // but the compiler gets confused w/o this extra declaration
539 using TBase::interpolate;
540};
541
542} // namespace o2::gpu
543
544#endif
Definition of FlatObject class.
int32_t i
#define GPUgeneric()
uint32_t j
Definition RawData.h:0
Definition of Spline1D class.
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
Definition FlatObject.h:538
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
Definition FlatObject.h:195
static constexpr size_t getClassAlignmentBytes()
GPUCA_GPUCODE.
Definition FlatObject.h:192
Forward declaration — specializations below select ClassDefNV based on FlatBase.
Definition Spline1D.h:171
GPUd() void setXrange(const DataT xMin[]
Set X range.
SplineContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() int32_t getXdimensions() const
_______________ Getters ________________________
Definition SplineSpec.h:88
int32_t mYdim
dimentionality of Y
Definition SplineSpec.h:183
GPUd() size_t getGridOffset(int32_t dimX) const
_______________ Technical stuff ________________________
Definition SplineSpec.h:126
~SplineContainer()=default
Destructor.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
Definition SplineSpec.h:103
int32_t mNknots
number of spline knots
Definition SplineSpec.h:184
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
Definition SplineSpec.h:100
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
void cloneFromObject(const SplineContainer &obj, char *newFlatBufferPtr)
static SplineContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
ClassDefNV(SplineContainer, 1)
(transient!!) F-dependent parameters of the spline
void moveBufferTo(char *newBufferPtr)
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
Definition SplineSpec.h:53
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
Spline1D< DataT > * mGrid
Definition SplineSpec.h:186
void setActualBufferAddress(char *actualFlatBufferPtr)
void setFutureBufferAddress(char *futureFlatBufferPtr)
GPUd() int32_t getNumberOfParametersPerKnot() const
Number of parameters per knot.
Definition SplineSpec.h:106
int32_t mXdim
_____________ Data members ____________
Definition SplineSpec.h:182
GPUd() const Spline1D< DataT > &getGrid(int32_t dimX) const
Get 1-D grid for dimX dimension.
Definition SplineSpec.h:109
DataT * mParameters
(transient!!) mXdim grids
Definition SplineSpec.h:187
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
Definition SplineSpec.h:97
void print() const
Print method.
GPUd() int32_t getYdimensions() const
Get number of Y dimensions.
Definition SplineSpec.h:91
SplineContainer(const SplineContainer &)=delete
Disable all other constructors.
void approximateFunction(const double xMin[], const double xMax[], std::function< void(const double x[], double f[])> F, const int32_t nAuxiliaryDataPoints[]=nullptr)
_______________ Construction interface ________________________
GPUd() const DataT *getParameters() const
Get spline parameters const.
Definition SplineSpec.h:121
GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const
Number of parameters per knot.
Definition SplineSpec.h:143
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
Definition SplineSpec.h:94
GPUd() DataT interpolate(const DataT x[]) const
Simplified interface for 1D: return the interpolated value.
Definition SplineSpec.h:530
GPUd() void interpolate(const DataT x[]
_______________ Interpolation math ________________________
GPUd() void interpolateAtU(int32_t inpXdim
Get interpolated value for S(u):inpXdim->inpYdim using spline parameters Parameters.
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
Definition SplineSpec.h:412
void recreate(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
Definition SplineSpec.h:402
GPUd() void interpolateAtU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
GPUd() const expr int32_t getXdimensions() const
Get number of X dimensions.
Definition SplineSpec.h:409
SplineSpec(const int32_t nKnots[])
Constructor for a regular spline.
Definition SplineSpec.h:380
SplineSpec(const SplineSpec &v)
Copy constructor.
Definition SplineSpec.h:391
void recreate(const int32_t nKnots[])
Constructor for a regular spline.
Definition SplineSpec.h:396
SplineSpec(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
Definition SplineSpec.h:385
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
Definition SplineSpec.h:449
SplineSpec(const SplineSpec &v)
Copy constructor.
Definition SplineSpec.h:462
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
Definition SplineSpec.h:475
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
Definition SplineSpec.h:455
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
Definition SplineSpec.h:468
void checkDimensions(int32_t &nXdim, int32_t &nYdim)
Check dimensions.
Definition SplineSpec.h:488
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
Definition SplineUtil.h:31
GLdouble n
Definition glcorearb.h:1982
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum void ** pointer
Definition glcorearb.h:805
const GLdouble * v
Definition glcorearb.h:832
GLuint index
Definition glcorearb.h:781
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLsizei GLenum const void * indices
Definition glcorearb.h:400
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GPUdi() o2
Definition TrackTRD.h:39