Skip to content

Commit 3953e79

Browse files
committed
ITS: improve logging
Signed-off-by: Felix Schlepper <felix.schlepper@cern.ch>
1 parent e1b5576 commit 3953e79

7 files changed

Lines changed: 121 additions & 44 deletions

File tree

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ struct LogLogThrottler {
5050
return false;
5151
}
5252
};
53+
54+
struct TimingStats {
55+
std::uint64_t calls = 0;
56+
double totalTimeMs = 0.;
57+
58+
void add(double timeMs)
59+
{
60+
++calls;
61+
totalTimeMs += timeMs;
62+
}
63+
double averageTimeMs() const { return calls ? totalTimeMs / static_cast<double>(calls) : 0.; }
64+
};
65+
5366
} // namespace o2::its
5467

55-
#endif
68+
#endif

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

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525
#include <string_view>
2626
#include <utility>
2727
#include <sstream>
28+
#include <vector>
2829

2930
#include <oneapi/tbb/task_arena.h>
3031

3132
#include "ITStracking/Configuration.h"
33+
#include "ITStracking/Definitions.h"
3234
#include "ITStracking/TimeFrame.h"
3335
#include "ITStracking/TrackerTraits.h"
3436
#include "ITStracking/BoundedAllocator.h"
@@ -91,16 +93,18 @@ class Tracker
9193
double mTotalTime{0};
9294
std::shared_ptr<BoundedMemoryResource> mMemoryPool;
9395

94-
enum State {
96+
enum Steps {
9597
TFInit = 0,
9698
Trackleting,
9799
Celling,
98100
Neighbouring,
99101
Roading,
100-
NStates,
102+
NSteps,
101103
};
102-
State mCurState{TFInit};
103-
static constexpr std::array<const char*, NStates> StateNames{"TimeFrame initialisation", "Tracklet finding", "Cell finding", "Neighbour finding", "Road finding"};
104+
Steps mCurStep{TFInit};
105+
static constexpr std::array<const char*, NSteps> StateNames{"TimeFrame initialisation", "Tracklet finding", "Cell finding", "Neighbour finding", "Road finding"};
106+
std::vector<std::array<TimingStats, NSteps>> mTimingStats;
107+
void addTimingStatCurStep(int iteration, double timeMs);
104108
};
105109

106110
template <int NLayers>
@@ -125,22 +129,23 @@ float Tracker<NLayers>::evaluateTask(void (Tracker<NLayers>::*task)(T...), std::
125129
}
126130
logger(sstream.str());
127131

128-
if (mTrkParams[0].SaveTimeBenchmarks) {
132+
if (mTrkParams[iteration].SaveTimeBenchmarks) {
129133
std::string taskNameStr(taskName);
130134
std::transform(taskNameStr.begin(), taskNameStr.end(), taskNameStr.begin(),
131135
[](unsigned char c) { return std::tolower(c); });
132136
std::replace(taskNameStr.begin(), taskNameStr.end(), ' ', '_');
133137
if (std::ofstream file{"its_time_benchmarks.txt", std::ios::app}) {
134138
file << "trk:" << iteration << '\t' << taskNameStr << '\t' << diff << '\n';
135139
}
140+
addTimingStatCurStep(iteration, diff);
136141
}
137142

138143
} else {
139144
(this->*task)(std::forward<F>(args)...);
140145
}
141146

142147
if (mTrkParams[iteration].PrintMemory) {
143-
LOGP(info, "iter:{}:{}: {}", iteration, StateNames[mCurState], mMemoryPool->asString());
148+
LOGP(info, "iter:{}:{}: {}", iteration, StateNames[mCurStep], mMemoryPool->asString());
144149
}
145150

146151
return diff;

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

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
#include <array>
2323
#include <iosfwd>
2424
#include <memory>
25+
#include <vector>
2526

2627
#include <oneapi/tbb/task_arena.h>
2728

2829
#include "ITStracking/Constants.h"
29-
#include "ITStracking/Definitions.h"
3030
#include "ITStracking/Configuration.h"
3131
#include "ITStracking/TimeFrame.h"
3232
#include "ITStracking/VertexerTraits.h"
@@ -56,6 +56,7 @@ class Vertexer
5656

5757
float clustersToVertices(LogFunc = [](const std::string& s) { std::cout << s << '\n'; });
5858
void filterMCTracklets();
59+
void printSummary() const;
5960

6061
template <typename... T>
6162
void findTracklets(T&&... args)
@@ -90,9 +91,9 @@ class Vertexer
9091
float evaluateTask(void (Vertexer::*task)(T...), std::string_view taskName, int iteration, LogFunc& logger, T&&... args);
9192

9293
void printEpilog(LogFunc& logger,
93-
const unsigned int trackletN01, const unsigned int trackletN12,
94-
const unsigned selectedN, const unsigned int vertexN, const unsigned int totalVertexN,
95-
const float trackletT, const float selecT, const float vertexT);
94+
unsigned int trackletN01, unsigned int trackletN12,
95+
unsigned selectedN, unsigned int vertexN, unsigned int totalVertexN,
96+
float initT, float trackletT, float selecT, float vertexT);
9697

9798
void setNThreads(int n, std::shared_ptr<tbb::task_arena>& arena) { mTraits->setNThreads(n, arena); }
9899

@@ -105,16 +106,18 @@ class Vertexer
105106
std::vector<VertexingParameters> mVertParams;
106107
std::shared_ptr<BoundedMemoryResource> mMemoryPool;
107108

108-
enum State {
109+
enum Steps {
109110
Init = 0,
110111
Trackleting,
111-
Validating,
112+
Selection,
112113
Finding,
113114
TruthSeeding,
114-
NStates,
115+
NSteps,
115116
};
116-
State mCurState{Init};
117-
static constexpr std::array<const char*, NStates> StateNames{"Initialisation", "Tracklet finding", "Tracklet validation", "Vertex finding", "Truth seeding"};
117+
Steps mCurStep{Init};
118+
static constexpr std::array<const char*, NSteps> StateNames{"Initialisation", "Tracklet finding", "Tracklet selection", "Vertex finding", "Truth seeding"};
119+
std::vector<std::array<TimingStats, NSteps>> mTimingStats;
120+
void addTimingStatCurStep(int iteration, double timeMs);
118121
};
119122

120123
template <int NLayers>
@@ -139,21 +142,22 @@ float Vertexer<NLayers>::evaluateTask(void (Vertexer<NLayers>::*task)(T...), std
139142
}
140143
logger(sstream.str());
141144

142-
if (mVertParams[0].SaveTimeBenchmarks) {
145+
if (mVertParams[iteration].SaveTimeBenchmarks) {
143146
std::string taskNameStr(taskName);
144147
std::transform(taskNameStr.begin(), taskNameStr.end(), taskNameStr.begin(),
145148
[](unsigned char c) { return std::tolower(c); });
146149
std::replace(taskNameStr.begin(), taskNameStr.end(), ' ', '_');
147150
if (std::ofstream file{"its_time_benchmarks.txt", std::ios::app}) {
148151
file << "vtx:" << iteration << '\t' << taskNameStr << '\t' << diff << '\n';
149152
}
153+
addTimingStatCurStep(iteration, diff);
150154
}
151155
} else {
152156
(this->*task)(std::forward<T>(args)...);
153157
}
154158

155159
if (mVertParams[iteration].PrintMemory) {
156-
LOGP(info, "iter:{}:{}: {}", iteration, StateNames[mCurState], mMemoryPool->asString());
160+
LOGP(info, "iter:{}:{}: {}", iteration, StateNames[mCurStep], mMemoryPool->asString());
157161
}
158162

159163
return diff;

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

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ float Tracker<NLayers>::clustersToTracks(const LogFunc& logger, const LogFunc& e
4949
int iteration{0}, iVertex{0};
5050
auto handleException = [&](const auto& err) {
5151
LOGP(error, "Too much memory in {} in iteration {} iVtx={}: {:.2f} GB. Current limit is {:.2f} GB, check the detector status and/or the selections.",
52-
StateNames[mCurState], iteration, iVertex,
52+
StateNames[mCurStep], iteration, iVertex,
5353
(double)mTimeFrame->getArtefactsMemory() / GB,
5454
(double)mTrkParams[iteration].MaxMemory / GB);
5555
if (typeid(err) != typeid(std::bad_alloc)) { // only print if the exceptions is different from what is expected
@@ -76,16 +76,16 @@ float Tracker<NLayers>::clustersToTracks(const LogFunc& logger, const LogFunc& e
7676
int nTracks{-static_cast<int>(mTimeFrame->getNumberOfTracks())};
7777
iVertex = std::min(maxNvertices, 0);
7878
logger(std::format("==== ITS {} Tracking iteration {} summary ====", mTraits->getName(), iteration));
79-
total += timeFrame = evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurState = TFInit], iteration, evalLog, iteration);
79+
total += timeFrame = evaluateTask(&Tracker::initialiseTimeFrame, StateNames[mCurStep = TFInit], iteration, evalLog, iteration);
8080
logger(std::format(" - TimeFrame initialisation completed in {:.2f} ms", timeFrame));
8181
do {
82-
timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurState = Trackleting], iteration, evalLog, iteration, iVertex);
82+
timeTracklets += evaluateTask(&Tracker::computeTracklets, StateNames[mCurStep = Trackleting], iteration, evalLog, iteration, iVertex);
8383
nTracklets += mTraits->getTFNumberOfTracklets();
84-
timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurState = Celling], iteration, evalLog, iteration);
84+
timeCells += evaluateTask(&Tracker::computeCells, StateNames[mCurStep = Celling], iteration, evalLog, iteration);
8585
nCells += mTraits->getTFNumberOfCells();
86-
timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurState = Neighbouring], iteration, evalLog, iteration);
86+
timeNeighbours += evaluateTask(&Tracker::findCellsNeighbours, StateNames[mCurStep = Neighbouring], iteration, evalLog, iteration);
8787
nNeighbours += mTimeFrame->getNumberOfNeighbours();
88-
timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurState = Roading], iteration, evalLog, iteration);
88+
timeRoads += evaluateTask(&Tracker::findRoads, StateNames[mCurStep = Roading], iteration, evalLog, iteration);
8989
} while (++iVertex < maxNvertices);
9090
logger(std::format(" - Tracklet finding: {} tracklets found in {:.2f} ms", nTracklets, timeTracklets));
9191
logger(std::format(" - Cell finding: {} cells found in {:.2f} ms", nCells, timeCells));
@@ -229,12 +229,33 @@ void Tracker<NLayers>::adoptTimeFrame(TimeFrame<NLayers>& tf)
229229
mTraits->adoptTimeFrame(&tf);
230230
}
231231

232+
template <int NLayers>
233+
void Tracker<NLayers>::addTimingStatCurStep(int iteration, double timeMs)
234+
{
235+
if (iteration < 0) {
236+
return;
237+
}
238+
if (mTimingStats.size() < (iteration + 1)) {
239+
mTimingStats.resize(iteration + 1);
240+
}
241+
mTimingStats[iteration][mCurStep].add(timeMs);
242+
}
243+
232244
template <int NLayers>
233245
void Tracker<NLayers>::printSummary() const
234246
{
235247
auto avgTF = mTotalTime * 1.e-3 / ((mTimeFrameCounter > 0) ? (double)mTimeFrameCounter : -1.0);
236248
auto avgTFwithDropped = mTotalTime * 1.e-3 / (((mTimeFrameCounter + mNumberOfDroppedTFs) > 0) ? (double)(mTimeFrameCounter + mNumberOfDroppedTFs) : -1.0);
237249
LOGP(info, "Tracker summary: Processed {} TFs (dropped {}) in TOT={:.2f} s, AVG/TF={:.2f} ({:.2f}) s", mTimeFrameCounter, mNumberOfDroppedTFs, mTotalTime * 1.e-3, avgTF, avgTFwithDropped);
250+
for (size_t iteration = 0; iteration < mTimingStats.size(); ++iteration) {
251+
for (size_t state = 0; state < NSteps; ++state) {
252+
const auto& stats = mTimingStats[iteration][state];
253+
if (!stats.calls) {
254+
continue;
255+
}
256+
LOGP(info, " - iter {} {}: calls={} total={:.2f} ms avg={:.2f} ms", iteration, StateNames[state], stats.calls, stats.totalTimeMs, stats.averageTimeMs());
257+
}
258+
}
238259
}
239260

240261
template class Tracker<7>;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,7 @@ void ITSTrackingInterface::finaliseCCDB(ConcreteDataMatcher& matcher, void* obj)
457457

458458
void ITSTrackingInterface::printSummary() const
459459
{
460+
mVertexer->printSummary();
460461
mTracker->printSummary();
461462
}
462463

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

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@
1515

1616
#include "ITStracking/Vertexer.h"
1717
#include "ITStracking/BoundedAllocator.h"
18-
#include "ITStracking/Cluster.h"
19-
20-
#include "ITStracking/ClusterLines.h"
21-
#include "ITStracking/Tracklet.h"
22-
#include "ITStracking/IndexTableUtils.h"
2318
#include "ITStracking/VertexerTraits.h"
2419
#include "ITStracking/TrackingConfigParam.h"
2520

@@ -41,16 +36,17 @@ float Vertexer<NLayers>::clustersToVertices(LogFunc logger)
4136
LogFunc evalLog = [](const std::string&) {};
4237

4338
if (mTimeFrame->hasMCinformation() && mVertParams[0].useTruthSeeding) {
44-
float t = evaluateTask(&Vertexer::addTruthSeeds, StateNames[mCurState = TruthSeeding], 0, evalLog);
39+
float t = evaluateTask(&Vertexer::addTruthSeeds, StateNames[mCurStep = TruthSeeding], 0, evalLog);
4540
sortVertices();
41+
++mTimeFrameCounter;
4642
return t;
4743
}
4844

4945
TrackingParameters trkPars;
5046
mTraits->updateVertexingParameters(mVertParams);
5147

5248
auto handleException = [&](const auto& err) {
53-
LOGP(error, "Encountered critical error in step {}, stopping further processing of this TF: {}", StateNames[mCurState], err.what());
49+
LOGP(error, "Encountered critical error in step {}, stopping further processing of this TF: {}", StateNames[mCurStep], err.what());
5450
if (!mVertParams[0].DropTFUponFailure) {
5551
throw err;
5652
} else {
@@ -59,22 +55,23 @@ float Vertexer<NLayers>::clustersToVertices(LogFunc logger)
5955
};
6056

6157
float timeTracklet{0.f}, timeSelection{0.f}, timeVertexing{0.f}, timeInit{0.f};
58+
bool completed = false;
6259
try {
6360
for (int iteration = 0; iteration < (int)mVertParams.size(); ++iteration) {
6461
mMemoryPool->setMaxMemory(mVertParams[iteration].MaxMemory);
6562
unsigned int nTracklets01{0}, nTracklets12{0};
6663
logger(fmt::format("=== ITS {} Seeding vertexer iteration {} summary:", mTraits->getName(), iteration));
6764
trkPars.PhiBins = mTraits->getVertexingParameters()[0].PhiBins;
6865
trkPars.ZBins = mTraits->getVertexingParameters()[0].ZBins;
69-
auto timeInitIteration = evaluateTask(&Vertexer::initialiseVertexer, StateNames[mCurState = Init], iteration, evalLog, trkPars, iteration);
70-
auto timeTrackletIteration = evaluateTask(&Vertexer::findTracklets, StateNames[mCurState = Trackleting], iteration, evalLog, iteration);
66+
auto timeInitIteration = evaluateTask(&Vertexer::initialiseVertexer, StateNames[mCurStep = Init], iteration, evalLog, trkPars, iteration);
67+
auto timeTrackletIteration = evaluateTask(&Vertexer::findTracklets, StateNames[mCurStep = Trackleting], iteration, evalLog, iteration);
7168
nTracklets01 = mTimeFrame->getTotalTrackletsTF(0);
7269
nTracklets12 = mTimeFrame->getTotalTrackletsTF(1);
73-
auto timeSelectionIteration = evaluateTask(&Vertexer::validateTracklets, StateNames[mCurState = Validating], iteration, evalLog, iteration);
70+
auto timeSelectionIteration = evaluateTask(&Vertexer::validateTracklets, StateNames[mCurStep = Selection], iteration, evalLog, iteration);
7471
const auto nVerticesBefore = mTimeFrame->getPrimaryVertices().size();
75-
auto timeVertexingIteration = evaluateTask(&Vertexer::findVertices, StateNames[mCurState = Finding], iteration, evalLog, iteration);
72+
auto timeVertexingIteration = evaluateTask(&Vertexer::findVertices, StateNames[mCurStep = Finding], iteration, evalLog, iteration);
7673
const auto nVerticesAfter = mTimeFrame->getPrimaryVertices().size();
77-
printEpilog(logger, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), nVerticesAfter - nVerticesBefore, nVerticesAfter, timeTrackletIteration, timeSelectionIteration, timeVertexingIteration);
74+
printEpilog(logger, nTracklets01, nTracklets12, mTimeFrame->getNLinesTotal(), nVerticesAfter - nVerticesBefore, nVerticesAfter, timeInitIteration, timeTrackletIteration, timeSelectionIteration, timeVertexingIteration);
7875
timeInit += timeInitIteration;
7976
timeTracklet += timeTrackletIteration;
8077
timeSelection += timeSelectionIteration;
@@ -84,6 +81,7 @@ float Vertexer<NLayers>::clustersToVertices(LogFunc logger)
8481
sortVertices();
8582
mTimeFrame->updateROFVertexLookupTable();
8683
}
84+
completed = true;
8785
} catch (const BoundedMemoryResource::MemoryLimitExceeded& err) {
8886
handleException(err);
8987
} catch (const std::bad_alloc& err) {
@@ -92,6 +90,10 @@ float Vertexer<NLayers>::clustersToVertices(LogFunc logger)
9290
LOGP(fatal, "Uncaught exception!");
9391
}
9492

93+
if (completed) {
94+
++mTimeFrameCounter;
95+
}
96+
9597
return timeInit + timeTracklet + timeSelection + timeVertexing;
9698
}
9799

@@ -135,15 +137,43 @@ void Vertexer<NLayers>::adoptTimeFrame(TimeFrameN& tf)
135137
mTraits->adoptTimeFrame(&tf);
136138
}
137139

140+
template <int NLayers>
141+
void Vertexer<NLayers>::addTimingStatCurStep(int iteration, double timeMs)
142+
{
143+
if (iteration < 0) {
144+
return;
145+
}
146+
if (mTimingStats.size() < (iteration + 1)) {
147+
mTimingStats.resize(iteration + 1);
148+
}
149+
mTimingStats[iteration][mCurStep].add(timeMs);
150+
}
151+
152+
template <int NLayers>
153+
void Vertexer<NLayers>::printSummary() const
154+
{
155+
LOGP(info, "Vertexer summary: Processed {} TFs", mTimeFrameCounter);
156+
for (size_t iteration = 0; iteration < mTimingStats.size(); ++iteration) {
157+
for (size_t state = 0; state < NSteps; ++state) {
158+
const auto& stats = mTimingStats[iteration][state];
159+
if (!stats.calls) {
160+
continue;
161+
}
162+
LOGP(info, " - iter {} {}: calls={} total={:.2f} ms avg={:.2f} ms", iteration, StateNames[state], stats.calls, stats.totalTimeMs, stats.averageTimeMs());
163+
}
164+
}
165+
}
166+
138167
template <int NLayers>
139168
void Vertexer<NLayers>::printEpilog(LogFunc& logger,
140-
const unsigned int trackletN01, const unsigned int trackletN12,
141-
const unsigned selectedN, const unsigned int vertexN, const unsigned int totalVertexN,
142-
const float trackletT, const float selecT, const float vertexT)
169+
unsigned int trackletN01, unsigned int trackletN12,
170+
unsigned selectedN, unsigned int vertexN, unsigned int totalVertexN,
171+
float initT, float trackletT, float selecT, float vertexT)
143172
{
144-
logger(fmt::format(" - {} Vertexer: found {} | {} tracklets in: {:.2f} ms", mTraits->getName(), trackletN01, trackletN12, trackletT));
145-
logger(fmt::format(" - {} Vertexer: selected {} tracklets in: {:.2f} ms", mTraits->getName(), selectedN, selecT));
146-
logger(fmt::format(" - {} Vertexer: found {} vertices (total: {}) in: {:.2f} ms", mTraits->getName(), vertexN, totalVertexN, vertexT));
173+
logger(fmt::format(" - {}: completed in {:.2f} ms", StateNames[Init], initT));
174+
logger(fmt::format(" - {}: found {} | {} tracklets in {:.2f} ms", StateNames[Trackleting], trackletN01, trackletN12, trackletT));
175+
logger(fmt::format(" - {}: selected {} tracklets in {:.2f} ms", StateNames[Selection], selectedN, selecT));
176+
logger(fmt::format(" - {}: found {} vertices (total {}) in {:.2f} ms", StateNames[Finding], vertexN, totalVertexN, vertexT));
147177
}
148178

149179
template class Vertexer<7>;

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,11 @@ void TrackerDPL::endOfStream(EndOfStreamContext& ec)
8585

8686
void TrackerDPL::end()
8787
{
88-
mITSTrackingInterface.printSummary();
89-
LOGF(info, "ITS CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
88+
if (static bool printOnce{false}; !printOnce) {
89+
printOnce = true;
90+
mITSTrackingInterface.printSummary();
91+
LOGF(info, "ITS CA-Tracker total timing: Cpu: %.3e Real: %.3e s in %d slots", mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1);
92+
}
9093
}
9194

9295
DataProcessorSpec getTrackerSpec(bool useMC, bool doStag, bool useGeom, int trgType, TrackingMode::Type trMode, const bool overrBeamEst, o2::gpu::gpudatatypes::DeviceType dType)

0 commit comments

Comments
 (0)