41 if (traits->
isGPU()) {
48 LogFunc evalLog = [](
const std::string&) {};
53 if (mTrkParams[0].PerPrimaryVertexProcessing) {
54 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
55 maxNvertices = std::max(maxNvertices, (
int)mTimeFrame->
getPrimaryVertices(iROF).size());
59 int iteration{0}, iROFs{0}, iVertex{0};
60 auto handleException = [&](
const auto& err) {
61 LOGP(error,
"Too much memory used during {} in iteration {} in ROF span {}-{} iVtx={}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
62 StateNames[mCurState], iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, iVertex,
64 LOGP(error,
"Exception: {}", err.what());
65 if (mTrkParams[iteration].DropTFUponFailure) {
68 ++mNumberOfDroppedTFs;
69 error(
"...Dropping Timeframe...");
76 for (iteration = 0; iteration < (
int)mTrkParams.size(); ++iteration) {
77 mMemoryPool->setMaxMemory(mTrkParams[iteration].MaxMemory);
78 if (iteration == 3 && mTrkParams[0].DoUPCIteration) {
81 double timeTracklets{0.}, timeCells{0.}, timeNeighbours{0.}, timeRoads{0.};
82 int nTracklets{0}, nCells{0}, nNeighbours{0}, nTracks{-
static_cast<int>(mTimeFrame->
getNumberOfTracks())};
83 int nROFsIterations = mTrkParams[iteration].nROFsPerIterations > 0 ? mTimeFrame->
getNrof() / mTrkParams[iteration].nROFsPerIterations + bool(mTimeFrame->
getNrof() % mTrkParams[iteration].nROFsPerIterations) : 1;
84 iVertex = std::min(maxNvertices, 0);
85 logger(std::format(
"==== ITS {} Tracking iteration {} summary ====", mTraits->
getName(), iteration));
87 total += evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurState = TFInit], iteration, logger, iteration);
89 for (iROFs = 0; iROFs < nROFsIterations; ++iROFs) {
90 timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurState = Trackleting], iteration, evalLog, iteration, iROFs, iVertex);
93 if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
94 error(std::format(
"Too many tracklets per cluster ({}) in iteration {} in ROF span {}-{}:, check the detector status and/or the selections. Current limit is {}",
95 trackletsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].TrackletsPerClusterLimit));
98 timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurState = Celling], iteration, evalLog, iteration);
101 if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
102 error(std::format(
"Too many cells per cluster ({}) in iteration {} in ROF span {}-{}, check the detector status and/or the selections. Current limit is {}",
103 cellsPerCluster, iteration, iROFs, iROFs + mTrkParams[iteration].nROFsPerIterations, mTrkParams[iteration].CellsPerClusterLimit));
106 timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurState = Neighbouring], iteration, evalLog, iteration);
108 timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurState = Roading], iteration, evalLog, iteration);
110 }
while (++iVertex < maxNvertices);
111 logger(std::format(
" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
112 logger(std::format(
" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
113 logger(std::format(
" - Neighbours finding: {} neighbours found in {:.2f} ms", nNeighbours, timeNeighbours));
114 logger(std::format(
" - Track finding: {} tracks found in {:.2f} ms", nTracks + mTimeFrame->
getNumberOfTracks(), timeRoads));
115 total += timeTracklets + timeCells + timeNeighbours + timeRoads;
118 auto timeExtending = evaluateTask(&Tracker::extendTracks,
"Extending tracks", iteration, evalLog, iteration);
119 total += timeExtending;
120 logger(std::format(
" - Extending Tracks: {} extended tracks using {} clusters found in {:.2f} ms", nExtendedTracks + mTimeFrame->
mNExtendedTracks, nExtendedClusters + mTimeFrame->
mNExtendedUsedClusters, timeExtending));
122 if (mTrkParams[iteration].PrintMemory) {
123 mMemoryPool->print();
128 total += evaluateTask(&Tracker::findShortPrimaries,
"Short primaries finding", 0, logger);
130 logger(std::format(
" `-> found {} additional tracks", nTracksA - nTracksB));
133 logger(std::format(
"=== TimeFrame {} processing completed in: {:.2f} ms using {} thread(s) ===", mTimeFrameCounter, total, mTraits->
getNThreads()));
136 handleException(err);
138 }
catch (
const std::bad_alloc& err) {
139 handleException(err);
142 error(
"Uncaught exception, all bets are off...");
145 if (mTrkParams[0].PrintMemory) {
147 mMemoryPool->print();
151 computeTracksMClabels();
153 rectifyClusterIndices();
158void Tracker::computeRoadsMClabels()
167 int roadsNum{
static_cast<int>(mTimeFrame->
getRoads().size())};
169 for (
int iRoad{0}; iRoad < roadsNum; ++iRoad) {
171 Road<5>& currentRoad{mTimeFrame->
getRoads()[iRoad]};
172 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
173 bool isFakeRoad{
false};
174 bool isFirstRoadCell{
true};
176 for (
int iCell{0}; iCell < mTrkParams[0].CellsPerRoad(); ++iCell) {
177 const int currentCellIndex{currentRoad[iCell]};
180 if (isFirstRoadCell) {
187 const CellSeed& currentCell{mTimeFrame->
getCells()[iCell][currentCellIndex]};
189 if (isFirstRoadCell) {
191 const int cl0index{mTimeFrame->
getClusters()[iCell][currentCell.getFirstClusterIndex()].clusterId};
194 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
195 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
196 for (
const auto&
label : cl0labs) {
197 if (
label == occurrence.first) {
205 for (
const auto&
label : cl0labs) {
206 occurrences.emplace_back(
label, 1);
210 const int cl1index{mTimeFrame->
getClusters()[iCell + 1][currentCell.getSecondClusterIndex()].clusterId};
214 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
215 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
216 for (
auto&
label : cl1labs) {
217 if (
label == occurrence.first) {
225 for (
auto&
label : cl1labs) {
226 occurrences.emplace_back(
label, 1);
230 isFirstRoadCell =
false;
233 const int cl2index{mTimeFrame->
getClusters()[iCell + 2][currentCell.getThirdClusterIndex()].clusterId};
236 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
237 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
238 for (
auto&
label : cl2labs) {
239 if (
label == occurrence.first) {
247 for (
auto&
label : cl2labs) {
248 occurrences.emplace_back(
label, 1);
253 std::sort(occurrences.begin(), occurrences.end(), [](
auto e1,
auto e2) {
254 return e1.second > e2.second;
257 auto maxOccurrencesValue = occurrences[0].first;
258 mTimeFrame->
setRoadLabel(iRoad, maxOccurrencesValue.getRawValue(), isFakeRoad);
262void Tracker::computeTracksMClabels()
264 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
265 for (
auto& track : mTimeFrame->getTracks(iROF)) {
266 std::vector<std::pair<MCCompLabel, size_t>> occurrences;
270 const int index = track.getClusterIndex(iCluster);
276 for (
size_t iOcc{0}; iOcc < occurrences.size(); ++iOcc) {
277 std::pair<o2::MCCompLabel, size_t>& occurrence = occurrences[iOcc];
278 for (
const auto&
label : labels) {
279 if (
label == occurrence.first) {
287 for (
const auto&
label : labels) {
288 occurrences.emplace_back(
label, 1);
292 std::sort(std::begin(occurrences), std::end(occurrences), [](
auto e1,
auto e2) {
293 return e1.second > e2.second;
296 auto maxOccurrencesValue = occurrences[0].first;
297 uint32_t
pattern = track.getPattern();
300 auto clid = track.getClusterIndex(ic);
303 for (
const auto& currentLabel : labelsSpan) {
304 if (currentLabel == maxOccurrencesValue) {
312 if (occurrences[0].second < track.getNumberOfClusters()) {
313 maxOccurrencesValue.setFakeFlag();
315 mTimeFrame->
getTracksLabel(iROF).emplace_back(maxOccurrencesValue);
320void Tracker::rectifyClusterIndices()
322 for (
int iROF{0}; iROF < mTimeFrame->
getNrof(); ++iROF) {
323 for (
auto& track : mTimeFrame->getTracks(iROF)) {
325 const int index = track.getClusterIndex(iCluster);
342 auto avgTF = mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (
double)mTimeFrameCounter : -1.0);
343 auto avgTFwithDropped = mTotalTime * 1.e-3 / (((mTimeFrameCounter + mNumberOfDroppedTFs) > 0) ? (double)(mTimeFrameCounter + mNumberOfDroppedTFs) : -1.0);
344 LOGP(info,
"Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} ({:.2f}) s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, avgTF, avgTFwithDropped);
static const ITSGpuTrackingParamConfig & Instance()
static constexpr int MaxClusters
< heavy version of TrackITS, with clusters embedded
virtual int getTFNumberOfTracklets() const
virtual bool isGPU() const noexcept
virtual int getTFNumberOfClusters() const
void updateTrackingParameters(const std::vector< TrackingParameters > &trkPars)
virtual void adoptTimeFrame(TimeFrame< nLayers > *tf)
virtual bool supportsFindShortPrimaries() const noexcept
virtual bool supportsExtendTracks() const noexcept
virtual const char * getName() const noexcept
virtual int getTFNumberOfCells() const
void printSummary() const
void clustersToTracks(const LogFunc &=[](const std::string &s) { std::cout<< s<< '\n';}, const LogFunc &=[](const std::string &s) { std::cerr<< s<< '\n';})
void adoptTimeFrame(TimeFrame< NLayers > &tf)
Tracker(TrackerTraits< NLayers > *traits)
GLuint GLsizei const GLchar * label
constexpr int UnusedIndex
constexpr bool DoTimeBenchmarks
std::unique_ptr< GPUReconstructionTimeframe > tf
bool hasMCinformation() const
size_t getNumberOfTracks() const
int getClusterExternalIndex(int layerId, const int clId) const
int mNExtendedUsedClusters
gsl::span< const Vertex > getPrimaryVertices(int rofId) const
void initialiseRoadLabels()
gsl::span< const MCCompLabel > getClusterLabels(int layerId, const Cluster &cl) const
unsigned long getArtefactsMemory() const
virtual int getNumberOfNeighbours() const
void printArtefactsMemory() const
auto & getTracksLabel(const int rofId)
void setRoadLabel(int i, const unsigned long long &lab, bool fake)
std::array< uint16_t, 5 > pattern