vecmem 1.21.0
Loading...
Searching...
No Matches
host_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/containers/details/resize_jagged_vector.hpp"
11#include "vecmem/containers/jagged_vector.hpp"
12#include "vecmem/containers/vector.hpp"
13#include "vecmem/edm/details/schema_traits.hpp"
14#include "vecmem/edm/schema.hpp"
15#include "vecmem/memory/memory_resource.hpp"
16
17// System include(s).
18#include <algorithm>
19#include <limits>
20#include <stdexcept>
21#include <tuple>
22#include <type_traits>
23#include <utility>
24
25namespace vecmem::edm::details {
26
29
30template <typename TYPE>
31struct host_type;
32
33template <typename TYPE>
34struct host_type<type::scalar<TYPE>> {
35 using type = vector<TYPE>;
36 using return_type = std::add_lvalue_reference_t<TYPE>;
37 using const_return_type =
38 std::add_lvalue_reference_t<std::add_const_t<TYPE>>;
39}; // struct host_type
40
41template <typename TYPE>
42struct host_type<type::vector<TYPE>> {
43 using type = vector<TYPE>;
44 using return_type = std::add_lvalue_reference_t<type>;
45 using const_return_type =
46 std::add_lvalue_reference_t<std::add_const_t<type>>;
47}; // struct host_type
48
49template <typename TYPE>
52 using return_type = std::add_lvalue_reference_t<type>;
53 using const_return_type =
54 std::add_lvalue_reference_t<std::add_const_t<type>>;
55}; // struct host_type
56
57template <std::size_t INDEX, typename... VARTYPES>
59 using type = typename host_type<typename std::tuple_element<
60 INDEX, std::tuple<VARTYPES...>>::type>::type;
61 using return_type = typename host_type<typename std::tuple_element<
62 INDEX, std::tuple<VARTYPES...>>::type>::return_type;
63 using const_return_type = typename host_type<typename std::tuple_element<
64 INDEX, std::tuple<VARTYPES...>>::type>::const_return_type;
65}; // struct host_type_at
66
68
71
72template <typename TYPE>
73struct host_alloc {
74 static typename host_type<TYPE>::type make(memory_resource& mr) {
75 return typename host_type<TYPE>::type{&mr};
76 }
77}; // struct host_alloc
78
79template <typename TYPE>
80struct host_alloc<type::scalar<TYPE>> {
81 static typename host_type<type::scalar<TYPE>>::type make(
82 memory_resource& mr) {
83 return typename host_type<type::scalar<TYPE>>::type{1, &mr};
84 }
85}; // struct host_alloc
86
88
95template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
96std::size_t get_host_size(
97 const std::tuple<typename host_type<VARTYPES>::type...>& data,
98 std::index_sequence<INDEX, Is...>, std::size_t size = 0,
99 bool size_known = false) {
100
101 // Get the size of this variable.
102 std::size_t var_size = 0;
103 bool var_size_known = false;
104 if constexpr (type::details::is_vector<typename std::tuple_element<
105 INDEX, std::tuple<VARTYPES...>>::type>::value) {
106 var_size = std::get<INDEX>(data).size();
107 var_size_known = true;
108 } else {
109 var_size = size;
110 }
111 // Make sure that it's the same as what has been found before.
112 if (size_known && var_size_known && (var_size != size)) {
113 throw std::length_error(
114 "Inconsistent variable sizes in host container!");
115 }
116 // Terminate, or continue.
117 if constexpr (sizeof...(Is) == 0) {
118 if (!(size_known || var_size_known)) {
119 throw std::length_error(
120 "Could not determine the size of the host container?!?");
121 }
122 return var_size;
123 } else {
124 return get_host_size<VARTYPES...>(data, std::index_sequence<Is...>{},
125 var_size,
126 size_known || var_size_known);
127 }
128}
129
136template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
137std::size_t get_host_capacity(
138 const std::tuple<typename host_type<VARTYPES>::type...>& data,
139 std::index_sequence<INDEX, Is...>,
140 std::size_t capacity = std::numeric_limits<std::size_t>::max(),
141 bool capacity_known = false) {
142
143 // Get the capacity of this variable.
144 if constexpr (type::details::is_vector<typename std::tuple_element<
145 INDEX, std::tuple<VARTYPES...>>::type>::value) {
146 // It's not guaranteed that the capacities of all of the (jagged)
147 // vectors would be the same. So we take the minimum capacity of all
148 // of them.
149 capacity = std::min(std::get<INDEX>(data).capacity(), capacity);
150 capacity_known = true;
151 }
152 // Terminate, or continue.
153 if constexpr (sizeof...(Is) == 0) {
154 if (!capacity_known) {
155 throw std::length_error(
156 "Could not determine the capacity of the host container?!?");
157 }
158 return capacity;
159 } else {
160 return get_host_capacity<VARTYPES...>(
161 data, std::index_sequence<Is...>{}, capacity, capacity_known);
162 }
163}
164
171template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
172void host_resize(std::tuple<typename host_type<VARTYPES>::type...>& data,
173 std::size_t size, std::index_sequence<INDEX, Is...>) {
174
175 // Resize this variable.
176 if constexpr (type::details::is_jagged_vector_v<typename std::tuple_element<
177 INDEX, std::tuple<VARTYPES...>>::type>) {
178 vecmem::details::resize_jagged_vector(std::get<INDEX>(data), size);
179 } else if constexpr (type::details::is_vector_v<typename std::tuple_element<
180 INDEX, std::tuple<VARTYPES...>>::type>) {
181 std::get<INDEX>(data).resize(size);
182 }
183 // Terminate, or continue.
184 if constexpr (sizeof...(Is) > 0) {
185 host_resize<VARTYPES...>(data, size, std::index_sequence<Is...>{});
186 }
187}
188
195template <typename... VARTYPES, std::size_t INDEX, std::size_t... Is>
196void host_reserve(std::tuple<typename host_type<VARTYPES>::type...>& data,
197 std::size_t size, std::index_sequence<INDEX, Is...>) {
198
199 // Resize this variable.
200 if constexpr (type::details::is_vector<typename std::tuple_element<
201 INDEX, std::tuple<VARTYPES...>>::type>::value) {
202 std::get<INDEX>(data).reserve(size);
203 }
204 // Terminate, or continue.
205 if constexpr (sizeof...(Is) > 0) {
206 host_reserve<VARTYPES...>(data, size, std::index_sequence<Is...>{});
207 }
208}
209
210} // namespace vecmem::edm::details
An allocator class that wraps a memory resource.
Definition allocator.hpp:37
Technical base type for data<schema<VARTYPES...>>
Definition data.hpp:25
void resize_jagged_vector(std::vector< std::vector< T, ALLOC1 >, ALLOC2 > &vec, std::size_t size)
Resize a generic jagged vector.
Definition resize_jagged_vector.hpp:23
std::vector< T, vecmem::polymorphic_allocator< T > > vector
Alias type for vectors with our polymorphic allocator.
Definition vector.hpp:35
Definition host_traits.hpp:73
Definition host_traits.hpp:58
Definition host_traits.hpp:31
Definition schema_traits.hpp:90