41 static constexpr int MaxLinks = (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(MaxLinks <= std::numeric_limits<Id>::max());
45 static_assert(MaxCells <= std::numeric_limits<Id>::max());
52 static_assert(std::is_standard_layout_v<LayerLink>);
53 static_assert(std::is_trivially_copyable_v<LayerLink>);
54 static_assert(
sizeof(LayerLink) == (2 *
sizeof(
Id)));
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));
87 for (
Id linkId = 0; linkId <
nLinks; ++linkId) {
88 const auto& t =
links[linkId];
89 out += fmt::format(
"\n {}: {} -> {}", linkId, t.fromLayer, t.toLayer);
92 for (
Id cellId = 0; cellId <
nCells; ++cellId) {
93 const auto&
c =
cells[cellId];
95 const auto& second =
links[
c.secondLink];
96 out += fmt::format(
"\n {}: {} -> {} -> {} hitMask={} links=({}, {})", cellId,
first.fromLayer,
first.toLayer, second.toLayer,
c.hitLayerMask.asString(),
c.firstLink,
c.secondLink);
108 void init(
int maxLayers,
int maxHoles,
Mask holeLayerMask,
Mask seedingLayerMask = 0)
111 mMaxLayers = o2::gpu::CAMath::Max(0, o2::gpu::CAMath::Min(maxLayers, NLayers));
112 mMaxHoles = o2::gpu::CAMath::Max(maxHoles, 0);
113 mHoleLayerMask = holeLayerMask;
114 mSeedingLayerMask = seedingLayerMask.empty() ? Mask::span(0, mMaxLayers - 1) : (seedingLayerMask & Mask::span(0, mMaxLayers - 1));
117 LOGP(fatal,
"Tracking topology has {} seeding layers, but at least {} are required to build CA cells", mSeedingLayerMask.count(),
constants::ClustersPerCell);
120 for (
int fromLayer = 0; fromLayer < mMaxLayers; ++fromLayer) {
121 if (!mSeedingLayerMask.has(fromLayer)) {
124 for (
int toLayer = fromLayer + 1; toLayer < mMaxLayers; ++toLayer) {
125 if (mSeedingLayerMask.has(toLayer) && isAllowedSeedingLink(fromLayer, toLayer)) {
126 mLinks[mNLinks++] =
LayerLink{
static_cast<Id>(fromLayer),
static_cast<Id>(toLayer)};
131 for (
Id firstId = 0; firstId < mNLinks; ++firstId) {
132 const auto&
first = mLinks[firstId];
133 for (
Id secondId = 0; secondId < mNLinks; ++secondId) {
134 const auto& second = mLinks[secondId];
135 if (
first.toLayer != second.fromLayer) {
138 const Mask hitMask{
first.fromLayer,
first.toLayer, second.toLayer};
139 if ((hitMask.holeMask() & mSeedingLayerMask).isAllowedHoleMask(mMaxHoles, mHoleLayerMask)) {
140 mCells[mNCells++] =
CellTopology{firstId, secondId, hitMask};
150 return View{mLinks.data(),
152 mCellsByFirstLinkIndex.data(),
153 mCellsByFirstLink.data(),
162 const Range* deviceCellsByFirstLinkIndex,
163 const Id* deviceCellsByFirstLink)
const
165 return View{deviceLinks,
167 deviceCellsByFirstLinkIndex,
168 deviceCellsByFirstLink,
175 const auto&
getLinks() const noexcept {
return mLinks; }
176 const auto&
getCells() const noexcept {
return mCells; }
188 mNCellsByFirstLink = 0;
191 mCellsByFirstLinkIndex.fill(
Range{0, 0});
192 mCellsByFirstLink.fill(0);
195 void fillCellsByLink()
197 std::array<Id, MaxLinks> counts{};
198 for (
Id cellId = 0; cellId < mNCells; ++cellId) {
199 ++counts[mCells[cellId].firstLink];
203 for (
Id linkId = 0; linkId < mNLinks; ++linkId) {
204 mCellsByFirstLinkIndex[linkId].setFirstEntry(
offset);
205 mCellsByFirstLinkIndex[linkId].setEntries(counts[linkId]);
209 std::array<Id, MaxLinks> cursor{};
210 for (
Id cellId = 0; cellId < mNCells; ++cellId) {
211 const Id linkId = mCells[cellId].firstLink;
212 mCellsByFirstLink[mCellsByFirstLinkIndex[linkId].getFirstEntry() + cursor[linkId]++] = cellId;
214 mNCellsByFirstLink =
offset;
217 bool isAllowedSeedingLink(
int fromLayer,
int toLayer)
const noexcept
219 return (Mask::skipped(fromLayer, toLayer) & mSeedingLayerMask).isAllowedHoleMask(mMaxHoles, mHoleLayerMask);
224 Mask mHoleLayerMask{0};
225 Mask mSeedingLayerMask{0};
228 Id mNCellsByFirstLink{0};
229 std::array<LayerLink, MaxLinks> mLinks{};
230 std::array<CellTopology, MaxCells> mCells{};
231 std::array<Range, MaxLinks> mCellsByFirstLinkIndex{};
232 std::array<Id, MaxCells> mCellsByFirstLink{};