12 #ifndef MFEM_SPARSEMAT_HPP 13 #define MFEM_SPARSEMAT_HPP 17 #include "../general/backends.hpp" 18 #include "../general/mem_alloc.hpp" 19 #include "../general/mem_manager.hpp" 20 #include "../general/device.hpp" 21 #include "../general/table.hpp" 22 #include "../general/globals.hpp" 25 #if defined(MFEM_USE_HIP) 26 #if (HIP_VERSION_MAJOR * 100 + HIP_VERSION_MINOR) < 502 27 #include <hipsparse.h> 29 #include <hipsparse/hipsparse.h> 38 #if defined(__alignas_is_defined) 82 #ifdef MFEM_USE_MEMALLOC 98 #ifdef MFEM_USE_CUDA_OR_HIP 105 #if defined(MFEM_USE_CUDA) 110 #if CUDA_VERSION >= 10010 114 #else // CUDA_VERSION >= 10010 116 #endif // CUDA_VERSION >= 10010 118 #else // defined(MFEM_USE_CUDA) 126 #endif // defined(MFEM_USE_CUDA) 127 #endif // MFEM_USE_CUDA_OR_HIP 147 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n);
154 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n,
bool ownij,
155 bool owna,
bool issorted);
224 inline const int *
GetI()
const {
return I; }
229 inline const int *
GetJ()
const {
return J; }
239 const int *
ReadI(
bool on_dev =
true)
const 255 const int *
ReadJ(
bool on_dev =
true)
const 285 int RowSize(
const int i)
const;
322 virtual double &
Elem(
int i,
int j);
325 virtual const double &
Elem(
int i,
int j)
const;
353 const double a = 1.0)
const;
366 const double a = 1.0)
const;
410 const double a=1.0)
const;
527 double sc,
bool use_abs_diag =
false)
const;
531 double sc = 1.0,
bool use_abs_diag =
false)
const;
535 double sc = 1.0)
const;
539 double sc = 1.0)
const;
549 void Finalize(
int skip_zeros,
bool fix_empty_rows);
559 void Threshold(
double tol,
bool fix_empty_rows =
false);
574 inline void SetColPtr(
const int row)
const;
585 inline void _Add_(
const int col,
const double a)
588 inline void _Set_(
const int col,
const double a)
591 inline double _Get_(
const int col)
const;
593 inline double &
SearchRow(
const int row,
const int col);
594 inline void _Add_(
const int row,
const int col,
const double a)
596 inline void _Set_(
const int row,
const int col,
const double a)
599 void Set(
const int i,
const int j,
const double val);
600 void Add(
const int i,
const int j,
const double val);
634 void ScaleRow(
const int row,
const double scale);
722 SparseMatrix *
Transpose(
const SparseMatrix &A);
733 SparseMatrix *
Mult(
const SparseMatrix &A,
const SparseMatrix &B,
734 SparseMatrix *OAB = NULL);
737 SparseMatrix *
TransposeMult(
const SparseMatrix &A,
const SparseMatrix &B);
741 const AbstractSparseMatrix &B);
744 DenseMatrix *
Mult(
const SparseMatrix &A, DenseMatrix &B);
747 DenseMatrix *
RAP(
const SparseMatrix &A, DenseMatrix &P);
750 DenseMatrix *
RAP(DenseMatrix &A,
const SparseMatrix &P);
754 SparseMatrix *
RAP(
const SparseMatrix &A,
const SparseMatrix &R,
755 SparseMatrix *ORAP = NULL);
758 SparseMatrix *
RAP(
const SparseMatrix &Rt,
const SparseMatrix &A,
759 const SparseMatrix &P);
762 SparseMatrix *
Mult_AtDA(
const SparseMatrix &A,
const Vector &D,
763 SparseMatrix *OAtDA = NULL);
767 SparseMatrix *
Add(
const SparseMatrix & A,
const SparseMatrix & B);
769 SparseMatrix *
Add(
double a,
const SparseMatrix & A,
double b,
770 const SparseMatrix & B);
772 SparseMatrix *
Add(Array<SparseMatrix *> & Ai);
775 void Add(
const SparseMatrix &A,
double alpha, DenseMatrix &B);
778 DenseMatrix *
OuterProduct(
const DenseMatrix &A,
const DenseMatrix &B);
781 SparseMatrix *
OuterProduct(
const DenseMatrix &A,
const SparseMatrix &B);
784 SparseMatrix *
OuterProduct(
const SparseMatrix &A,
const DenseMatrix &B);
787 SparseMatrix *
OuterProduct(
const SparseMatrix &A,
const SparseMatrix &B);
799 for (
int i = 0; i <
width; i++)
804 for (RowNode *node_p =
Rows[row]; node_p != NULL; node_p = node_p->Prev)
814 for (
int i = 0; i <
width; i++)
819 for (
int j =
I[row], end =
I[row+1]; j < end; j++)
832 node_p = node_p->Prev)
853 #ifdef MFEM_USE_MEMALLOC 856 node_p =
new RowNode;
859 node_p->Column = col;
863 return node_p->Value;
868 MFEM_VERIFY(j != -1,
"Entry for column " << col <<
" is not allocated.");
878 return (node_p == NULL) ? 0.0 : node_p->Value;
883 return (j == -1) ? 0.0 :
A[j];
893 for (node_p =
Rows[row]; 1; node_p = node_p->Prev)
897 #ifdef MFEM_USE_MEMALLOC 900 node_p =
new RowNode;
902 node_p->Prev =
Rows[row];
903 node_p->Column = col;
908 else if (node_p->Column == col)
913 return node_p->Value;
917 int *Ip =
I+row, *Jp =
J;
918 for (
int k = Ip[0], end = Ip[1]; k < end; k++)
925 MFEM_ABORT(
"Could not find entry for row = " << row <<
", col = " << col);
Memory< int > I
Array with size (height+1) containing the row offsets.
void _Add_(const int row, const int col, const double a)
const double * HostReadData() const
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
SparseMatrix * TransposeAbstractSparseMatrix(const AbstractSparseMatrix &A, int useActualWidth)
Transpose of a sparse matrix. A does not need to be a CSR matrix.
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
void _Add_(const int col, const double a)
Add a value to an entry in the "current row". See SetColPtr().
void Clear()
Clear the contents of the SparseMatrix.
void EliminateCol(int col, DiagonalPolicy dpolicy=DIAG_ZERO)
Eliminates the column col from the matrix.
SparseMatrix * At
Transpose of A. Owned. Used to perform MultTranspose() on devices.
int Size() const
For backward compatibility, define Size() to be synonym of Height().
static MemoryClass GetHostMemoryClass()
Get the current Host MemoryClass. This is the MemoryClass used by most MFEM host Memory objects...
void GetDiag(Vector &d) const
Returns the Diagonal of A.
void PrintMM(std::ostream &out=mfem::out) const
Prints matrix in Matrix Market sparse format.
void _Set_(const int row, const int col, const double a)
bool OwnsData() const
Get the data ownership flag (A array).
double GetRowNorml1(int irow) const
For i = irow compute .
virtual void Finalize(int skip_zeros=1)
Finalize the matrix initialization, switching the storage format from LIL to CSR. ...
void MakeRef(const SparseMatrix &master)
Clear the contents of the SparseMatrix and make it a reference to master.
double & SearchRow(const int col)
Perform a fast search for an entry in the "current row". See SetColPtr().
const Memory< int > & GetMemoryI() const
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
void PrintCSR(std::ostream &out) const
Prints matrix to stream out in hypre_CSRMatrix format.
double GetJacobiScaling() const
Determine appropriate scaling for Jacobi iteration.
int RowSize(const int i) const
Returns the number of elements in row i.
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
void SetColPtr(const int row) const
Initialize the SparseMatrix for fast access to the entries of the given row which becomes the "curren...
int * GetJ()
Return the array J.
Abstract data type for sparse matrices.
double IsSymmetric() const
Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix.
SparseMatrix & operator+=(const SparseMatrix &B)
Add the sparse matrix 'B' to '*this'. This operation will cause an error if '*this' is finalized and ...
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...
Data type dense matrix using column-major storage.
int * GetI()
Return the array I.
Abstract data type for matrix inverse.
void EliminateRowColMultipleRHS(int rc, const Vector &sol, DenseMatrix &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Similar to EliminateRowCol(int, const double, Vector &, DiagonalPolicy), but multiple values for elim...
virtual void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
void ClearGPUSparse()
Clear the cuSPARSE/hipSPARSE descriptors. This must be called after releasing the device memory of A...
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
void LoseData()
Lose the ownership of the graph (I, J) and data (A) arrays.
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
void AddRow(const int row, const Array< int > &cols, const Vector &srow)
double * GetRowEntries(const int row)
Return a pointer to the entries in a row.
void SortColumnIndices()
Sort the column indices corresponding to each row.
Memory< double > & GetMemoryData()
Memory< int > & GetMemoryI()
cusparseDnVecDescr_t vecY_descr
double * HostReadWriteData()
void _Set_(const int col, const double a)
Set an entry in the "current row". See SetColPtr().
SparseMatrix * Mult_AtDA(const SparseMatrix &A, const Vector &D, SparseMatrix *OAtDA)
Matrix multiplication A^t D A. All matrices must be finalized.
const Memory< double > & GetMemoryData() const
void Gauss_Seidel_back(const Vector &x, Vector &y) const
void ScaleRow(const int row, const double scale)
double * GetData()
Return the element data, i.e. the array A.
virtual MatrixInverse * Inverse() const
This virtual method is not supported: it always returns NULL.
Memory< int > & GetMemoryJ()
DenseMatrix * ToDenseMatrix() const
Produces a DenseMatrix from a SparseMatrix.
void UseGPUSparse(bool useGPUSparse_=true)
Runtime option to use cuSPARSE or hipSPARSE. Only valid when using a CUDA or HIP backend.
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
void Jacobi3(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) const
void MoveDiagonalFirst()
Move the diagonal entry to the first position in each row, preserving the order of the rest of the co...
void SetGraphOwner(bool ownij)
Set the graph ownership flag (I and J arrays).
ID for class SparseMatrix.
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
void Set(const int i, const int j, const double val)
hipsparseDnVecDescr_t vecY_descr
void GetBlocks(Array2D< SparseMatrix *> &blocks) const
MFEM_DEPRECATED void ClearCuSparse()
Deprecated equivalent of ClearGPUSparse().
void ScaleColumns(const Vector &sr)
this = this * diag(sr);
void GetRowSums(Vector &x) const
For all i compute .
virtual ~SparseMatrix()
Destroys sparse matrix.
double f(const Vector &xvec)
bool Empty() const
Check if the SparseMatrix is empty.
bool isSorted
Are the columns sorted already.
void ClearColPtr() const
Reset the "current row" set by calling SetColPtr(). This method must be called between any two calls ...
Memory< double > A
Array with size I[height], containing the actual entries of the sparse matrix, as indexed by the I ar...
bool Empty() const
Return true if the Memory object is empty, see Reset().
SparseMatrix()
Create an empty SparseMatrix.
static MemoryClass GetDeviceMemoryClass()
Get the current Device MemoryClass. This is the MemoryClass used by most MFEM device kernels to acces...
hipsparseSpMatDescr_t matA_descr
void SetWidth(int width_=-1)
Change the width of a SparseMatrix.
void EnsureMultTranspose() const
Ensures that the matrix is capable of performing MultTranspose(), AddMultTranspose(), and AbsMultTranspose().
const int * HostReadJ() const
virtual void PrintMatlab(std::ostream &out=mfem::out) const
Prints matrix in matlab format.
int * ReadWriteI(bool on_dev=true)
int CountSmallElems(double tol) const
Count the number of entries with |a_ij| <= tol.
static int SparseMatrixCount
const double * ReadData(bool on_dev=true) const
double InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
bool OwnsGraph() const
Get the graph ownership flag (I and J arrays).
void SetDiagIdentity()
If a row contains only one diag entry of zero, set it to 1.
MFEM_DEPRECATED void UseCuSparse(bool useCuSparse_=true)
Deprecated equivalent of UseGPUSparse().
void ScaleRows(const Vector &sl)
this = diag(sl) * this;
static cusparseHandle_t handle
void Swap< SparseMatrix >(SparseMatrix &a, SparseMatrix &b)
Specialization of the template function Swap<> for class SparseMatrix.
DenseMatrix * OuterProduct(const DenseMatrix &A, const DenseMatrix &B)
Produces a block matrix with blocks A_{ij}*B.
void DiagScale(const Vector &b, Vector &x, double sc=1.0, bool use_abs_diag=false) const
x = sc b / A_ii. When use_abs_diag = true, |A_ii| is used.
int * WriteI(bool on_dev=true)
int Capacity() const
Return the size of the allocated memory.
Set the diagonal value to one.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
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...
bool RowIsEmpty(const int row) const
bool Finalized() const
Returns whether or not CSR format has been finalized.
void Jacobi2(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) const
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Add(const int i, const int j, const double val)
Dynamic 2D array using row-major layout.
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
virtual void MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
Type
Enumeration defining IDs for some classes derived from Operator.
void SparseMatrixFunction(SparseMatrix &S, double(*f)(double))
Applies f() to each element of the matrix (after it is finalized).
const int * ReadI(bool on_dev=true) const
double _Get_(const int col) const
Read the value of an entry in the "current row". See SetColPtr().
void EliminateRowColDiag(int rc, double value)
Perform elimination and set the diagonal entry to the given value.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
MemoryType
Memory types supported by MFEM.
void SetSubMatrixTranspose(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Gauss_Seidel_forw(const Vector &x, Vector &y) const
Gauss-Seidel forward and backward iterations over a vector x.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
int ActualWidth() const
Returns the actual Width of the matrix.
void EliminateRowCol(int rc, const double sol, Vector &rhs, DiagonalPolicy dpolicy=DIAG_ONE)
Eliminate row rc and column rc and modify the rhs using sol.
void Transpose(const Table &A, Table &At, int ncols_A_)
Transpose a Table.
void Threshold(double tol, bool fix_empty_rows=false)
Remove entries smaller in absolute value than a given tolerance tol. If fix_empty_rows is true...
const int * GetI() const
Return the array I, const version.
const double * GetData() const
Return the element data, i.e. the array A, const version.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
RowNode ** Rows
Array of linked lists, one for every row. This array represents the linked list (LIL) storage format...
void Jacobi(const Vector &b, const Vector &x0, Vector &x1, double sc, bool use_abs_diag=false) const
const int * HostReadI() const
hipsparseDnVecDescr_t vecX_descr
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
int * WriteJ(bool on_dev=true)
void EliminateRow(int row, const double sol, Vector &rhs)
Eliminates a column from the transpose matrix.
void BuildTranspose() const
Build and store internally the transpose of this matrix which will be used in the methods AddMultTran...
MemAlloc< RowNode, 1024 > RowNodeAlloc
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.
SparseMatrix * TransposeMult(const SparseMatrix &A, const SparseMatrix &B)
C = A^T B.
virtual void EliminateZeroRows(const double threshold=1e-12)
If a row contains only zeros, set its diagonal to 1.
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
DiagonalPolicy
Defines operator diagonal policy upon elimination of rows and/or columns.
double & operator()(int i, int j)
Returns reference to A[i][j].
void AbsMult(const Vector &x, Vector &y) const
y = |A| * x, using entry-wise absolute values of matrix A
void PrintInfo(std::ostream &out) const
Print various sparse matrix statistics.
void EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
void OverrideSize(int height_, int width_)
Sets the height and width of the matrix.
const int * ReadJ(bool on_dev=true) const
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
SparseMatrix & operator=(const SparseMatrix &rhs)
Assignment operator: deep copy.
void AbsMultTranspose(const Vector &x, Vector &y) const
y = |At| * x, using entry-wise absolute values of the transpose of matrix A
SparseMatrix & operator*=(double a)
void ResetTranspose() const
void SetDataOwner(bool owna)
Set the data ownership flag (A array).
void PrintCSR2(std::ostream &out) const
Prints a sparse matrix to stream out in CSR format.
int MaxRowSize() const
Returns the maximum number of elements among all rows.
std::ostream & operator<<(std::ostream &os, SparseMatrix const &mat)
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
const int * GetJ() const
Return the array J, const version.
void SetRow(const int row, const Array< int > &cols, const Vector &srow)
cusparseSpMatDescr_t matA_descr
double * ReadWriteData(bool on_dev=true)
int * ReadWriteJ(bool on_dev=true)
static hipsparseHandle_t handle
void PartAddMult(const Array< int > &rows, const Vector &x, Vector &y, const double a=1.0) const
cusparseDnVecDescr_t vecX_descr
int CheckFinite() const
Count the number of entries that are NOT finite, i.e. Inf or Nan.
const Memory< int > & GetMemoryJ() const
cusparseMatDescr_t matA_descr
SparseMatrix * MultAbstractSparseMatrix(const AbstractSparseMatrix &A, const AbstractSparseMatrix &B)
Matrix product of sparse matrices. A and B do not need to be CSR matrices.
Memory< int > J
Array with size I[height], containing the column indices for all matrix entries, as indexed by the I ...
void Swap(SparseMatrix &other)
MemoryClass
Memory classes identify sets of memory types.
Set the diagonal value to zero.
int width
Dimension of the input / number of columns in the matrix.
void EliminateBC(const Array< int > &ess_dofs, DiagonalPolicy diag_policy)
Eliminate essential (Dirichlet) boundary conditions.
virtual void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += At * x (default) or y += a * At * x
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
double * WriteData(bool on_dev=true)
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).