17#ifndef dealii_aligned_vector_h
18#define dealii_aligned_vector_h
30#include <boost/version.hpp>
31#if BOOST_VERSION >= 106400
32# include <boost/serialization/array_wrapper.hpp>
34# include <boost/serialization/array.hpp>
36#include <boost/serialization/split_member.hpp>
234 template <
typename ForwardIterator>
438 template <
class Archive>
447 template <
class Archive>
457 template <
class Archive>
568#ifdef DEAL_II_WITH_MPI
577 const bool is_shmem_root,
578 T * aligned_shmem_pointer,
580 MPI_Win shmem_window);
622#ifdef DEAL_II_WITH_MPI
717 template <
typename T>
722 160000 /
sizeof(T) + 1;
756 const std::size_t end)
const override
765 if (std::is_trivial<T>::value ==
true)
767 static_cast<const void *
>(
source_ + begin),
768 (end - begin) *
sizeof(T));
770 for (std::size_t i = begin; i < end; ++i)
786 template <
typename T>
791 160000 /
sizeof(T) + 1;
825 const std::size_t end)
const override
833 if (std::is_trivial<T>::value ==
true)
835 static_cast<void *
>(
source_ + begin),
836 (end - begin) *
sizeof(T));
840 for (std::size_t i = begin; i < end; ++i)
867 template <
typename T,
bool initialize_memory>
871 160000 /
sizeof(T) + 1;
892 if (std::is_trivial<T>::value ==
true &&
893 std::is_same<T, long double>::value ==
false)
895 const unsigned char zero[
sizeof(T)] = {};
899 if (std::memcmp(zero,
900 static_cast<const void *
>(&element),
915 const std::size_t end)
const override
924 (end - begin) *
sizeof(T));
927 begin, end, std::integral_constant<bool, initialize_memory>());
938 const std::size_t end,
939 std::integral_constant<bool, false>)
const
941 for (std::size_t i = begin; i < end; ++i)
948 const std::size_t end,
949 std::integral_constant<bool, true>)
const
951 for (std::size_t i = begin; i < end; ++i)
970 template <
typename T,
bool initialize_memory>
975 160000 /
sizeof(T) + 1;
1000 const std::size_t end)
const override
1006 if (std::is_trivial<T>::value ==
true)
1009 (end - begin) *
sizeof(T));
1012 begin, end, std::integral_constant<bool, initialize_memory>());
1021 const std::size_t end,
1022 std::integral_constant<bool, false>)
const
1024 for (std::size_t i = begin; i < end; ++i)
1031 const std::size_t end,
1032 std::integral_constant<bool, true>)
const
1034 for (std::size_t i = begin; i < end; ++i)
1046template <
typename T>
1048 : deleter_action_object(
nullptr)
1053# ifdef DEAL_II_WITH_MPI
1055template <
typename T>
1057 const bool is_shmem_root,
1058 T * aligned_shmem_pointer,
1060 MPI_Win shmem_window)
1061 : deleter_action_object(
1062 std::make_unique<MPISharedMemDeleterAction>(is_shmem_root,
1063 aligned_shmem_pointer,
1064 shmem_group_communicator,
1071template <
typename T>
1077 if (deleter_action_object ==
nullptr)
1081 Assert(owning_aligned_vector->used_elements_end !=
nullptr,
1084 if (std::is_trivial<T>::value ==
false)
1085 for (T *p = owning_aligned_vector->used_elements_end - 1; p >= ptr;
1094 deleter_action_object->delete_array(owning_aligned_vector, ptr);
1099template <
typename T>
1108# ifdef DEAL_II_WITH_MPI
1110template <
typename T>
1113 T * aligned_shmem_pointer,
1115 MPI_Win shmem_window)
1116 : is_shmem_root(is_shmem_root)
1117 , aligned_shmem_pointer(aligned_shmem_pointer)
1118 , shmem_group_communicator(shmem_group_communicator)
1119 , shmem_window(shmem_window)
1124template <
typename T>
1141 if (std::is_trivial<T>::value ==
false)
1142 for (T *p =
aligned_vector->used_elements_end - 1; p >= ptr; --p)
1159 , allocated_elements_end(
nullptr)
1168 , allocated_elements_end(
nullptr)
1180 , allocated_elements_end(
nullptr)
1184 used_elements_end = allocated_elements_end;
1186 vec.used_elements_end,
1197 *
this = std::move(
vec);
1216 vec.used_elements_end,
1220 used_elements_end = elements.get() +
new_size;
1239 elements = std::move(
vec.elements);
1240 elements.get_deleter().reset_owning_object(
this);
1243 used_elements_end =
vec.used_elements_end;
1244 allocated_elements_end =
vec.allocated_elements_end;
1246 vec.used_elements_end =
nullptr;
1247 vec.allocated_elements_end =
nullptr;
1269 if (std::is_trivial<T>::value ==
false)
1270 for (T *p = used_elements_end - 1; p >= elements.get() +
new_size; --p)
1272 used_elements_end = elements.get() +
new_size;
1278 used_elements_end = elements.get() +
new_size;
1282 if (std::is_trivial<T>::value ==
false)
1305 if (std::is_trivial<T>::value ==
false)
1306 for (T *p = used_elements_end - 1; p >= elements.get() +
new_size; --p)
1308 used_elements_end = elements.get() +
new_size;
1314 used_elements_end = elements.get() +
new_size;
1339 if (std::is_trivial<T>::value ==
false)
1340 for (T *p = used_elements_end - 1; p >= elements.get() +
new_size; --p)
1342 used_elements_end = elements.get() +
new_size;
1348 used_elements_end = elements.get() +
new_size;
1400 used_elements_end = elements.get() +
old_size;
1401 allocated_elements_end = elements.get() +
new_size;
1423 used_elements_end =
nullptr;
1424 allocated_elements_end =
nullptr;
1434 if (used_elements_end == allocated_elements_end)
1436 if (std::is_trivial<T>::value ==
false)
1437 new (used_elements_end++) T(
in_data);
1439 *used_elements_end++ =
in_data;
1449 T *
field = used_elements_end - 1;
1460 const T *
field = used_elements_end - 1;
1467template <
typename ForwardIterator>
1475 if (std::is_trivial<T>::value ==
false)
1476 new (used_elements_end) T;
1477 *used_elements_end = *
begin;
1509# ifdef DEAL_II_WITH_MPI
1530 used_elements_end =
nullptr;
1531 allocated_elements_end =
nullptr;
1568 &shmem_group_communicator);
1579 const bool is_shmem_root =
1615 (is_shmem_root ? 0 : 1),
1636 if (std::is_trivial<T>::value)
1714 MPI_Win shmem_window;
1719 (size() *
sizeof(T) + (
align_by - 1)),
1729 "mpi_minimum_memory_alignment",
1735 shmem_group_communicator,
1763 if (is_shmem_root ==
false)
1790 T * aligned_shmem_pointer =
static_cast<T *
>(
1829 if (std::is_trivial<T>::value ==
true)
1830 std::memcpy(aligned_shmem_pointer, elements.get(),
sizeof(T) * size());
1832 for (std::size_t i = 0; i < size(); ++i)
1833 new (&aligned_shmem_pointer[i]) T(std::move(elements[i]));
1858 elements =
decltype(elements)(aligned_shmem_pointer,
1861 aligned_shmem_pointer,
1862 shmem_group_communicator,
1869 used_elements_end = elements.get() +
new_size;
1870 allocated_elements_end = used_elements_end;
1897 std::swap(elements,
vec.elements);
1898 elements.get_deleter().reset_owning_object(
this);
1899 vec.elements.get_deleter().reset_owning_object(&
vec);
1902 std::swap(used_elements_end,
vec.used_elements_end);
1903 std::swap(allocated_elements_end,
vec.allocated_elements_end);
1912 return used_elements_end == elements.get();
1921 return used_elements_end - elements.get();
1930 return allocated_elements_end - elements.get();
1940 return elements[
index];
1950 return elements[
index];
1955template <
typename T>
1959 return elements.get();
1964template <
typename T>
1968 return elements.get();
1977 return elements.get();
1986 return used_elements_end;
1995 return elements.get();
2004 return used_elements_end;
2010template <
class Archive>
2017 ar &boost::serialization::make_array(elements.get(),
vec_size);
2023template <
class Archive>
2033 ar &boost::serialization::make_array(elements.get(),
vec_size);
2034 used_elements_end = elements.get() +
vec_size;
2045 for (
const T *t = elements.get(); t != used_elements_end; ++t)
2047 memory +=
sizeof(T) * (allocated_elements_end - used_elements_end);
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
virtual ~DeleterActionBase()=default
virtual void delete_array(const AlignedVector< T > *owning_aligned_vector, T *ptr)=0
MPI_Comm shmem_group_communicator
virtual void delete_array(const AlignedVector< T > *aligned_vector, T *ptr)
MPISharedMemDeleterAction(const bool is_shmem_root, T *aligned_shmem_pointer, MPI_Comm shmem_group_communicator, MPI_Win shmem_window)
T * aligned_shmem_pointer
Deleter(AlignedVector< T > *owning_object, const bool is_shmem_root, T *aligned_shmem_pointer, MPI_Comm shmem_group_communicator, MPI_Win shmem_window)
Deleter(AlignedVector< T > *owning_object)
std::unique_ptr< DeleterActionBase > deleter_action_object
void reset_owning_object(const AlignedVector< T > *new_aligned_vector_ptr)
const AlignedVector< T > * owning_aligned_vector
void replicate_across_communicator(const MPI_Comm communicator, const unsigned int root_process)
size_type memory_consumption() const
void resize_fast(const size_type new_size)
std::unique_ptr< T[], Deleter > elements
reference operator[](const size_type index)
void fill(const T &element)
const_iterator end() const
AlignedVector(AlignedVector< T > &&vec) noexcept
void reserve(const size_type new_allocated_size)
void serialize(Archive &archive, const unsigned int version)
bool operator!=(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
const_reference operator[](const size_type index) const
void swap(AlignedVector< T > &vec)
void resize(const size_type new_size, const T &init)
AlignedVector & operator=(AlignedVector< T > &&vec) noexcept
size_type capacity() const
AlignedVector & operator=(const AlignedVector< T > &vec)
const value_type * const_pointer
void push_back(const T in_data)
const_iterator begin() const
AlignedVector(const size_type size, const T &init=T())
T * allocated_elements_end
AlignedVector(const AlignedVector< T > &vec)
const_reference back() const
bool operator==(const AlignedVector< T > &lhs, const AlignedVector< T > &rhs)
const value_type * const_iterator
void resize(const size_type new_size)
void load(Archive &ar, const unsigned int version)
void save(Archive &ar, const unsigned int version) const
void insert_back(ForwardIterator begin, ForwardIterator end)
const value_type & const_reference
const_pointer data() const
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
AlignedVectorCopyConstruct(const T *const source_begin, const T *const source_end, T *const destination)
static const std::size_t minimum_parallel_grain_size
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
void default_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
AlignedVectorDefaultInitialize(const std::size_t size, T *const destination)
static const std::size_t minimum_parallel_grain_size
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, true >) const
static const std::size_t minimum_parallel_grain_size
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
void copy_construct_or_assign(const std::size_t begin, const std::size_t end, std::integral_constant< bool, false >) const
AlignedVectorInitialize(const std::size_t size, const T &element, T *const destination)
static const std::size_t minimum_parallel_grain_size
AlignedVectorMoveConstruct(T *const source_begin, T *const source_end, T *const destination)
virtual void apply_to_subrange(const std::size_t begin, const std::size_t end) const override
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
#define Assert(cond, exc)
#define AssertThrowMPI(error_code)
#define AssertIndexRange(index, range)
static ::ExceptionBase & ExcInternalError()
types::global_dof_index size_type
std::enable_if_t< std::is_fundamental< T >::value, std::size_t > memory_consumption(const T &t)
VectorType::value_type * end(VectorType &V)
VectorType::value_type * begin(VectorType &V)
std::enable_if_t< is_mpi_type< T >==false, T > broadcast(const MPI_Comm comm, const T &object_to_send, const unsigned int root_process=0)
T max(const T &t, const MPI_Comm mpi_communicator)
T min(const T &t, const MPI_Comm mpi_communicator)
unsigned int this_mpi_process(const MPI_Comm mpi_communicator)
void free_communicator(MPI_Comm mpi_communicator)
void posix_memalign(void **memptr, std::size_t alignment, std::size_t size)
size_t pack(const T &object, std::vector< char > &dest_buffer, const bool allow_compression=true)
::VectorizedArray< Number, width > max(const ::VectorizedArray< Number, width > &, const ::VectorizedArray< Number, width > &)
void apply_parallel(const std::size_t begin, const std::size_t end, const std::size_t minimum_parallel_grain_size) const