17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
25#if !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
27#include <Vc/SimdArray>
46template <
typename DataT>
71#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
74 std::function<
void(
const double x[],
double f[])> F,
75 const int32_t nAuxiliaryDataPoints[] =
nullptr);
80#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
91 GPUd() int32_t getXdimensions()
const {
return mXdim; }
94 GPUd() int32_t getYdimensions()
const {
return mYdim; }
97 GPUd() static constexpr
size_t getParameterAlignmentBytes() {
return 16; }
100 GPUd() int32_t getNumberOfParameters()
const {
return this->calcNumberOfParameters(
mYdim); }
103 GPUd() size_t getSizeOfParameters()
const {
return sizeof(DataT) * this->getNumberOfParameters(); }
109 GPUd() int32_t getNumberOfParametersPerKnot()
const {
return calcNumberOfParametersPerKnot(
mYdim); }
140 GPUd() int32_t calcNumberOfParameters(int32_t nYdim)
const
142 return calcNumberOfParametersPerKnot(nYdim) * getNumberOfKnots();
146 GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim)
const
148 return (1 <<
mXdim) * nYdim;
153#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
155 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
163#if !defined(GPUCA_GPUCODE)
175#if !defined(GPUCA_GPUCODE)
177 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[]);
180 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[]);
195template <
typename DataT>
199 for (int32_t dim = 0; dim < mXdim; dim++) {
200 int32_t
n = mGrid[dim].getNumberOfKnots();
201 u[dim] = mGrid[dim].getKnot(iKnot %
n).getU();
206template <
typename DataT>
207GPUdi() int32_t SplineContainer<DataT>::getKnotIndex(const int32_t iKnot[])
const
210 int32_t ind = iKnot[0];
212 for (int32_t dim = 1; dim < mXdim; dim++) {
213 n *= mGrid[dim - 1].getNumberOfKnots();
214 ind +=
n * iKnot[dim];
219template <
typename DataT>
221 setXrange(const DataT xMin[], const DataT xMax[])
224 for (int32_t
i = 0;
i < mXdim;
i++) {
225 mGrid[
i].setXrange(xMin[
i], xMax[
i]);
251template <
typename DataT,
int32_t XdimT,
int32_t YdimT,
int32_t SpecT>
258template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
272 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
273 const auto nXdim = nXdimTmp.get();
274 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
275 DataT u[maxXdimTmp.get()];
276 for (int32_t
i = 0;
i < nXdim;
i++) {
277 u[
i] = mGrid[
i].convXtoU(
x[
i]);
279 interpolateU<SafetyLevel::kSafe>(mXdim, mYdim, mParameters, u,
S);
283 template <SafetyLevel SafeT = SafetyLevel::kSafe>
287 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
288 const auto nXdim = nXdimTmp.get();
289 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
290 const auto maxXdim = maxXdimTmp.get();
291 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(mYdim);
292 const auto nYdim = nYdimTmp.get();
293 const auto maxYdimTmp = SplineUtil::getMaxNdim<XdimT>(mYdim);
294 const auto maxYdim = maxYdimTmp.get();
297 const auto nKnotParametersPerY = 1 << nXdim;
298 const auto nKnotParameters = (1 << nXdim) * nYdim;
300 DataT iParameters[(1 << (2 * maxXdim)) * maxYdim];
305 for (int32_t
i = 0;
i < nXdim;
i++) {
306 indices[
i] = mGrid[
i].getLeftKnotIndexForU(u[
i]);
309 int32_t indicestmp[maxXdim];
310 for (int32_t
i = 0;
i < nKnotParametersPerY;
i++) {
311 for (int32_t k = 0; k < nXdim; k++) {
312 indicestmp[k] =
indices[k] + (
i / (1 << k)) % 2;
314 int32_t
index = TBase::getKnotIndex(indicestmp);
316 for (int32_t
j = 0;
j < nKnotParameters;
j++) {
322 constexpr auto maxInterpolations = (1 << (2 * maxXdim - 2)) * maxYdim;
324 DataT S0[maxInterpolations];
325 DataT D0[maxInterpolations];
326 DataT S1[maxInterpolations];
327 DataT D1[maxInterpolations];
329 int32_t nInterpolations = (1 << (2 * nXdim - 2)) * nYdim;
330 int32_t nKnots = 1 << (nXdim);
332 for (int32_t d = 0; d < nXdim; d++) {
333 DataT*
pointer[4] = {S0, D0, S1, D1};
334 for (int32_t
i = 0;
i < nKnots;
i++) {
335 for (int32_t
j = 0;
j < nKnots;
j++) {
336 int32_t pointernr = 2 * (
i % 2) + (
j % 2);
337 for (int32_t k = 0; k < nYdim; k++) {
338 pointer[pointernr][0] = iParameters[(
i * nKnots +
j) * nYdim + k];
345 DataT coordinate = u[d];
347 const TGridX& gridX = *((
const TGridX*)&(mGrid[d]));
348 gridX.interpolateU(nInterpolations, knotL, S0, D0, S1, D1, coordinate, iParameters);
349 nInterpolations /= 4;
353 for (int32_t
i = 0;
i < nYdim;
i++) {
354 S[
i] = iParameters[
i];
361 using TBase::mParameters;
371template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
381#if !defined(GPUCA_GPUCODE)
391 SplineSpec(
const int32_t nKnots[],
const int32_t*
const knotU[])
394 recreate(nKnots, knotU);
399 TBase::cloneFromObject(
v,
nullptr);
404 TBase::recreate(XdimT, YdimT, nKnots);
408 void recreate(
const int32_t nKnots[],
const int32_t*
const knotU[])
410 TBase::recreate(XdimT, YdimT, nKnots, knotU);
415 GPUd() constexpr int32_t getXdimensions()
const {
return XdimT; }
418 GPUd() constexpr int32_t getYdimensions()
const {
return YdimT; }
423 template <SafetyLevel SafeT = SafetyLevel::kSafe>
427 TBase::template interpolateU<SafeT>(XdimT, YdimT,
Parameters, u,
S);
432#if !defined(GPUCA_GPUCODE)
433 using TBase::recreate;
435 using TBase::interpolateU;
442template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
452#if !defined(GPUCA_GPUCODE)
459 this->recreate(nXdim, nYdim, nKnots);
463 SplineSpec(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[])
466 this->recreate(nXdim, nYdim, nKnots, knotU);
472 cloneFromObject(
v,
nullptr);
476 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[])
478 checkDimensions(nXdim, nYdim);
479 TBase::recreate(nXdim, nYdim, nKnots);
483 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[])
485 checkDimensions(nXdim, nYdim);
486 TBase::recreate(nXdim, nYdim, nKnots, knotU);
493 using TBase::interpolateU;
498 if (XdimT > 0 && nXdim != XdimT) {
502 if (XdimT < 0 && nXdim > abs(XdimT)) {
510 if (YdimT > 0 && nYdim != YdimT) {
514 if (YdimT < 0 && nYdim > abs(YdimT)) {
528template <
typename DataT,
int32_t XdimT>
530 :
public SplineSpec<DataT, XdimT, 1, SplineUtil::getSpec(XdimT, 999)>
538 GPUd() DataT interpolate(const DataT
x[])
const
541 TBase::interpolate(
x, &
S);
547 using TBase::interpolate;
Definition of FlatObject class.
Definition of Spline1D class.
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
SafetyLevel
Named enumeration for the safety level used by some methods.
GPUd() void setXrange(const DataT xMin[]
Set X range.
SplineContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() int32_t getXdimensions() const
_______________ Getters ________________________
int32_t mYdim
dimentionality of Y
GPUd() size_t getGridOffset(int32_t dimX) const
_______________ Technical stuff ________________________
~SplineContainer()=default
Destructor.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
int32_t mNknots
number of spline knots
Spline1D< DataT >::SafetyLevel SafetyLevel
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
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 __________________________
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
Spline1D< DataT > * mGrid
void setActualBufferAddress(char *actualFlatBufferPtr)
void setFutureBufferAddress(char *futureFlatBufferPtr)
GPUd() int32_t getNumberOfParametersPerKnot() const
Number of parameters per knot.
int32_t mXdim
_____________ Data members ____________
GPUd() const Spline1D< DataT > &getGrid(int32_t dimX) const
Get 1-D grid for dimX dimension.
DataT * mParameters
(transient!!) mXdim grids
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void print() const
Print method.
GPUd() int32_t getYdimensions() const
Get number of Y dimensions.
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.
Spline1D< DataT >::Knot Knot
GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const
Number of parameters per knot.
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
GPUd() DataT interpolate(const DataT x[]) const
Simplified interface for 1D: return the interpolated value.
GPUd() void interpolate(const DataT x[]
_______________ Interpolation math ________________________
GPUd() void interpolateU(int32_t inpXdim
Get interpolated value for S(u):inpXdim->inpYdim using spline parameters Parameters.
TBase::SafetyLevel SafetyLevel
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
GPUd() void interpolateU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
void recreate(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec()
Default constructor.
TVeryBase::SafetyLevel SafetyLevel
GPUd() const expr int32_t getXdimensions() const
Get number of X dimensions.
SplineSpec(const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const SplineSpec &v)
Copy constructor.
void recreate(const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const SplineSpec &v)
Copy constructor.
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec()
Default constructor.
TVeryBase::SafetyLevel SafetyLevel
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
void checkDimensions(int32_t &nXdim, int32_t &nYdim)
Check dimensions.
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
GLuint const GLchar * name
GLsizei GLenum const void * indices
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...