Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add CPU and CUDA benchmark for toy detector reconstruction #674

Merged
merged 1 commit into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ option( TRACCC_BUILD_ALPAKA "Build the Alpaka sources included in traccc"
FALSE )
option( TRACCC_BUILD_IO "Build the IO module (needed by examples, performance, testing)" TRUE )
option( TRACCC_BUILD_TESTING "Build the (unit) tests of traccc" TRUE )
option( TRACCC_BUILD_BENCHMARKS "Build the benchmarks of traccc" TRUE )
option( TRACCC_BUILD_EXAMPLES "Build the examples of traccc" TRUE )

# Flags controlling what traccc should use.
Expand Down Expand Up @@ -291,6 +292,20 @@ if( TRACCC_SETUP_GOOGLETEST )
endif()
endif()

# Set up Google Benchmark
option( TRACCC_SETUP_BENCHMARKS
"Set up the Google Benchmark target(s) explicitly" TRUE )
option( TRACCC_USE_SYSTEM_BENCHMARKS
"Pick up an existing installation of Google Benchmark from the build environment"
${TRACCC_USE_SYSTEM_LIBS} )
if( TRACCC_SETUP_BENCHMARKS )
if( TRACCC_USE_SYSTEM_BENCHMARKS )
find_package( benchmark REQUIRED )
else()
add_subdirectory( extern/benchmark )
endif()
endif()

option( TRACCC_ENABLE_NVTX_PROFILING
"Use instrument functions to enable fine grained profiling" FALSE )

Expand Down Expand Up @@ -341,6 +356,16 @@ if( BUILD_TESTING AND TRACCC_BUILD_TESTING )
add_subdirectory( tests )
endif()

# Set up the benchmark(s).
if( TRACCC_BUILD_BENCHMARKS )
# Find Boost.
find_package( Boost REQUIRED COMPONENTS filesystem)
if ( NOT TRACCC_BUILD_IO )
message(FATAL_ERROR "traccc::io is disabled, but it is required to build the tests.")
endif()
add_subdirectory( benchmarks )
krasznaa marked this conversation as resolved.
Show resolved Hide resolved
endif()

if(TRACCC_BUILD_FUTHARK)
add_subdirectory(device/futhark)
endif()
Expand Down
23 changes: 23 additions & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# TRACCC library, part of the ACTS project (R&D line)
#
# (c) 2024 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Project include(s).
include( traccc-compiler-options-cpp )

# Set up a common library, shared by all of the tests.
add_library( traccc_benchmarks_common STATIC
"common/benchmarks/toy_detector_benchmark.hpp" )
target_include_directories( traccc_benchmarks_common
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/common )
target_link_libraries( traccc_benchmarks_common
PUBLIC benchmark::benchmark benchmark::benchmark_main
traccc::core traccc::io traccc::simulation detray::core detray::utils
vecmem::core Boost::filesystem)

add_subdirectory(cpu)
if( TRACCC_BUILD_CUDA )
add_subdirectory(cuda)
endif()
186 changes: 186 additions & 0 deletions benchmarks/common/benchmarks/toy_detector_benchmark.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/** TRACCC library, part of the ACTS project (R&D line)
*
* (c) 2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Traccc include(s).
#include "traccc/definitions/common.hpp"
#include "traccc/finding/finding_algorithm.hpp"
#include "traccc/fitting/fitting_algorithm.hpp"
#include "traccc/io/utils.hpp"
#include "traccc/seeding/seeding_algorithm.hpp"
#include "traccc/seeding/track_params_estimation.hpp"
#include "traccc/simulation/measurement_smearer.hpp"
#include "traccc/simulation/simulator.hpp"
#include "traccc/simulation/smearing_writer.hpp"

// Detray include(s).
#include "detray/core/detector.hpp"
#include "detray/definitions/units.hpp"
#include "detray/detectors/bfield.hpp"
#include "detray/detectors/build_toy_detector.hpp"
#include "detray/geometry/mask.hpp"
#include "detray/geometry/shapes/rectangle2D.hpp"
#include "detray/io/frontend/detector_reader.hpp"
#include "detray/io/frontend/detector_writer.hpp"
#include "detray/navigation/detail/ray.hpp"
#include "detray/navigation/navigator.hpp"
#include "detray/propagator/propagator.hpp"
#include "detray/propagator/rk_stepper.hpp"
#include "detray/simulation/event_generator/track_generators.hpp"

// VecMem include(s).
#include <vecmem/memory/host_memory_resource.hpp>

// Boost include(s).
#include <boost/filesystem.hpp>

// Google Benchmark include(s).
#include <benchmark/benchmark.h>

class ToyDetectorBenchmark : public benchmark::Fixture {
public:
static const int n_events = 100u;
static const int n_tracks = 5000u;

std::vector<traccc::spacepoint_collection_types::host> spacepoints;
std::vector<traccc::measurement_collection_types::host> measurements;

// Configs
traccc::seedfinder_config seeding_cfg;
traccc::seedfilter_config filter_cfg;
traccc::spacepoint_grid_config grid_cfg{seeding_cfg};
traccc::finding_config<float> finding_cfg;
traccc::fitting_config fitting_cfg;

static constexpr std::array<float, 2> phi_range{
-traccc::constant<float>::pi, traccc::constant<float>::pi};
static constexpr std::array<float, 2> theta_range{
0.f, traccc::constant<float>::pi};
static constexpr std::array<float, 2> mom_range{
10.f * traccc::unit<float>::GeV, 100.f * traccc::unit<float>::GeV};

static inline const std::string sim_dir = "toy_detector_benchmark/";

// Detector type
using detector_type = detray::detector<detray::toy_metadata>;

// B field value and its type
// @TODO: Set B field as argument
using b_field_t = covfie::field<detray::bfield::const_bknd_t>;

static constexpr traccc::vector3 B{0, 0,
2 * detray::unit<traccc::scalar>::T};

ToyDetectorBenchmark() {

std::cout << "Please be patient. It may take some time to generate "
"the simulation data."
<< std::endl;

// VecMem memory resource(s)
vecmem::host_memory_resource host_mr;

// Use deterministic random number generator for testing
using uniform_gen_t = detray::detail::random_numbers<
traccc::scalar, std::uniform_real_distribution<traccc::scalar>>;

// Build the detector
auto [det, name_map] =
detray::build_toy_detector(host_mr, get_toy_config());

// B field
auto field = detray::bfield::create_const_field(B);

// Origin of particles
using generator_type =
detray::random_track_generator<traccc::free_track_parameters,
uniform_gen_t>;
generator_type::configuration gen_cfg{};
gen_cfg.n_tracks(n_tracks);
gen_cfg.phi_range(phi_range);
gen_cfg.theta_range(theta_range);
gen_cfg.mom_range(mom_range);
generator_type generator(gen_cfg);

// Smearing value for measurements
traccc::measurement_smearer<traccc::default_algebra> meas_smearer(
50 * detray::unit<traccc::scalar>::um,
50 * detray::unit<traccc::scalar>::um);

// Type declarations
using writer_type = traccc::smearing_writer<
traccc::measurement_smearer<traccc::default_algebra>>;

// Writer config
typename writer_type::config smearer_writer_cfg{meas_smearer};

// Run simulator
const std::string full_path = traccc::io::data_directory() + sim_dir;
krasznaa marked this conversation as resolved.
Show resolved Hide resolved

boost::filesystem::create_directories(full_path);

auto sim = traccc::simulator<detector_type, b_field_t, generator_type,
writer_type>(
n_events, det, field, std::move(generator),
std::move(smearer_writer_cfg), full_path);

// Set constrained step size to 1 mm
sim.get_config().propagation.stepping.step_constraint =
1.f * detray::unit<traccc::scalar>::mm;

sim.run();

// Write detector file
auto writer_cfg = detray::io::detector_writer_config{}
.format(detray::io::format::json)
.replace_files(true)
.write_grids(true)
.write_material(true)
.path(sim_dir);
detray::io::write_detector(det, name_map, writer_cfg);
}

detray::toy_det_config get_toy_config() const {

// Create the toy geometry
detray::toy_det_config toy_cfg{};
toy_cfg.n_brl_layers(4u).n_edc_layers(7u).do_check(false);

// @TODO: Increase the material budget again
toy_cfg.module_mat_thickness(0.11f * detray::unit<traccc::scalar>::mm);

return toy_cfg;
}

void SetUp(::benchmark::State& /*state*/) {

// VecMem memory resource(s)
vecmem::host_memory_resource host_mr;

// Build the detector
auto [det, name_map] =
detray::build_toy_detector(host_mr, get_toy_config());

// Read geometry
traccc::geometry surface_transforms =
traccc::io::alt_read_geometry(det);

// Read events
for (std::size_t i_evt = 0; i_evt < n_events; i_evt++) {

// Read the hits from the relevant event file
traccc::io::spacepoint_reader_output readOut(&host_mr);
traccc::io::read_spacepoints(readOut, i_evt, sim_dir,
surface_transforms);
spacepoints.push_back(readOut.spacepoints);

// Read measurements
traccc::io::measurement_reader_output meas_read_out(&host_mr);
traccc::io::read_measurements(meas_read_out, i_evt, sim_dir);
measurements.push_back(meas_read_out.measurements);
}
}
};
19 changes: 19 additions & 0 deletions benchmarks/cpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# TRACCC library, part of the ACTS project (R&D line)
#
# (c) 2024 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

# Look for openMP, which is used for the CPU benchmark
find_package(OpenMP)

# Build the benchmark executable.
traccc_add_executable(benchmark_cpu
"toy_detector_cpu.cpp"
LINK_LIBRARIES benchmark::benchmark benchmark::benchmark_main
traccc::core traccc_benchmarks_common
detray::core detray::utils vecmem::core)

if(OpenMP_CXX_FOUND)
target_link_libraries(traccc_benchmark_cpu PRIVATE OpenMP::OpenMP_CXX)
endif()
95 changes: 95 additions & 0 deletions benchmarks/cpu/toy_detector_cpu.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/** TRACCC library, part of the ACTS project (R&D line)
*
* (c) 2024 CERN for the benefit of the ACTS project
*
* Mozilla Public License Version 2.0
*/

// Traccc algorithm include(s).
#include "traccc/finding/finding_algorithm.hpp"
#include "traccc/fitting/fitting_algorithm.hpp"
#include "traccc/seeding/seeding_algorithm.hpp"
#include "traccc/seeding/track_params_estimation.hpp"

// Traccc IO include(s).
#include "traccc/io/event_map2.hpp"
#include "traccc/io/read_geometry.hpp"
#include "traccc/io/read_measurements.hpp"
#include "traccc/io/read_spacepoints.hpp"

// Local include(s).
#include "benchmarks/toy_detector_benchmark.hpp"

// Detray include(s).
#include "detray/core/detector.hpp"
#include "detray/detectors/bfield.hpp"
#include "detray/io/frontend/detector_reader.hpp"
#include "detray/navigation/navigator.hpp"
#include "detray/propagator/propagator.hpp"
#include "detray/propagator/rk_stepper.hpp"

// VecMem include(s).
#include <vecmem/memory/host_memory_resource.hpp>

// Google benchmark include(s).
#include <benchmark/benchmark.h>

BENCHMARK_F(ToyDetectorBenchmark, CPU)(benchmark::State& state) {

// Type declarations
using rk_stepper_type =
detray::rk_stepper<b_field_t::view_t,
typename detector_type::algebra_type,
detray::constrained_step<>>;
using host_detector_type = detray::detector<detray::default_metadata>;
using host_navigator_type = detray::navigator<const host_detector_type>;
using host_fitter_type =
traccc::kalman_fitter<rk_stepper_type, host_navigator_type>;

// VecMem memory resource(s)
vecmem::host_memory_resource host_mr;

// Read back detector file
const std::string path = sim_dir;
detray::io::detector_reader_config reader_cfg{};
reader_cfg.add_file(path + "toy_detector_geometry.json")
.add_file(path + "toy_detector_homogeneous_material.json")
.add_file(path + "toy_detector_surface_grids.json");

auto [det, names] =
detray::io::read_detector<host_detector_type>(host_mr, reader_cfg);

// B field
auto field = detray::bfield::create_const_field(B);

// Algorithms
traccc::seeding_algorithm sa(seeding_cfg, grid_cfg, filter_cfg, host_mr);
traccc::track_params_estimation tp(host_mr);
traccc::finding_algorithm<rk_stepper_type, host_navigator_type>
host_finding(finding_cfg);
traccc::fitting_algorithm<host_fitter_type> host_fitting(fitting_cfg);

for (auto _ : state) {

// Iterate over events
#pragma omp parallel for
for (int i_evt = 0; i_evt < n_events; i_evt++) {

auto& spacepoints_per_event = spacepoints[i_evt];
auto& measurements_per_event = measurements[i_evt];

// Seeding
auto seeds = sa(spacepoints_per_event);

// Track param estimation
auto params = tp(spacepoints_per_event, seeds, B);

// Track finding with CKF
auto track_candidates =
host_finding(det, field, measurements_per_event, params);

// Track fitting with KF
auto track_states = host_fitting(det, field, track_candidates);
}
}
}
12 changes: 12 additions & 0 deletions benchmarks/cuda/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# TRACCC library, part of the ACTS project (R&D line)
#
# (c) 2024 CERN for the benefit of the ACTS project
#
# Mozilla Public License Version 2.0

traccc_add_executable( benchmark_cuda
"toy_detector_cuda.cpp"
LINK_LIBRARIES benchmark::benchmark
vecmem::core vecmem::cuda
traccc::core traccc::device_common
traccc::cuda traccc_benchmarks_common )
Loading
Loading