vecmem 1.28.0
Loading...
Searching...
No Matches
jagged_vector_buffer.ipp
1/*
2 * VecMem project, part of the ACTS project (R&D line)
3 *
4 * (c) 2021-2026 CERN for the benefit of the ACTS project
5 *
6 * Mozilla Public License Version 2.0
7 */
8#pragma once
9
10// vecmem include(s).
11#include "vecmem/containers/details/aligned_multiple_placement.hpp"
12#include "vecmem/utils/details/narrow_size.hpp"
13
14// System include(s).
15#include <algorithm>
16#include <cassert>
17#include <cstddef>
18#include <memory>
19#include <numeric>
20#include <vector>
21
22namespace {
23
25template <typename TYPE>
28allocate_jagged_buffer_outer_memory(
30 vecmem::memory_resource& resource) {
31
32 if (size == 0) {
33 return nullptr;
34 } else {
37 resource, size);
38 }
39}
40
41} // namespace
42
43namespace vecmem {
44namespace data {
45
50template <typename TYPE>
52
53template <typename TYPE>
54template <typename OTHERTYPE,
55 std::enable_if_t<std::is_convertible<TYPE, OTHERTYPE>::value, bool> >
61
62template <typename TYPE>
63template <typename SIZE_TYPE, typename SIZE_ALLOC,
64 std::enable_if_t<std::is_integral<SIZE_TYPE>::value &&
65 std::is_unsigned<SIZE_TYPE>::value,
66 bool> >
68 const std::vector<SIZE_TYPE, SIZE_ALLOC>& capacities,
69 memory_resource& resource, memory_resource* host_access_resource,
70 buffer_type type)
71 : base_type(vecmem::details::narrow_size<size_type>(capacities.size()),
72 nullptr),
75 ? 0
76 : vecmem::details::narrow_size<size_type>(capacities.size())),
77 resource)),
78 m_outer_host_memory(::allocate_jagged_buffer_outer_memory<TYPE>(
79 vecmem::details::narrow_size<size_type>(capacities.size()),
80 (host_access_resource == nullptr ? resource
82
83 // Determine the allocation size.
85 TYPE>::value_type::size_type;
86 const std::size_t total_elements = std::accumulate(
87 capacities.begin(), capacities.end(), static_cast<std::size_t>(0));
88
89 // Helper pointers to the "inner data".
90 header_t* header_ptr = nullptr;
91 TYPE* data_ptr = nullptr;
92
93 // Allocate the "inner memory" for a fixed size buffer.
94 if (type == buffer_type::fixed_size && total_elements != 0) {
95 m_inner_memory = vecmem::make_unique_alloc<char[]>(
96 resource, total_elements * sizeof(TYPE));
97 data_ptr = reinterpret_cast<TYPE*>(m_inner_memory.get());
98 }
99 // Allocate the "inner memory" for a resizable buffer.
100 else if (type == buffer_type::resizable && capacities.size() != 0) {
101 std::tie(m_inner_memory, header_ptr, data_ptr) =
102 details::aligned_multiple_placement<header_t, TYPE>(
104 }
105
106 // Set up the base object.
108 vecmem::details::narrow_size<size_type>(capacities.size()),
109 ((host_access_resource != nullptr) ? m_outer_memory.get()
110 : m_outer_host_memory.get()),
111 m_outer_host_memory.get()});
112
113 // Set up the vecmem::vector_view objects in the host accessible memory.
114 std::ptrdiff_t ptrdiff = 0;
115 for (std::size_t i = 0; i < capacities.size(); ++i) {
116 if (header_ptr != nullptr) {
118 static_cast<typename value_type::size_type>(capacities[i]),
120 } else {
122 static_cast<typename value_type::size_type>(capacities[i]),
123 data_ptr + ptrdiff);
124 }
125 ptrdiff += capacities[i];
126 }
127}
128
129template <typename TYPE>
130memory_resource* jagged_vector_buffer<TYPE>::resource() const {
131
132 // If we allocated any "main" memory, the return value is simple.
133 if (m_inner_memory) {
134 return m_inner_memory.get_deleter().resource();
135 }
136
137 // Handle the case when we
138 // - use a shared/managed memory resource;
139 // - create a buffer that has all empty inner vectors.
140 if ((this->capacity() != 0) && (!m_outer_memory)) {
141 return m_outer_host_memory.get_deleter().resource();
142 }
143
144 // If we are still here, use whatever is in the outer memory deleter.
145 return m_outer_memory.get_deleter().resource();
146}
147
148template <typename TYPE>
150
151 return m_outer_host_memory.get_deleter().resource();
152}
153
154} // namespace data
155
156template <typename TYPE>
162
163template <typename TYPE>
166
167 return data;
168}
169
170} // namespace vecmem
An allocator class that wraps a memory resource.
Definition allocator.hpp:37
Object owning all the data of a jagged vector.
Definition jagged_vector_buffer.hpp:30
memory_resource * resource() const
Get the main (device-accessible) memory resource used by this buffer.
Definition jagged_vector_buffer.ipp:130
typename base_type::size_type size_type
Use the base class's size_type.
Definition jagged_vector_buffer.hpp:36
memory_resource * host_resource() const
Get the optional, host-accessible memory resource used by this buffer.
Definition jagged_vector_buffer.ipp:149
typename base_type::value_type value_type
Use the base class's value_type.
Definition jagged_vector_buffer.hpp:38
jagged_vector_buffer()
Make sure that the template type does not have a custom destructor.
Definition jagged_vector_buffer.ipp:51
VECMEM_HOST_AND_DEVICE pointer host_ptr() const
Access the host accessible array describing the inner vectors.
Definition jagged_vector_view.ipp:105
VECMEM_HOST_AND_DEVICE jagged_vector_view & operator=(const jagged_vector_view< OTHERTYPE > &rhs)
Assignment operator from a "slightly different" object.
VECMEM_HOST std::vector< typename vector_view< T >::size_type > get_capacities(const jagged_vector_view< T > &data)
Get the capacities of the inner vectors of a jagged vector.
Definition jagged_vector_view.ipp:111
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.
Main namespace for the vecmem classes/functions.
Definition atomic_ref.hpp:16
unique_alloc_ptr< T > make_unique_alloc(memory_resource &m)
Create a unique allocation pointer to a type.
Definition unique_ptr.hpp:185
std::unique_ptr< T, details::unique_alloc_deleter< T > > unique_alloc_ptr
A unique pointer type for trivial types.
Definition unique_ptr.hpp:69
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