Skip to content

Commit e8e0776

Browse files
authored
Merge pull request #1090 from krasznaa/SeedingThroughput-main-20250724
Seeding Throughput, main branch (2025.07.24.)
1 parent 68f95fc commit e8e0776

File tree

12 files changed

+295
-5
lines changed

12 files changed

+295
-5
lines changed

examples/options/include/traccc/options/throughput.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ class throughput : public interface {
2323
/// @name Options
2424
/// @{
2525

26+
/// "Reconstruction stage" to run
27+
enum class stage {
28+
seeding, ///< Run until the end of seeding
29+
full ///< Run the full chain of reconstruction
30+
};
31+
/// The reconstruction stage to run
32+
stage reco_stage = stage::full;
33+
2634
/// The number of events to process during the job
2735
std::size_t processed_events = 100;
2836
/// The number of events to run "cold", i.e. run without accounting for
@@ -43,6 +51,13 @@ class throughput : public interface {
4351
throughput();
4452

4553
std::unique_ptr<configuration_printable> as_printable() const override;
54+
55+
/// Read/process the command line options
56+
///
57+
/// @param vm The command line options to interpret/read
58+
///
59+
void read(const boost::program_options::variables_map& vm) override;
60+
4661
}; // class throughput
4762

4863
} // namespace traccc::opts

examples/options/src/throughput.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,16 @@ namespace traccc::opts {
1818
/// Convenience namespace shorthand
1919
namespace po = boost::program_options;
2020

21+
/// Type alias for the reconstruction stage enumeration
22+
using stage_type = std::string;
23+
/// Name of the reconstruction stage option
24+
static const char* stage_option = "reco-stage";
25+
2126
throughput::throughput() : interface("Throughput Measurement Options") {
2227

28+
m_desc.add_options()(
29+
stage_option, po::value<stage_type>()->default_value("full"),
30+
"Reconstruction stage to run (\"seeding\" or \"full\")");
2331
m_desc.add_options()(
2432
"processed-events",
2533
po::value(&processed_events)->default_value(processed_events),
@@ -40,9 +48,38 @@ throughput::throughput() : interface("Throughput Measurement Options") {
4048
"File where result logs will be printed (in append mode).");
4149
}
4250

51+
void throughput::read(const po::variables_map& vm) {
52+
53+
// Decode the input data format.
54+
if (vm.count(stage_option)) {
55+
const std::string stage_string = vm[stage_option].as<stage_type>();
56+
if (stage_string == "full") {
57+
reco_stage = stage::full;
58+
} else if (stage_string == "seeding") {
59+
reco_stage = stage::seeding;
60+
} else {
61+
throw std::invalid_argument("Unknown reconstruction stage");
62+
}
63+
}
64+
}
65+
4366
std::unique_ptr<configuration_printable> throughput::as_printable() const {
4467
auto cat = std::make_unique<configuration_category>(m_description);
4568

69+
std::string reco_stage_string;
70+
switch (reco_stage) {
71+
case stage::seeding:
72+
reco_stage_string = "seeding";
73+
break;
74+
case stage::full:
75+
reco_stage_string = "full";
76+
break;
77+
default:
78+
reco_stage_string = "unknown";
79+
break;
80+
}
81+
cat->add_child(std::make_unique<configuration_kv_pair>(
82+
"Reconstruction stage", reco_stage_string));
4683
cat->add_child(std::make_unique<configuration_kv_pair>(
4784
"Cold run events", std::to_string(cold_run_events)));
4885
cat->add_child(std::make_unique<configuration_kv_pair>(

examples/run/alpaka/full_chain_algorithm.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,4 +200,47 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
200200
}
201201
}
202202

203+
bound_track_parameters_collection_types::host full_chain_algorithm::seeding(
204+
const edm::silicon_cell_collection::host& cells) const {
205+
206+
// Create device copy of input collections
207+
edm::silicon_cell_collection::buffer cells_buffer(
208+
static_cast<unsigned int>(cells.size()), *m_cached_device_mr);
209+
m_vecmem_objects.async_copy()(::vecmem::get_data(cells), cells_buffer)
210+
->ignore();
211+
212+
// Run the clusterization (asynchronously).
213+
const clusterization_algorithm::output_type measurements =
214+
m_clusterization(cells_buffer, m_device_det_descr);
215+
m_measurement_sorting(measurements);
216+
217+
// If we have a Detray detector, run the track finding and fitting.
218+
if (m_detector != nullptr) {
219+
220+
// Run the seed-finding (asynchronously).
221+
const spacepoint_formation_algorithm::output_type spacepoints =
222+
m_spacepoint_formation(m_device_detector_view, measurements);
223+
const track_params_estimation::output_type track_params =
224+
m_track_parameter_estimation(measurements, spacepoints,
225+
m_seeding(spacepoints), m_field_vec);
226+
227+
// Copy a limited amount of result data back to the host.
228+
bound_track_parameters_collection_types::host result{&m_host_mr};
229+
m_vecmem_objects.async_copy()(track_params, result)->wait();
230+
return result;
231+
232+
}
233+
// If not, copy the track parameters back to the host, and return a dummy
234+
// object.
235+
else {
236+
237+
// Copy the measurements back to the host.
238+
measurement_collection_types::host measurements_host(&m_host_mr);
239+
m_vecmem_objects.async_copy()(measurements, measurements_host)->wait();
240+
241+
// Return an empty object.
242+
return {};
243+
}
244+
}
245+
203246
} // namespace traccc::alpaka

examples/run/alpaka/full_chain_algorithm.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "traccc/bfield/magnetic_field.hpp"
2121
#include "traccc/clusterization/clustering_config.hpp"
2222
#include "traccc/edm/silicon_cell_collection.hpp"
23+
#include "traccc/edm/track_parameters.hpp"
2324
#include "traccc/edm/track_state.hpp"
2425
#include "traccc/fitting/kalman_filter/kalman_fitter.hpp"
2526
#include "traccc/geometry/detector.hpp"
@@ -108,6 +109,14 @@ class full_chain_algorithm
108109
output_type operator()(
109110
const edm::silicon_cell_collection::host& cells) const override;
110111

112+
/// Reconstruct track seeds in the entire detector
113+
///
114+
/// @param cells The cells for every detector module in the event
115+
/// @return The track seeds reconstructed
116+
///
117+
bound_track_parameters_collection_types::host seeding(
118+
const edm::silicon_cell_collection::host& cells) const;
119+
111120
private:
112121
/// Alpaka Queue
113122
traccc::alpaka::queue m_queue;

examples/run/common/throughput_mt.ipp

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
#include <cstdlib>
5555
#include <ctime>
5656
#include <fstream>
57+
#include <functional>
5758
#include <iostream>
5859
#include <memory>
5960
#include <vector>
@@ -187,6 +188,27 @@ int throughput_mt(std::string_view description, int argc, char* argv[],
187188
logger().clone()});
188189
}
189190

191+
// Set up a lambda that calls the correct function on the algorithms.
192+
std::function<std::size_t(int, const edm::silicon_cell_collection::host&)>
193+
process_event;
194+
if (throughput_opts.reco_stage == opts::throughput::stage::seeding) {
195+
process_event = [&](int thread,
196+
const edm::silicon_cell_collection::host& cells)
197+
-> std::size_t {
198+
return algs.at(static_cast<std::size_t>(thread))
199+
.seeding(cells)
200+
.size();
201+
};
202+
} else if (throughput_opts.reco_stage == opts::throughput::stage::full) {
203+
process_event = [&](int thread,
204+
const edm::silicon_cell_collection::host& cells)
205+
-> std::size_t {
206+
return algs.at(static_cast<std::size_t>(thread))(cells).size();
207+
};
208+
} else {
209+
throw std::invalid_argument("Unknown reconstruction stage");
210+
}
211+
190212
// Set up the TBB arena and thread group. From here on out TBB is only
191213
// allowed to use the specified number of threads.
192214
tbb::global_control global_thread_limit(
@@ -233,10 +255,9 @@ int throughput_mt(std::string_view description, int argc, char* argv[],
233255
// Launch the processing of the event.
234256
arena.execute([&, event]() {
235257
group.run([&, event]() {
236-
rec_track_params.fetch_add(algs.at(static_cast<std::size_t>(
237-
tbb::this_task_arena::current_thread_index()))(
238-
input[event])
239-
.size());
258+
rec_track_params.fetch_add(process_event(
259+
tbb::this_task_arena::current_thread_index(),
260+
input[event]));
240261
progress_bar.tick();
241262
});
242263
});

examples/run/common/throughput_st.ipp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
// System include(s).
4646
#include <cstdlib>
4747
#include <ctime>
48+
#include <functional>
4849
#include <iostream>
4950
#include <memory>
5051

@@ -151,6 +152,19 @@ int throughput_st(std::string_view description, int argc, char* argv[],
151152
std::srand(throughput_opts.random_seed);
152153
}
153154

155+
// Set up a lambda that calls the correct function on the algorithm.
156+
std::function<std::size_t(const edm::silicon_cell_collection::host&)>
157+
process_event;
158+
if (throughput_opts.reco_stage == opts::throughput::stage::seeding) {
159+
process_event = [&](const edm::silicon_cell_collection::host& cells)
160+
-> std::size_t { return alg->seeding(cells).size(); };
161+
} else if (throughput_opts.reco_stage == opts::throughput::stage::full) {
162+
process_event = [&](const edm::silicon_cell_collection::host& cells)
163+
-> std::size_t { return (*alg)(cells).size(); };
164+
} else {
165+
throw std::invalid_argument("Unknown reconstruction stage");
166+
}
167+
154168
// Dummy count uses output of tp algorithm to ensure the compiler
155169
// optimisations don't skip any step
156170
std::size_t rec_track_params = 0;
@@ -180,7 +194,7 @@ int throughput_st(std::string_view description, int argc, char* argv[],
180194
input_opts.events;
181195

182196
// Process one event.
183-
rec_track_params += (*alg)(input[event]).size();
197+
rec_track_params += process_event(input[event]);
184198
progress_bar.tick();
185199
}
186200
}

examples/run/cpu/full_chain_algorithm.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,41 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
9090
}
9191
}
9292

93+
bound_track_parameters_collection_types::host full_chain_algorithm::seeding(
94+
const edm::silicon_cell_collection::host& cells) const {
95+
96+
// Create a data object for the detector description.
97+
const silicon_detector_description::const_data det_descr_data =
98+
vecmem::get_data(m_det_descr.get());
99+
100+
// Run the clusterization.
101+
auto cells_data = vecmem::get_data(cells);
102+
const clustering_algorithm::output_type measurements =
103+
m_clusterization(cells_data, det_descr_data);
104+
105+
// If we have a Detray detector, run the seeding track finding and fitting.
106+
if (m_detector != nullptr) {
107+
108+
// Run the seed-finding.
109+
const measurement_collection_types::const_view measurements_view =
110+
vecmem::get_data(measurements);
111+
const spacepoint_formation_algorithm::output_type spacepoints =
112+
m_spacepoint_formation(*m_detector, measurements_view);
113+
const edm::spacepoint_collection::const_data spacepoints_data =
114+
vecmem::get_data(spacepoints);
115+
const host::seeding_algorithm::output_type seeds =
116+
m_seeding(spacepoints_data);
117+
const edm::seed_collection::const_data seeds_data =
118+
vecmem::get_data(seeds);
119+
return m_track_parameter_estimation(measurements_view, spacepoints_data,
120+
seeds_data, m_field_vec);
121+
}
122+
// If not, just return an empty object.
123+
else {
124+
125+
// Return an empty object.
126+
return {};
127+
}
128+
}
129+
93130
} // namespace traccc

examples/run/cpu/full_chain_algorithm.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "traccc/bfield/magnetic_field.hpp"
1212
#include "traccc/clusterization/clusterization_algorithm.hpp"
1313
#include "traccc/edm/silicon_cell_collection.hpp"
14+
#include "traccc/edm/track_parameters.hpp"
1415
#include "traccc/edm/track_state.hpp"
1516
#include "traccc/finding/combinatorial_kalman_filter_algorithm.hpp"
1617
#include "traccc/fitting/kalman_fitting_algorithm.hpp"
@@ -87,6 +88,14 @@ class full_chain_algorithm : public algorithm<track_state_container_types::host(
8788
output_type operator()(
8889
const edm::silicon_cell_collection::host& cells) const override;
8990

91+
/// Reconstruct track seeds in the entire detector
92+
///
93+
/// @param cells The cells for every detector module in the event
94+
/// @return The track seeds reconstructed
95+
///
96+
bound_track_parameters_collection_types::host seeding(
97+
const edm::silicon_cell_collection::host& cells) const;
98+
9099
private:
91100
/// Vecmem copy object
92101
std::unique_ptr<vecmem::copy> m_copy;

examples/run/cuda/full_chain_algorithm.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,4 +206,46 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
206206
}
207207
}
208208

209+
bound_track_parameters_collection_types::host full_chain_algorithm::seeding(
210+
const edm::silicon_cell_collection::host& cells) const {
211+
212+
// Create device copy of input collections
213+
edm::silicon_cell_collection::buffer cells_buffer(
214+
static_cast<unsigned int>(cells.size()), *m_cached_device_mr);
215+
m_copy(vecmem::get_data(cells), cells_buffer)->ignore();
216+
217+
// Run the clusterization (asynchronously).
218+
const measurement_collection_types::buffer measurements =
219+
m_clusterization(cells_buffer, m_device_det_descr);
220+
m_measurement_sorting(measurements);
221+
222+
// If we have a Detray detector, run the seeding, track finding and fitting.
223+
if (m_detector != nullptr) {
224+
225+
// Run the seed-finding (asynchronously).
226+
const spacepoint_formation_algorithm::output_type spacepoints =
227+
m_spacepoint_formation(m_device_detector_view, measurements);
228+
const track_params_estimation::output_type track_params =
229+
m_track_parameter_estimation(measurements, spacepoints,
230+
m_seeding(spacepoints), m_field_vec);
231+
232+
// Copy a limited amount of result data back to the host.
233+
bound_track_parameters_collection_types::host result{&m_host_mr};
234+
m_copy(track_params, result)->wait();
235+
return result;
236+
237+
}
238+
// If not, copy the measurements back to the host, and return a dummy
239+
// object.
240+
else {
241+
242+
// Copy the measurements back to the host.
243+
measurement_collection_types::host measurements_host(&m_host_mr);
244+
m_copy(measurements, measurements_host)->wait();
245+
246+
// Return an empty object.
247+
return {};
248+
}
249+
}
250+
209251
} // namespace traccc::cuda

examples/run/cuda/full_chain_algorithm.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "traccc/cuda/seeding/track_params_estimation.hpp"
1919
#include "traccc/cuda/utils/stream.hpp"
2020
#include "traccc/edm/silicon_cell_collection.hpp"
21+
#include "traccc/edm/track_parameters.hpp"
2122
#include "traccc/edm/track_state.hpp"
2223
#include "traccc/geometry/detector.hpp"
2324
#include "traccc/geometry/silicon_detector_description.hpp"
@@ -109,6 +110,14 @@ class full_chain_algorithm
109110
output_type operator()(
110111
const edm::silicon_cell_collection::host& cells) const override;
111112

113+
/// Reconstruct track seeds in the entire detector
114+
///
115+
/// @param cells The cells for every detector module in the event
116+
/// @return The track seeds reconstructed
117+
///
118+
bound_track_parameters_collection_types::host seeding(
119+
const edm::silicon_cell_collection::host& cells) const;
120+
112121
private:
113122
/// Host memory resource
114123
vecmem::memory_resource& m_host_mr;

0 commit comments

Comments
 (0)