vecmem 1.14.0
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Pages
buffer.ipp
1/* VecMem project, part of the ACTS project (R&D line)
2 *
3 * (c) 2023 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::runtime_error("Unknown buffer type");
48 }
49}
50
51template <typename... VARTYPES>
52template <typename SIZE_TYPE,
53 std::enable_if_t<std::is_integral<SIZE_TYPE>::value &&
54 std::is_unsigned<SIZE_TYPE>::value,
55 bool>>
56VECMEM_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)
60
61 // Make sure that this constructor is only used for a container that has
62 // jagged vectors in it.
63 static_assert(
64 std::disjunction_v<type::details::is_jagged_vector<VARTYPES>...>,
65 "Use the other buffer constructor without jagged vector variables!");
66
67 // Perform the appropriate setup.
68 switch (type) {
70 setup_fixed(capacities, main_mr, host_mr,
71 std::index_sequence_for<VARTYPES...>{});
72 break;
74 setup_resizable(capacities, main_mr, host_mr,
75 std::index_sequence_for<VARTYPES...>{});
76 break;
77 default:
78 throw std::runtime_error("Unknown buffer type");
79 }
80}
81
82template <typename... VARTYPES>
83template <typename SIZE_TYPE, std::size_t... INDICES>
84VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_fixed(
85 const std::vector<SIZE_TYPE>& capacities, memory_resource& mr,
86 memory_resource* host_mr, std::index_sequence<INDICES...>) {
87
88 // Sanity check.
89 static_assert(sizeof...(VARTYPES) == sizeof...(INDICES),
90 "Invalid number of indices");
91
92 // Tuple of pointers to the allocated "layout objects" and "payloads".
93 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
95 std::tuple<typename details::view_type<VARTYPES>::payload_ptr...>
97
98 // Allocate memory for fixed sized variables.
99 std::tie(m_memory, std::get<INDICES>(layout_ptrs)...,
100 std::get<INDICES>(payload_ptrs)...) =
103 typename details::view_type<VARTYPES>::payload_type...>(
106
107 // Set the base class's memory views.
108 view_type::m_layout = details::find_layout_view<VARTYPES...>(
111 view_type::m_payload = details::find_payload_view<VARTYPES...>(
113 {details::buffer_alloc<VARTYPES>::payload_size(capacities)...});
114
115 // If requested, allocate host memory for the layouts.
116 if (host_mr != nullptr) {
117
118 // Allocate memory for just the layout in host memory.
119 std::tie(m_host_memory, std::get<INDICES>(host_layout_ptrs)...) =
121 typename details::view_type<VARTYPES>::layout_type...>(
122 *host_mr,
123 details::buffer_alloc<VARTYPES>::layout_size(capacities)...);
124
125 // Set the base class's memory view.
126 view_type::m_host_layout = details::find_layout_view<VARTYPES...>(
128 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
129 } else {
130 // The layout is apparently host accessible.
131 view_type::m_host_layout = view_type::m_layout;
132 }
133
134 // Initialize the views from all the raw pointers.
135 view_type::m_views = details::make_buffer_views<SIZE_TYPE, VARTYPES...>(
137 std::index_sequence_for<VARTYPES...>{});
138}
139
140template <typename... VARTYPES>
141template <typename SIZE_TYPE, std::size_t... INDICES>
142VECMEM_HOST void buffer<schema<VARTYPES...>>::setup_resizable(
143 const std::vector<SIZE_TYPE>& capacities, memory_resource& mr,
144 memory_resource* host_mr, std::index_sequence<INDICES...>) {
145
146 // Sanity check(s).
147 static_assert(sizeof...(VARTYPES) == sizeof...(INDICES),
148 "Invalid number of indices");
149 static_assert(
150 std::disjunction_v<type::details::is_vector<VARTYPES>...>,
151 "Trying to create a resizable container without any vector variables!");
152
153 // Does the container have jagged vectors in it?
154 constexpr bool has_jagged_vectors =
155 std::disjunction_v<type::details::is_jagged_vector<VARTYPES>...>;
156
157 // Pointers to the allocated "size variables".
158 std::tuple<typename details::view_type<VARTYPES>::size_ptr...> sizes_ptrs;
159
160 // Tuple of pointers to the allocated "layout objects" and "payloads".
161 std::tuple<typename details::view_type<VARTYPES>::layout_ptr...>
163 std::tuple<typename details::view_type<VARTYPES>::payload_ptr...>
165
166 // Allocate memory for fixed sized variables. A little differently for
167 // containers that have some jagged vectors, versus ones that only have
168 // 1D vectors.
169 if constexpr (has_jagged_vectors) {
170 // Perform the allocation.
171 std::tie(m_memory, std::get<INDICES>(sizes_ptrs)...,
172 std::get<INDICES>(layout_ptrs)...,
173 std::get<INDICES>(payload_ptrs)...) =
175 typename details::view_type<VARTYPES>::size_type...,
176 typename details::view_type<VARTYPES>::layout_type...,
177 typename details::view_type<VARTYPES>::payload_type...>(
178 mr, details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
179 details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
180 details::buffer_alloc<VARTYPES>::payload_size(capacities)...);
181 // Point the base class at the size array.
182 view_type::m_size = {
183 static_cast<typename view_type::memory_view_type::size_type>(
184 (details::buffer_alloc<VARTYPES>::layout_size(capacities) +
185 ...) *
186 sizeof(typename view_type::size_type)),
187 reinterpret_cast<typename view_type::memory_view_type::pointer>(
188 details::find_first_pointer(
189 sizes_ptrs, std::index_sequence_for<VARTYPES...>{}))};
190 } else {
191 // Perform the allocation.
192 typename view_type::size_pointer size = nullptr;
193 std::tie(m_memory, size, std::get<INDICES>(layout_ptrs)...,
194 std::get<INDICES>(payload_ptrs)...) =
196 typename view_type::size_type,
197 typename details::view_type<VARTYPES>::layout_type...,
198 typename details::view_type<VARTYPES>::payload_type...>(
199 mr, 1u,
200 details::buffer_alloc<VARTYPES>::layout_size(capacities)...,
201 details::buffer_alloc<VARTYPES>::payload_size(capacities)...);
202 // Point the base class at the size variable.
203 view_type::m_size = {
204 static_cast<typename view_type::memory_view_type::size_type>(
205 sizeof(typename view_type::size_type)),
206 reinterpret_cast<typename view_type::memory_view_type::pointer>(
207 size)};
208 // Set all size pointers to point at the one allocated number.
209 ((std::get<INDICES>(sizes_ptrs) = size), ...);
210 }
211
212 // Set the base class's memory views.
213 view_type::m_layout = details::find_layout_view<VARTYPES...>(
215 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
216 view_type::m_payload = details::find_payload_view<VARTYPES...>(
218 {details::buffer_alloc<VARTYPES>::payload_size(capacities)...});
219
220 // If requested, allocate host memory for the layouts.
221 if (host_mr != nullptr) {
222
223 // Allocate memory for just the layout in host memory.
224 std::tie(m_host_memory, std::get<INDICES>(host_layout_ptrs)...) =
226 typename details::view_type<VARTYPES>::layout_type...>(
227 *host_mr,
228 details::buffer_alloc<VARTYPES>::layout_size(capacities)...);
229
230 // Set the base class's memory view.
231 view_type::m_host_layout = details::find_layout_view<VARTYPES...>(
233 {details::buffer_alloc<VARTYPES>::layout_size(capacities)...});
234 } else {
235 // The layout is apparently host accessible.
236 view_type::m_host_layout = view_type::m_layout;
237 }
238
239 // Initialize the views from all the raw pointers.
240 view_type::m_views = details::make_buffer_views<SIZE_TYPE, VARTYPES...>(
242 std::index_sequence_for<VARTYPES...>{});
243}
244
245} // namespace edm
246
247template <typename... VARTYPES>
250
251 return buffer;
252}
253
254template <typename... VARTYPES>
255VECMEM_HOST edm::view<edm::details::add_const_t<edm::schema<VARTYPES...>>>
257
258 return buffer;
259}
260
261} // namespace vecmem
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
std::vector< T, vecmem::polymorphic_allocator< T > > vector
Alias type for vectors with our polymorphic allocator.
Definition vector.hpp:35
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