Project
Loading...
Searching...
No Matches
TrackerTraitsGPU.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.
12
13#include <unistd.h>
14
19
20namespace o2::its
21{
22
25
26template <int NLayers>
28{
29 this->mTaskArena->execute([&] {
30 mTimeFrameGPU->initialise(this->mTrkParams[iteration], this->mTrkParams[iteration].NLayers, iteration);
31 });
32 // load iteration parameters
33 mTimeFrameGPU->loadIterationParameters(this->mTrkParams[iteration]);
34
35 if (this->mTrkParams[iteration].PassFlags[IterationStep::FirstPass]) {
36 // on default stream
37 mTimeFrameGPU->loadVertices();
38 // TODO these tables can be put in persistent memory
39 mTimeFrameGPU->loadROFOverlapTable(); // this can be put in constant memory actually
40 mTimeFrameGPU->loadROFVertexLookupTable();
41 mTimeFrameGPU->loadTrackingTopologies();
42 // once the tables are in persistent memory just re-upload the vertex one
43 // mTimeFrameGPU->uploadROFVertexLookupTable();
44 mTimeFrameGPU->loadIndexTableUtils();
45 // pinned on host
46 mTimeFrameGPU->createUsedClustersDeviceArray();
47 mTimeFrameGPU->createClustersDeviceArray();
48 mTimeFrameGPU->createUnsortedClustersDeviceArray();
49 mTimeFrameGPU->createClustersIndexTablesArray();
50 mTimeFrameGPU->createTrackingFrameInfoDeviceArray();
51 mTimeFrameGPU->createROFrameClustersDeviceArray();
52 // device array
53 mTimeFrameGPU->createTrackletsLUTDeviceArray();
54 mTimeFrameGPU->createTrackletsBuffersArray();
55 mTimeFrameGPU->createCellsBuffersArray();
56 mTimeFrameGPU->createCellsLUTDeviceArray();
57 }
58 if (this->mTrkParams[iteration].PassFlags[IterationStep::FirstPass] || this->mTrkParams[iteration].PassFlags[IterationStep::UseUPCMask]) {
59 mTimeFrameGPU->loadROFCutMask(iteration);
60 }
61}
62
63template <int NLayers>
65{
66 mTimeFrameGPU = static_cast<gpu::TimeFrameGPU<NLayers>*>(tf);
67 this->mTimeFrame = static_cast<TimeFrame<NLayers>*>(tf);
68}
69
70template <int NLayers>
71void TrackerTraitsGPU<NLayers>::computeLayerTracklets(const int iteration, int iVertex)
72{
73 const auto topology = mTimeFrameGPU->getDeviceTrackingTopologyView();
74 const auto hostTopology = mTimeFrameGPU->getTrackingTopologyView();
75 const bool loadFirstPassData = this->mTrkParams[iteration].PassFlags[IterationStep::FirstPass] && iVertex <= 0; // load data only on first pass and first vertex
76 for (int iLayer{0}; iLayer < this->mTrkParams[iteration].NLayers; ++iLayer) {
77 if (loadFirstPassData) {
78 mTimeFrameGPU->createUsedClustersDevice(iLayer);
79 mTimeFrameGPU->loadClustersDevice(iLayer);
80 mTimeFrameGPU->loadClustersIndexTables(iLayer);
81 mTimeFrameGPU->loadROFrameClustersDevice(iLayer);
82 }
83 mTimeFrameGPU->recordEvent(iLayer);
84 }
85
86 for (int linkId{0}; linkId < hostTopology.nLinks; ++linkId) {
87 mTimeFrameGPU->createTrackletsLUTDevice(loadFirstPassData, linkId); // on first pass allocates, then only clears memory
88 }
89
90 // Stack allocations created from trackleting through road finding are scoped to one tracker pass.
91 // With per-primary-vertex processing, the chain is called once per vertex while initialisation is only done once.
92 mTimeFrameGPU->pushMemoryStack(iteration);
93
94 const auto nClusters = mTimeFrameGPU->getClusterSizes();
95 for (int linkId{0}; linkId < hostTopology.nLinks; ++linkId) {
96 const auto link = hostTopology.getLink(linkId);
97 mTimeFrameGPU->waitEvent(linkId, link.fromLayer);
98 mTimeFrameGPU->waitEvent(linkId, link.toLayer);
99 const auto key = CapacityEstimator::makeKey(SlabSite::Tracklets, iteration, iVertex + 1, linkId);
100 const auto scale = static_cast<double>(nClusters[link.fromLayer]);
101 runOnSlab(mTimeFrameGPU->getCapacityEstimator(), key, scale, [&](const int capacity) {
102 mTimeFrameGPU->createTrackletsBuffers(linkId, capacity);
103 return TrackingKernels<NLayers>::computeTrackletsInROFsHandler(mTimeFrameGPU->getDeviceIndexTableUtils(),
104 mTimeFrameGPU->getDeviceROFMaskTableView(),
105 linkId,
106 link.fromLayer,
107 link.toLayer,
108 mTimeFrameGPU->getDeviceROFOverlapTableView(),
109 mTimeFrameGPU->getDeviceROFVertexLookupTableView(),
110 iVertex,
111 mTimeFrameGPU->getDeviceVertices(),
112 mTimeFrameGPU->getDeviceArrayClusters(),
113 nClusters,
114 mTimeFrameGPU->getDeviceROFrameClusters(),
115 (const uint8_t**)mTimeFrameGPU->getDeviceArrayUsedClusters(),
116 mTimeFrameGPU->getDeviceArrayClustersIndexTables(),
117 mTimeFrameGPU->getDeviceArrayTracklets(),
118 mTimeFrameGPU->getDeviceTracklets(),
119 mTimeFrameGPU->getNTracklets(),
120 capacity,
121 mTimeFrameGPU->getDeviceTrackletsLUTs(),
122 this->mTrkParams[iteration].PassFlags[IterationStep::SelectUPCVertices],
123 this->mTrkParams[iteration].NSigmaCut,
124 topology,
125 mTimeFrameGPU->getLinkPhiCuts(),
126 this->mTrkParams[iteration].PVres,
127 mTimeFrameGPU->getMinRs(),
128 mTimeFrameGPU->getMaxRs(),
129 mTimeFrameGPU->getPositionResolutions(),
130 this->mTrkParams[iteration].LayerRadii,
131 mTimeFrameGPU->getLinkMSAngles(),
132 mTimeFrameGPU->getFrameworkAllocator(),
133 mTimeFrameGPU->getStreams());
134 });
135 mTimeFrameGPU->recordEvent(linkId);
136 }
137}
138
139template <int NLayers>
141{
142 const auto topology = mTimeFrameGPU->getDeviceTrackingTopologyView();
143 const auto hostTopology = mTimeFrameGPU->getTrackingTopologyView();
144 for (int iLayer{0}; iLayer < this->mTrkParams[iteration].NLayers; ++iLayer) {
145 if (this->mTrkParams[iteration].PassFlags[IterationStep::FirstPass]) {
146 mTimeFrameGPU->loadUnsortedClustersDevice(iLayer);
147 mTimeFrameGPU->loadTrackingFrameInfoDevice(iLayer);
148 }
149 mTimeFrameGPU->recordEvent(iLayer);
150 }
151
152 for (int cellTopologyId{hostTopology.nCells}; cellTopologyId--;) {
153 const auto cellTopology = hostTopology.getCell(cellTopologyId);
154 const auto first = hostTopology.getLink(cellTopology.firstLink);
155 const auto second = hostTopology.getLink(cellTopology.secondLink);
156 const int currentLayerTrackletsNum{static_cast<int>(mTimeFrameGPU->getNTracklets()[cellTopology.firstLink])};
157 if (!currentLayerTrackletsNum || !mTimeFrameGPU->getNTracklets()[cellTopology.secondLink]) {
158 mTimeFrameGPU->getNCells()[cellTopologyId] = 0;
159 continue;
160 }
161
162 mTimeFrameGPU->createCellsLUTDevice(cellTopologyId);
163 mTimeFrameGPU->waitEvent(cellTopologyId, cellTopology.firstLink);
164 mTimeFrameGPU->waitEvent(cellTopologyId, cellTopology.secondLink);
165 mTimeFrameGPU->waitEvent(cellTopologyId, first.fromLayer);
166 mTimeFrameGPU->waitEvent(cellTopologyId, first.toLayer);
167 mTimeFrameGPU->waitEvent(cellTopologyId, second.toLayer);
168 const auto key = CapacityEstimator::makeKey(SlabSite::Cells, iteration, 0, cellTopologyId);
169 const auto scale = static_cast<double>(currentLayerTrackletsNum);
170 const int emitted = runOnSlab(mTimeFrameGPU->getCapacityEstimator(), key, scale, [&](const int capacity) {
171 mTimeFrameGPU->createCellsBuffers(cellTopologyId, capacity);
172 return TrackingKernels<NLayers>::computeCellsHandler(mTimeFrameGPU->getDeviceArrayClusters(),
173 mTimeFrameGPU->getDeviceArrayUnsortedClusters(),
174 mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(),
175 mTimeFrameGPU->getDeviceArrayTracklets(),
176 mTimeFrameGPU->getDeviceArrayTrackletsLUT(),
177 currentLayerTrackletsNum,
178 cellTopologyId,
179 topology,
180 mTimeFrameGPU->getDeviceCells()[cellTopologyId],
181 capacity,
182 mTimeFrameGPU->getDeviceCellLUTs()[cellTopologyId],
183 this->mBz,
184 this->mTrkParams[iteration].MaxChi2ClusterAttachment,
185 this->mTrkParams[iteration].CellDeltaTanLambdaSigma,
186 this->mTrkParams[iteration].NSigmaCut,
187 mTimeFrameGPU->getDeviceLayerxX0(),
188 mTimeFrameGPU->getFrameworkAllocator(),
189 mTimeFrameGPU->getStreams());
190 });
191 mTimeFrameGPU->getNCells()[cellTopologyId] = emitted;
192 mTimeFrameGPU->recordEvent(cellTopologyId);
193 }
194 mTimeFrameGPU->syncStreams(false);
195}
196
197template <int NLayers>
199{
200 const auto hostTopology = mTimeFrameGPU->getTrackingTopologyView();
201 bounded_vector<int> sourceTopologies(this->getMemoryPool().get());
202 sourceTopologies.reserve(hostTopology.nCells);
203 for (int outerLayer{0}; outerLayer < NLayers; ++outerLayer) {
204 for (int targetCellTopologyId{0}; targetCellTopologyId < hostTopology.nCells; ++targetCellTopologyId) {
205 const auto targetCellTopology = hostTopology.getCell(targetCellTopologyId);
206 if (targetCellTopology.hitLayerMask.last() != outerLayer) {
207 continue;
208 }
209 const int targetCellsNum{static_cast<int>(mTimeFrameGPU->getNCells()[targetCellTopologyId])};
210 sourceTopologies.clear();
211 size_t sourceCellCount{0};
212 for (int sourceCellTopologyId{0}; sourceCellTopologyId < hostTopology.nCells; ++sourceCellTopologyId) {
213 const auto sourceCellTopology = hostTopology.getCell(sourceCellTopologyId);
214 const int sourceCellsNum{static_cast<int>(mTimeFrameGPU->getNCells()[sourceCellTopologyId])};
215 if (!sourceCellsNum || sourceCellTopology.secondLink != targetCellTopology.firstLink) {
216 continue;
217 }
218 sourceTopologies.push_back(sourceCellTopologyId);
219 sourceCellCount += sourceCellsNum;
220 }
221 if (!targetCellsNum || sourceTopologies.empty()) {
222 mTimeFrameGPU->getNNeighbours()[targetCellTopologyId] = 0;
223 mTimeFrameGPU->createNeighboursDevice(targetCellTopologyId, 0);
224 mTimeFrameGPU->recordEvent(targetCellTopologyId);
225 continue;
226 }
227 mTimeFrameGPU->createNeighboursLUTDevice(targetCellTopologyId, targetCellsNum);
228 auto& stream = mTimeFrameGPU->getStream(targetCellTopologyId);
229 int* outputCounter = mTimeFrameGPU->getDeviceNeighboursLUT(targetCellTopologyId) + targetCellsNum;
230
231 const auto key = CapacityEstimator::makeKey(SlabSite::Neighbours, iteration, 0, targetCellTopologyId);
232 const auto scale = static_cast<double>(sourceCellCount);
233 const int emitted = runOnSlab(mTimeFrameGPU->getCapacityEstimator(), key, scale, [&](const int capacity) {
234 mTimeFrameGPU->createNeighboursDevice(targetCellTopologyId, capacity);
235 resetOutputCounterHandler(outputCounter, stream);
236 for (const int sourceCellTopologyId : sourceTopologies) {
237 mTimeFrameGPU->waitEvent(targetCellTopologyId, sourceCellTopologyId);
238 TrackingKernels<NLayers>::computeCellNeighboursHandler(mTimeFrameGPU->getDeviceArrayCells(),
239 mTimeFrameGPU->getDeviceArrayCellsLUT(),
240 mTimeFrameGPU->getDeviceNeighbours(targetCellTopologyId),
241 outputCounter,
242 capacity,
243 sourceCellTopologyId,
244 targetCellTopologyId,
245 this->mTrkParams[iteration].MaxChi2ClusterAttachment,
246 this->mBz,
247 mTimeFrameGPU->getNCells()[sourceCellTopologyId],
248 mTimeFrameGPU->getFrameworkAllocator(),
249 stream);
250 }
251 return finalizeCellNeighboursHandler(mTimeFrameGPU->getDeviceNeighbours(targetCellTopologyId),
252 mTimeFrameGPU->getDeviceNeighboursLUT(targetCellTopologyId),
253 targetCellsNum,
254 capacity,
255 mTimeFrameGPU->getFrameworkAllocator(),
256 stream);
257 });
258 mTimeFrameGPU->getNNeighbours()[targetCellTopologyId] = emitted;
259 mTimeFrameGPU->recordEvent(targetCellTopologyId);
260 }
261 }
262 mTimeFrameGPU->syncStreams(false);
263}
264
265template <int NLayers>
267{
268 bounded_vector<bounded_vector<int>> firstClusters(this->mTrkParams[iteration].NLayers, bounded_vector<int>(this->getMemoryPool().get()), this->getMemoryPool().get());
269 firstClusters.resize(this->mTrkParams[iteration].NLayers);
270 const auto hostTopology = mTimeFrameGPU->getTrackingTopologyView();
271 const bool extendTop = this->mTrkParams[iteration].PassFlags[IterationStep::TrackFollowerTop];
272 const bool extendBot = this->mTrkParams[iteration].PassFlags[IterationStep::TrackFollowerBot];
273 const bool extendTracks = extendTop || extendBot;
274 for (int startLevel{this->mTrkParams[iteration].CellsPerRoad()}; startLevel >= this->mTrkParams[iteration].CellMinimumLevel(); --startLevel) {
275 // The cells that may start a road at this level, as the scale the estimator predicts from.
276 size_t startCells{0};
277 for (int startCellTopologyId{0}; startCellTopologyId < hostTopology.nCells; ++startCellTopologyId) {
278 const int startLayer = hostTopology.getCell(startCellTopologyId).hitLayerMask.last();
279 if (this->mTrkParams[iteration].StartLayerMask.has(startLayer)) {
280 startCells += mTimeFrameGPU->getNCells()[startCellTopologyId];
281 }
282 }
283 if (!startCells) {
284 continue;
285 }
286 const auto key = CapacityEstimator::makeKey(SlabSite::TrackSeeds, iteration, startLevel, 0);
287 auto& estimator = mTimeFrameGPU->getCapacityEstimator();
288 const int nSeeds = runOnSlab(estimator, key, static_cast<double>(startCells), [&](const int capacity) {
289 mTimeFrameGPU->createTrackSeedsDevice(capacity);
290 int cursor{0};
291 for (int startCellTopologyId{0}; startCellTopologyId < hostTopology.nCells; ++startCellTopologyId) {
292 const int startLayer = hostTopology.getCell(startCellTopologyId).hitLayerMask.last();
293 if (!(this->mTrkParams[iteration].StartLayerMask.has(startLayer)) || mTimeFrameGPU->getNCells()[startCellTopologyId] == 0) {
294 continue;
295 }
297 startCellTopologyId,
298 mTimeFrameGPU->getDeviceArrayCells(),
299 mTimeFrameGPU->getDeviceCells()[startCellTopologyId],
300 nullptr,
301 nullptr,
302 mTimeFrameGPU->getArrayNCells().data(),
303 (const uint8_t**)mTimeFrameGPU->getDeviceArrayUsedClusters(),
304 mTimeFrameGPU->getDeviceArrayNeighbours(),
305 mTimeFrameGPU->getDeviceArrayNeighboursCellLUT(),
306 mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(),
307 mTimeFrameGPU->getDeviceTrackSeeds(),
308 capacity,
309 cursor,
310 mTimeFrameGPU->getCapacityEstimator(),
311 iteration,
312 this->mBz,
313 this->mTrkParams[iteration].MaxChi2ClusterAttachment,
314 this->mTrkParams[iteration].MaxChi2NDF,
315 this->mTrkParams[iteration].MaxHoles,
316 this->mTrkParams[iteration].getMinSeedingClusters(),
317 this->mTrkParams[iteration].HoleLayerMask,
318 this->mTrkParams[iteration].getNonSeedingLayerMask(),
319 mTimeFrameGPU->getDeviceLayerxX0(),
320 mTimeFrameGPU->getDevicePropagator(),
321 this->mTrkParams[iteration].CorrType,
322 mTimeFrameGPU->getFrameworkAllocator());
323 }
324 return cursor; }, estimator.peakCapacity(key));
325 if (!nSeeds) {
326 LOGP(debug, "No track seeds found, skipping track finding");
327 continue;
328 }
329 if (extendTracks) { // independent of the slab size, so it must not be redone on a retry
330 mTimeFrameGPU->createTrackExtensionScratchDevice(gpu::gridThreads(gpu::ResidentBlocks.fitTrackSeedsExtended),
331 this->mTrkParams[iteration].TrackFollowerMaxHypotheses);
332 }
333 const auto trackKey = CapacityEstimator::makeKey(extendTracks ? SlabSite::TracksExtended : SlabSite::Tracks,
334 iteration, startLevel, 0);
335 const int nTracks = runOnSlab(estimator, trackKey, static_cast<double>(nSeeds), [&](const int capacity) {
336 mTimeFrameGPU->createTrackITSExtDevice(capacity);
337 return TrackingKernels<NLayers>::computeTrackSeedHandler(mTimeFrameGPU->getDeviceTrackSeeds(),
338 mTimeFrameGPU->getDeviceArrayTrackingFrameInfo(),
339 mTimeFrameGPU->getDeviceArrayUnsortedClusters(),
340 mTimeFrameGPU->getDeviceIndexTableUtils(),
341 mTimeFrameGPU->getDeviceROFMaskTableView(),
342 mTimeFrameGPU->getDeviceROFOverlapTableView(),
343 mTimeFrameGPU->getDeviceArrayClusters(),
344 (const unsigned char**)mTimeFrameGPU->getDeviceArrayUsedClusters(),
345 mTimeFrameGPU->getDeviceArrayClustersIndexTables(),
346 mTimeFrameGPU->getDeviceROFrameClusters(),
347 mTimeFrameGPU->getDeviceTrackITSExt(),
348 mTimeFrameGPU->getDeviceTrackIndices(),
349 mTimeFrameGPU->getDeviceTrackSeedIndices(),
350 mTimeFrameGPU->getDeviceTrackCounter(),
351 capacity,
352 extendTracks ? mTimeFrameGPU->getDeviceActiveTrackExtensionHypotheses() : nullptr,
353 extendTracks ? mTimeFrameGPU->getDeviceNextTrackExtensionHypotheses() : nullptr,
354 mTimeFrameGPU->getDeviceLayerRadii(),
355 mTimeFrameGPU->getDeviceMinPts(),
356 mTimeFrameGPU->getDeviceLayerxX0(),
357 static_cast<unsigned int>(nSeeds),
358 this->mBz,
359 this->mTrkParams[iteration].MaxChi2ClusterAttachment,
360 this->mTrkParams[iteration].MaxChi2NDF,
361 this->mTrkParams[iteration].ReseedIfShorter,
362 this->mTrkParams[iteration].RepeatRefitOut,
363 this->mTrkParams[iteration].ShiftRefToCluster,
364 this->mTrkParams[iteration].NLayers,
365 this->mTrkParams[iteration].PhiBins,
366 this->mTrkParams[iteration].TrackFollowerMaxHypotheses,
367 extendTop,
368 extendBot,
369 this->mTrkParams[iteration].TrackFollowerNSigmaCutPhi,
370 this->mTrkParams[iteration].TrackFollowerNSigmaCutZ,
371 mTimeFrameGPU->getDevicePropagator(),
372 this->mTrkParams[iteration].CorrType,
373 mTimeFrameGPU->getFrameworkAllocator()); }, estimator.peakCapacity(trackKey));
374 mTimeFrameGPU->createTrackITSExtHost(nTracks);
375 mTimeFrameGPU->downloadTrackITSExtDevice();
376
377 auto& tracks = mTimeFrameGPU->getTrackITSExt();
378 const auto& trackIndices = mTimeFrameGPU->getTrackIndices();
379 this->acceptTracks(iteration, tracks, trackIndices, firstClusters);
380 mTimeFrameGPU->loadUsedClustersDevice();
381 }
382 this->markTracks(iteration);
383 // wipe the artefact memory
384 mTimeFrameGPU->popMemoryStack(iteration);
385};
386
387template <int NLayers>
389{
390 return mTimeFrameGPU->getNumberOfClusters();
391}
392
393template <int NLayers>
395{
396 return std::accumulate(mTimeFrameGPU->getNTracklets().begin(), mTimeFrameGPU->getNTracklets().end(), 0);
397}
398
399template <int NLayers>
401{
402 return mTimeFrameGPU->getNumberOfCells();
403}
404
405template <int NLayers>
407{
408 this->mBz = bz;
409 mTimeFrameGPU->setBz(bz);
410}
411
412template class TrackerTraitsGPU<7>;
413#ifdef ENABLE_UPGRADES
414template class TrackerTraitsGPU<11>;
415template class TrackerTraitsGPU<13>;
416#endif
417} // namespace o2::its
std::ostringstream debug
Compile-time launch geometry of the ITS tracking kernels, per GPU family. Poor man's RTC to be remove...
int nClusters
StringRef key
void computeLayerTracklets(const int iteration, int) final
void initialiseTimeFrame(const int iteration) final
void computeLayerCells(const int iteration) final
void adoptTimeFrame(TimeFrame< NLayers > *tf) final
void findCellsNeighbours(const int iteration) final
static constexpr KeyType makeKey(SlabSite site, int iteration, int variant, int slot) noexcept
GLuint GLuint stream
Definition glcorearb.h:1806
auto get(const std::byte *buffer, size_t=0)
Definition DataHeader.h:454
const bool const bool extendBot
const bool extendTop
int finalizeCellNeighboursHandler(CellNeighbour *cellNeighbours, int *neighboursLUT, const int nTargetCells, const int capacity, o2::its::ExternalAllocator *alloc, gpu::Stream &stream)
int runOnSlab(CapacityEstimator &estimator, const CapacityEstimator::KeyType key, const double scale, Emit &&emit, const size_t floorCapacity=0)
std::unique_ptr< GPUReconstructionTimeframe > tf
const auto & getTrackingTopologyView() const
Definition TimeFrame.h:149