Skip to content

Commit 64ddf38

Browse files
authored
single_store: added support for handling multiple contexts on the host (#939)
Added support for handling multiple contexts on the host
1 parent ba458e5 commit 64ddf38

17 files changed

+230
-88
lines changed

core/include/detray/core/detail/single_store.hpp

+69-17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <vecmem/memory/memory_resource.hpp>
1919

2020
// System include(s)
21+
#include <iostream>
2122
#include <type_traits>
2223

2324
namespace detray {
@@ -65,7 +66,9 @@ class single_store {
6566
template <typename allocator_t = vecmem::memory_resource>
6667
requires(std::derived_from<allocator_t, std::pmr::memory_resource>)
6768
DETRAY_HOST explicit single_store(allocator_t &resource)
68-
: m_container(&resource) {}
69+
: m_container(&resource) {
70+
m_context_size = m_container.size();
71+
}
6972

7073
/// Copy Construct with a specific memory resource @param resource
7174
/// (host-side only)
@@ -74,12 +77,16 @@ class single_store {
7477
requires(std::is_same_v<C, std::vector<T>>
7578
&&std::derived_from<allocator_t, std::pmr::memory_resource>)
7679
DETRAY_HOST single_store(allocator_t &resource, const T &arg)
77-
: m_container(&resource, arg) {}
80+
: m_container(&resource, arg) {
81+
m_context_size = m_container.size();
82+
}
7883

7984
/// Construct from the container @param view . Mainly used device-side.
8085
template <concepts::device_view container_view_t>
8186
DETRAY_HOST_DEVICE explicit single_store(container_view_t &view)
82-
: m_container(view) {}
87+
: m_container(view) {
88+
m_context_size = m_container.size();
89+
}
8390

8491
/// @returns a pointer to the underlying container - const
8592
DETRAY_HOST_DEVICE
@@ -95,26 +102,29 @@ class single_store {
95102
DETRAY_HOST_DEVICE
96103
constexpr auto size(const context_type & /*ctx*/ = {}) const noexcept
97104
-> dindex {
98-
return static_cast<dindex>(m_container.size());
105+
return static_cast<dindex>(m_context_size);
99106
}
100107

101108
/// @returns true if the underlying container is empty
102109
DETRAY_HOST_DEVICE
103-
constexpr auto empty(const context_type & /*ctx*/ = {}) const noexcept
104-
-> bool {
105-
return m_container.empty();
110+
constexpr auto empty(const context_type &ctx = {}) const noexcept -> bool {
111+
if (ctx.get() == 0u) {
112+
return m_container.empty();
113+
} else {
114+
return ctx.get() > m_n_contexts;
115+
}
106116
}
107117

108118
/// @returns the collections iterator at the start position
109119
DETRAY_HOST_DEVICE
110-
constexpr auto begin(const context_type & /*ctx*/ = {}) const {
111-
return m_container.begin();
120+
constexpr auto begin(const context_type &ctx = {}) const {
121+
return m_container.begin() + ctx.get() * m_context_size;
112122
}
113123

114124
/// @returns the collections iterator sentinel
115125
DETRAY_HOST_DEVICE
116-
constexpr auto end(const context_type & /*ctx*/ = {}) const {
117-
return m_container.end();
126+
constexpr auto end(const context_type &ctx = {}) const {
127+
return m_container.begin() + (ctx.get() + 1) * m_context_size;
118128
}
119129

120130
/// @returns access to the underlying container - const
@@ -135,33 +145,34 @@ class single_store {
135145
constexpr auto at(const dindex i,
136146
const context_type &ctx = {}) const noexcept
137147
-> const T & {
138-
[[maybe_unused]] context_type tmp_ctx{
139-
ctx}; // Temporary measure to avoid warnings
140-
return m_container.at(i);
148+
return m_container.at(ctx.get() * m_context_size + i);
141149
}
142150

143151
/// @returns context based access to an element (also range checked)
144152
DETRAY_HOST_DEVICE
145153
constexpr auto at(const dindex i, const context_type &ctx = {}) noexcept
146154
-> T & {
147-
[[maybe_unused]] context_type tmp_ctx{
148-
ctx}; // Temporary measure to avoid warnings
149-
return m_container.at(i);
155+
return m_container.at(ctx.get() * m_context_size + i);
150156
}
151157

152158
/// Removes and destructs all elements in the container.
153159
DETRAY_HOST void clear(const context_type & /*ctx*/) {
160+
assert(m_n_contexts == 0u);
154161
m_container.clear();
162+
m_context_size = 0;
155163
}
156164

157165
/// Reserve memory of size @param n for a given geometry context
158166
DETRAY_HOST void reserve(std::size_t n, const context_type & /*ctx*/) {
167+
assert(m_n_contexts == 0u);
159168
m_container.reserve(n);
160169
}
161170

162171
/// Resize the underlying container to @param n for a given geometry context
163172
DETRAY_HOST void resize(std::size_t n, const context_type & /*ctx*/) {
173+
assert(m_n_contexts == 0u);
164174
m_container.resize(n);
175+
m_context_size = m_container.size();
165176
}
166177

167178
/// Add a new element to the collection - copy
@@ -175,7 +186,9 @@ class single_store {
175186
DETRAY_HOST constexpr auto push_back(
176187
const U &arg, const context_type & /*ctx*/ = {}) noexcept(false)
177188
-> void {
189+
assert(m_n_contexts == 0u);
178190
m_container.push_back(arg);
191+
m_context_size = m_container.size();
179192
}
180193

181194
/// Add a new element to the collection - move
@@ -188,7 +201,9 @@ class single_store {
188201
template <typename U>
189202
DETRAY_HOST constexpr auto push_back(
190203
U &&arg, const context_type & /*ctx*/ = {}) noexcept(false) -> void {
204+
assert(m_n_contexts == 0u);
191205
m_container.push_back(std::forward<U>(arg));
206+
m_context_size = m_container.size();
192207
}
193208

194209
/// Add a new element to the collection in place
@@ -201,6 +216,8 @@ class single_store {
201216
template <typename... Args>
202217
DETRAY_HOST constexpr decltype(auto) emplace_back(
203218
const context_type & /*ctx*/ = {}, Args &&... args) noexcept(false) {
219+
assert(m_n_contexts == 0u);
220+
m_context_size++;
204221
return m_container.emplace_back(std::forward<Args>(args)...);
205222
}
206223

@@ -215,8 +232,10 @@ class single_store {
215232
DETRAY_HOST auto insert(container_t<U> &new_data,
216233
const context_type & /*ctx*/ = {}) noexcept(false)
217234
-> void {
235+
assert(m_n_contexts == 0u);
218236
m_container.reserve(m_container.size() + new_data.size());
219237
m_container.insert(m_container.end(), new_data.begin(), new_data.end());
238+
m_context_size = m_container.size();
220239
}
221240

222241
/// Insert another collection - move
@@ -230,30 +249,61 @@ class single_store {
230249
DETRAY_HOST auto insert(container_t<U> &&new_data,
231250
const context_type & /*ctx*/ = {}) noexcept(false)
232251
-> void {
252+
assert(m_n_contexts == 0u);
233253
m_container.reserve(m_container.size() + new_data.size());
234254
m_container.insert(m_container.end(),
235255
std::make_move_iterator(new_data.begin()),
236256
std::make_move_iterator(new_data.end()));
257+
m_context_size = m_container.size();
258+
}
259+
260+
template <typename U>
261+
DETRAY_HOST auto add_context(container_t<U> &context_data) noexcept(false)
262+
-> void {
263+
// Cannot add context data to an empty store
264+
if (m_context_size == 0u) {
265+
std::cout << "WARNING: Single Store. Cannot add a context to an "
266+
"empty store ";
267+
return;
268+
}
269+
// Wrong size of the context_data vector
270+
if (context_data.size() % m_context_size != 0u) {
271+
std::cout << "WARNING: Single Store. Wrong size of the inserted "
272+
"vector. Must be multiple of the context size";
273+
return;
274+
}
275+
// Drop previous contexts if any
276+
if (m_container.size() > m_context_size)
277+
m_container.resize(m_context_size);
278+
// Add new contexts
279+
m_n_contexts = context_data.size() / m_context_size;
280+
m_container.reserve(m_container.size() + context_data.size());
281+
m_container.insert(m_container.end(), context_data.begin(),
282+
context_data.end());
237283
}
238284

239285
/// Append another store to the current one
240286
///
241287
/// @param other The other container
242288
///
243289
/// @note in general can throw an exception
290+
/// ? Remove the ctx argument ?
244291
DETRAY_HOST void append(single_store &other,
245292
const context_type &ctx = {}) noexcept(false) {
246293
insert(other.m_container, ctx);
294+
m_context_size = m_container.size();
247295
}
248296

249297
/// Append another store to the current one - move
250298
///
251299
/// @param other The other container
252300
///
253301
/// @note in general can throw an exception
302+
/// ? Remove the ctx argument ?
254303
DETRAY_HOST void append(single_store &&other,
255304
const context_type &ctx = {}) noexcept(false) {
256305
insert(std::move(other.m_container), ctx);
306+
m_context_size = m_container.size();
257307
}
258308

259309
/// @return the view on the underlying container - non-const
@@ -269,6 +319,8 @@ class single_store {
269319
private:
270320
/// The underlying container implementation
271321
base_type m_container;
322+
size_type m_context_size{0u};
323+
size_type m_n_contexts{0u};
272324
};
273325

274326
} // namespace detray

tests/include/detray/test/common/detail/register_checks.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ template <template <typename> class check_t, typename detector_t,
1919
typename config_t = typename check_t<detector_t>::config>
2020
void register_checks(const detector_t &det,
2121
const typename detector_t::name_map &vol_names,
22-
const config_t &cfg = {},
23-
const typename detector_t::geometry_context &gctx = {}) {
22+
const config_t &cfg,
23+
const typename detector_t::geometry_context &gctx) {
2424

2525
const char *test_name = cfg.name().c_str();
2626
if (!test_name) {

tests/integration_tests/cpu/detectors/telescope_detector_navigation.cpp

+11-7
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,13 @@ int main(int argc, char **argv) {
5151
build_telescope_detector<test_algebra>(host_mr, tel_cfg);
5252

5353
auto white_board = std::make_shared<test::whiteboard>();
54+
tel_detector_t::geometry_context ctx{};
5455

5556
// General data consistency of the detector
5657
test::consistency_check<tel_detector_t>::config cfg_cons{};
5758
detail::register_checks<test::consistency_check>(
58-
tel_det, tel_names, cfg_cons.name("telescope_detector_consistency"));
59+
tel_det, tel_names, cfg_cons.name("telescope_detector_consistency"),
60+
ctx);
5961

6062
// Navigation link consistency, discovered by ray intersection
6163
test::ray_scan<tel_detector_t>::config cfg_ray_scan{};
@@ -67,7 +69,8 @@ int main(int argc, char **argv) {
6769
cfg_ray_scan.track_generator().theta_range(0.f,
6870
0.25f * constant<scalar>::pi_4);
6971

70-
detail::register_checks<test::ray_scan>(tel_det, tel_names, cfg_ray_scan);
72+
detail::register_checks<test::ray_scan>(tel_det, tel_names, cfg_ray_scan,
73+
ctx);
7174

7275
// Comparison of straight line navigation with ray scan
7376
test::straight_line_navigation<tel_detector_t>::config cfg_str_nav{};
@@ -80,7 +83,7 @@ int main(int argc, char **argv) {
8083
static_cast<float>(mask_tolerance[1]);
8184

8285
detail::register_checks<test::straight_line_navigation>(tel_det, tel_names,
83-
cfg_str_nav);
86+
cfg_str_nav, ctx);
8487

8588
// Navigation link consistency, discovered by helix intersection
8689
test::helix_scan<tel_detector_t>::config cfg_hel_scan{};
@@ -95,7 +98,8 @@ int main(int argc, char **argv) {
9598
cfg_hel_scan.track_generator().theta_range(0.f,
9699
0.25f * constant<scalar>::pi_4);
97100

98-
detail::register_checks<test::helix_scan>(tel_det, tel_names, cfg_hel_scan);
101+
detail::register_checks<test::helix_scan>(tel_det, tel_names, cfg_hel_scan,
102+
ctx);
99103

100104
// Comparison of navigation in a constant B-field with helix
101105
test::helix_navigation<tel_detector_t>::config cfg_hel_nav{};
@@ -105,7 +109,7 @@ int main(int argc, char **argv) {
105109
-100.f * unit<float>::um;
106110

107111
detail::register_checks<test::helix_navigation>(tel_det, tel_names,
108-
cfg_hel_nav);
112+
cfg_hel_nav, ctx);
109113

110114
// Run the material validation
111115
test::material_scan<tel_detector_t>::config mat_scan_cfg{};
@@ -117,7 +121,7 @@ int main(int argc, char **argv) {
117121

118122
// Record the material using a ray scan
119123
detail::register_checks<test::material_scan>(tel_det, tel_names,
120-
mat_scan_cfg);
124+
mat_scan_cfg, ctx);
121125

122126
// Now trace the material during navigation and compare
123127
test::material_validation<tel_detector_t>::config mat_val_cfg{};
@@ -126,7 +130,7 @@ int main(int argc, char **argv) {
126130
mat_val_cfg.propagation() = cfg_str_nav.propagation();
127131

128132
detail::register_checks<test::material_validation>(tel_det, tel_names,
129-
mat_val_cfg);
133+
mat_val_cfg, ctx);
130134

131135
// Run the checks
132136
return RUN_ALL_TESTS();

0 commit comments

Comments
 (0)