Reference documentation for deal.II version 9.4.1
|
#include <deal.II/base/aligned_vector.h>
Classes | |
class | Deleter |
Public Types | |
using | value_type = T |
using | pointer = value_type * |
using | const_pointer = const value_type * |
using | iterator = value_type * |
using | const_iterator = const value_type * |
using | reference = value_type & |
using | const_reference = const value_type & |
using | size_type = std::size_t |
Public Member Functions | |
AlignedVector () | |
AlignedVector (const size_type size, const T &init=T()) | |
~AlignedVector ()=default | |
AlignedVector (const AlignedVector< T > &vec) | |
AlignedVector (AlignedVector< T > &&vec) noexcept | |
AlignedVector & | operator= (const AlignedVector< T > &vec) |
AlignedVector & | operator= (AlignedVector< T > &&vec) noexcept |
void | resize_fast (const size_type new_size) |
void | resize (const size_type new_size) |
void | resize (const size_type new_size, const T &init) |
void | reserve (const size_type new_allocated_size) |
void | clear () |
void | push_back (const T in_data) |
reference | back () |
const_reference | back () const |
template<typename ForwardIterator > | |
void | insert_back (ForwardIterator begin, ForwardIterator end) |
void | fill () |
void | fill (const T &element) |
void | replicate_across_communicator (const MPI_Comm &communicator, const unsigned int root_process) |
void | swap (AlignedVector< T > &vec) |
bool | empty () const |
size_type | size () const |
size_type | capacity () const |
reference | operator[] (const size_type index) |
const_reference | operator[] (const size_type index) const |
pointer | data () |
const_pointer | data () const |
iterator | begin () |
iterator | end () |
const_iterator | begin () const |
const_iterator | end () const |
size_type | memory_consumption () const |
template<class Archive > | |
void | save (Archive &ar, const unsigned int version) const |
template<class Archive > | |
void | load (Archive &ar, const unsigned int version) |
template<class Archive > | |
void | serialize (Archive &archive, const unsigned int version) |
Private Attributes | |
std::unique_ptr< T[], Deleter > | elements |
T * | used_elements_end |
T * | allocated_elements_end |
Related Functions | |
(Note that these are not member functions.) | |
template<class T > | |
bool | operator== (const AlignedVector< T > &lhs, const AlignedVector< T > &rhs) |
template<class T > | |
bool | operator!= (const AlignedVector< T > &lhs, const AlignedVector< T > &rhs) |
This is a replacement class for std::vector to be used in combination with VectorizedArray and derived data types. It allocates memory aligned to addresses of a vectorized data type (in order to avoid segmentation faults when a variable of type VectorizedArray which the compiler assumes to be aligned to certain memory addresses does not actually follow these rules). This could also be achieved by proving std::vector with a user-defined allocator. On the other hand, writing an own small vector class lets us implement parallel copy and move operations with TBB, insert deal.II-style assertions, and cut some unnecessary functionality. Note that this vector is a bit more memory-consuming than std::vector because of alignment, so it is recommended to only use this vector on long vectors.
Definition at line 61 of file aligned_vector.h.
using AlignedVector< T >::value_type = T |
Declare standard types used in all containers. These types parallel those in the C++
standard libraries vector<...>
class.
Definition at line 68 of file aligned_vector.h.
using AlignedVector< T >::pointer = value_type * |
Definition at line 69 of file aligned_vector.h.
using AlignedVector< T >::const_pointer = const value_type * |
Definition at line 70 of file aligned_vector.h.
using AlignedVector< T >::iterator = value_type * |
Definition at line 71 of file aligned_vector.h.
using AlignedVector< T >::const_iterator = const value_type * |
Definition at line 72 of file aligned_vector.h.
using AlignedVector< T >::reference = value_type & |
Definition at line 73 of file aligned_vector.h.
using AlignedVector< T >::const_reference = const value_type & |
Definition at line 74 of file aligned_vector.h.
using AlignedVector< T >::size_type = std::size_t |
Definition at line 75 of file aligned_vector.h.
AlignedVector< T >::AlignedVector | ( | ) |
Empty constructor. Sets the vector size to zero.
|
explicit |
Set the vector size to the given size and initializes all elements with T().
|
default |
Destructor.
AlignedVector< T >::AlignedVector | ( | const AlignedVector< T > & | vec | ) |
Copy constructor.
|
noexcept |
Move constructor. Create a new aligned vector by stealing the contents of vec
.
AlignedVector & AlignedVector< T >::operator= | ( | const AlignedVector< T > & | vec | ) |
Assignment to the input vector vec
.
|
noexcept |
Move assignment operator.
void AlignedVector< T >::resize_fast | ( | const size_type | new_size | ) |
Change the size of the vector. If the new size is larger than the previous size, then new elements will be added to the end of the vector; these elements will remain uninitialized (i.e., left in an undefined state) if std::is_trivial<T>
is true
, and will be default initialized if std::is_trivial<T>
is false
. See here for a definition of what std::is_trivial
does.
If the new size is less than the previous size, then the last few elements will be destroyed if std::is_trivial<T>
will be false
or will simply be ignored in the future if std::is_trivial<T>
is true
.
As a consequence of the outline above, the "_fast" suffix of this function refers to the fact that for "trivial" classes T
, this function omits constructor/destructor calls and in particular the initialization of new elements.
T
that define a default constructor, T()
. Otherwise, compilation will fail. void AlignedVector< T >::resize | ( | const size_type | new_size | ) |
Change the size of the vector. It keeps old elements previously available, and initializes each newly added element to a default-constructed object of type T
.
If the new vector size is shorter than the old one, the memory is not immediately released unless the new size is zero; however, the size of the current object is of course set to the requested value. The destructors of released elements are also called.
void AlignedVector< T >::resize | ( | const size_type | new_size, |
const T & | init | ||
) |
Change the size of the vector. It keeps old elements previously available, and initializes each newly added element with the provided initializer.
If the new vector size is shorter than the old one, the memory is not immediately released unless the new size is zero; however, the size of the current object is of course set to the requested value.
void AlignedVector< T >::reserve | ( | const size_type | new_allocated_size | ) |
Reserve memory space for new_allocated_size
elements.
If the argument new_allocated_size
is less than the current number of stored elements (as indicated by calling size()), then this function does not do anything at all. Except if the argument new_allocated_size
is set to zero, then all previously allocated memory is released (this operation then being equivalent to directly calling the clear() function).
In order to avoid too frequent reallocation (which involves copy of the data), this function doubles the amount of memory occupied when the given size is larger than the previously allocated size.
Note that this function only changes the amount of elements the object can store, but not the number of elements it actually stores. As a consequence, no constructors or destructors of newly created objects are run, though the existing elements may be moved to a new location (which involves running the move constructor at the new location and the destructor at the old location).
void AlignedVector< T >::clear | ( | ) |
Releases all previously allocated memory and leaves the vector in a state equivalent to the state after the default constructor has been called.
void AlignedVector< T >::push_back | ( | const T | in_data | ) |
Inserts an element at the end of the vector, increasing the vector size by one. Note that the allocated size will double whenever the previous space is not enough to hold the new element.
reference AlignedVector< T >::back | ( | ) |
Return the last element of the vector (read and write access).
const_reference AlignedVector< T >::back | ( | ) | const |
Return the last element of the vector (read-only access).
void AlignedVector< T >::insert_back | ( | ForwardIterator | begin, |
ForwardIterator | end | ||
) |
Inserts several elements at the end of the vector given by a range of elements.
void AlignedVector< T >::fill | ( | ) |
Fills the vector with size() copies of a default constructed object.
void AlignedVector< T >::fill | ( | const T & | element | ) |
Fills the vector with size() copies of the given input.
void AlignedVector< T >::replicate_across_communicator | ( | const MPI_Comm & | communicator, |
const unsigned int | root_process | ||
) |
This function replicates the state found on the process indicated by root_process
across all processes of the MPI communicator. The current state found on any of the processes other than root_process
is lost in this process. One can imagine this operation to act like a call to Utilities::MPI::broadcast() from the root process to all other processes, though in practice the function may try to move the data into shared memory regions on each of the machines that host MPI processes and let all MPI processes on this machine then access this shared memory region instead of keeping their own copy.
The intent of this function is to quickly exchange large arrays from one process to others, rather than having to compute or create it on all processes. This is specifically the case for data loaded from disk – say, large data tables – that are more easily dealt with by reading once and then distributing across all processes in an MPI universe, than letting each process read the data from disk itself. Specifically, the use of shared memory regions allows for replicating the data only once per multicore machine in the MPI universe, rather than replicating data once for each MPI process. This results in large memory savings if the data is large on today's machines that can easily house several dozen MPI processes per shared memory space. This use case is outlined in the TableBase class documentation as the current function is called from TableBase::replicate_across_communicator(). Indeed, the primary rationale for this function is to enable sharing data tables based on TableBase across MPI processes.
This function does not imply a model of keeping data on different processes in sync, as LinearAlgebra::distributed::Vector and other vector classes do where there exists a notion of certain elements of the vector owned by each process and possibly ghost elements that are mirrored from its owning process to other processes. Rather, the elements of the current object are simply copied to the other processes, and it is useful to think of this operation as creating a set of const
AlignedVector objects on all processes that should not be changed any more after the replication operation, as this is the only way to ensure that the vectors remain the same on all processes. This is particularly true because of the use of shared memory regions where any modification of a vector element on one MPI process may also result in a modification of elements visible on other processes, assuming they are located within one shared memory node.
communicator
object, which is generally an expensive operation. Likewise, the generation of shared memory spaces is not a cheap operation. As a consequence, this function primarily makes sense when the goal is to share large read-only data tables among processes; examples are data tables that are loaded at start-up time and then used over the course of the run time of the program. In such cases, the start-up cost of running this function can be amortized over time, and the potential memory savings from not having to store the table on each process may be substantial on machines with large core counts on which many MPI processes run on the same machine.T
is "self-contained", i.e., all if its information is stored in its member variables, and if none of the member variables are pointers to other parts of the memory. This is because if a type T
does have pointers to other parts of memory, then moving T
into a shared memory space does not result in the other processes having access to data that the object points to with its member variable pointers: These continue to live only on one process, and are typically in memory areas not accessible to the other processes. As a consequence, the usual use case for this function is to share arrays of simple objects such as double
s or int
s.root_process
throw away their data, which is not a collective operation. Generally, these restrictions on what can and can not be done hint at the correctness of the comments above: You should treat an AlignedVector on which the current function has been called as const
, on which no further operations can be performed until the destructor is called. void AlignedVector< T >::swap | ( | AlignedVector< T > & | vec | ) |
Swaps the given vector with the calling vector.
bool AlignedVector< T >::empty | ( | ) | const |
Return whether the vector is empty, i.e., its size is zero.
size_type AlignedVector< T >::size | ( | ) | const |
Return the size of the vector.
size_type AlignedVector< T >::capacity | ( | ) | const |
Return the capacity of the vector, i.e., the size this vector can hold without reallocation. Note that capacity() >= size().
reference AlignedVector< T >::operator[] | ( | const size_type | index | ) |
Read-write access to entry index
in the vector.
const_reference AlignedVector< T >::operator[] | ( | const size_type | index | ) | const |
Read-only access to entry index
in the vector.
pointer AlignedVector< T >::data | ( | ) |
Return a pointer to the underlying data buffer.
const_pointer AlignedVector< T >::data | ( | ) | const |
Return a const pointer to the underlying data buffer.
iterator AlignedVector< T >::begin | ( | ) |
Return a read and write pointer to the beginning of the data array.
iterator AlignedVector< T >::end | ( | ) |
Return a read and write pointer to the end of the data array.
const_iterator AlignedVector< T >::begin | ( | ) | const |
Return a read-only pointer to the beginning of the data array.
const_iterator AlignedVector< T >::end | ( | ) | const |
Return a read-only pointer to the end of the data array.
size_type AlignedVector< T >::memory_consumption | ( | ) | const |
Return the memory consumption of the allocated memory in this class. If the underlying type T
allocates memory by itself, this memory is not counted.
void AlignedVector< T >::save | ( | Archive & | ar, |
const unsigned int | version | ||
) | const |
Write the data of this object to a stream for the purpose of serialization using the BOOST serialization library.
void AlignedVector< T >::load | ( | Archive & | ar, |
const unsigned int | version | ||
) |
Read the data of this object from a stream for the purpose of serialization using the BOOST serialization library.
void AlignedVector< T >::serialize | ( | Archive & | archive, |
const unsigned int | version | ||
) |
Write and read the data of this object from a stream for the purpose of serialization using the BOOST serialization library.
|
related |
Relational operator == for AlignedVector
Definition at line 2062 of file aligned_vector.h.
|
related |
Relational operator != for AlignedVector
Definition at line 2084 of file aligned_vector.h.
|
private |
Pointer to actual data array, using the custom deleter class above.
Definition at line 676 of file aligned_vector.h.
|
private |
Pointer to one past the last valid value.
Definition at line 681 of file aligned_vector.h.
|
private |
Pointer to the end of the allocated memory.
Definition at line 686 of file aligned_vector.h.