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 = FlatObject::alignSize(nextDynOffs, SplineType::getParameterAlignmentBytes());
71 nextDynOffs += origCorr.mSectorDataSizeBytes[is] * TPCFastTransformGeo::getNumberOfSectors();
72 }
73 nextDynOffs = alignOffset(nextDynOffs);
74 return nextDynOffs;
75}
76
78{
79 LOGP(info, "TPCFastTransformPOD: this={:p} sizeof={} mApplyCorrection={} mNumberOfScenarios={} mTotalSize={} mOffsScenariosOffsets={} mT0={} mVdrift={} mLumi={} mIDC={}",
80 (void*)this, sizeof(*this), mApplyCorrection, mNumberOfScenarios, mTotalSize, mOffsScenariosOffsets, mT0, mVdrift, mLumi, mIDC);
81
82 for (int s = 0; s < TPCFastTransformGeo::getNumberOfSectors(); s++) {
83 for (int i = 0; i < NSplineIDs; i++) {
84 LOGP(info, "mSplineDataOffsets[{}][{}]={}", s, i, mSplineDataOffsets[s][i]);
85 }
86 }
87 const size_t scenOffset = getScenarioOffset(0);
88 const auto& spline = getSplineForRow(0);
89 LOGP(info, "scenOffset={} spline_addr={:p} expected={:p}", scenOffset, (void*)&spline, (void*)(getThis() + scenOffset));
90
91 const float* splineData = getCorrectionData(0, 0);
92 LOGP(info, "spline internal check: &spline={:p} splineData={:p} buf_start={:p} buf_end={:p}",
93 (void*)&spline, (void*)splineData,
94 (void*)getThis(), (void*)(getThis() + mTotalSize));
95
96 // check if splineData is within buffer
97 bool dataInBuf = (splineData >= (float*)getThis()) && (splineData < (float*)(getThis() + mTotalSize));
98 LOGP(info, "splineData in buffer: {}", dataInBuf);
99
100 LOGP(info, "splineData offset from buf_start = {}", (size_t)((const char*)splineData - getThis()));
101}
102
104{
105 // instantiate object to already created buffer of the right size
106 assert(buffSize > sizeof(TPCFastTransformPOD));
107 auto& podMap = getNonConst(buff);
108 podMap.mApplyCorrection = true; // by default always apply corrections
109
110 // copy fixed size data --- start
111 podMap.mNumberOfScenarios = origCorr.mNumberOfScenarios;
112
113 for (int row = 0; row < NROWS; row++) {
114 podMap.mRowInfos[row] = origCorr.getRowInfo(row);
115 }
116
117 podMap.mTimeStamp = origCorr.mTimeStamp;
118 //
119 // init data members coming from the TPCFastTrasform
120 podMap.mVdrift = 0.;
121 podMap.mT0 = 0.;
122 // copy fixed size data --- end
123
124 size_t nextDynOffs = alignOffset(sizeof(TPCFastTransformPOD));
125
126 // copy sector scenarios
127 podMap.mOffsScenariosOffsets = nextDynOffs; // spline scenarios offsets start here
128 LOGP(debug, "Set mOffsScenariosOffsets = {}", podMap.mOffsScenariosOffsets);
129 nextDynOffs = alignOffset(nextDynOffs + podMap.mNumberOfScenarios * sizeof(size_t)); // spline scenarios start here
130
131 podMap.mOffsFlatBufferOffsets = nextDynOffs; // <-- add this
132 nextDynOffs = alignOffset(nextDynOffs + podMap.mNumberOfScenarios * sizeof(size_t));
133
134 // copy spline objects
135 size_t* scenOffs = reinterpret_cast<size_t*>(buff + podMap.mOffsScenariosOffsets);
136 size_t* flatBufOffs = reinterpret_cast<size_t*>(buff + podMap.mOffsFlatBufferOffsets);
137
138 for (int isc = 0; isc < origCorr.mNumberOfScenarios; isc++) {
139 scenOffs[isc] = nextDynOffs;
140 const auto& spline = origCorr.mScenarioPtr[isc];
141 if (buffSize < nextDynOffs + sizeof(SplineType)) {
142 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));
143 }
144
145 // Placement-new a slim (NoFlatObject) spline and populate its schema from the source
146 auto* slimSpline = new (buff + scenOffs[isc]) SplineType();
147 slimSpline->importFrom(spline);
148 nextDynOffs = alignOffset(nextDynOffs + sizeof(SplineType));
149 LOGP(debug, "Write {} bytes for slim spline scenario {} to offset {}", sizeof(SplineType), isc, scenOffs[isc]);
150
151 // copy spline flat buffer (layout identical regardless of FlatBase)
152 flatBufOffs[isc] = nextDynOffs;
153 std::memcpy(buff + nextDynOffs, spline.getFlatBufferPtr(), spline.getFlatBufferSize());
154
155 // fix up internal pointers (mParameters, mGridX1.mKnots, mGridX2.mKnots)
156 slimSpline->setActualBufferAddress(buff + nextDynOffs);
157
158 nextDynOffs = alignOffset(nextDynOffs + spline.getFlatBufferSize());
159 }
160
161 // copy spline data
162 for (int is = 0; is < 3; is++) {
163 nextDynOffs = FlatObject::alignSize(nextDynOffs, SplineType::getParameterAlignmentBytes());
164 float* data = reinterpret_cast<float*>(buff + nextDynOffs);
165 LOGP(debug, "splinID={} start offset {} -> {}", is, nextDynOffs, (void*)data);
166
167 // metadata
168 size_t sectorDataSizeBytes = origCorr.mSectorDataSizeBytes[is];
169
170 for (int sector = 0; sector < TPCFastTransformGeo::getNumberOfSectors(); sector++) {
171 podMap.mSplineDataOffsets[sector][is] = nextDynOffs + sectorDataSizeBytes * sector;
172 }
173 size_t dataSize = TPCFastTransformGeo::getNumberOfSectors() * sectorDataSizeBytes;
174 if (buffSize < nextDynOffs + dataSize) {
175 throw std::runtime_error(fmt::format("attempt to copy {} bytes of data for spline{} to {}, overflowing the buffer of size {}", sectorDataSizeBytes, is, nextDynOffs, buffSize));
176 }
177 const char* dataOr = origCorr.mCorrectionData[is];
178 std::memcpy(data, dataOr, dataSize);
179 nextDynOffs += dataSize;
180 }
181 nextDynOffs = alignOffset(nextDynOffs);
182 podMap.mTotalSize = nextDynOffs;
183 if (buffSize != podMap.mTotalSize) {
184 throw std::runtime_error(fmt::format("Estimated buffer size {} differs from filled one {}", buffSize, podMap.mTotalSize));
185 }
186 return &getNonConst(buff);
187}
188
190{
191 // instantiate objec to already created buffer of the right size
192 auto podMap = create(buff, buffSize, src.getCorrection());
193 // set data members of TPCFastTransform
194 podMap->mVdrift = src.getVDrift();
195 podMap->mT0 = src.getT0();
196 podMap->mLumi = src.getLumi();
197 if (src.isIDCSet()) {
198 podMap->mIDC = src.getIDC();
199 }
200 podMap->mTimeStamp = src.getTimeStamp();
201 // copy fixed size data --- end
202 return podMap;
203}
204
205#ifndef GPUCA_STANDALONE
206
207bool TPCFastTransformPOD::test(const TPCFastSpaceChargeCorrection& origCorr, int npoints) const
208{
209 if (npoints < 1) {
210 return false;
211 }
212 std::vector<unsigned char> sector, row;
213 std::vector<float> y, z;
214 std::vector<std::array<float, 3>> corr0, corr1;
215 std::vector<std::array<float, 2>> corrInv0, corrInv1;
216 std::vector<float> corrInvX0, corrInvX1;
217
218 sector.reserve(npoints);
219 row.reserve(npoints);
220 y.reserve(npoints);
221 z.reserve(npoints);
222 corr0.reserve(npoints);
223 corr1.reserve(npoints);
224 corrInv0.reserve(npoints);
225 corrInv1.reserve(npoints);
226 corrInvX0.reserve(npoints);
227 corrInvX1.reserve(npoints);
228
229 for (int i = 0; i < npoints; i++) {
230 sector.push_back(gRandom->Integer(NSECTORS));
231 row.push_back(gRandom->Integer(NROWS));
232 y.push_back((gRandom->Rndm() - 0.5) * mGeo.getRowInfoMaxPad(row.back()) * mGeo.getRowInfoPadWidth(row.back()));
233 z.push_back((sector.back() < NSECTORS / 2 ? 1.f : -1.f) * gRandom->Rndm() * 240);
234 }
235 long origStart[3], origEnd[3], thisStart[3], thisEnd[3];
236 origStart[0] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
237 for (int i = 0; i < npoints; i++) {
238 std::array<float, 3> val;
239 origCorr.getCorrectionLocal(sector[i], row[i], y[i], z[i], val[0], val[1], val[2]);
240 corr0.push_back(val);
241 }
242
243 origEnd[0] = origStart[1] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
244 for (int i = 0; i < npoints; i++) {
245 std::array<float, 2> val;
246 origCorr.getCorrectionYZatRealYZ(sector[i], row[i], y[i], z[i], val[0], val[1]);
247 corrInv0.push_back(val);
248 }
249
250 origEnd[1] = origStart[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
251 for (int i = 0; i < npoints; i++) {
252 corrInvX0.push_back(origCorr.getCorrectionXatRealYZ(sector[i], row[i], y[i], z[i]));
253 }
254 //
255 origEnd[2] = thisStart[0] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
256 for (int i = 0; i < npoints; i++) {
257 std::array<float, 3> val;
258 this->getCorrectionLocal(sector[i], row[i], y[i], z[i], val[0], val[1], val[2]);
259 corr1.push_back(val);
260 }
261 thisEnd[0] = thisStart[1] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
262 for (int i = 0; i < npoints; i++) {
263 std::array<float, 2> val;
264 this->getCorrectionYZatRealYZ(sector[i], row[i], y[i], z[i], val[0], val[1]);
265 corrInv1.push_back(val);
266 }
267
268 thisEnd[1] = thisStart[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
269 for (int i = 0; i < npoints; i++) {
270 corrInvX1.push_back(this->getCorrectionXatRealYZ(sector[i], row[i], y[i], z[i]));
271 }
272 thisEnd[2] = std::chrono::time_point_cast<std::chrono::microseconds>(std::chrono::system_clock::now()).time_since_epoch().count();
273 //
274 size_t ndiff[3] = {};
275 for (int i = 0; i < npoints; i++) {
276 if (corr0[i][0] != corr1[i][0] || corr0[i][1] != corr1[i][1] || corr0[i][2] != corr1[i][2]) {
277 ndiff[0]++;
278 }
279 if (corrInv0[i][0] != corrInv1[i][0] || corrInv0[i][1] != corrInv1[i][1]) {
280 ndiff[1]++;
281 }
282 if (corrInvX0[i] != corrInvX1[i]) {
283 ndiff[2]++;
284 }
285 }
286 //
287 LOGP(info, " (ns per call) original this Nmissmatch");
288 LOGP(info, "getCorrection {:.3e} {:.3e} {}", double(origEnd[0] - origStart[0]) / npoints * 1000., double(thisEnd[0] - thisStart[0]) / npoints * 1000., ndiff[0]);
289 LOGP(info, "getCorrectionInvCorrectedX {:.3e} {:.3e} {}", double(origEnd[1] - origStart[1]) / npoints * 1000., double(thisEnd[1] - thisStart[1]) / npoints * 1000., ndiff[1]);
290 LOGP(info, "getCorrectionInvUV {:.3e} {:.3e} {}", double(origEnd[2] - origStart[2]) / npoints * 1000., double(thisEnd[2] - thisStart[2]) / npoints * 1000., ndiff[2]);
291 return ndiff[0] == 0 && ndiff[1] == 0 && ndiff[2] == 0;
292}
293
294#endif
295
296} // namespace gpu
297} // namespace o2
std::ostringstream debug
int32_t i
uint32_t res
Definition RawData.h:0
POD correction map.
static constexpr size_t alignSize(size_t sizeBytes, size_t alignmentBytes)
_______________ Generic utilities _______________________________________________
Definition FlatObject.h:275
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)