vecmem 1.18.0
Loading...
Searching...
No Matches
buffer.ipp
1/* VecMem project, part of the ACTS project (R&D line)
2 *
3 * (c) 2023-2025 CERN for the benefit of the ACTS project
4 *
5 * Mozilla Public License Version 2.0
6 */
7#pragma once
8
9// Local include(s).
10#include "vecmem/containers/details/aligned_multiple_placement.hpp"
11#include "vecmem/edm/details/buffer_traits.hpp"
12#include "vecmem/edm/details/schema_traits.hpp"
13#include "vecmem/edm/details/view_traits.hpp"
14
15// System include(s).
16#include <stdexcept>
17#include <tuple>
18#include <type_traits>
19
20namespace vecmem {
21namespace edm {
22
23template <typename... VARTYPES>
24VECMEM_HOST buffer<schema<VARTYPES...>>::buffer(size_type capacity,
25 memory_resource& mr,
27 : view_type(capacity) {
28
29 // Make sure that this constructor is not used for a container that has
30 // jagged vectors in it.
31 static_assert(
32 std::disjunction_v<type::details::is_jagged_vector<VARTYPES>...> ==
33 false,
34 "Use the other buffer constructor with jagged vector variables!");
35
36 // Perform the appropriate setup.
37 switch (type) {
39 setup_fixed(std::vector<std::size_t>(capacity), mr, nullptr,
40 std::index_sequence_for<VARTYPES...>{});
41 break;
43 setup_resizable(std::vector<std::size_t>(capacity), mr, nullptr,
44 std::index_sequence_for<VARTYPES...>{});
45 break;
46 default:
47 throw std::invalid_argument("Unknown buffer type");
48 }
49}
50
51template <typename... VARTYPES>
52template <
53 typename SIZE_TYPE, typename SIZE_ALLOC,
54 std::enable_if_t<
55 std::is_integral_v<SIZE_TYPE> && std::is_unsigned_v<SIZE_TYPE>, bool>>
56VECMEM_HOST buffer<schema<VARTYPES...>>::buffer(
57 const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
58 memory_resource& main_mr, memory_resource* host_mr,
61
62 // Make sure that this constructor is only used for a container that has
63 // jagged vectors in it.
64 static_assert(
65 std::disjunction_v<type::details::is_jagged_vector<VARTYPES>...>,
66 "Use the other buffer constructor without jagged vector variables!");
67
68 // Perform the appropriate setup.
69 switch (type) {
71 setup_fixed(capacities, main_mr, host_mr,
72 std::index_sequence_for<VARTYPES...>{});
73 break;
75 setup_resizable(capacities, main_mr, host_mr,
76 std::index_sequence_for<VARTYPES...>{});
77 break;
78 default:
79 throw std::invalid_argument("Unknown buffer type");
80 }
81}
82
83template <typename... VARTYPES>
84template <typename SIZE_TYPE, typename SIZE_ALLOC, std::size_t... INDICES>
85VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_fixed(
86 const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities, memory_resource& mr,
87 memory_resource* host_mr, std::index_sequence<INDICES...>) {
88
89 // Sanity check.
90 static_assert(sizeof...(VARTYPES) == sizeof...(INDICES),
91 "Invalid number of indices");
92
93 // Tuple of pointers to the allocated "layout objects" and "payloads".
94 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
96 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
98 std::tuple<typename details::view_type<VARTYPES>::payload_ptr...>
100
101 // Allocate memory for fixed sized variables.
102 std::tie(m_memory, std::get<INDICES>(layout_ptrs)...,
103 std::get<INDICES>(payload_ptrs)...) =
109
110 // Set the base class's memory views.
111 view_type::m_layout = details::find_layout_view<VARTYPES...>(
114 view_type::m_payload = details::find_payload_view<VARTYPES...>(
116 {details::buffer_alloc<VARTYPES>::payload_size(capacities)...});
117
118 // If requested, allocate host memory for the layouts.
119 if (host_mr != nullptr) {
120
121 // Allocate memory for just the layout in host memory.
122 std::tie(m_host_memory, std::get<INDICES>(host_layout_ptrs)...) =
124 typename details::view_type<VARTYPES>::layout_type...>(
125 *host_mr,
126 details::buffer_alloc<VARTYPES>::layout_size(capacities)...);
127
128 // Set the base class's memory view.
129 view_type::m_host_layout = details::find_layout_view<VARTYPES...>(
130 host_layout_ptrs,
131 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
132 } else {
133 // The layout is apparently host accessible.
134 view_type::m_host_layout = view_type::m_layout;
135 }
136
137 // Initialize the views from all the raw pointers.
138 view_type::m_views =
139 details::make_buffer_views<SIZE_TYPE, SIZE_ALLOC, VARTYPES...>(
140 capacities, layout_ptrs, host_layout_ptrs, payload_ptrs,
141 std::index_sequence_for<VARTYPES...>{});
142}
143
144template <typename... VARTYPES>
145template <typename SIZE_TYPE, typename SIZE_ALLOC, std::size_t... INDICES>
146VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_resizable(
147 const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities, memory_resource& mr,
148 memory_resource* host_mr, std::index_sequence<INDICES...>) {
149
150 // Sanity check(s).
151 static_assert(sizeof...(VARTYPES) == sizeof...(INDICES),
152 "Invalid number of indices");
153 static_assert(
154 std::disjunction_v<type::details::is_vector<VARTYPES>...>,
155 "Trying to create a resizable container without any vector variables!");
156
157 // Does the container have jagged vectors in it?
158 constexpr bool has_jagged_vectors =
159 std::disjunction_v<type::details::is_jagged_vector<VARTYPES>...>;
160
161 // Pointers to the allocated "size variables".
162 std::tuple<typename details::view_type<VARTYPES>::size_ptr...> sizes_ptrs;
163
164 // Tuple of pointers to the allocated "layout objects" and "payloads".
165 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
166 layout_ptrs;
167 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
168 host_layout_ptrs;
169 std::tuple<typename details::view_type<VARTYPES>::payload_ptr...>
170 payload_ptrs;
171
172 // Allocate memory for fixed sized variables. A little differently for
173 // containers that have some jagged vectors, versus ones that only have
174 // 1D vectors.
175 if constexpr (has_jagged_vectors) {
176 // Perform the allocation.
177 std::tie(m_memory, std::get<INDICES>(sizes_ptrs)...,
178 std::get<INDICES>(layout_ptrs)...,
179 std::get<INDICES>(payload_ptrs)...) =
181 typename details::view_type<VARTYPES>::size_type...,
182 typename details::view_type<VARTYPES>::layout_type...,
183 typename details::view_type<VARTYPES>::payload_type...>(
184 mr, details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
185 details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
186 details::buffer_alloc<VARTYPES>::payload_size(capacities)...);
187 // Point the base class at the size array.
188 view_type::m_size = {
189 static_cast<typename view_type::memory_view_type::size_type>(
190 (details::buffer_alloc<VARTYPES>::layout_size(capacities) +
191 ...) *
192 sizeof(typename view_type::size_type)),
193 reinterpret_cast<typename view_type::memory_view_type::pointer>(
194 details::find_first_pointer(
195 sizes_ptrs, std::index_sequence_for<VARTYPES...>{}))};
196 } else {
197 // Perform the allocation.
198 typename view_type::size_pointer size = nullptr;
199 std::tie(m_memory, size, std::get<INDICES>(layout_ptrs)...,
200 std::get<INDICES>(payload_ptrs)...) =
202 typename view_type::size_type,
203 typename details::view_type<VARTYPES>::layout_type...,
204 typename details::view_type<VARTYPES>::payload_type...>(
205 mr, 1u,
206 details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
207 details::buffer_alloc<VARTYPES>::payload_size(capacities)...);
208 // Point the base class at the size variable.
209 view_type::m_size = {
210 static_cast<typename view_type::memory_view_type::size_type>(
211 sizeof(typename view_type::size_type)),
212 reinterpret_cast<typename view_type::memory_view_type::pointer>(
213 size)};
214 // Set all size pointers to point at the one allocated number.
215 ((std::get<INDICES>(sizes_ptrs) = size), ...);
216 }
217
218 // Set the base class's memory views.
219 view_type::m_layout = details::find_layout_view<VARTYPES...>(
220 layout_ptrs,
221 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
222 view_type::m_payload = details::find_payload_view<VARTYPES...>(
223 payload_ptrs,
224 {details::buffer_alloc<VARTYPES>::payload_size(capacities)...});
225
226 // If requested, allocate host memory for the layouts.
227 if (host_mr != nullptr) {
228
229 // Allocate memory for just the layout in host memory.
230 std::tie(m_host_memory, std::get<INDICES>(host_layout_ptrs)...) =
232 typename details::view_type<VARTYPES>::layout_type...>(
233 *host_mr,
234 details::buffer_alloc<VARTYPES>::layout_size(capacities)...);
235
236 // Set the base class's memory view.
237 view_type::m_host_layout = details::find_layout_view<VARTYPES...>(
238 host_layout_ptrs,
239 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
240 } else {
241 // The layout is apparently host accessible.
242 view_type::m_host_layout = view_type::m_layout;
243 }
244
245 // Initialize the views from all the raw pointers.
246 view_type::m_views =
247 details::make_buffer_views<SIZE_TYPE, SIZE_ALLOC, VARTYPES...>(
248 capacities, sizes_ptrs, layout_ptrs, host_layout_ptrs, payload_ptrs,
249 std::index_sequence_for<VARTYPES...>{});
250}
251
252} // namespace edm
253
254template <typename... VARTYPES>
257
258 return buffer;
259}
260
261template <typename... VARTYPES>
262VECMEM_HOST edm::view<edm::details::add_const_t<edm::schema<VARTYPES...>>>
264
265 return buffer;
266}
267
268} // namespace vecmem
An allocator class that wraps a memory resource.
Definition allocator.hpp:37
typename view_type::size_type size_type
Size type used for the container.
Definition buffer.hpp:180
Technical base type for buffer<schema<VARTYPES...>>
Definition buffer.hpp:28
buffer_type
"Overall type" for a buffer object
Definition buffer_type.hpp:13
@ fixed_size
The buffer has a fixed number of elements.
@ resizable
The buffer is resizable/expandable.
std::tuple< vecmem::unique_alloc_ptr< char[]>, std::add_pointer_t< Ts >... > aligned_multiple_placement(vecmem::memory_resource &r, Ps &&... ps)
Allocation of aligned arrays of given types.
Definition aligned_multiple_placement.ipp:137
Main namespace for the vecmem classes/functions.
Definition atomic_ref.hpp:16
VECMEM_HOST data::vector_view< T > get_data(array< T, N > &a)
Helper function creating a vecmem::data::vector_view object.
Definition array.ipp:217
Definition buffer_traits.hpp:31
Definition view_traits.hpp:33
Meta type describing the "schema" of an SoA container.
Definition schema.hpp:46