Project
Loading...
Searching...
No Matches
TrackingTopology.h
Go to the documentation of this file.
1// Copyright 2019-2026 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.
11
12#ifndef TRACKINGITSU_INCLUDE_TRACKINGTOPOLOGY_H_
13#define TRACKINGITSU_INCLUDE_TRACKINGTOPOLOGY_H_
14
15#include <array>
16#include <cstdint>
17#include <limits>
18#include <type_traits>
19
20#ifndef GPUCA_GPUCODE
21#include <fmt/format.h>
22#include <string>
23#include "Framework/Logger.h"
24#endif
25
27#include "GPUCommonDef.h"
28#include "GPUCommonMath.h"
30
31namespace o2::its
32{
33
34template <int NLayers>
36{
37 public:
38 using Id = uint8_t;
39 using Mask = LayerMask;
41 static constexpr int MaxTransitions = (NLayers * (NLayers - 1)) / 2;
42 static constexpr int MaxCells = (NLayers * (NLayers - 1) * (NLayers - 2)) / 6;
43 static_assert(NLayers < std::numeric_limits<Id>::max());
44 static_assert(MaxTransitions <= std::numeric_limits<Id>::max());
45 static_assert(MaxCells <= std::numeric_limits<Id>::max());
46
47 // Describes from which layer to which layer the look-up happens
52 static_assert(std::is_standard_layout_v<LayerTransition>);
53 static_assert(std::is_trivially_copyable_v<LayerTransition>);
54 static_assert(sizeof(LayerTransition) == (2 * sizeof(Id)));
55
56 // Describes from which LayerTransition a tracklet is allowed to originate
57 // and with which LayerTransition this can be combined additionally the hitMasked is cached
63 static_assert(std::is_standard_layout_v<CellTopology>);
64 static_assert(std::is_trivially_copyable_v<CellTopology>);
65 static_assert(sizeof(CellTopology) == (2 * sizeof(Id)) + sizeof(Mask));
66
67 // GPU ready view of the underlying LUTs
68 struct View {
70 const CellTopology* cells{nullptr};
72 const Id* cellsByFirstTransition{nullptr};
76
77 GPUhdi() const LayerTransition& getTransition(Id id) const { return transitions[id]; }
78 GPUhdi() const CellTopology& getCell(Id id) const { return cells[id]; }
79 GPUhdi() Range getCellsStartingWithTransition(Id transitionId) const { return cellsByFirstTransitionIndex[transitionId]; }
80
81#ifndef GPUCA_GPUCODE
82 std::string asString() const
83 {
84 std::string out = fmt::format("TrackingTopology: transitions={} cells={}", nTransitions, nCells);
85 out += "\n transitions:";
86 for (Id transitionId = 0; transitionId < nTransitions; ++transitionId) {
87 const auto& t = transitions[transitionId];
88 out += fmt::format("\n {}: {} -> {}", transitionId, t.fromLayer, t.toLayer);
89 }
90 out += "\n cells:";
91 for (Id cellId = 0; cellId < nCells; ++cellId) {
92 const auto& c = cells[cellId];
93 const auto& first = transitions[c.firstTransition];
94 const auto& second = transitions[c.secondTransition];
95 out += fmt::format("\n {}: {} -> {} -> {} hitMask={} transitions=({}, {})", cellId, first.fromLayer, first.toLayer, second.toLayer, c.hitLayerMask.asString(), c.firstTransition, c.secondTransition);
96 }
97 return out;
98 }
99
100 void print() const
101 {
102 LOGP(info, "{}", asString());
103 }
104#endif
105 };
106
107 void init(int maxLayers, int maxHoles, Mask holeLayerMask)
108 {
109 clear();
110 mMaxLayers = o2::gpu::CAMath::Max(0, o2::gpu::CAMath::Min(maxLayers, NLayers));
111 mMaxHoles = o2::gpu::CAMath::Max(maxHoles, 0);
112 mHoleLayerMask = holeLayerMask;
113 for (int fromLayer = 0; fromLayer < mMaxLayers; ++fromLayer) {
114 for (int toLayer = fromLayer + 1; toLayer < mMaxLayers; ++toLayer) {
115 if (Mask::skipped(fromLayer, toLayer).isAllowedHoleMask(mMaxHoles, mHoleLayerMask)) {
116 mTransitions[mNTransitions++] = LayerTransition{static_cast<Id>(fromLayer), static_cast<Id>(toLayer)};
117 }
118 }
119 }
120
121 for (Id firstId = 0; firstId < mNTransitions; ++firstId) {
122 const auto& first = mTransitions[firstId];
123 for (Id secondId = 0; secondId < mNTransitions; ++secondId) {
124 const auto& second = mTransitions[secondId];
125 if (first.toLayer != second.fromLayer) {
126 continue;
127 }
128 const Mask hitMask{first.fromLayer, first.toLayer, second.toLayer};
129 if (hitMask.isAllowed(mMaxHoles, mHoleLayerMask)) {
130 mCells[mNCells++] = CellTopology{firstId, secondId, hitMask};
131 }
132 }
133 }
134
135 fillCellsByTransition();
136 }
137
138 View getView() const
139 {
140 return View{mTransitions.data(),
141 mCells.data(),
142 mCellsByFirstTransitionIndex.data(),
143 mCellsByFirstTransition.data(),
144 mNTransitions,
145 mNCells,
146 mNCellsByFirstTransition};
147 }
148
149 View getDeviceView(const LayerTransition* deviceTransitions,
150 const CellTopology* deviceCells,
151 const Range* deviceCellsByFirstTransitionIndex,
152 const Id* deviceCellsByFirstTransition) const
153 {
154 return View{deviceTransitions,
155 deviceCells,
156 deviceCellsByFirstTransitionIndex,
157 deviceCellsByFirstTransition,
158 mNTransitions,
159 mNCells,
160 mNCellsByFirstTransition};
161 }
162
163 const auto& getTransitions() const noexcept { return mTransitions; }
164 const auto& getCells() const noexcept { return mCells; }
165 const auto& getCellsByFirstTransitionIndex() const noexcept { return mCellsByFirstTransitionIndex; }
166 const auto& getCellsByFirstTransition() const noexcept { return mCellsByFirstTransition; }
167 Id getNTransitions() const noexcept { return mNTransitions; }
168 Id getNCells() const noexcept { return mNCells; }
169 Id getNCellsByFirstTransition() const noexcept { return mNCellsByFirstTransition; }
170
171 private:
172 void clear()
173 {
174 mNTransitions = 0;
175 mNCells = 0;
176 mNCellsByFirstTransition = 0;
177 mTransitions.fill({});
178 mCells.fill({});
179 mCellsByFirstTransitionIndex.fill(Range{0, 0});
180 mCellsByFirstTransition.fill(0);
181 }
182
183 void fillCellsByTransition()
184 {
185 std::array<Id, MaxTransitions> counts{};
186 for (Id cellId = 0; cellId < mNCells; ++cellId) {
187 ++counts[mCells[cellId].firstTransition];
188 }
189
190 Id offset = 0;
191 for (Id transitionId = 0; transitionId < mNTransitions; ++transitionId) {
192 mCellsByFirstTransitionIndex[transitionId].setFirstEntry(offset);
193 mCellsByFirstTransitionIndex[transitionId].setEntries(counts[transitionId]);
194 offset += counts[transitionId];
195 }
196
197 std::array<Id, MaxTransitions> cursor{};
198 for (Id cellId = 0; cellId < mNCells; ++cellId) {
199 const Id transitionId = mCells[cellId].firstTransition;
200 mCellsByFirstTransition[mCellsByFirstTransitionIndex[transitionId].getFirstEntry() + cursor[transitionId]++] = cellId;
201 }
202 mNCellsByFirstTransition = offset;
203 }
204
205 int mMaxLayers{0};
206 int mMaxHoles{0};
207 Mask mHoleLayerMask{0};
208 Id mNTransitions{0};
209 Id mNCells{0};
210 Id mNCellsByFirstTransition{0};
211 std::array<LayerTransition, MaxTransitions> mTransitions{};
212 std::array<CellTopology, MaxCells> mCells{};
213 std::array<Range, MaxTransitions> mCellsByFirstTransitionIndex{};
214 std::array<Id, MaxCells> mCellsByFirstTransition{};
215};
216
217} // namespace o2::its
218
219#endif
Class to refer to the 1st entry and N elements of some group in the continuous container.
uint32_t c
Definition RawData.h:2
const auto & getCells() const noexcept
const auto & getCellsByFirstTransitionIndex() const noexcept
o2::dataformats::RangeReference< Id, Id > Range
static constexpr int MaxCells
const auto & getCellsByFirstTransition() const noexcept
Id getNTransitions() const noexcept
static constexpr int MaxTransitions
Id getNCellsByFirstTransition() const noexcept
View getDeviceView(const LayerTransition *deviceTransitions, const CellTopology *deviceCells, const Range *deviceCellsByFirstTransitionIndex, const Id *deviceCellsByFirstTransition) const
const auto & getTransitions() const noexcept
Id getNCells() const noexcept
void init(int maxLayers, int maxHoles, Mask holeLayerMask)
GLintptr offset
Definition glcorearb.h:660
GLuint id
Definition glcorearb.h:650
GPUhdi() const LayerTransition &getTransition(Id id) const
const LayerTransition * transitions
GPUhdi() Range getCellsStartingWithTransition(Id transitionId) const
GPUhdi() const CellTopology &getCell(Id id) const