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
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
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual sector
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
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)
GLsizeiptr size
Definition glcorearb.h:659
GLenum GLsizei dataSize
Definition glcorearb.h:3994
GLint y
Definition glcorearb.h:270
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)