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