Project
Loading...
Searching...
No Matches
Spline2DSpec.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_SPLINE2DSPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE2DSPEC_H
19
20#include "Spline1D.h"
21#include "FlatObject.h"
22#include "GPUCommonDef.h"
23#include "SplineUtil.h"
24
25#if !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
26#include <Vc/Vc>
27#include <Vc/SimdArray>
28#endif
29
30class TFile;
31
32namespace o2
33{
34namespace gpu
35{
36
46template <typename DataT>
48{
49 public:
51 typedef typename Spline1D<DataT>::Knot Knot;
52
54
56 GPUd() static constexpr int32_t getVersion() { return (1 << 16) + Spline1D<DataT>::getVersion(); }
57
59
61 Spline2DContainer() = default;
62
65
67 ~Spline2DContainer() = default;
68
70
71#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
73 void approximateFunction(double x1Min, double x1Max, double x2Min, double x2Max,
74 std::function<void(double x1, double x2, double f[/*mYdim*/])> F,
75 int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4);
76
77 void approximateFunctionViaDataPoints(double x1Min, double x1Max, double x2Min, double x2Max,
78 std::function<void(double x1, double x2, double f[])> F,
79 int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2);
80#endif
81
83
84#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
86 int32_t writeToFile(TFile& outf, const char* name);
87
89 static Spline2DContainer* readFromFile(TFile& inpf, const char* name);
90#endif
91
93
95 GPUd() int32_t getYdimensions() const { return mYdim; }
96
98 GPUd() static constexpr size_t getParameterAlignmentBytes() { return 16; }
99
101 GPUd() int32_t getNumberOfParameters() const { return this->calcNumberOfParameters(mYdim); }
102
104 GPUd() size_t getSizeOfParameters() const { return sizeof(DataT) * this->getNumberOfParameters(); }
105
107 GPUd() int32_t getNumberOfKnots() const { return mGridX1.getNumberOfKnots() * mGridX2.getNumberOfKnots(); }
108
110 GPUd() const Spline1D<DataT>& getGridX1() const { return mGridX1; }
111
113 GPUd() const Spline1D<DataT>& getGridX2() const { return mGridX2; }
114
116 GPUd() const Spline1D<DataT>& getGrid(int32_t ix) const { return (ix == 0) ? mGridX1 : mGridX2; }
117
119 GPUd() void getKnotU(int32_t iKnot, int32_t& u1, int32_t& u2) const
120 {
121 u1 = mGridX1.getKnot(iKnot % mGridX1.getNumberOfKnots()).getU();
122 u2 = mGridX2.getKnot(iKnot / mGridX1.getNumberOfKnots()).getU();
123 }
124
126 GPUd() int32_t getKnotIndex(int32_t iKnotX1, int32_t iKnotX2) const
127 {
128 return mGridX1.getNumberOfKnots() * iKnotX2 + iKnotX1;
129 }
130
132 GPUd() DataT* getParameters() { return mParameters; }
133
135 GPUd() const DataT* getParameters() const { return mParameters; }
136
138
140 GPUd() size_t getGridX1Offset() const { return mGridX1.getFlatBufferPtr() - mFlatBufferPtr; }
141
143 GPUd() size_t getGridX2Offset() const { return mGridX2.getFlatBufferPtr() - mFlatBufferPtr; }
144
146 GPUd() void setXrange(DataT x1Min, DataT x1Max, DataT x2Min, DataT x2Max)
147 {
148 mGridX1.setXrange(x1Min, x1Max);
149 mGridX2.setXrange(x2Min, x2Max);
150 }
151
153 void print() const;
154
156
158 GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const { return (4 * nYdim) * getNumberOfKnots(); }
159
161
162#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE) // code invisible on GPU and in the standalone compilation
164 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
165#endif
166
168
171
172#if !defined(GPUCA_GPUCODE)
173 void cloneFromObject(const Spline2DContainer& obj, char* newFlatBufferPtr);
174 void moveBufferTo(char* newBufferPtr);
175#endif
176
178
179 void destroy();
180 void setActualBufferAddress(char* actualFlatBufferPtr);
181 void setFutureBufferAddress(char* futureFlatBufferPtr);
182
183 protected:
184#if !defined(GPUCA_GPUCODE)
186 void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2);
187
189 void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[]);
190#endif
191
193
194 int32_t mYdim = 0;
197 DataT* mParameters = nullptr;
198
200};
201
220template <typename DataT, int32_t YdimT, int32_t SpecT>
222
227template <typename DataT, int32_t YdimT>
228class Spline2DSpec<DataT, YdimT, 0>
229 : public Spline2DContainer<DataT>
230{
232
233 public:
235 typedef typename TBase::Knot Knot;
236
238
240 GPUd() void interpolate(DataT x1, DataT x2, GPUgeneric() DataT S[/*mYdim*/]) const
241 {
242 interpolateU<SafetyLevel::kSafe>(mYdim, mParameters, mGridX1.convXtoU(x1), mGridX2.convXtoU(x2), S);
243 }
244
246 template <SafetyLevel SafeT = SafetyLevel::kSafe>
247 GPUd() void interpolateUold(int32_t inpYdim, GPUgeneric() const DataT Parameters[],
248 DataT u1, DataT u2, GPUgeneric() DataT S[/*inpYdim*/]) const
249 {
250
251 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
252 const int32_t nYdim = nYdimTmp.get();
253
254 const auto maxYdim = SplineUtil::getMaxNdim<YdimT>(inpYdim);
255 const int32_t maxYdim4 = 4 * maxYdim.get();
256
257 const auto nYdim2 = nYdim * 2;
258 const auto nYdim4 = nYdim * 4;
259
260 const DataT& u = u1;
261 const DataT& v = u2;
262 int32_t nu = mGridX1.getNumberOfKnots();
263 int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
264 int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(v);
265
266 const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
267 const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
268
269 const DataT* par00 = Parameters + (nu * iv + iu) * nYdim4; // values { {Y1,Y2,Y3}, {Y1,Y2,Y3}'v, {Y1,Y2,Y3}'u, {Y1,Y2,Y3}''vu } at {u0, v0}
270 const DataT* par10 = par00 + nYdim4; // values { ... } at {u1, v0}
271 const DataT* par01 = par00 + nYdim4 * nu; // values { ... } at {u0, v1}
272 const DataT* par11 = par01 + nYdim4; // values { ... } at {u1, v1}
273
274 DataT Su0[maxYdim4]; // values { {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v0), {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v1) }, at u0
275 DataT Du0[maxYdim4]; // derivatives {}'_u at u0
276 DataT Su1[maxYdim4]; // values { {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v0), {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v1) }, at u1
277 DataT Du1[maxYdim4]; // derivatives {}'_u at u1
278
279 for (int32_t i = 0; i < nYdim2; i++) {
280 Su0[i] = par00[i];
281 Su0[nYdim2 + i] = par01[i];
282
283 Du0[i] = par00[nYdim2 + i];
284 Du0[nYdim2 + i] = par01[nYdim2 + i];
285
286 Su1[i] = par10[i];
287 Su1[nYdim2 + i] = par11[i];
288
289 Du1[i] = par10[nYdim2 + i];
290 Du1[nYdim2 + i] = par11[nYdim2 + i];
291 }
292
293 DataT parU[maxYdim4]; // interpolated values { {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v0), {Y1,Y2,Y3,Y1'v,Y2'v,Y3'v}(v1) } at u
294
295 typedef Spline1DSpec<DataT, 4 * YdimT, 0> TGridX1;
296 const TGridX1& gridX1 = reinterpret_cast<const TGridX1&>(mGridX1);
297
298 gridX1.interpolateU(nYdim4, knotU, Su0, Du0, Su1, Du1, u, parU);
299
300 const DataT* Sv0 = parU + 0;
301 const DataT* Dv0 = parU + nYdim;
302 const DataT* Sv1 = parU + nYdim2;
303 const DataT* Dv1 = parU + nYdim2 + nYdim;
304
305 typedef Spline1DSpec<DataT, YdimT, 0> TGridX2;
306 const TGridX2& gridX2 = reinterpret_cast<const TGridX2&>(mGridX2);
307 gridX2.interpolateU(nYdim, knotV, Sv0, Dv0, Sv1, Dv1, v, S);
308 }
309
311 template <SafetyLevel SafeT = SafetyLevel::kSafe>
312 GPUd() void interpolateU(int32_t inpYdim, GPUgeneric() const DataT Parameters[],
313 DataT u1, DataT u2, GPUgeneric() DataT S[/*inpYdim*/]) const
314 {
315
316 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
317 const int32_t nYdim = nYdimTmp.get();
318
319 // const auto maxYdim = SplineUtil::getMaxNdim<YdimT>(inpYdim);
320 // const int32_t maxYdim4 = 4 * maxYdim.get();
321
322 // const auto nYdim2 = nYdim * 2;
323 const auto nYdim4 = nYdim * 4;
324
325 const DataT& u = u1;
326 const DataT& v = u2;
327 int32_t nu = mGridX1.getNumberOfKnots();
328 int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
329 int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(v);
330
331 const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
332 const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
333
334 const DataT* A = Parameters + (nu * iv + iu) * nYdim4; // values { {Y1,Y2,Y3}, {Y1,Y2,Y3}'v, {Y1,Y2,Y3}'u, {Y1,Y2,Y3}''vu } at {u0, v0}
335 const DataT* B = A + nYdim4 * nu; // values { ... } at {u0, v1}
336
337 DataT dSl, dDl, dSr, dDr;
338 mGridX1.getUderivatives(knotU, u, dSl, dDl, dSr, dDr);
339 DataT dSd, dDd, dSu, dDu;
340 mGridX2.getUderivatives(knotV, v, dSd, dDd, dSu, dDu);
341
342 // when nYdim == 1:
343 // S = dSl * (dSd * A[0] + dDd * A[1]) + dDl * (dSd * A[2] + dDd * A[3]) +
344 // dSr * (dSd * A[4] + dDd * A[5]) + dDr * (dSd * A[6] + dDd * A[7]) +
345 // dSl * (dSu * B[0] + dDu * B[1]) + dDl * (dSu * B[2] + dDu * B[3]) +
346 // dSr * (dSu * B[4] + dDu * B[5]) + dDr * (dSu * B[6] + dDu * B[7]);
347
348 DataT a[8] = {dSl * dSd, dSl * dDd, dDl * dSd, dDl * dDd,
349 dSr * dSd, dSr * dDd, dDr * dSd, dDr * dDd};
350 DataT b[8] = {dSl * dSu, dSl * dDu, dDl * dSu, dDl * dDu,
351 dSr * dSu, dSr * dDu, dDr * dSu, dDr * dDu};
352
353 // S = sum a[i]*A[i] + b[i]*B[i]
354
355 for (int32_t dim = 0; dim < nYdim; dim++) {
356 S[dim] = 0;
357 for (int32_t i = 0; i < 8; i++) {
358 S[dim] += a[i] * A[nYdim * i + dim] + b[i] * B[nYdim * i + dim];
359 }
360 }
361 }
362
363 protected:
364 using TBase::mGridX1;
365 using TBase::mGridX2;
366 using TBase::mParameters;
367 using TBase::mYdim;
368 using TBase::TBase; // inherit constructors and hide them
369};
370
375template <typename DataT, int32_t YdimT>
376class Spline2DSpec<DataT, YdimT, 1>
377 : public Spline2DSpec<DataT, YdimT, 0>
378{
381
382 public:
384
385#if !defined(GPUCA_GPUCODE)
388
390 Spline2DSpec(int32_t nKnotsX1, int32_t nKnotsX2) : TBase()
391 {
392 recreate(nKnotsX1, nKnotsX2);
393 }
395 Spline2DSpec(int32_t nKnotsX1, const int32_t knotU1[],
396 int32_t nKnotsX2, const int32_t knotU2[])
397 : TBase()
398 {
399 recreate(nKnotsX1, knotU1, nKnotsX2, knotU2);
400 }
403 {
404 TBase::cloneFromObject(v, nullptr);
405 }
407 void recreate(int32_t nKnotsX1, int32_t nKnotsX2)
408 {
409 TBase::recreate(YdimT, nKnotsX1, nKnotsX2);
410 }
411
413 void recreate(int32_t nKnotsX1, const int32_t knotU1[],
414 int32_t nKnotsX2, const int32_t knotU2[])
415 {
416 TBase::recreate(YdimT, nKnotsX1, knotU1, nKnotsX2, knotU2);
417 }
418#endif
419
421 GPUd() constexpr int32_t getYdimensions() const { return YdimT; }
422
424 GPUd() int32_t getNumberOfParameters() const { return (4 * YdimT) * getNumberOfKnots(); }
425
427 GPUd() size_t getSizeOfParameters() const { return (sizeof(DataT) * 4 * YdimT) * getNumberOfKnots(); }
428
430
432 template <SafetyLevel SafeT = SafetyLevel::kSafe>
433 GPUd() void interpolateU(GPUgeneric() const DataT Parameters[],
434 DataT u1, DataT u2, GPUgeneric() DataT S[/*nYdim*/]) const
435 {
436 TBase::template interpolateU<SafeT>(YdimT, Parameters, u1, u2, S);
437 }
438
440 template <SafetyLevel SafeT = SafetyLevel::kSafe>
441 GPUd() void interpolateUold(GPUgeneric() const DataT Parameters[],
442 DataT u1, DataT u2, GPUgeneric() DataT S[/*nYdim*/]) const
443 {
444 TBase::template interpolateUold<SafeT>(YdimT, Parameters, u1, u2, S);
445 }
446
447 using TBase::getNumberOfKnots;
448
450 private:
451#if !defined(GPUCA_GPUCODE)
452 using TBase::recreate;
453#endif
454 using TBase::interpolateU;
455};
456
461template <typename DataT, int32_t YdimT>
462class Spline2DSpec<DataT, YdimT, 2>
463 : public Spline2DSpec<DataT, YdimT, 0>
464{
467
468 public:
470
471#if !defined(GPUCA_GPUCODE)
474
476 Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2) : TBase()
477 {
478 TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
479 }
480
482 Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[],
483 int32_t nKnotsX2, const int32_t knotU2[]) : TBase()
484 {
485 TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
486 }
487
490 {
491 cloneFromObject(v, nullptr);
492 }
493
495 void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
496 {
497 TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
498 }
499
501 void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[],
502 int32_t nKnotsX2, const int32_t knotU2[])
503 {
504 TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
505 }
506#endif
507
509
510 using TBase::interpolateU;
511};
512
516template <typename DataT>
517class Spline2DSpec<DataT, 1, 3>
518 : public Spline2DSpec<DataT, 1, SplineUtil::getSpec(999)>
519{
520 typedef Spline2DSpec<DataT, 1, SplineUtil::getSpec(999)> TBase;
521
522 public:
523 using TBase::TBase; // inherit constructors
524
526 GPUd() DataT interpolate(DataT x1, DataT x2) const
527 {
528 DataT S = 0.;
529 TBase::interpolate(x1, x2, &S);
530 return S;
531 }
532
533 // this parent method should be public anyhow,
534 // but w/o this extra declaration compiler gets confused
535 using TBase::interpolate;
536};
537} // namespace gpu
538} // namespace o2
539
540#endif
Definition of FlatObject class.
int32_t i
#define GPUgeneric()
Definition of Spline1D class.
Definition A.h:16
Definition B.h:16
GPUCA_GPUCODE.
Definition FlatObject.h:176
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
Definition FlatObject.h:526
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
Definition FlatObject.h:197
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
Definition FlatObject.h:194
SafetyLevel
Named enumeration for the safety level used by some methods.
int32_t int32_t &u2 const
mGridX2 setXrange(x2Min, x2Max)
DataT DataT DataT x2Max
GPUd() DataT *getParameters()
Get spline parameters.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void cloneFromObject(const Spline2DContainer &obj, char *newFlatBufferPtr)
void approximateFunction(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsU1=4, int32_t nAuxiliaryDataPointsU2=4)
_______________ Construction interface ________________________
Spline1D< DataT >::Knot Knot
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
void setActualBufferAddress(char *actualFlatBufferPtr)
void print() const
Print method.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
GPUd() size_t getGridX2Offset() const
Get offset of GridX2 flat data in the flat buffer.
GPUd() size_t getGridX1Offset() const
_______________ Technical stuff ________________________
Spline2DContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
GPUd() const Spline1D< DataT > &getGrid(int32_t ix) const
Get 1-D grid for X1 or X2 coordinate.
Spline1D< DataT > mGridX2
grid for V axis
Spline1D< DataT >::SafetyLevel SafetyLevel
int32_t mYdim
_____________ Data members ____________
~Spline2DContainer()=default
Destructor.
ClassDefNV(Spline2DContainer, 1)
(transient!!) F-dependent parameters of the spline
GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const
_______________ Expert tools _______________
GPUd() void setXrange(DataT x1Min
Set X range.
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
void moveBufferTo(char *newBufferPtr)
GPUd() const DataT *getParameters() const
Get spline parameters const.
GPUd() int32_t getYdimensions() const
_______________ Getters ________________________
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
GPUd() const Spline1D< DataT > &getGridX1() const
Get 1-D grid for the X1 coordinate.
static Spline2DContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
Spline1D< DataT > mGridX1
grid for U axis
Spline2DContainer(const Spline2DContainer &)=delete
Disable all other constructors.
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void setFutureBufferAddress(char *futureFlatBufferPtr)
void approximateFunctionViaDataPoints(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2)
GPUd() const Spline1D< DataT > &getGridX2() const
Get 1-D grid for the X2 coordinate.
GPUd() void interpolateU(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
GPUd() void interpolateUold(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
GPUd() void interpolate(DataT x1
_______________ Interpolation math ________________________
Spline2DSpec(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
Spline2DSpec(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
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 _______
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void recreate(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void recreate(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
GPUd() void interpolateUold(GPUgeneric() const DataT Parameters[]
Get interpolated value for an YdimT-dimensional S(u1,u2) using spline parameters Parameters.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
Definition SplineUtil.h:33
const GLdouble * v
Definition glcorearb.h:832
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLuint const GLchar * name
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...