Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-07-26 08:22:03

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2024-2026 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 // Local include(s).
0009 #include "traccc/alpaka/clusterization/clusterization_algorithm.hpp"
0010 
0011 #include "../utils/barrier.hpp"
0012 #include "../utils/get_queue.hpp"
0013 #include "../utils/thread_id.hpp"
0014 #include "../utils/utils.hpp"
0015 
0016 // Project include(s)
0017 #include "traccc/clusterization/clustering_config.hpp"
0018 #include "traccc/clusterization/device/ccl_kernel.hpp"
0019 #include "traccc/clusterization/device/reify_cluster_data.hpp"
0020 #include "traccc/utils/projections.hpp"
0021 #include "traccc/utils/relations.hpp"
0022 
0023 // System include(s).
0024 #include <stdexcept>
0025 
0026 namespace traccc::alpaka {
0027 namespace kernels {
0028 
0029 /// Alpaka kernel for running @c traccc::device::ccl_kernel
0030 struct ccl_kernel {
0031   template <typename TAcc>
0032   ALPAKA_FN_ACC void operator()(
0033       TAcc const& acc, const clustering_config cfg,
0034       const edm::silicon_cell_collection::const_view cells_view,
0035       const detector_design_description::const_view det_descr_view,
0036       const detector_conditions_description::const_view det_cond_view,
0037       vecmem::data::vector_view<device::details::fallback_index_t>
0038           f_backup_view,
0039       vecmem::data::vector_view<device::details::fallback_index_t>
0040           gf_backup_view,
0041       vecmem::data::vector_view<unsigned char> adjc_backup_view,
0042       vecmem::data::vector_view<device::details::fallback_index_t>
0043           adjv_backup_view,
0044       uint32_t* backup_mutex_ptr,
0045       vecmem::data::vector_view<unsigned int> disjoint_set_view,
0046       vecmem::data::vector_view<unsigned int> cluster_size_view,
0047       edm::measurement_collection::view measurements_view) const {
0048     details::thread_id1 thread_id(acc);
0049 
0050     auto& partition_start =
0051         ::alpaka::declareSharedVar<std::size_t, __COUNTER__>(acc);
0052     auto& partition_end =
0053         ::alpaka::declareSharedVar<std::size_t, __COUNTER__>(acc);
0054     auto& outi = ::alpaka::declareSharedVar<std::size_t, __COUNTER__>(acc);
0055 
0056     device::details::index_t* const shared_v =
0057         ::alpaka::getDynSharedMem<device::details::index_t>(acc);
0058     vecmem::data::vector_view<device::details::index_t> f_view{
0059         cfg.max_partition_size(), shared_v};
0060     vecmem::data::vector_view<device::details::index_t> gf_view{
0061         cfg.max_partition_size(), shared_v + cfg.max_partition_size()};
0062 
0063     vecmem::device_atomic_ref<uint32_t> backup_mutex(*backup_mutex_ptr);
0064 
0065     alpaka::barrier<TAcc> barry_r(&acc);
0066 
0067     device::ccl_kernel(
0068         cfg, thread_id, cells_view, det_descr_view, det_cond_view,
0069         partition_start, partition_end, outi, f_view, gf_view, f_backup_view,
0070         gf_backup_view, adjc_backup_view, adjv_backup_view, backup_mutex,
0071         disjoint_set_view, cluster_size_view, barry_r, measurements_view);
0072   }
0073 
0074 };  // struct ccl_kernel
0075 
0076 /// Alpaka kernel for running @c traccc::device::reify_cluster_data
0077 struct reify_cluster_data {
0078   template <typename TAcc>
0079   ALPAKA_FN_ACC void operator()(
0080       TAcc const& acc,
0081       vecmem::data::vector_view<const unsigned int> disjoint_set_view,
0082       vecmem::data::vector_view<const unsigned int> permutation_map_view,
0083       traccc::edm::silicon_cluster_collection::view cluster_view) const {
0084     device::reify_cluster_data(details::thread_id1{acc}.getGlobalThreadId(),
0085                                disjoint_set_view, permutation_map_view,
0086                                cluster_view);
0087   }
0088 
0089 };  // struct reify_cluster_data
0090 
0091 }  // namespace kernels
0092 
0093 clusterization_algorithm::clusterization_algorithm(
0094     const traccc::memory_resource& mr, const vecmem::copy& copy,
0095     alpaka::queue& q, const config_type& config,
0096     std::unique_ptr<const Logger> logger)
0097     : device::clusterization_algorithm(mr, copy, config, std::move(logger)),
0098       alpaka::algorithm_base(q) {}
0099 
0100 bool clusterization_algorithm::input_is_contiguous(
0101     const edm::silicon_cell_collection::const_view&) const {
0102   // TODO: implement sanity checks for the input data in Alpaka
0103   return true;
0104 }
0105 
0106 bool clusterization_algorithm::input_is_sorted(
0107     const edm::silicon_cell_collection::const_view&) const {
0108   // TODO: implement sanity checks for the input data in Alpaka
0109   return true;
0110 }
0111 
0112 void clusterization_algorithm::sort_cells_kernel(
0113     const unsigned int, const edm::silicon_cell_collection::const_view&,
0114     edm::silicon_cell_collection::view&,
0115     vecmem::data::vector_view<unsigned int>&, const bool) const {
0116   throw std::runtime_error(
0117       "Cell sorting is not yet implemented for the Alpaka backend.");
0118 }
0119 
0120 void clusterization_algorithm::ccl_kernel(
0121     const ccl_kernel_payload& payload) const {
0122   Idx num_blocks =
0123       (payload.n_cells + (payload.config.target_partition_size()) - 1) /
0124       payload.config.target_partition_size();
0125   static_assert(::alpaka::isMultiThreadAcc<Acc>,
0126                 "Clustering algorithm must be compiled for an accelerator "
0127                 "with support for multi-thread blocks.");
0128   auto workDiv =
0129       makeWorkDiv<Acc>(num_blocks, payload.config.threads_per_partition);
0130   ::alpaka::exec<Acc>(
0131       details::get_queue(queue()), workDiv, kernels::ccl_kernel{},
0132       payload.config, payload.cells, payload.det_descr, payload.det_cond,
0133       payload.f_backup, payload.gf_backup, payload.adjc_backup,
0134       payload.adjv_backup, payload.backup_mutex, payload.disjoint_set,
0135       payload.cluster_sizes, payload.measurements);
0136 }
0137 
0138 void clusterization_algorithm::cluster_maker_kernel(
0139     unsigned int num_cells,
0140     const vecmem::data::vector_view<unsigned int>& disjoint_set,
0141     edm::silicon_cluster_collection::view& cluster_data,
0142     const vecmem::data::vector_view<const unsigned int>& permutation_map_view)
0143     const {
0144   const unsigned int num_threads = warp_size() * 16u;
0145   const unsigned int num_blocks = (num_cells + num_threads - 1) / num_threads;
0146   static_assert(::alpaka::isMultiThreadAcc<Acc>,
0147                 "Clustering algorithm must be compiled for an accelerator "
0148                 "with support for multi-thread blocks.");
0149   auto workDiv = makeWorkDiv<Acc>(num_blocks, num_threads);
0150   ::alpaka::exec<Acc>(details::get_queue(queue()), workDiv,
0151                       kernels::reify_cluster_data{}, disjoint_set,
0152                       permutation_map_view, cluster_data);
0153   // The base class destroys the input buffers right after this call, so
0154   // the kernel must finish before returning.
0155   queue().synchronize();
0156 }
0157 
0158 }  // namespace traccc::alpaka
0159 
0160 // Define the required trait needed for Dynamic shared memory allocation.
0161 namespace alpaka::trait {
0162 
0163 template <typename TAcc>
0164 struct BlockSharedMemDynSizeBytes<traccc::alpaka::kernels::ccl_kernel, TAcc> {
0165   template <typename TVec, typename... TArgs>
0166   ALPAKA_FN_HOST_ACC static auto getBlockSharedMemDynSizeBytes(
0167       traccc::alpaka::kernels::ccl_kernel const& /* kernel */,
0168       TVec const& /* blockThreadExtent */, TVec const& /* threadElemExtent */,
0169       const traccc::clustering_config config, TArgs const&... /* args */
0170       ) -> std::size_t {
0171     return static_cast<std::size_t>(2 * config.max_partition_size() *
0172                                     sizeof(traccc::device::details::index_t));
0173   }
0174 };
0175 
0176 }  // namespace alpaka::trait