File array.hxx#
Functions
-
template<typename T>
struct ArrayData# - #include <array.hxx>
ArrayData holds the actual data Handles the allocation and deletion of data
-
template<typename T, typename Backing = ArrayData<T>>
class Array# - #include <array.hxx>
Data array type with automatic memory management
This implements a container similar to std::vector but with reference counting like a smart pointer and custom memory management to minimise new and delete calls
This can be used as an alternative to static arrays
Array<dcomplex> vals(100); // 100 complex numbers
vals[10] = 1.0; // ok
When an Array goes out of scope or is deleted, the underlying memory (dataBlock/Backing) is put into a map, rather than being freed. If the same size arrays are used repeatedly then this avoids the need to use new and delete.
This behaviour can be disabled by calling the static function useStore:
Array<dcomplex>::useStore(false); // Disables memory store
The second template argument determines what type of container to use to store data. This defaults to a custom struct but can be std::valarray ( provided T is a compatible type), std::vector etc. Must provide the following : size, operator=, operator[], begin, end
Notes:
Arrays can’t be used in GPU code. To access Array data inside a RAJA loop, first extract the raw pointer
Public Functions
-
inline ~Array() noexcept#
Destructor. Releases the underlying dataBlock
-
inline Array &operator=(Array other) noexcept#
Assignment operator After this both Arrays share the same dataBlock
Uses copy-and-swap idiom
-
inline void reallocate(size_type new_size)#
Reallocate the array with size =
new_size
Note that this invalidates the existing data!
-
inline void clear() noexcept#
Release data. After this the Array is empty and any data access will be invalid
-
inline void ensureUnique()#
Ensures that this Array does not share data with another This should be called before performing any write operations on the data.
Public Static Functions
-
static inline bool useStore(bool keep_using = true) noexcept#
Holds a static variable which controls whether memory blocks (dataBlock) are put into a store or new/deleted each time.
The variable is initialised to true on first use, but can be set to false by passing “false” as input. Once set to false it can’t be changed back to true.
-
static inline void cleanup()#
Delete all data from the store and disable the store
Note: After this is called the store cannot be re-enabled
Private Types
-
using storeType = std::map<size_type, std::vector<dataPtrType>>#
Private Functions
-
inline dataPtrType get(size_type len)#
Returns a pointer to a dataBlock object of size
len
with no references. This is either from the store, or newly allocatedExpects
len
>= 0
-
inline void release(dataPtrType &d) noexcept#
Release an dataBlock object, reducing its reference count by one. If no more references, then put back into the store. It’s important to pass a reference to the pointer, otherwise we get a copy of the shared_ptr, which therefore increases the use count and doesn’t allow us to free the pass pointer directly
Note that this is noexcept only because we’ve ensure that both a) store()[<size>] already exists, and b) it has space for at least one data block. Of course, store() could throw — in which case we’re doomed anyway, so the only thing we can do is abort
Private Members
-
dataPtrType ptr#
Pointer to the data container object owned by this Array. May be null
Private Static Functions
-
static inline storeType &store(bool cleanup = false)#
This maps from array size (size_type) to vectors of pointers to dataBlock objects
By putting the static store inside a function it is initialised on first use, and doesn’t need to be separately declared for each type T
Inputs
- Parameters:
cleanup – [in] If set to true, deletes all dataBlock and clears the store