26#include <initializer_list>
35template <
class T>
inline void Swap(T &
a, T &
b);
57 static_assert(std::is_trivial<T>::value,
"type T must be trivial");
71 explicit inline Array(
int asize)
72 :
size(asize) {
if (asize > 0) {
data.New(asize); } }
76 :
data(mt),
size(asize) {
if (asize > 0) {
data.New(asize, mt); } }
84 inline Array(T *data_,
int asize,
bool own_data =
false)
85 {
data.Wrap(data_, asize, own_data);
size = asize; }
92 template <
typename CT>
96 template <
typename CT,
int N>
97 explicit inline Array(
const CT (&values)[N]);
100 template <
typename CT,
typename std::enable_if<
101 std::is_convertible<CT,T>::value,
bool>::type =
true>
102 explicit inline Array(std::initializer_list<CT> values);
119 if (
this == &src) {
return *
this; }
126 template <
typename CT>
134 inline operator T *() {
return data; }
137 inline operator const T *()
const {
return data; }
172 inline void SetSize(
int nsize,
const T &initval);
200 inline int Append(
const T *els,
int nels);
218 inline int Find(
const T &el)
const;
244 inline void MakeRef(T *data_,
int size_,
bool own_data =
false);
271 template <
typename I>
273 template <
typename I>
288 void Save(std::ostream &
out,
int fmt = 0)
const;
296 void Load(std::istream &in,
int fmt = 0);
300 void Load(
int new_size, std::istream &in)
315 template<
class Compare>
351 template <
typename U>
357 template <
typename U>
361 MFEM_ASSERT(
begin() && src,
"Error in Array::CopyFrom");
381 const T *
Read(
bool on_dev =
true)
const
408 if ( LHS.
Size() != RHS.
Size() ) {
return false; }
409 for (
int i=0; i<LHS.
Size(); i++)
411 if ( LHS[i] != RHS[i] ) {
return false; }
419 return !( LHS == RHS );
424template <
typename T>
const T &
AsConst(
const T &
a) {
return a; }
439 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
459 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
475 void Save(std::ostream &os,
int fmt = 0)
const
487 void Load(std::istream &in,
int fmt = 0)
489 if (fmt == 0) { in >> M >> N; array1d.
SetSize(M*N); }
494 void Load(
const char *filename,
int fmt = 0);
498 void Load(
int new_size0,
int new_size1, std::istream &in)
520 { M = master.M; N = master.N; array1d.
MakeRef(master.array1d); }
550 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
554 { array1d.
SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
559 const int size = array1d.
Size();
560 return size == 0 ? 0 : size / (N2 * N3);
629 template <
typename cA,
typename cT>
656 MFEM_ASSERT(!
stop,
"invalid use");
668 MFEM_ASSERT(
b_end_idx == array->size,
"invalid use");
728 "Out of bounds access: " <<
index <<
", size = " <<
size);
738template <
class T>
inline void Swap(T &
a, T &
b)
759 data.UseDevice(src.
data.UseDevice());
762template <
typename T>
template <
typename CT>
767 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
771template <
typename CT,
typename std::enable_if<
772 std::is_convertible<CT,T>::value,
bool>::type>
775 std::copy(values.begin(), values.end(),
begin());
778template <
typename T>
template <
typename CT,
int N>
781 std::copy(values, values + N,
begin());
788 std::swap(size, other.
size);
794 const int nsize = std::max(minsize, 2 * data.
Capacity());
796 p.CopyFrom(data, size);
805 if (Capacity() == size) {
return; }
807 p.CopyFrom(data, size);
817 for (
int i = 0; i < size; i++)
820 while (i != indices[current])
822 auto next = indices[current];
823 std::swap(data[current], data[next]);
824 indices[current] = current;
827 indices[current] = current;
831template <
typename T>
template <
typename CT>
835 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
842 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
843 if (nsize > Capacity())
853 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
856 if (nsize > Capacity())
860 for (
int i = size; i < nsize; i++)
871 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
874 if (nsize <= Capacity())
898 MFEM_ASSERT( i>=0 && i<size,
899 "Access element " << i <<
" of array, size = " << size );
906 MFEM_ASSERT( i>=0 && i<size,
907 "Access element " << i <<
" of array, size = " << size );
922 const int old_size = size;
924 SetSize(size + nels);
925 for (
int i = 0; i < nels; i++)
927 data[old_size+i] = els[i];
936 for (
int i = size-1; i > 0; i--)
947 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
954 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
962 while ((i < size) && (data[i] != el)) { i++; }
973 for (
int i = 0; i < size; i++)
975 if (data[i] == el) {
return i; }
983 const T *begin = data, *end = begin + size;
984 const T* first = std::lower_bound(begin, end, el);
985 if (first == end || !(*first == el)) {
return -1; }
986 return (
int)(first - begin);
992 for (
int i = 0; i < size; i++)
996 for (i++; i < size; i++)
1013 sorted_indices.
Sort();
1016 for (
int i = 0; i < size; i++)
1018 if (rm_count < sorted_indices.
Size() && i == sorted_indices[rm_count])
1024 data[i-rm_count] = data[i];
1041template <
typename T>
1044 copy.SetSize(Size());
1045 const bool use_dev = UseDevice() || copy.UseDevice();
1046 copy.data.UseDevice(use_dev);
1048 if (use_dev) { copy.Write(); }
1049 copy.data.CopyFrom(data, Size());
1056 data.
Wrap(data_, size_, own_data);
1064 data.
Wrap(data_, size_, mt, own_data);
1078 const Memory<T> &mem,
int s,
bool own_mem)
1096 for (
int i = 0; i < sa_size; i++)
1098 sa[i] = (*this)[offset+i];
1105 for (
int i = 0; i < size; i++)
1121 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1122 "Array2D: invalid access of element (" << i <<
',' << j
1123 <<
") in array of size (" << array1d.Size()/N <<
',' << N
1125 return array1d[i*N+j];
1131 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
1132 "Array2D: invalid access of element (" << i <<
',' << j
1133 <<
") in array of size (" << array1d.Size()/N <<
',' << N
1135 return array1d[i*N+j];
1141 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1142 "Array2D: invalid access of row " << i <<
" in array with "
1143 << array1d.Size()/N <<
" rows.");
1144 return &array1d[i*N];
1150 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
1151 "Array2D: invalid access of row " << i <<
" in array with "
1152 << array1d.Size()/N <<
" rows.");
1153 return &array1d[i*N];
1160 std::swap(M, other.M);
1161 std::swap(N, other.N);
1166template <
typename T>
1176 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1177 && k >= 0 && k < N3,
1178 "Array3D: invalid access of element ("
1179 << i <<
',' << j <<
',' << k <<
") in array of size ("
1180 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
1181 return array1d[(i*N2+j)*N3+k];
1187 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
1188 && k >= 0 && k < N3,
1189 "Array3D: invalid access of element ("
1190 << i <<
',' << j <<
',' << k <<
") in array of size ("
1191 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
1192 return array1d[(i*N2+j)*N3+k];
1199 mask = block_size-1;
1200 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
1203 while ((1 << shift) < block_size) { shift++; }
1212 shift = other.
shift;
1216 for (
int i = 0; i < blocks.Size(); i++)
1218 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
1222 for (
int i = 0; i < size; i++)
1224 new (&At(i)) T(other[i]);
1232 if (size >= blocks.Size() * bsize)
1234 T* new_block = (T*)
new char[bsize *
sizeof(T)];
1235 blocks.Append(new_block);
1243 int index = Alloc();
1244 new (&At(
index)) T();
1251 int index = Alloc();
1252 new (&At(
index)) T(item);
1260 std::swap(size, other.
size);
1261 std::swap(shift, other.
shift);
1262 std::swap(mask, other.
mask);
1268 return (mask+1)*
sizeof(T)*blocks.Size() + blocks.MemoryUsage();
1274 int bsize = size & mask;
1275 for (
int i = blocks.Size(); i != 0; )
1277 T *block = blocks[--i];
1278 for (
int j = bsize; j != 0; )
1282 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 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.
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)
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)