Project
Loading...
Searching...
No Matches
TPCFastTransformPOD.cxx
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#if !defined(GPUCA_NO_ROOT) && !defined(GPUCA_NO_FMT) && !defined(GPUCA_STANDALONE)
18#include <TRandom.h>
19#endif
20#include "TPCFastTransformPOD.h"
21#include "GPUDebugStreamer.h"
22#include "GPUCommonLogger.h"
23
24namespace o2
25{
26namespace gpu
27{
28
31{
32 size_t size = estimateSize(src);
33 destVector.alloc(size); // allocate exact size
34 LOGP(debug, "OrigCorrSize:{} SelfSize: {} Estimated POD size: {}", src.getCorrection().getFlatBufferSize(), sizeof(TPCFastTransformPOD), size);
35 auto res = create(destVector.getraw(), size, src);
36 res->setTimeStamp(src.getTimeStamp());
37 res->setVDrift(src.getVDrift());
38 res->setT0(src.getT0());
39 res->setLumi(src.getLumi());
40 if (src.isIDCSet()) {
41 res->setIDC(src.getIDC());
42 }
43 return res;
44}
45
47{
48 // create filling only part corresponding to TPCFastSpaceChargeCorrection. Data members coming from TPCFastTransform (e.g. VDrift, T0..) are not set
49 size_t size = estimateSize(origCorr);
50 destVector.alloc(size);
51 LOGP(debug, "OrigCorrSize:{} SelfSize: {} Estimated POD size: {}", origCorr.getFlatBufferSize(), sizeof(TPCFastTransformPOD), size);
52 return create(destVector.getraw(), size, origCorr);
53}
54
56{
57 // estimate size of own buffer
58 const size_t selfSizeFix = sizeof(TPCFastTransformPOD);
59 size_t nextDynOffs = alignOffset(selfSizeFix);
60 nextDynOffs = alignOffset(nextDynOffs + origCorr.mNumberOfScenarios * sizeof(size_t)); // spline scenarios start here
61 nextDynOffs = alignOffset(nextDynOffs + origCorr.mNumberOfScenarios * sizeof(size_t)); // flatBufOffs array
62 // space for splines (use sizeof(SplineType) = slim size, not the origCorr spline size)
63 for (int isc = 0; isc < origCorr.mNumberOfScenarios; isc++) {
64 const auto& spline = origCorr.mScenarioPtr[isc];
65 nextDynOffs = alignOffset(nextDynOffs + sizeof(SplineType));
66 nextDynOffs = alignOffset(nextDynOffs + spline.getFlatBufferSize());
67 }
68 // space for splines data
69 for (int is = 0; is < 3; is++) {
70 nextDynOffs += origCorr.mSectorDataSizeBytes[is] * TPCFastTransformGeo::getNumberOfSectors();
71 }
72 nextDynOffs = alignOffset(nextDynOffs);
73 return nextDynOffs;
74}
75
77{
78 LOGP(info, "TPCFastTransformPOD: this={:p} sizeof={} mApplyCorrection={} mNumberOfScenarios={} mTotalSize={} mOffsScenariosOffsets={} mT0={} mVdrift={} mLumi={} mIDC={}",
79 (void*)this, sizeof(*this), mApplyCorrection, mNumberOfScenarios, mTotalSize, mOffsScenariosOffsets, mT0, mVdrift, mLumi, mIDC);
80
81 for (int s = 0; s < TPCFastTransformGeo::getNumberOfSectors(); s++) {
82 for (int i = 0; i < NSplineIDs; i++) {
83 LOGP(info, "mSplineDataOffsets[{}][{}]={}", s, i, mSplineDataOffsets[s][i]);
84 }
85 }
86 const size_t scenOffset = getScenarioOffset(0);
87 const auto& spline = getSplineForRow(0);
88 LOGP(info, "scenOffset={} spline_addr={:p} expected={:p}", scenOffset, (void*)&spline, (void*)(getThis() + scenOffset));
89
90 const float* splineData = getCorrectionData(0, 0);
91 LOGP(info, "spline internal check: &spline={:p} splineData={:p} buf_start={:p} buf_end={:p}",
92 (void*)&spline, (void*)splineData,
93 (void*)getThis(), (void*)(getThis() + mTotalSize));
94
95 // check if splineData is within buffer
96 bool dataInBuf = (splineData >= (float*)getThis()) && (splineData < (float*)(getThis() + mTotalSize));
97 LOGP(info, "splineData in buffer: {}", dataInBuf);
98
99 LOGP(info, "splineData offset from buf_start = {}", (size_t)((const char*)splineData - getThis()));
100}
101
103{
104 // instantiate object to already created buffer of the right size
105 assert(buffSize > sizeof(TPCFastTransformPOD));
106 auto& podMap = getNonConst(buff);
107 podMap.mApplyCorrection = true; // by default always apply corrections
108
109 // copy fixed size data --- start
110 podMap.mNumberOfScenarios = origCorr.mNumberOfScenarios;
111
112 for (int row = 0; row < NROWS; row++) {
113 podMap.mRowInfos[row] = origCorr.getRowInfo(row);
114 }
115
116 podMap.mTimeStamp = origCorr.mTimeStamp;
117 //
118 // init data members coming from the TPCFastTrasform
119 podMap.mVdrift = 0.;
120 podMap.mT0 = 0.;
121 // copy fixed size data --- end
122
123 size_t nextDynOffs = alignOffset(sizeof(TPCFastTransformPOD));
124
125 // copy sector scenarios
126 podMap.mOffsScenariosOffsets = nextDynOffs; // spline scenarios offsets start here
127 LOGP(debug, "Set mOffsScenariosOffsets = {}", podMap.mOffsScenariosOffsets);
128 nextDynOffs = alignOffset(nextDynOffs + podMap.mNumberOfScenarios * sizeof(size_t)); // spline scenarios start here
129
130 podMap.mOffsFlatBufferOffsets = nextDynOffs; // <-- add this
131 nextDynOffs = alignOffset(nextDynOffs + podMap.mNumberOfScenarios * sizeof(size_t));
132
133 // copy spline objects
134 size_t* scenOffs = reinterpret_cast<size_t*>(buff + podMap.mOffsScenariosOffsets);
135 size_t* flatBufOffs = reinterpret_cast<size_t*>(buff + podMap.mOffsFlatBufferOffsets);
136
137 for (int isc = 0; isc < origCorr.mNumberOfScenarios; isc++) {
138 scenOffs[isc] = nextDynOffs;
139 const auto& spline = origCorr.mScenarioPtr[isc];
140 if (buffSize < nextDynOffs + sizeof(SplineType)) {
141 throw std::runtime_error(fmt::format("attempt to write {} bytes for slim spline for scenario {} to {}, overflowing the buffer of size {}", sizeof(SplineType), isc, nextDynOffs + sizeof(SplineType), buffSize));
142 }
143
144 // Placement-new a slim (NoFlatObject) spline and populate its schema from the source
145 auto* slimSpline = new (buff + scenOffs[isc]) SplineType();
146 slimSpline->importFrom(spline);
147 nextDynOffs = alignOffset(nextDynOffs + sizeof(SplineType));
148 LOGP(debug, "Write {} bytes for slim spline scenario {} to offset {}", sizeof(SplineType), isc, scenOffs[isc]);
149
150 // copy spline flat buffer (layout identical regardless of FlatBase)
151 flatBufOffs[isc] = nextDynOffs;
152 std::memcpy(buff + nextDynOffs, spline.getFlatBufferPtr(), spline.getFlatBufferSize());
153
154 // fix up internal pointers (mParameters, mGridX1.mKnots, mGridX2.mKnots)
155 slimSpline->setActualBufferAddress(buff + nextDynOffs);
156
157 nextDynOffs = alignOffset(nextDynOffs + spline.getFlatBufferSize());
158 }
159
160 // copy spline data
161 for (int is = 0; is < 3; is++) {
162 float* data = reinterpret_cast<float*>(buff + nextDynOffs);
163 LOGP(debug, "splinID={} start offset {} -> {}", is, nextDynOffs, (void*)data);
164
165 // metadata
166 size_t sectorDataSizeBytes = origCorr.mSectorDataSizeBytes[is];
167
168 for (int sector = 0; sector < TPCFastTransformGeo::getNumberOfSectors(); sector++) {
169 podMap.mSplineDataOffsets[sector][is] = nextDynOffs + sectorDataSizeBytes * sector;
170 }
171 size_t dataSize = TPCFastTransformGeo::getNumberOfSectors() * sectorDataSizeBytes;
172 if (buffSize < nextDynOffs + dataSize) {
173 throw std::runtime_error(fmt::format("attempt to copy {} bytes of data for spline{} to {}, overflowing the buffer of size {}", sectorDataSizeBytes, is, nextDynOffs, buffSize));
174 }
175 const char* dataOr = origCorr.mCorrectionData[is];
176 std::memcpy(data, dataOr, dataSize);
177 nextDynOffs += dataSize;
178 }
179 nextDynOffs = alignOffset(nextDynOffs);
180 podMap.mTotalSize = nextDynOffs;
181 if (buffSize != podMap.mTotalSize) {
182 throw std::runtime_error(fmt::format("Estimated buffer size {} differs from filled one {}", buffSize, podMap.mTotalSize));
183 }
184 return &getNonConst(buff);
185}
186
188{
189 // instantiate objec to already created buffer of the right size
190 auto podMap = create(buff, buffSize, src.getCorrection());
191 // set data members of TPCFastTransform
192 podMap->mVdrift = src.getVDrift();
193 podMap->mT0 = src.getT0();
194 podMap->mLumi = src.getLumi();
195 if (src.isIDCSet()) {
196 podMap->mIDC = src.getIDC();
197 }
198 podMap->mTimeStamp = src.getTimeStamp();
199 // copy fixed size data --- end
200 return podMap;
201}
202
203#ifndef GPUCA_STANDALONE
204
205bool TPCFastTransformPOD::test(const TPCFastSpaceChargeCorrection& origCorr, int npoints) const
206{
207 if (npoints < 1) {
208 return false;
209 }
210 std::vector<unsigned char> sector, row;
211 std::vector<float> y, z;
212 std::vector<std::array<float, 3>> corr0, corr1;
213 std::vector<std::array<float, 2>> corrInv0, corrInv1;
214 std::vector<float> corrInvX0, corrInvX1;
215
216 sector.reserve(npoints);
217 row.reserve(npoints);
218 y.reserve(npoints);
219 z.reserve(npoints);
220 corr0.reserve(npoints);
221 corr1.reserve(npoints);
222 corrInv0.reserve(npoints);
223 corrInv1.reserve(npoints);
224 corrInvX0.reserve(npoints);
225 corrInvX1.reserve(npoints);
226
227 for (int i = 0; i < npoints; i++) {
228 sector.push_back(gRandom->Integer(NSECTORS));
229 row.push_back(gRandom->Integer(NROWS));
230 y.push_back((gRandom->Rndm() - 0.5) * mGeo.getRowInfoMaxPad(row.back()) * mGeo.getRowInfoPadWidth(row.back()));
231 z.push_back((sector.back() < NSECTORS / 2 ? 1.f : -1.f) * gRandom->Rndm() * 240);
232 }
233 long origStart[3], origEnd[3], thisStart[3], thisEnd[3];
234 origStart[0] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
235 for (int i = 0; i < npoints; i++) {
236 std::array<float, 3> val;
237 origCorr.getCorrectionLocal(sector[i], row[i], y[i], z[i], val[0], val[1], val[2]);
238 corr0.push_back(val);
239 }
240
241 origEnd[0] = origStart[1] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
242 for (int i = 0; i < npoints; i++) {
243 std::array<float, 2> val;
244 origCorr.getCorrectionYZatRealYZ(sector[i], row[i], y[i], z[i], val[0], val[1]);
245 corrInv0.push_back(val);
246 }
247
248 origEnd[1] = origStart[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
249 for (int i = 0; i < npoints; i++) {
250 corrInvX0.push_back(origCorr.getCorrectionXatRealYZ(sector[i], row[i], y[i], z[i]));
251 }
252 //
253 origEnd[2] = thisStart[0] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
254 for (int i = 0; i < npoints; i++) {
255 std::array<float, 3> val;
256 this->getCorrectionLocal(sector[i], row[i], y[i], z[i], val[0], val[1], val[2]);
257 corr1.push_back(val);
258 }
259 thisEnd[0] = thisStart[1] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
260 for (int i = 0; i < npoints; i++) {
261 std::array<float, 2> val;
262 this->getCorrectionYZatRealYZ(sector[i], row[i], y[i], z[i], val[0], val[1]);
263 corrInv1.push_back(val);
264 }
265
266 thisEnd[1] = thisStart[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
267 for (int i = 0; i < npoints; i++) {
268 corrInvX1.push_back(this->getCorrectionXatRealYZ(sector[i], row[i], y[i], z[i]));
269 }
270 thisEnd[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
271 //
272 size_t ndiff[3] = {};
273 for (int i = 0; i < npoints; i++) {
274 if (corr0[i][0] != corr1[i][0] || corr0[i][1] != corr1[i][1] || corr0[i][2] != corr1[i][2]) {
275 ndiff[0]++;
276 }
277 if (corrInv0[i][0] != corrInv1[i][0] || corrInv0[i][1] != corrInv1[i][1]) {
278 ndiff[1]++;
279 }
280 if (corrInvX0[i] != corrInvX1[i]) {
281 ndiff[2]++;
282 }
283 }
284 //
285 LOGP(info, " (ns per call) original this Nmissmatch");
286 LOGP(info, "getCorrection {:.3e} {:.3e} {}", double(origEnd[0] - origStart[0]) / npoints * 1000., double(thisEnd[0] - thisStart[0]) / npoints * 1000., ndiff[0]);
287 LOGP(info, "getCorrectionInvCorrectedX {:.3e} {:.3e} {}", double(origEnd[1] - origStart[1]) / npoints * 1000., double(thisEnd[1] - thisStart[1]) / npoints * 1000., ndiff[1]);
288 LOGP(info, "getCorrectionInvUV {:.3e} {:.3e} {}", double(origEnd[2] - origStart[2]) / npoints * 1000., double(thisEnd[2] - thisStart[2]) / npoints * 1000., ndiff[2]);
289 return ndiff[0] == 0 && ndiff[1] == 0 && ndiff[2] == 0;
290}
291
292#endif
293
294} // namespace gpu
295} // namespace o2
std::ostringstream debug
int32_t i
uint32_t res
Definition RawData.h:0
POD correction map.
Forward declaration — specializations below select ClassDefNV based on FlatBase.
Definition Spline2D.h:104
static constexpr int32_t getNumberOfSectors()
_______________ Getters _________________________________
bool test(const TPCFastTransform &src, int32_t npoints=100000) const
TPCFastSpaceChargeCorrection::SlimSplineType SplineType
static TPCFastTransformPOD * create(aligned_unique_buffer_ptr< TPCFastTransformPOD > &destVector, const TPCFastTransform &src)
Create POD transform from old flat-buffer one. Provided vector will serve as a buffer.
int32_t float float float float float & z
void print() const
Print method.
int32_t float float float float & y
static size_t estimateSize(const TPCFastTransform &src)
static constexpr int NSplineIDs
number of spline data sets for each sector/row
GLenum src
Definition glcorearb.h:1767
GLsizeiptr size
Definition glcorearb.h:659
GLenum GLsizei dataSize
Definition glcorearb.h:3994
GLboolean * data
Definition glcorearb.h:298
GLuint GLfloat * val
Definition glcorearb.h:1582
GLdouble GLdouble GLdouble z
Definition glcorearb.h:843
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
static constexpr float getRowInfoPadWidth(uint32_t row)
static constexpr int32_t getRowInfoMaxPad(uint32_t row)