vecmem 1.14.0
Loading...
Searching...
No Matches
buffer_traits.hpp
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/edm/details/schema_traits.hpp"
11#include "vecmem/edm/details/view_traits.hpp"
12#include "vecmem/edm/schema.hpp"
13#include "vecmem/edm/view.hpp"
14#include "vecmem/memory/unique_ptr.hpp"
15#include "vecmem/utils/tuple.hpp"
16#include "vecmem/utils/types.hpp"
17
18// System include(s).
19#include <array>
20#include <numeric>
21#include <tuple>
22#include <type_traits>
23#include <vector>
24
25namespace vecmem::edm::details {
26
29
30template <typename TYPE>
32
33template <typename TYPE>
34struct buffer_alloc<type::scalar<TYPE> > {
36 template <typename SIZE_TYPE = std::size_t>
37 VECMEM_HOST static std::size_t payload_size(const std::vector<SIZE_TYPE>&) {
38 return 1u;
39 }
41 template <typename SIZE_TYPE = std::size_t>
42 VECMEM_HOST static std::size_t layout_size(const std::vector<SIZE_TYPE>&) {
43 return 0u;
44 }
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) {
52 return ptr;
53 }
54}; // struct buffer_alloc
55
56template <typename TYPE>
57struct buffer_alloc<type::vector<TYPE> > {
59 template <typename SIZE_TYPE = std::size_t>
60 VECMEM_HOST static std::size_t payload_size(
61 const std::vector<SIZE_TYPE>& sizes) {
62 return sizes.size();
63 }
65 template <typename SIZE_TYPE = std::size_t>
66 VECMEM_HOST static std::size_t layout_size(const std::vector<SIZE_TYPE>&) {
67 return 0u;
68 }
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) {
76 return {static_cast<
77 typename view_type<type::vector<TYPE> >::type::size_type>(
78 capacity.size()),
79 size, ptr};
80 }
81}; // struct buffer_alloc
82
83template <typename TYPE>
84struct buffer_alloc<type::jagged_vector<TYPE> > {
86 template <typename SIZE_TYPE = std::size_t>
87 VECMEM_HOST static std::size_t payload_size(
88 const std::vector<SIZE_TYPE>& sizes) {
89 return std::accumulate(sizes.begin(), sizes.end(),
90 static_cast<std::size_t>(0));
91 }
93 template <typename SIZE_TYPE = std::size_t>
94 VECMEM_HOST static std::size_t layout_size(
95 const std::vector<SIZE_TYPE>& sizes) {
96 return sizes.size();
97 }
99 template <typename SIZE_TYPE = std::size_t>
100 VECMEM_HOST static typename view_type<type::jagged_vector<TYPE> >::type
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) {
106
107 // Set up the "layout objects" for use by the view.
108 typename view_type<type::jagged_vector<TYPE> >::layout_ptr used_layout =
109 (host_layout != nullptr ? host_layout : layout);
110 std::ptrdiff_t ptrdiff = 0;
111 for (std::size_t i = 0; i < capacities.size(); ++i) {
112 new (used_layout + i)
113 typename view_type<type::jagged_vector<TYPE> >::layout_type(
114 static_cast<typename view_type<
115 type::jagged_vector<TYPE> >::layout_type::size_type>(
116 capacities[i]),
117 (sizes != nullptr ? &(sizes[i]) : nullptr), ptr + ptrdiff);
118 ptrdiff += capacities[i];
119 }
120
121 // Create the jagged vector view.
122 return {static_cast<
123 typename view_type<type::vector<TYPE> >::type::size_type>(
124 capacities.size()),
125 layout, host_layout};
126 }
127}; // struct buffer_alloc
128
130
132template <typename SIZE_TYPE, typename... TYPES, std::size_t... INDICES>
133VECMEM_HOST auto make_buffer_views(
134 const std::vector<SIZE_TYPE>& sizes,
135 const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
136 const std::tuple<typename view_type<TYPES>::layout_ptr...>& host_layouts,
137 const std::tuple<typename view_type<TYPES>::payload_ptr...>& payloads,
138 std::index_sequence<INDICES...>) {
139
140 return vecmem::make_tuple(buffer_alloc<TYPES>::make_view(
141 sizes, nullptr, std::get<INDICES>(layouts),
142 std::get<INDICES>(host_layouts), std::get<INDICES>(payloads))...);
143}
144
146template <typename SIZE_TYPE, typename... TYPES, std::size_t... INDICES>
147VECMEM_HOST auto make_buffer_views(
148 const std::vector<SIZE_TYPE>& capacities,
149 const std::tuple<typename view_type<TYPES>::size_ptr...>& sizes,
150 const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
151 const std::tuple<typename view_type<TYPES>::layout_ptr...>& host_layouts,
152 const std::tuple<typename view_type<TYPES>::payload_ptr...>& payloads,
153 const std::index_sequence<INDICES...>) {
154
155 // Helper variable(s).
156 constexpr auto is_jagged_vector =
157 std::make_tuple(type::details::is_jagged_vector<TYPES>::value...);
158 constexpr bool has_jagged_vector =
159 std::disjunction_v<type::details::is_jagged_vector<TYPES>...>;
160
161 // The logic here is that if there are any jagged vectors in the schema,
162 // then only the jagged vectors are resizable, the "normal vectors" are not.
163 // But the received "sizes" variable would be hard to set up like that
164 // outside of this function, so the logic has to sit here.
165 return vecmem::make_tuple(buffer_alloc<TYPES>::make_view(
167 ((has_jagged_vector && (!std::get<INDICES>(is_jagged_vector)))
168 ? nullptr
169 : std::get<INDICES>(sizes)),
170 std::get<INDICES>(layouts), std::get<INDICES>(host_layouts),
171 std::get<INDICES>(payloads))...);
172}
173
175template <typename... TYPES, std::size_t INDEX, std::size_t... INDICES>
176VECMEM_HOST constexpr void* find_first_pointer(
177 const std::tuple<TYPES...>& pointers,
178 std::index_sequence<INDEX, INDICES...>) {
179
180 auto ptr = std::get<INDEX>(pointers);
181 if (ptr != nullptr) {
182 return ptr;
183 } else {
184 if constexpr (sizeof...(INDICES) > 0) {
185 return find_first_pointer<TYPES...>(
186 pointers, std::index_sequence<INDICES...>());
187 } else {
188 return nullptr;
189 }
190 }
191}
192
194template <typename... TYPES, std::size_t INDEX, std::size_t... INDICES>
195VECMEM_HOST constexpr void* find_last_pointer(
196 const std::tuple<TYPES...>& pointers,
197 const std::array<std::size_t, sizeof...(TYPES)>& sizes,
198 std::index_sequence<INDEX, INDICES...>) {
199
200 auto ptr = std::get<sizeof...(TYPES) - 1 - INDEX>(pointers);
201 if (ptr != nullptr) {
202 return ptr + std::get<sizeof...(TYPES) - 1 - INDEX>(sizes);
203 } else {
204 if constexpr (sizeof...(INDICES) > 0) {
205 return find_last_pointer<TYPES...>(
206 pointers, sizes, std::index_sequence<INDICES...>());
207 } else {
208 return nullptr;
209 }
210 }
211}
212
214template <typename... TYPES>
215VECMEM_HOST constexpr typename view<schema<TYPES...> >::memory_view_type
216find_layout_view(
217 const std::tuple<typename view_type<TYPES>::layout_ptr...>& layouts,
218 const std::array<std::size_t, sizeof...(TYPES)>& sizes) {
219
220 // The result type.
221 using result_type = typename view<schema<TYPES...> >::memory_view_type;
222
223 // Find the first non-zero pointer.
224 typename result_type::pointer ptr =
225 reinterpret_cast<typename result_type::pointer>(
226 find_first_pointer(layouts, std::index_sequence_for<TYPES...>()));
227 // Find the last non-zero pointer.
228 typename result_type::pointer end_ptr =
229 reinterpret_cast<typename result_type::pointer>(find_last_pointer(
230 layouts, sizes, std::index_sequence_for<TYPES...>()));
231
232 // Construct the result.
233 return {static_cast<typename result_type::size_type>(end_ptr - ptr), ptr};
234}
235
237template <typename... TYPES>
238VECMEM_HOST constexpr typename view<schema<TYPES...> >::memory_view_type
239find_payload_view(
240 const std::tuple<typename view_type<TYPES>::payload_ptr...>& payloads,
241 const std::array<std::size_t, sizeof...(TYPES)>& sizes) {
242
243 // The result type.
244 using result_type = typename view<schema<TYPES...> >::memory_view_type;
245
246 // Find the first non-zero pointer.
247 typename result_type::pointer ptr =
248 reinterpret_cast<typename result_type::pointer>(
249 find_first_pointer(payloads, std::index_sequence_for<TYPES...>()));
250 // Find the last non-zero pointer.
251 typename result_type::pointer end_ptr =
252 reinterpret_cast<typename result_type::pointer>(find_last_pointer(
253 payloads, sizes, std::index_sequence_for<TYPES...>()));
254
255 // Construct the result.
256 return {static_cast<typename result_type::size_type>(end_ptr - ptr), ptr};
257}
258
259} // namespace vecmem::edm::details
vector< vector< T > > jagged_vector
Alias type for jagged vectors with our polymorphic allocator.
Definition jagged_vector.hpp:30
VECMEM_HOST_AND_DEVICE constexpr tuple< typename std::decay< Ts >::type... > make_tuple(Ts &&... args)
Make a tuple with automatic type deduction.
Definition tuple.ipp:88
VECMEM_HOST_AND_DEVICE constexpr const auto & get(const tuple< Ts... > &t) noexcept
Get a constant element out of a tuple.
Definition tuple.ipp:58
std::vector< T, vecmem::polymorphic_allocator< T > > vector
Alias type for vectors with our polymorphic allocator.
Definition vector.hpp:35
static VECMEM_HOST view_type< type::jagged_vector< TYPE > >::type make_view(const std::vector< SIZE_TYPE > &capacities, unsigned int *sizes, typename view_type< type::jagged_vector< TYPE > >::layout_ptr layout, typename view_type< type::jagged_vector< TYPE > >::layout_ptr host_layout, typename view_type< type::jagged_vector< TYPE > >::payload_ptr ptr)
Construct a view for a jagged vector variable.
Definition buffer_traits.hpp:101
static VECMEM_HOST std::size_t layout_size(const std::vector< SIZE_TYPE > &sizes)
The number of "layout meta-objects" to allocate for the payload.
Definition buffer_traits.hpp:94
static VECMEM_HOST std::size_t payload_size(const std::vector< SIZE_TYPE > &sizes)
The number of TYPE elements to allocate for the payload.
Definition buffer_traits.hpp:87
static VECMEM_HOST view_type< type::scalar< TYPE > >::type make_view(const std::vector< SIZE_TYPE > &, unsigned int *, typename view_type< type::scalar< TYPE > >::layout_ptr, typename view_type< type::scalar< TYPE > >::layout_ptr, typename view_type< type::scalar< TYPE > >::payload_ptr ptr)
Construct a view for a scalar variable.
Definition buffer_traits.hpp:47
static VECMEM_HOST std::size_t payload_size(const std::vector< SIZE_TYPE > &)
The number of TYPE elements to allocate for the payload.
Definition buffer_traits.hpp:37
static VECMEM_HOST std::size_t layout_size(const std::vector< SIZE_TYPE > &)
The number of "layout meta-objects" to allocate for the payload.
Definition buffer_traits.hpp:42
static VECMEM_HOST std::size_t payload_size(const std::vector< SIZE_TYPE > &sizes)
The number of TYPE elements to allocate for the payload.
Definition buffer_traits.hpp:60
static VECMEM_HOST view_type< type::vector< TYPE > >::type make_view(const std::vector< SIZE_TYPE > &capacity, unsigned int *size, typename view_type< type::vector< TYPE > >::layout_ptr, typename view_type< type::vector< TYPE > >::layout_ptr, typename view_type< type::vector< TYPE > >::payload_ptr ptr)
Construct a view for a vector variable.
Definition buffer_traits.hpp:71
static VECMEM_HOST std::size_t layout_size(const std::vector< SIZE_TYPE > &)
The number of "layout meta-objects" to allocate for the payload.
Definition buffer_traits.hpp:66
Definition buffer_traits.hpp:31
Definition view_traits.hpp:33
1D vector variable
Definition schema.hpp:26