File indexing completed on 2026-07-26 08:22:02
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <type_traits>
0011 #include <utility>
0012
0013 #include <traccc/definitions/qualifiers.hpp>
0014 #include <traccc/utils/functor.hpp>
0015 #include <vecmem/memory/memory_resource.hpp>
0016 #include <vecmem/memory/unique_ptr.hpp>
0017
0018 namespace traccc {
0019
0020
0021
0022
0023
0024
0025 template <typename... Ts>
0026 struct pod {};
0027
0028 template <>
0029 struct pod<> {};
0030
0031 template <typename T, typename... Ts>
0032 struct pod<T, Ts...> {
0033 static_assert(std::is_standard_layout_v<T> && std::is_trivial_v<T>,
0034 "Types in POD-tuple must each be POD.");
0035
0036 T v;
0037 pod<Ts...> r;
0038 };
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050 template <std::size_t I, typename... Ts>
0051 constexpr auto& pod_get(pod<Ts...>& p) {
0052 if constexpr (I == 0) {
0053 return p.v;
0054 } else {
0055 return pod_get<I - 1>(p.r);
0056 }
0057 }
0058
0059
0060
0061
0062
0063
0064
0065
0066 template <template <typename...> typename F,
0067 template <template <typename> typename> typename T>
0068 struct array_wrapper {
0069 struct owner {
0070 owner(vecmem::memory_resource& mr, std::size_t n) : data(mr, n) {}
0071
0072 typename details::functor::reapply<
0073 F, typename T<details::functor::identity>::tuple_t>::type::owner data;
0074 };
0075
0076 struct handle {
0077 using handle_t = typename details::functor::reapply<
0078 F, typename T<details::functor::identity>::tuple_t>::type::handle;
0079
0080 handle(const owner& o) : data(o.data) {}
0081
0082 TRACCC_HOST_DEVICE std::size_t size() const { return data.size(); }
0083
0084 template <std::size_t I>
0085 constexpr TRACCC_HOST_DEVICE auto& get(std::size_t i) {
0086 return data.get<I>(i);
0087 }
0088
0089 template <std::size_t I>
0090 constexpr TRACCC_HOST_DEVICE auto get(std::size_t i) const {
0091 return data.get<I>(i);
0092 }
0093
0094 template <std::size_t... Ns>
0095 constexpr TRACCC_HOST_DEVICE T<details::functor::identity>
0096 _construct_helper_identity(std::index_sequence<Ns...>,
0097 std::size_t i) const {
0098 return T<details::functor::identity>{get<Ns>(i)...};
0099 }
0100
0101 template <std::size_t... Ns>
0102 constexpr TRACCC_HOST_DEVICE T<details::functor::reference>
0103 _construct_helper_reference(std::index_sequence<Ns...>, std::size_t i) {
0104 return T<details::functor::reference>{get<Ns>(i)...};
0105 }
0106
0107 constexpr TRACCC_HOST_DEVICE T<details::functor::identity> operator[](
0108 std::size_t i) const {
0109 return _construct_helper_identity(
0110 std::make_index_sequence<std::tuple_size_v<
0111 typename T<details::functor::identity>::tuple_t>>(),
0112 i);
0113 }
0114
0115 constexpr TRACCC_HOST_DEVICE T<details::functor::reference> operator[](
0116 std::size_t i) {
0117 return _construct_helper_reference(
0118 std::make_index_sequence<std::tuple_size_v<
0119 typename T<details::functor::identity>::tuple_t>>(),
0120 i);
0121 }
0122
0123 handle_t data;
0124 };
0125 };
0126
0127
0128
0129
0130 template <std::size_t... Ns, typename... Ts>
0131 std::tuple<Ts*...> _get_ptrs(
0132 std::index_sequence<Ns...>,
0133 const std::tuple<vecmem::unique_alloc_ptr<Ts[]>...>& o) {
0134 return {std::get<Ns>(o).get()...};
0135 }
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146 template <typename... Ts>
0147 struct soa {
0148 struct owner {
0149 owner(vecmem::memory_resource& mr, std::size_t n)
0150 : _size(n), _ptrs{vecmem::make_unique_alloc<Ts[]>(mr, n)...} {}
0151
0152 constexpr std::size_t size() const { return _size; }
0153
0154 const std::tuple<vecmem::unique_alloc_ptr<Ts[]>...>& pointers() const {
0155 return _ptrs;
0156 }
0157
0158 private:
0159 std::size_t _size;
0160 std::tuple<vecmem::unique_alloc_ptr<Ts[]>...> _ptrs;
0161 };
0162
0163 struct handle {
0164 private:
0165 using tuple_t = std::tuple<Ts*...>;
0166
0167 public:
0168 handle(const owner& o)
0169 : _size(o.size()),
0170 _ptrs(_get_ptrs(std::make_index_sequence<sizeof...(Ts)>(),
0171 o.pointers())) {}
0172
0173 constexpr TRACCC_HOST_DEVICE std::size_t size() const { return _size; }
0174
0175 template <std::size_t I>
0176 constexpr TRACCC_HOST_DEVICE auto& get(std::size_t i) {
0177 return std::get<I>(_ptrs)[i];
0178 }
0179
0180 template <std::size_t I>
0181 constexpr TRACCC_HOST_DEVICE const auto& get(std::size_t i) const {
0182 return std::get<I>(_ptrs)[i];
0183 }
0184
0185 private:
0186 std::size_t _size;
0187 std::tuple<Ts*...> _ptrs;
0188 };
0189 };
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199 template <typename... Ts>
0200 struct aos {
0201 struct owner {
0202 constexpr owner(vecmem::memory_resource& mr, std::size_t n)
0203 : _size(n), _ptr{vecmem::make_unique_alloc<pod<Ts...>[]>(mr, n)} {}
0204
0205 constexpr std::size_t size() const { return _size; }
0206
0207 constexpr const vecmem::unique_alloc_ptr<pod<Ts...>[]>& pointer() const {
0208 return _ptr;
0209 }
0210
0211 private:
0212 std::size_t _size;
0213 vecmem::unique_alloc_ptr<pod<Ts...>[]> _ptr;
0214 };
0215
0216 struct handle {
0217 private:
0218 using tuple_t = pod<Ts...>;
0219
0220 public:
0221 constexpr handle(const owner& o)
0222 : _size(o.size()), _ptr(o.pointer().get()) {}
0223
0224 constexpr TRACCC_HOST_DEVICE std::size_t size() const { return _size; }
0225
0226 template <std::size_t I>
0227 constexpr TRACCC_HOST_DEVICE auto& get(std::size_t i) {
0228 return pod_get<I>(_ptr[i]);
0229 }
0230
0231 template <std::size_t I>
0232 constexpr TRACCC_HOST_DEVICE const auto& get(std::size_t i) const {
0233 return pod_get<I>(_ptr[i]);
0234 }
0235
0236 private:
0237 std::size_t _size;
0238 tuple_t* _ptr;
0239 };
0240 };
0241 }