File indexing completed on 2026-07-26 08:22:01
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010
0011 #include "traccc/definitions/primitives.hpp"
0012 #include "traccc/definitions/qualifiers.hpp"
0013 #include "traccc/seeding/grids/axis.hpp"
0014
0015
0016 #include <detray/utils/concepts.hpp>
0017 #include <detray/utils/invalid_values.hpp>
0018 #include <detray/utils/tuple.hpp>
0019
0020
0021 #include <vecmem/containers/data/buffer_type.hpp>
0022 #include <vecmem/memory/memory_resource.hpp>
0023
0024
0025 #include <algorithm>
0026
0027 namespace traccc {
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 template <template <template <typename...> class, template <typename...> class,
0039 template <typename, std::size_t> class, typename, bool,
0040 unsigned int> class populator_t,
0041 template <template <typename, std::size_t> class,
0042 template <typename...> class> class axis_p0_t,
0043 template <template <typename, std::size_t> class,
0044 template <typename...> class> class axis_p1_t,
0045 typename serializer_t,
0046 template <typename...> class vector_t = vecmem::vector,
0047 template <typename...> class jagged_vector_t = vecmem::jagged_vector,
0048 template <typename, std::size_t> class array_t = std::array,
0049 template <typename...> class tuple_t = detray::tuple,
0050 typename value_t = unsigned int, bool kSORT = false,
0051 unsigned int kDIM = 1u>
0052 class grid2 {
0053 public:
0054 using populator_type =
0055 populator_t<vector_t, jagged_vector_t, array_t, value_t, kSORT, kDIM>;
0056 using serializer_type = serializer_t;
0057 using axis_p0_type = axis_p0_t<array_t, vector_t>;
0058 using axis_p1_type = axis_p1_t<array_t, vector_t>;
0059 using bare_value = typename populator_type::bare_value;
0060 using serialized_storage = typename populator_type::serialized_storage;
0061
0062 template <typename neighbor_t>
0063 using neighborhood = array_t<array_t<neighbor_t, 2>, 2>;
0064
0065 static constexpr array_t<unsigned int, 2> hermit1 = {0u, 0u};
0066 static constexpr neighborhood<unsigned int> hermit2 = {hermit1, hermit1};
0067
0068 grid2() = default;
0069
0070 DETRAY_HOST
0071 grid2(
0072 vecmem::memory_resource &mr,
0073 const bare_value m_invalid = detray::detail::invalid_value<bare_value>())
0074 : _axis_p0(mr),
0075 _axis_p1(mr),
0076 _data_serialized(&mr),
0077 _populator(m_invalid) {}
0078
0079
0080
0081
0082
0083
0084
0085 DETRAY_HOST
0086 grid2(
0087 const axis_p0_type &axis_p0, const axis_p1_type &axis_p1,
0088 vecmem::memory_resource &mr,
0089 const bare_value m_invalid = detray::detail::invalid_value<bare_value>())
0090 : _axis_p0(axis_p0, mr),
0091 _axis_p1(axis_p1, mr),
0092 _data_serialized(&mr),
0093 _populator(m_invalid) {
0094 _data_serialized = serialized_storage(_axis_p0.bins() * _axis_p1.bins(),
0095 _populator.init());
0096 }
0097
0098
0099
0100
0101
0102
0103
0104 DETRAY_HOST
0105 grid2(
0106 axis_p0_type &&axis_p0, axis_p1_type &&axis_p1,
0107 vecmem::memory_resource &mr,
0108 const bare_value m_invalid = detray::detail::invalid_value<bare_value>())
0109 : _axis_p0(std::move(axis_p0), mr),
0110 _axis_p1(std::move(axis_p1), mr),
0111 _data_serialized(&mr),
0112 _populator(m_invalid) {
0113 _data_serialized = serialized_storage(_axis_p0.bins() * _axis_p1.bins(),
0114 _populator.init());
0115 }
0116
0117
0118
0119 template <typename grid_view_t>
0120 requires(!std::is_same_v<grid2, grid_view_t>) &&
0121 (!std::is_base_of_v<vecmem::memory_resource, grid_view_t>)
0122 DETRAY_HOST_DEVICE grid2(
0123 const grid_view_t &grid_data,
0124 const bare_value m_invalid = detray::detail::invalid_value<bare_value>())
0125 : _axis_p0(grid_data._axis_p0_view),
0126 _axis_p1(grid_data._axis_p1_view),
0127 _data_serialized(grid_data._data_view),
0128 _populator(m_invalid) {}
0129
0130
0131
0132
0133
0134
0135 void shift(const typename populator_type::bare_value &offset) {
0136 std::ranges::for_each(_data_serialized,
0137 [&](auto &ds) { _populator.shift(ds, offset); });
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 template <detray::concepts::point2D point2_t>
0149 DETRAY_HOST_DEVICE void populate(
0150 const point2_t &p2, typename populator_type::bare_value &&fvalue) {
0151 auto sbin = _serializer.template serialize<axis_p0_type, axis_p1_type>(
0152 _axis_p0, _axis_p1, _axis_p0.bin(p2[0]), _axis_p1.bin(p2[1]));
0153 _populator(_data_serialized[sbin], std::move(fvalue));
0154 }
0155
0156
0157
0158
0159
0160
0161
0162 DETRAY_HOST_DEVICE
0163 void populate(unsigned int bin0, unsigned int bin1,
0164 typename populator_type::bare_value &&fvalue) {
0165 auto sbin = _serializer.template serialize<axis_p0_type, axis_p1_type>(
0166 _axis_p0, _axis_p1, bin0, bin1);
0167 _populator(_data_serialized[sbin], std::move(fvalue));
0168 }
0169
0170 DETRAY_HOST_DEVICE
0171 void populate(unsigned int gbin,
0172 typename populator_type::bare_value &&fvalue) {
0173 unsigned int bin0 = gbin % _axis_p0.bins();
0174 unsigned int bin1 = gbin / _axis_p0.bins();
0175 populate(bin0, bin1, std::move(fvalue));
0176 }
0177
0178
0179
0180
0181
0182
0183
0184
0185 DETRAY_HOST_DEVICE
0186 typename serialized_storage::const_reference bin(unsigned int bin0,
0187 unsigned int bin1) const {
0188 return _data_serialized[_serializer.template serialize<
0189 axis_p0_type, axis_p1_type>(_axis_p0, _axis_p1, bin0, bin1)];
0190 }
0191
0192 DETRAY_HOST_DEVICE
0193 typename serialized_storage::reference bin(unsigned int bin0,
0194 unsigned int bin1) {
0195 return _data_serialized.at(
0196 _serializer.template serialize<axis_p0_type, axis_p1_type>(
0197 _axis_p0, _axis_p1, bin0, bin1));
0198 }
0199
0200 DETRAY_HOST_DEVICE
0201 typename serialized_storage::const_reference bin(unsigned int gbin) const {
0202 unsigned int bin0 = gbin % _axis_p0.bins();
0203 unsigned int bin1 = gbin / _axis_p0.bins();
0204 return bin(bin0, bin1);
0205 }
0206
0207 DETRAY_HOST_DEVICE
0208 typename serialized_storage::reference bin(unsigned int gbin) {
0209 unsigned int bin0 = gbin % _axis_p0.bins();
0210 unsigned int bin1 = gbin / _axis_p0.bins();
0211 return bin(bin0, bin1);
0212 }
0213
0214
0215
0216
0217
0218
0219
0220 template <detray::concepts::point2D point2_t>
0221 requires(!std::is_scalar_v<point2_t>)
0222 DETRAY_HOST_DEVICE typename serialized_storage::const_reference bin(
0223 const point2_t &p2) const {
0224 return _data_serialized[_serializer.template serialize<axis_p0_type,
0225 axis_p1_type>(
0226 _axis_p0, _axis_p1, _axis_p0.bin(p2[0]), _axis_p1.bin(p2[1]))];
0227 }
0228
0229
0230
0231
0232
0233
0234
0235 template <detray::concepts::point2D point2_t>
0236 requires(!std::is_scalar_v<point2_t>)
0237 DETRAY_HOST_DEVICE typename serialized_storage::reference bin(
0238 const point2_t &p2) {
0239 return _data_serialized[_serializer.template serialize<axis_p0_type,
0240 axis_p1_type>(
0241 _axis_p0, _axis_p1, _axis_p0.bin(p2[0]), _axis_p1.bin(p2[1]))];
0242 }
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 template <typename neighbor_t, detray::concepts::point2D point2_t>
0257 DETRAY_HOST_DEVICE vector_t<typename populator_type::bare_value> zone_t(
0258 const point2_t &p2, const neighborhood<neighbor_t> &nhood,
0259 bool sort) const {
0260 auto zone0 = _axis_p0.zone(p2[0], nhood[0]);
0261 auto zone1 = _axis_p1.zone(p2[1], nhood[1]);
0262
0263 vector_t<typename populator_type::bare_value> zone;
0264
0265
0266 if constexpr (std::is_same_v<typename populator_type::bare_value,
0267 typename populator_type::store_value>) {
0268 unsigned int iz = 0u;
0269 zone = vector_t<typename populator_type::bare_value>(
0270 zone0.size() * zone1.size(), {});
0271 for (const auto z1 : zone1) {
0272 for (const auto z0 : zone0) {
0273 auto sbin =
0274 _serializer.template serialize<axis_p0_type, axis_p1_type>(
0275 _axis_p0, _axis_p1, z0, z1);
0276 zone[iz++] = _data_serialized[sbin];
0277 }
0278 }
0279 } else {
0280 zone.reserve(10u);
0281 for (const auto z1 : zone1) {
0282 for (const auto z0 : zone0) {
0283 auto sbin =
0284 _serializer.template serialize<axis_p0_type, axis_p1_type>(
0285 _axis_p0, _axis_p1, z0, z1);
0286 auto bin_data = _data_serialized[sbin];
0287 auto bin_content = _populator.sequence(bin_data);
0288 zone.insert(zone.end(), bin_content.begin(), bin_content.end());
0289 }
0290 }
0291 }
0292
0293 if (sort) {
0294 std::ranges::sort(zone);
0295 }
0296 return zone;
0297 }
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310 template <detray::concepts::point2D point2_t>
0311 DETRAY_HOST_DEVICE vector_t<typename populator_type::bare_value> zone(
0312 const point2_t &p2, const neighborhood<unsigned int> &nhood = hermit2,
0313 bool sort = false) const {
0314 return zone_t<unsigned int>(p2, nhood, sort);
0315 }
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 template <detray::concepts::point2D point2_t>
0329 DETRAY_HOST_DEVICE vector_t<typename populator_type::bare_value> zone(
0330 const point2_t &p2, const neighborhood<scalar> &nhood,
0331 bool sort = false) const {
0332 return zone_t<scalar>(p2, nhood, sort);
0333 }
0334
0335
0336 DETRAY_HOST_DEVICE
0337 const axis_p0_type &axis_p0() const { return _axis_p0; }
0338
0339
0340 DETRAY_HOST_DEVICE
0341 axis_p0_type &axis_p0() { return _axis_p0; }
0342
0343
0344 DETRAY_HOST_DEVICE
0345 const axis_p1_type &axis_p1() const { return _axis_p1; }
0346
0347
0348 DETRAY_HOST_DEVICE
0349 axis_p1_type &axis_p1() { return _axis_p1; }
0350
0351
0352 DETRAY_HOST_DEVICE
0353 tuple_t<axis_p0_type, axis_p1_type> axes() const {
0354 return std::tie(_axis_p0, _axis_p1);
0355 }
0356
0357
0358 DETRAY_HOST_DEVICE
0359 unsigned int nbins() const { return _axis_p0.bins() * _axis_p1.bins(); }
0360
0361
0362 DETRAY_HOST_DEVICE
0363 const serializer_type &serializer() const { return _serializer; }
0364
0365
0366 DETRAY_HOST_DEVICE
0367 const populator_type &populator() const { return _populator; }
0368
0369 DETRAY_HOST_DEVICE
0370 serialized_storage &data() { return _data_serialized; }
0371 DETRAY_HOST_DEVICE
0372 const serialized_storage &data() const { return _data_serialized; }
0373
0374 private:
0375 axis_p0_type _axis_p0;
0376 axis_p1_type _axis_p1;
0377 serialized_storage _data_serialized;
0378 populator_type _populator;
0379 serializer_type _serializer;
0380 };
0381
0382
0383 template <typename TYPE, typename ALLOC>
0384 DETRAY_HOST vecmem::data::vector_view<TYPE> get_data(
0385 std::vector<TYPE, ALLOC> &vec, vecmem::memory_resource &) {
0386 return vecmem::get_data(vec);
0387 }
0388
0389
0390 template <typename TYPE, typename ALLOC>
0391 DETRAY_HOST vecmem::data::vector_view<const TYPE> get_data(
0392 const std::vector<TYPE, ALLOC> &vec, vecmem::memory_resource &) {
0393 return vecmem::get_data(vec);
0394 }
0395
0396
0397 template <typename TYPE, typename ALLOC1, typename ALLOC2>
0398 DETRAY_HOST vecmem::data::jagged_vector_data<TYPE> get_data(
0399 std::vector<std::vector<TYPE, ALLOC1>, ALLOC2> &vec,
0400 vecmem::memory_resource &resource) {
0401 return vecmem::get_data(vec, &resource);
0402 }
0403
0404
0405 template <typename TYPE, typename ALLOC1, typename ALLOC2>
0406 DETRAY_HOST vecmem::data::jagged_vector_data<const TYPE> get_data(
0407 const std::vector<std::vector<TYPE, ALLOC1>, ALLOC2> &vec,
0408 vecmem::memory_resource &resource) {
0409 return vecmem::get_data(vec, &resource);
0410 }
0411
0412
0413
0414 template <typename grid2_t>
0415 struct grid2_view {
0416 axis_data<typename grid2_t::axis_p0_type, scalar> _axis_p0_view;
0417 axis_data<typename grid2_t::axis_p1_type, scalar> _axis_p1_view;
0418 typename grid2_t::populator_type::vector_view_type _data_view;
0419 };
0420
0421
0422
0423 template <typename grid2_t>
0424 struct const_grid2_view {
0425
0426 const_grid2_view() = default;
0427
0428 DETRAY_HOST_DEVICE
0429 const_grid2_view(
0430 const axis_data<typename grid2_t::axis_p0_type, const scalar>
0431 &axis_p0_view,
0432 const axis_data<typename grid2_t::axis_p1_type, const scalar>
0433 &axis_p1_view,
0434 const typename grid2_t::populator_type::const_vector_view_type &data_view)
0435 : _axis_p0_view(axis_p0_view),
0436 _axis_p1_view(axis_p1_view),
0437 _data_view(data_view) {}
0438
0439 DETRAY_HOST_DEVICE
0440 const_grid2_view(const grid2_view<grid2_t> &parent)
0441 : _axis_p0_view(parent._axis_p0_view),
0442 _axis_p1_view(parent._axis_p1_view),
0443 _data_view(parent._data_view) {}
0444
0445 axis_data<typename grid2_t::axis_p0_type, const scalar> _axis_p0_view;
0446 axis_data<typename grid2_t::axis_p1_type, const scalar> _axis_p1_view;
0447 typename grid2_t::populator_type::const_vector_view_type _data_view;
0448 };
0449
0450
0451
0452 template <typename grid2_t>
0453 struct grid2_data : public grid2_view<grid2_t> {
0454
0455
0456
0457
0458
0459
0460 grid2_data(grid2_t &grid, vecmem::memory_resource &resource)
0461 : _axis_p0(grid.axis_p0(), resource),
0462 _axis_p1(grid.axis_p1(), resource),
0463 _data(traccc::get_data(grid.data(), resource)) {
0464 grid2_view<grid2_t>::_axis_p0_view = traccc::get_data(_axis_p0);
0465 grid2_view<grid2_t>::_axis_p1_view = traccc::get_data(_axis_p1);
0466 grid2_view<grid2_t>::_data_view = _data;
0467 }
0468
0469 typename grid2_t::axis_p0_type _axis_p0;
0470 typename grid2_t::axis_p1_type _axis_p1;
0471 typename grid2_t::populator_type::vector_data_type _data;
0472 };
0473
0474
0475
0476 template <typename grid2_t>
0477 struct const_grid2_data : public const_grid2_view<grid2_t> {
0478
0479
0480
0481
0482
0483
0484 const_grid2_data(const grid2_t &grid, vecmem::memory_resource &resource)
0485 : _axis_p0(grid.axis_p0(), resource),
0486 _axis_p1(grid.axis_p1(), resource),
0487 _data(traccc::get_data(grid.data(), resource)) {
0488 const typename grid2_t::axis_p0_type &const_axis_p0 = _axis_p0;
0489 const_grid2_view<grid2_t>::_axis_p0_view = traccc::get_data(const_axis_p0);
0490 const typename grid2_t::axis_p1_type &const_axis_p1 = _axis_p1;
0491 const_grid2_view<grid2_t>::_axis_p1_view = traccc::get_data(const_axis_p1);
0492 const_grid2_view<grid2_t>::_data_view = _data;
0493 }
0494
0495 typename grid2_t::axis_p0_type _axis_p0;
0496 typename grid2_t::axis_p1_type _axis_p1;
0497 typename grid2_t::populator_type::const_vector_data_type _data;
0498 };
0499
0500
0501
0502 template <typename grid2_t>
0503 struct grid2_buffer : public grid2_view<grid2_t> {
0504 using populator_type = typename grid2_t::populator_type;
0505 using axis_p0_type = typename grid2_t::axis_p0_type;
0506 using axis_p1_type = typename grid2_t::axis_p1_type;
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518 grid2_buffer(const axis_p0_type &axis_p0, const axis_p1_type &axis_p1,
0519 typename populator_type::buffer_size_type capacities,
0520 vecmem::memory_resource &resource,
0521 vecmem::memory_resource *host_resource = nullptr,
0522 vecmem::data::buffer_type buffer_type =
0523 vecmem::data::buffer_type::fixed_size)
0524 : _axis_p0(axis_p0),
0525 _axis_p1(axis_p1),
0526 _buffer(capacities, resource, host_resource, buffer_type) {
0527 grid2_view<grid2_t>::_axis_p0_view = traccc::get_data(_axis_p0);
0528 grid2_view<grid2_t>::_axis_p1_view = traccc::get_data(_axis_p1);
0529 grid2_view<grid2_t>::_data_view = _buffer;
0530 }
0531
0532 axis_p0_type _axis_p0;
0533 axis_p1_type _axis_p1;
0534 typename populator_type::vector_buffer_type _buffer;
0535 };
0536
0537
0538
0539 template <template <template <typename...> class, template <typename...> class,
0540 template <typename, std::size_t> class, typename, bool,
0541 unsigned int> class populator_t,
0542 template <template <typename, std::size_t> class,
0543 template <typename...> class> class axis_p0_t,
0544 template <template <typename, std::size_t> class,
0545 template <typename...> class> class axis_p1_t,
0546 typename serializer_t, template <typename...> class vector_t,
0547 template <typename...> class jagged_vector_t,
0548 template <typename, std::size_t> class array_t,
0549 template <typename...> class tuple_t, typename value_t = unsigned int,
0550 bool kSORT = false, unsigned int kDIM = 1>
0551 inline grid2_data<
0552 grid2<populator_t, axis_p0_t, axis_p1_t, serializer_t, vector_t,
0553 jagged_vector_t, array_t, tuple_t, value_t, kSORT, kDIM>>
0554 get_data(grid2<populator_t, axis_p0_t, axis_p1_t, serializer_t, vector_t,
0555 jagged_vector_t, array_t, tuple_t, value_t, kSORT, kDIM> &grid,
0556 vecmem::memory_resource &resource) {
0557 return {grid, resource};
0558 }
0559
0560
0561
0562 template <template <template <typename...> class, template <typename...> class,
0563 template <typename, std::size_t> class, typename, bool,
0564 unsigned int> class populator_t,
0565 template <template <typename, std::size_t> class,
0566 template <typename...> class> class axis_p0_t,
0567 template <template <typename, std::size_t> class,
0568 template <typename...> class> class axis_p1_t,
0569 typename serializer_t, template <typename...> class vector_t,
0570 template <typename...> class jagged_vector_t,
0571 template <typename, std::size_t> class array_t,
0572 template <typename...> class tuple_t, typename value_t = unsigned int,
0573 bool kSORT = false, unsigned int kDIM = 1>
0574 inline const_grid2_data<
0575 grid2<populator_t, axis_p0_t, axis_p1_t, serializer_t, vector_t,
0576 jagged_vector_t, array_t, tuple_t, value_t, kSORT, kDIM>>
0577 get_data(
0578 const grid2<populator_t, axis_p0_t, axis_p1_t, serializer_t, vector_t,
0579 jagged_vector_t, array_t, tuple_t, value_t, kSORT, kDIM> &grid,
0580 vecmem::memory_resource &resource) {
0581 return {grid, resource};
0582 }
0583
0584 }