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"
29 #if defined(__alignas_is_defined)
73 #ifdef MFEM_USE_MEMALLOC
97 #if CUDA_VERSION >= 10010
124 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n);
131 SparseMatrix(
int *i,
int *j,
double *data,
int m,
int n,
bool ownij,
132 bool owna,
bool issorted);
182 inline const int *
GetI()
const {
return I; }
187 inline const int *
GetJ()
const {
return J; }
197 const int *
ReadI(
bool on_dev =
true)
const
213 const int *
ReadJ(
bool on_dev =
true)
const
243 int RowSize(
const int i)
const;
280 virtual double &
Elem(
int i,
int j);
283 virtual const double &
Elem(
int i,
int j)
const;
317 const double a = 1.0)
const;
346 const double a=1.0)
const;
456 double sc = 1.0)
const;
460 double sc = 1.0)
const;
470 void Finalize(
int skip_zeros,
bool fix_empty_rows);
480 void Threshold(
double tol,
bool fix_empty_rows =
false);
495 inline void SetColPtr(
const int row)
const;
506 inline void _Add_(
const int col,
const double a)
509 inline void _Set_(
const int col,
const double a)
512 inline double _Get_(
const int col)
const;
514 inline double &
SearchRow(
const int row,
const int col);
515 inline void _Add_(
const int row,
const int col,
const double a)
517 inline void _Set_(
const int row,
const int col,
const double a)
520 void Set(
const int i,
const int j,
const double a);
521 void Add(
const int i,
const int j,
const double a);
555 void ScaleRow(
const int row,
const double scale);
666 SparseMatrix *
Transpose(
const SparseMatrix &A);
677 SparseMatrix *
Mult(
const SparseMatrix &A,
const SparseMatrix &B,
678 SparseMatrix *OAB = NULL);
681 SparseMatrix *
TransposeMult(
const SparseMatrix &A,
const SparseMatrix &B);
685 const AbstractSparseMatrix &B);
688 DenseMatrix *
Mult(
const SparseMatrix &A, DenseMatrix &B);
691 DenseMatrix *
RAP(
const SparseMatrix &A, DenseMatrix &P);
694 DenseMatrix *
RAP(DenseMatrix &A,
const SparseMatrix &P);
698 SparseMatrix *
RAP(
const SparseMatrix &A,
const SparseMatrix &R,
699 SparseMatrix *ORAP = NULL);
702 SparseMatrix *
RAP(
const SparseMatrix &Rt,
const SparseMatrix &A,
703 const SparseMatrix &P);
706 SparseMatrix *
Mult_AtDA(
const SparseMatrix &A,
const Vector &D,
707 SparseMatrix *OAtDA = NULL);
711 SparseMatrix *
Add(
const SparseMatrix & A,
const SparseMatrix & B);
713 SparseMatrix *
Add(
double a,
const SparseMatrix & A,
double b,
714 const SparseMatrix & B);
716 SparseMatrix *
Add(Array<SparseMatrix *> & Ai);
719 void Add(
const SparseMatrix &A,
double alpha, DenseMatrix &B);
722 DenseMatrix *
OuterProduct(
const DenseMatrix &A,
const DenseMatrix &B);
725 SparseMatrix *
OuterProduct(
const DenseMatrix &A,
const SparseMatrix &B);
728 SparseMatrix *
OuterProduct(
const SparseMatrix &A,
const DenseMatrix &B);
731 SparseMatrix *
OuterProduct(
const SparseMatrix &A,
const SparseMatrix &B);
743 for (
int i = 0; i <
width; i++)
748 for (RowNode *node_p =
Rows[row]; node_p != NULL; node_p = node_p->Prev)
758 for (
int i = 0; i <
width; i++)
763 for (
int j =
I[row], end =
I[row+1]; j < end; j++)
776 node_p = node_p->Prev)
783 for (
int j =
I[
current_row], end =
I[current_row+1]; j < end; j++)
797 #ifdef MFEM_USE_MEMALLOC
800 node_p =
new RowNode;
803 node_p->Column = col;
807 return node_p->Value;
812 MFEM_VERIFY(j != -1,
"Entry for column " << col <<
" is not allocated.");
822 return (node_p == NULL) ? 0.0 : node_p->Value;
827 return (j == -1) ? 0.0 :
A[j];
837 for (node_p =
Rows[row]; 1; node_p = node_p->Prev)
841 #ifdef MFEM_USE_MEMALLOC
844 node_p =
new RowNode;
846 node_p->Prev =
Rows[row];
847 node_p->Column = col;
852 else if (node_p->Column == col)
857 return node_p->Value;
861 int *Ip =
I+row, *Jp =
J;
862 for (
int k = Ip[0], end = Ip[1]; k < end; k++)
869 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)
double GetJacobiScaling() const
Determine appropriate scaling for Jacobi iteration.
int CheckFinite() const
Count the number of entries that are NOT finite, i.e. Inf or Nan.
SparseMatrix * TransposeAbstractSparseMatrix(const AbstractSparseMatrix &A, int useActualWidth)
Transpose of a sparse matrix. A does not need to be a CSR matrix.
int RowSize(const int i) const
Returns the number of elements in row i.
virtual int NumNonZeroElems() const
Returns the number of the nonzero elements in the matrix.
void Add(const int i, const int j, const double a)
void * CuMemFree(void *dptr)
Frees device memory and returns destination ptr.
void _Add_(const int col, const double a)
Add a value to an entry in the "current row". See SetColPtr().
void BuildTranspose() const
Build and store internally the transpose of this matrix which will be used in the methods AddMultTran...
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.
static MemoryClass GetHostMemoryClass()
Get the current Host MemoryClass. This is the MemoryClass used by most MFEM host Memory objects...
bool ColumnsAreSorted() const
Returns whether or not the columns are sorted.
void _Set_(const int row, const int col, const double a)
HypreParMatrix * RAP(const HypreParMatrix *A, const HypreParMatrix *P)
Returns the matrix P^t * A * P.
void DiagScale(const Vector &b, Vector &x, double sc=1.0) const
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().
DenseMatrix * ToDenseMatrix() const
Produces a DenseMatrix from a SparseMatrix.
bool Empty() const
Check if the SparseMatrix is empty.
int * GetRowColumns(const int row)
Return a pointer to the column indices in a row.
void BooleanMult(const Array< int > &x, Array< int > &y) const
y = A * x, treating all entries as booleans (zero=false, nonzero=true).
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
const double * ReadData(bool on_dev=true) const
int * GetJ()
Return the array J.
Abstract data type for sparse matrices.
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.
void AddMult(const Vector &x, Vector &y, const double a=1.0) const
y += A * x (default) or y += a * A * x
virtual ~SparseMatrix()
Destroys sparse matrix.
int * GetI()
Return the array I.
void AddMultTranspose(const Vector &x, Vector &y, const double a=1.0) const
y += At * x (default) or y += a * At * x
void ClearCuSparse()
Clear the CuSparse descriptors. This must be called after releasing the device memory of A...
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...
void PrintInfo(std::ostream &out) const
Print various sparse matrix statistics.
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
void LoseData()
Lose the ownership of the graph (I, J) and data (A) arrays.
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()
void PrintMM(std::ostream &out=mfem::out) const
Prints matrix in Matrix Market sparse format.
int Capacity() const
Return the size of the allocated memory.
Memory< int > & GetMemoryI()
cusparseDnVecDescr_t vecY_descr
void GetSubMatrix(const Array< int > &rows, const Array< int > &cols, DenseMatrix &subm) const
double * HostReadWriteData()
void _Set_(const int col, const double a)
Set an entry in the "current row". See SetColPtr().
void BooleanMultTranspose(const Array< int > &x, Array< int > &y) const
y = At * x, treating all entries as booleans (zero=false, nonzero=true).
SparseMatrix * Mult_AtDA(const SparseMatrix &A, const Vector &D, SparseMatrix *OAtDA)
Matrix multiplication A^t D A. All matrices must be finalized.
void PartAddMult(const Array< int > &rows, const Vector &x, Vector &y, const double a=1.0) const
bool RowIsEmpty(const int row) const
void GetBlocks(Array2D< SparseMatrix * > &blocks) const
const int * ReadJ(bool on_dev=true) const
void ScaleRow(const int row, const double scale)
double * GetData()
Return the element data, i.e. the array A.
Memory< int > & GetMemoryJ()
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
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 UseCuSparse(bool useCuSparse_=true)
bool OwnsData() const
Get the data ownership flag (A array).
void ClearColPtr() const
Reset the "current row" set by calling SetColPtr(). This method must be called between any two calls ...
void ScaleColumns(const Vector &sr)
this = this * diag(sr);
void PrintCSR2(std::ostream &out) const
Prints a sparse matrix to stream out in CSR format.
double f(const Vector &xvec)
virtual int GetRow(const int row, Array< int > &cols, Vector &srow) const
Extract all column indices and values from a given row.
bool isSorted
Are the columns sorted already.
Memory< double > A
Array with size I[height], containing the actual entries of the sparse matrix, as indexed by the I ar...
SparseMatrix()
Create an empty SparseMatrix.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
static MemoryClass GetDeviceMemoryClass()
Get the current Device MemoryClass. This is the MemoryClass used by most MFEM device kernels to acces...
bool OwnsGraph() const
Get the graph ownership flag (I and J arrays).
void SetWidth(int width_=-1)
Change the width of a SparseMatrix.
const double * HostReadData() const
int * ReadWriteI(bool on_dev=true)
double IsSymmetric() const
Returns max_{i,j} |(i,j)-(j,i)| for a finalized matrix.
const int * HostReadJ() const
static int SparseMatrixCount
void SetDiagIdentity()
If a row contains only one diag entry of zero, set it to 1.
bool OwnsHostPtr() const
Return true if the host pointer is owned. Ownership indicates whether the pointer will be deleted by ...
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.
int * WriteI(bool on_dev=true)
Set the diagonal value to one.
void PrintMatlab(std::ostream &out=mfem::out) const
Prints matrix in matlab format.
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...
void AddSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
Dynamic 2D array using row-major layout.
void Jacobi(const Vector &b, const Vector &x0, Vector &x1, double sc) const
void SetSubMatrix(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
virtual MemoryClass GetMemoryClass() const
Return the MemoryClass preferred by the Operator.
bool Finalized() const
Returns whether or not CSR format has been finalized.
const double * GetData() const
Return the element data, i.e. the array A, const version.
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).
virtual MatrixInverse * Inverse() const
This virtual method is not supported: it always returns NULL.
const Memory< double > & GetMemoryData() const
void EliminateRowColDiag(int rc, double value)
Perform elimination and set the diagonal entry to the given value.
const Memory< int > & GetMemoryI() const
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication.
void SetColPtr(const int row) const
Initialize the SparseMatrix for fast access to the entries of the given row which becomes the "curren...
const int * GetJ() const
Return the array J, const version.
MemoryType
Memory types supported by MFEM.
void SetHostPtrOwner(bool own) const
Set/clear the ownership flag for the host pointer. Ownership indicates whether the pointer will be de...
void SetSubMatrixTranspose(const Array< int > &rows, const Array< int > &cols, const DenseMatrix &subm, int skip_zeros=1)
void Set(const int i, const int j, const double a)
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...
int Size() const
For backward compatibility, define Size() to be synonym of Height().
void Gauss_Seidel_back(const Vector &x, Vector &y) const
const int * ReadI(bool on_dev=true) const
void Gauss_Seidel_forw(const Vector &x, Vector &y) const
Gauss-Seidel forward and backward iterations over a vector x.
RowNode ** Rows
Array of linked lists, one for every row. This array represents the linked list (LIL) storage format...
const Memory< int > & GetMemoryJ() const
int * WriteJ(bool on_dev=true)
void EliminateRow(int row, const double sol, Vector &rhs)
Eliminates a column from the transpose matrix.
int ActualWidth() const
Returns the actual Width of the matrix.
void GetDiag(Vector &d) const
Returns the Diagonal of A.
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.
double GetRowNorml1(int irow) const
For i = irow compute .
void ResetTranspose() const
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.
bool Empty() const
Return true if the Memory object is empty, see Reset().
void AbsMultTranspose(const Vector &x, Vector &y) const
y = |At| * x, using entry-wise absolute values of the transpose of matrix A
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 MultTranspose(const Vector &x, Vector &y) const
Multiply a vector with the transposed matrix. y = At * x.
void EliminateCols(const Array< int > &cols, const Vector *x=NULL, Vector *b=NULL)
Eliminate all columns i for which cols[i] != 0.
SparseMatrix & operator=(const SparseMatrix &rhs)
Assignment operator: deep copy.
SparseMatrix & operator*=(double a)
void SetDataOwner(bool owna)
Set the data ownership flag (A array).
std::ostream & operator<<(std::ostream &os, SparseMatrix const &mat)
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)
void Print(std::ostream &out=mfem::out, int width_=4) const
Prints matrix to stream out.
const int * HostReadI() const
const int * GetI() const
Return the array I, const version.
void Jacobi2(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) const
cusparseDnVecDescr_t vecX_descr
int MaxRowSize() const
Returns the maximum number of elements among all rows.
void Jacobi3(const Vector &b, const Vector &x0, Vector &x1, double sc=1.0) 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.
void AbsMult(const Vector &x, Vector &y) const
y = |A| * x, using entry-wise absolute values of matrix A
double _Get_(const int col) const
Read the value of an entry in the "current row". See SetColPtr().
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
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)
void PrintCSR(std::ostream &out) const
Prints matrix to stream out in hypre_CSRMatrix format.
double InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
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.
int CountSmallElems(double tol) const
Count the number of entries with |a_ij| <= tol.
void PartMult(const Array< int > &rows, const Vector &x, Vector &y) const
void GetRowSums(Vector &x) const
For all i compute .
double * WriteData(bool on_dev=true)