1 #ifndef AMREX_PODVECTOR_H_
2 #define AMREX_PODVECTOR_H_
3 #include <AMReX_Config.H>
14 #include <type_traits>
23 template <
typename T,
typename Size,
template<
class>
class Allocator>
25 Allocator<T>& allocator)
28 return allocator.allocate_in_place(p, nmin, nmax);
30 T* pnew = allocator.allocate(nmax);
35 template <
typename T,
typename Size,
template<
class>
class Allocator>
39 return allocator.shrink_in_place(p, n);
41 return allocator.allocate(n);
45 template <
typename T,
typename Size,
template<
class>
class Allocator>
47 [[maybe_unused]] Allocator<T>
const& allocator)
50 if constexpr (
RunOnGpu<Allocator<T>>::value)
60 if (allocator.arena()->isManaged() ||
61 allocator.arena()->isDevice())
72 std::uninitialized_fill_n(data, count, value);
75 template <
typename T,
template<
class>
class Allocator>
77 [[maybe_unused]] Allocator<T>
const & allocator)
79 auto count = list.size() *
sizeof(T);
81 if constexpr (
RunOnGpu<Allocator<T>>::value)
89 if (allocator.arena()->isManaged() ||
90 allocator.arena()->isDevice())
101 template <
typename T,
typename Size,
template<
class>
class Allocator>
103 [[maybe_unused]] Allocator<T>
const& allocator)
106 if constexpr (
RunOnGpu<Allocator<T>>::value)
116 if (allocator.arena()->isManaged() ||
117 allocator.arena()->isDevice())
128 static_assert(
RunOnGpu<Allocator<T>>::value ==
false);
130 if constexpr (!
RunOnGpu<Allocator<T>>::value) {
131 for (Size i = 0; i < count; ++i) { dst[i] = src[i]; }
135 template <
typename Allocator>
137 [[maybe_unused]] Allocator
const& dst_allocator,
138 [[maybe_unused]] Allocator
const& src_allocator,
139 [[maybe_unused]]
bool sync =
true)
150 bool dst_on_device = dst_allocator.arena()->isManaged() ||
151 dst_allocator.arena()->isDevice();
152 bool src_on_device = src_allocator.arena()->isManaged() ||
153 src_allocator.arena()->isDevice();
154 if (dst_on_device || src_on_device)
156 if (dst_on_device && src_on_device) {
158 }
else if (dst_on_device) {
171 template <
typename Allocator>
173 [[maybe_unused]] Allocator
const& allocator)
187 if (allocator.arena()->isManaged() ||
188 allocator.arena()->isDevice())
199 std::memmove(dst, src, count);
202 template <
typename T,
typename Size,
template<
class>
class Allocator>
206 if constexpr (std::is_same_v<
float, std::remove_cv_t<T>> ||
207 std::is_same_v<
double, std::remove_cv_t<T>>) {
210 if constexpr (
RunOnGpu<Allocator<T>>::value) {
211 amrex::fill_snan<RunOn::Device>(data, count);
215 if (allocator.arena()->isManaged() ||
216 allocator.arena()->isDevice())
218 amrex::fill_snan<RunOn::Device>(data, count);
224 amrex::fill_snan<RunOn::Host>(data, count);
230 namespace VectorGrowthStrategy
244 template <
class T,
class Allocator = std::allocator<T> >
248 static_assert(std::is_trivially_copyable<T>(),
"PODVector can only hold trivially copyable types");
251 using Allocator::allocate;
252 using Allocator::deallocate;
278 : Allocator(a_allocator)
297 (Allocator
const&)(*
this));
303 : Allocator(a_allocator),
307 if (a_initializer_list.size() != 0) {
310 (Allocator
const&)(*
this));
315 : Allocator(a_vector),
319 if (a_vector.
size() != 0) {
322 (Allocator
const&)(*
this),
323 (Allocator
const&)a_vector);
328 : Allocator(
static_cast<Allocator&&
>(a_vector)),
333 a_vector.m_data =
nullptr;
335 a_vector.m_capacity = 0;
341 static_assert(std::is_same<Allocator,std::allocator<T>>::value ||
350 if (
this == &a_vector) {
return *
this; }
352 if ((Allocator
const&)(*
this) != (Allocator
const&)a_vector) {
359 (Allocator&)(*
this) = (Allocator
const&)a_vector;
362 const auto other_size = a_vector.
size();
371 (Allocator
const&)(*
this),
372 (Allocator
const&)a_vector);
379 if (
this == &a_vector) {
return *
this; }
381 if (
static_cast<Allocator const&
>(a_vector) ==
382 static_cast<Allocator const&
>(*
this))
392 a_vector.m_data =
nullptr;
394 a_vector.m_capacity = 0;
407 auto* pos =
const_cast<iterator>(a_pos);
410 (Allocator
const&)(*
this));
416 size_type num_to_erase = a_last - a_first;
417 auto* first =
const_cast<iterator>(a_first);
418 if (num_to_erase > 0) {
421 (Allocator
const&)(*
this));
428 return insert(a_pos, 1, a_item);
433 auto* pos =
const_cast<iterator>(a_pos);
437 std::size_t insert_index = std::distance(
m_data, pos);
439 pos =
m_data + insert_index;
444 (Allocator
const&)(*
this));
448 (Allocator
const&)(*
this));
456 return insert(a_pos, 1, std::move(a_item));
460 std::initializer_list<T> a_initializer_list)
462 auto* pos =
const_cast<iterator>(a_pos);
463 size_type count = a_initializer_list.size();
467 std::size_t insert_index = std::distance(
m_data, pos);
469 pos =
m_data + insert_index;
474 (Allocator
const&)(*
this));
478 (Allocator
const&)(*
this));
483 template <class InputIt, class bar = typename std::iterator_traits<InputIt>::difference_type>
486 auto* pos =
const_cast<iterator>(a_pos);
487 size_type count = std::distance(a_first, a_last);
491 std::size_t insert_index = std::distance(
m_data, pos);
493 pos =
m_data + insert_index;
498 (Allocator
const&)(*
this));
505 (Allocator
const&)(*
this));
518 (Allocator
const&)(*
this));
521 void assign (std::initializer_list<T> a_initializer_list)
525 reserve(a_initializer_list.size());
527 m_size = a_initializer_list.size();
529 (Allocator
const&)(*
this));
532 template <class InputIt, class bar = typename std::iterator_traits<InputIt>::difference_type>
533 void assign (InputIt a_first, InputIt a_last)
535 std::size_t count = std::distance(a_first, a_last);
542 (Allocator
const&)(*
this));
563 (Allocator
const&)(*
this));
579 [[nodiscard]]
bool empty () const noexcept {
return m_size == 0; }
587 [[nodiscard]]
const T&
front () const noexcept {
return *
m_data; }
595 [[nodiscard]]
const T*
data () const noexcept {
return m_data; }
629 if (old_size < a_new_size) {
631 m_size - old_size, (Allocator
const&)(*
this));
639 if (old_size < a_new_size)
643 (Allocator
const&)(*
this));
651 (Allocator&)(*
this));
665 (Allocator&)(*
this));
668 (Allocator
const&)(*
this),
669 (Allocator
const&)(*
this));
682 std::swap(
static_cast<Allocator&
>(a_vector),
static_cast<Allocator&
>(*
this));
709 auto* new_data = fp.
ptr();
710 auto new_capacity = fp.
size();
714 (Allocator
const&)(*
this),
715 (Allocator
const&)(*
this));
728 (Allocator&)(*
this));
740 (Allocator&)(*
this));
741 auto* new_data = fp.ptr();
742 new_capacity = fp.size();
748 (
m_size-a_index)*
sizeof(T),
749 (Allocator
const&)(*
this));
755 (Allocator
const&)(*
this),
756 (Allocator
const&)(*
this),
false);
760 (
m_size-a_index)*
sizeof(T),
761 (Allocator
const&)(*
this),
762 (Allocator
const&)(*
this),
false);
#define AMREX_EXPORT
Definition: AMReX_Extension.H:191
#define AMREX_GPU_DEVICE
Definition: AMReX_GpuQualifiers.H:18
virtual void free(void *pt)=0
A pure virtual function for deleting the arena pointed to by pt.
virtual void * alloc(std::size_t sz)=0
static void streamSynchronize() noexcept
Definition: AMReX_GpuDevice.cpp:641
Definition: AMReX_PODVector.H:246
PODVector(std::initializer_list< T > a_initializer_list, const allocator_type &a_allocator=Allocator())
Definition: AMReX_PODVector.H:301
iterator insert(const_iterator a_pos, T &&a_item)
Definition: AMReX_PODVector.H:453
const_iterator begin() const noexcept
Definition: AMReX_PODVector.H:603
void resize_without_init_snan(size_type a_new_size)
Definition: AMReX_PODVector.H:774
const_iterator cbegin() const noexcept
Definition: AMReX_PODVector.H:617
iterator insert(const_iterator a_pos, const T &a_item)
Definition: AMReX_PODVector.H:426
iterator erase(const_iterator a_pos)
Definition: AMReX_PODVector.H:405
void reserve(size_type a_capacity)
Definition: AMReX_PODVector.H:647
iterator insert(const_iterator a_pos, size_type a_count, const T &a_value)
Definition: AMReX_PODVector.H:431
size_type size() const noexcept
Definition: AMReX_PODVector.H:575
const T * const_pointer
Definition: AMReX_PODVector.H:266
void swap(PODVector< T, Allocator > &a_vector) noexcept
Definition: AMReX_PODVector.H:677
const T & front() const noexcept
Definition: AMReX_PODVector.H:587
void UpdateDataPtr(FatPtr< T > const &fp)
Definition: AMReX_PODVector.H:707
const_reverse_iterator crbegin() const noexcept
Definition: AMReX_PODVector.H:621
T & back() noexcept
Definition: AMReX_PODVector.H:589
PODVector(const PODVector< T, Allocator > &a_vector)
Definition: AMReX_PODVector.H:314
std::reverse_iterator< iterator > reverse_iterator
Definition: AMReX_PODVector.H:263
T * pointer
Definition: AMReX_PODVector.H:261
void shrink_to_fit()
Definition: AMReX_PODVector.H:656
void assign(const T &a_value)
Definition: AMReX_PODVector.H:549
void pop_back() noexcept
Definition: AMReX_PODVector.H:571
size_type nBytes() const noexcept
Definition: AMReX_PODVector.H:687
iterator insert(const_iterator a_pos, std::initializer_list< T > a_initializer_list)
Definition: AMReX_PODVector.H:459
iterator insert(const_iterator a_pos, InputIt a_first, InputIt a_last)
Definition: AMReX_PODVector.H:484
T * data() noexcept
Definition: AMReX_PODVector.H:593
T & operator[](size_type a_index) noexcept
Definition: AMReX_PODVector.H:581
T * iterator
Definition: AMReX_PODVector.H:262
void AllocateBufferForPush(size_type target_capacity)
Definition: AMReX_PODVector.H:725
size_type GetNewCapacityForPush() const noexcept
Definition: AMReX_PODVector.H:693
reverse_iterator rend() noexcept
Definition: AMReX_PODVector.H:613
PODVector(size_type a_size)
Definition: AMReX_PODVector.H:281
allocator_type get_allocator() const noexcept
Definition: AMReX_PODVector.H:554
iterator begin() noexcept
Definition: AMReX_PODVector.H:601
const T * data() const noexcept
Definition: AMReX_PODVector.H:595
PODVector & operator=(const PODVector< T, Allocator > &a_vector)
Definition: AMReX_PODVector.H:348
void assign(std::initializer_list< T > a_initializer_list)
Definition: AMReX_PODVector.H:521
iterator end() noexcept
Definition: AMReX_PODVector.H:605
T value_type
Definition: AMReX_PODVector.H:255
constexpr PODVector() noexcept=default
void assign(size_type a_count, const T &a_value)
Definition: AMReX_PODVector.H:510
const_reverse_iterator rbegin() const noexcept
Definition: AMReX_PODVector.H:611
std::size_t size_type
Definition: AMReX_PODVector.H:257
const T & back() const noexcept
Definition: AMReX_PODVector.H:591
const_reverse_iterator rend() const noexcept
Definition: AMReX_PODVector.H:615
size_type m_size
Definition: AMReX_PODVector.H:272
void assign(InputIt a_first, InputIt a_last)
Definition: AMReX_PODVector.H:533
pointer m_data
Definition: AMReX_PODVector.H:271
const_reverse_iterator crend() const noexcept
Definition: AMReX_PODVector.H:623
reverse_iterator rbegin() noexcept
Definition: AMReX_PODVector.H:609
iterator erase(const_iterator a_first, const_iterator a_last)
Definition: AMReX_PODVector.H:414
void clear() noexcept
Definition: AMReX_PODVector.H:573
size_type capacity() const noexcept
Definition: AMReX_PODVector.H:577
const_iterator cend() const noexcept
Definition: AMReX_PODVector.H:619
size_type m_capacity
Definition: AMReX_PODVector.H:272
PODVector(PODVector< T, Allocator > &&a_vector) noexcept
Definition: AMReX_PODVector.H:327
T & reference
Definition: AMReX_PODVector.H:260
const T * const_iterator
Definition: AMReX_PODVector.H:267
void resize(size_type a_new_size)
Definition: AMReX_PODVector.H:625
~PODVector()
Definition: AMReX_PODVector.H:338
const_iterator end() const noexcept
Definition: AMReX_PODVector.H:607
const T & const_reference
Definition: AMReX_PODVector.H:265
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: AMReX_PODVector.H:268
const T * dataPtr() const noexcept
Definition: AMReX_PODVector.H:599
T & front() noexcept
Definition: AMReX_PODVector.H:585
void resize(size_type a_new_size, const T &a_val)
Definition: AMReX_PODVector.H:635
std::ptrdiff_t difference_type
Definition: AMReX_PODVector.H:258
T * dataPtr() noexcept
Definition: AMReX_PODVector.H:597
PODVector(size_type a_size, const value_type &a_value, const allocator_type &a_allocator=Allocator())
Definition: AMReX_PODVector.H:290
bool empty() const noexcept
Definition: AMReX_PODVector.H:579
void AllocateBufferForInsert(size_type a_index, size_type a_count)
Definition: AMReX_PODVector.H:735
void push_back(const T &a_value)
Definition: AMReX_PODVector.H:556
Allocator allocator_type
Definition: AMReX_PODVector.H:256
void dtod_memcpy_async(void *p_d_dst, const void *p_d_src, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:279
void streamSynchronize() noexcept
Definition: AMReX_GpuDevice.H:237
void dtoh_memcpy_async(void *p_h, const void *p_d, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:265
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void * memcpy(void *dest, const void *src, std::size_t count)
Definition: AMReX_GpuUtility.H:214
void htod_memcpy_async(void *p_d, const void *p_h, const std::size_t sz) noexcept
Definition: AMReX_GpuDevice.H:251
void ValidateUserInput()
Definition: AMReX_PODVector.cpp:15
Real growth_factor
Definition: AMReX_PODVector.cpp:7
void Initialize()
Definition: AMReX_PODVector.cpp:34
Real GetGrowthFactor()
Definition: AMReX_PODVector.H:233
void SetGrowthFactor(Real a_factor)
Definition: AMReX_PODVector.cpp:41
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition: AMReX_algoim_K.H:113
@ max
Definition: AMReX_ParallelReduce.H:17
FatPtr< T > allocate_in_place([[maybe_unused]] T *p, [[maybe_unused]] Size nmin, Size nmax, Allocator< T > &allocator)
Definition: AMReX_PODVector.H:24
void memCopyImpl(void *dst, const void *src, std::size_t count, [[maybe_unused]] Allocator const &dst_allocator, [[maybe_unused]] Allocator const &src_allocator, [[maybe_unused]] bool sync=true)
Definition: AMReX_PODVector.H:136
void uninitializedFillNImpl(T *data, Size count, const T &value, [[maybe_unused]] Allocator< T > const &allocator)
Definition: AMReX_PODVector.H:46
void initFromListImpl(T *data, std::initializer_list< T > const &list, [[maybe_unused]] Allocator< T > const &allocator)
Definition: AMReX_PODVector.H:76
T * shrink_in_place([[maybe_unused]] T *p, Size n, Allocator< T > &allocator)
Definition: AMReX_PODVector.H:36
void maybe_init_snan(T *data, Size count, Allocator< T > const &allocator)
Definition: AMReX_PODVector.H:203
void fillValuesImpl(T *dst, T const *src, Size count, [[maybe_unused]] Allocator< T > const &allocator)
Definition: AMReX_PODVector.H:102
void memMoveImpl(void *dst, const void *src, std::size_t count, [[maybe_unused]] Allocator const &allocator)
Definition: AMReX_PODVector.H:172
Definition: AMReX_Amr.cpp:49
std::enable_if_t< std::is_integral_v< T > > ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition: AMReX_CTOParallelForImpl.H:200
bool InitSNaN() noexcept
Definition: AMReX.cpp:168
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void ignore_unused(const Ts &...)
This shuts up the compiler about unused variables.
Definition: AMReX.H:111
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE std::enable_if_t< std::is_floating_point_v< T >, bool > almostEqual(T x, T y, int ulp=2)
Definition: AMReX_Algorithm.H:93
Arena * The_Arena()
Definition: AMReX_Arena.cpp:609
Definition: AMReX_FabArrayCommI.H:896
Definition: AMReX_GpuAllocators.H:24
constexpr T * ptr() const noexcept
Definition: AMReX_GpuAllocators.H:27
constexpr std::size_t size() const noexcept
Definition: AMReX_GpuAllocators.H:28
Definition: AMReX_GpuAllocators.H:161
Definition: AMReX_GpuAllocators.H:172
Definition: AMReX_GpuAllocators.H:158