From e9d3f18516a16a795ca0f57bee92e13b4e186072 Mon Sep 17 00:00:00 2001 From: shahoian Date: Fri, 12 Jul 2024 14:31:21 +0200 Subject: [PATCH] POD version of TPCFastSpaceChargeCorrection Created from the TPCFastTransform using: std::vector buff; // can be also pmr::vector from DPL make(..) const o2::gpu::TPCFastTransformPOD& pod = o2::gpu::TPCFastTransformPOD::create(buff, tpc_fast_transform); The buff vector will be expanded during creation and can be sent over DPL. On the receiving side, it should be cast as: const auto& podTransform = o2::gpu::TPCFastTransformPOD::get(pc.inputs().get>(ref)); No initialization is needed, the transform methods (at the moment all methods of TPCFastSpaceChargeCorrection are implemented) can be directly queried from the object received over sh.memory. --- GPU/TPCFastTransformation/CMakeLists.txt | 1 + .../TPCFastSpaceChargeCorrection.h | 2 + .../TPCFastTransformPOD.cxx | 138 +++++++ .../TPCFastTransformPOD.h | 354 ++++++++++++++++++ .../TPCFastTransformationLinkDef_O2.h | 1 + 5 files changed, 496 insertions(+) create mode 100644 GPU/TPCFastTransformation/TPCFastTransformPOD.cxx create mode 100644 GPU/TPCFastTransformation/TPCFastTransformPOD.h diff --git a/GPU/TPCFastTransformation/CMakeLists.txt b/GPU/TPCFastTransformation/CMakeLists.txt index b338e1492cc6c..c1c155805117e 100644 --- a/GPU/TPCFastTransformation/CMakeLists.txt +++ b/GPU/TPCFastTransformation/CMakeLists.txt @@ -25,6 +25,7 @@ set(SRCS TPCFastSpaceChargeCorrection.cxx TPCFastSpaceChargeCorrectionMap.cxx TPCFastTransform.cxx + TPCFastTransformPOD.cxx CorrectionMapsHelper.cxx ) diff --git a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h index ecbc3c4ad73f5..5560b7d8d8fef 100644 --- a/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h +++ b/GPU/TPCFastTransformation/TPCFastSpaceChargeCorrection.h @@ -37,6 +37,8 @@ namespace gpu /// class TPCFastSpaceChargeCorrection : public FlatObject { + friend class TPCFastTransformPOD; + public: /// /// \brief The struct contains necessary info for TPC padrow diff --git a/GPU/TPCFastTransformation/TPCFastTransformPOD.cxx b/GPU/TPCFastTransformation/TPCFastTransformPOD.cxx new file mode 100644 index 0000000000000..e82d81dabccce --- /dev/null +++ b/GPU/TPCFastTransformation/TPCFastTransformPOD.cxx @@ -0,0 +1,138 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file TPCFastTransformPOD.cxx +/// \brief Implementation of POD correction map +/// +/// \author ruben.shahoayn@cern.ch + +#include "TPCFastTransformPOD.h" + +namespace GPUCA_NAMESPACE +{ +namespace gpu +{ +#if !defined(GPUCA_GPUCODE) + +size_t TPCFastTransformPOD::estimateSize(const TPCFastTransform& src) +{ + // estimate size of own buffer + const auto& origCorr = src.getCorrection(); + const size_t selfSizeFix = sizeof(TPCFastTransformPOD); + size_t nextDynOffs = alignOffset(selfSizeFix); + nextDynOffs = alignOffset(nextDynOffs + origCorr.mNumberOfScenarios * sizeof(size_t)); // spline scenarios start here + // space for splines + for (int isc = 0; isc < origCorr.mNumberOfScenarios; isc++) { + const auto& spline = origCorr.mScenarioPtr[isc]; + nextDynOffs = alignOffset(nextDynOffs + sizeof(spline)); + } + // space for splines data + for (int is = 0; is < 3; is++) { + for (int slice = 0; slice < origCorr.mGeo.getNumberOfSlices(); slice++) { + for (int row = 0; row < NROWS; row++) { + const auto& spline = origCorr.getSpline(slice, row); + int nPar = spline.getNumberOfParameters(); + if (is == 1) { + nPar = nPar / 3; + } + if (is == 2) { + nPar = nPar * 2 / 3; + } + nextDynOffs += nPar * sizeof(float); + } + } + } + nextDynOffs = alignOffset(nextDynOffs); + return nextDynOffs; +} + +const TPCFastTransformPOD& TPCFastTransformPOD::create(char* buff, size_t buffSize, const TPCFastTransform& src) +{ + // instantiate objec to already created buffer of the right size + assert(buffSize > sizeof(TPCFastTransformPOD)); + const auto& origCorr = src.getCorrection(); + auto& podMap = getNonConst(buff); + + // copy fixed size data --- start + podMap.mNumberOfScenarios = origCorr.mNumberOfScenarios; + std::memcpy(&podMap.mGeo, &origCorr.mGeo, sizeof(TPCFastTransformGeo)); // copy geometry (fixed size) + for (int row = 0; row < NROWS; row++) { + podMap.mRowInfo[row] = origCorr.getRowInfo(row); // dataOffsetBytes will be modified later + } + for (int slice = 0; slice < TPCFastTransformGeo::getNumberOfSlices(); slice++) { + podMap.mSliceInfo[slice] = origCorr.getSliceInfo(slice); + for (int row = 0; row < NROWS; row++) { + podMap.mSliceRowInfo[NROWS * slice + row] = origCorr.getSliceRowInfo(slice, row); + } + } + podMap.mInterpolationSafetyMargin = origCorr.fInterpolationSafetyMargin; + podMap.mTimeStamp = origCorr.mTimeStamp; + // copy fixed size data --- end + + size_t nextDynOffs = alignOffset(sizeof(TPCFastTransformPOD)); + // copy slice scenarios + podMap.mOffsScenariosOffsets = nextDynOffs; // spline scenarios offsets start here + LOGP(debug, "Set mOffsScenariosOffsets = {}", podMap.mOffsScenariosOffsets); + nextDynOffs = alignOffset(nextDynOffs + podMap.mNumberOfScenarios * sizeof(size_t)); // spline scenarios start here + + // copy spline objects + size_t* scenOffs = reinterpret_cast(buff + podMap.mOffsScenariosOffsets); + for (int isc = 0; isc < origCorr.mNumberOfScenarios; isc++) { + scenOffs[isc] = nextDynOffs; + const auto& spline = origCorr.mScenarioPtr[isc]; + if (buffSize < nextDynOffs + sizeof(spline)) { + throw std::runtime_error(fmt::format("attempt to copy {} bytes for spline for scenario {} to {}, overflowing the buffer of size {}", sizeof(spline), isc, nextDynOffs + sizeof(spline), buffSize)); + } + std::memcpy(buff + scenOffs[isc], &spline, sizeof(spline)); + nextDynOffs = alignOffset(nextDynOffs + sizeof(spline)); + LOGP(debug, "Copy {} bytes for spline scenario {} (ptr:{}) to offsset {}", sizeof(spline), isc, (void*)&spline, scenOffs[isc]); + } + + // copy splines data + for (int is = 0; is < 3; is++) { + float* data = reinterpret_cast(buff + nextDynOffs); + LOGP(debug, "splinID={} start offset {} -> {}", is, nextDynOffs, (void*)data); + for (int slice = 0; slice < origCorr.mGeo.getNumberOfSlices(); slice++) { + podMap.mSplineDataOffsets[slice][is] = nextDynOffs; + size_t rowDataOffs = 0; + for (int row = 0; row < NROWS; row++) { + const auto& spline = origCorr.getSpline(slice, row); + const float* dataOr = origCorr.getSplineData(slice, row, is); + int nPar = spline.getNumberOfParameters(); + if (is == 1) { + nPar = nPar / 3; + } + if (is == 2) { + nPar = nPar * 2 / 3; + } + LOGP(debug, "Copying {} floats for spline{} of slice:{} row:{} to offset {}", nPar, is, slice, row, nextDynOffs); + size_t nbcopy = nPar * sizeof(float); + if (buffSize < nextDynOffs + nbcopy) { + throw std::runtime_error(fmt::format("attempt to copy {} bytes of data for spline{} of slice{}/row{} to {}, overflowing the buffer of size {}", nbcopy, is, slice, row, nextDynOffs, buffSize)); + } + std::memcpy(data, dataOr, nbcopy); + podMap.getRowInfo(row).dataOffsetBytes[is] = rowDataOffs; + rowDataOffs += nbcopy; + data += nPar; + nextDynOffs += nbcopy; + } + } + } + podMap.mTotalSize = alignOffset(nextDynOffs); + if (buffSize != podMap.mTotalSize) { + throw std::runtime_error(fmt::format("Estimated buffer size {} differs from filled one {}", buffSize, podMap.mTotalSize)); + } + return podMap; +} +#endif + +} // namespace gpu +} // namespace GPUCA_NAMESPACE diff --git a/GPU/TPCFastTransformation/TPCFastTransformPOD.h b/GPU/TPCFastTransformation/TPCFastTransformPOD.h new file mode 100644 index 0000000000000..a218142b6f29b --- /dev/null +++ b/GPU/TPCFastTransformation/TPCFastTransformPOD.h @@ -0,0 +1,354 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file TPCFastTransformPOD.h +/// \brief POD correction map +/// +/// \author ruben.shahoayn@cern.ch + +#ifndef ALICEO2_GPU_TPCFastTransformPOD_H +#define ALICEO2_GPU_TPCFastTransformPOD_H + +#include "TPCFastTransform.h" + +/* +Binary buffer should be cast to TPCFastTransformPOD class using static TPCFastTransformPOD& t = get(buffer); method, +so that the its head becomes `this` pointer of the object. + +First we have all the fixed size data members mentioned explicitly. Part of them is duplicating fixed size +data members of TPCFastSpaceChargeCorrection but those starting with mOffs... provide the offset in bytes +(wrt this) for dynamic data which cannot be declared as data member explicitly (since we cannot have any +pointer except `this`) but obtained via getters using stored offsets wrt `this`. +This is followed dynamic part itself. + +dynamic part layout: +1) size_t[ mNumberOfScenarios ] array starting at offset mOffsScenariosOffsets, each element is the offset +of distict spline object (scenario in TPCFastSpaceChargeCorrection) +2) size_t[ mNSplineIDs ] array starting at offset mOffsSplineDataOffsets, each element is the offset of the +beginning of splines data for give splineID + +*/ + +namespace GPUCA_NAMESPACE +{ +namespace gpu +{ + +class TPCFastTransformPOD +{ + public: + using SplineType = TPCFastSpaceChargeCorrection::SplineType; + using RowInfo = TPCFastSpaceChargeCorrection::RowInfo; + using RowActiveArea = TPCFastSpaceChargeCorrection::RowActiveArea; + using SliceRowInfo = TPCFastSpaceChargeCorrection::SliceRowInfo; + using SliceInfo = TPCFastSpaceChargeCorrection::SliceInfo; + + /// convert prefilled buffer to TPCFastTransformPOD + GPUd() static const TPCFastTransformPOD& get(const char* head) { return *reinterpret_cast(head); } + + /// _______________ The main method: cluster correction _______________________ + /// + GPUd() int getCorrection(int slice, int row, float u, float v, float& dx, float& du, float& dv) const; + + /// temporary method with the an way of calculating 2D spline + GPUd() int getCorrectionOld(int slice, int row, float u, float v, float& dx, float& du, float& dv) const; + + /// inverse correction: Corrected U and V -> coorrected X + GPUd() void getCorrectionInvCorrectedX(int slice, int row, float corrU, float corrV, float& corrX) const; + + /// inverse correction: Corrected U and V -> uncorrected U and V + GPUd() void getCorrectionInvUV(int slice, int row, float corrU, float corrV, float& nomU, float& nomV) const; + + /// maximal possible drift length of the active area + GPUd() float getMaxDriftLength(int slice, int row, float pad) const; + + /// maximal possible drift length of the active area + GPUd() float getMaxDriftLength(int slice, int row) const { return getSliceRowInfo(slice, row).activeArea.vMax; } + + /// maximal possible drift length of the active area + GPUd() float getMaxDriftLength(int slice) const { return getSliceInfo(slice).vMax; } + + /// _______________ Utilities _______________________________________________ + + /// shrink u,v coordinats to the TPC row area +/- fkInterpolationSafetyMargin + GPUd() void schrinkUV(int slice, int row, float& u, float& v) const; + + /// shrink corrected u,v coordinats to the TPC row area +/- fkInterpolationSafetyMargin + GPUd() void schrinkCorrectedUV(int slice, int row, float& corrU, float& corrV) const; + + /// convert u,v to internal grid coordinates + GPUd() void convUVtoGrid(int slice, int row, float u, float v, float& gridU, float& gridV) const; + + /// convert u,v to internal grid coordinates + GPUd() void convGridToUV(int slice, int row, float gridU, float gridV, float& u, float& v) const; + + /// convert corrected u,v to internal grid coordinates + GPUd() void convCorrectedUVtoGrid(int slice, int row, float cu, float cv, float& gridU, float& gridV) const; + + /// TPC geometry information + GPUd() const TPCFastTransformGeo& getGeometry() const { return mGeo; } + + /// Gives the time stamp of the current calibaration parameters + GPUd() long int getTimeStamp() const { return mTimeStamp; } + + /// Gives the interpolation safety marging around the TPC row. + GPUd() float getInterpolationSafetyMargin() const { return mInterpolationSafetyMargin; } + + /// Sets the time stamp of the current calibaration + GPUd() void setTimeStamp(long int v) { mTimeStamp = v; } + + /// Set safety marging for the interpolation around the TPC row. + /// Outside of this area the interpolation returns the boundary values. + GPUd() void setInterpolationSafetyMargin(float val) { mInterpolationSafetyMargin = val; } + + /// Gives TPC row info + GPUd() const RowInfo& getRowInfo(int row) const { return mRowInfo[row]; } + + /// Gives TPC slice info + GPUd() const SliceInfo& getSliceInfo(int slice) const { return mSliceInfo[slice]; } + + /// Gives a reference to a spline + GPUd() const SplineType& getSpline(int slice, int row) const { return *reinterpret_cast(getThis() + getScenarioOffset(getRowInfo(row).splineScenarioID)); } + + /// Gives pointer to spline data + GPUd() const float* getSplineData(int slice, int row, int iSpline = 0) const { return reinterpret_cast(getThis() + mSplineDataOffsets[slice][iSpline] + getRowInfo(row).dataOffsetBytes[iSpline]); } + + /// Gives TPC slice & row info + GPUd() const SliceRowInfo& getSliceRowInfo(int slice, int row) const { return mSliceRowInfo[NROWS * slice + row]; } + +#if !defined(GPUCA_GPUCODE) + /// Create POD transform from old flat-buffer one. Provided vector will serve as a buffer + template + static const TPCFastTransformPOD& create(V& destVector, const TPCFastTransform& src); +#endif + + static constexpr int NROWS = 152; + static constexpr int NSLICES = TPCFastTransformGeo::getNumberOfSlices(); + static constexpr int NSplineIDs = 3; ///< number of spline data sets for each slice/row + + private: +#if !defined(GPUCA_GPUCODE) + static constexpr size_t AlignmentBytes = 8; + static size_t alignOffset(size_t offs) + { + auto res = offs % AlignmentBytes; + return res ? offs + (AlignmentBytes - res) : offs; + } + static size_t estimateSize(const TPCFastTransform& src); + static const TPCFastTransformPOD& create(char* buff, size_t buffSize, const TPCFastTransform& src); + + ///< get address to which the offset in bytes must be added to arrive to particular dynamic part + GPUd() const char* getThis() const { return reinterpret_cast(this); } + GPUd() static TPCFastTransformPOD& getNonConst(char* head) { return *reinterpret_cast(head); } + +#endif + + /// Gives non-const TPC row info + GPUd() RowInfo& getRowInfo(int row) { return mRowInfo[row]; } + + ///< return offset of the spline object start (equivalent of mScenarioPtr in the TPCFastSpaceChargeCorrection) + GPUd() const size_t getScenarioOffset(int s) const { return (reinterpret_cast(getThis() + mOffsScenariosOffsets))[s]; } + + int mNumberOfScenarios{}; ///< Number of approximation spline scenarios + size_t mTotalSize{}; ///< total size of the buffer + size_t mOffsScenariosOffsets{}; ///< start of the array of mNumberOfScenarios offsets for each type of spline + size_t mSplineDataOffsets[TPCFastTransformGeo::getNumberOfSlices()][NSplineIDs]; ///< start of data for each slice and iSpline data + long int mTimeStamp{}; ///< time stamp of the current calibration + float mInterpolationSafetyMargin{0.1f}; // 10% area around the TPC row. Outside of this area the interpolation returns the boundary values. + + TPCFastTransformGeo mGeo; ///< TPC geometry information + TPCFastSpaceChargeCorrection::SliceInfo mSliceInfo[TPCFastTransformGeo::getNumberOfSlices()]; ///< SliceInfo array + RowInfo mRowInfo[NROWS]; + SliceRowInfo mSliceRowInfo[NROWS * TPCFastTransformGeo::getNumberOfSlices()]; + + ClassDefNV(TPCFastTransformPOD, 0) +}; + +GPUdi() int TPCFastTransformPOD::getCorrection(int slice, int row, float u, float v, float& dx, float& du, float& dv) const +{ + const SplineType& spline = getSpline(slice, row); + const float* splineData = getSplineData(slice, row); + float gridU = 0, gridV = 0; + convUVtoGrid(slice, row, u, v, gridU, gridV); + float dxuv[3]; + spline.interpolateU(splineData, gridU, gridV, dxuv); + dx = dxuv[0]; + du = dxuv[1]; + dv = dxuv[2]; + return 0; +} + +GPUdi() int TPCFastTransformPOD::getCorrectionOld(int slice, int row, float u, float v, float& dx, float& du, float& dv) const +{ + const SplineType& spline = getSpline(slice, row); + const float* splineData = getSplineData(slice, row); + float gridU = 0, gridV = 0; + convUVtoGrid(slice, row, u, v, gridU, gridV); + float dxuv[3]; + spline.interpolateUold(splineData, gridU, gridV, dxuv); + dx = dxuv[0]; + du = dxuv[1]; + dv = dxuv[2]; + return 0; +} + +GPUdi() void TPCFastTransformPOD::getCorrectionInvCorrectedX(int slice, int row, float corrU, float corrV, float& x) const +{ + float gridU, gridV; + convCorrectedUVtoGrid(slice, row, corrU, corrV, gridU, gridV); + + const Spline2D& spline = reinterpret_cast&>(getSpline(slice, row)); + const float* splineData = getSplineData(slice, row, 1); + float dx = 0; + spline.interpolateU(splineData, gridU, gridV, &dx); + x = mGeo.getRowInfo(row).x + dx; +} + +GPUdi() void TPCFastTransformPOD::getCorrectionInvUV(int slice, int row, float corrU, float corrV, float& nomU, float& nomV) const +{ + float gridU, gridV; + convCorrectedUVtoGrid(slice, row, corrU, corrV, gridU, gridV); + + const Spline2D& spline = reinterpret_cast&>(getSpline(slice, row)); + const float* splineData = getSplineData(slice, row, 2); + + float duv[2]; + spline.interpolateU(splineData, gridU, gridV, duv); + nomU = corrU - duv[0]; + nomV = corrV - duv[1]; +} + +GPUdi() float TPCFastTransformPOD::getMaxDriftLength(int slice, int row, float pad) const +{ + const RowActiveArea& area = getSliceRowInfo(slice, row).activeArea; + const float* c = area.maxDriftLengthCheb; + float x = -1.f + 2.f * pad / mGeo.getRowInfo(row).maxPad; + float y = c[0] + c[1] * x; + float f0 = 1.f; + float f1 = x; + x *= 2.f; + for (int i = 2; i < 5; i++) { + double f = x * f1 - f0; + y += c[i] * f; + f0 = f1; + f1 = f; + } + return y; +} + +GPUdi() void TPCFastTransformPOD::schrinkUV(int slice, int row, float& u, float& v) const +{ + /// shrink u,v coordinats to the TPC row area +/- mInterpolationSafetyMargin + + float uWidth05 = mGeo.getRowInfo(row).getUwidth() * (0.5f + mInterpolationSafetyMargin); + float vWidth = mGeo.getTPCzLength(slice); + + if (u < -uWidth05) { + u = -uWidth05; + } + if (u > uWidth05) { + u = uWidth05; + } + if (v < -0.1f * vWidth) { + v = -0.1f * vWidth; + } + if (v > 1.1f * vWidth) { + v = 1.1f * vWidth; + } +} + +GPUdi() void TPCFastTransformPOD::schrinkCorrectedUV(int slice, int row, float& corrU, float& corrV) const +{ + /// shrink corrected u,v coordinats to the TPC row area +/- mInterpolationSafetyMargin + + const SliceRowInfo& sliceRowInfo = getSliceRowInfo(slice, row); + + float uMargin = mInterpolationSafetyMargin * mGeo.getRowInfo(row).getUwidth(); + float vMargin = mInterpolationSafetyMargin * mGeo.getTPCzLength(slice); + + if (corrU < sliceRowInfo.activeArea.cuMin - uMargin) { + corrU = sliceRowInfo.activeArea.cuMin - uMargin; + } + + if (corrU > sliceRowInfo.activeArea.cuMax + uMargin) { + corrU = sliceRowInfo.activeArea.cuMax + uMargin; + } + + if (corrV < 0.f - vMargin) { + corrV = 0.f - vMargin; + } + + if (corrV > sliceRowInfo.activeArea.cvMax + vMargin) { + corrV = sliceRowInfo.activeArea.cvMax + vMargin; + } +} + +GPUdi() void TPCFastTransformPOD::convUVtoGrid(int slice, int row, float u, float v, float& gu, float& gv) const +{ + // TODO optimise !!! + gu = 0.f; + gv = 0.f; + + schrinkUV(slice, row, u, v); + + const SliceRowInfo& info = getSliceRowInfo(slice, row); + const SplineType& spline = getSpline(slice, row); + + float su0 = 0.f, sv0 = 0.f; + mGeo.convUVtoScaledUV(slice, row, u, info.gridV0, su0, sv0); + mGeo.convUVtoScaledUV(slice, row, u, v, gu, gv); + + gv = (gv - sv0) / (1.f - sv0); + gu *= spline.getGridX1().getUmax(); + gv *= spline.getGridX2().getUmax(); +} + +GPUdi() void TPCFastTransformPOD::convGridToUV(int slice, int row, float gridU, float gridV, float& u, float& v) const +{ + // TODO optimise + /// convert u,v to internal grid coordinates + float su0 = 0.f, sv0 = 0.f; + const SliceRowInfo& info = getSliceRowInfo(slice, row); + const SplineType& spline = getSpline(slice, row); + mGeo.convUVtoScaledUV(slice, row, 0.f, info.gridV0, su0, sv0); + float su = gridU / spline.getGridX1().getUmax(); + float sv = sv0 + gridV / spline.getGridX2().getUmax() * (1.f - sv0); + mGeo.convScaledUVtoUV(slice, row, su, sv, u, v); +} + +GPUdi() void TPCFastTransformPOD::convCorrectedUVtoGrid(int slice, int row, float corrU, float corrV, float& gridU, float& gridV) const +{ + schrinkCorrectedUV(slice, row, corrU, corrV); + + const SliceRowInfo& sliceRowInfo = getSliceRowInfo(slice, row); + + gridU = (corrU - sliceRowInfo.gridCorrU0) * sliceRowInfo.scaleCorrUtoGrid; + gridV = (corrV - sliceRowInfo.gridCorrV0) * sliceRowInfo.scaleCorrVtoGrid; +} + +#if !defined(GPUCA_GPUCODE) +/// Create POD transform from old flat-buffer one. Provided vector will serve as a buffer +template +const TPCFastTransformPOD& TPCFastTransformPOD::create(V& destVector, const TPCFastTransform& src) +{ + const auto& origCorr = src.getCorrection(); + size_t estSize = estimateSize(src); + destVector.resize(estSize); // allocate exact size + LOGP(debug, "OrigCorrSize:{} SelfSize: {} Estimated POS size: {}", src.getCorrection().getFlatBufferSize(), sizeof(TPCFastTransformPOD), estSize); + char* base = destVector.data(); + return create(destVector.data(), destVector.size(), src); +} +#endif + +} // namespace gpu +} // namespace GPUCA_NAMESPACE + +#endif // ALICEO2_GPU_TPCFastTransformPOD_H diff --git a/GPU/TPCFastTransformation/TPCFastTransformationLinkDef_O2.h b/GPU/TPCFastTransformation/TPCFastTransformationLinkDef_O2.h index 4421d44aab0c8..7482cbf52768a 100644 --- a/GPU/TPCFastTransformation/TPCFastTransformationLinkDef_O2.h +++ b/GPU/TPCFastTransformation/TPCFastTransformationLinkDef_O2.h @@ -63,6 +63,7 @@ #pragma link C++ class o2::gpu::TPCFastTransformGeo::RowInfo + ; #pragma link C++ class o2::gpu::TPCFastTransform + ; +#pragma link C++ class o2::gpu::TPCFastTransformPOD; #pragma link C++ class o2::gpu::TPCFastSpaceChargeCorrectionMap + ; #pragma link C++ class o2::gpu::TPCFastSpaceChargeCorrection::RowInfo + ;