Back to home page

EIC code displayed by LXR

 
 

    


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

0001 /** TRACCC library, part of the ACTS project (R&D line)
0002  *
0003  * (c) 2020-2026 CERN for the benefit of the ACTS project
0004  *
0005  * Mozilla Public License Version 2.0
0006  */
0007 
0008 // Project include(s).
0009 #include "traccc/definitions/common.hpp"
0010 
0011 // Traccc test include(s)
0012 #include "tests/grid2_test.hpp"
0013 
0014 // VecMem include(s).
0015 #include <vecmem/memory/cuda/managed_memory_resource.hpp>
0016 #include <vecmem/utils/cuda/copy.hpp>
0017 
0018 // GTest include(s).
0019 #include <gtest/gtest.h>
0020 
0021 // System include(s).
0022 #include <limits>
0023 
0024 using namespace traccc;
0025 
0026 TEST(grids_cuda, grid2_replace_populator) {
0027   // memory resource
0028   vecmem::cuda::managed_memory_resource mng_mr;
0029 
0030   // axis
0031   axis2::regular<> xaxis{4u, -1.f, 3.f, mng_mr};
0032   axis2::regular<> yaxis{6u, 0.f, 6.f, mng_mr};
0033 
0034   auto x_interval = (xaxis.max - xaxis.min) / static_cast<scalar>(xaxis.n_bins);
0035   auto y_interval = (yaxis.max - yaxis.min) / static_cast<scalar>(yaxis.n_bins);
0036 
0037   // declare host grid
0038   host_grid2_replace g2(std::move(xaxis), std::move(yaxis), mng_mr,
0039                         point3{0.f, 0.f, 0.f});
0040 
0041   // pre-check
0042   for (unsigned int i_x = 0u; i_x < xaxis.bins(); i_x++) {
0043     for (unsigned int i_y = 0u; i_y < yaxis.bins(); i_y++) {
0044       const auto& data = g2.bin(i_x, i_y);
0045 
0046       EXPECT_EQ(data, g2.populator().m_invalid);
0047     }
0048   }
0049 
0050   // get grid_data
0051   auto g2_data = get_data(g2, mng_mr);
0052 
0053   // fill the grids
0054   grid_replace_test(g2_data);
0055 
0056   // post-check
0057   for (unsigned int i_x = 0u; i_x < xaxis.bins(); i_x++) {
0058     for (unsigned int i_y = 0u; i_y < yaxis.bins(); i_y++) {
0059       auto bin_id = static_cast<scalar>(i_x + i_y * xaxis.bins());
0060       const auto& data = g2.bin(i_x, i_y);
0061 
0062       point3 tp({xaxis.min + bin_id * x_interval,
0063                  yaxis.min + bin_id * y_interval, 0.5f});
0064 
0065       EXPECT_EQ(data, tp);
0066     }
0067   }
0068 }
0069 
0070 TEST(grids_cuda, grid2_replace_populator_ci) {
0071   // memory resource
0072   vecmem::cuda::managed_memory_resource mng_mr;
0073 
0074   // axis
0075   axis2::circular<> caxis{4u, -2.f, 2.f, mng_mr};
0076   axis2::irregular<> iaxis{{1.f, 3.f, 9.f, 27.f, 81.f}, mng_mr};
0077 
0078   auto x_interval = (caxis.max - caxis.min) / static_cast<scalar>(caxis.n_bins);
0079 
0080   // declare host grid
0081   host_grid2_replace_ci g2(std::move(caxis), std::move(iaxis), mng_mr,
0082                            point3{0.f, 0.f, 0.f});
0083 
0084   // pre-check
0085   for (unsigned int i_x = 0u; i_x < caxis.bins(); i_x++) {
0086     for (unsigned int i_y = 0u; i_y < iaxis.bins(); i_y++) {
0087       const auto& data = g2.bin(i_x, i_y);
0088 
0089       EXPECT_EQ(data, g2.populator().m_invalid);
0090     }
0091   }
0092 
0093   // get grid_data
0094   auto g2_data = get_data(g2, mng_mr);
0095 
0096   // fill the grids
0097   grid_replace_ci_test(g2_data);
0098 
0099   // post-check
0100   for (unsigned int i_x = 0u; i_x < caxis.bins(); i_x++) {
0101     for (unsigned int i_y = 0u; i_y < iaxis.bins(); i_y++) {
0102       auto y_interval = iaxis.boundaries[i_y + 1] - iaxis.boundaries[i_y];
0103       auto bin_id = static_cast<scalar>(i_x + i_y * caxis.bins());
0104 
0105       const auto& data = g2.bin(i_x, i_y);
0106 
0107       point3 tp({caxis.min + bin_id * x_interval,
0108                  iaxis.min + bin_id * y_interval, 0.5f});
0109 
0110       EXPECT_EQ(data, tp);
0111     }
0112   }
0113 }
0114 
0115 // Equality operator in complete populator does not work correctly in CUDA
0116 // (!constexpr)
0117 TEST(grids_cuda, grid2_complete_populator) {
0118   // memory resource
0119   vecmem::cuda::managed_memory_resource mng_mr;
0120 
0121   // axis
0122   axis2::regular<> xaxis{7u, -1.f, 6.f, mng_mr};
0123   axis2::regular<> yaxis{3u, 0.f, 3.f, mng_mr};
0124 
0125   // declare grid
0126   host_grid2_complete g2(std::move(xaxis), std::move(yaxis), mng_mr,
0127                          point3{0.f, 0.f, 0.f});
0128 
0129   // pre-check
0130   for (unsigned int i_x = 0u; i_x < xaxis.bins(); i_x++) {
0131     for (unsigned int i_y = 0u; i_y < yaxis.bins(); i_y++) {
0132       const auto& data = g2.bin(i_x, i_y);
0133 
0134       for (auto pt : data) {
0135         EXPECT_EQ(pt, g2.populator().m_invalid);
0136       }
0137     }
0138   }
0139 
0140   // get grid_data
0141   auto g2_data = get_data(g2, mng_mr);
0142 
0143   // fill the grid
0144   grid_complete_test(g2_data);
0145 
0146   auto x_interval = (xaxis.max - xaxis.min) / static_cast<scalar>(xaxis.n_bins);
0147   auto y_interval = (yaxis.max - yaxis.min) / static_cast<scalar>(yaxis.n_bins);
0148 
0149   // post-check
0150   for (unsigned int i_y = 0u; i_y < yaxis.bins(); i_y++) {
0151     for (unsigned int i_x = 0u; i_x < xaxis.bins(); i_x++) {
0152       const auto& data = g2.bin(i_x, i_y);
0153 
0154       for (unsigned int i_p = 0u; i_p < data.size(); i_p++) {
0155         auto& pt = data[i_p];
0156 
0157         auto bin_id = i_x + i_y * xaxis.bins();
0158         auto gid = static_cast<scalar>(i_p + bin_id * data.size());
0159 
0160         point3 tp(
0161             {xaxis.min + gid * x_interval, yaxis.min + gid * y_interval, 0.5f});
0162         EXPECT_EQ(pt, tp);
0163       }
0164     }
0165   }
0166 }
0167 
0168 TEST(grids_cuda, grid2_attach_populator) {
0169   // memory resource
0170   vecmem::cuda::managed_memory_resource mng_mr;
0171 
0172   axis2::circular<> xaxis{65u, -constant<scalar>::pi, constant<scalar>::pi,
0173                           mng_mr};
0174   axis2::regular<> yaxis{2u, 0.f, 6.f, mng_mr};
0175 
0176   auto x_interval = (xaxis.max - xaxis.min) / static_cast<scalar>(xaxis.n_bins);
0177   auto y_interval = (yaxis.max - yaxis.min) / static_cast<scalar>(yaxis.n_bins);
0178 
0179   host_grid2_attach g2(xaxis, yaxis, mng_mr, point3{0.f, 0.f, 0.f});
0180 
0181   for (unsigned int i_y = 0u; i_y < yaxis.bins(); i_y++) {
0182     for (unsigned int i_x = 0u; i_x < xaxis.bins(); i_x++) {
0183       for (unsigned int i_p = 0u; i_p < 100u; i_p++) {
0184         auto bin_id = i_x + i_y * xaxis.bins();
0185         auto gid = static_cast<scalar>(i_p + bin_id * 100u);
0186 
0187         point3 tp(
0188             {xaxis.min + gid * x_interval, yaxis.min + gid * y_interval, 0.5f});
0189         g2.populate(i_x, i_y, std::move(tp));
0190       }
0191     }
0192   }
0193 
0194   // Read the grid
0195   grid_attach_read_test(get_data(g2, mng_mr));
0196 }
0197 
0198 /// This test demonstrates how to call grid buffer without calling host grid
0199 /// object It is especially useful when you don't need to save the objects in
0200 /// host side (e.g. internal spacepoint creation in traccc)
0201 TEST(grids_cuda, grid2_buffer_attach_populator) {
0202   // Helper object for performing memory copies.
0203   vecmem::cuda::copy copy;
0204 
0205   // memory resource
0206   vecmem::cuda::managed_memory_resource mng_mr;
0207 
0208   axis2::circular<> xaxis{2u, -1.f, 3.f, mng_mr};
0209   axis2::regular<> yaxis{2u, 0.f, 6.f, mng_mr};
0210 
0211   grid2_buffer<host_grid2_attach> g2_buffer(
0212       xaxis, yaxis, {100, 200, 300, 400}, mng_mr, nullptr,
0213       vecmem::data::buffer_type::resizable);
0214   copy.setup(g2_buffer._buffer)->wait();
0215 
0216   // Check if the initialization work well
0217   // Non-zero starting size not working yet so initial argument for sizes is
0218   // ignored (acts-projects/vecmem#95)
0219   const auto& ptr = g2_buffer._buffer.host_ptr();
0220   EXPECT_EQ(ptr[0].size(), 0u);
0221   EXPECT_EQ(ptr[1].size(), 0u);
0222   EXPECT_EQ(ptr[2].size(), 0u);
0223   EXPECT_EQ(ptr[3].size(), 0u);
0224   EXPECT_EQ(ptr[0].capacity(), 100u);
0225   EXPECT_EQ(ptr[1].capacity(), 200u);
0226   EXPECT_EQ(ptr[2].capacity(), 300u);
0227   EXPECT_EQ(ptr[3].capacity(), 400u);
0228 
0229   // fill each bin with 100 points
0230   grid_attach_fill_test(g2_buffer);
0231 
0232   host_grid2_attach g2(xaxis, yaxis, mng_mr, point3{0.f, 0.f, 0.f});
0233   copy(g2_buffer._buffer, g2.data())->wait();
0234 
0235   // Check if each bin has 100 points
0236   EXPECT_EQ(g2.data()[0].size(), 100u);
0237   EXPECT_EQ(g2.data()[1].size(), 100u);
0238   EXPECT_EQ(g2.data()[2].size(), 100u);
0239   EXPECT_EQ(g2.data()[3].size(), 100u);
0240 
0241   // Check that we can give a non-const buffer to a function expecting
0242   // a const view.
0243   grid_attach_read_test(g2_buffer);
0244 }
0245 
0246 TEST(grids_cuda, grid2_buffer_attach_populator2) {
0247   // Helper object for performing memory copies.
0248   vecmem::cuda::copy copy;
0249 
0250   // memory resource
0251   vecmem::cuda::managed_memory_resource mng_mr;
0252 
0253   axis2::circular<> xaxis{2u, -1.f, 3.f, mng_mr};
0254   axis2::regular<> yaxis{2u, 0.f, 6.f, mng_mr};
0255 
0256   grid2_buffer<host_grid2_attach> g2_buffer(xaxis, yaxis, {1, 2, 3, 4}, mng_mr);
0257   copy.setup(g2_buffer._buffer)->wait();
0258 
0259   // Check if the initialization works well
0260   const auto& ptr = g2_buffer._buffer.host_ptr();
0261   EXPECT_EQ(ptr[0].size(), 1u);
0262   EXPECT_EQ(ptr[1].size(), 2u);
0263   EXPECT_EQ(ptr[2].size(), 3u);
0264   EXPECT_EQ(ptr[3].size(), 4u);
0265   EXPECT_EQ(ptr[0].capacity(), 1u);
0266   EXPECT_EQ(ptr[1].capacity(), 2u);
0267   EXPECT_EQ(ptr[2].capacity(), 3u);
0268   EXPECT_EQ(ptr[3].capacity(), 4u);
0269 
0270   // Assign values to the vector elements
0271   grid_attach_assign_test(g2_buffer);
0272 
0273   host_grid2_attach g2(xaxis, yaxis, mng_mr, point3{0.f, 0.f, 0.f});
0274   copy(g2_buffer._buffer, g2.data())->wait();
0275 
0276   // Check the outputs
0277   auto bin0 = g2.bin(0u);
0278   EXPECT_EQ(bin0[0], point3({0.f, 1.f, 2.f}));
0279 
0280   auto bin1 = g2.bin(1u);
0281   EXPECT_EQ(bin1[0], point3({0.f, 1.f, 2.f}));
0282   EXPECT_EQ(bin1[1], point3({1.f, 2.f, 3.f}));
0283 
0284   auto bin2 = g2.bin(2u);
0285   EXPECT_EQ(bin2[0], point3({0.f, 1.f, 2.f}));
0286   EXPECT_EQ(bin2[1], point3({1.f, 2.f, 3.f}));
0287   EXPECT_EQ(bin2[2], point3({2.f, 3.f, 4.f}));
0288 
0289   auto bin3 = g2.bin(3u);
0290   EXPECT_EQ(bin3[0], point3({0.f, 1.f, 2.f}));
0291   EXPECT_EQ(bin3[1], point3({1.f, 2.f, 3.f}));
0292   EXPECT_EQ(bin3[2], point3({2.f, 3.f, 4.f}));
0293   EXPECT_EQ(bin3[3], point3({3.f, 4.f, 5.f}));
0294 }