Back to home page

EIC code displayed by LXR

 
 

    


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

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 // Detray core include(s).
0010 #include "detray/utils/grid/grid.hpp"
0011 
0012 #include "detray/builders/grid_factory.hpp"
0013 #include "detray/definitions/containers.hpp"
0014 #include "detray/definitions/indexing.hpp"
0015 #include "detray/geometry/shapes/rectangle2D.hpp"
0016 #include "detray/utils/grid/concepts.hpp"
0017 #include "detray/utils/logging.hpp"
0018 
0019 // Detray benchmark include(s)
0020 #include "detray/benchmarks/types.hpp"
0021 
0022 // VecMem include(s).
0023 #include <vecmem/memory/host_memory_resource.hpp>
0024 
0025 // Google benchmark include(s).
0026 #include <benchmark/benchmark.h>
0027 
0028 // System include(s)
0029 #include <cstdlib>
0030 #include <iostream>
0031 #include <random>
0032 #include <vector>
0033 
0034 // Use the detray:: namespace implicitly.
0035 using namespace detray;
0036 
0037 using bench_algebra = benchmarks::algebra;
0038 using scalar = benchmarks::scalar;
0039 
0040 namespace {
0041 
0042 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0043 /// Test point for printouts
0044 const auto tp = benchmarks::point2{12.f, 30.f};
0045 #endif
0046 
0047 /// Prepare test points
0048 auto make_random_points() {
0049   std::random_device rd;
0050   std::mt19937_64 gen(rd());
0051   std::uniform_real_distribution<scalar> dist1(0.f, 24.f);
0052   std::uniform_real_distribution<scalar> dist2(0.f, 59.f);
0053 
0054   std::vector<benchmarks::point2> points{};
0055   for (unsigned int itest = 0u; itest < 1000000u; ++itest) {
0056     points.push_back({dist1(gen), dist2(gen)});
0057   }
0058 
0059   return points;
0060 }
0061 
0062 /// Make a regular grid for the tests.
0063 template <typename bin_t>
0064 auto make_regular_grid(vecmem::memory_resource &mr) {
0065   // Data-owning grids with bin capacity 1
0066   auto gr_factory = grid_factory<bin_t, simple_serializer, bench_algebra>{mr};
0067 
0068   // Spans of the axes
0069   std::vector<scalar> spans = {0.f, 25.f, 0.f, 60.f};
0070   // #bins of the axes
0071   std::vector<std::size_t> nbins = {25u, 60u};
0072 
0073   // Rectangular grid with closed bin bounds and regular binning on all axes
0074   return gr_factory.template new_grid<rectangle2D>(
0075       spans, nbins, {}, {},
0076       types::list<axis::closed<axis::label::e_x>,
0077                   axis::closed<axis::label::e_y>>{},
0078       types::list<axis::regular<scalar>, axis::regular<scalar>>{});
0079 }
0080 
0081 /// Make an irregular grid for the tests.
0082 template <typename bin_t>
0083 auto make_irregular_grid(vecmem::memory_resource &mr) {
0084   // Fill a 25 x 60 grid with an "irregular" axis
0085   std::vector<std::vector<scalar>> boundaries(2);
0086   boundaries[0].reserve(25u);
0087   boundaries[1].reserve(60u);
0088   for (scalar i = 0.f; i < 61.f; i += 1.f) {
0089     if (i < 26.f) {
0090       boundaries[0].push_back(i);
0091     }
0092     boundaries[1].push_back(i);
0093   }
0094 
0095   // Data-owning grids with bin capacity 1
0096   auto gr_factory = grid_factory<bin_t, simple_serializer, bench_algebra>{mr};
0097 
0098   // Rectangular grid with closed bin bounds and irregular binning on all axes
0099   return gr_factory.template new_grid<rectangle2D>(
0100       {}, {}, {}, boundaries,
0101       types::list<axis::closed<axis::label::e_x>,
0102                   axis::closed<axis::label::e_y>>{},
0103       types::list<axis::irregular<scalar>, axis::irregular<scalar>>{});
0104 }
0105 
0106 /// Fill a grid with some values.
0107 template <typename populator_t, concepts::grid grid_t>
0108 void populate_grid(grid_t &grid) {
0109   for (dindex gbin = 0u; gbin < grid.nbins(); ++gbin) {
0110     grid.template populate<populator_t>(
0111         gbin, static_cast<typename grid_t::value_type>(gbin));
0112   }
0113 }
0114 
0115 }  // namespace
0116 
0117 // This runs a reference test with a regular grid structure
0118 void BM_GRID_REGULAR_BIN_CAP1(benchmark::State &state) {
0119   // Set up the tested grid object.
0120   vecmem::host_memory_resource host_mr;
0121   auto g2r = make_regular_grid<bins::single<dindex>>(host_mr);
0122   populate_grid<replace<>>(g2r);
0123   spatial_grid_impl g2r_acc{std::move(g2r)};
0124 
0125   // Prepare test points
0126   auto points = make_random_points();
0127 
0128   for (auto _ : state) {
0129     for (const auto &p : points) {
0130       benchmark::DoNotOptimize(g2r_acc.search(p).value());
0131     }
0132   }
0133 
0134 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0135   DETRAY_INFO_HOST("BM_GRID_REGULAR_BIN_CAP1: " << g2r_acc.search(p).value());
0136 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0137 }
0138 
0139 // This runs a reference test with a regular grid structure
0140 void BM_GRID_REGULAR_BIN_CAP4(benchmark::State &state) {
0141   // Set up the tested grid object.
0142   vecmem::host_memory_resource host_mr;
0143   auto g2r = make_regular_grid<bins::static_array<dindex, 4>>(host_mr);
0144   populate_grid<complete<>>(g2r);
0145   spatial_grid_impl g2r_acc{std::move(g2r)};
0146 
0147   auto points = make_random_points();
0148 
0149   for (auto _ : state) {
0150     for (const auto &p : points) {
0151       for (dindex entry : g2r_acc.search(p)) {
0152         benchmark::DoNotOptimize(entry);
0153       }
0154     }
0155   }
0156 
0157 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0158   std::stringstream out_str{};
0159   std::size_t count{0u};
0160   for (const dindex entry : g2r_acc.search(tp)) {
0161     out_str << entry << ", ";
0162     ++count;
0163   }
0164   DETRAY_INFO_HOST("BM_GRID_REGULAR_BIN_CAP4: \n" << out_str.str());
0165   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0166 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0167 }
0168 
0169 // This runs a reference test with a regular grid structure
0170 void BM_GRID_REGULAR_BIN_CAP25(benchmark::State &state) {
0171   // Set up the tested grid object.
0172   vecmem::host_memory_resource host_mr;
0173   auto g2r = make_regular_grid<bins::static_array<dindex, 25>>(host_mr);
0174   populate_grid<complete<>>(g2r);
0175   spatial_grid_impl g2r_acc{std::move(g2r)};
0176 
0177   auto points = make_random_points();
0178 
0179   for (auto _ : state) {
0180     for (const auto &p : points) {
0181       for (dindex entry : g2r_acc.search(p)) {
0182         benchmark::DoNotOptimize(entry);
0183       }
0184     }
0185   }
0186 
0187 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0188   std::stringstream out_str{};
0189   std::size_t count{0u};
0190   for (const dindex entry : g2r_acc.search(tp)) {
0191     out_str << entry << ", ";
0192     ++count;
0193   }
0194   DETRAY_INFO_HOST("BM_GRID_REGULAR_BIN_CAP25: \n" << out_str.str());
0195   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0196 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0197 }
0198 
0199 // This runs a reference test with a regular grid structure
0200 void BM_GRID_REGULAR_BIN_CAP100(benchmark::State &state) {
0201   // Set up the tested grid object.
0202   vecmem::host_memory_resource host_mr;
0203   auto g2r = make_regular_grid<bins::static_array<dindex, 100>>(host_mr);
0204   populate_grid<complete<>>(g2r);
0205   spatial_grid_impl g2r_acc{std::move(g2r)};
0206 
0207   auto points = make_random_points();
0208 
0209   for (auto _ : state) {
0210     for (const auto &p : points) {
0211       for (dindex entry : g2r_acc.search(p)) {
0212         benchmark::DoNotOptimize(entry);
0213       }
0214     }
0215   }
0216 
0217 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0218   std::stringstream out_str{};
0219   std::size_t count{0u};
0220   for (const dindex entry : g2r_acc.search(tp)) {
0221     out_str << entry << ", ";
0222     ++count;
0223   }
0224   DETRAY_INFO_HOST("BM_GRID_REGULAR_BIN_CAP100: \n" << out_str.str());
0225   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0226 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0227 }
0228 
0229 void BM_GRID_REGULAR_NEIGHBOR_CAP1(benchmark::State &state) {
0230   // Set up the tested grid object.
0231   vecmem::host_memory_resource host_mr;
0232   auto g2r = make_regular_grid<bins::single<dindex>>(host_mr);
0233   populate_grid<replace<>>(g2r);
0234   spatial_grid_impl g2r_acc{std::move(g2r)};
0235 
0236   auto points = make_random_points();
0237 
0238   // Search window size.
0239   static const darray<dindex, 2> window = {2u, 2u};
0240 
0241   for (auto _ : state) {
0242     for (const auto &p : points) {
0243       for (dindex entry : g2r_acc.search(p, window)) {
0244         benchmark::DoNotOptimize(entry);
0245       }
0246     }
0247   }
0248 
0249 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0250   std::stringstream out_str{};
0251   std::size_t count{0u};
0252   for (const dindex entry : g2r_acc.search(tp, window)) {
0253     out_str << entry << ", ";
0254     ++count;
0255   }
0256   DETRAY_INFO_HOST("BM_GRID_REGULAR_NEIGHBOR_CAP1: \n" << out_str.str());
0257   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0258 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0259 }
0260 
0261 void BM_GRID_REGULAR_NEIGHBOR_CAP4(benchmark::State &state) {
0262   // Set up the tested grid object.
0263   vecmem::host_memory_resource host_mr;
0264   auto g2r = make_regular_grid<bins::static_array<dindex, 4>>(host_mr);
0265   populate_grid<complete<>>(g2r);
0266   spatial_grid_impl g2r_acc{std::move(g2r)};
0267 
0268   auto points = make_random_points();
0269 
0270   // Search window size.
0271   static const darray<dindex, 2> window = {2u, 2u};
0272 
0273   for (auto _ : state) {
0274     for (const auto &p : points) {
0275       for (dindex entry : g2r_acc.search(p, window)) {
0276         benchmark::DoNotOptimize(entry);
0277       }
0278     }
0279   }
0280 
0281 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0282   std::stringstream out_str{};
0283   std::size_t count{0u};
0284   for (const dindex entry : g2r_acc.search(tp, window)) {
0285     out_str << entry << ", ";
0286     ++count;
0287   }
0288   DETRAY_INFO_HOST("BM_GRID_REGULAR_NEIGHBOR_CAP4: \n" << out_str.str());
0289   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0290 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0291 }
0292 
0293 // This runs a reference test with a irregular grid structure
0294 void BM_GRID_IRREGULAR_BIN_CAP1(benchmark::State &state) {
0295   // Set up the tested grid object.
0296   vecmem::host_memory_resource host_mr;
0297   auto g2irr = make_irregular_grid<bins::single<dindex>>(host_mr);
0298   populate_grid<replace<>>(g2irr);
0299   spatial_grid_impl g2irr_acc{std::move(g2irr)};
0300 
0301   auto points = make_random_points();
0302 
0303   for (auto _ : state) {
0304     for (const auto &p : points) {
0305       benchmark::DoNotOptimize(g2irr_acc.search(p).value());
0306     }
0307   }
0308 
0309 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0310   DETRAY_INFO_HOST("BM_GRID_IRREGULAR_BIN_CAP1:\n"
0311                    << g2irr_acc.search(tp).value());
0312 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0313 }
0314 
0315 void BM_GRID_IRREGULAR_NEIGHBOR_CAP1(benchmark::State &state) {
0316   // Set up the tested grid object.
0317   vecmem::host_memory_resource host_mr;
0318   auto g2irr = make_irregular_grid<bins::single<dindex>>(host_mr);
0319   populate_grid<replace<>>(g2irr);
0320   spatial_grid_impl g2irr_acc{std::move(g2irr)};
0321 
0322   auto points = make_random_points();
0323 
0324   // Search window size.
0325   static const darray<dindex, 2> window = {2u, 2u};
0326 
0327   for (auto _ : state) {
0328     for (const auto &p : points) {
0329       for (dindex entry : g2irr_acc.search(p, window)) {
0330         benchmark::DoNotOptimize(entry);
0331       }
0332     }
0333   }
0334 
0335 #ifdef DETRAY_BENCHMARK_PRINTOUTS
0336   std::stringstream out_str{};
0337   std::size_t count{0u};
0338   for (const dindex entry : g2irr_acc.search(tp, window)) {
0339     out_str << entry << ", ";
0340     ++count;
0341   }
0342   DETRAY_INFO_HOST("BM_GRID_IRREGULAR_NEIGHBOR_CAP1: \n" << out_str.str());
0343   DETRAY_INFO_HOST("\n=> Neighbors: " << count);
0344 #endif  // DETRAY_BENCHMARK_PRINTOUTS
0345 }
0346 
0347 BENCHMARK(BM_GRID_REGULAR_BIN_CAP1)
0348 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0349     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0350 #endif
0351     ->MeasureProcessCPUTime()
0352     ->Unit(benchmark::kMillisecond);
0353 
0354 BENCHMARK(BM_GRID_REGULAR_BIN_CAP4)
0355 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0356     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0357 #endif
0358     ->MeasureProcessCPUTime()
0359     ->Unit(benchmark::kMillisecond);
0360 
0361 BENCHMARK(BM_GRID_REGULAR_BIN_CAP25)
0362 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0363     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0364 #endif
0365     ->MeasureProcessCPUTime()
0366     ->Unit(benchmark::kMillisecond);
0367 
0368 BENCHMARK(BM_GRID_REGULAR_BIN_CAP100)
0369 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0370     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0371 #endif
0372     ->MeasureProcessCPUTime()
0373     ->Unit(benchmark::kMillisecond);
0374 
0375 BENCHMARK(BM_GRID_REGULAR_NEIGHBOR_CAP1)
0376 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0377     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0378 #endif
0379     ->MeasureProcessCPUTime()
0380     ->Unit(benchmark::kMillisecond);
0381 
0382 BENCHMARK(BM_GRID_REGULAR_NEIGHBOR_CAP4)
0383 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0384     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0385 #endif
0386     ->MeasureProcessCPUTime()
0387     ->Unit(benchmark::kMillisecond);
0388 
0389 BENCHMARK(BM_GRID_IRREGULAR_BIN_CAP1)
0390 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0391     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0392 #endif
0393     ->MeasureProcessCPUTime()
0394     ->Unit(benchmark::kMillisecond);
0395 
0396 BENCHMARK(BM_GRID_IRREGULAR_NEIGHBOR_CAP1)
0397 #ifdef DETRAY_BENCHMARK_MULTITHREAD
0398     ->ThreadRange(1, benchmark::CPUInfo::Get().num_cpus)
0399 #endif
0400     ->MeasureProcessCPUTime()
0401     ->Unit(benchmark::kMillisecond);