Back to home page

EIC code displayed by LXR

 
 

    


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

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 // Project include(s)
0010 #include "detray/navigation/caching_navigator.hpp"
0011 #include "detray/propagator/actors.hpp"
0012 #include "detray/propagator/rk_stepper.hpp"
0013 #include "detray/tracks/tracks.hpp"
0014 #include "detray/utils/type_list.hpp"
0015 
0016 // Detray IO include(s)
0017 #include "detray/io/frontend/detector_reader.hpp"
0018 
0019 // Detray benchmark include(s)
0020 #include "detray/benchmarks/cpu/propagation_benchmark.hpp"
0021 #include "detray/benchmarks/types.hpp"
0022 
0023 // Detray test include(s)
0024 #include "detray/test/common/bfield.hpp"
0025 #include "detray/test/common/track_generators.hpp"
0026 
0027 // Detray tools include(s)
0028 #include "detray/options/detector_io_options.hpp"
0029 #include "detray/options/parse_options.hpp"
0030 #include "detray/options/propagation_options.hpp"
0031 #include "detray/options/track_generator_options.hpp"
0032 
0033 // Vecmem include(s)
0034 #include <vecmem/memory/host_memory_resource.hpp>
0035 
0036 // System include(s)
0037 #include <algorithm>
0038 #include <string>
0039 #include <thread>
0040 
0041 namespace po = boost::program_options;
0042 
0043 using namespace detray;
0044 
0045 int main(int argc, char** argv) {
0046   // Use the most general type to be able to read in all detector files
0047   using detector_t = detray::detector<detray::benchmarks::default_metadata>;
0048   using bench_algebra = typename detector_t::algebra_type;
0049   using scalar = dscalar<bench_algebra>;
0050   using vector3 = dvector3D<bench_algebra>;
0051 
0052   using free_track_parameters_t = free_track_parameters<bench_algebra>;
0053   using uniform_gen_t =
0054       detail::random_numbers<scalar, std::uniform_real_distribution<scalar>>;
0055   using track_generator_t =
0056       random_track_generator<free_track_parameters_t, uniform_gen_t>;
0057 
0058   using field_t = bfield::const_field_t<scalar>;
0059   using stepper_t = rk_stepper<typename field_t::view_t, bench_algebra>;
0060   using empty_chain_t = actor_chain<>;
0061   using default_chain = actor_chain<actor::parameter_updater<
0062       bench_algebra, actor::pointwise_material_interactor<bench_algebra>>>;
0063 
0064   // Code for the openMP scheduling scheme,
0065   // @see https://www.openmp.org/spec-html/5.0/openmpsu121.html
0066   // omp_sched_static = 0x1,
0067   // omp_sched_dynamic = 0x2,
0068   // omp_sched_guided = 0x3,
0069   // omp_sched_auto = 0x4,
0070   //
0071   // schedule modifier
0072   // omp_sched_monotonic = 0x80000000u
0073   constexpr int sched_policy{1};
0074   /// Number of host threads
0075   std::vector<int> n_threads{1, 2, 4, 8, 16, 24, 32, 48, 64, 96, 128, 256};
0076 
0077   /// Number of tracks per thread in weak scaling
0078   constexpr int chunk_size{1000};
0079   std::vector<int> n_tracks_weak_sc;
0080   // Ensure that number of tracks is divisible by number of threads
0081   for (const int n : n_threads) {
0082     n_tracks_weak_sc.push_back(n * chunk_size);
0083   }
0084 
0085   /// Maximum number of tracks to be assigned to thread (invalid:
0086   /// set per benchmark case as strong_sc_sample_size/#threads)
0087   constexpr int max_chunk_size{detail::invalid_value<int>()};
0088   /// Strong scaling sample size
0089   constexpr std::size_t strong_sc_sample_size{76'800u};
0090 
0091   // Host memory resource
0092   vecmem::host_memory_resource host_mr;
0093 
0094   // Constant magnetic field
0095   vector3 B{0.f, 0.f, 2.f * unit<scalar>::T};
0096 
0097   //
0098   // Configuration
0099   //
0100 
0101   // Google benchmark specific options
0102   ::benchmark::Initialize(&argc, argv);
0103 
0104   // Specific options for this test
0105   po::options_description desc("\ndetray propagation scaling options");
0106 
0107   desc.add_options()("context", po::value<dindex>(),
0108                      "Index of the geometry context")(
0109       "bknd_name", po::value<std::string>(), "Name of the Processor")(
0110       "sort_tracks", "Does nothing in scaling test");
0111 
0112   // Configs to be filled
0113   detray::io::detector_reader_config reader_cfg{};
0114   track_generator_t::configuration trk_cfg{};
0115   propagation::config prop_cfg{};
0116   detray::benchmarks::benchmark_base::configuration bench_cfg{};
0117 
0118   // Read options from commandline
0119   po::variables_map vm = detray::options::parse_options(
0120       desc, argc, argv, reader_cfg, trk_cfg, prop_cfg);
0121 
0122   // The geometry context to be used
0123   detector_t::geometry_context gctx;
0124   if (vm.count("context") != 0u) {
0125     gctx = detector_t::geometry_context{vm["context"].as<dindex>()};
0126   }
0127   std::string proc_name{"unknown"};
0128   if (vm.count("bknd_name") != 0u) {
0129     proc_name = vm["bknd_name"].as<std::string>();
0130   }
0131 
0132   // String that describes the detector setup
0133   std::string setup_str{};
0134   auto add_delim = [](std::string& str) { str += ", "; };
0135   if (vm.count("grid_file") == 0u) {
0136     setup_str += "no grids";
0137   }
0138   if (vm.count("material_file") == 0u) {
0139     if (!setup_str.empty()) {
0140       add_delim(setup_str);
0141     }
0142     setup_str += "no mat.";
0143   }
0144 
0145   //
0146   // Prepare data
0147   //
0148 
0149   // Read the detector geometry
0150   reader_cfg.do_check(true);
0151 
0152   const auto [det, names] =
0153       detray::io::read_detector<detector_t>(host_mr, reader_cfg);
0154   const std::string& det_name = det.name(names);
0155 
0156   // Generate the track samples for weak scaling
0157   track_generator_t trk_gen{trk_cfg};
0158   auto track_samples_weak_sc = detray::benchmarks::generate_track_samples(
0159       &host_mr, n_tracks_weak_sc, trk_gen, false);
0160 
0161   // Generate track sample for strong scaling
0162   trk_gen.config().n_tracks(strong_sc_sample_size);
0163   auto single_sample =
0164       detray::benchmarks::generate_tracks(&host_mr, trk_gen, false);
0165   std::vector<dvector<free_track_parameters_t>> track_samples_strong_sc{
0166       std::move(single_sample)};
0167 
0168   // Create a constant b-field
0169   auto bfield = create_const_field<scalar>(B);
0170 
0171   // Build actor states
0172   dtuple<> empty_state{};
0173 
0174   actor::parameter_updater_state<bench_algebra> updater_state{prop_cfg};
0175   actor::pointwise_material_interactor<bench_algebra>::state interactor_state{};
0176 
0177   auto actor_states =
0178       detail::make_tuple<dtuple>(updater_state, interactor_state);
0179 
0180   //
0181   // Register benchmarks
0182   //
0183 
0184   // Number of warmup tracks
0185   const int n_max_tracks{*std::ranges::max_element(n_tracks_weak_sc)};
0186   bench_cfg.n_warmup(
0187       static_cast<int>(std::ceil(0.1f * static_cast<float>(n_max_tracks))));
0188 
0189   if (prop_cfg.stepping.do_covariance_transport) {
0190     // Number of tracks to be sampled and number of threads are the same
0191     detray::benchmarks::register_benchmark<
0192         detray::benchmarks::host_propagation_bm, stepper_t, default_chain>(
0193         det_name + "_W_COV_TRANSPORT_WEAK-SCALING", bench_cfg, prop_cfg, det,
0194         bfield, &actor_states, track_samples_weak_sc, n_tracks_weak_sc,
0195         n_threads, chunk_size, sched_policy);
0196 
0197     // Number of tracks is increased on a fixed size sample
0198     detray::benchmarks::register_benchmark<
0199         detray::benchmarks::host_propagation_bm, stepper_t, default_chain>(
0200         det_name + "_W_COV_TRANSPORT_STRONG-SCALING", bench_cfg, prop_cfg, det,
0201         bfield, &actor_states, track_samples_strong_sc, {strong_sc_sample_size},
0202         n_threads, max_chunk_size, sched_policy);
0203   } else {
0204     detray::benchmarks::register_benchmark<
0205         detray::benchmarks::host_propagation_bm, stepper_t, empty_chain_t>(
0206         det_name + "_WEAK-SCALING", bench_cfg, prop_cfg, det, bfield,
0207         &empty_state, track_samples_weak_sc, n_tracks_weak_sc, n_threads,
0208         chunk_size, sched_policy);
0209 
0210     detray::benchmarks::register_benchmark<
0211         detray::benchmarks::host_propagation_bm, stepper_t, empty_chain_t>(
0212         det_name + "_STRONG-SCALING", bench_cfg, prop_cfg, det, bfield,
0213         &empty_state, track_samples_strong_sc, {strong_sc_sample_size},
0214         n_threads, max_chunk_size, sched_policy);
0215 
0216     if (!setup_str.empty()) {
0217       add_delim(setup_str);
0218     }
0219     setup_str += "no cov.";
0220   }
0221 
0222   // These fields are needed by the plotting scripts
0223   ::benchmark::AddCustomContext("Backend", "CPU");
0224   ::benchmark::AddCustomContext("Backend Name", proc_name);
0225   ::benchmark::AddCustomContext(
0226       "Max no. Threads", std::to_string(std::thread::hardware_concurrency()));
0227   ::benchmark::AddCustomContext("Algebra-plugin",
0228                                 detray::types::get_name<bench_algebra>());
0229   ::benchmark::AddCustomContext("Detector Setup", setup_str);
0230 
0231   // Run benchmarks
0232   ::benchmark::RunSpecifiedBenchmarks();
0233   ::benchmark::Shutdown();
0234 }