Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
388f63c
First draft of heterogeneous trackster producer
sbaldu Nov 21, 2025
4032467
Create plugin factory for alpaka pattern recognition plugins
sbaldu Nov 24, 2025
3b75988
Add alpaka pattern recognition plugin factory
sbaldu Dec 8, 2025
cfb906e
Use scalar values for CLUEstering parameters
sbaldu Dec 17, 2025
49a6329
Use weighted chebyshev metric for cluestering
sbaldu Dec 17, 2025
ead3c3d
Add TICL heterogeneous producer to BuildFile
sbaldu Dec 19, 2025
dbf3a72
Implement `CaloClusterSoA` and produce it in `HGCalLayerClusterProducer`
sbaldu Jan 29, 2026
7b03afe
[WIP] use `CLUEstering` for legacy layer clusters
sbaldu Mar 16, 2026
fbe7fbe
Remove `HGCalImagingAlgo`
sbaldu Mar 18, 2026
8750227
Define `ClusterMask` and `HitsAndFractions` for TICL
sbaldu Mar 18, 2026
c32b25d
Define `LayerClusterAndAssociations` wrapper
sbaldu Mar 18, 2026
70bbaa5
Update legacy LC producer (missing timing)
sbaldu Mar 18, 2026
a280ac2
Use `CaloClusterSoA` for alpaka LC producer
sbaldu Mar 20, 2026
7a4910a
Implement heterogeneous LC merging
sbaldu Mar 20, 2026
0b9b01d
[WIP] Add heterogeneous filtered layer cluster producer
sbaldu Dec 19, 2025
0a731ca
Finalize heterogeneous filtered LC producer
sbaldu Mar 23, 2026
f7693ea
Save cluster sizes in legacy producer SoA
sbaldu Mar 23, 2026
3652f37
[TEMPORARY] add association map headers
sbaldu Mar 23, 2026
b5e6937
Add workaround for legacy LC production in barrel
sbaldu Mar 23, 2026
c1e4879
Test classes def fix
sbaldu Mar 23, 2026
9f87ddd
[TEMPORARY] unlock view methods and fix in associator
sbaldu Mar 23, 2026
12e9c7e
Compute LC timing in legacy producer
sbaldu Mar 23, 2026
4fc9e2f
simplify example
waredjeb Mar 27, 2026
efebe87
code-checks
waredjeb Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DataFormats/SoATemplate/interface/SoABlocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@
\
/* Accessors for the const views for each block */ \
_ITERATE_ON_ALL(_DECLARE_ACCESSORS_CONST_VIEW_BLOCKS, ~, __VA_ARGS__) \
ENUM_IF_VALID(_ITERATE_ON_ALL(GENERATE_CONST_VIEW_METHODS, ~, __VA_ARGS__)) \
\
private: \
_ITERATE_ON_ALL(_DECLARE_MEMBERS_CONST_VIEW_BLOCKS, ~, __VA_ARGS__) \
Expand Down Expand Up @@ -480,6 +481,7 @@
\
/* Accessors for the views for each block */ \
_ITERATE_ON_ALL(_DECLARE_ACCESSORS_VIEW_BLOCKS, ~, __VA_ARGS__) \
ENUM_IF_VALID(_ITERATE_ON_ALL(GENERATE_VIEW_METHODS, ~, __VA_ARGS__)) \
\
/* Data members inherited from the ConstView */ \
}; \
Expand Down
13 changes: 13 additions & 0 deletions DataFormats/TICL/BuildFile.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<use name="eigen"/>
<use name="DataFormats/Candidate"/>
<use name="DataFormats/Common"/>
<use name="DataFormats/GeometryVector"/>
<use name="DataFormats/Math"/>
<use name="DataFormats/Portable"/>
<use name="DataFormats/Provenance"/>
<use name="DataFormats/SoATemplate"/>
<use name="DataFormats/TrackReco"/>
<use name="HeterogeneousCore/AlpakaInterface"/>
<export>
<lib name="1"/>
</export>
70 changes: 70 additions & 0 deletions DataFormats/TICL/interface/AssociationMap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#ifndef DataFormats_TICL_interface_AssociationMap_h
#define DataFormats_TICL_interface_AssociationMap_h

#include "DataFormats/SoATemplate/interface/SoALayout.h"
#include "DataFormats/SoATemplate/interface/SoABlocks.h"
#include <concepts>
#include <cstdint>
#include <type_traits>

namespace ticl {

namespace concepts {

template <typename T>
concept trivially_copyable = std::is_trivially_copyable_v<T>;

}

// clang-format off
template <typename TKey, typename TMapped>
struct AssociationMapLayout {
GENERATE_SOA_LAYOUT(ContentBuffersLayout, SOA_COLUMN(TMapped, values))
GENERATE_SOA_LAYOUT(OffsetBufferLayout, SOA_COLUMN(TKey, keys_offsets))

GENERATE_SOA_BLOCKS(Layout,
SOA_BLOCK(content, ContentBuffersLayout),
SOA_BLOCK(offsets, OffsetBufferLayout),
SOA_VIEW_METHODS(
constexpr SOA_HOST_DEVICE auto operator[](TKey key) {
auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets();
auto size = (key == 0u) ? this->offsets()[0].keys_offsets()
: this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets();
return std::span<TMapped>{this->content().values().data() + offset, static_cast<std::size_t>(size)};
}
),
SOA_CONST_VIEW_METHODS(
constexpr SOA_HOST_DEVICE auto operator[](TKey key) const {
auto offset = (key == 0u) ? 0u : this->offsets()[key].keys_offsets();
auto size = (key == 0u) ? this->offsets()[0].keys_offsets()
: this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets();
return std::span<const TMapped>{this->content().values().data() + offset, static_cast<std::size_t>(size)};
}
constexpr SOA_HOST_DEVICE auto contains(TKey key) const {
return this->count(key) > 0;
}
constexpr SOA_HOST_DEVICE auto count(TKey key) const {
return (key == 0u) ? this->offsets()[0].keys_offsets()
: this->offsets()[key].keys_offsets() - this->offsets()[key - 1].keys_offsets();
}
constexpr SOA_HOST_DEVICE auto keys() const {
return this->offsets().metadata().size();
}
constexpr SOA_HOST_DEVICE auto size() const {
return this->offsets().metadata().size();
}
)
)
};
// clang-format on

template <std::integral TKey = uint32_t, concepts::trivially_copyable TMapped = uint32_t>
using TICLAssociationMap = typename AssociationMapLayout<TKey, TMapped>::template Layout<>;
template <std::integral TKey = uint32_t, concepts::trivially_copyable TMapped = uint32_t>
using TICLAssociationMapView = typename TICLAssociationMap<TKey, TMapped>::View;
template <std::integral TKey = uint32_t, concepts::trivially_copyable TMapped = uint32_t>
using TICLAssociationMapConstView = typename TICLAssociationMap<TKey, TMapped>::ConstView;

} // namespace ticl

#endif
12 changes: 12 additions & 0 deletions DataFormats/TICL/interface/CaloClusterHostCollection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#pragma once

#include "DataFormats/TICL/interface/CaloClusterSoA.h"
#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include <alpaka/alpaka.hpp>

namespace reco {

using CaloClusterHostCollection = PortableHostCollection<CaloClusterSoA>;

} // namespace reco
40 changes: 40 additions & 0 deletions DataFormats/TICL/interface/CaloClusterSoA.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

#pragma once

// Authors: Simone Balducci, Felice Pantaleo, Wahid Redjeb, Aurora Perego, Leonardo Beltrame

#include "DataFormats/SoATemplate/interface/SoABlocks.h"
#include "DataFormats/SoATemplate/interface/SoALayout.h"
#include "DataFormats/CaloRecHit/interface/CaloCluster.h"
#include "DataFormats/CaloRecHit/interface/CaloID.h"
#include "DataFormats/DetId/interface/DetId.h"

namespace reco {

GENERATE_SOA_LAYOUT(
CaloClusterSoAPosition, SOA_COLUMN(float, x), SOA_COLUMN(float, y), SOA_COLUMN(float, z), SOA_COLUMN(int, cells))

GENERATE_SOA_LAYOUT(CaloClusterSoAEnergy,
SOA_COLUMN(float, energy),
SOA_COLUMN(float, correctedEnergy),
SOA_COLUMN(float, correctedEnergyUncertainty))

GENERATE_SOA_LAYOUT(CaloClusterSoAIndexes,
SOA_COLUMN(CaloID, caloID),
SOA_COLUMN(CaloCluster::AlgoID, algoID),
SOA_COLUMN(DetId, seedID),
SOA_COLUMN(uint32_t, flags))

GENERATE_SOA_LAYOUT(CaloClusterSoATiming, SOA_COLUMN(float, time), SOA_COLUMN(float, timeError))

GENERATE_SOA_BLOCKS(CaloClusterSoALayout,
SOA_BLOCK(position, CaloClusterSoAPosition),
SOA_BLOCK(energy, CaloClusterSoAEnergy),
SOA_BLOCK(indexes, CaloClusterSoAIndexes),
SOA_BLOCK(timing, CaloClusterSoATiming))

using CaloClusterSoA = CaloClusterSoALayout<>;
using CaloClusterSoAView = CaloClusterSoA::View;
using CaloClusterSoAConstView = CaloClusterSoA::ConstView;

} // namespace reco
14 changes: 14 additions & 0 deletions DataFormats/TICL/interface/ClusterMask.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#pragma once

#include "DataFormats/SoATemplate/interface/SoALayout.h"

namespace ticl {

GENERATE_SOA_LAYOUT(ClusterMaskLayout, SOA_COLUMN(float, mask));

using ClusterMask = ClusterMaskLayout<>;
using ClusterMaskView = ClusterMask::View;
using ClusterMaskConstView = ClusterMask::ConstView;

} // namespace ticl
11 changes: 11 additions & 0 deletions DataFormats/TICL/interface/ClusterMaskHost.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#pragma once

#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/TICL/interface/ClusterMask.h"

namespace ticl {

using ClusterMaskHost = PortableHostCollection<ClusterMask>;

}
22 changes: 22 additions & 0 deletions DataFormats/TICL/interface/FillAssociator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef DataFormats_TICL_interface_FillAssociator_h
#define DataFormats_TICL_interface_FillAssociator_h

#include "DataFormats/TICL/interface/AssociationMap.h"
#include "DataFormats/TICL/interface/detail/FillAssociator.h"
#include <alpaka/alpaka.hpp>
#include <span>

namespace ticl::associator {

template <alpaka::concepts::Acc TAcc, typename TQueue, std::integral TKey, concepts::trivially_copyable TMapped>
requires alpaka::isQueue<TQueue>
ALPAKA_FN_HOST auto fill(TQueue& queue,
ticl::TICLAssociationMapView<TKey, TMapped>& map,
std::span<const TKey> keys,
std::span<const TMapped> values) {
detail::fill<TAcc>(queue, map, keys, values);
}

} // namespace ticl::associator

#endif
13 changes: 13 additions & 0 deletions DataFormats/TICL/interface/HitAndFraction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

#pragma once

#include "DataFormats/DetId/interface/DetId.h"

namespace ticl {

struct HitAndFraction {
DetId hit;
float fraction;
};

} // namespace ticl
13 changes: 13 additions & 0 deletions DataFormats/TICL/interface/HitsAndFractionsHost.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

#pragma once

#include "DataFormats/Portable/interface/PortableHostCollection.h"
#include "DataFormats/TICL/interface/AssociationMap.h"
#include "DataFormats/TICL/interface/HitAndFraction.h"

namespace ticl {

using TICLAssociationMap_t = AssociationMapLayout<int, HitAndFraction>::Layout<128, false>;
using HitsAndFractionsHost = PortableHostCollection<TICLAssociationMap_t>;

} // namespace ticl
12 changes: 12 additions & 0 deletions DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#pragma once

#include "DataFormats/Portable/interface/alpaka/PortableCollection.h"
#include "DataFormats/TICL/interface/CaloClusterSoA.h"
#include <alpaka/alpaka.hpp>

namespace ALPAKA_ACCELERATOR_NAMESPACE::reco {

using CaloClusterDeviceCollection = PortableCollection<::reco::CaloClusterSoA>;

} // namespace ALPAKA_ACCELERATOR_NAMESPACE::reco
11 changes: 11 additions & 0 deletions DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

#pragma once

#include "DataFormats/Portable/interface/alpaka/PortableCollection.h"
#include "DataFormats/TICL/interface/ClusterMask.h"

namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl {

using ClusterMaskDevice = PortableCollection<::ticl::ClusterMask>;

}
12 changes: 12 additions & 0 deletions DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

#pragma once

#include "DataFormats/Portable/interface/alpaka/PortableCollection.h"
#include "DataFormats/TICL/interface/AssociationMap.h"
#include "DataFormats/TICL/interface/HitAndFraction.h"

namespace ALPAKA_ACCELERATOR_NAMESPACE::ticl {

using HitsAndFractionsDevice = PortableCollection<ticl::TICLAssociationMap<int, HitAndFraction>>;

}
84 changes: 84 additions & 0 deletions DataFormats/TICL/interface/detail/FillAssociator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#ifndef DataFormats_TICL_interface_detail_FillAssociator_h
#define DataFormats_TICL_interface_detail_FillAssociator_h

#include "DataFormats/TICL/interface/AssociationMap.h"
#include "HeterogeneousCore/AlpakaInterface/interface/prefixScan.h"
#include <alpaka/alpaka.hpp>
#include <concepts>
#include <span>

namespace ticl::associator::detail {

struct KernelComputeAssociationSizes {
template <alpaka::concepts::Acc TAcc, std::integral TKey>
ALPAKA_FN_ACC void operator()(const TAcc& acc,
std::span<const TKey> keys,
TKey* keys_counts,
std::size_t size) const {
for (auto i : alpaka::uniformElements(acc, size)) {
alpaka::atomicAdd(acc, &keys_counts[keys[i]], TKey{1});
}
}
};

struct KernelFillAssociator {
template <alpaka::concepts::Acc TAcc, std::integral TKey, concepts::trivially_copyable TMapped>
ALPAKA_FN_ACC void operator()(const TAcc& acc,
ticl::TICLAssociationMapView<TKey, TMapped> view,
std::span<const TKey> keys,
std::span<const TMapped> values,
TKey* temp_offsets) const {
for (auto i : alpaka::uniformElements(acc, values.size())) {
const auto key = keys[i];
const auto offset = alpaka::atomicAdd(acc, &temp_offsets[key], TKey{1});
view.content().values()[offset] = values[i];
}
}
};

template <alpaka::concepts::Acc TAcc, typename TQueue, std::integral TKey, concepts::trivially_copyable TMapped>
requires alpaka::isQueue<TQueue>
ALPAKA_FN_HOST auto fill(TQueue& queue,
ticl::TICLAssociationMapView<TKey, TMapped>& map,
std::span<const TKey> keys,
std::span<const TMapped> values) {
using namespace ::cms::alpakatools;

const auto nkeys = map.metadata().size()[1];
const auto nvalues = map.metadata().size()[0];

const auto blocksize = 1024;
const auto gridsize = divide_up_by(keys.size(), blocksize);
const auto workdiv = make_workdiv<TAcc>(gridsize, blocksize);
auto keys_counts = make_device_buffer<TKey[]>(queue, nkeys);
alpaka::memset(queue, keys_counts, 0);
alpaka::exec<TAcc>(queue, workdiv, KernelComputeAssociationSizes{}, keys, keys_counts.data(), nvalues);

// prepare for prefix scan
auto block_counter = make_device_buffer<TKey>(queue);
alpaka::memset(queue, block_counter, 0);
auto temp_offsets = make_device_buffer<TKey[]>(queue, nkeys + 1);
alpaka::memset(queue, temp_offsets, 0);
const auto blocksize_multiblockscan = 1024;
auto gridsize_multiblockscan = divide_up_by(nkeys, blocksize_multiblockscan);
const auto workdiv_multiblockscan = make_workdiv<TAcc>(gridsize_multiblockscan, blocksize_multiblockscan);
auto warp_size = alpaka::getPreferredWarpSize(alpaka::getDev(queue));
alpaka::exec<TAcc>(queue,
workdiv_multiblockscan,
multiBlockPrefixScan<TKey>{},
keys_counts.data(),
temp_offsets.data() + 1,
nkeys,
gridsize_multiblockscan,
block_counter.data(),
warp_size);

alpaka::memcpy(queue,
make_device_view(queue, map.offsets().keys_offsets().data(), nkeys),
make_device_view(queue, temp_offsets.data() + 1, nkeys));
alpaka::exec<TAcc>(queue, workdiv, KernelFillAssociator{}, map, keys, values, temp_offsets.data());
}

} // namespace ticl::associator::detail

#endif
8 changes: 8 additions & 0 deletions DataFormats/TICL/src/alpaka/classes_cuda.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "DataFormats/Common/interface/DeviceProduct.h"
#include "DataFormats/Common/interface/Wrapper.h"
#include "DataFormats/TICL/interface/CaloClusterSoA.h"
#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h"
#include "DataFormats/TICL/interface/ClusterMask.h"
#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h"
#include "DataFormats/TICL/interface/AssociationMap.h"
#include "DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h"
13 changes: 13 additions & 0 deletions DataFormats/TICL/src/alpaka/classes_cuda_def.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<lcgdict>
<class name="alpaka_cuda_async::reco::CaloClusterDeviceCollection" persistent="false"/>
<class name="edm::DeviceProduct<alpaka_cuda_async::reco::CaloClusterDeviceCollection>" persistent="false"/>
<class name="edm::Wrapper<edm::DeviceProduct<alpaka_cuda_async::reco::CaloClusterDeviceCollection>>" persistent="false"/>

<class name="alpaka_cuda_async::ticl::ClusterMaskDevice" persistent="false"/>
<class name="edm::DeviceProduct<alpaka_cuda_async::ticl::ClusterMaskDevice>" persistent="false"/>
<class name="edm::Wrapper<edm::DeviceProduct<alpaka_cuda_async::ticl::ClusterMaskDevice>>" persistent="false"/>

<class name="alpaka_cuda_async::ticl::HitsAndFractionsDevice" persistent="false"/>
<class name="edm::DeviceProduct<alpaka_cuda_async::ticl::HitsAndFractionsDevice>" persistent="false"/>
<class name="edm::Wrapper<edm::DeviceProduct<alpaka_cuda_async::ticl::HitsAndFractionsDevice>>" persistent="false"/>
</lcgdict>
8 changes: 8 additions & 0 deletions DataFormats/TICL/src/alpaka/classes_rocm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "DataFormats/Common/interface/DeviceProduct.h"
#include "DataFormats/Common/interface/Wrapper.h"
#include "DataFormats/TICL/interface/CaloClusterSoA.h"
#include "DataFormats/TICL/interface/alpaka/CaloClusterDeviceCollection.h"
#include "DataFormats/TICL/interface/ClusterMask.h"
#include "DataFormats/TICL/interface/alpaka/ClusterMaskDevice.h"
#include "DataFormats/TICL/interface/AssociationMap.h"
#include "DataFormats/TICL/interface/alpaka/HitsAndFractionsDevice.h"
Loading