15 #include "../config/config.hpp"
33 void Swap(Array<T> &, Array<T> &);
64 explicit inline Array(
int asize)
65 :
size(asize) { asize > 0 ?
data.New(asize) :
data.Reset(); }
70 inline Array(T *_data,
int asize)
71 {
data.Wrap(_data, asize,
false);
size = asize; }
78 template <
typename CT>
88 template <
typename CT>
92 inline operator T *() {
return data; }
95 inline operator const T *()
const {
return data; }
127 inline void SetSize(
int nsize);
130 inline void SetSize(
int nsize,
const T &initval);
152 inline int Append(
const T & el);
155 inline int Append(
const T *els,
int nels);
161 inline int Prepend(
const T &el);
167 inline const T &
Last()
const;
170 inline int Union(
const T & el);
173 inline int Find(
const T &el)
const;
210 void Save(std::ostream &
out,
int fmt = 0)
const;
218 void Load(std::istream &in,
int fmt = 0);
222 void Load(
int new_size, std::istream &in)
237 template<
class Compare>
261 inline void Assign(
const T *);
264 template <
typename U>
270 template <
typename U>
290 const T *
Read(
bool on_dev =
true)
const
317 if ( LHS.Size() != RHS.Size() ) {
return false; }
318 for (
int i=0; i<LHS.Size(); i++)
320 if ( LHS[i] != RHS[i] ) {
return false; }
328 return !( LHS == RHS );
350 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
352 void SetSize(
int m,
int n) { array1d.SetSize(m*n); M = m; N = n; }
357 inline const T &
operator()(
int i,
int j)
const;
366 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
382 void Save(std::ostream &
out,
int fmt = 0)
const
385 array1d.Save(out, 1);
394 void Load(std::istream &in,
int fmt = 0)
396 if (fmt == 0) { in >> M >> N; array1d.SetSize(M*N); }
401 void Load(
const char *filename,
int fmt = 0);
405 void Load(
int new_size0,
int new_size1, std::istream &in)
409 { copy.M = M; copy.N = N; array1d.Copy(copy.array1d); }
418 { M = master.M; N = master.N; array1d.MakeRef(master.array1d); }
421 inline void DeleteAll() { M = 0; N = 0; array1d.DeleteAll(); }
438 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
441 { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
443 inline const T &
operator()(
int i,
int j,
int k)
const;
464 int Append(
const T &item);
496 template <
typename cA,
typename cT>
517 b_end_idx = std::min(a->size, a->mask+1);
523 MFEM_ASSERT(!
stop,
"invalid use");
526 if (b_end_idx < array->
size)
530 b_end_idx = std::min(
array->size, (b_end_idx|
array->mask) + 1);
577 iterator
begin() {
return size ? iterator(
this) : iterator(
true); }
578 iterator
end() {
return iterator(); }
581 {
return size ? const_iterator(
this) : const_iterator(
true); }
582 const_iterator
cend()
const {
return const_iterator(); }
592 MFEM_ASSERT(index >= 0 && index <
size,
593 "Out of bounds access: " << index <<
", size = " <<
size);
613 Swap(a.data, b.data);
614 Swap(a.size, b.size);
623 data.UseDevice(src.data.UseDevice());
626 template <
typename T>
template <
typename CT>
631 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
637 const int nsize = std::max(minsize, 2 * data.Capacity());
639 p.CopyFrom(data, size);
640 p.UseDevice(data.UseDevice());
645 template <
typename T>
template <
typename CT>
649 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
656 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
657 if (nsize > Capacity())
667 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
670 if (nsize > Capacity())
674 for (
int i = size; i < nsize; i++)
685 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
686 if (mt == data.GetMemoryType())
688 if (nsize <= Capacity())
694 const bool use_dev = data.UseDevice();
706 data.UseDevice(use_dev);
712 MFEM_ASSERT( i>=0 && i<size,
713 "Access element " << i <<
" of array, size = " << size );
720 MFEM_ASSERT( i>=0 && i<size,
721 "Access element " << i <<
" of array, size = " << size );
736 const int old_size = size;
738 SetSize(size + nels);
739 for (
int i = 0; i < nels; i++)
741 data[old_size+i] = els[i];
750 for (
int i = size-1; i > 0; i--)
761 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
768 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
776 while ((i < size) && (data[i] != el)) { i++; }
787 for (
int i = 0; i < size; i++)
789 if (data[i] == el) {
return i; }
797 const T *begin = data, *end = begin + size;
798 const T* first = std::lower_bound(begin, end, el);
799 if (first == end || !(*first == el)) {
return -1; }
800 return first - begin;
806 for (
int i = 0; i < size; i++)
810 for (i++; i < size; i++)
823 const bool use_dev = data.UseDevice();
827 data.UseDevice(use_dev);
830 template <
typename T>
833 copy.SetSize(Size(), data.GetMemoryType());
834 data.CopyTo(copy.data, Size());
835 copy.data.UseDevice(data.UseDevice());
842 data.Wrap(p, s,
false);
852 data.ClearOwnerFlags();
859 for (
int i = 0; i < sa_size; i++)
861 sa[i] = (*this)[offset+i];
868 for (
int i = 0; i < size; i++)
877 data.CopyFromHost(p, Size());
884 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
885 "Array2D: invalid access of element (" << i <<
',' << j
886 <<
") in array of size (" << array1d.Size()/N <<
',' << N
888 return array1d[i*N+j];
894 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
895 "Array2D: invalid access of element (" << i <<
',' << j
896 <<
") in array of size (" << array1d.Size()/N <<
',' << N
898 return array1d[i*N+j];
904 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
905 "Array2D: invalid access of row " << i <<
" in array with "
906 << array1d.Size()/N <<
" rows.");
907 return &array1d[i*N];
913 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
914 "Array2D: invalid access of row " << i <<
" in array with "
915 << array1d.Size()/N <<
" rows.");
916 return &array1d[i*N];
923 Swap(a.array1d, b.array1d);
931 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
933 "Array3D: invalid access of element ("
934 << i <<
',' << j <<
',' << k <<
") in array of size ("
935 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
936 return array1d[(i*N2+j)*N3+k];
942 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
944 "Array3D: invalid access of element ("
945 << i <<
',' << j <<
',' << k <<
") in array of size ("
946 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
947 return array1d[(i*N2+j)*N3+k];
955 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
958 while ((1 << shift) < block_size) { shift++; }
971 for (
int i = 0; i < blocks.Size(); i++)
973 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
977 for (
int i = 0; i < size; i++)
979 new (&At(i)) T(other[i]);
987 if (size >= blocks.Size() * bsize)
989 T* new_block = (T*)
new char[bsize *
sizeof(T)];
990 blocks.Append(new_block);
999 new (&At(index)) T();
1003 template<
typename T>
1006 int index = Alloc();
1007 new (&At(index)) T(item);
1011 template<
typename T>
1015 std::swap(size, other.
size);
1016 std::swap(shift, other.
shift);
1017 std::swap(mask, other.
mask);
1020 template<
typename T>
1023 return blocks.Size()*(mask+1)*
sizeof(T) +
1024 blocks.MemoryUsage();
1027 template<
typename T>
1030 int bsize = size & mask;
1031 for (
int i = blocks.Size(); i != 0; )
1033 T *block = blocks[--i];
1034 for (
int j = bsize; j != 0; )
1038 delete [] (
char*) block;
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
int Size() const
Return the logical size of the array.
const_iterator(const BlockArray *a)
void Load(std::istream &in, int fmt=0)
Read an Array from the stream in using format fmt. The format fmt can be:
Array(T *_data, int asize)
Creates array using an existing c-array of asize elements; allocsize is set to -asize to indicate tha...
void Unique()
Removes duplicities from a sorted array. This requires operator== to be defined for T...
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
T * end()
STL-like end. Returns pointer after the last element of the array.
const_iterator cbegin() const
const T * begin() const
STL-like begin. Returns const pointer to the first element of the array.
iterator_base< const BlockArray, const T > base
const T * operator()(int i) const
int Capacity() const
Return the current capacity of the BlockArray.
void Load(std::istream &in, int fmt=0)
Read an Array2D from the stream in using format fmt. The format fmt can be:
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
int size
Size of the array.
int Size() const
Return the number of items actually stored.
void Save(std::ostream &out, int fmt=0) const
Save the Array2D 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.
T * GetData()
Returns the data.
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...
void operator=(const T &a)
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:
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
Array(int asize)
Creates array of asize elements.
void Sort(Compare cmp)
Sorts the array in ascending order using the supplied comparison function object. ...
T Sum()
Return the sum of all the array entries using the '+'' operator for class 'T'.
bool operator==(const iterator &other) const
void MakeRef(const Array2D &master)
Make this Array a reference to 'master'.
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 T & At(int index) const
bool operator==(const const_iterator &other) const
void DeleteFirst(const T &el)
Delete the first entry with value == 'el'.
T & operator[](int index)
Access item of the array.
void SetSize(int n1, int n2, int n3)
T Min() const
Find the minimal element in the array, using the comparison operator < for class T.
void DeleteAll()
Delete the whole array.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
void CopyTo(U *dest)
STL-like copyTo dest from begin to end.
void SetSize(int m, int n)
void Copy(Array2D ©) const
bool OwnsData() const
Return true if the data will be deleted by the array.
const T & operator()(int i, int j) const
const T * GetData() const
Returns the data.
int Append(const T &el)
Append element 'el' to array, resize if necessary.
void DeleteAll()
Destroy all items, set size to zero.
void GetSubArray(int offset, int sa_size, Array< T > &sa) const
Copy sub array starting from offset out to the provided sa.
T & operator[](int i)
Reference access to the ith element.
void LoseData()
NULL-ifies the data.
T Max() const
Find the maximal element in the array, using the comparison operator < for class T.
void Reserve(int capacity)
Ensures that the allocated size is at least the given size.
void CopyFrom(const U *src)
Copy from src into this array. Copies enough entries to fill the Capacity size of this array...
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
bool operator!=(const Array< T > &LHS, const Array< T > &RHS)
T * begin()
STL-like begin. Returns pointer to the first element of the array.
void Assign(const T *)
Copy data from a pointer. 'Size()' elements are copied.
long MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
void Sort()
Sorts the array in ascending order. This requires operator< to be defined for T.
int FindSorted(const T &el) const
Do bisection search for 'el' in a sorted array; return -1 if not found.
void StealData(T **p)
Changes the ownership of the data.
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...
int Union(const T &el)
Append element when it is not yet in the array, return index.
Dynamic 2D array using row-major layout.
Memory< T > data
Pointer to data.
void Print(std::ostream &out=mfem::out, int width=4)
Prints array to stream with width elements per row.
void Swap(Array< T > &, Array< T > &)
double p(const Vector &x, double t)
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
void GrowSize(int minsize)
int IsSorted()
Return 1 if the array is sorted from lowest to highest. Otherwise return 0.
BlockArray(int block_size=16 *1024)
MemoryType
Memory types supported by MFEM.
int Find(const T &el) const
Return the first index where 'el' is found; return -1 if not found.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
const T * operator[](int i) const
void PartialSum()
Fill the entries of the array with the cumulative sum of the entries.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void DeleteLast()
Delete the last entry of the array.
const T & operator[](int index) const
void MakeDataOwner() const
Make the Array own the data.
Array(MemoryType mt)
Creates an empty array with a given MemoryType.
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
bool operator!=(const iterator &other) const
const_iterator(bool stop)
void CheckIndex(int index) const
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, if on_dev = true, or the mfem::Device's HostMemoryClass, otherwise.
Array()
Creates an empty array.
int index(int i, int j, int nx, int ny)
bool operator!=(const const_iterator &other) const
Class used by MFEM to store pointers to host and/or device memory.
const_iterator & operator++()
T & Last()
Return the last element in the array.
void Print(std::ostream &out=mfem::out, int width=4) const
Prints array to stream with width elements per row.
iterator_base< BlockArray, T > base
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
void MakeRef(T *, int)
Make this Array a reference to a pointer.
Array< T > & operator=(const Array< T > &src)
Assignment operator: deep copy from 'src'.
const_iterator cend() const
const Memory< T > & GetMemory() const
Return a reference to the Memory object used by the Array, const version.
void DeleteAll()
Delete all dynamically allocated memory, resetting all dimensions to zero.
const T & operator()(int i, int j, int k) const
Array3D(int n1, int n2, int n3)
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
const T * end() const
STL-like end. Returns const pointer after the last element of the array.
T & At(int index)
Access item of the array.
const T * GetRow(int i) const
int Prepend(const T &el)
Prepend an 'el' to the array, resize if necessary.
int Append()
Allocate and construct a new item in the array, return its index.
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...
void Swap(BlockArray< T > &other)
void GetRow(int i, Array< T > &sa) const
Extract a copy of the i-th row into the Array sa.