Skip to content

Commit fbb3a88

Browse files
authored
ITS tracker: Reserve output buffers (#12089)
* ITS tracker: Reserve output buffers * Rerserve all possible buffers
1 parent d764dde commit fbb3a88

File tree

4 files changed

+51
-45
lines changed

4 files changed

+51
-45
lines changed

Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ class TimeFrame
166166
int getNumberOfClusters() const;
167167
int getNumberOfCells() const;
168168
int getNumberOfTracklets() const;
169-
int getNumberOfTracks() const;
169+
size_t getNumberOfTracks() const;
170+
size_t getNumberOfUsedClusters() const;
170171

171172
bool checkMemory(unsigned long max) { return getArtefactsMemory() < max; }
172173
unsigned long getArtefactsMemory();
@@ -610,7 +611,7 @@ inline int TimeFrame::getNumberOfTracklets() const
610611
return nTracklets;
611612
}
612613

613-
inline int TimeFrame::getNumberOfTracks() const
614+
inline size_t TimeFrame::getNumberOfTracks() const
614615
{
615616
int nTracks = 0;
616617
for (auto& t : mTracks) {
@@ -619,6 +620,15 @@ inline int TimeFrame::getNumberOfTracks() const
619620
return nTracks;
620621
}
621622

623+
inline size_t TimeFrame::getNumberOfUsedClusters() const
624+
{
625+
size_t nClusters = 0;
626+
for (auto& layer : mUsedClusters) {
627+
nClusters += std::count(layer.begin(), layer.end(), true);
628+
}
629+
return nClusters;
630+
}
631+
622632
} // namespace its
623633
} // namespace o2
624634

Detectors/ITSMFT/ITS/tracking/src/Tracker.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,24 @@ void Tracker::clustersToTracks(std::function<void(std::string s)> logger, std::f
5454
total += evaluateTask(&Tracker::computeTracklets, "Tracklet finding", logger, iteration);
5555
logger(fmt::format("\t- Number of tracklets: {}", mTraits->getTFNumberOfTracklets()));
5656
if (!mTimeFrame->checkMemory(mTrkParams[iteration].MaxMemory)) {
57-
error("Too much memory used during trackleting, check the detector status and/or the selections.");
57+
error(fmt::format("Too much memory used during trackleting in iteration {}, check the detector status and/or the selections.", iteration));
5858
break;
5959
}
6060
float trackletsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfTracklets()) / mTraits->getTFNumberOfClusters() : 0.f;
6161
if (trackletsPerCluster > mTrkParams[iteration].TrackletsPerClusterLimit) {
62-
error(fmt::format("Too many tracklets per cluster ({}), check the detector status and/or the selections.", trackletsPerCluster));
62+
error(fmt::format("Too many tracklets per cluster ({}) in iteration {}, check the detector status and/or the selections.", trackletsPerCluster, iteration));
6363
break;
6464
}
6565

6666
total += evaluateTask(&Tracker::computeCells, "Cell finding", logger, iteration);
6767
logger(fmt::format("\t- Number of Cells: {}", mTraits->getTFNumberOfCells()));
6868
if (!mTimeFrame->checkMemory(mTrkParams[iteration].MaxMemory)) {
69-
error("Too much memory used during cell finding, check the detector status and/or the selections.");
69+
error(fmt::format("Too much memory used during cell finding in iteration {}, check the detector status and/or the selections.", iteration));
7070
break;
7171
}
7272
float cellsPerCluster = mTraits->getTFNumberOfClusters() > 0 ? float(mTraits->getTFNumberOfCells()) / mTraits->getTFNumberOfClusters() : 0.f;
7373
if (cellsPerCluster > mTrkParams[iteration].CellsPerClusterLimit) {
74-
error(fmt::format("Too many cells per cluster ({}), check the detector status and/or the selections.", cellsPerCluster));
74+
error(fmt::format("Too many cells per cluster ({}) in iteration {}, check the detector status and/or the selections.", cellsPerCluster, iteration));
7575
break;
7676
}
7777

Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -147,39 +147,35 @@ void TrackerDPL::run(ProcessingContext& pc)
147147
physTriggers = pc.inputs().get<gsl::span<o2::itsmft::PhysTrigger>>("phystrig");
148148
}
149149

150-
// code further down does assignment to the rofs and the altered object is used for output
151-
// we therefore need a copy of the vector rather than an object created directly on the input data,
152-
// the output vector however is created directly inside the message memory thus avoiding copy by
153-
// snapshot
154150
auto rofsinput = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
155151
auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "ITSTrackROF", 0, Lifetime::Timeframe}, rofsinput.begin(), rofsinput.end());
156-
157152
auto& irFrames = pc.outputs().make<std::vector<o2::dataformats::IRFrame>>(Output{"ITS", "IRFRAMES", 0, Lifetime::Timeframe});
158-
159153
const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance(); // RS: this should come from CCDB
154+
155+
irFrames.reserve(rofs.size());
160156
int nBCPerTF = alpParams.roFrameLengthInBC;
161157

162-
LOG(info) << "ITSTracker pulled " << compClusters.size() << " clusters, " << rofs.size() << " RO frames";
158+
LOGP(info, "ITSTracker pulled {} clusters, {} RO frames", compClusters.size(), rofs.size());
163159

164160
const dataformats::MCTruthContainer<MCCompLabel>* labels = nullptr;
165161
gsl::span<itsmft::MC2ROFRecord const> mc2rofs;
166162
if (mIsMC) {
167163
labels = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("itsmclabels").release();
168-
// get the array as read-only span, a snapshot is send forward
169-
mc2rofs = pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("ITSMC2ROframes");
164+
// get the array as read-only span, a snapshot is sent forward
165+
pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("ITSMC2ROframes"));
170166
LOG(info) << labels->getIndexedSize() << " MC label objects , in " << mc2rofs.size() << " MC events";
171167
}
172168

173169
auto& allClusIdx = pc.outputs().make<std::vector<int>>(Output{"ITS", "TRACKCLSID", 0, Lifetime::Timeframe});
174-
std::vector<o2::MCCompLabel> trackLabels;
175-
std::vector<MCCompLabel> verticesLabels;
176170
auto& allTracks = pc.outputs().make<std::vector<o2::its::TrackITS>>(Output{"ITS", "TRACKS", 0, Lifetime::Timeframe});
177-
std::vector<o2::MCCompLabel> allTrackLabels;
178-
std::vector<o2::MCCompLabel> allVerticesLabels;
179-
180171
auto& vertROFvec = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "VERTICESROF", 0, Lifetime::Timeframe});
181172
auto& vertices = pc.outputs().make<std::vector<Vertex>>(Output{"ITS", "VERTICES", 0, Lifetime::Timeframe});
182173

174+
// MC
175+
static pmr::vector<o2::MCCompLabel> dummyMCLabTracks, dummyMCLabVerts;
176+
auto& allTrackLabels = mIsMC ? pc.outputs().make<std::vector<o2::MCCompLabel>>(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}) : dummyMCLabTracks;
177+
auto& allVerticesLabels = mIsMC ? pc.outputs().make<std::vector<o2::MCCompLabel>>(Output{"ITS", "VERTICESMCTR", 0, Lifetime::Timeframe}) : dummyMCLabVerts;
178+
183179
std::uint32_t roFrame = 0;
184180

185181
bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS);
@@ -210,6 +206,7 @@ void TrackerDPL::run(ProcessingContext& pc)
210206
mTimeFrame->setMultiplicityCutMask(processingMask);
211207
float vertexerElapsedTime{0.f};
212208
if (mRunVertexer) {
209+
vertROFvec.reserve(rofs.size());
213210
// Run seeding vertexer
214211
vertexerElapsedTime = mVertexer->clustersToVertices(logger);
215212
} else { // cosmics
@@ -233,6 +230,7 @@ void TrackerDPL::run(ProcessingContext& pc)
233230
vertices.push_back(v);
234231
if (mIsMC) {
235232
auto vLabels = mTimeFrame->getPrimaryVerticesLabels(iRof)[iV];
233+
allVerticesLabels.reserve(allVerticesLabels.size() + vLabels.size());
236234
std::copy(vLabels.begin(), vLabels.end(), std::back_inserter(allVerticesLabels));
237235
}
238236
}
@@ -269,14 +267,17 @@ void TrackerDPL::run(ProcessingContext& pc)
269267
mTimeFrame->setMultiplicityCutMask(processingMask);
270268
// Run CA tracker
271269
mTracker->clustersToTracks(logger, errorLogger);
270+
size_t totTracks{mTimeFrame->getNumberOfTracks()}, totClusIDs{mTimeFrame->getNumberOfUsedClusters()};
271+
allTracks.reserve(totTracks);
272+
allClusIdx.reserve(totClusIDs);
273+
272274
if (mTimeFrame->hasBogusClusters()) {
273275
LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", mTimeFrame->hasBogusClusters());
274276
}
275277

276278
for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) {
277279
auto& rof{rofs[iROF]};
278280
auto& tracks = mTimeFrame->getTracks(iROF);
279-
trackLabels = mTimeFrame->getTracksLabel(iROF);
280281
auto number{tracks.size()};
281282
auto first{allTracks.size()};
282283
int offset = -rof.getFirstEntry(); // cluster entry!!!
@@ -286,8 +287,8 @@ void TrackerDPL::run(ProcessingContext& pc)
286287
if (processingMask[iROF]) {
287288
irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size();
288289
}
289-
290-
std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
290+
allTrackLabels.reserve(mTimeFrame->getTracksLabel(iROF).size()); // should be 0 if not MC
291+
std::copy(mTimeFrame->getTracksLabel(iROF).begin(), mTimeFrame->getTracksLabel(iROF).end(), std::back_inserter(allTrackLabels));
291292
// Some conversions that needs to be moved in the tracker internals
292293
for (unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) {
293294
auto& trc{tracks[iTrk]};
@@ -309,10 +310,6 @@ void TrackerDPL::run(ProcessingContext& pc)
309310
if (mIsMC) {
310311
LOGP(info, "ITSTracker pushed {} track labels", allTrackLabels.size());
311312
LOGP(info, "ITSTracker pushed {} vertex labels", allVerticesLabels.size());
312-
313-
pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}, allTrackLabels);
314-
pc.outputs().snapshot(Output{"ITS", "VERTICESMCTR", 0, Lifetime::Timeframe}, allVerticesLabels);
315-
pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, mc2rofs);
316313
}
317314
}
318315
mTimer.Stop();

GPU/Workflow/src/GPUWorkflowITS.cxx

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,11 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
132132
physTriggers = pc.inputs().get<gsl::span<o2::itsmft::PhysTrigger>>("phystrig");
133133
}
134134

135-
// code further down does assignment to the rofs and the altered object is used for output
136-
// we therefore need a copy of the vector rather than an object created directly on the input data,
137-
// the output vector however is created directly inside the message memory thus avoiding copy by
138-
// snapshot
139135
auto rofsinput = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("ROframes");
140-
auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "ITSTrackROF", 0, Lifetime::Timeframe}, rofsinput.begin(), rofsinput.end());
141136

137+
auto& rofs = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "ITSTrackROF", 0, Lifetime::Timeframe}, rofsinput.begin(), rofsinput.end());
142138
auto& irFrames = pc.outputs().make<std::vector<o2::dataformats::IRFrame>>(Output{"ITS", "IRFRAMES", 0, Lifetime::Timeframe});
139+
irFrames.reserve(rofs.size());
143140

144141
const auto& alpParams = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::Instance(); // RS: this should come from CCDB
145142
int nBCPerTF = alpParams.roFrameLengthInBC;
@@ -150,21 +147,21 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
150147
gsl::span<itsmft::MC2ROFRecord const> mc2rofs;
151148
if (mSpecConfig.processMC) {
152149
labels = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("itsmclabels").release();
153-
// get the array as read-only span, a snapshot is send forward
154-
mc2rofs = pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("ITSMC2ROframes");
150+
// get the array as read-only span, a snapshot is sent forward
151+
pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, pc.inputs().get<gsl::span<itsmft::MC2ROFRecord>>("ITSMC2ROframes"));
155152
LOG(info) << labels->getIndexedSize() << " MC label objects , in " << mc2rofs.size() << " MC events";
156153
}
157154

158155
auto& allClusIdx = pc.outputs().make<std::vector<int>>(Output{"ITS", "TRACKCLSID", 0, Lifetime::Timeframe});
159-
std::vector<o2::MCCompLabel> trackLabels;
160-
std::vector<MCCompLabel> verticesLabels;
161156
auto& allTracks = pc.outputs().make<std::vector<o2::its::TrackITS>>(Output{"ITS", "TRACKS", 0, Lifetime::Timeframe});
162-
std::vector<o2::MCCompLabel> allTrackLabels;
163-
std::vector<o2::MCCompLabel> allVerticesLabels;
164-
165157
auto& vertROFvec = pc.outputs().make<std::vector<o2::itsmft::ROFRecord>>(Output{"ITS", "VERTICESROF", 0, Lifetime::Timeframe});
166158
auto& vertices = pc.outputs().make<std::vector<Vertex>>(Output{"ITS", "VERTICES", 0, Lifetime::Timeframe});
167159

160+
// MC
161+
static pmr::vector<o2::MCCompLabel> dummyMCLabTracks, dummyMCLabVerts;
162+
auto& allTrackLabels = mSpecConfig.processMC ? pc.outputs().make<std::vector<o2::MCCompLabel>>(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}) : dummyMCLabTracks;
163+
auto& allVerticesLabels = mSpecConfig.processMC ? pc.outputs().make<std::vector<o2::MCCompLabel>>(Output{"ITS", "VERTICESMCTR", 0, Lifetime::Timeframe}) : dummyMCLabVerts;
164+
168165
std::uint32_t roFrame = 0;
169166

170167
bool continuous = o2::base::GRPGeomHelper::instance().getGRPECS()->isDetContinuousReadOut(o2::detectors::DetID::ITS);
@@ -196,6 +193,7 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
196193
float vertexerElapsedTime{0.f};
197194
if (mITSRunVertexer) {
198195
// Run seeding vertexer
196+
vertROFvec.reserve(rofs.size());
199197
vertexerElapsedTime = mITSVertexer->clustersToVertices(logger);
200198
} else { // cosmics
201199
mITSTimeFrame->resetRofPV();
@@ -218,6 +216,7 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
218216
vertices.push_back(v);
219217
if (mSpecConfig.processMC) {
220218
auto vLabels = mITSTimeFrame->getPrimaryVerticesLabels(iRof)[iV];
219+
allVerticesLabels.reserve(allVerticesLabels.size() + vLabels.size());
221220
std::copy(vLabels.begin(), vLabels.end(), std::back_inserter(allVerticesLabels));
222221
}
223222
}
@@ -254,14 +253,17 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
254253
mITSTimeFrame->setMultiplicityCutMask(processingMask);
255254
// Run CA tracker
256255
mITSTracker->clustersToTracks(logger, errorLogger);
256+
size_t totTracks{mITSTimeFrame->getNumberOfTracks()}, totClusIDs{mITSTimeFrame->getNumberOfUsedClusters()};
257+
allTracks.reserve(totTracks);
258+
allClusIdx.reserve(totClusIDs);
259+
257260
if (mITSTimeFrame->hasBogusClusters()) {
258261
LOG(warning) << fmt::format(" - The processed timeframe had {} clusters with wild z coordinates, check the dictionaries", mITSTimeFrame->hasBogusClusters());
259262
}
260263

261264
for (unsigned int iROF{0}; iROF < rofs.size(); ++iROF) {
262265
auto& rof{rofs[iROF]};
263266
auto& tracks = mITSTimeFrame->getTracks(iROF);
264-
trackLabels = mITSTimeFrame->getTracksLabel(iROF);
265267
auto number{tracks.size()};
266268
auto first{allTracks.size()};
267269
int offset = -rof.getFirstEntry(); // cluster entry!!!
@@ -272,7 +274,8 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
272274
irFrames.emplace_back(rof.getBCData(), rof.getBCData() + nBCPerTF - 1).info = tracks.size();
273275
}
274276

275-
std::copy(trackLabels.begin(), trackLabels.end(), std::back_inserter(allTrackLabels));
277+
allTrackLabels.reserve(mITSTimeFrame->getTracksLabel(iROF).size()); // should be 0 if not MC
278+
std::copy(mITSTimeFrame->getTracksLabel(iROF).begin(), mITSTimeFrame->getTracksLabel(iROF).end(), std::back_inserter(allTrackLabels));
276279
// Some conversions that needs to be moved in the tracker internals
277280
for (unsigned int iTrk{0}; iTrk < tracks.size(); ++iTrk) {
278281
auto& trc{tracks[iTrk]};
@@ -293,10 +296,6 @@ int GPURecoWorkflowSpec::runITSTracking(o2::framework::ProcessingContext& pc)
293296
if (mSpecConfig.processMC) {
294297
LOGP(info, "ITSTracker pushed {} track labels", allTrackLabels.size());
295298
LOGP(info, "ITSTracker pushed {} vertex labels", allVerticesLabels.size());
296-
297-
pc.outputs().snapshot(Output{"ITS", "TRACKSMCTR", 0, Lifetime::Timeframe}, allTrackLabels);
298-
pc.outputs().snapshot(Output{"ITS", "VERTICESMCTR", 0, Lifetime::Timeframe}, allVerticesLabels);
299-
pc.outputs().snapshot(Output{"ITS", "ITSTrackMC2ROF", 0, Lifetime::Timeframe}, mc2rofs);
300299
}
301300
}
302301
return 0;

0 commit comments

Comments
 (0)