Skip to content

Commit ea18956

Browse files
committed
Make edm::buffer usable with a vecmem::vector for its size.
1 parent 0faa4eb commit ea18956

File tree

4 files changed

+101
-74
lines changed

4 files changed

+101
-74
lines changed

core/include/vecmem/edm/buffer.hpp

+18-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* VecMem project, part of the ACTS project (R&D line)
22
*
3-
* (c) 2023 CERN for the benefit of the ACTS project
3+
* (c) 2023-2025 CERN for the benefit of the ACTS project
44
*
55
* Mozilla Public License Version 2.0
66
*/
@@ -215,26 +215,32 @@ class buffer<schema<VARTYPES...>> : public view<schema<VARTYPES...>> {
215215
/// @param type The type of the buffer (fixed or variable size)
216216
///
217217
template <typename SIZE_TYPE = std::size_t,
218+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>,
218219
std::enable_if_t<std::is_integral<SIZE_TYPE>::value &&
219220
std::is_unsigned<SIZE_TYPE>::value,
220221
bool> = true>
221222
VECMEM_HOST buffer(
222-
const std::vector<SIZE_TYPE>& capacities, memory_resource& mr,
223-
memory_resource* host_mr = nullptr,
223+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
224+
memory_resource& mr, memory_resource* host_mr = nullptr,
224225
vecmem::data::buffer_type type = vecmem::data::buffer_type::fixed_size);
225226

226227
private:
227228
/// Set up a fixed sized buffer
228-
template <typename SIZE_TYPE = std::size_t, std::size_t... INDICES>
229-
VECMEM_HOST void setup_fixed(const std::vector<SIZE_TYPE>& capacities,
230-
memory_resource& mr, memory_resource* host_mr,
231-
std::index_sequence<INDICES...>);
229+
template <typename SIZE_TYPE = std::size_t,
230+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>,
231+
std::size_t... INDICES>
232+
VECMEM_HOST void setup_fixed(
233+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
234+
memory_resource& mr, memory_resource* host_mr,
235+
std::index_sequence<INDICES...>);
232236
/// Set up a resizable buffer
233-
template <typename SIZE_TYPE = std::size_t, std::size_t... INDICES>
234-
VECMEM_HOST void setup_resizable(const std::vector<SIZE_TYPE>& capacities,
235-
memory_resource& mr,
236-
memory_resource* host_mr,
237-
std::index_sequence<INDICES...>);
237+
template <typename SIZE_TYPE = std::size_t,
238+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>,
239+
std::size_t... INDICES>
240+
VECMEM_HOST void setup_resizable(
241+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
242+
memory_resource& mr, memory_resource* host_mr,
243+
std::index_sequence<INDICES...>);
238244

239245
/// The full allocated block of (device) memory
240246
memory_type m_memory;

core/include/vecmem/edm/details/buffer_traits.hpp

+62-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* VecMem project, part of the ACTS project (R&D line)
22
*
3-
* (c) 2023 CERN for the benefit of the ACTS project
3+
* (c) 2023-2025 CERN for the benefit of the ACTS project
44
*
55
* Mozilla Public License Version 2.0
66
*/
@@ -31,96 +31,109 @@ template <typename TYPE>
3131
struct buffer_alloc;
3232

3333
template <typename TYPE>
34-
struct buffer_alloc<type::scalar<TYPE> > {
34+
struct buffer_alloc<type::scalar<TYPE>> {
3535
/// The number of @c TYPE elements to allocate for the payload
36-
template <typename SIZE_TYPE = std::size_t>
37-
VECMEM_HOST static std::size_t payload_size(const std::vector<SIZE_TYPE>&) {
36+
template <typename SIZE_TYPE = std::size_t,
37+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
38+
VECMEM_HOST static std::size_t payload_size(
39+
const std::vector<SIZE_TYPE, SIZE_ALLOC>&) {
3840
return 1u;
3941
}
4042
/// The number of "layout meta-objects" to allocate for the payload
41-
template <typename SIZE_TYPE = std::size_t>
42-
VECMEM_HOST static std::size_t layout_size(const std::vector<SIZE_TYPE>&) {
43+
template <typename SIZE_TYPE = std::size_t,
44+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
45+
VECMEM_HOST static std::size_t layout_size(
46+
const std::vector<SIZE_TYPE, SIZE_ALLOC>&) {
4347
return 0u;
4448
}
4549
/// Construct a view for a scalar variable.
46-
template <typename SIZE_TYPE = std::size_t>
47-
VECMEM_HOST static typename view_type<type::scalar<TYPE> >::type make_view(
48-
const std::vector<SIZE_TYPE>&, unsigned int*,
49-
typename view_type<type::scalar<TYPE> >::layout_ptr,
50-
typename view_type<type::scalar<TYPE> >::layout_ptr,
51-
typename view_type<type::scalar<TYPE> >::payload_ptr ptr) {
50+
template <typename SIZE_TYPE = std::size_t,
51+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
52+
VECMEM_HOST static typename view_type<type::scalar<TYPE>>::type make_view(
53+
const std::vector<SIZE_TYPE, SIZE_ALLOC>&, unsigned int*,
54+
typename view_type<type::scalar<TYPE>>::layout_ptr,
55+
typename view_type<type::scalar<TYPE>>::layout_ptr,
56+
typename view_type<type::scalar<TYPE>>::payload_ptr ptr) {
5257
return ptr;
5358
}
5459
}; // struct buffer_alloc
5560

5661
template <typename TYPE>
57-
struct buffer_alloc<type::vector<TYPE> > {
62+
struct buffer_alloc<type::vector<TYPE>> {
5863
/// The number of @c TYPE elements to allocate for the payload
59-
template <typename SIZE_TYPE = std::size_t>
64+
template <typename SIZE_TYPE = std::size_t,
65+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
6066
VECMEM_HOST static std::size_t payload_size(
61-
const std::vector<SIZE_TYPE>& sizes) {
67+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& sizes) {
6268
return sizes.size();
6369
}
6470
/// The number of "layout meta-objects" to allocate for the payload
65-
template <typename SIZE_TYPE = std::size_t>
66-
VECMEM_HOST static std::size_t layout_size(const std::vector<SIZE_TYPE>&) {
71+
template <typename SIZE_TYPE = std::size_t,
72+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
73+
VECMEM_HOST static std::size_t layout_size(
74+
const std::vector<SIZE_TYPE, SIZE_ALLOC>&) {
6775
return 0u;
6876
}
6977
/// Construct a view for a vector variable.
70-
template <typename SIZE_TYPE = std::size_t>
71-
VECMEM_HOST static typename view_type<type::vector<TYPE> >::type make_view(
72-
const std::vector<SIZE_TYPE>& capacity, unsigned int* size,
73-
typename view_type<type::vector<TYPE> >::layout_ptr,
74-
typename view_type<type::vector<TYPE> >::layout_ptr,
75-
typename view_type<type::vector<TYPE> >::payload_ptr ptr) {
78+
template <typename SIZE_TYPE = std::size_t,
79+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
80+
VECMEM_HOST static typename view_type<type::vector<TYPE>>::type make_view(
81+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacity, unsigned int* size,
82+
typename view_type<type::vector<TYPE>>::layout_ptr,
83+
typename view_type<type::vector<TYPE>>::layout_ptr,
84+
typename view_type<type::vector<TYPE>>::payload_ptr ptr) {
7685
return {static_cast<
77-
typename view_type<type::vector<TYPE> >::type::size_type>(
86+
typename view_type<type::vector<TYPE>>::type::size_type>(
7887
capacity.size()),
7988
size, ptr};
8089
}
8190
}; // struct buffer_alloc
8291

8392
template <typename TYPE>
84-
struct buffer_alloc<type::jagged_vector<TYPE> > {
93+
struct buffer_alloc<type::jagged_vector<TYPE>> {
8594
/// The number of @c TYPE elements to allocate for the payload
86-
template <typename SIZE_TYPE = std::size_t>
95+
template <typename SIZE_TYPE = std::size_t,
96+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
8797
VECMEM_HOST static std::size_t payload_size(
88-
const std::vector<SIZE_TYPE>& sizes) {
98+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& sizes) {
8999
return std::accumulate(sizes.begin(), sizes.end(),
90100
static_cast<std::size_t>(0));
91101
}
92102
/// The number of "layout meta-objects" to allocate for the payload
93-
template <typename SIZE_TYPE = std::size_t>
103+
template <typename SIZE_TYPE = std::size_t,
104+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
94105
VECMEM_HOST static std::size_t layout_size(
95-
const std::vector<SIZE_TYPE>& sizes) {
106+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& sizes) {
96107
return sizes.size();
97108
}
98109
/// Construct a view for a jagged vector variable.
99-
template <typename SIZE_TYPE = std::size_t>
100-
VECMEM_HOST static typename view_type<type::jagged_vector<TYPE> >::type
110+
template <typename SIZE_TYPE = std::size_t,
111+
typename SIZE_ALLOC = std::allocator<SIZE_TYPE>>
112+
VECMEM_HOST static typename view_type<type::jagged_vector<TYPE>>::type
101113
make_view(
102-
const std::vector<SIZE_TYPE>& capacities, unsigned int* sizes,
103-
typename view_type<type::jagged_vector<TYPE> >::layout_ptr layout,
104-
typename view_type<type::jagged_vector<TYPE> >::layout_ptr host_layout,
105-
typename view_type<type::jagged_vector<TYPE> >::payload_ptr ptr) {
114+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
115+
unsigned int* sizes,
116+
typename view_type<type::jagged_vector<TYPE>>::layout_ptr layout,
117+
typename view_type<type::jagged_vector<TYPE>>::layout_ptr host_layout,
118+
typename view_type<type::jagged_vector<TYPE>>::payload_ptr ptr) {
106119

107120
// Set up the "layout objects" for use by the view.
108-
typename view_type<type::jagged_vector<TYPE> >::layout_ptr used_layout =
121+
typename view_type<type::jagged_vector<TYPE>>::layout_ptr used_layout =
109122
(host_layout != nullptr ? host_layout : layout);
110123
std::ptrdiff_t ptrdiff = 0;
111124
for (std::size_t i = 0; i < capacities.size(); ++i) {
112125
new (used_layout + i)
113-
typename view_type<type::jagged_vector<TYPE> >::layout_type(
126+
typename view_type<type::jagged_vector<TYPE>>::layout_type(
114127
static_cast<typename view_type<
115-
type::jagged_vector<TYPE> >::layout_type::size_type>(
128+
type::jagged_vector<TYPE>>::layout_type::size_type>(
116129
capacities[i]),
117130
(sizes != nullptr ? &(sizes[i]) : nullptr), ptr + ptrdiff);
118131
ptrdiff += capacities[i];
119132
}
120133

121134
// Create the jagged vector view.
122135
return {static_cast<
123-
typename view_type<type::vector<TYPE> >::type::size_type>(
136+
typename view_type<type::vector<TYPE>>::type::size_type>(
124137
capacities.size()),
125138
layout, host_layout};
126139
}
@@ -129,9 +142,10 @@ struct buffer_alloc<type::jagged_vector<TYPE> > {
129142
/// @}
130143

131144
/// Function constructing fixed size view objects for @c vecmem::edm::buffer
132-
template <typename SIZE_TYPE, typename... TYPES, std::size_t... INDICES>
145+
template <typename SIZE_TYPE, typename SIZE_ALLOC, typename... TYPES,
146+
std::size_t... INDICES>
133147
VECMEM_HOST auto make_buffer_views(
134-
const std::vector<SIZE_TYPE>& sizes,
148+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& sizes,
135149
const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
136150
const std::tuple<typename view_type<TYPES>::layout_ptr...>& host_layouts,
137151
const std::tuple<typename view_type<TYPES>::payload_ptr...>& payloads,
@@ -143,9 +157,10 @@ VECMEM_HOST auto make_buffer_views(
143157
}
144158

145159
/// Function constructing resizable view objects for @c vecmem::edm::buffer
146-
template <typename SIZE_TYPE, typename... TYPES, std::size_t... INDICES>
160+
template <typename SIZE_TYPE, typename SIZE_ALLOC, typename... TYPES,
161+
std::size_t... INDICES>
147162
VECMEM_HOST auto make_buffer_views(
148-
const std::vector<SIZE_TYPE>& capacities,
163+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
149164
const std::tuple<typename view_type<TYPES>::size_ptr...>& sizes,
150165
const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
151166
const std::tuple<typename view_type<TYPES>::layout_ptr...>& host_layouts,
@@ -212,13 +227,13 @@ VECMEM_HOST constexpr void* find_last_pointer(
212227

213228
/// Function creating a view for the layout of a buffer.
214229
template <typename... TYPES>
215-
VECMEM_HOST constexpr typename view<schema<TYPES...> >::memory_view_type
230+
VECMEM_HOST constexpr typename view<schema<TYPES...>>::memory_view_type
216231
find_layout_view(
217232
const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
218233
const std::array<std::size_t, sizeof...(TYPES)>& sizes) {
219234

220235
// The result type.
221-
using result_type = typename view<schema<TYPES...> >::memory_view_type;
236+
using result_type = typename view<schema<TYPES...>>::memory_view_type;
222237

223238
// Find the first non-zero pointer.
224239
typename result_type::pointer ptr =
@@ -235,13 +250,13 @@ find_layout_view(
235250

236251
/// Function creating a view of the payload of a buffer
237252
template <typename... TYPES>
238-
VECMEM_HOST constexpr typename view<schema<TYPES...> >::memory_view_type
253+
VECMEM_HOST constexpr typename view<schema<TYPES...>>::memory_view_type
239254
find_payload_view(
240255
const std::tuple<typename view_type<TYPES>::payload_ptr...>& payloads,
241256
const std::array<std::size_t, sizeof...(TYPES)>& sizes) {
242257

243258
// The result type.
244-
using result_type = typename view<schema<TYPES...> >::memory_view_type;
259+
using result_type = typename view<schema<TYPES...>>::memory_view_type;
245260

246261
// Find the first non-zero pointer.
247262
typename result_type::pointer ptr =

core/include/vecmem/edm/impl/buffer.ipp

+17-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* VecMem project, part of the ACTS project (R&D line)
22
*
3-
* (c) 2023 CERN for the benefit of the ACTS project
3+
* (c) 2023-2025 CERN for the benefit of the ACTS project
44
*
55
* Mozilla Public License Version 2.0
66
*/
@@ -49,13 +49,14 @@ VECMEM_HOST buffer<schema<VARTYPES...>>::buffer(size_type capacity,
4949
}
5050

5151
template <typename... VARTYPES>
52-
template <typename SIZE_TYPE,
52+
template <typename SIZE_TYPE, typename SIZE_ALLOC,
5353
std::enable_if_t<std::is_integral<SIZE_TYPE>::value &&
5454
std::is_unsigned<SIZE_TYPE>::value,
5555
bool>>
5656
VECMEM_HOST buffer<schema<VARTYPES...>>::buffer(
57-
const std::vector<SIZE_TYPE>& capacities, memory_resource& main_mr,
58-
memory_resource* host_mr, vecmem::data::buffer_type type)
57+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
58+
memory_resource& main_mr, memory_resource* host_mr,
59+
vecmem::data::buffer_type type)
5960
: view_type(static_cast<size_type>(capacities.size())) {
6061

6162
// Make sure that this constructor is only used for a container that has
@@ -80,9 +81,9 @@ VECMEM_HOST buffer<schema<VARTYPES...>>::buffer(
8081
}
8182

8283
template <typename... VARTYPES>
83-
template <typename SIZE_TYPE, std::size_t... INDICES>
84+
template <typename SIZE_TYPE, typename SIZE_ALLOC, std::size_t... INDICES>
8485
VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_fixed(
85-
const std::vector<SIZE_TYPE>& capacities, memory_resource& mr,
86+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities, memory_resource& mr,
8687
memory_resource* host_mr, std::index_sequence<INDICES...>) {
8788

8889
// Sanity check.
@@ -132,15 +133,16 @@ VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_fixed(
132133
}
133134

134135
// Initialize the views from all the raw pointers.
135-
view_type::m_views = details::make_buffer_views<SIZE_TYPE, VARTYPES...>(
136-
capacities, layout_ptrs, host_layout_ptrs, payload_ptrs,
137-
std::index_sequence_for<VARTYPES...>{});
136+
view_type::m_views =
137+
details::make_buffer_views<SIZE_TYPE, SIZE_ALLOC, VARTYPES...>(
138+
capacities, layout_ptrs, host_layout_ptrs, payload_ptrs,
139+
std::index_sequence_for<VARTYPES...>{});
138140
}
139141

140142
template <typename... VARTYPES>
141-
template <typename SIZE_TYPE, std::size_t... INDICES>
143+
template <typename SIZE_TYPE, typename SIZE_ALLOC, std::size_t... INDICES>
142144
VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_resizable(
143-
const std::vector<SIZE_TYPE>& capacities, memory_resource& mr,
145+
const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities, memory_resource& mr,
144146
memory_resource* host_mr, std::index_sequence<INDICES...>) {
145147

146148
// Sanity check(s).
@@ -237,9 +239,10 @@ VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_resizable(
237239
}
238240

239241
// Initialize the views from all the raw pointers.
240-
view_type::m_views = details::make_buffer_views<SIZE_TYPE, VARTYPES...>(
241-
capacities, sizes_ptrs, layout_ptrs, host_layout_ptrs, payload_ptrs,
242-
std::index_sequence_for<VARTYPES...>{});
242+
view_type::m_views =
243+
details::make_buffer_views<SIZE_TYPE, SIZE_ALLOC, VARTYPES...>(
244+
capacities, sizes_ptrs, layout_ptrs, host_layout_ptrs, payload_ptrs,
245+
std::index_sequence_for<VARTYPES...>{});
243246
}
244247

245248
} // namespace edm

tests/core/test_core_edm_buffer.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,11 @@ TEST_F(core_edm_buffer_test, construct) {
7272
// Test the creation of fixed sized and resizable "jagged buffers".
7373
vecmem::edm::buffer<jagged_schema> buffer3{
7474
CAPACITIES, m_resource, nullptr, vecmem::data::buffer_type::fixed_size};
75+
const vecmem::vector<unsigned int> vecmem_capacities({10, 100, 1000},
76+
&m_resource);
7577
vecmem::edm::buffer<jagged_schema> buffer4{
76-
CAPACITIES, m_resource, nullptr, vecmem::data::buffer_type::resizable};
78+
vecmem_capacities, m_resource, nullptr,
79+
vecmem::data::buffer_type::resizable};
7780
}
7881

7982
TEST_F(core_edm_buffer_test, get_data) {

0 commit comments

Comments
 (0)