Skip to content

Commit 55284bd

Browse files
author
Vakho Tsulaia
committed
single_store: added support for handling multiple contexts on the host
1 parent 59b52c3 commit 55284bd

File tree

6 files changed

+92
-23
lines changed

6 files changed

+92
-23
lines changed

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

+81-16
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ class single_store {
6565
template <typename allocator_t = vecmem::memory_resource>
6666
requires(std::derived_from<allocator_t, std::pmr::memory_resource>)
6767
DETRAY_HOST explicit single_store(allocator_t &resource)
68-
: m_container(&resource) {}
68+
: m_container(&resource) {
69+
m_context_size = m_container.size();
70+
}
6971

7072
/// Copy Construct with a specific memory resource @param resource
7173
/// (host-side only)
@@ -74,7 +76,9 @@ class single_store {
7476
requires(std::is_same_v<C, std::vector<T>>
7577
&&std::derived_from<allocator_t, std::pmr::memory_resource>)
7678
DETRAY_HOST single_store(allocator_t &resource, const T &arg)
77-
: m_container(&resource, arg) {}
79+
: m_container(&resource, arg) {
80+
m_context_size = m_container.size();
81+
}
7882

7983
/// Construct from the container @param view . Mainly used device-side.
8084
template <concepts::device_view container_view_t>
@@ -95,36 +99,53 @@ class single_store {
9599
DETRAY_HOST_DEVICE
96100
constexpr auto size(const context_type & /*ctx*/ = {}) const noexcept
97101
-> dindex {
98-
return static_cast<dindex>(m_container.size());
102+
if (m_n_contexts == 0) {
103+
return static_cast<dindex>(m_container.size());
104+
} else {
105+
return static_cast<dindex>(m_context_size);
106+
}
99107
}
100108

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

108119
/// @returns the collections iterator at the start position
109120
DETRAY_HOST_DEVICE
110-
constexpr auto begin(const context_type & /*ctx*/ = {}) const {
111-
return m_container.begin();
121+
constexpr auto begin(const context_type &ctx = {}) const {
122+
if (m_n_contexts == 0) {
123+
return m_container.begin();
124+
} else {
125+
return m_container.begin() + ctx.get() * m_context_size;
126+
}
112127
}
113128

114129
/// @returns the collections iterator sentinel
115130
DETRAY_HOST_DEVICE
116-
constexpr auto end(const context_type & /*ctx*/ = {}) const {
117-
return m_container.end();
131+
constexpr auto end(const context_type &ctx = {}) const {
132+
if (m_n_contexts == 0) {
133+
return m_container.end();
134+
} else {
135+
return m_container.begin() + (ctx.get() + 1) * m_context_size;
136+
}
118137
}
119138

120139
/// @returns access to the underlying container - const
140+
/// ? Remove the ctx argument ?
121141
DETRAY_HOST_DEVICE
122142
constexpr auto get(const context_type & /*ctx*/) const noexcept
123143
-> const base_type & {
124144
return m_container;
125145
}
126146

127147
/// @returns access to the underlying container - non-const
148+
/// ? Remove the ctx argument ?
128149
DETRAY_HOST_DEVICE
129150
constexpr auto get(const context_type & /*ctx*/) noexcept -> base_type & {
130151
return m_container;
@@ -135,33 +156,42 @@ class single_store {
135156
constexpr auto at(const dindex i,
136157
const context_type &ctx = {}) const noexcept
137158
-> const T & {
138-
[[maybe_unused]] context_type tmp_ctx{
139-
ctx}; // Temporary measure to avoid warnings
140-
return m_container.at(i);
159+
if (m_n_contexts == 0) {
160+
return m_container.at(i);
161+
} else {
162+
return m_container.at(ctx.get() * m_context_size + i);
163+
}
141164
}
142165

143166
/// @returns context based access to an element (also range checked)
144167
DETRAY_HOST_DEVICE
145168
constexpr auto at(const dindex i, const context_type &ctx = {}) noexcept
146169
-> T & {
147-
[[maybe_unused]] context_type tmp_ctx{
148-
ctx}; // Temporary measure to avoid warnings
149-
return m_container.at(i);
170+
if (m_n_contexts == 0) {
171+
return m_container.at(i);
172+
} else {
173+
return m_container.at(ctx.get() * m_context_size + i);
174+
}
150175
}
151176

152177
/// Removes and destructs all elements in the container.
178+
/// ? Remove the ctx argument ?
153179
DETRAY_HOST void clear(const context_type & /*ctx*/) {
154180
m_container.clear();
181+
m_context_size = 0;
155182
}
156183

157184
/// Reserve memory of size @param n for a given geometry context
185+
/// ? Remove the ctx argument ?
158186
DETRAY_HOST void reserve(std::size_t n, const context_type & /*ctx*/) {
159187
m_container.reserve(n);
160188
}
161189

162190
/// Resize the underlying container to @param n for a given geometry context
191+
/// ? Remove the ctx argument ?
163192
DETRAY_HOST void resize(std::size_t n, const context_type & /*ctx*/) {
164193
m_container.resize(n);
194+
m_context_size = m_container.size();
165195
}
166196

167197
/// Add a new element to the collection - copy
@@ -171,11 +201,13 @@ class single_store {
171201
/// @param arg the constructor argument
172202
///
173203
/// @note in general can throw an exception
204+
/// ? Remove the ctx argument ?
174205
template <typename U>
175206
DETRAY_HOST constexpr auto push_back(
176207
const U &arg, const context_type & /*ctx*/ = {}) noexcept(false)
177208
-> void {
178209
m_container.push_back(arg);
210+
m_context_size = m_container.size();
179211
}
180212

181213
/// Add a new element to the collection - move
@@ -185,10 +217,12 @@ class single_store {
185217
/// @param arg the constructor argument
186218
///
187219
/// @note in general can throw an exception
220+
/// ? Remove the ctx argument ?
188221
template <typename U>
189222
DETRAY_HOST constexpr auto push_back(
190223
U &&arg, const context_type & /*ctx*/ = {}) noexcept(false) -> void {
191224
m_container.push_back(std::forward<U>(arg));
225+
m_context_size = m_container.size();
192226
}
193227

194228
/// Add a new element to the collection in place
@@ -198,9 +232,11 @@ class single_store {
198232
/// @param args is the list of constructor arguments
199233
///
200234
/// @note in general can throw an exception
235+
/// ? Remove the ctx argument ?
201236
template <typename... Args>
202237
DETRAY_HOST constexpr decltype(auto) emplace_back(
203238
const context_type & /*ctx*/ = {}, Args &&... args) noexcept(false) {
239+
m_context_size++;
204240
return m_container.emplace_back(std::forward<Args>(args)...);
205241
}
206242

@@ -211,12 +247,14 @@ class single_store {
211247
/// @param new_data is the new collection to be added
212248
///
213249
/// @note in general can throw an exception
250+
/// ? Remove the ctx argument ?
214251
template <typename U>
215252
DETRAY_HOST auto insert(container_t<U> &new_data,
216253
const context_type & /*ctx*/ = {}) noexcept(false)
217254
-> void {
218255
m_container.reserve(m_container.size() + new_data.size());
219256
m_container.insert(m_container.end(), new_data.begin(), new_data.end());
257+
m_context_size = m_container.size();
220258
}
221259

222260
/// Insert another collection - move
@@ -226,6 +264,7 @@ class single_store {
226264
/// @param new_data is the new collection to be added
227265
///
228266
/// @note in general can throw an exception
267+
/// ? Remove the ctx argument ?
229268
template <typename U>
230269
DETRAY_HOST auto insert(container_t<U> &&new_data,
231270
const context_type & /*ctx*/ = {}) noexcept(false)
@@ -234,26 +273,50 @@ class single_store {
234273
m_container.insert(m_container.end(),
235274
std::make_move_iterator(new_data.begin()),
236275
std::make_move_iterator(new_data.end()));
276+
m_context_size = m_container.size();
277+
}
278+
279+
template <typename U>
280+
DETRAY_HOST auto add_context(container_t<U> &context_data) noexcept(false)
281+
-> void {
282+
// Cannot add context data to an empty store
283+
if (m_context_size == 0)
284+
return;
285+
// Wrong size of the context_data vector
286+
if (context_data.size() % m_context_size != 0)
287+
return;
288+
// Drop previous contexts if any
289+
if (m_container.size() > m_context_size)
290+
m_container.resize(m_context_size);
291+
// Add new contexts
292+
m_n_contexts = context_data.size() / m_context_size;
293+
m_container.reserve(m_container.size() + context_data.size());
294+
m_container.insert(m_container.end(), context_data.begin(),
295+
context_data.end());
237296
}
238297

239298
/// Append another store to the current one
240299
///
241300
/// @param other The other container
242301
///
243302
/// @note in general can throw an exception
303+
/// ? Remove the ctx argument ?
244304
DETRAY_HOST void append(single_store &other,
245305
const context_type &ctx = {}) noexcept(false) {
246306
insert(other.m_container, ctx);
307+
m_context_size = m_container.size();
247308
}
248309

249310
/// Append another store to the current one - move
250311
///
251312
/// @param other The other container
252313
///
253314
/// @note in general can throw an exception
315+
/// ? Remove the ctx argument ?
254316
DETRAY_HOST void append(single_store &&other,
255317
const context_type &ctx = {}) noexcept(false) {
256318
insert(std::move(other.m_container), ctx);
319+
m_context_size = m_container.size();
257320
}
258321

259322
/// @return the view on the underlying container - non-const
@@ -269,6 +332,8 @@ class single_store {
269332
private:
270333
/// The underlying container implementation
271334
base_type m_container;
335+
size_type m_context_size{0};
336+
size_type m_n_contexts{0};
272337
};
273338

274339
} // namespace detray

tests/unit_tests/cpu/core/transform_store.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ GTEST_TEST(detray_core, static_transform_store) {
2020
using transform3 = test::transform3;
2121
using point3 = test::point3;
2222

23-
using transform_store_t = single_store<transform3>;
23+
using transform_store_t =
24+
single_store<transform3, dvector, geometry_context>;
2425
transform_store_t static_store;
2526
typename transform_store_t::context_type ctx0{};
2627
typename transform_store_t::context_type ctx1{};

tests/unit_tests/cpu/navigation/intersection/intersection_kernel.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ using mask_container_t =
7373
using mask_link_t = typename mask_container_t::single_link;
7474
using material_link_t = dtyped_index<material_ids, dindex>;
7575

76-
using transform_container_t = single_store<test::transform3>;
76+
using transform_container_t =
77+
single_store<test::transform3, dvector, geometry_context>;
7778

7879
/// The Surface definition:
7980
using surface_t =

tests/unit_tests/device/cuda/container_cuda.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ TEST(container_cuda, single_store) {
4646
EXPECT_EQ(mng_store.size(), 0u);
4747

4848
// Test the managed memory allocation
49-
empty_context ctx{};
49+
geometry_context ctx{};
5050
mng_store.reserve(4, ctx);
5151
mng_store.emplace_back(ctx, 1.);
5252
mng_store.push_back(2., ctx);

tests/unit_tests/device/cuda/container_cuda_kernel.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ namespace detray {
1919

2020
// Single store test
2121
/// @{
22-
using single_store_t = single_store<double, vecmem::vector>;
23-
using single_store_dev_t = single_store<double, vecmem::device_vector>;
22+
using single_store_t = single_store<double, vecmem::vector, geometry_context>;
23+
using single_store_dev_t =
24+
single_store<double, vecmem::device_vector, geometry_context>;
2425
/// @}
2526

2627
// Tuple container test

tests/unit_tests/device/cuda/transform_store_cuda_kernel.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ using scalar = dscalar<test_algebra>;
2424
using point3 = dpoint3D<test_algebra>;
2525
using transform3 = dtransform3D<test_algebra>;
2626

27-
using host_transform_store_t = single_store<transform3, vecmem::vector>;
27+
using host_transform_store_t =
28+
single_store<transform3, vecmem::vector, geometry_context>;
2829

2930
using device_transform_store_t =
30-
single_store<transform3, vecmem::device_vector>;
31+
single_store<transform3, vecmem::device_vector, geometry_context>;
3132

3233
void transform_test(vecmem::data::vector_view<point3> input_data,
3334
typename host_transform_store_t::view_type store_data,

0 commit comments

Comments
 (0)