Skip to content

Commit ea4d277

Browse files
committed
Momentum vector usage created by neural network
1 parent bd18612 commit ea4d277

11 files changed

Lines changed: 95 additions & 8 deletions

File tree

DataFormats/Detectors/TPC/include/DataFormatsTPC/ClusterNative.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ struct ClusterNative {
6666
static constexpr int scaleSaturatedQtot = 8;
6767
static constexpr int maxRegularQtot = 25 * 1024;
6868
static constexpr int maxSaturatedQtot = (USHRT_MAX - maxRegularQtot) * scaleSaturatedQtot;
69+
static constexpr float scaleNNDirectionPacked = 2048.f;
70+
static constexpr int16_t invalidNNDirectionPacked = -32768;
71+
static constexpr float maxNNDirection = 32767.f / scaleNNDirectionPacked;
6972

7073
uint32_t timeFlagsPacked; //< Contains the time in the lower 24 bits in a packed format, contains the flags in the
7174
// upper 8 bits
@@ -74,18 +77,40 @@ struct ClusterNative {
7477
uint8_t sigmaPadPacked; //< Sigma of the pad in packed format
7578
uint16_t qMax; //< QMax of the cluster
7679
uint16_t qTotPacked; //< Total charge of the cluster
80+
int16_t nnDydxPacked = invalidNNDirectionPacked;
81+
int16_t nnDzdxPacked = invalidNNDirectionPacked;
7782

7883
GPUd() static uint16_t packPad(float pad) { return (uint16_t)(pad * scalePadPacked + 0.5); }
7984
GPUd() static uint32_t packTime(float time) { return (uint32_t)(time * scaleTimePacked + 0.5); }
8085
GPUd() static float unpackPad(uint16_t pad) { return float(pad) * (1.f / scalePadPacked); }
8186
GPUd() static float unpackTime(uint32_t time) { return float(time) * (1.f / scaleTimePacked); }
87+
GPUd() static int16_t packNNDirection(float v)
88+
{
89+
v = v < -maxNNDirection ? -maxNNDirection : (v > maxNNDirection ? maxNNDirection : v);
90+
return static_cast<int16_t>(v * scaleNNDirectionPacked + (v >= 0.f ? 0.5f : -0.5f));
91+
}
92+
GPUd() static float unpackNNDirection(int16_t v) { return float(v) * (1.f / scaleNNDirectionPacked); }
8293

8394
GPUdDefault() ClusterNative() = default;
8495
GPUd() ClusterNative(uint32_t time, uint8_t flags, uint16_t pad, uint8_t sigmaTime, uint8_t sigmaPad, uint16_t qmax, uint16_t qtotPacked) : padPacked(pad), sigmaTimePacked(sigmaTime), sigmaPadPacked(sigmaPad), qMax(qmax), qTotPacked(qtotPacked)
8596
{
8697
setTimePackedFlags(time, flags);
8798
}
8899

100+
GPUd() bool hasNNDirection() const { return nnDydxPacked != invalidNNDirectionPacked && nnDzdxPacked != invalidNNDirectionPacked; }
101+
GPUd() float getNNDydx() const { return unpackNNDirection(nnDydxPacked); }
102+
GPUd() float getNNDzdx() const { return unpackNNDirection(nnDzdxPacked); }
103+
GPUd() void setNNDirection(float dydx, float dzdx)
104+
{
105+
nnDydxPacked = packNNDirection(dydx);
106+
nnDzdxPacked = packNNDirection(dzdx);
107+
}
108+
GPUd() void clearNNDirection()
109+
{
110+
nnDydxPacked = invalidNNDirectionPacked;
111+
nnDzdxPacked = invalidNNDirectionPacked;
112+
}
113+
89114
GPUd() uint16_t getQmax() const { return qMax; }
90115
GPUd() uint32_t getQtot() const { return isSaturated() ? getSaturatedQtot() : (uint32_t)qTotPacked; }
91116
GPUd() uint8_t getFlags() const { return timeFlagsPacked >> 24; }
@@ -187,6 +212,10 @@ struct ClusterNative {
187212
return (this->qMax < rhs.qMax);
188213
} else if (this->qTotPacked != rhs.qTotPacked) {
189214
return (this->getQtot() < rhs.getQtot());
215+
} else if (this->nnDydxPacked != rhs.nnDydxPacked) {
216+
return (this->nnDydxPacked < rhs.nnDydxPacked);
217+
} else if (this->nnDzdxPacked != rhs.nnDzdxPacked) {
218+
return (this->nnDzdxPacked < rhs.nnDzdxPacked);
190219
} else {
191220
return (this->getFlags() < rhs.getFlags());
192221
}
@@ -200,6 +229,8 @@ struct ClusterNative {
200229
this->sigmaPadPacked == rhs.sigmaPadPacked &&
201230
this->qMax == rhs.qMax &&
202231
this->qTotPacked == rhs.qTotPacked &&
232+
this->nnDydxPacked == rhs.nnDydxPacked &&
233+
this->nnDzdxPacked == rhs.nnDzdxPacked &&
203234
this->getFlags() == rhs.getFlags();
204235
}
205236

GPU/GPUTracking/Base/GPUConstantMem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ GPUdi() GPUconstantref() const GPUParam& GPUProcessor::Param() const
111111
return GetConstantMem()->param;
112112
}
113113

114+
GPUdi() const o2::tpc::ClusterNativeAccess* GPUProcessor::GetClustersNative() const
115+
{
116+
return GetConstantMem()->ioPtrs.clustersNative;
117+
}
118+
114119
GPUdi() void GPUProcessor::raiseError(uint32_t code, uint32_t param1, uint32_t param2, uint32_t param3) const
115120
{
116121
GetConstantMem()->errorCodes.raiseError(code, param1, param2, param3);

GPU/GPUTracking/Base/GPUProcessor.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@
2323
#include <algorithm>
2424
#endif
2525

26+
namespace o2::tpc
27+
{
28+
struct ClusterNativeAccess;
29+
}
30+
2631
namespace o2::gpu
2732
{
2833
struct GPUTrackingInOutPointers;
@@ -49,6 +54,7 @@ class GPUProcessor
4954
#endif
5055

5156
GPUd() GPUconstantref() const GPUConstantMem* GetConstantMem() const; // Body in GPUConstantMem.h to avoid circular headers
57+
GPUd() const o2::tpc::ClusterNativeAccess* GetClustersNative() const; // ...
5258
GPUd() GPUconstantref() const GPUParam& Param() const; // ...
5359
GPUd() void raiseError(uint32_t code, uint32_t param1 = 0, uint32_t param2 = 0, uint32_t param3 = 0) const;
5460
const GPUReconstruction& GetRec() const { return *mRec; }

GPU/GPUTracking/Definitions/GPUSettingsList.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ AddOption(nnLoadFromCCDB, int, 0, "", 0, "If 1 networks are fetched from ccdb, e
295295
AddOption(nnCCDBDumpToFile, int, 0, "", 0, "If 1, additionally dump fetched CCDB networks to nnLocalFolder")
296296
AddOption(nnLocalFolder, std::string, ".", "", 0, "Local folder in which the networks will be fetched")
297297
AddOption(nnCCDBPath, std::string, "Users/c/csonnabe/TPC/Clusterization", "", 0, "Folder path containing the networks")
298-
AddOption(nnCCDBWithMomentum, std::string, "", "", 0, "Distinguishes between the network with and without momentum output for the regression")
298+
AddOption(nnCCDBWithMomentum, std::string, "0", "", 0, "Distinguishes between the network with and without momentum output for the regression")
299299
AddOption(nnCCDBClassificationLayerType, std::string, "FC", "", 0, "Distinguishes between network with different layer types. Options: FC, CNN")
300300
AddOption(nnCCDBRegressionLayerType, std::string, "FC", "", 0, "Distinguishes between network with different layer types. Options: FC, CNN")
301301
AddOption(nnCCDBBeamType, std::string, "pp", "", 0, "Distinguishes between networks trained for different beam types. Options: pp, pPb, PbPb")

GPU/GPUTracking/SectorTracker/GPUTPCNeighboursFinder.cxx

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,15 +120,17 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int32_t /*nBlocks*/, int32_t nTh
120120
const GPUglobalref() cahit2& hitData = pHitData[lHitNumberOffset + ih];
121121
const float y = y0 + hitData.x * stepY;
122122
const float z = z0 + hitData.y * stepZ;
123+
float nnDydx = 0.f, nnDzdx = 0.f;
124+
const bool useNNDir = tracker.HitNNDirection(row, ih, nnDydx, nnDzdx) && CAMath::Abs(nnDydx) < 10.f && CAMath::Abs(nnDzdx) < 10.f;
123125

124126
uint32_t nNeighUp = 0;
125127
float minZ, maxZ, minY, maxY;
126128
int32_t binYmin, binYmax, binZmin, binZmax;
127129
int32_t nY;
128130

129131
{ // area in the upper row
130-
const float yy = y * s.mUpTx;
131-
const float zz = z * kAreaSlopeZUp;
132+
const float yy = useNNDir ? y + nnDydx * s.mUpDx : y * s.mUpTx;
133+
const float zz = useNNDir ? z + nnDzdx * s.mUpDx : z * kAreaSlopeZUp;
132134
minZ = zz - kAreaSizeZUp;
133135
maxZ = zz + kAreaSizeZUp;
134136
minY = yy - kAreaSizeY;
@@ -196,8 +198,8 @@ GPUdii() void GPUTPCNeighboursFinder::Thread<0>(int32_t /*nBlocks*/, int32_t nTh
196198
}
197199

198200
{ // area in the lower row
199-
const float yy = y * s.mDnTx;
200-
const float zz = z * kAreaSlopeZDn;
201+
const float yy = useNNDir ? y + nnDydx * s.mDnDx : y * s.mDnTx;
202+
const float zz = useNNDir ? z + nnDzdx * s.mDnDx : z * kAreaSlopeZDn;
201203
minZ = zz - kAreaSizeZDn;
202204
maxZ = zz + kAreaSizeZDn;
203205
minY = yy - kAreaSizeY;

GPU/GPUTracking/SectorTracker/GPUTPCTracker.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "GPUTPCTrackParam.h"
2727
#include "GPUTPCTracklet.h"
2828
#include "GPUProcessor.h"
29+
#include "DataFormatsTPC/ClusterNative.h"
2930

3031
namespace o2::gpu
3132
{
@@ -151,6 +152,22 @@ class GPUTPCTracker : public GPUProcessor
151152

152153
GPUhd() int32_t HitInputID(const GPUTPCRow& row, int32_t hitIndex) const { return mData.ClusterDataIndex(row, hitIndex); }
153154

155+
GPUd() bool HitNNDirection(const GPUTPCRow& row, int32_t hitIndex, float& dydx, float& dzdx) const
156+
{
157+
const o2::tpc::ClusterNativeAccess* native = GetClustersNative();
158+
if (native == nullptr || native->clustersLinear == nullptr) {
159+
return false;
160+
}
161+
const uint32_t sectorOffset = native->clusterOffset[mISector][0];
162+
const o2::tpc::ClusterNative& cluster = native->clustersLinear[sectorOffset + mData.ClusterDataIndex(row, hitIndex)];
163+
if (!cluster.hasNNDirection()) {
164+
return false;
165+
}
166+
dydx = cluster.getNNDydx();
167+
dzdx = cluster.getNNDzdx();
168+
return true;
169+
}
170+
154171
/**
155172
* The hit weight is used to determine whether a hit belongs to a certain tracklet or another one
156173
* competing for the same hit. The tracklet that has a higher weight wins. Comparison is done

GPU/GPUTracking/SectorTracker/GPUTPCTrackletConstructor.cxx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -170,9 +170,16 @@ GPUdic(2, 1) void GPUTPCTrackletConstructor::UpdateTracklet(int32_t /*nBlocks*/,
170170

171171
float ri = 1.f / CAMath::Sqrt(dx * dx + dy * dy);
172172
if (iRow == (int32_t)r.mStartRow + 2) {
173-
tParam.SetSinPhi(dy * ri);
173+
float nnDydx = 0.f, nnDzdx = 0.f;
174+
if (tracker.HitNNDirection(row, seedIH, nnDydx, nnDzdx) && CAMath::Abs(nnDydx) < 10.f && CAMath::Abs(nnDzdx) < 10.f) {
175+
const float nnNormI = CAMath::InvSqrt(1.f + nnDydx * nnDydx);
176+
tParam.SetSinPhi(0.5f * (dy * ri + nnDydx * nnNormI));
177+
tParam.SetDzDs(0.5f * (dz * ri + nnDzdx * nnNormI));
178+
} else {
179+
tParam.SetSinPhi(dy * ri);
180+
tParam.SetDzDs(dz * ri);
181+
}
174182
tParam.SetSignCosPhi(dx);
175-
tParam.SetDzDs(dz * ri);
176183
float err2Y, err2Z;
177184
tracker.GetErrors2Seeding(iRow, tParam, -1.f, err2Y, err2Z); // Use correct time
178185
tParam.SetCov(0, err2Y);

GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class GPUTPCNNClusterizer : public GPUProcessor
5454
int32_t mNnClusterizerBoundaryFillValue = -1;
5555
int32_t mNnClusterizerModelClassNumOutputNodes = -1;
5656
int32_t mNnClusterizerModelReg1NumOutputNodes = -1;
57+
int32_t mNnClusterizerUseMomentumVector = 0;
5758
int32_t mNnClusterizerModelReg2NumOutputNodes = -1;
5859
int32_t mNnInferenceInputDType = 0; // 0: float16, 1: float32
5960
int32_t mNnInferenceOutputDType = 0; // 0: float16, 1: float32

GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerHost.cxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,9 @@ void GPUTPCNNClusterizerHost::initClusterizer(const GPUSettingsProcessingNNclust
138138
if (!settings.nnClusterizerUseCfRegression) {
139139
if (mModelClass.getNumOutputNodes()[0][1] == 1 || !mModelReg2.isInitialized()) {
140140
clustererNN.mNnClusterizerModelReg1NumOutputNodes = mModelReg1.getNumOutputNodes()[0][1];
141+
if (clustererNN.mNnClusterizerModelReg1NumOutputNodes > 5) {
142+
clustererNN.mNnClusterizerUseMomentumVector = true;
143+
}
141144
} else {
142145
clustererNN.mNnClusterizerModelReg1NumOutputNodes = mModelReg1.getNumOutputNodes()[0][1];
143146
clustererNN.mNnClusterizerModelReg2NumOutputNodes = mModelReg2.getNumOutputNodes()[0][1];

GPU/GPUTracking/TPCClusterFinder/GPUTPCNNClusterizerKernels.cxx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ using namespace o2::gpu::tpccf;
3838

3939
static_assert(GPUTPCNNClusterizerKernels::SCRATCH_PAD_WORK_GROUP_SIZE == GPUTPCCFClusterizer::SCRATCH_PAD_WORK_GROUP_SIZE, "Work group sizes do not match");
4040

41+
GPUd() static void setClass1NNDirection(const GPUTPCNNClusterizer& nn, int8_t dtype, int32_t base, o2::tpc::ClusterNative& cluster)
42+
{
43+
if (dtype == 0) {
44+
cluster.setNNDirection(nn.mOutputDataReg1_32[base + 5], nn.mOutputDataReg1_32[base + 5]);
45+
} else {
46+
cluster.setNNDirection(nn.mOutputDataReg1_16[base + 6].ToFloat(), nn.mOutputDataReg1_16[base + 6].ToFloat());
47+
}
48+
}
49+
4150
// Defining individual thread functions for data filling, determining the class label and running the CF clusterizer
4251
template <>
4352
GPUdii() void GPUTPCNNClusterizerKernels::Thread<GPUTPCNNClusterizerKernels::runCfClusterizer>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUSharedMemory& smem, processorType& processors, uint8_t sector, int8_t dtype, int8_t withMC, uint32_t batchStart)
@@ -476,6 +485,9 @@ GPUdii() void GPUTPCNNClusterizerKernels::Thread<GPUTPCNNClusterizerKernels::pub
476485
}
477486
return;
478487
}
488+
if (clustererNN.mNnClusterizerUseMomentumVector) {
489+
setClass1NNDirection(clustererNN, dtype, model_output_index, myCluster);
490+
}
479491

480492
uint32_t rowIndex = 0;
481493
if (clusterOut != nullptr) {
@@ -593,6 +605,7 @@ GPUdii() void GPUTPCNNClusterizerKernels::Thread<GPUTPCNNClusterizerKernels::pub
593605
}
594606
return;
595607
}
608+
// setClass2NNDirection(clustererNN, dtype, model_output_index, myCluster);
596609

597610
uint32_t rowIndex = 0;
598611
if (clusterOut != nullptr) {
@@ -646,6 +659,7 @@ GPUdii() void GPUTPCNNClusterizerKernels::Thread<GPUTPCNNClusterizerKernels::pub
646659
}
647660
return;
648661
}
662+
// setClass2NNDirection(clustererNN, dtype, model_output_index, myCluster);
649663

650664
if (clusterOut != nullptr) {
651665
rowIndex = GPUTPCCFClusterizer::sortIntoBuckets(

0 commit comments

Comments
 (0)