33 const int s = v.
Size();
37 MFEM_ASSERT(!v.
data.
Empty(),
"invalid source vector");
54 for (i = 0; i < np; i++)
63 for (i = 0; i < np; i++)
65 for (j = 0; j <
dim[i]; j++)
70 if (!*in[i] && errno == ERANGE)
83 for (
int i = 0; i <
size; i++)
88 if (!in && errno == ERANGE)
108#ifdef MFEM_USE_LEGACY_OPENMP
109 #pragma omp parallel for reduction(+:dot)
111 for (
int i = 0; i <
size; i++)
113 dot +=
data[i] * v[i];
133 const bool use_dev =
UseDevice() || vuse;
136 if (use_dev) {
Write(); }
145 data = std::move(v.data);
147 const auto size_tmp = v.size;
157 auto y =
Write(use_dev);
173 MFEM_ASSERT(
size == v.
size,
"incompatible Vectors!");
178 auto x = v.
Read(use_dev);
195 MFEM_ASSERT(
size == v.
size,
"incompatible Vectors!");
200 auto x = v.
Read(use_dev);
216 MFEM_ASSERT(
size == v.
size,
"incompatible Vectors!");
221 auto x = v.
Read(use_dev);
237 MFEM_ASSERT(
size == v.
size,
"incompatible Vectors!");
242 auto x = v.
Read(use_dev);
249 MFEM_ASSERT(
size == Va.
size,
"incompatible Vectors!");
256 auto x = Va.
Read(use_dev);
264 MFEM_ASSERT(
size == Va.
size,
"incompatible Vectors!");
268 auto x = Va.
Read(use_dev);
269 auto y =
Write(use_dev);
276 MFEM_ASSERT(v.
Size() + offset <=
size,
"invalid sub-vector");
278 const int vs = v.
Size();
281 for (
int i = 0; i < vs; i++)
289 MFEM_ASSERT(v.
Size() + offset <=
size,
"invalid sub-vector");
291 const int vs = v.
Size();
294 for (
int i = 0; i < vs; i++)
319 "incompatible Vectors!");
321#if !defined(MFEM_USE_LEGACY_OPENMP)
323 const int N = v.
size;
325 auto x1 = v1.
Read(use_dev);
326 auto x2 = v2.
Read(use_dev);
327 auto y = v.
Write(use_dev);
330 #pragma omp parallel for
331 for (
int i = 0; i < v.
size; i++)
341 "incompatible Vectors!");
347 else if (
alpha == 1.0)
353#if !defined(MFEM_USE_LEGACY_OPENMP)
355 const int N = v.
size;
357 auto d_x = v1.
Read(use_dev);
358 auto d_y = v2.
Read(use_dev);
359 auto d_z = v.
Write(use_dev);
362 d_z[i] = d_x[i] +
alpha * d_y[i];
367 const int s = v.
size;
368 #pragma omp parallel for
369 for (
int i = 0; i <
s; i++)
371 vp[i] = v1p[i] +
alpha*v2p[i];
380 "incompatible Vectors!");
392#if !defined(MFEM_USE_LEGACY_OPENMP)
394 const int N = x.
size;
396 auto xd = x.
Read(use_dev);
397 auto yd = y.
Read(use_dev);
398 auto zd = z.
Write(use_dev);
401 zd[i] =
a * (xd[i] + yd[i]);
407 const int s = x.
size;
408 #pragma omp parallel for
409 for (
int i = 0; i <
s; i++)
411 zp[i] =
a * (xp[i] + yp[i]);
421 "incompatible Vectors!");
447#if !defined(MFEM_USE_LEGACY_OPENMP)
449 const int N = x.
size;
451 auto xd = x.
Read(use_dev);
452 auto yd = y.
Read(use_dev);
453 auto zd = z.
Write(use_dev);
456 zd[i] =
a * xd[i] +
b * yd[i];
462 const int s = x.
size;
463 #pragma omp parallel for
464 for (
int i = 0; i <
s; i++)
466 zp[i] =
a * xp[i] +
b * yp[i];
475 "incompatible Vectors!");
477#if !defined(MFEM_USE_LEGACY_OPENMP)
479 const int N = x.
size;
481 auto xd = x.
Read(use_dev);
482 auto yd = y.
Read(use_dev);
483 auto zd = z.
Write(use_dev);
486 zd[i] = xd[i] - yd[i];
492 const int s = x.
size;
493 #pragma omp parallel for
494 for (
int i = 0; i <
s; i++)
496 zp[i] = xp[i] - yp[i];
504 "incompatible Vectors!");
516#if !defined(MFEM_USE_LEGACY_OPENMP)
518 const int N = x.
size;
520 auto xd = x.
Read(use_dev);
521 auto yd = y.
Read(use_dev);
522 auto zd = z.
Write(use_dev);
525 zd[i] =
a * (xd[i] - yd[i]);
531 const int s = x.
size;
532 #pragma omp parallel for
533 for (
int i = 0; i <
s; i++)
535 zp[i] =
a * (xp[i] - yp[i]);
546 MFEM_VERIFY(
size == 3,
"Only 3D vectors supported in cross.");
547 MFEM_VERIFY(vin.
Size() == 3,
"Only 3D vectors supported in cross.");
549 vout(0) =
data[1]*vin(2)-
data[2]*vin(1);
550 vout(1) =
data[2]*vin(0)-
data[0]*vin(2);
551 vout(2) =
data[0]*vin(1)-
data[1]*vin(0);
557 "incompatible Vectors!");
562 auto l = lo.
Read(use_dev);
563 auto h = hi.
Read(use_dev);
564 auto m =
Write(use_dev);
571 else if (m[i] > h[i])
580 const int n = dofs.
Size();
583 auto d_y = elemvect.
Write(use_dev);
584 auto d_X =
Read(use_dev);
585 auto d_dofs = dofs.
Read(use_dev);
588 const int dof_i = d_dofs[i];
589 d_y[i] = dof_i >= 0 ? d_X[dof_i] : -d_X[-dof_i-1];
596 const int n = dofs.
Size();
597 for (
int i = 0; i < n; i++)
599 const int j = dofs[i];
600 elem_data[i] = (j >= 0) ?
data[j] : -
data[-1-j];
607 const int n = dofs.
Size();
610 auto d_dofs = dofs.
Read(use_dev);
613 const int j = d_dofs[i];
627 MFEM_ASSERT(dofs.
Size() <= elemvect.
Size(),
628 "Size mismatch: length of dofs is " << dofs.
Size()
629 <<
", length of elemvect is " << elemvect.
Size());
632 const int n = dofs.
Size();
635 auto d_y = elemvect.
Read(use_dev);
636 auto d_dofs = dofs.
Read(use_dev);
639 const int dof_i = d_dofs[i];
646 d_X[-1-dof_i] = -d_y[i];
655 const int n = dofs.
Size();
656 for (
int i = 0; i < n; i++)
658 const int j= dofs[i];
672 MFEM_ASSERT(dofs.
Size() <= elemvect.
Size(),
"Size mismatch: "
673 "length of dofs is " << dofs.
Size() <<
674 ", length of elemvect is " << elemvect.
Size());
677 const int n = dofs.
Size();
678 auto d_y = elemvect.
Read(use_dev);
680 auto d_dofs = dofs.
Read(use_dev);
683 const int j = d_dofs[i];
698 const int n = dofs.
Size();
699 for (
int i = 0; i < n; i++)
701 const int j = dofs[i];
716 MFEM_ASSERT(dofs.
Size() <= elemvect.
Size(),
"Size mismatch: "
717 "length of dofs is " << dofs.
Size() <<
718 ", length of elemvect is " << elemvect.
Size());
721 const int n = dofs.
Size();
723 auto d_x = elemvect.
Read(use_dev);
724 auto d_dofs = dofs.
Read(use_dev);
727 const int j = d_dofs[i];
730 d_y[j] +=
a * d_x[i];
734 d_y[-1-j] -=
a * d_x[i];
742 const int n = dofs.
Size();
744 Vector dofs_vals(n, use_dev ?
748 auto d_dofs_vals = dofs_vals.
Write(use_dev);
749 auto d_dofs = dofs.
Read(use_dev);
750 mfem::forall_switch(use_dev, n, [=] MFEM_HOST_DEVICE (
int i) { d_dofs_vals[i] = d_data[d_dofs[i]]; });
752 mfem::forall_switch(use_dev, n, [=] MFEM_HOST_DEVICE (
int i) { d_data[d_dofs[i]] = d_dofs_vals[i]; });
757 if (!
size) {
return; }
767 if ( i % width == 0 )
779#ifdef MFEM_USE_ADIOS2
781 const std::string& variable_name)
const
783 if (!
size) {
return; }
785 os.engine.Put(variable_name, &
data[0] );
792 std::ios::fmtflags old_fmt = os.flags();
793 os.setf(std::ios::scientific);
794 std::streamsize old_prec = os.precision(14);
799 for (i = 0; i <
size; i++)
804 os.precision(old_prec);
810 os <<
"size: " <<
size <<
'\n';
813 os <<
"hash: " << hf.
GetHash() <<
'\n';
823 srand((
unsigned)seed);
826 for (
int i = 0; i <
size; i++)
845 return std::abs(
data[0]);
854 for (
int i = 0; i <
size; i++)
856 max = std::max(std::abs(
data[i]), max);
865 for (
int i = 0; i <
size; i++)
867 sum += std::abs(
data[i]);
874 MFEM_ASSERT(
p > 0.0,
"Vector::Normlp");
896 return std::abs(
data[0]);
902 for (
int i = 0; i <
size; i++)
907 if (scale <= absdata)
909 sum = 1.0 + sum * std::pow(scale / absdata,
p);
913 sum += std::pow(absdata / scale,
p);
916 return scale * std::pow(sum, 1.0/
p);
929 for (
int i = 1; i <
size; i++)
941static __global__
void cuKernelMin(
const int N,
real_t *gdsr,
const real_t *x)
943 __shared__
real_t s_min[MFEM_CUDA_BLOCKS];
944 const int n = blockDim.x*blockIdx.x + threadIdx.x;
945 if (n>=N) {
return; }
946 const int bid = blockIdx.x;
947 const int tid = threadIdx.x;
948 const int bbd = bid*blockDim.x;
949 const int rid = bbd+tid;
951 for (
int workers=blockDim.x>>1; workers>0; workers>>=1)
954 if (tid >= workers) {
continue; }
955 if (rid >= N) {
continue; }
956 const int dualTid = tid + workers;
957 if (dualTid >= N) {
continue; }
958 const int rdd = bbd+dualTid;
959 if (rdd >= N) {
continue; }
960 if (dualTid >= blockDim.x) {
continue; }
961 s_min[tid] = fmin(s_min[tid], s_min[dualTid]);
963 if (tid==0) { gdsr[bid] = s_min[0]; }
966static Array<real_t> cuda_reduce_buf;
970 const int tpb = MFEM_CUDA_BLOCKS;
971 const int blockSize = MFEM_CUDA_BLOCKS;
972 const int gridSize = (N+blockSize-1)/blockSize;
973 const int min_sz = (N%tpb)==0? (N/tpb) : (1+N/tpb);
974 cuda_reduce_buf.
SetSize(min_sz);
975 Memory<real_t> &buf = cuda_reduce_buf.
GetMemory();
977 cuKernelMin<<<gridSize,blockSize>>>(N, d_min, X);
978 MFEM_GPU_CHECK(cudaGetLastError());
980 real_t min = std::numeric_limits<real_t>::infinity();
981 for (
int i = 0; i < min_sz; i++) { min = std::min(min, h_min[i]); }
985static __global__
void cuKernelDot(
const int N,
real_t *gdsr,
988 __shared__
real_t s_dot[MFEM_CUDA_BLOCKS];
989 const int n = blockDim.x*blockIdx.x + threadIdx.x;
990 if (n>=N) {
return; }
991 const int bid = blockIdx.x;
992 const int tid = threadIdx.x;
993 const int bbd = bid*blockDim.x;
994 const int rid = bbd+tid;
995 s_dot[tid] = y ? (x[n] * y[n]) : x[n];
996 for (
int workers=blockDim.x>>1; workers>0; workers>>=1)
999 if (tid >= workers) {
continue; }
1000 if (rid >= N) {
continue; }
1001 const int dualTid = tid + workers;
1002 if (dualTid >= N) {
continue; }
1003 const int rdd = bbd+dualTid;
1004 if (rdd >= N) {
continue; }
1005 if (dualTid >= blockDim.x) {
continue; }
1006 s_dot[tid] += s_dot[dualTid];
1008 if (tid==0) { gdsr[bid] = s_dot[0]; }
1013 const int tpb = MFEM_CUDA_BLOCKS;
1014 const int blockSize = MFEM_CUDA_BLOCKS;
1015 const int gridSize = (N+blockSize-1)/blockSize;
1016 const int dot_sz = (N%tpb)==0? (N/tpb) : (1+N/tpb);
1018 Memory<real_t> &buf = cuda_reduce_buf.
GetMemory();
1020 cuKernelDot<<<gridSize,blockSize>>>(N, d_dot, X, Y);
1021 MFEM_GPU_CHECK(cudaGetLastError());
1024 for (
int i = 0; i < dot_sz; i++) { dot += h_dot[i]; }
1030static __global__
void hipKernelMin(
const int N,
real_t *gdsr,
const real_t *x)
1032 __shared__
real_t s_min[MFEM_HIP_BLOCKS];
1033 const int n = hipBlockDim_x*hipBlockIdx_x + hipThreadIdx_x;
1034 if (n>=N) {
return; }
1035 const int bid = hipBlockIdx_x;
1036 const int tid = hipThreadIdx_x;
1037 const int bbd = bid*hipBlockDim_x;
1038 const int rid = bbd+tid;
1040 for (
int workers=hipBlockDim_x>>1; workers>0; workers>>=1)
1043 if (tid >= workers) {
continue; }
1044 if (rid >= N) {
continue; }
1045 const int dualTid = tid + workers;
1046 if (dualTid >= N) {
continue; }
1047 const int rdd = bbd+dualTid;
1048 if (rdd >= N) {
continue; }
1049 if (dualTid >= hipBlockDim_x) {
continue; }
1050 s_min[tid] = std::min(s_min[tid], s_min[dualTid]);
1052 if (tid==0) { gdsr[bid] = s_min[0]; }
1055static Array<real_t> hip_reduce_buf;
1057static real_t hipVectorMin(
const int N,
const real_t *X)
1059 const int tpb = MFEM_HIP_BLOCKS;
1060 const int blockSize = MFEM_HIP_BLOCKS;
1061 const int gridSize = (N+blockSize-1)/blockSize;
1062 const int min_sz = (N%tpb)==0 ? (N/tpb) : (1+N/tpb);
1063 hip_reduce_buf.
SetSize(min_sz);
1064 Memory<real_t> &buf = hip_reduce_buf.
GetMemory();
1066 hipLaunchKernelGGL(hipKernelMin,gridSize,blockSize,0,0,N,d_min,X);
1067 MFEM_GPU_CHECK(hipGetLastError());
1069 real_t min = std::numeric_limits<real_t>::infinity();
1070 for (
int i = 0; i < min_sz; i++) { min = std::min(min, h_min[i]); }
1074static __global__
void hipKernelDot(
const int N,
real_t *gdsr,
1077 __shared__
real_t s_dot[MFEM_HIP_BLOCKS];
1078 const int n = hipBlockDim_x*hipBlockIdx_x + hipThreadIdx_x;
1079 if (n>=N) {
return; }
1080 const int bid = hipBlockIdx_x;
1081 const int tid = hipThreadIdx_x;
1082 const int bbd = bid*hipBlockDim_x;
1083 const int rid = bbd+tid;
1084 s_dot[tid] = y ? (x[n] * y[n]) : x[n];
1085 for (
int workers=hipBlockDim_x>>1; workers>0; workers>>=1)
1088 if (tid >= workers) {
continue; }
1089 if (rid >= N) {
continue; }
1090 const int dualTid = tid + workers;
1091 if (dualTid >= N) {
continue; }
1092 const int rdd = bbd+dualTid;
1093 if (rdd >= N) {
continue; }
1094 if (dualTid >= hipBlockDim_x) {
continue; }
1095 s_dot[tid] += s_dot[dualTid];
1097 if (tid==0) { gdsr[bid] = s_dot[0]; }
1102 const int tpb = MFEM_HIP_BLOCKS;
1103 const int blockSize = MFEM_HIP_BLOCKS;
1104 const int gridSize = (N+blockSize-1)/blockSize;
1105 const int dot_sz = (N%tpb)==0 ? (N/tpb) : (1+N/tpb);
1106 hip_reduce_buf.
SetSize(dot_sz);
1107 Memory<real_t> &buf = hip_reduce_buf.
GetMemory();
1109 hipLaunchKernelGGL(hipKernelDot,gridSize,blockSize,0,0,N,d_dot,X,Y);
1110 MFEM_GPU_CHECK(hipGetLastError());
1113 for (
int i = 0; i < dot_sz; i++) { dot += h_dot[i]; }
1120 MFEM_ASSERT(
size == v.
size,
"incompatible Vectors!");
1121 if (
size == 0) {
return 0.0; }
1124#if defined(MFEM_USE_CUDA) || defined(MFEM_USE_HIP) || defined(MFEM_USE_OPENMP)
1125 auto m_data =
Read(use_dev);
1129 auto v_data = v.
Read(use_dev);
1131 if (!use_dev) {
goto vector_dot_cpu; }
1136 return occa::linalg::dot<real_t,real_t,real_t>(
1144 return cuVectorDot(
size, m_data, v_data);
1151 return hipVectorDot(
size, m_data, v_data);
1155#ifdef MFEM_USE_OPENMP
1158#define MFEM_USE_OPENMP_DETERMINISTIC_DOT
1159#ifdef MFEM_USE_OPENMP_DETERMINISTIC_DOT
1162 #pragma omp parallel
1164 const int nt = omp_get_num_threads();
1167 const int tid = omp_get_thread_num();
1168 const int stride = (
size + nt - 1)/nt;
1169 const int start = tid*stride;
1170 const int stop = std::min(start + stride,
size);
1172 for (
int i = start; i < stop; i++)
1174 my_dot += m_data[i] * v_data[i];
1177 th_dot(tid) = my_dot;
1179 return th_dot.
Sum();
1183 #pragma omp parallel for reduction(+:prod)
1184 for (
int i = 0; i <
size; i++)
1186 prod += m_data[i] * v_data[i];
1195 auto v_data_ = v.
Read();
1196 auto m_data_ =
Read();
1198 dot.UseDevice(
true);
1199 auto d_dot = dot.Write();
1203 d_dot[0] += m_data_[i] * v_data_[i];
1205 dot.HostReadWrite();
1217 auto m_data =
Read(use_dev);
1219 if (!use_dev) {
goto vector_min_cpu; }
1231 return cuVectorMin(
size, m_data);
1238 return hipVectorMin(
size, m_data);
1242#ifdef MFEM_USE_OPENMP
1245 real_t minimum = m_data[0];
1246 #pragma omp parallel for reduction(min:minimum)
1247 for (
int i = 0; i <
size; i++)
1249 minimum = std::min(minimum, m_data[i]);
1258 auto m_data_ =
Read();
1265 d_min[0] = (d_min[0]<m_data_[i])?d_min[0]:m_data_[i];
1273 for (
int i = 1; i <
size; i++)
1275 if (m_data[i] < minimum)
1277 minimum = m_data[i];
1285 if (
size == 0) {
return 0.0; }
1292 return cuVectorDot(
size,
Read(),
nullptr);
1298 return hipVectorDot(
size,
Read(),
nullptr);
1304 auto d_data =
Read();
1307 auto d_sum = sum.
Write();
1311 d_sum[0] += d_data[i];
1321 for (
int i = 0; i <
size; i++)
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
int Size() const
Return the logical size of the array.
bool UseDevice() const
Return the device flag of the Memory object used by the Array.
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
static MemoryType GetHostMemoryType()
Get the current Host MemoryType. This is the MemoryType used by most MFEM classes when allocating mem...
static bool Allows(unsigned long b_mask)
Return true if any of the backends in the backend mask, b_mask, are allowed.
static MemoryType GetDeviceMemoryType()
Get the current Device MemoryType. This is the MemoryType used by most MFEM classes when allocating m...
Hash function for data sequences.
std::string GetHash() const
Return the hash string for the current sequence and reset (clear) the sequence.
HashFunction & AppendDoubles(const real_t *doubles, size_t num_doubles)
Add a sequence of doubles for hashing, given as a c-array.
T * Write(MemoryClass mc, int size)
Get write-only access to the memory with the given MemoryClass.
void CopyFromHost(const T *src, int size)
Copy size entries from the host pointer src to *this.
T * ReadWrite(MemoryClass mc, int size)
Get read-write access to the memory with the given MemoryClass.
MemoryType GetMemoryType() const
Return a MemoryType that is currently valid. If both the host and the device pointers are currently v...
bool Empty() const
Return true if the Memory object is empty, see Reset().
const T * Read(MemoryClass mc, int size) const
Get read-only access to the memory with the given MemoryClass.
void CopyFrom(const Memory &src, int size)
Copy size entries from src to *this.
void New(int size)
Allocate host memory for size entries with the current host memory type returned by MemoryManager::Ge...
void Randomize(int seed=0)
Set random values in the vector.
void PrintHash(std::ostream &out) const
Print the Vector size and hash of its data.
real_t & Elem(int i)
Access Vector entries. Index i = 0 .. size-1.
void SetVector(const Vector &v, int offset)
virtual const real_t * HostRead() const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), false).
virtual const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read(vec.GetMemory(), vec.Size(), on_dev).
void median(const Vector &lo, const Vector &hi)
v = median(v,lo,hi) entrywise. Implementation assumes lo <= hi.
void Neg()
(*this) = -(*this)
void Print(std::ostream &out=mfem::out, int width=8) const
Prints vector to stream out.
virtual real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), on_dev).
real_t Normlinf() const
Returns the l_infinity norm of the vector.
real_t Norml1() const
Returns the l_1 norm of the vector.
void SetSubVector(const Array< int > &dofs, const real_t value)
Set the entries listed in dofs to the given value.
void AddElementVector(const Array< int > &dofs, const Vector &elemvect)
Add elements of the elemvect Vector to the entries listed in dofs. Negative dof values cause the -dof...
real_t operator*(const real_t *) const
Dot product with a double * array.
void AddSubVector(const Vector &v, int offset)
Vector & operator*=(real_t c)
real_t Norml2() const
Returns the l2 norm of the vector.
void Load(std::istream **in, int np, int *dim)
Reads a vector from multiple files.
Vector & Set(const real_t a, const Vector &x)
(*this) = a * x
real_t Max() const
Returns the maximal element of the vector.
virtual bool UseDevice() const
Return the device flag of the Memory object used by the Vector.
int Size() const
Returns the size of the vector.
virtual void UseDevice(bool use_dev) const
Enable execution of Vector operations using the mfem::Device.
real_t Sum() const
Return the sum of the vector entries.
void Print_HYPRE(std::ostream &out) const
Prints vector to stream out in HYPRE_Vector format.
void SetSize(int s)
Resize the vector to size s.
void Reciprocal()
(*this)(i) = 1.0 / (*this)(i)
virtual real_t * HostWrite()
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), false).
real_t Normlp(real_t p) const
Returns the l_p norm of the vector.
Vector & operator-=(real_t c)
Vector & operator=(const real_t *v)
Copy Size() entries from v.
void SetSubVectorComplement(const Array< int > &dofs, const real_t val)
Set all vector entries NOT in the dofs Array to the given val.
virtual real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(vec.GetMemory(), vec.Size(), false).
real_t Min() const
Returns the minimal element of the vector.
void GetSubVector(const Array< int > &dofs, Vector &elemvect) const
Extract entries listed in dofs to the output Vector elemvect.
Vector & operator+=(real_t c)
virtual real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(vec.GetMemory(), vec.Size(), on_dev).
Vector & Add(const real_t a, const Vector &Va)
(*this) += a * Va
real_t & operator()(int i)
Access Vector entries using () for 0-based indexing.
void cross3D(const Vector &vin, Vector &vout) const
Vector & operator/=(real_t c)
MFEM_HOST_DEVICE real_t Norml2(const int size, const T *data)
Returns the l2 norm of the Vector with given size and data.
real_t infinity()
Define a shortcut for std::numeric_limits<double>::infinity()
real_t rand_real()
Generate a random real_t number in the interval [0,1) using rand().
void add(const Vector &v1, const Vector &v2, Vector &v)
bool DeviceCanUseOcca()
Function that determines if an OCCA kernel should be used, based on the current mfem::Device configur...
void subtract(const Vector &x, const Vector &y, Vector &z)
const occa::memory OccaMemoryRead(const Memory< T > &mem, size_t size)
Wrap a Memory object as occa::memory for read only access with the mfem::Device MemoryClass....
void forall(int N, lambda &&body)
void forall_switch(bool use_dev, int N, lambda &&body)
real_t p(const Vector &x, real_t t)
@ DEBUG_DEVICE
[device] Debug backend: host memory is READ/WRITE protected while a device is in use....
@ HIP_MASK
Biwise-OR of all HIP backends.
@ CUDA_MASK
Biwise-OR of all CUDA backends.
@ OMP_MASK
Biwise-OR of all OpenMP backends.