File indexing completed on 2026-07-26 08:22:16
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "traccc/cuda/finding/combinatorial_kalman_filter_algorithm.hpp"
0010 #include "traccc/cuda/fitting/kalman_fitting_algorithm.hpp"
0011 #include "traccc/cuda/utils/make_magnetic_field.hpp"
0012 #include "traccc/cuda/utils/stream_wrapper.hpp"
0013 #include "traccc/definitions/common.hpp"
0014 #include "traccc/definitions/primitives.hpp"
0015 #include "traccc/device/container_d2h_copy_alg.hpp"
0016 #include "traccc/device/container_h2d_copy_alg.hpp"
0017 #include "traccc/efficiency/finding_performance_writer.hpp"
0018 #include "traccc/examples/make_magnetic_field.hpp"
0019 #include "traccc/finding/combinatorial_kalman_filter_algorithm.hpp"
0020 #include "traccc/fitting/kalman_fitting_algorithm.hpp"
0021 #include "traccc/geometry/detector.hpp"
0022 #include "traccc/geometry/host_detector.hpp"
0023 #include "traccc/io/read_detector.hpp"
0024 #include "traccc/io/read_detector_description.hpp"
0025 #include "traccc/io/read_measurements.hpp"
0026 #include "traccc/io/utils.hpp"
0027 #include "traccc/options/accelerator.hpp"
0028 #include "traccc/options/detector.hpp"
0029 #include "traccc/options/input_data.hpp"
0030 #include "traccc/options/magnetic_field.hpp"
0031 #include "traccc/options/performance.hpp"
0032 #include "traccc/options/program_options.hpp"
0033 #include "traccc/options/track_finding.hpp"
0034 #include "traccc/options/track_fitting.hpp"
0035 #include "traccc/options/track_matching.hpp"
0036 #include "traccc/options/track_propagation.hpp"
0037 #include "traccc/options/truth_finding.hpp"
0038 #include "traccc/performance/collection_comparator.hpp"
0039 #include "traccc/performance/container_comparator.hpp"
0040 #include "traccc/performance/soa_comparator.hpp"
0041 #include "traccc/performance/timer.hpp"
0042 #include "traccc/resolution/fitting_performance_writer.hpp"
0043 #include "traccc/utils/propagation.hpp"
0044 #include "traccc/utils/seed_generator.hpp"
0045
0046
0047 #include <vecmem/memory/cuda/device_memory_resource.hpp>
0048 #include <vecmem/memory/cuda/host_memory_resource.hpp>
0049 #include <vecmem/memory/cuda/managed_memory_resource.hpp>
0050 #include <vecmem/memory/host_memory_resource.hpp>
0051 #include <vecmem/utils/cuda/async_copy.hpp>
0052 #include <vecmem/utils/cuda/stream_wrapper.hpp>
0053
0054
0055 #include <exception>
0056 #include <iomanip>
0057 #include <iostream>
0058
0059 using namespace traccc;
0060
0061 int seq_run(const traccc::opts::track_finding& finding_opts,
0062 const traccc::opts::track_propagation& propagation_opts,
0063 const traccc::opts::track_fitting& fitting_opts,
0064 const traccc::opts::input_data& input_opts,
0065 const traccc::opts::detector& detector_opts,
0066 const traccc::opts::magnetic_field& bfield_opts,
0067 const traccc::opts::performance& performance_opts,
0068 const traccc::opts::accelerator& accelerator_opts,
0069 const traccc::opts::truth_finding& truth_finding_opts,
0070 const traccc::opts::track_matching& track_matching_opts,
0071 std::unique_ptr<const traccc::Logger> ilogger) {
0072 TRACCC_LOCAL_LOGGER(std::move(ilogger));
0073
0074
0075 vecmem::host_memory_resource host_mr;
0076 vecmem::cuda::host_memory_resource cuda_host_mr;
0077 vecmem::cuda::managed_memory_resource mng_mr;
0078 vecmem::cuda::device_memory_resource device_mr;
0079 traccc::memory_resource mr{device_mr, &cuda_host_mr};
0080
0081
0082 traccc::finding_performance_writer find_performance_writer(
0083 traccc::finding_performance_writer::config{
0084 .truth_config = truth_finding_opts,
0085 .track_truth_config = track_matching_opts},
0086 logger().clone("FindingPerformanceWriter"));
0087 traccc::fitting_performance_writer fit_performance_writer(
0088 traccc::fitting_performance_writer::config{},
0089 logger().clone("FittingPerformanceWriter"));
0090
0091
0092 uint64_t n_found_tracks = 0;
0093 uint64_t n_found_tracks_cuda = 0;
0094 uint64_t n_fitted_tracks = 0;
0095 uint64_t n_fitted_tracks_cuda = 0;
0096
0097
0098
0099
0100
0101
0102 const auto host_field = traccc::details::make_magnetic_field(bfield_opts);
0103 const auto device_field = traccc::cuda::make_magnetic_field(host_field);
0104
0105
0106 traccc::host_detector polymorphic_detector;
0107 traccc::io::read_detector(
0108 polymorphic_detector, mng_mr, detector_opts.detector_file,
0109 detector_opts.material_file, detector_opts.grid_file);
0110
0111
0112
0113
0114
0115
0116 vecmem::cuda::stream_wrapper vecmem_stream;
0117 traccc::cuda::stream_wrapper stream{vecmem_stream.stream()};
0118
0119
0120 vecmem::copy host_copy;
0121 vecmem::cuda::async_copy async_copy{stream.cudaStream()};
0122
0123 const traccc::detector_buffer detector_buffer =
0124 traccc::buffer_from_host_detector(polymorphic_detector, device_mr,
0125 async_copy);
0126
0127
0128 static constexpr std::array<double, traccc::e_bound_size> stddevs = {
0129 1e-4 * traccc::unit<double>::mm,
0130 1e-4 * traccc::unit<double>::mm,
0131 1e-3,
0132 1e-3,
0133 1e-4 / traccc::unit<double>::GeV,
0134 1e-4 * traccc::unit<double>::ns};
0135
0136
0137 detray::propagation::config propagation_config(propagation_opts);
0138
0139
0140 traccc::finding_config cfg(finding_opts);
0141 cfg.propagation = propagation_config;
0142
0143
0144 traccc::host::combinatorial_kalman_filter_algorithm host_finding(
0145 cfg, host_mr, logger().clone("HostFindingAlg"));
0146 traccc::cuda::combinatorial_kalman_filter_algorithm device_finding(
0147 cfg, mr, async_copy, stream, logger().clone("CudaFindingAlg"));
0148
0149
0150 traccc::fitting_config fit_cfg(fitting_opts);
0151 fit_cfg.propagation = propagation_config;
0152
0153 traccc::host::kalman_fitting_algorithm host_fitting(
0154 fit_cfg, host_mr, host_copy, logger().clone("HostFittingAlg"));
0155 traccc::cuda::kalman_fitting_algorithm device_fitting(
0156 fit_cfg, mr, async_copy, stream, logger().clone("CudaFittingAlg"));
0157
0158 traccc::performance::timing_info elapsedTimes;
0159
0160
0161 for (std::size_t event = input_opts.skip;
0162 event < input_opts.events + input_opts.skip; ++event) {
0163
0164 traccc::event_data evt_data(
0165 input_opts.directory, event, host_mr, input_opts.use_acts_geom_source,
0166 &polymorphic_detector, input_opts.format, false);
0167
0168 traccc::edm::measurement_collection::host truth_measurements{host_mr};
0169 traccc::edm::track_container<traccc::default_algebra>::host
0170 truth_track_candidates{host_mr};
0171
0172 host_detector_visitor<detector_type_list>(
0173 polymorphic_detector, [&]<typename detector_traits_t>(
0174 const typename detector_traits_t::host& det) {
0175 typename traccc::seed_generator<
0176 typename detector_traits_t::host>::config seed_cfg{};
0177 seed_cfg.initial_sigmas = stddevs;
0178
0179 traccc::seed_generator<typename detector_traits_t::host> sg(det,
0180 seed_cfg);
0181 evt_data.generate_truth_candidates(truth_track_candidates,
0182 truth_measurements, sg, host_mr,
0183 truth_finding_opts.m_pT_min);
0184 });
0185 truth_track_candidates.measurements = vecmem::get_data(truth_measurements);
0186
0187
0188 traccc::bound_track_parameters_collection_types::host seeds(mr.host);
0189 const std::size_t n_tracks = truth_track_candidates.tracks.size();
0190 for (std::size_t i_trk = 0; i_trk < n_tracks; i_trk++) {
0191 seeds.push_back(truth_track_candidates.tracks.at(i_trk).params());
0192 }
0193
0194 std::cout << "Number of seeds: " << seeds.size() << std::endl;
0195
0196 traccc::bound_track_parameters_collection_types::buffer seeds_buffer{
0197 static_cast<unsigned int>(seeds.size()), mr.main};
0198 async_copy.setup(seeds_buffer)->wait();
0199 async_copy(vecmem::get_data(seeds), seeds_buffer,
0200 vecmem::copy::type::host_to_device)
0201 ->wait();
0202
0203
0204 traccc::edm::measurement_collection::host measurements_per_event{host_mr};
0205 traccc::io::read_measurements(
0206 measurements_per_event, event, input_opts.directory,
0207 (input_opts.use_acts_geom_source ? &polymorphic_detector : nullptr),
0208 nullptr, nullptr, input_opts.format);
0209
0210 traccc::edm::measurement_collection::buffer measurements_cuda_buffer(
0211 static_cast<unsigned int>(measurements_per_event.size()), mr.main);
0212 async_copy.setup(measurements_cuda_buffer)->wait();
0213 async_copy(vecmem::get_data(measurements_per_event),
0214 measurements_cuda_buffer)
0215 ->wait();
0216
0217
0218 traccc::cuda::combinatorial_kalman_filter_algorithm::output_type
0219 track_candidates_cuda_buffer;
0220
0221 {
0222 traccc::performance::timer t("Track finding (cuda)", elapsedTimes);
0223
0224
0225 track_candidates_cuda_buffer =
0226 device_finding(detector_buffer, device_field,
0227 measurements_cuda_buffer, seeds_buffer);
0228 }
0229
0230 traccc::edm::track_container<traccc::default_algebra>::host
0231 track_candidates_cuda{host_mr,
0232 vecmem::get_data(measurements_per_event)};
0233 async_copy(track_candidates_cuda_buffer.tracks,
0234 track_candidates_cuda.tracks, vecmem::copy::type::device_to_host)
0235 ->wait();
0236
0237
0238 traccc::edm::track_container<traccc::default_algebra>::buffer
0239 track_states_cuda_buffer;
0240
0241 {
0242 traccc::performance::timer t("Track fitting (cuda)", elapsedTimes);
0243
0244
0245 track_states_cuda_buffer = device_fitting(detector_buffer, device_field,
0246 track_candidates_cuda_buffer);
0247 }
0248 traccc::edm::track_container<traccc::default_algebra>::host
0249 track_states_cuda{host_mr};
0250 async_copy(track_states_cuda_buffer.tracks, track_states_cuda.tracks,
0251 vecmem::copy::type::device_to_host)
0252 ->wait();
0253 async_copy(track_states_cuda_buffer.states, track_states_cuda.states,
0254 vecmem::copy::type::device_to_host)
0255 ->wait();
0256
0257
0258 traccc::host::combinatorial_kalman_filter_algorithm::output_type
0259 track_candidates{host_mr};
0260 traccc::host::kalman_fitting_algorithm::output_type track_states{host_mr};
0261
0262 if (accelerator_opts.compare_with_cpu) {
0263 {
0264 traccc::performance::timer t("Track finding (cpu)", elapsedTimes);
0265
0266
0267 track_candidates = host_finding(
0268 polymorphic_detector, host_field,
0269 vecmem::get_data(measurements_per_event), vecmem::get_data(seeds));
0270 }
0271
0272 {
0273 traccc::performance::timer t("Track fitting (cpu)", elapsedTimes);
0274
0275
0276 track_states = host_fitting(
0277 polymorphic_detector, host_field,
0278 traccc::edm::track_container<traccc::default_algebra>::const_data(
0279 track_candidates));
0280 }
0281 }
0282
0283 if (accelerator_opts.compare_with_cpu) {
0284
0285 TRACCC_INFO("===>>> Event " << event << " <<<===");
0286
0287
0288 traccc::soa_comparator<
0289 traccc::edm::track_collection<traccc::default_algebra>>
0290 compare_track_candidates{
0291 "track candidates",
0292 traccc::details::comparator_factory<traccc::edm::track_collection<
0293 traccc::default_algebra>::const_device::const_proxy_type>{
0294 vecmem::get_data(measurements_per_event),
0295 vecmem::get_data(measurements_per_event),
0296 {},
0297 {}}};
0298 compare_track_candidates(vecmem::get_data(track_candidates.tracks),
0299 vecmem::get_data(track_candidates_cuda.tracks));
0300 }
0301
0302
0303 n_found_tracks += track_candidates.tracks.size();
0304 n_fitted_tracks += track_states.tracks.size();
0305 n_found_tracks_cuda += track_candidates_cuda.tracks.size();
0306 n_fitted_tracks_cuda += track_states_cuda.tracks.size();
0307
0308 if (performance_opts.run) {
0309 find_performance_writer.write(
0310 traccc::edm::track_container<traccc::default_algebra>::const_data(
0311 track_candidates_cuda),
0312
0313 evt_data);
0314
0315 for (unsigned int i = 0; i < track_states_cuda.tracks.size(); i++) {
0316 host_detector_visitor<detector_type_list>(
0317 polymorphic_detector,
0318 [&]<typename detector_traits_t>(
0319 const typename detector_traits_t::host& det) {
0320 fit_performance_writer.write(
0321 track_states_cuda.tracks.at(i), track_states_cuda.states,
0322 measurements_per_event, det, evt_data);
0323 });
0324 }
0325 }
0326 }
0327
0328 if (performance_opts.run) {
0329 find_performance_writer.finalize();
0330 fit_performance_writer.finalize();
0331 }
0332
0333 TRACCC_INFO("==> Statistics ... ");
0334 TRACCC_INFO("- created (cuda) " << n_found_tracks_cuda << " found tracks");
0335 TRACCC_INFO("- created (cuda) " << n_fitted_tracks_cuda << " fitted tracks");
0336 TRACCC_INFO("- created (cpu) " << n_found_tracks << " found tracks");
0337 TRACCC_INFO("- created (cpu) " << n_fitted_tracks << " fitted tracks");
0338 TRACCC_INFO("==>Elapsed times... " << elapsedTimes);
0339
0340 return 1;
0341 }
0342
0343
0344
0345 int main(int argc, char* argv[]) {
0346 std::unique_ptr<const traccc::Logger> logger = traccc::getDefaultLogger(
0347 "TracccExampleTruthFindingCuda", traccc::Logging::Level::INFO);
0348
0349
0350 traccc::opts::detector detector_opts;
0351 traccc::opts::magnetic_field bfield_opts;
0352 traccc::opts::input_data input_opts;
0353 traccc::opts::track_finding finding_opts;
0354 traccc::opts::track_propagation propagation_opts;
0355 traccc::opts::track_fitting fitting_opts;
0356 traccc::opts::performance performance_opts;
0357 traccc::opts::accelerator accelerator_opts;
0358 traccc::opts::truth_finding truth_finding_config;
0359 traccc::opts::track_matching track_matching_opts;
0360 traccc::opts::program_options program_opts{
0361 "Truth Track Finding Using CUDA",
0362 {detector_opts, bfield_opts, input_opts, finding_opts, propagation_opts,
0363 fitting_opts, performance_opts, accelerator_opts, truth_finding_config,
0364 track_matching_opts},
0365 argc,
0366 argv,
0367 logger->cloneWithSuffix("Options")};
0368
0369
0370 return seq_run(finding_opts, propagation_opts, fitting_opts, input_opts,
0371 detector_opts, bfield_opts, performance_opts, accelerator_opts,
0372 truth_finding_config, track_matching_opts, logger->clone());
0373 }