Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-27 07:24:04

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 // Project include(s).
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/utils/grid/concepts.hpp"
0014 #include "detray/utils/grid/grid.hpp"
0015 
0016 // VecMem include(s).
0017 #include <vecmem/memory/memory_resource.hpp>
0018 
0019 // System include(s).
0020 #include <cstddef>
0021 #include <type_traits>
0022 
0023 namespace detray {
0024 
0025 /// @brief A collection of grids that can be moved to device as part of the
0026 /// detector
0027 ///
0028 /// @tparam grid_t The type of grid in this collection. Must be non-owning, so
0029 ///                that the grid collection can manage the underlying memory.
0030 template <concepts::grid grid_t, typename = void>
0031 class grid_collection {};
0032 
0033 /// Specialization for @c detray::grid
0034 template <typename axes_t, typename bin_t,
0035           template <std::size_t> class serializer_t>
0036   requires(!detray::grid_impl<axes_t, bin_t, serializer_t>::is_owning)
0037 class grid_collection<detray::grid_impl<axes_t, bin_t, serializer_t>> {
0038   using grid_t = detray::grid_impl<axes_t, bin_t, serializer_t>;
0039   using const_grid_t =
0040       const detray::grid_impl<const axes_t, const bin_t, serializer_t>;
0041   using multi_axis_t = typename grid_t::axes_type;
0042 
0043  public:
0044   using value_type = grid_t;
0045   using size_type = dindex;
0046 
0047   /// Backend storage type for the grid
0048   using bin_container_type = typename grid_t::bin_container_type;
0049   /// Offsets into the bin edges container
0050   using edge_offset_container_type =
0051       typename multi_axis_t::edge_offset_container_type;
0052   /// Contains all bin edges for all axes
0053   using edges_container_type = typename multi_axis_t::edges_container_type;
0054   template <typename T>
0055   using vector_type = typename multi_axis_t::template vector_type<T>;
0056 
0057  private:
0058   /// @brief Iterator for the grid collection: Generates grids on the fly.
0059   struct iterator {
0060     using difference_type = std::ptrdiff_t;
0061     using value_type = grid_t;
0062     using pointer = grid_t *;
0063     using reference = grid_t &;
0064     using iterator_category = detray::ranges::bidirectional_iterator_tag;
0065 
0066     /// Parametrized Constructor from a grid collection and a start index
0067     DETRAY_HOST_DEVICE
0068     constexpr explicit iterator(const grid_collection &grid_coll, dindex i = 0u)
0069         : m_i{i}, m_grid_coll{grid_coll} {}
0070 
0071     constexpr iterator(const iterator &other) = default;
0072     constexpr iterator(iterator &&other) noexcept = default;
0073     constexpr iterator &operator=(const iterator &rhs) noexcept = default;
0074 
0075     /// @returns true if grid indices are the same
0076     DETRAY_HOST_DEVICE
0077     constexpr auto operator==(const iterator &rhs) const -> bool {
0078       return (m_i == rhs.m_i);
0079     }
0080 
0081     /// Increment the grid index
0082     DETRAY_HOST_DEVICE
0083     constexpr auto operator++() -> iterator & {
0084       ++m_i;
0085       return *this;
0086     }
0087 
0088     /// Decrement the grid index
0089     DETRAY_HOST_DEVICE
0090     constexpr auto operator--() -> iterator & {
0091       --m_i;
0092       return *this;
0093     }
0094 
0095     /// @returns the grid instance for the current position in the
0096     /// collection
0097     DETRAY_HOST_DEVICE
0098     constexpr auto operator*() const -> value_type { return m_grid_coll[m_i]; }
0099 
0100    private:
0101     /// Current value of sequence
0102     dindex m_i;
0103     /// The grid collection
0104     const grid_collection &m_grid_coll;
0105   };
0106 
0107  public:
0108   /// Vecmem based grid collection view type
0109   using view_type = dmulti_view<dvector_view<size_type>,
0110                                 detail::get_view_t<bin_container_type>,
0111                                 detail::get_view_t<edge_offset_container_type>,
0112                                 detail::get_view_t<edges_container_type>>;
0113 
0114   /// Vecmem based grid collection view type
0115   using const_view_type =
0116       dmulti_view<dvector_view<const size_type>,
0117                   detail::get_view_t<const bin_container_type>,
0118                   detail::get_view_t<const edge_offset_container_type>,
0119                   detail::get_view_t<const edges_container_type>>;
0120 
0121   /// Vecmem based buffer type
0122   using buffer_type =
0123       dmulti_buffer<dvector_buffer<size_type>,
0124                     detail::get_buffer_t<bin_container_type>,
0125                     detail::get_buffer_t<edge_offset_container_type>,
0126                     detail::get_buffer_t<edges_container_type>>;
0127 
0128   /// Make grid collection default constructible: Empty
0129   grid_collection() = default;
0130 
0131   /// Create empty grid collection from specific vecmem memory resource
0132   DETRAY_HOST
0133   explicit grid_collection(vecmem::memory_resource *resource)
0134       : m_bin_offsets(resource),
0135         m_bins(resource),
0136         m_bin_edge_offsets(resource),
0137         m_bin_edges(resource) {}
0138 
0139   /// Create grid collection from existing data - move
0140   DETRAY_HOST_DEVICE
0141   grid_collection(vector_type<size_type> &&offs, bin_container_type &&bins,
0142                   edge_offset_container_type &&edge_offs,
0143                   edges_container_type &&edges)
0144       : m_bin_offsets(std::move(offs)),
0145         m_bins(std::move(bins)),
0146         m_bin_edge_offsets(std::move(edge_offs)),
0147         m_bin_edges(std::move(edges)) {}
0148 
0149   /// Device-side construction from a vecmem based view type
0150   template <concepts::device_view coll_view_t>
0151   DETRAY_HOST_DEVICE explicit grid_collection(coll_view_t &view)
0152       : m_bin_offsets(detail::get<0>(view.m_view)),
0153         m_bins(detail::get<1>(view.m_view)),
0154         m_bin_edge_offsets(detail::get<2>(view.m_view)),
0155         m_bin_edges(detail::get<3>(view.m_view)) {}
0156 
0157   /// Move constructor
0158   DETRAY_HOST_DEVICE grid_collection(grid_collection &&other) noexcept
0159       : m_bin_offsets(std::move(other.m_bin_offsets)),
0160         m_bins(std::move(other.m_bins)),
0161         m_bin_edge_offsets(std::move(other.m_bin_edge_offsets)),
0162         m_bin_edges(std::move(other.m_bin_edges)) {}
0163 
0164   /// Move assignment
0165   DETRAY_HOST_DEVICE grid_collection &operator=(
0166       grid_collection &&other) noexcept {
0167     if (this != &other) {
0168       m_bin_offsets = std::move(other.m_bin_offsets);
0169       m_bins = std::move(other.m_bins);
0170       m_bin_edge_offsets = std::move(other.m_bin_edge_offsets);
0171       m_bin_edges = std::move(other.m_bin_edges);
0172     }
0173     return *this;
0174   }
0175 
0176   /// @returns the number of grids in the collection - const
0177   DETRAY_HOST_DEVICE
0178   constexpr auto size() const noexcept -> dindex {
0179     return static_cast<dindex>(m_bin_offsets.size());
0180   }
0181 
0182   /// @returns an iterator that points to the first grid
0183   DETRAY_HOST_DEVICE
0184   constexpr auto begin() const { return iterator{*this, 0u}; }
0185 
0186   /// @returns an iterator that points to the coll. end
0187   DETRAY_HOST_DEVICE
0188   constexpr auto end() const { return iterator{*this, size()}; }
0189 
0190   /// @returns the number of grids in the collection - const
0191   DETRAY_HOST_DEVICE
0192   constexpr auto empty() const noexcept -> bool {
0193     return m_bin_offsets.empty();
0194   }
0195 
0196   /// @brief Resize the underlying containers
0197   /// @note Not defined! The amount of memory can differ for every grid
0198   DETRAY_HOST_DEVICE
0199   constexpr void resize(std::size_t /*unused*/) noexcept { /*Not defined*/ }
0200 
0201   /// @brief Reserve memory
0202   /// @note Not defined! The amount of memory can differ for every grid
0203   DETRAY_HOST_DEVICE
0204   constexpr void reserve(std::size_t /*unused*/) noexcept { /*Not defined*/ }
0205 
0206   /// Removes all data from the grid collection containers
0207   DETRAY_HOST_DEVICE
0208   constexpr void clear() noexcept {
0209     m_bin_offsets.clear();
0210     m_bins.clear();
0211     m_bin_edge_offsets.clear();
0212     m_bin_edges.clear();
0213   }
0214 
0215   /// Insert a number of grids
0216   /// @note Not defined! There is no grid iterator implementation
0217   template <typename... Args>
0218   DETRAY_HOST_DEVICE constexpr void insert(Args &&.../*unused*/) noexcept {
0219     /*Not defined*/
0220   }
0221 
0222   /// @returns the offsets for the grids in the bin storage - const
0223   DETRAY_HOST_DEVICE
0224   constexpr auto offsets() const -> const vector_type<size_type> & {
0225     return m_bin_offsets;
0226   }
0227 
0228   /// @returns the underlying bin content storage - const
0229   DETRAY_HOST_DEVICE
0230   constexpr auto bin_storage() const -> const bin_container_type & {
0231     return m_bins;
0232   }
0233 
0234   /// @returns the underlying axis boundary storage - const
0235   DETRAY_HOST_DEVICE
0236   constexpr auto axes_storage() const -> const edge_offset_container_type & {
0237     return m_bin_edge_offsets;
0238   }
0239 
0240   /// @returns the underlying bin edges storage - const
0241   DETRAY_HOST_DEVICE
0242   constexpr auto bin_edges_storage() const -> const edges_container_type & {
0243     return m_bin_edges;
0244   }
0245 
0246   /// Create grid from container pointers - const
0247   DETRAY_HOST_DEVICE
0248   auto operator[](const size_type i) const -> grid_t {
0249     const size_type axes_offset{grid_t::dim * i};
0250     return grid_t(&m_bins,
0251                   multi_axis_t(m_bin_edge_offsets, m_bin_edges, axes_offset),
0252                   m_bin_offsets[i]);
0253   }
0254 
0255   /// Create grid from container pointers with range check
0256   DETRAY_HOST_DEVICE
0257   auto at(const size_type i) const -> grid_t {
0258     const size_type axes_offset{grid_t::dim * i};
0259     return grid_t(&m_bins,
0260                   multi_axis_t(m_bin_edge_offsets, m_bin_edges, axes_offset),
0261                   m_bin_offsets.at(i));
0262   }
0263 
0264   /// @returns a vecmem view on the grid collection data - non-const
0265   DETRAY_HOST auto get_data() -> view_type {
0266     return view_type{detray::get_data(m_bin_offsets), detray::get_data(m_bins),
0267                      detray::get_data(m_bin_edge_offsets),
0268                      detray::get_data(m_bin_edges)};
0269   }
0270 
0271   /// @returns a vecmem view on the grid collection data - const
0272   DETRAY_HOST
0273   auto get_data() const -> const_view_type {
0274     return const_view_type{
0275         detray::get_data(m_bin_offsets), detray::get_data(m_bins),
0276         detray::get_data(m_bin_edge_offsets), detray::get_data(m_bin_edges)};
0277   }
0278 
0279   /// Add a new grid @param gr to the collection.
0280   /// @note this takes a data owning grid to transcribe the data from.
0281   template <typename other_grid_t>
0282     requires std::constructible_from<typename grid_t::template type<true>,
0283                                      other_grid_t>
0284   DETRAY_HOST constexpr auto push_back(const other_grid_t &gr) noexcept(false)
0285       -> void {
0286     // Current offset into the global bin storage for the new grid
0287     m_bin_offsets.push_back(static_cast<size_type>(m_bins.size()));
0288 
0289     // Add the bins of the new grid to the collection
0290     insert_bin_data(m_bins, gr.bins());
0291 
0292     // Add the bin edge offsets of the new grid to the collection
0293     // (how to lookup the axis bin edges)
0294     const auto &bin_edge_offsets = gr.axes().bin_edge_offsets();
0295     m_bin_edge_offsets.insert(m_bin_edge_offsets.end(),
0296                               bin_edge_offsets.begin(), bin_edge_offsets.end());
0297 
0298     // Current offset into the global bin edges storage
0299     auto bin_edges_offset{static_cast<dindex>(m_bin_edges.size())};
0300 
0301     // Update the bin edges index offset for the axes in the grid collection
0302     const auto start_idx{m_bin_edge_offsets.size() - grid_t::dim};
0303     for (std::size_t i = start_idx; i < m_bin_edge_offsets.size(); ++i) {
0304       auto &bin_entry_range = m_bin_edge_offsets.at(i);
0305       bin_entry_range.shift(bin_edges_offset);
0306     }
0307 
0308     // Add the bin edges of the new grid to the collection
0309     const auto &bin_edges = gr.axes().bin_edges();
0310     m_bin_edges.insert(m_bin_edges.end(), bin_edges.begin(), bin_edges.end());
0311   }
0312 
0313  private:
0314   /// Insert data into a vector of bins
0315   DETRAY_HOST void insert_bin_data(
0316       vector_type<typename grid_t::bin_type> &bin_data,
0317       const typename grid_t::template type<true>::bin_storage &grid_bins) {
0318     bin_data.insert(bin_data.end(), grid_bins.begin(), grid_bins.end());
0319   }
0320 
0321   /// Insert data into the backend containers of a grid with dynamic bin
0322   /// capacities
0323   template <typename container_t>
0324   DETRAY_HOST void insert_bin_data(
0325       detray::detail::dynamic_bin_container<bin_t, container_t> &bin_data,
0326       const grid_t::template type<true>::bin_storage &grid_bins) {
0327     bin_data.append(grid_bins);
0328   }
0329 
0330   /// Offsets for the respective grids into the bin storage
0331   vector_type<size_type> m_bin_offsets{};
0332   /// Contains the bin content for all grids
0333   bin_container_type m_bins{};
0334   /// Contains the offsets/no. bins for the bin edges of all axes of all grids
0335   edge_offset_container_type m_bin_edge_offsets{};
0336   /// Contains the bin edges for all grids
0337   edges_container_type m_bin_edges{};
0338 };
0339 
0340 }  // namespace detray