15 #include "../config/config.hpp"
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);
165 inline const T &
Last()
const;
168 inline int Union(
const T & el);
171 inline int Find(
const T &el)
const;
205 void Save(std::ostream &
out,
int fmt = 0)
const;
213 void Load(std::istream &in,
int fmt = 0);
217 void Load(
int new_size, std::istream &in)
232 template<
class Compare>
255 inline void Assign(
const T *);
257 template <
typename U>
260 template <
typename U>
273 const T *
Read(
bool on_dev =
true)
const
300 if ( LHS.
Size() != RHS.
Size() ) {
return false; }
301 for (
int i=0; i<LHS.
Size(); i++)
303 if ( LHS[i] != RHS[i] ) {
return false; }
311 return !( LHS == RHS );
333 Array2D(
int m,
int n) : array1d(m*n) { M = m; N = n; }
335 void SetSize(
int m,
int n) { array1d.SetSize(m*n); M = m; N = n; }
340 inline const T &
operator()(
int i,
int j)
const;
349 const T *
GetRow(
int i)
const {
return (*
this)[i]; }
365 void Save(std::ostream &
out,
int fmt = 0)
const
368 array1d.Save(out, 1);
377 void Load(std::istream &in,
int fmt = 0)
379 if (fmt == 0) { in >> M >> N; array1d.SetSize(M*N); }
384 void Load(
const char *filename,
int fmt = 0);
388 void Load(
int new_size0,
int new_size1, std::istream &in)
392 { copy.M = M; copy.N = N; array1d.Copy(copy.array1d); }
399 { M = master.M; N = master.N; array1d.MakeRef(master.array1d); }
402 inline void DeleteAll() { M = 0; N = 0; array1d.DeleteAll(); }
419 : array1d(n1*n2*n3) { N2 = n2; N3 = n3; }
422 { array1d.SetSize(n1*n2*n3); N2 = n2; N3 = n3; }
424 inline const T &
operator()(
int i,
int j,
int k)
const;
445 int Append(
const T &item);
477 template <
typename cA,
typename cT>
498 b_end_idx = std::min(a->size, a->mask+1);
504 MFEM_ASSERT(!
stop,
"invalid use");
507 if (b_end_idx < array->
size)
511 b_end_idx = std::min(
array->size, (b_end_idx|
array->mask) + 1);
558 iterator
begin() {
return size ? iterator(
this) : iterator(
true); }
559 iterator
end() {
return iterator(); }
562 {
return size ? const_iterator(
this) : const_iterator(
true); }
563 const_iterator
cend()
const {
return const_iterator(); }
573 MFEM_ASSERT(index >= 0 && index <
size,
574 "Out of bounds access: " << index <<
", size = " <<
size);
604 data.UseDevice(src.
data.UseDevice());
607 template <
typename T>
template <
typename CT>
612 for (
int i = 0; i <
size; i++) { (*this)[i] = T(src[i]); }
618 const int nsize = std::max(minsize, 2 * data.Capacity());
619 Memory<T> p(nsize, data.GetMemoryType());
621 p.UseDevice(data.UseDevice());
626 template <
typename T>
template <
typename CT>
630 for (
int i = 0; i < size; i++) { (*this)[i] = T(src[i]); }
637 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
638 if (nsize > Capacity())
648 MFEM_ASSERT( nsize>=0,
"Size must be non-negative. It is " << nsize );
651 if (nsize > Capacity())
655 for (
int i = size; i < nsize; i++)
666 MFEM_ASSERT(nsize >= 0,
"invalid new size: " << nsize);
667 if (mt == data.GetMemoryType())
669 if (nsize <= Capacity())
675 const bool use_dev = data.UseDevice();
687 data.UseDevice(use_dev);
693 MFEM_ASSERT( i>=0 && i<size,
694 "Access element " << i <<
" of array, size = " << size );
701 MFEM_ASSERT( i>=0 && i<size,
702 "Access element " << i <<
" of array, size = " << size );
717 const int old_size = size;
719 SetSize(size + nels);
720 for (
int i = 0; i < nels; i++)
722 data[old_size+i] = els[i];
731 for (
int i = size-1; i > 0; i--)
742 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
749 MFEM_ASSERT(size > 0,
"Array size is zero: " << size);
757 while ((i < size) && (data[i] != el)) { i++; }
768 for (
int i = 0; i < size; i++)
770 if (data[i] == el) {
return i; }
778 const T *begin = data, *end = begin + size;
779 const T* first = std::lower_bound(begin, end, el);
780 if (first == end || !(*first == el)) {
return -1; }
781 return first - begin;
787 for (
int i = 0; i < size; i++)
791 for (i++; i < size; i++)
804 const bool use_dev = data.UseDevice();
808 data.UseDevice(use_dev);
811 template <
typename T>
814 copy.
SetSize(Size(), data.GetMemoryType());
815 data.CopyTo(copy.
data, Size());
816 copy.
data.UseDevice(data.UseDevice());
823 data.Wrap(p, s,
false);
833 data.ClearOwnerFlags();
840 for (
int i = 0; i < sa_size; i++)
842 sa[i] = (*this)[offset+i];
849 for (
int i = 0; i < size; i++)
858 data.CopyFromHost(p, Size());
865 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
866 "Array2D: invalid access of element (" << i <<
',' << j
867 <<
") in array of size (" << array1d.Size()/N <<
',' << N
869 return array1d[i*N+j];
875 MFEM_ASSERT( i>=0 && i< array1d.Size()/N && j>=0 && j<N,
876 "Array2D: invalid access of element (" << i <<
',' << j
877 <<
") in array of size (" << array1d.Size()/N <<
',' << N
879 return array1d[i*N+j];
885 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
886 "Array2D: invalid access of row " << i <<
" in array with "
887 << array1d.Size()/N <<
" rows.");
888 return &array1d[i*N];
894 MFEM_ASSERT( i>=0 && i< array1d.Size()/N,
895 "Array2D: invalid access of row " << i <<
" in array with "
896 << array1d.Size()/N <<
" rows.");
897 return &array1d[i*N];
904 Swap(a.array1d, b.array1d);
912 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
914 "Array3D: invalid access of element ("
915 << i <<
',' << j <<
',' << k <<
") in array of size ("
916 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
917 return array1d[(i*N2+j)*N3+k];
923 MFEM_ASSERT(i >= 0 && i < array1d.Size() / N2 / N3 && j >= 0 && j < N2
925 "Array3D: invalid access of element ("
926 << i <<
',' << j <<
',' << k <<
") in array of size ("
927 << array1d.Size() / N2 / N3 <<
',' << N2 <<
',' << N3 <<
").");
928 return array1d[(i*N2+j)*N3+k];
936 MFEM_VERIFY(!(block_size & mask),
"block_size must be a power of two.");
939 while ((1 << shift) < block_size) { shift++; }
952 for (
int i = 0; i < blocks.Size(); i++)
954 blocks[i] = (T*)
new char[bsize *
sizeof(T)];
958 for (
int i = 0; i < size; i++)
960 new (&At(i)) T(other[i]);
968 if (size >= blocks.Size() * bsize)
970 T* new_block = (T*)
new char[bsize *
sizeof(T)];
971 blocks.Append(new_block);
980 new (&At(index)) T();
988 new (&At(index)) T(item);
996 std::swap(size, other.
size);
997 std::swap(shift, other.
shift);
998 std::swap(mask, other.
mask);
1001 template<
typename T>
1004 return blocks.Size()*(mask+1)*
sizeof(T) +
1005 blocks.MemoryUsage();
1008 template<
typename T>
1011 int bsize = size & mask;
1012 for (
int i = blocks.Size(); i != 0; )
1014 T *block = blocks[--i];
1015 for (
int j = bsize; j != 0; )
1019 delete [] (
char*) block;
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
int Size() const
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)
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
const_iterator cbegin() const
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 current array.
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 using the supplied comparison function object.
bool operator==(const iterator &other) const
void MakeRef(const Array2D &master)
Make this Array a reference to 'master'.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
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 'el' entry.
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 whole array.
int Append(const Array< T > &els)
Append another array to this array, resize if necessary.
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 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
T & operator[](int i)
Access 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)
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)
void Assign(const T *)
Copy data from a pointer. Size() elements are copied.
void Sort()
Sorts the array. 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 > &)
bool operator==(const Array< T > &LHS, const Array< T > &RHS)
void GrowSize(int minsize)
int IsSorted()
return true if the array is sorted.
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 logical size of the array, keep existing entries.
const T * operator[](int i) const
void PartialSum()
Partial Sum.
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
void DeleteLast()
Delete the last entry.
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.
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...
T & At(int index)
Access item of the array.
const T * GetRow(int i) const
int Prepend(const T &el)
Prepend an element 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.