File indexing completed on 2026-05-27 07:24:04
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011
0012 #include "detray/definitions/detail/qualifiers.hpp"
0013 #include "detray/utils/grid/concepts.hpp"
0014 #include "detray/utils/grid/grid.hpp"
0015
0016
0017 #include <vecmem/memory/memory_resource.hpp>
0018
0019
0020 #include <cstddef>
0021 #include <type_traits>
0022
0023 namespace detray {
0024
0025
0026
0027
0028
0029
0030 template <concepts::grid grid_t, typename = void>
0031 class grid_collection {};
0032
0033
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
0048 using bin_container_type = typename grid_t::bin_container_type;
0049
0050 using edge_offset_container_type =
0051 typename multi_axis_t::edge_offset_container_type;
0052
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
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
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
0076 DETRAY_HOST_DEVICE
0077 constexpr auto operator==(const iterator &rhs) const -> bool {
0078 return (m_i == rhs.m_i);
0079 }
0080
0081
0082 DETRAY_HOST_DEVICE
0083 constexpr auto operator++() -> iterator & {
0084 ++m_i;
0085 return *this;
0086 }
0087
0088
0089 DETRAY_HOST_DEVICE
0090 constexpr auto operator--() -> iterator & {
0091 --m_i;
0092 return *this;
0093 }
0094
0095
0096
0097 DETRAY_HOST_DEVICE
0098 constexpr auto operator*() const -> value_type { return m_grid_coll[m_i]; }
0099
0100 private:
0101
0102 dindex m_i;
0103
0104 const grid_collection &m_grid_coll;
0105 };
0106
0107 public:
0108
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
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
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
0129 grid_collection() = default;
0130
0131
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
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
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
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
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
0177 DETRAY_HOST_DEVICE
0178 constexpr auto size() const noexcept -> dindex {
0179 return static_cast<dindex>(m_bin_offsets.size());
0180 }
0181
0182
0183 DETRAY_HOST_DEVICE
0184 constexpr auto begin() const { return iterator{*this, 0u}; }
0185
0186
0187 DETRAY_HOST_DEVICE
0188 constexpr auto end() const { return iterator{*this, size()}; }
0189
0190
0191 DETRAY_HOST_DEVICE
0192 constexpr auto empty() const noexcept -> bool {
0193 return m_bin_offsets.empty();
0194 }
0195
0196
0197
0198 DETRAY_HOST_DEVICE
0199 constexpr void resize(std::size_t ) noexcept { }
0200
0201
0202
0203 DETRAY_HOST_DEVICE
0204 constexpr void reserve(std::size_t ) noexcept { }
0205
0206
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
0216
0217 template <typename... Args>
0218 DETRAY_HOST_DEVICE constexpr void insert(Args &&...) noexcept {
0219
0220 }
0221
0222
0223 DETRAY_HOST_DEVICE
0224 constexpr auto offsets() const -> const vector_type<size_type> & {
0225 return m_bin_offsets;
0226 }
0227
0228
0229 DETRAY_HOST_DEVICE
0230 constexpr auto bin_storage() const -> const bin_container_type & {
0231 return m_bins;
0232 }
0233
0234
0235 DETRAY_HOST_DEVICE
0236 constexpr auto axes_storage() const -> const edge_offset_container_type & {
0237 return m_bin_edge_offsets;
0238 }
0239
0240
0241 DETRAY_HOST_DEVICE
0242 constexpr auto bin_edges_storage() const -> const edges_container_type & {
0243 return m_bin_edges;
0244 }
0245
0246
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
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
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
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
0280
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
0287 m_bin_offsets.push_back(static_cast<size_type>(m_bins.size()));
0288
0289
0290 insert_bin_data(m_bins, gr.bins());
0291
0292
0293
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
0299 auto bin_edges_offset{static_cast<dindex>(m_bin_edges.size())};
0300
0301
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
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
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
0322
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
0331 vector_type<size_type> m_bin_offsets{};
0332
0333 bin_container_type m_bins{};
0334
0335 edge_offset_container_type m_bin_edge_offsets{};
0336
0337 edges_container_type m_bin_edges{};
0338 };
0339
0340 }