Project
Loading...
Searching...
No Matches
GPUChainTrackingSectorTracker.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
14
15#include "GPUChainTracking.h"
17#include "GPULogging.h"
18#include "GPUO2DataTypes.h"
22#include "GPUDefParametersRuntime.h"
33#include "utils/strtag.h"
34#include <fstream>
35
36using namespace o2::gpu;
37
38uint32_t GPUChainTracking::StreamForSector(uint32_t sector) const
39{
40 return sector % mRec->NStreams();
41}
42
43int32_t GPUChainTracking::ExtrapolationTracking(uint32_t iSector, bool blocking)
44{
45 const uint32_t stream = StreamForSector(iSector);
46 runKernel<GPUTPCExtrapolationTracking>({GetGridBlk(256, stream), {iSector}});
47 TransferMemoryResourceLinkToHost(RecoStep::TPCSectorTracking, processors()->tpcTrackers[iSector].MemoryResCommon(), stream);
48 if (blocking) {
50 }
51 return (0);
52}
53
55{
56 if (mRec->GPUStuck()) {
57 GPUWarning("This GPU is stuck, processing of tracking for this event is skipped!");
58 return (1);
59 }
60
61 const auto& threadContext = GetThreadContext();
62
63 int32_t retVal = RunTPCTrackingSectors_internal();
64 if (retVal) {
66 }
67 return (retVal != 0);
68}
69
70int32_t GPUChainTracking::RunTPCTrackingSectors_internal()
71{
72 if (GetProcessingSettings().debugLevel >= 2) {
73 GPUInfo("Running TPC Sector Tracker");
74 }
75 bool doGPU = GetRecoStepsGPU() & RecoStep::TPCSectorTracking;
76 for (uint32_t i = 0; i < NSECTORS; i++) {
78 if (doGPU) {
79 processorsShadow()->tpcTrackers[i].Data().SetClusterData(mIOPtrs.clustersNative->nClustersSector[i], mIOPtrs.clustersNative->clusterOffset[i][0]); // TODO: not needed I think, anyway copied in SetupGPUProcessor
80 }
81 }
83 GPUInfo("Event has %u TPC Clusters, %d TRD Tracklets", (uint32_t)mRec->MemoryScalers()->nTPCHits, mIOPtrs.nTRDTracklets);
84
85 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
86 processors()->tpcTrackers[iSector].SetMaxData(mIOPtrs); // First iteration to set data sizes
87 }
88 mRec->ComputeReuseMax(nullptr); // Resolve maximums for shared buffers
89 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
90 SetupGPUProcessor(&processors()->tpcTrackers[iSector], false); // Prepare custom allocation for 1st stack level
91 mRec->AllocateRegisteredMemory(processors()->tpcTrackers[iSector].MemoryResSectorScratch());
92 }
94 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
95 SetupGPUProcessor(&processors()->tpcTrackers[iSector], true); // Now we allocate
96 mRec->ResetRegisteredMemoryPointers(&processors()->tpcTrackers[iSector]); // TODO: The above call breaks the GPU ptrs to already allocated memory. This fixes them. Should actually be cleaned up at the source.
98 }
99
100 bool streamInit[GPUCA_MAX_STREAMS] = {false};
101 int32_t streamInitAndOccMap = mRec->NStreams() - 1;
102
103 bool initializeOccMap = param().rec.tpc.occupancyMapTimeBins || param().rec.tpc.sysClusErrorC12Norm;
104 if (doGPU) {
105 // Copy Tracker Object to GPU Memory
106 if (GetProcessingSettings().debugLevel >= 3) {
107 GPUInfo("Copying Tracker objects to GPU");
108 }
109 if (PrepareProfile()) {
110 return 2;
111 }
112
113 WriteToConstantMemory(RecoStep::TPCSectorTracking, (char*)processors()->tpcTrackers - (char*)processors(), processorsShadow()->tpcTrackers, sizeof(GPUTPCTracker) * NSECTORS, streamInitAndOccMap, !initializeOccMap ? &mEvents->init : nullptr);
114
115 std::fill(streamInit, streamInit + mRec->NStreams(), false);
116 streamInit[streamInitAndOccMap] = true;
117 }
118
119 if (param().rec.tpc.occupancyMapTimeBins || param().rec.tpc.sysClusErrorC12Norm) {
121 }
122 if (param().rec.tpc.occupancyMapTimeBins) {
123 if (doGPU) {
125 }
126 uint32_t* ptr = doGPU ? mInputsShadow->mTPCClusterOccupancyMap : mInputsHost->mTPCClusterOccupancyMap;
127 auto* ptrTmp = (GPUTPCClusterOccupancyMapBin*)mRec->AllocateVolatileMemory(GPUTPCClusterOccupancyMapBin::getTotalSize(param()), doGPU);
128 runKernel<GPUMemClean16>(GetGridAutoStep(streamInitAndOccMap, RecoStep::TPCSectorTracking), ptrTmp, GPUTPCClusterOccupancyMapBin::getTotalSize(param()));
129 runKernel<GPUTPCCreateOccupancyMap, GPUTPCCreateOccupancyMap::fill>(GetGridBlk(GPUCA_NSECTORS * GPUCA_ROW_COUNT, streamInitAndOccMap), ptrTmp);
130 runKernel<GPUTPCCreateOccupancyMap, GPUTPCCreateOccupancyMap::fold>(GetGridBlk(mInputsHost->mTPCClusterOccupancyMapSize, streamInitAndOccMap), ptrTmp, ptr + 2);
132 mInputsHost->mTPCClusterOccupancyMap[1] = param().rec.tpc.occupancyMapTimeBins * 0x10000 + param().rec.tpc.occupancyMapTimeBinsAverage;
133 if (doGPU) {
134 GPUMemCpy(RecoStep::TPCSectorTracking, mInputsHost->mTPCClusterOccupancyMap + 2, mInputsShadow->mTPCClusterOccupancyMap + 2, sizeof(*ptr) * mInputsHost->mTPCClusterOccupancyMapSize, streamInitAndOccMap, false);
135 } else {
136 TransferMemoryResourceLinkToGPU(RecoStep::TPCSectorTracking, mInputsHost->mResourceOccupancyMap, streamInitAndOccMap);
137 }
138 }
139 if (initializeOccMap) {
140 uint32_t& occupancyTotal = *mInputsHost->mTPCClusterOccupancyMap;
141 occupancyTotal = CAMath::Float2UIntRn(mRec->MemoryScalers()->nTPCHits / (mIOPtrs.settingsTF && mIOPtrs.settingsTF->hasNHBFPerTF ? mIOPtrs.settingsTF->nHBFPerTF : 128));
142 mRec->UpdateParamOccupancyMap(param().rec.tpc.occupancyMapTimeBins ? mInputsHost->mTPCClusterOccupancyMap + 2 : nullptr, doGPU && param().rec.tpc.occupancyMapTimeBins ? mInputsShadow->mTPCClusterOccupancyMap + 2 : nullptr, occupancyTotal, mInputsHost->mTPCClusterOccupancyMapSize, streamInitAndOccMap, &mEvents->init);
143 }
144
145 int32_t streamMap[NSECTORS];
146
147 bool error = false;
148 mRec->runParallelOuterLoop(doGPU, NSECTORS, [&](uint32_t iSector) {
149 GPUTPCTracker& trk = processors()->tpcTrackers[iSector];
150 GPUTPCTracker& trkShadow = doGPU ? processorsShadow()->tpcTrackers[iSector] : trk;
151 int32_t useStream = StreamForSector(iSector);
152
153 if (GetProcessingSettings().debugLevel >= 3) {
154 GPUInfo("Creating Sector Data (Sector %d)", iSector);
155 }
156 TransferMemoryResourcesToGPU(RecoStep::TPCSectorTracking, &trk, useStream);
157 runKernel<GPUTPCCreateTrackingData>({doGPU ? GetGridBlk(GPUCA_ROW_COUNT, useStream) : GetGridAuto(0), {iSector}, {nullptr, streamInit[useStream] ? nullptr : &mEvents->init}}); // TODO: Check why GetGridAuto(0) is much fast on CPU
158 streamInit[useStream] = true;
159 if (GetProcessingSettings().deterministicGPUReconstruction) {
160 runKernel<GPUTPCSectorDebugSortKernels, GPUTPCSectorDebugSortKernels::hitData>({GetGridBlk(GPUCA_ROW_COUNT, useStream), {iSector}});
161 }
162 if (!doGPU && trk.CheckEmptySector() && GetProcessingSettings().debugLevel == 0) {
163 return;
164 }
165
166 if (GetProcessingSettings().debugLevel >= 6) {
167 if ((GetProcessingSettings().debugMask & 63)) {
168 *mDebugFile << "\n\nReconstruction: Sector " << iSector << "/" << NSECTORS << std::endl;
169 }
171 if (doGPU) {
172 TransferMemoryResourcesToHost(RecoStep::TPCSectorTracking, &trk, -1, true);
173 }
175 }
176 }
177
178 runKernel<GPUMemClean16>(GetGridAutoStep(useStream, RecoStep::TPCSectorTracking), trkShadow.Data().HitWeights(), trkShadow.Data().NumberOfHitsPlusAlign() * sizeof(*trkShadow.Data().HitWeights()));
179 runKernel<GPUTPCNeighboursFinder>({GetGridBlk(GPUCA_ROW_COUNT, useStream), {iSector}, {nullptr, streamInit[useStream] ? nullptr : &mEvents->init}});
180 streamInit[useStream] = true;
181
182 if (GetProcessingSettings().keepDisplayMemory) {
183 TransferMemoryResourcesToHost(RecoStep::TPCSectorTracking, &trk, -1, true);
184 memcpy(trk.LinkTmpMemory(), mRec->Res(trk.MemoryResLinks()).Ptr(), mRec->Res(trk.MemoryResLinks()).Size());
186 trk.DumpLinks(*mDebugFile, 0);
187 }
188 }
189
190 runKernel<GPUTPCNeighboursCleaner>({GetGridBlk(GPUCA_ROW_COUNT - 2, useStream), {iSector}});
192
193 runKernel<GPUTPCStartHitsFinder>({GetGridBlk(GPUCA_ROW_COUNT - 6, useStream), {iSector}});
194 if (mRec->getGPUParameters(doGPU).par_SORT_STARTHITS) {
195 runKernel<GPUTPCStartHitsSorter>({GetGridAuto(useStream), {iSector}});
196 }
197 if (GetProcessingSettings().deterministicGPUReconstruction) {
198 runKernel<GPUTPCSectorDebugSortKernels, GPUTPCSectorDebugSortKernels::startHits>({GetGrid(1, 1, useStream), {iSector}});
199 }
201
202 if (GetProcessingSettings().memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_INDIVIDUAL) {
203 trk.UpdateMaxData();
206 }
207
208 runKernel<GPUTPCTrackletConstructor>({GetGridAuto(useStream), {iSector}});
210 if (GetProcessingSettings().debugMask & GPUChainTrackingDebugFlags::TPCHitWeights && GetProcessingSettings().deterministicGPUReconstruction < 2) {
212 }
213
214 runKernel<GPUTPCTrackletSelector>({GetGridAuto(useStream), {iSector}});
215 runKernel<GPUTPCExtrapolationTrackingCopyNumbers>({{1, -ThreadCount(), useStream}, {iSector}}, 1);
216 if (GetProcessingSettings().deterministicGPUReconstruction) {
217 runKernel<GPUTPCSectorDebugSortKernels, GPUTPCSectorDebugSortKernels::sectorTracks>({GetGrid(1, 1, useStream), {iSector}});
218 }
219 TransferMemoryResourceLinkToHost(RecoStep::TPCSectorTracking, trk.MemoryResCommon(), useStream, &mEvents->sector[iSector]);
220 streamMap[iSector] = useStream;
221 if (GetProcessingSettings().debugLevel >= 3) {
222 GPUInfo("Sector %u, Number of tracks: %d", iSector, *trk.NTracks());
223 }
225 if (GetProcessingSettings().memoryAllocationStrategy == GPUMemoryResource::ALLOCATION_INDIVIDUAL && !trk.MemoryReuseAllowed()) {
226 mRec->PopNonPersistentMemory(RecoStep::TPCSectorTracking, qStr2Tag("TPCSLTRK"), &trk);
227 }
228 });
230 if (error) {
231 return (3);
232 }
233
234 if (doGPU || GetProcessingSettings().debugLevel >= 1) {
235 if (param().rec.tpc.extrapolationTracking) {
236 std::vector<bool> blocking(NSECTORS * mRec->NStreams());
237 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
238 for (uint32_t iStream = 0; iStream < mRec->NStreams(); iStream++) {
239 blocking[iSector * mRec->NStreams() + iStream] = StreamForSector(iSector) == iStream;
240 }
241 }
242 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
243 uint32_t tmpSector = GPUTPCExtrapolationTracking::ExtrapolationTrackingSectorOrder(iSector);
244 uint32_t sectorLeft, sectorRight;
245 GPUTPCExtrapolationTracking::ExtrapolationTrackingSectorLeftRight(tmpSector, sectorLeft, sectorRight);
246 if (doGPU && !blocking[tmpSector * mRec->NStreams() + StreamForSector(sectorLeft)]) {
247 StreamWaitForEvents(StreamForSector(tmpSector), &mEvents->sector[sectorLeft]);
248 blocking[tmpSector * mRec->NStreams() + StreamForSector(sectorLeft)] = true;
249 }
250 if (doGPU && !blocking[tmpSector * mRec->NStreams() + StreamForSector(sectorRight)]) {
251 StreamWaitForEvents(StreamForSector(tmpSector), &mEvents->sector[sectorRight]);
252 blocking[tmpSector * mRec->NStreams() + StreamForSector(sectorRight)] = true;
253 }
254 ExtrapolationTracking(tmpSector, false);
255 }
256 }
257 if (doGPU) {
259 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
260 ReleaseEvent(mEvents->sector[iSector]);
261 }
262 }
263 } else {
264 mRec->runParallelOuterLoop(doGPU, NSECTORS, [&](uint32_t iSector) {
265 if (param().rec.tpc.extrapolationTracking) {
266 ExtrapolationTracking(iSector, true);
267 }
268 });
270 }
271
272 if (param().rec.tpc.extrapolationTracking && GetProcessingSettings().debugLevel >= 3) {
273 for (uint32_t iSector = 0; iSector < NSECTORS; iSector++) {
274 GPUInfo("Sector %d - Tracks: Local %d Extrapolated %d - Hits: Local %d Extrapolated %d", iSector,
275 processors()->tpcTrackers[iSector].CommonMemory()->nLocalTracks, processors()->tpcTrackers[iSector].CommonMemory()->nTracks, processors()->tpcTrackers[iSector].CommonMemory()->nLocalTrackHits, processors()->tpcTrackers[iSector].CommonMemory()->nTrackHits);
276 }
277 }
278
279 if (DoProfile()) {
280 return (1);
281 }
282 for (uint32_t i = 0; i < NSECTORS; i++) {
283 mIOPtrs.nSectorTracks[i] = *processors()->tpcTrackers[i].NTracks();
285 mIOPtrs.nSectorClusters[i] = *processors()->tpcTrackers[i].NTrackHits();
286 mIOPtrs.sectorClusters[i] = processors()->tpcTrackers[i].TrackHits();
287 if (GetProcessingSettings().keepDisplayMemory && !GetProcessingSettings().keepAllMemory) {
288 TransferMemoryResourcesToHost(RecoStep::TPCSectorTracking, &processors()->tpcTrackers[i], -1, true);
289 }
290 }
291 if (GetProcessingSettings().debugLevel >= 2) {
292 GPUInfo("TPC Sector Tracker finished");
293 }
294 mRec->PopNonPersistentMemory(RecoStep::TPCSectorTracking, qStr2Tag("TPCSLTRK"));
295 return 0;
296}
int32_t i
#define GPUCA_MAX_STREAMS
int32_t retVal
#define GPUCA_NSECTORS
#define GPUCA_ROW_COUNT
TBranch * ptr
std::unique_ptr< GPUTrackingInputProvider > mInputsHost
std::array< GPUOutputControl *, GPUTrackingOutputs::count()> mSubOutputControls
std::unique_ptr< std::ofstream > mDebugFile
GPUTrackingInOutPointers & mIOPtrs
std::unique_ptr< GPUTrackingInputProvider > mInputsShadow
int32_t ExtrapolationTracking(uint32_t iSector, bool blocking)
void TransferMemoryResourceLinkToGPU(RecoStep step, int16_t res, int32_t stream=-1, deviceEvent *ev=nullptr, deviceEvent *evList=nullptr, int32_t nEvents=1)
Definition GPUChain.h:124
void GPUMemCpy(RecoStep step, void *dst, const void *src, size_t size, int32_t stream, int32_t toGPU, deviceEvent *ev=nullptr, deviceEvent *evList=nullptr, int32_t nEvents=1)
Definition GPUChain.h:128
bool DoDebugAndDump(RecoStep step, uint32_t mask, T &processor, S T::*func, Args &&... args)
Definition GPUChain.h:228
void SynchronizeGPU()
Definition GPUChain.h:110
GPUReconstruction::RecoStepField GetRecoStepsGPU() const
Definition GPUChain.h:72
void WriteToConstantMemory(RecoStep step, size_t offset, const void *src, size_t size, int32_t stream=-1, deviceEvent *ev=nullptr)
Definition GPUChain.h:127
void ReleaseEvent(deviceEvent ev, bool doGPU=true)
Definition GPUChain.h:111
krnlExec GetGrid(uint32_t totalItems, uint32_t nThreads, int32_t stream, GPUReconstruction::krnlDeviceType d=GPUReconstruction::krnlDeviceType::Auto, gpudatatypes::RecoStep st=gpudatatypes::RecoStep::NoRecoStep)
Definition GPUChain.cxx:21
uint32_t ThreadCount() const
Definition GPUChain.h:215
krnlExec GetGridAuto(int32_t stream, GPUReconstruction::krnlDeviceType d=GPUReconstruction::krnlDeviceType::Auto, gpudatatypes::RecoStep st=gpudatatypes::RecoStep::NoRecoStep)
Definition GPUChain.cxx:42
size_t AllocateRegisteredMemory(GPUProcessor *proc)
Definition GPUChain.h:217
virtual std::unique_ptr< GPUReconstructionProcessing::threadContext > GetThreadContext()
Definition GPUChain.h:109
GPUConstantMem * processors()
Definition GPUChain.h:84
void StreamWaitForEvents(int32_t stream, deviceEvent *evList, int32_t nEvents=1)
Definition GPUChain.h:117
krnlExec GetGridAutoStep(int32_t stream, gpudatatypes::RecoStep st=gpudatatypes::RecoStep::NoRecoStep)
Definition GPUChain.cxx:47
GPUParam & param()
Definition GPUChain.h:87
void SetupGPUProcessor(T *proc, bool allocate)
Definition GPUChain.h:220
const GPUSettingsProcessing & GetProcessingSettings() const
Definition GPUChain.h:76
void SynchronizeStream(int32_t stream)
Definition GPUChain.h:89
GPUReconstructionCPU * mRec
Definition GPUChain.h:79
GPUConstantMem * processorsShadow()
Definition GPUChain.h:85
krnlExec GetGridBlk(uint32_t nBlocks, int32_t stream, GPUReconstruction::krnlDeviceType d=GPUReconstruction::krnlDeviceType::Auto, gpudatatypes::RecoStep st=gpudatatypes::RecoStep::NoRecoStep)
Definition GPUChain.cxx:32
static constexpr int32_t NSECTORS
Definition GPUChain.h:58
void TransferMemoryResourceLinkToHost(RecoStep step, int16_t res, int32_t stream=-1, deviceEvent *ev=nullptr, deviceEvent *evList=nullptr, int32_t nEvents=1)
Definition GPUChain.h:125
void TransferMemoryResourcesToHost(RecoStep step, GPUProcessor *proc, int32_t stream=-1, bool all=false)
Definition GPUChain.h:123
GPUReconstruction * rec()
Definition GPUChain.h:66
void TransferMemoryResourcesToGPU(RecoStep step, GPUProcessor *proc, int32_t stream=-1, bool all=false)
Definition GPUChain.h:122
void UpdateParamOccupancyMap(const uint32_t *mapHost, const uint32_t *mapGPU, uint32_t occupancyTotal, uint32_t mapSize, int32_t stream=-1, deviceEvent *ev=nullptr)
void runParallelOuterLoop(bool doGPU, uint32_t nThreads, std::function< void(uint32_t)> lambda)
const GPUDefParameters & getGPUParameters(bool doGPU) const override
void * AllocateVolatileMemory(size_t size, bool device)
void ComputeReuseMax(GPUProcessor *proc)
void ResetRegisteredMemoryPointers(GPUProcessor *proc)
GPUMemoryResource & Res(int16_t num)
void PopNonPersistentMemory(RecoStep step, uint64_t tag, const GPUProcessor *proc=nullptr)
void PushNonPersistentMemory(uint64_t tag)
GPUMemorySizeScalers * MemoryScalers()
size_t AllocateRegisteredMemory(GPUProcessor *proc, bool resetCustom=false)
int16_t MemoryResTracklets() const
int16_t MemoryResLinks() const
void SetMaxData(const GPUTrackingInOutPointers &io)
int16_t MemoryResOutput() const
void DumpTrackHits(std::ostream &out)
void DumpLinks(std::ostream &out, int32_t phase)
void DumpStartHits(std::ostream &out)
void DumpHitWeights(std::ostream &out)
int16_t MemoryResCommon() const
void DumpTrackingData(std::ostream &out)
void DumpTrackletHits(std::ostream &out)
GLenum GLfloat param
Definition glcorearb.h:271
GLuint GLuint stream
Definition glcorearb.h:1806
constexpr T qStr2Tag(const char *str)
Definition strtag.h:22
GPUTPCTracker tpcTrackers[GPUCA_NSECTORS]
const GPUTPCHitId * sectorClusters[NSECTORS]
const o2::tpc::ClusterNativeAccess * clustersNative
const GPUTPCTrack * sectorTracks[NSECTORS]
size_t getIndex(const GPUOutputControl &v)
unsigned int nClustersSector[constants::MAXSECTOR]
unsigned int clusterOffset[constants::MAXSECTOR][constants::MAXGLOBALPADROW]