26#include <initializer_list>
32template <
typename ViewedType>
class MemoryView;
39template <
class T>
inline void Swap(T &
a, T &
b);
61 static_assert(std::is_trivial<T>::value,
"type T must be trivial");
78 explicit inline Array(
int asize)
79 :
size(asize) {
if (asize > 0) {
data.New(asize); } }
83 :
data(mt),
size(asize) {
if (asize > 0) {
data.New(asize, mt); } }
91 inline Array(T *data_,
int asize,
bool own_data =
false)
92 {
data.Wrap(data_, asize, own_data);
size = asize; }
99 template <
typename CT>
103 template <
typename CT,
int N>
104 explicit inline Array(
const CT (&values)[N]);
107 template <
typename CT,
typename std::enable_if<
108 std::is_convertible<CT,T>::value,
bool>::type =
true>
109 explicit inline Array(std::initializer_list<CT> values);
128 if (
this == &src) {
return *
this; }
145 template <
typename CT>
153 inline operator T *() {
return data; }
156 inline operator const T *()
const {
return data; }
198 inline void SetSize(
int nsize,
const T &initval);
226 inline int Append(
const T *els,
int nels);
244 inline int Find(
const T &el)
const;
270 inline void MakeRef(T *data_,
int size_,
bool own_data =
false);
300 template <
typename I>
302 template <
typename I>
317 void Save(std::ostream &
out,
int fmt = 0)
const;
325 void Load(std::istream &in,
int fmt = 0);
329 void Load(
int new_size, std::istream &in)
344 template<
class Compare>
380 template <
typename U>
386 template <
typename U>
390 MFEM_ASSERT(
begin() && src,
"Error in Array::CopyFrom");
410 const T *
Read(
bool on_dev =
true)
const
437 if ( LHS.
Size() != RHS.
Size() ) {
return false; }
438 for (
int i=0; i<LHS.
Size(); i++)
440 if ( LHS[i] != RHS[i] ) {
return false; }
448 return !( LHS == RHS );
453template <
typename T>
const T &
AsConst(
const T &
a) {
return a; }
468 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
488 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
504 void Save(std::ostream &os,
int fmt = 0)
const
516 void Load(std::istream &in,
int fmt = 0)
518 if (fmt == 0) { in >> M >> N; array1d.
SetSize(M*N); }
523 void Load(
const char *filename,
int fmt = 0);
527 void Load(
int new_size0,
int new_size1, std::istream &in)
549 { M = master.M; N = master.N; array1d.
MakeRef(master.array1d); }
579 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
583 { array1d.
SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
588 const int size = array1d.
Size();
589 return size == 0 ? 0 : size / (N2 * N3);
658 template <
typename cA,
typename cT>
685 MFEM_ASSERT(!
stop,
"invalid use");
697 MFEM_ASSERT(
b_end_idx == array->size,
"invalid use");
757 "Out of bounds access: " <<
index <<
", size = " <<
size);
767template <
class T>
inline void Swap(T &
a, T &
b)
788 data.UseDevice(src.
data.UseDevice());
791template <
typename T>
template <
typename CT>
796 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
800template <
typename CT,
typename std::enable_if<
801 std::is_convertible<CT,T>::value,
bool>::type>
804 std::copy(values.begin(), values.end(),
begin());
807template <
typename T>
template <
typename CT,
int N>
810 std::copy(values, values + N,
begin());
817 std::swap(size, other.
size);
823 const int nsize = std::max(minsize, 2 * data.
Capacity());
825 p.CopyFrom(data, size);
834 if (Capacity() == size) {
return; }
836 p.CopyFrom(data, size);
846 for (
int i = 0; i < size; i++)
849 while (i != indices[current])
851 auto next = indices[current];
852 std::swap(data[current], data[next]);
853 indices[current] = current;
856 indices[current] = current;
860template <
typename T>
template <
typename CT>
864 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
871 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
872 if (nsize > Capacity())
882 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
885 if (nsize > Capacity())
889 for (
int i = size; i < nsize; i++)
900 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
903 if (nsize <= Capacity())
927 MFEM_ASSERT( i>=0 && i<size,
928 "Access element " << i <<
" of array, size = " << size );
935 MFEM_ASSERT( i>=0 && i<size,
936 "Access element " << i <<
" of array, size = " << size );
951 const int old_size = size;
953 SetSize(size + nels);
954 for (
int i = 0; i < nels; i++)
956 data[old_size+i] = els[i];
965 for (
int i = size-1; i > 0; i--)
976 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
983 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
991 while ((i < size) && (data[i] != el)) { i++; }
1002 for (
int i = 0; i < size; i++)
1004 if (data[i] == el) {
return i; }
1012 const T *begin = data, *end = begin + size;
1013 const T* first = std::lower_bound(begin, end, el);
1014 if (first == end || !(*first == el)) {
return -1; }
1015 return (
int)(first - begin);
1021 for (
int i = 0; i < size; i++)
1025 for (i++; i < size; i++)
1027 data[i-1] = data[i];
1042 sorted_indices.
Sort();
1045 for (
int i = 0; i < size; i++)
1047 if (rm_count < sorted_indices.
Size() && i == sorted_indices[rm_count])
1053 data[i-rm_count] = data[i];
1070template <
typename T>
1073 copy.SetSize(Size());
1074 const bool use_dev = UseDevice() || copy.UseDevice();
1075 copy.data.UseDevice(use_dev);
1077 if (use_dev) { copy.Write(); }
1078 copy.data.CopyFrom(data, Size());
1085 data.
Wrap(data_, size_, own_data);
1093 data.
Wrap(data_, size_, mt, own_data);
1115 const Memory<T> &mem,
int s,
bool own_mem)
1133 for (
int i = 0; i < sa_size; i++)
1135 sa[i] = (*this)[offset+i];
1142 for (
int i = 0; i < size; i++)
1158 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1159 "Array2D: invalid access of element (" << i <<
',' << j
1160 <<
") in array of size (" << array1d.Size()/N <<
',' << N
1162 return array1d[i*N+j];
1168 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1169 "Array2D: invalid access of element (" << i <<
',' << j
1170 <<
") in array of size (" << array1d.Size()/N <<
',' << N
1172 return array1d[i*N+j];
1178 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1179 "Array2D: invalid access of row " << i <<
" in array with "
1180 << array1d.Size()/N <<
" rows.");
1181 return &array1d[i*N];
1187 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1188 "Array2D: invalid access of row " << i <<
" in array with "
1189 << array1d.Size()/N <<
" rows.");
1190 return &array1d[i*N];
1197 std::swap(M, other.M);
1198 std::swap(N, other.N);
1203template <
typename T>
1213 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1214 && k >= 0 && k < N3,
1215 "Array3D: invalid access of element ("
1216 << i <<
',' << j <<
',' << k <<
") in array of size ("
1217 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
1218 return array1d[(i*N2+j)*N3+k];
1224 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1225 && k >= 0 && k < N3,
1226 "Array3D: invalid access of element ("
1227 << i <<
',' << j <<
',' << k <<
") in array of size ("
1228 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
1229 return array1d[(i*N2+j)*N3+k];
1236 mask = block_size-1;
1237 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
1240 while ((1 << shift) < block_size) { shift++; }
1249 shift = other.
shift;
1253 for (
int i = 0; i < blocks.Size(); i++)
1255 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
1259 for (
int i = 0; i < size; i++)
1261 new (&At(i)) T(other[i]);
1269 if (size >= blocks.Size() * bsize)
1271 T* new_block = (T*)
new char[bsize *
sizeof(T)];
1272 blocks.Append(new_block);
1280 int index = Alloc();
1281 new (&At(
index)) T();
1288 int index = Alloc();
1289 new (&At(
index)) T(item);
1297 std::swap(size, other.
size);
1298 std::swap(shift, other.
shift);
1299 std::swap(mask, other.
mask);
1305 return (mask+1)*
sizeof(T)*blocks.Size() + blocks.MemoryUsage();
1311 int bsize = size & mask;
1312 for (
int i = blocks.Size(); i != 0; )
1314 T *block = blocks[--i];
1315 for (
int j = bsize; j != 0; )
1319 delete [] (
char*) block;
Dynamic 2D array using row-major layout.
void DeleteAll()
Delete all dynamically allocated memory, resetting all dimensions to zero.
const T * operator[](int i) const
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
Array2D(int m, int n)
Construct an m x n 2D array.
void Swap(Array2D &other)
Swap the contents of the Array2D with other.
Array2D & operator=(const Array2D &)=default
Copy assignment.
void Copy(Array2D ©) const
Array2D(const Array2D &)=default
void Save(std::ostream &os, int fmt=0) const
Save the Array2D to the stream out using the format fmt.
const T & operator()(int i, int j) const
Array2D & operator=(Array2D &&)=default
Move assignment.
const T * GetRow(int i) const
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt.
T & operator()(int i, int j)
void Print(std::ostream &out=mfem::out, int width=4)
Prints array to stream with width elements per row.
void operator=(const T &a)
Set all entries of the array to the provided constant.
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.
const T * operator()(int i) const
Array2D(Array2D &&)=default
void MakeRef(const Array2D &master)
Make this Array2D a reference to 'master'.
void SetSize(int m, int n)
Set the 2D array size to m x n.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Load(int new_size0, int new_size1, std::istream &in)
Set the Array2D dimensions to new_size0 x new_size1 and read that many entries from the stream in.
int GetSize2() const
Get the 3D array size in the second dimension.
const T & operator()(int i, int j, int k) const
Array3D(int n1, int n2, int n3)
Construct a 3D array of size n1 x n2 x n3.
int GetSize1() const
Get the 3D array size in the first dimension.
void SetSize(int n1, int n2, int n3)
Set the 3D array size to n1 x n2 x n3.
void operator=(const T &a)
Set all entries of the array to the provided constant.
int GetSize3() const
Get the 3D array size in the third dimension.
T & operator()(int i, int j, int k)
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
T value_type
Type alias for stl.
Array(std::initializer_list< CT > values)
Construct an Array from a braced initializer list of convertible type.
const T & Last() const
Return the last element in the array.
void Sort(Compare cmp)
Sorts the array in ascending order using the supplied comparison function object.
void DeleteFirst(const T &el)
Delete the first entry with value == 'el'.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
void MakeRef(const Array &master)
Make this Array a reference to 'master'.
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
Copy sub array starting from offset out to the provided sa.
int size
Size of the array.
Array< T > & operator=(Array< T > &&src)
Move assignment operator.
int Union(const T &el)
Append element when it is not yet in the array, return index.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
T & operator[](int i)
Reference access to the ith element.
void MakeDataOwner() const
Make the Array own the data.
bool IsConstant() const
Return true if all entries of the array are the same.
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
void push_back(const T &el)
STL-like push_back. Append element 'el' to array, resize if necessary.
void MakeRef(Memory< T > &base, int offset, int size_)
Make this Array a reference to the given sub-Memory of base.
void CopyFrom(const U *src)
Copy from src into this array. Copies enough entries to fill the Capacity size of this array....
Array< T > & operator=(const Array< T > &src)
Copy assignment operator: deep copy from 'src'.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void StealData(T **p)
Changes the ownership of the data.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Prepend(const T &el)
Prepend an 'el' to the array, resize if necessary.
bool IsEmpty() const
Does the Array have Size zero.
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void LoseData()
NULL-ifies the data.
int Size() const
Return the logical size of the array.
const T * begin() const
STL-like begin. Returns const pointer to the first element of the array.
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
Memory< T > data
Pointer to data.
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
const T * end() const
STL-like end. Returns const pointer after the last element of the array.
void operator=(const T &a)
Set all entries of the array to the provided constant.
Array(MemoryType mt)
Creates an empty array with a given MemoryType.
int Append(const T *els, int nels)
Append another array to this array, resize if necessary.
int IsSorted() const
Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Array(int asize, MemoryType mt)
Creates array of asize elements with a given MemoryType.
Array(const Array< CT > &src)
Copy constructor (deep copy) from 'src', an Array of convertible type.
void DeleteAll()
Delete the whole array.
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void UseDevice(bool use_dev) const
Set the device flag of the Array, i.e. the device flag of the Memory object used by the Array.
T * GetData()
Returns the data.
const T * GetData() const
Returns the data.
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
void Save(std::ostream &out, int fmt=0) const
Save the Array to the stream out using the format fmt. The format fmt can be:
void Copy(Array ©) const
Create a copy of the internal array to the provided copy.
Array(Array< T > &&src)
Move constructor ("steals" data from 'src')
Array(const Array &src)
Copy constructor: deep copy from src.
void Permute(const I &indices)
bool OwnsData() const
Return true if the data will be deleted by the Array.
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T.
void Permute(I &&indices)
Permute the array using the provided indices. Sorts the indices variable in the process,...
T & reference
Type alias for stl.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
void ShrinkToFit()
Reduces the capacity of the array to exactly match the current size.
T * end()
STL-like end. Returns pointer after the last element of the array.
const T & const_reference
Type alias for stl.
void Abs()
Replace each entry of the array with its absolute value.
Array()
Creates an empty array.
Array(T *data_, int asize, bool own_data=false)
Creates array using an externally allocated host pointer data_ to asize elements. If own_data is true...
T * begin()
STL-like begin. Returns pointer to the first element of the array.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
const T & operator[](int i) const
Const reference access to the ith element.
Array & operator=(const Array< CT > &src)
Assignment operator (deep copy) from src, an Array of convertible type.
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
Array(const CT(&values)[N])
Construct an Array from a C-style array of static length.
void NewMemoryAndSize(const Memory< T > &mem, int s, bool own_mem)
Reset the Array to use the given external Memory mem and size s.
void MakeRef(T *data_, int size, MemoryType mt, bool own_data)
Make this Array a reference to a pointer.
Array(int asize)
Creates array of asize elements.
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
void DeleteAt(const Array< int > &indices)
Delete entries at indices, and resize.
void SetSize(int nsize, MemoryType mt)
Resize the array to size nsize using MemoryType mt. Note that unlike the other versions of SetSize(),...
void GrowSize(int minsize)
T Sum() const
Return the sum of all the array entries using the '+'' operator for class 'T'.
void Swap(Array &other)
Swap the contents of the Array with other.
void DeleteLast()
Delete the last entry of the array.
void SetSize(int nsize, const T &initval)
Same as SetSize(int) plus initialize new entries with 'initval'.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
T & Last()
Return the last element in the array.
void Load(int new_size, std::istream &in)
Set the Array size to new_size and read that many entries from the stream in.
const_iterator(bool stop)
const_iterator(const BlockArray *a)
const_iterator & operator++()
iterator_base< const BlockArray, const T > base
bool operator!=(const const_iterator &other) const
bool operator==(const const_iterator &other) const
bool operator==(const iterator &other) const
bool operator!=(const iterator &other) const
iterator_base< BlockArray, T > base
void DeleteAll()
Destroy all items, set size to zero.
BlockArray(const BlockArray< T > &other)
const T & At(int index) const
int Capacity() const
Return the current capacity of the BlockArray.
std::size_t MemoryUsage() const
const_iterator cend() const
BlockArray & operator=(const BlockArray &)=delete
T & At(int index)
Access item of the array.
const T & operator[](int index) const
void CheckIndex(int index) const
void Swap(BlockArray< T > &other)
int Append()
Allocate and construct a new item in the array, return its index.
const_iterator cbegin() const
BlockArray & operator=(BlockArray< T > &&other)=default
const_iterator begin() const
const_iterator end() const
T & operator[](int index)
Access item of the array.
int Append(const T &item)
Allocate and copy-construct a new item in the array, return its index.
int Size() const
Return the number of items actually stored.
BlockArray(BlockArray< T > &&other)=default
BlockArray(int block_size=16 *1024)
Type that enables viewing Vector objects as Array<real_t> objects and vice versa. Currently,...
Class used by MFEM to store pointers to host and/or device memory.
int Capacity() const
Return the size of the allocated memory.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
void MakeAlias(const Memory &base, int offset, int size)
Create a memory object that points inside the memory object base.
bool UseDevice() const
Read the internal device flag.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
void Reset()
Reset the memory to be empty, ensuring that Delete() will be a no-op.
void Wrap(T *ptr, int size, bool own)
Wrap an externally allocated host pointer, ptr with the current host memory type returned by MemoryMa...
void Delete()
Delete the owned pointers and reset the Memory object.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
int index(int i, int j, int nx, int ny)
const T * Read(const Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
T * HostReadWrite(Memory< T > &mem, int size)
Shortcut to ReadWrite(Memory<T> &mem, int size, false)
void swap(Array< T > &a, Array< T > &b)
Swap of Array<T> objects for use with standard library algorithms. Also, used by mfem::Swap().
T * Write(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for write access to mem with the mfem::Device's DeviceMemoryClass, if on_dev = true,...
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
T * ReadWrite(Memory< T > &mem, int size, bool on_dev=true)
Get a pointer for read+write access to mem with the mfem::Device's DeviceMemoryClass,...
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
const T & AsConst(const T &a)
Utility function similar to std::as_const in c++17.
MemoryType
Memory types supported by MFEM.
real_t p(const Vector &x, real_t t)