Skip to content

Commit dbf9319

Browse files
committed
ITS: debug dump
1 parent 5491ae4 commit dbf9319

File tree

9 files changed

+301
-152
lines changed

9 files changed

+301
-152
lines changed

Detectors/ITSMFT/ITS/tracking/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ o2_add_library(ITSTrackingInterface
4848
o2_target_root_dictionary(ITStracking
4949
HEADERS include/ITStracking/Tracklet.h
5050
include/ITStracking/Cluster.h
51+
include/ITStracking/Seeding.h
5152
include/ITStracking/TrackingConfigParam.h
5253
LINKDEF src/TrackingLinkDef.h)
5354

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ struct TrackingParameters {
5555
int MinTrackLength = 7;
5656
float NSigmaCut = 5;
5757
float NSigmaCutZ = 5;
58-
float NSigmaCutPhi = 1;
58+
float NSigmaCutPhi = 5;
5959
int NTimeSlices{1};
6060
/// Trackleting cuts
6161
float TrackletMinPt = 0.3f;

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

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,29 @@ using TimeEstBC = o2::dataformats::TimeStampWithError<uint32_t, uint16_t>;
3030
using Vertex = o2::dataformats::Vertex<TimeEstBC>;
3131

3232
template <bool IsConst, typename T>
33-
using maybe_const = typename std::conditional<IsConst, const T, T>::type;
33+
using maybe_const = std::conditional_t<IsConst, const T, T>;
34+
35+
// simple implemnetion of logging with exp. backoff
36+
struct LogLogThrottler {
37+
uint32_t evCount{0};
38+
uint32_t nextLog{1};
39+
int32_t iteration{-1};
40+
int32_t layer{-1};
41+
bool needToLog(int32_t iter, int32_t lay)
42+
{
43+
if (iteration != iter || layer != lay) {
44+
iteration = iter;
45+
layer = lay;
46+
evCount = 0;
47+
nextLog = 1;
48+
}
49+
if (++evCount > nextLog) {
50+
nextLog *= 2;
51+
return true;
52+
}
53+
return false;
54+
}
55+
};
3456

3557
} // namespace o2::its
3658

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

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "ITStracking/Constants.h"
2727
#include "GPUCommonDef.h"
2828
#include "GPUCommonMath.h"
29+
#include "GPUCommonRtypes.h"
2930
#include "GPUCommonLogger.h"
3031

3132
namespace o2::its
@@ -57,7 +58,7 @@ struct LinearizedTrack {
5758

5859
float getChi2(const dataformats::VertexBase&) const;
5960

60-
int32_t cellIdx{-1}; /// < index of attached cell
61+
int32_t cellIdx{-1}; ///< index of attached cell
6162
float x{0.f}; ///< reference X
6263
float y{0.f}; ///< Y at X
6364
float z{0.f}; ///< Z at X
@@ -68,7 +69,7 @@ struct LinearizedTrack {
6869
float tgL{0.f}; ///< tangent(lambda)
6970
float cosAlp{0.f}; ///< cos of alpha frame
7071
float sinAlp{0.f}; ///< sin of alpha frame
71-
TimeEstBC time{}; ///< timestamp; exclusive range of BCs that are spanned [time, time+error)
72+
TimeEstBC time; ///< timestamp; exclusive range of BCs that are spanned [time, time+error)
7273
uint8_t status{0}; ///< status bits
7374

7475
GPUhdi() void markDead() noexcept { status |= kDead; }
@@ -78,6 +79,8 @@ struct LinearizedTrack {
7879
{
7980
LOGP(info, "LT: cell={} x={} y={} z={} t={}+{} status={:b}", cellIdx, x, y, z, time.getTimeStamp(), time.getTimeStampError(), status);
8081
}
82+
83+
ClassDefNV(LinearizedTrack, 1);
8184
};
8285

8386
struct VertexSeed : public Vertex {
@@ -116,6 +119,7 @@ constexpr int32_t NDim{2};
116119
struct DBSCANParams {
117120
std::array<float, NDim> eps; // Maximum distance per dimension (z,t)
118121
int32_t minPts; // Minimum points to form a dense region
122+
size_t avgNeigh{1024}; // average number of neighbors
119123
};
120124

121125
// Clustering result
@@ -127,19 +131,8 @@ struct DBSCANResult {
127131
int32_t nNoise = 0;
128132
};
129133

130-
// Flat neighbor list
131-
struct FlatNeighborList {
132-
std::vector<size_t> indices;
133-
std::vector<size_t> offsets;
134-
[[nodiscard]] size_t getSize(size_t i) const
135-
{
136-
return offsets[i + 1] - offsets[i];
137-
}
138-
[[nodiscard]] std::span<const size_t> getNeighbors(size_t i) const
139-
{
140-
return {&indices[offsets[i]], getSize(i)};
141-
}
142-
};
134+
// Neighbor list
135+
using NeighborList = std::vector<std::vector<size_t>>;
143136

144137
// Point classification
145138
enum DBSCANLabel : int32_t {
@@ -149,6 +142,29 @@ enum DBSCANLabel : int32_t {
149142
DB_CORE = -(1 << 3),
150143
};
151144

145+
// #define ITS_DB_MEASURE_TIMING
146+
#ifdef ITS_DB_MEASURE_TIMING
147+
class ScopedTimer
148+
{
149+
std::string_view name;
150+
std::chrono::high_resolution_clock::time_point start;
151+
152+
public:
153+
explicit ScopedTimer(std::string_view name)
154+
: name(name), start(std::chrono::high_resolution_clock::now()) {}
155+
156+
~ScopedTimer()
157+
{
158+
auto end = std::chrono::high_resolution_clock::now();
159+
double elapsed_ms = std::chrono::duration<double, std::milli>(end - start).count();
160+
LOGP(info, "{} : {:.2f} ms", name, elapsed_ms);
161+
}
162+
};
163+
#define SCOPED_TIMER(name) ScopedTimer _timer##__LINE__(name)
164+
#else
165+
#define SCOPED_TIMER(name) ((void)0)
166+
#endif
167+
152168
class DBSCANDistance
153169
{
154170
using EPS = decltype(DBSCANParams::eps);
@@ -172,20 +188,21 @@ class DBSCANDistance
172188
const int end0 = l0.time.getTimeStamp() + l0.time.getTimeStampError();
173189
const int end1 = l1.time.getTimeStamp() + l1.time.getTimeStampError();
174190
const int diffT = o2::gpu::CAMath::Max(0, o2::gpu::CAMath::Max((int)l0.time.getTimeStamp(), (int)l1.time.getTimeStamp())) - o2::gpu::CAMath::Min(end0, end1);
175-
return diffT <= mEps[1];
191+
return diffT <= (int)mEps[1];
176192
}
177193

178-
// Batch compute
179-
void computeNeighbors(const LinearizedTrack& query, const LinearizedTrack* tracks, const std::vector<size_t>& candidates, std::vector<size_t>& neighbors) const
194+
float getDistance(const LinearizedTrack& l0, const LinearizedTrack& l1) const
180195
{
181-
neighbors.clear();
182-
neighbors.reserve(candidates.size());
183-
for (auto idx : candidates) {
184-
const auto& lt = tracks[idx];
185-
if (areNeighbours(query, lt)) {
186-
neighbors.push_back(idx);
187-
}
196+
if (l0.isDead() || l1.isDead()) {
197+
return std::numeric_limits<float>::max();
198+
}
199+
const int end0 = l0.time.getTimeStamp() + l0.time.getTimeStampError();
200+
const int end1 = l1.time.getTimeStamp() + l1.time.getTimeStampError();
201+
const int diffT = o2::gpu::CAMath::Max(0, o2::gpu::CAMath::Max((int)l0.time.getTimeStamp(), (int)l1.time.getTimeStamp())) - o2::gpu::CAMath::Min(end0, end1);
202+
if (diffT > (int)mEps[1]) {
203+
return std::numeric_limits<float>::max();
188204
}
205+
return o2::gpu::CAMath::Abs(l0.z - l1.z);
189206
}
190207

191208
private:
@@ -199,11 +216,13 @@ class DBSCAN
199216
DBSCAN(const DBSCANParams& p);
200217

201218
DBSCANResult cluster(const LinearizedTrack* tracks, size_t n);
219+
const auto& getParams() { return mParams; }
220+
const auto& getDistance() { return mDistance; }
202221

203222
private:
204-
void findNeighbors(const LinearizedTrack* tracks, size_t n, FlatNeighborList& neighbors);
205-
void classify(size_t n, const FlatNeighborList& neighbors, std::vector<int32_t>& labels);
206-
void expandCluster(size_t i, int32_t idx, const FlatNeighborList& neighbors, std::vector<int32_t>& labels) const;
223+
void findNeighbors(const LinearizedTrack* tracks, size_t n, NeighborList& neighbors);
224+
void classify(size_t n, const NeighborList& neighbors, std::vector<int32_t>& labels);
225+
void expandCluster(size_t i, int32_t idx, const NeighborList& neighbors, std::vector<int32_t>& labels) const;
207226

208227
DBSCANParams mParams;
209228
DBSCANDistance mDistance;
@@ -220,6 +239,7 @@ class Grid
220239
Grid(const LinearizedTrack* tracks, size_t n, const std::array<float, NDim>& cellSizes)
221240
: mTracks(tracks), mNPoints(n), mCellSizes(cellSizes)
222241
{
242+
SCOPED_TIMER("Grid construction");
223243
computeBounds();
224244
computeGridDimensions();
225245
allocateCells();

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
#ifndef TRACKINGITSU_INCLUDE_TRACKERTRAITS_H_
1717
#define TRACKINGITSU_INCLUDE_TRACKERTRAITS_H_
1818

19-
#include <oneapi/tbb.h>
19+
#include <oneapi/tbb/task_arena.h>
20+
21+
#include <type_traits>
2022

2123
#include "DetectorsBase/Propagator.h"
2224
#include "ITStracking/Configuration.h"
@@ -27,8 +29,6 @@
2729
#include "ITStracking/Cell.h"
2830
#include "ITStracking/BoundedAllocator.h"
2931

30-
// #define OPTIMISATION_OUTPUT
31-
3232
namespace o2
3333
{
3434
namespace gpu
@@ -42,16 +42,20 @@ class TrackITSExt;
4242
template <int NLayers = 7>
4343
class TrackerTraits
4444
{
45+
struct Neighbor {
46+
int32_t cell{-1}, nextCell{-1}, level{-1};
47+
};
48+
4549
public:
4650
using IndexTableUtilsN = IndexTableUtils<NLayers>;
4751
using CellSeedN = CellSeed<NLayers>;
4852

49-
TrackerTraits() = default;
53+
TrackerTraits();
5054
TrackerTraits(const TrackerTraits&) = delete;
5155
TrackerTraits(TrackerTraits&&) = delete;
5256
TrackerTraits& operator=(const TrackerTraits&) = delete;
5357
TrackerTraits& operator=(TrackerTraits&&) = delete;
54-
virtual ~TrackerTraits() = default;
58+
virtual ~TrackerTraits();
5559

5660
virtual void adoptTimeFrame(TimeFrame<NLayers>* tf) { mTimeFrame = tf; }
5761
virtual void initialiseTimeFrame(const RecoIteration& reco) { mTimeFrame->initialise(reco); }
@@ -106,14 +110,19 @@ class TrackerTraits
106110
std::shared_ptr<BoundedMemoryResource> mMemoryPool;
107111
std::shared_ptr<tbb::task_arena> mTaskArena;
108112

113+
// Debug output
114+
inline void debugComputeLayerTracklets(int iteration, int layer, const Cluster& currentCls, const Cluster& nextCls, const Vertex& pv, float sigmaZ, float sigmaPhi, bool accepted);
115+
inline void debugComputeLayerCells(int iteration, int layer, int currentTrkl, int nextTrkl, bool accepted);
116+
inline void debugFindCellsNeighbours(int iteration, int layer, int currentCell, int nextCell, bool accepted);
117+
109118
protected:
110119
o2::gpu::GPUChainITS* mChain = nullptr;
111120
TimeFrame<NLayers>* mTimeFrame;
112121
std::vector<RecoIteration> mRecoParams;
113122

114123
float mBz{-999.f};
115124
bool mIsZeroField{false};
116-
dbscan::DBSCAN mDBScan;
125+
dbscan::DBSCAN mDBScan{};
117126
};
118127

119128
template <int NLayers>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ struct TrackerParamConfig : public o2::conf::ConfigurableParamHelper<TrackerPara
6666
int seedingMaxFitIter{3}; // maximum iterations for fit
6767
int seedingMinTracksIter{50}; // minimum tracks needed for one iteration
6868
int seedingDBScanMinPt{100}; // DBSCAN: minimum number of cluster points
69-
float seedingDBScanEpsZ{0.1f}; // DBSCAN: maximum epsilon z
69+
float seedingDBScanEpsZ{0.2f}; // DBSCAN: maximum epsilon z
7070
float seedingDBScanEpsT{10.f}; // DBSCAN: maximum epsilon t (BC)
7171
float seedingVertexExtraErr2[6] = {0.f}; // impose additional errors on seeding vertices
7272
bool seedingUseMCTruth{false}; // skip seeding and impose MC event information

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

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -150,11 +150,12 @@ DBSCANResult DBSCAN::cluster(const LinearizedTrack* tracks, size_t n)
150150
}
151151

152152
// Step 1: Find neighbors for all points using grid
153-
FlatNeighborList neighbors;
153+
NeighborList neighbors;
154154
findNeighbors(tracks, n, neighbors);
155155
// Step 2: Classify points and form clusters
156156
classify(n, neighbors, result.labels);
157157
// Step 3: Count clusters and noise points
158+
SCOPED_TIMER("finalizing");
158159
int32_t max_label = *std::ranges::max_element(result.labels);
159160
result.nClusters = max_label + 1;
160161
result.nNoise = static_cast<int32_t>(std::count(result.labels.begin(), result.labels.end(), DB_NOISE));
@@ -184,49 +185,39 @@ DBSCANResult DBSCAN::cluster(const LinearizedTrack* tracks, size_t n)
184185
return result;
185186
}
186187

187-
void DBSCAN::findNeighbors(const LinearizedTrack* tracks, size_t n, FlatNeighborList& neighbors)
188+
void DBSCAN::findNeighbors(const LinearizedTrack* tracks, size_t n, NeighborList& neighbors)
188189
{
189190
Grid grid(tracks, n, mParams.eps);
190-
std::vector<std::vector<size_t>> temp(n);
191191

192192
// Parallel neighbor finding
193+
SCOPED_TIMER("find neighbors");
194+
neighbors.resize(n);
193195
tbb::parallel_for(
194196
tbb::blocked_range<size_t>(0, n), [&](const tbb::blocked_range<size_t>& range) {
195-
std::vector<const GridCell*> neighbor_cells;
196-
std::vector<size_t> candidates;
197+
std::vector<const GridCell*> neighborCells;
197198

198199
for (size_t i = range.begin(); i < range.end(); ++i) {
199200
const auto& query = tracks[i];
200201
if (query.isDead()) {
201202
continue;
202203
}
203204
auto coords = grid.getGridCoords(i);
204-
grid.getNeighborCells(coords, neighbor_cells);
205-
candidates.clear();
206-
for (const GridCell* cell : neighbor_cells) {
205+
grid.getNeighborCells(coords, neighborCells);
206+
neighbors[i].reserve(mParams.avgNeigh);
207+
for (const GridCell* cell : neighborCells) {
207208
for (auto idx : *cell) {
208-
if (idx != i) {
209-
candidates.push_back(idx);
209+
if (idx != i && mDistance.areNeighbours(query, tracks[idx])) {
210+
neighbors[i].push_back(idx);
210211
}
211212
}
212213
}
213-
mDistance.computeNeighbors(query, tracks, candidates, temp[i]);
214214
}
215215
});
216-
// flatten
217-
neighbors.offsets.resize(n + 1);
218-
neighbors.offsets[0] = 0;
219-
for (size_t i = 0; i < n; ++i) {
220-
neighbors.offsets[i + 1] = neighbors.offsets[i] + temp[i].size();
221-
}
222-
neighbors.indices.resize(neighbors.offsets[n]);
223-
for (size_t i = 0; i < n; ++i) {
224-
std::copy(temp[i].begin(), temp[i].end(), &neighbors.indices[neighbors.offsets[i]]);
225-
}
226216
}
227217

228-
void DBSCAN::classify(size_t n, const FlatNeighborList& neighbors, std::vector<int32_t>& labels)
218+
void DBSCAN::classify(size_t n, const NeighborList& neighbors, std::vector<int32_t>& labels)
229219
{
220+
SCOPED_TIMER("classify");
230221
std::vector<bool> isCore(n, false);
231222
int32_t nextClsIdx{0};
232223

@@ -235,7 +226,7 @@ void DBSCAN::classify(size_t n, const FlatNeighborList& neighbors, std::vector<i
235226
tbb::blocked_range<size_t>(0, n),
236227
[&](const tbb::blocked_range<size_t>& range) {
237228
for (size_t i = range.begin(); i < range.end(); ++i) {
238-
if (static_cast<int32_t>(neighbors.getSize(i)) >= mParams.minPts) {
229+
if (static_cast<int32_t>(neighbors[i].size()) >= mParams.minPts) {
239230
isCore[i] = true;
240231
}
241232
}
@@ -263,7 +254,7 @@ void DBSCAN::classify(size_t n, const FlatNeighborList& neighbors, std::vector<i
263254
});
264255
}
265256

266-
void DBSCAN::expandCluster(size_t i, int32_t idx, const FlatNeighborList& neighbors, std::vector<int32_t>& labels) const
257+
void DBSCAN::expandCluster(size_t i, int32_t idx, const NeighborList& neighbors, std::vector<int32_t>& labels) const
267258
{
268259
std::queue<size_t> seeds;
269260
seeds.push(i);
@@ -274,8 +265,8 @@ void DBSCAN::expandCluster(size_t i, int32_t idx, const FlatNeighborList& neighb
274265
seeds.pop();
275266

276267
// If current is a core point, add its neighbors to the cluster
277-
if (static_cast<int32_t>(neighbors.getSize(current)) >= mParams.minPts) {
278-
for (auto neighbor : neighbors.getNeighbors(current)) {
268+
if (static_cast<int32_t>(neighbors[current].size()) >= mParams.minPts) {
269+
for (const auto neighbor : neighbors[current]) {
279270
if (labels[neighbor] == DB_UNVISITED) {
280271
labels[neighbor] = idx;
281272
seeds.push(neighbor);

0 commit comments

Comments
 (0)