10.9. The SUNMATRIX_DENSE Module
The dense implementation of the SUNMatrix module, SUNMATRIX_DENSE,
defines the content field of SUNMatrix to be the following structure:
struct _SUNMatrixContent_Dense {
sunindextype M;
sunindextype N;
realtype *data;
sunindextype ldata;
realtype **cols;
};
These entries of the content field contain the following information:
M- number of rowsN- number of columnsdata- pointer to a contiguous block ofrealtypevariables. The elements of the dense matrix are stored columnwise, i.e. the \((i,j)\) element of a denseSUNMatrixobject (with \(0 \le i < M\) and \(0 \le j < N\)) may be accessed viadata[j*M+i].ldata- length of the data array (\(= M\, N\)).cols- array of pointers.cols[j]points to the first element of the j-th column of the matrix in the arraydata. The \((i,j)\) element of a denseSUNMatrix(with \(0 \le i < M\) and \(0 \le j < N\)) may be accessed may be accessed viacols[j][i].
The header file to be included when using this module is
sunmatrix/sunmatrix_dense.h.
The following macros are provided to access the content of a
SUNMATRIX_DENSE matrix. The prefix SM_ in the names denotes that
these macros are for SUNMatrix implementations, and the suffix
_D denotes that these are specific to the dense version.
-
SM_CONTENT_D(A)
This macro gives access to the contents of the dense
SUNMatrixA.The assignment
A_cont = SM_CONTENT_D(A)setsA_contto be a pointer to the denseSUNMatrixcontent structure.Implementation:
#define SM_CONTENT_D(A) ( (SUNMatrixContent_Dense)(A->content) )
-
SM_ROWS_D(A)
Access the number of rows in the dense
SUNMatrixA.This may be used either to retrieve or to set the value. For example, the assignment
A_rows = SM_ROWS_D(A)setsA_rowsto be the number of rows in the matrixA. Similarly, the assignmentSM_ROWS_D(A) = A_rowssets the number of columns inAto equalA_rows.Implementation:
#define SM_ROWS_D(A) ( SM_CONTENT_D(A)->M )
-
SM_COLUMNS_D(A)
Access the number of columns in the dense
SUNMatrixA.This may be used either to retrieve or to set the value. For example, the assignment
A_columns = SM_COLUMNS_D(A)setsA_columnsto be the number of columns in the matrixA. Similarly, the assignmentSM_COLUMNS_D(A) = A_columnssets the number of columns inAto equalA_columnsImplementation:
#define SM_COLUMNS_D(A) ( SM_CONTENT_D(A)->N )
-
SM_LDATA_D(A)
Access the total data length in the dense
SUNMatrixA.This may be used either to retrieve or to set the value. For example, the assignment
A_ldata = SM_LDATA_D(A)setsA_ldatato be the length of the data array in the matrixA. Similarly, the assignmentSM_LDATA_D(A) = A_ldatasets the parameter for the length of the data array inAto equalA_ldata.Implementation:
#define SM_LDATA_D(A) ( SM_CONTENT_D(A)->ldata )
-
SM_DATA_D(A)
This macro gives access to the
datapointer for the matrix entries.The assignment
A_data = SM_DATA_D(A)setsA_datato be a pointer to the first component of the data array for the denseSUNMatrix A. The assignmentSM_DATA_D(A) = A_datasets the data array ofAto beA_databy storing the pointerA_data.Implementation:
#define SM_DATA_D(A) ( SM_CONTENT_D(A)->data )
-
SM_COLS_D(A)
This macro gives access to the
colspointer for the matrix entries.The assignment
A_cols = SM_COLS_D(A)setsA_colsto be a pointer to the array of column pointers for the denseSUNMatrix A. The assignmentSM_COLS_D(A) = A_colssets the column pointer array ofAto beA_colsby storing the pointerA_cols.Implementation:
#define SM_COLS_D(A) ( SM_CONTENT_D(A)->cols )
-
SM_COLUMN_D(A)
This macros gives access to the individual columns of the data array of a dense
SUNMatrix.The assignment
col_j = SM_COLUMN_D(A,j)setscol_jto be a pointer to the first entry of thej-th column of the \(M \times N\) dense matrixA(with \(0 \le j < N\)). The type of the expressionSM_COLUMN_D(A,j)isrealtype *. The pointer returned by the callSM_COLUMN_D(A,j)can be treated as an array which is indexed from 0 toM-1.Implementation:
#define SM_COLUMN_D(A,j) ( (SM_CONTENT_D(A)->cols)[j] )
-
SM_ELEMENT_D(A)
This macro gives access to the individual entries of the data array of a dense
SUNMatrix.The assignments
SM_ELEMENT_D(A,i,j) = a_ijanda_ij = SM_ELEMENT_D(A,i,j)reference the \(A_{i,j}\) element of the \(M \times N\) dense matrixA(with \(0 \le i < M\) and \(0 \le j < N\)).Implementation:
#define SM_ELEMENT_D(A,i,j) ( (SM_CONTENT_D(A)->cols)[j][i] )
The SUNMATRIX_DENSE module defines dense implementations of all matrix
operations listed in §10.2. Their names are obtained
from those in that section by appending the suffix _Dense
(e.g. SUNMatCopy_Dense). The module SUNMATRIX_DENSE provides the
following additional user-callable routines:
-
SUNMatrix SUNDenseMatrix(sunindextype M, sunindextype N, SUNContext sunctx)
This constructor function creates and allocates memory for a dense
SUNMatrix. Its arguments are the number of rows,M, and columns,N, for the dense matrix.
-
void SUNDenseMatrix_Print(SUNMatrix A, FILE *outfile)
This function prints the content of a dense
SUNMatrixto the output stream specified byoutfile. Note:stdoutorstderrmay be used as arguments foroutfileto print directly to standard output or standard error, respectively.
-
sunindextype SUNDenseMatrix_Rows(SUNMatrix A)
This function returns the number of rows in the dense
SUNMatrix.
-
sunindextype SUNDenseMatrix_Columns(SUNMatrix A)
This function returns the number of columns in the dense
SUNMatrix.
-
sunindextype SUNDenseMatrix_LData(SUNMatrix A)
This function returns the length of the data array for the dense
SUNMatrix.
-
realtype *SUNDenseMatrix_Data(SUNMatrix A)
This function returns a pointer to the data array for the dense
SUNMatrix.
-
realtype **SUNDenseMatrix_Cols(SUNMatrix A)
This function returns a pointer to the cols array for the dense
SUNMatrix.
-
realtype *SUNDenseMatrix_Column(SUNMatrix A, sunindextype j)
This function returns a pointer to the first entry of the jth column of the dense
SUNMatrix. The resulting pointer should be indexed over the range0toM-1.
Notes
When looping over the components of a dense
SUNMatrix A, the most efficient approaches are to:First obtain the component array via
A_data = SUNDenseMatrix_Data(A), or equivalentlyA_data = SM_DATA_D(A), and then accessA_data[i]within the loop.First obtain the array of column pointers via
A_cols = SUNDenseMatrix_Cols(A), or equivalentlyA_cols = SM_COLS_D(A), and then accessA_cols[j][i]within the loop.Within a loop over the columns, access the column pointer via
A_colj = SUNDenseMatrix_Column(A,j)and then to access the entries within that column usingA_colj[i]within the loop.
All three of these are more efficient than using
SM_ELEMENT_D(A,i,j)within a double loop.Within the
SUNMatMatvec_Denseroutine, internal consistency checks are performed to ensure that the matrix is called with consistentN_Vectorimplementations. These are currently limited to: NVECTOR_SERIAL, NVECTOR_OPENMP, and NVECTOR_PTHREADS. As additional compatible vector implementations are added to SUNDIALS, these will be included within this compatibility check.
10.10. The SUNMATRIX_MAGMADENSE Module
The SUNMATRIX_MAGMADENSE module interfaces to the MAGMA linear algebra library and can target NVIDIA’s CUDA programming model or AMD’s HIP programming model [91]. All data stored by this matrix implementation resides on the GPU at all times. The implementation currently supports a standard LAPACK column-major storage format as well as a low-storage format for block-diagonal matrices
This matrix implementation is best paired with the SUNLinearSolver_MagmaDense SUNLinearSolver.
The header file to include when using this module is
sunmatrix/sunmatrix_magmadense.h. The installed library to link to is
libsundials_sunmatrixmagmadense.lib where lib is typically .so for
shared libraries and .a for static libraries.
Warning
The SUNMATRIX_MAGMADENSE module is experimental and subject to change.
10.10.1. SUNMATRIX_MAGMADENSE Functions
The SUNMATRIX_MAGMADENSE module defines GPU-enabled implementations of all matrix operations listed in §10.2.
SUNMatGetID_MagmaDense– returnsSUNMATRIX_MAGMADENSESUNMatClone_MagmaDenseSUNMatDestroy_MagmaDenseSUNMatZero_MagmaDenseSUNMatCopy_MagmaDenseSUNMatScaleAdd_MagmaDenseSUNMatScaleAddI_MagmaDenseSUNMatMatvecSetup_MagmaDenseSUNMatMatvec_MagmaDenseSUNMatSpace_MagmaDense
In addition, the SUNMATRIX_MAGMADENSE module defines the following implementation specific functions:
-
SUNMatrix SUNMatrix_MagmaDense(sunindextype M, sunindextype N, SUNMemoryType memtype, SUNMemoryHelper memhelper, void *queue, SUNContext sunctx)
This constructor function creates and allocates memory for an \(M \times N\) SUNMATRIX_MAGMADENSE
SUNMatrix.- Arguments:
M – the number of matrix rows.
N – the number of matrix columns.
memtype – the type of memory to use for the matrix data; can be
SUNMEMTYPE_UVMorSUNMEMTYPE_DEVICE.memhelper – the memory helper used for allocating data.
queue – a
cudaStream_twhen using CUDA or ahipStream_twhen using HIP.sunctx – the
SUNContextobject (see §2.1)
- Return value:
If successful, a
SUNMatrixobject otherwiseNULL.
-
SUNMatrix SUNMatrix_MagmaDenseBlock(sunindextype nblocks, sunindextype M_block, sunindextype N_block, SUNMemoryType memtype, SUNMemoryHelper memhelper, void *queue, SUNContext sunctx)
This constructor function creates and allocates memory for a block diagonal SUNMATRIX_MAGMADENSE
SUNMatrixwith nblocks of size \(M \times N\).- Arguments:
nblocks – the number of matrix rows.
M_block – the number of matrix rows in each block.
N_block – the number of matrix columns in each block.
memtype – the type of memory to use for the matrix data; can be
SUNMEMTYPE_UVMorSUNMEMTYPE_DEVICE.memhelper – the memory helper used for allocating data.
queue – a
cudaStream_twhen using CUDA or ahipStream_twhen using HIP.sunctx – the
SUNContextobject (see §2.1)
- Return value:
If successful, a
SUNMatrixobject otherwiseNULL.
-
sunindextype SUNMatrix_MagmaDense_Rows(SUNMatrix A)
This function returns the number of rows in the
SUNMatrixobject. For block diagonal matrices, the number of rows is computed as \(M_{\text{block}} \times \text{nblocks}\).- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of rows in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_MagmaDense_Columns(SUNMatrix A)
This function returns the number of columns in the
SUNMatrixobject. For block diagonal matrices, the number of columns is computed as \(N_{\text{block}} \times \text{nblocks}\).- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of columns in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_MagmaDense_BlockRows(SUNMatrix A)
This function returns the number of rows in a block of the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of rows in a block of the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_MagmaDense_BlockColumns(SUNMatrix A)
This function returns the number of columns in a block of the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of columns in a block of the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_MagmaDense_LData(SUNMatrix A)
This function returns the length of the
SUNMatrixdata array.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the length of the
SUNMatrixdata array otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_MagmaDense_NumBlocks(SUNMatrix A)
This function returns the number of blocks in the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of blocks in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
realtype *SUNMatrix_MagmaDense_Data(SUNMatrix A)
This function returns the
SUNMatrixdata array.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the
SUNMatrixdata array otherwiseNULL.
-
realtype **SUNMatrix_MagmaDense_BlockData(SUNMatrix A)
This function returns an array of pointers that point to the start of the data array for each block in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, an array of data pointers to each of the
SUNMatrixblocks otherwiseNULL.
-
realtype *SUNMatrix_MagmaDense_Block(SUNMatrix A, sunindextype k)
This function returns a pointer to the data array for block k in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.k – the block index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixblock otherwiseNULL.
Note
No bounds-checking is performed by this function, j should be strictly less than nblocks.
-
realtype *SUNMatrix_MagmaDense_Column(SUNMatrix A, sunindextype j)
This function returns a pointer to the data array for column j in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.j – the column index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixcolumn otherwiseNULL.
Note
No bounds-checking is performed by this function, j should be strictly less than \(nblocks * N_{\text{block}}\).
-
realtype *SUNMatrix_MagmaDense_BlockColumn(SUNMatrix A, sunindextype k, sunindextype j)
This function returns a pointer to the data array for column j of block k in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.k – the block index.
j – the column index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixcolumn otherwiseNULL.
Note
No bounds-checking is performed by this function, k should be strictly less than nblocks and j should be strictly less than \(N_{\text{block}}\).
-
int SUNMatrix_MagmaDense_CopyToDevice(SUNMatrix A, realtype *h_data)
This function copies the matrix data to the GPU device from the provided host array.
- Arguments:
A – a
SUNMatrixobjecth_data – a host array pointer to copy data from.
- Return value:
SUNMAT_SUCCESS– if the copy is successful.SUNMAT_ILL_INPUT– if either theSUNMatrixis not aSUNMATRIX_MAGMADENSEmatrix.SUNMAT_MEM_FAIL– if the copy fails.
-
int SUNMatrix_MagmaDense_CopyFromDevice(SUNMatrix A, realtype *h_data)
This function copies the matrix data from the GPU device to the provided host array.
- Arguments:
A – a
SUNMatrixobjecth_data – a host array pointer to copy data to.
- Return value:
SUNMAT_SUCCESS– if the copy is successful.SUNMAT_ILL_INPUT– if either theSUNMatrixis not aSUNMATRIX_MAGMADENSEmatrix.SUNMAT_MEM_FAIL– if the copy fails.
10.10.2. SUNMATRIX_MAGMADENSE Usage Notes
Warning
When using the SUNMATRIX_MAGMADENSE module with a SUNDIALS package (e.g. CVODE), the stream given to matrix should be the same stream used for the NVECTOR object that is provided to the package, and the NVECTOR object given to the SUNMatvec operation. If different streams are utilized, synchronization issues may occur.
10.11. The SUNMATRIX_ONEMKLDENSE Module
The SUNMATRIX_ONEMKLDENSE module is intended for interfacing with direct linear solvers from the Intel oneAPI Math Kernel Library (oneMKL) using the SYCL (DPC++) programming model. The implementation currently supports a standard LAPACK column-major storage format as well as a low-storage format for block-diagonal matrices,
This matrix implementation is best paired with the SUNLinearSolver_OneMklDense linear solver.
The header file to include when using this class is
sunmatrix/sunmatrix_onemkldense.h. The installed library to link to is
libsundials_sunmatrixonemkldense.lib where lib is typically .so for
shared libraries and .a for static libraries.
Warning
The SUNMATRIX_ONEMKLDENSE class is experimental and subject to change.
10.11.1. SUNMATRIX_ONEMKLDENSE Functions
The SUNMATRIX_ONEMKLDENSE class defines implementations of the following matrix operations listed in §10.2.
SUNMatGetID_OneMklDense– returnsSUNMATRIX_ONEMKLDENSESUNMatClone_OneMklDenseSUNMatDestroy_OneMklDenseSUNMatZero_OneMklDenseSUNMatCopy_OneMklDenseSUNMatScaleAdd_OneMklDenseSUNMatScaleAddI_OneMklDenseSUNMatMatvec_OneMklDenseSUNMatSpace_OneMklDense
In addition, the SUNMATRIX_ONEMKLDENSE class defines the following implementation specific functions.
10.11.1.1. Constructors
-
SUNMatrix SUNMatrix_OneMklDense(sunindextype M, sunindextype N, SUNMemoryType memtype, SUNMemoryHelper memhelper, sycl::queue *queue, SUNContext sunctx)
This constructor function creates and allocates memory for an \(M \times N\) SUNMATRIX_ONEMKLDENSE
SUNMatrix.- Arguments:
M – the number of matrix rows.
N – the number of matrix columns.
memtype – the type of memory to use for the matrix data; can be
SUNMEMTYPE_UVMorSUNMEMTYPE_DEVICE.memhelper – the memory helper used for allocating data.
queue – the SYCL queue to which operations will be submitted.
sunctx – the
SUNContextobject (see §2.1)
- Return value:
If successful, a
SUNMatrixobject otherwiseNULL.
-
SUNMatrix SUNMatrix_OneMklDenseBlock(sunindextype nblocks, sunindextype M_block, sunindextype N_block, SUNMemoryType memtype, SUNMemoryHelper memhelper, sycl::queue *queue, SUNContext sunctx)
This constructor function creates and allocates memory for a block diagonal SUNMATRIX_ONEMKLDENSE
SUNMatrixwith nblocks of size \(M_{block} \times N_{block}\).- Arguments:
nblocks – the number of matrix rows.
M_block – the number of matrix rows in each block.
N_block – the number of matrix columns in each block.
memtype – the type of memory to use for the matrix data; can be
SUNMEMTYPE_UVMorSUNMEMTYPE_DEVICE.memhelper – the memory helper used for allocating data.
queue – the SYCL queue to which operations will be submitted.
sunctx – the
SUNContextobject (see §2.1)
- Return value:
If successful, a
SUNMatrixobject otherwiseNULL.
10.11.1.2. Access Matrix Dimensions
-
sunindextype SUNMatrix_OneMklDense_Rows(SUNMatrix A)
This function returns the number of rows in the
SUNMatrixobject. For block diagonal matrices, the number of rows is computed as \(M_{\text{block}} \times \text{nblocks}\).- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of rows in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_OneMklDense_Columns(SUNMatrix A)
This function returns the number of columns in the
SUNMatrixobject. For block diagonal matrices, the number of columns is computed as \(N_{\text{block}} \times \text{nblocks}\).- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of columns in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
10.11.1.3. Access Matrix Block Dimensions
-
sunindextype SUNMatrix_OneMklDense_NumBlocks(SUNMatrix A)
This function returns the number of blocks in the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of blocks in the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_OneMklDense_BlockRows(SUNMatrix A)
This function returns the number of rows in a block of the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of rows in a block of the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
-
sunindextype SUNMatrix_OneMklDense_BlockColumns(SUNMatrix A)
This function returns the number of columns in a block of the
SUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the number of columns in a block of the
SUNMatrixobject otherwiseSUNMATRIX_ILL_INPUT.
10.11.1.4. Access Matrix Data
-
sunindextype SUNMatrix_OneMklDense_LData(SUNMatrix A)
This function returns the length of the
SUNMatrixdata array.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the length of the
SUNMatrixdata array otherwiseSUNMATRIX_ILL_INPUT.
-
realtype *SUNMatrix_OneMklDense_Data(SUNMatrix A)
This function returns the
SUNMatrixdata array.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the
SUNMatrixdata array otherwiseNULL.
-
realtype *SUNMatrix_OneMklDense_Column(SUNMatrix A, sunindextype j)
This function returns a pointer to the data array for column j in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.j – the column index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixcolumn otherwiseNULL.
Note
No bounds-checking is performed by this function, j should be strictly less than \(nblocks * N_{\text{block}}\).
10.11.1.5. Access Matrix Block Data
-
sunindextype SUNMatrix_OneMklDense_BlockLData(SUNMatrix A)
This function returns the length of the
SUNMatrixdata array for each block of theSUNMatrixobject.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, the length of the
SUNMatrixdata array for each block otherwiseSUNMATRIX_ILL_INPUT.
-
realtype **SUNMatrix_OneMklDense_BlockData(SUNMatrix A)
This function returns an array of pointers that point to the start of the data array for each block in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.
- Return value:
If successful, an array of data pointers to each of the
SUNMatrixblocks otherwiseNULL.
-
realtype *SUNMatrix_OneMklDense_Block(SUNMatrix A, sunindextype k)
This function returns a pointer to the data array for block k in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.k – the block index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixblock otherwiseNULL.
Note
No bounds-checking is performed by this function, j should be strictly less than nblocks.
-
realtype *SUNMatrix_OneMklDense_BlockColumn(SUNMatrix A, sunindextype k, sunindextype j)
This function returns a pointer to the data array for column j of block k in the
SUNMatrix.- Arguments:
A – a
SUNMatrixobject.k – the block index.
j – the column index.
- Return value:
If successful, a pointer to the data array for the
SUNMatrixcolumn otherwiseNULL.
Note
No bounds-checking is performed by this function, k should be strictly less than nblocks and j should be strictly less than \(N_{\text{block}}\).
10.11.1.6. Copy Data
-
int SUNMatrix_OneMklDense_CopyToDevice(SUNMatrix A, realtype *h_data)
This function copies the matrix data to the GPU device from the provided host array.
- Arguments:
A – a
SUNMatrixobjecth_data – a host array pointer to copy data from.
- Return value:
SUNMAT_SUCCESS– if the copy is successful.SUNMAT_ILL_INPUT– if either theSUNMatrixis not aSUNMATRIX_ONEMKLDENSEmatrix.SUNMAT_MEM_FAIL– if the copy fails.
-
int SUNMatrix_OneMklDense_CopyFromDevice(SUNMatrix A, realtype *h_data)
This function copies the matrix data from the GPU device to the provided host array.
- Arguments:
A – a
SUNMatrixobjecth_data – a host array pointer to copy data to.
- Return value:
SUNMAT_SUCCESS– if the copy is successful.SUNMAT_ILL_INPUT– if either theSUNMatrixis not aSUNMATRIX_ONEMKLDENSEmatrix.SUNMAT_MEM_FAIL– if the copy fails.
10.11.2. SUNMATRIX_ONEMKLDENSE Usage Notes
Warning
The SUNMATRIX_ONEMKLDENSE class only supports 64-bit indexing, thus SUNDIALS must be built for 64-bit indexing to use this class.
When using the SUNMATRIX_ONEMKLDENSE class with a SUNDIALS package (e.g.
CVODE), the queue given to matrix should be the same stream used for the
NVECTOR object that is provided to the package, and the NVECTOR object given
to the SUNMatMatvec() operation. If different streams are utilized,
synchronization issues may occur.
10.12. The SUNMATRIX_BAND Module
The banded implementation of the SUNMatrix module, SUNMATRIX_BAND,
defines the content field of SUNMatrix to be the following structure:
struct _SUNMatrixContent_Band {
sunindextype M;
sunindextype N;
sunindextype mu;
sunindextype ml;
sunindextype smu;
sunindextype ldim;
realtype *data;
sunindextype ldata;
realtype **cols;
};
A diagram of the underlying data representation in a banded matrix is shown in Fig. 10.1. A more complete description of the parts of this content field is given below:
M- number of rowsN- number of columns (N=M)mu- upper half-bandwidth, \(0 \le \text{mu} < N\)ml- lower half-bandwidth, \(0 \le \text{ml} < N\)smu- storage upper bandwidth, \(\text{mu} \le \text{smu} < N\). The LU decomposition routines in the associated SUNLINSOL_BAND and SUNLINSOL_LAPACKBAND modules write the LU factors into the existing storage for the band matrix. The upper triangular factor \(U\), however, may have an upper bandwidth as big asmin(N-1, mu+ml)because of partial pivoting. Thesmufield holds the upper half-bandwidth allocated for the band matrix.ldim- leading dimension (\(\text{ldim} \ge smu + ml + 1\))data- pointer to a contiguous block ofrealtypevariables. The elements of the banded matrix are stored columnwise (i.e. columns are stored one on top of the other in memory). Only elements within the specified half-bandwidths are stored.datais a pointer toldatacontiguous locations which hold the elements within the banded matrix.ldata- length of the data array (\(= \text{ldim}\, N\))cols- array of pointers.cols[j]is a pointer to the uppermost element within the band in the j-th column. This pointer may be treated as an array indexed fromsmu-mu(to access the uppermost element within the band in the j-th column) tosmu+ml(to access the lowest element within the band in the j-th column). Indices from 0 tosmu-mu-1give access to extra storage elements required by the LU decomposition function. Finally,cols[j][i-j+smu]is the (\(i,j\))-th element with \(j-\text{mu} \le i \le j+\text{ml}\).
Fig. 10.1 Diagram of the storage for the SUNMATRIX_BAND module. Here A is an
\(N \times N\) band matrix with upper and lower half-bandwidths mu
and ml, respectively. The rows and columns of A are
numbered from 0 to N-1 and the (\(i,j\))-th element of A is
denoted A(i,j). The greyed out areas of the underlying
component storage are used by the associated SUNLINSOL_BAND or
SUNLINSOL_LAPACKBAND linear solver.
The header file to be included when using this module is
sunmatrix/sunmatrix_band.h.
The following macros are provided to access the
content of a SUNMATRIX_BAND matrix. The prefix SM_ in the names
denotes that these macros are for SUNMatrix implementations,
and the suffix _B denotes that these are specific to
the banded version.
-
SM_CONTENT_B(A)
This macro gives access to the contents of the banded
SUNMatrixA.The assignment
A_cont = SM_CONTENT_B(A)setsA_contto be a pointer to the bandedSUNMatrixcontent structure.Implementation:
#define SM_CONTENT_B(A) ( (SUNMatrixContent_Band)(A->content) )
-
SM_ROWS_B(A)
Access the number of rows in the banded
SUNMatrixA.This may be used either to retrieve or to set the value. For example, the assignment
A_rows = SM_ROWS_B(A)setsA_rowsto be the number of rows in the matrixA. Similarly, the assignmentSM_ROWS_B(A) = A_rowssets the number of columns inAto equalA_rows.Implementation:
#define SM_ROWS_B(A) ( SM_CONTENT_B(A)->M )
-
SM_COLUMNS_B(A)
Access the number of columns in the banded
SUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_COLUMNS_B(A) ( SM_CONTENT_B(A)->N )
-
SM_UBAND_B(A)
Access the
muparameter in the bandedSUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_UBAND_B(A) ( SM_CONTENT_B(A)->mu )
-
SM_LBAND_B(A)
Access the
mlparameter in the bandedSUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_LBAND_B(A) ( SM_CONTENT_B(A)->ml )
-
SM_SUBAND_B(A)
Access the
smuparameter in the bandedSUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_SUBAND_B(A) ( SM_CONTENT_B(A)->smu )
-
SM_LDIM_B(A)
Access the
ldimparameter in the bandedSUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_LDIM_B(A) ( SM_CONTENT_B(A)->ldim )
-
SM_LDATA_B(A)
Access the
ldataparameter in the bandedSUNMatrixA. As withSM_ROWS_B, this may be used either to retrieve or to set the value.Implementation:
#define SM_LDATA_B(A) ( SM_CONTENT_B(A)->ldata )
-
SM_DATA_B(A)
This macro gives access to the
datapointer for the matrix entries.The assignment
A_data = SM_DATA_B(A)setsA_datato be a pointer to the first component of the data array for the bandedSUNMatrix A. The assignmentSM_DATA_B(A) = A_datasets the data array ofAto beA_databy storing the pointerA_data.Implementation:
#define SM_DATA_B(A) ( SM_CONTENT_B(A)->data )
-
SM_COLS_B(A)
This macro gives access to the
colspointer for the matrix entries.The assignment
A_cols = SM_COLS_B(A)setsA_colsto be a pointer to the array of column pointers for the bandedSUNMatrix A. The assignmentSM_COLS_B(A) = A_colssets the column pointer array ofAto beA_colsby storing the pointerA_cols.Implementation:
#define SM_COLS_B(A) ( SM_CONTENT_B(A)->cols )
-
SM_COLUMN_B(A)
This macros gives access to the individual columns of the data array of a banded
SUNMatrix.The assignment
col_j = SM_COLUMN_B(A,j)setscol_jto be a pointer to the diagonal element of the j-th column of the \(N \times N\) band matrixA, \(0 \le j \le N-1\). The type of the expressionSM_COLUMN_B(A,j)isrealtype *. The pointer returned by the callSM_COLUMN_B(A,j)can be treated as an array which is indexed from-mutoml.Implementation:
#define SM_COLUMN_B(A,j) ( ((SM_CONTENT_B(A)->cols)[j])+SM_SUBAND_B(A) )
-
SM_ELEMENT_B(A)
This macro gives access to the individual entries of the data array of a banded
SUNMatrix.The assignments
SM_ELEMENT_B(A,i,j) = a_ijanda_ij = SM_ELEMENT_B(A,i,j)reference the (\(i,j\))-th element of the \(N \times N\) band matrixA, where \(0 \le i,j \le N-1\). The location (\(i,j\)) should further satisfy \(j-\text{mu} \le i \le j+\text{ml}\).Implementation:
#define SM_ELEMENT_B(A,i,j) ( (SM_CONTENT_B(A)->cols)[j][(i)-(j)+SM_SUBAND_B(A)] )
-
SM_COLUMN_ELEMENT_B(A)
This macro gives access to the individual entries of the data array of a banded
SUNMatrix.The assignments
SM_COLUMN_ELEMENT_B(col_j,i,j) = a_ijanda_ij = SM_COLUMN_ELEMENT_B(col_j,i,j)reference the (\(i,j\))-th entry of the band matrixAwhen used in conjunction withSM_COLUMN_Bto reference the j-th column throughcol_j. The index (\(i,j\)) should satisfy \(j-\text{mu} \le i \le j+\text{ml}\).Implementation:
#define SM_COLUMN_ELEMENT_B(col_j,i,j) (col_j[(i)-(j)])
The SUNMATRIX_BAND module defines banded implementations of all matrix
operations listed in §10.2. Their names are
obtained from those in that section by appending the suffix _Band
(e.g. SUNMatCopy_Band). The module SUNMATRIX_BAND provides the
following additional user-callable routines:
-
SUNMatrix SUNBandMatrix(sunindextype N, sunindextype mu, sunindextype ml, SUNContext sunctx)
This constructor function creates and allocates memory for a banded
SUNMatrix. Its arguments are the matrix size,N, and the upper and lower half-bandwidths of the matrix,muandml. The stored upper bandwidth is set tomu+mlto accommodate subsequent factorization in the SUNLINSOL_BAND and SUNLINSOL_LAPACKBAND modules.
-
SUNMatrix SUNBandMatrixStorage(sunindextype N, sunindextype mu, sunindextype ml, sunindextype smu, SUNContext sunctx)
This constructor function creates and allocates memory for a banded
SUNMatrix. Its arguments are the matrix size,N, the upper and lower half-bandwidths of the matrix,muandml, and the stored upper bandwidth,smu. When creating a bandSUNMatrix, this value should beat least
min(N-1,mu+ml)if the matrix will be used by the SUNLinSol_Band module;exactly equal to
mu+mlif the matrix will be used by the SUNLinSol_LapackBand module;at least
muif used in some other manner.
Note
It is strongly recommended that users call the default constructor,
SUNBandMatrix(), in all standard use cases. This advanced constructor is used internally within SUNDIALS solvers, and is provided to users who require banded matrices for non-default purposes.
-
void SUNBandMatrix_Print(SUNMatrix A, FILE *outfile)
This function prints the content of a banded
SUNMatrixto the output stream specified byoutfile. Note:stdoutorstderrmay be used as arguments foroutfileto print directly to standard output or standard error, respectively.
-
sunindextype SUNBandMatrix_Rows(SUNMatrix A)
This function returns the number of rows in the banded
SUNMatrix.
-
sunindextype SUNBandMatrix_Columns(SUNMatrix A)
This function returns the number of columns in the banded
SUNMatrix.
-
sunindextype SUNBandMatrix_LowerBandwidth(SUNMatrix A)
This function returns the lower half-bandwidth for the banded
SUNMatrix.
-
sunindextype SUNBandMatrix_UpperBandwidth(SUNMatrix A)
This function returns the upper half-bandwidth of the banded
SUNMatrix.
-
sunindextype SUNBandMatrix_StoredUpperBandwidth(SUNMatrix A)
This function returns the stored upper half-bandwidth of the banded
SUNMatrix.
-
sunindextype SUNBandMatrix_LDim(SUNMatrix A)
This function returns the length of the leading dimension of the banded
SUNMatrix.
-
realtype *SUNBandMatrix_Data(SUNMatrix A)
This function returns a pointer to the data array for the banded
SUNMatrix.
-
realtype **SUNBandMatrix_Cols(SUNMatrix A)
This function returns a pointer to the cols array for the band
SUNMatrix.
-
realtype *SUNBandMatrix_Column(SUNMatrix A, sunindextype j)
This function returns a pointer to the diagonal entry of the j-th column of the banded
SUNMatrix. The resulting pointer should be indexed over the range-mutoml.
Notes
When looping over the components of a banded
SUNMatrix A, the most efficient approaches are to:First obtain the component array via
A_data = SUNBandMatrix_Data(A), or equivalentlyA_data = SM_DATA_B(A), and then accessA_data[i]within the loop.First obtain the array of column pointers via
A_cols = SUNBandMatrix_Cols(A), or equivalentlyA_cols = SM_COLS_B(A), and then accessA_cols[j][i]within the loop.Within a loop over the columns, access the column pointer via
A_colj = SUNBandMatrix_Column(A,j)and then to access the entries within that column usingSM_COLUMN_ELEMENT_B(A_colj,i,j).
All three of these are more efficient than using
SM_ELEMENT_B(A,i,j)within a double loop.Within the
SUNMatMatvec_Bandroutine, internal consistency checks are performed to ensure that the matrix is called with consistentN_Vectorimplementations. These are currently limited to: NVECTOR_SERIAL, NVECTOR_OPENMP, and NVECTOR_PTHREADS. As additional compatible vector implementations are added to SUNDIALS, these will be included within this compatibility check.
10.13. The SUNMATRIX_CUSPARSE Module
The SUNMATRIX_CUSPARSE module is an interface to the NVIDIA cuSPARSE matrix for use on NVIDIA GPUs [101]. All data stored by this matrix implementation resides on the GPU at all times.
The header file to be included when using this module is sunmatrix/sunmatrix_cusparse.h.
The installed library to link to is libsundials_sunmatrixcusparse.lib where .lib is
typically .so for shared libraries and .a for static libraries.
10.13.1. SUNMATRIX_CUSPARSE Description
The implementation currently supports the cuSPARSE CSR matrix format described in the cuSPARSE documentation, as well as a unique low-storage format for block-diagonal matrices of the form
where all the block matrices \(\mathbf{A_j}\) share the same sparsity pattern.
We will refer to this format as BCSR (not to be confused with the canonical BSR format where
each block is stored as dense). In this format, the CSR column indices and row pointers
are only stored for the first block and are computed only as necessary for other blocks.
This can drastically reduce the amount of storage required compared to the regular CSR
format when the number of blocks is large. This format is well-suited for, and
intended to be used with, the SUNLinearSolver_cuSolverSp_batchQR linear solver
(see §11.22).
The SUNMATRIX_CUSPARSE module is experimental and subject to change.
10.13.2. SUNMATRIX_CUSPARSE Functions
The SUNMATRIX_CUSPARSE module defines GPU-enabled sparse implementations of all matrix
operations listed in §10.2 except for the SUNMatSpace()
and SUNMatMatvecSetup() operations:
SUNMatGetID_cuSparse– returnsSUNMATRIX_CUSPARSESUNMatClone_cuSparseSUNMatDestroy_cuSparseSUNMatZero_cuSparseSUNMatCopy_cuSparseSUNMatScaleAdd_cuSparse– performs \(A = cA + B\), where \(A\) and \(B\) must have the same sparsity patternSUNMatScaleAddI_cuSparse– performs \(A = cA + I\), where the diagonal of \(A\) must be presentSUNMatMatvec_cuSparse
In addition, the SUNMATRIX_CUSPARSE module defines the following implementation specific functions:
-
SUNMatrix SUNMatrix_cuSparse_NewCSR(int M, int N, int NNZ, cusparseHandle_t cusp, SUNContext sunctx)
This constructor function creates and allocates memory for a SUNMATRIX_CUSPARSE
SUNMatrixthat uses the CSR storage format. Its arguments are the number of rows and columns of the matrix,MandN, the number of nonzeros to be stored in the matrix,NNZ, and a validcusparseHandle_t.
-
SUNMatrix SUNMatrix_cuSparse_NewBlockCSR(int nblocks, int blockrows, int blockcols, int blocknnz, cusparseHandle_t cusp, SUNContext sunctx)
This constructor function creates and allocates memory for a SUNMATRIX_CUSPARSE
SUNMatrixobject that leverages theSUNMAT_CUSPARSE_BCSRstorage format to store a block diagonal matrix where each block shares the same sparsity pattern. The blocks must be square. The function arguments are the number of blocks,nblocks, the number of rows,blockrows, the number of columns,blockcols, the number of nonzeros in each each block,blocknnz, and a validcusparseHandle_t.Warning
The
SUNMAT_CUSPARSE_BCSRformat currently only supports square matrices, i.e.,blockrows == blockcols.
-
SUNMatrix SUNMatrix_cuSparse_MakeCSR(cusparseMatDescr_t mat_descr, int M, int N, int NNZ, int *rowptrs, int *colind, realtype *data, cusparseHandle_t cusp, SUNContext sunctx)
This constructor function creates a SUNMATRIX_CUSPARSE
SUNMatrixobject from user provided pointers. Its arguments are acusparseMatDescr_tthat must have index baseCUSPARSE_INDEX_BASE_ZERO, the number of rows and columns of the matrix,MandN, the number of nonzeros to be stored in the matrix,NNZ, and a validcusparseHandle_t.
-
int SUNMatrix_cuSparse_Rows(SUNMatrix A)
This function returns the number of rows in the sparse
SUNMatrix.
-
int SUNMatrix_cuSparse_Columns(SUNMatrix A)
This function returns the number of columns in the sparse
SUNMatrix.
-
int SUNMatrix_cuSparse_NNZ(SUNMatrix A)
This function returns the number of entries allocated for nonzero storage for the sparse
SUNMatrix.
-
int SUNMatrix_cuSparse_SparseType(SUNMatrix A)
This function returns the storage type (
SUNMAT_CUSPARSE_CSRorSUNMAT_CUSPARSE_BCSR) for the sparseSUNMatrix.
-
realtype *SUNMatrix_cuSparse_Data(SUNMatrix A)
This function returns a pointer to the data array for the sparse
SUNMatrix.
-
int *SUNMatrix_cuSparse_IndexValues(SUNMatrix A)
This function returns a pointer to the index value array for the sparse
SUNMatrix– for the CSR format this is an array of column indices for each nonzero entry. For the BCSR format this is an array of the column indices for each nonzero entry in the first block only.
-
int *SUNMatrix_cuSparse_IndexPointers(SUNMatrix A)
This function returns a pointer to the index pointer array for the sparse
SUNMatrix– for the CSR format this is an array of the locations of the first entry of each row in thedataandindexvaluesarrays, for the BCSR format this is an array of the locations of each row in thedataandindexvaluesarrays in the first block only.
-
int SUNMatrix_cuSparse_BlockRows(SUNMatrix A)
This function returns the number of rows in a matrix block.
-
int SUNMatrix_cuSparse_BlockColumns(SUNMatrix A)
This function returns the number of columns in a matrix block.
-
int SUNMatrix_cuSparse_BlockNNZ(SUNMatrix A)
This function returns the number of nonzeros in each matrix block.
-
realtype *SUNMatrix_cuSparse_BlockData(SUNMatrix A, int blockidx)
This function returns a pointer to the location in the
dataarray where the data for the block,blockidx, begins. Thus,blockidxmust be less thanSUNMatrix_cuSparse_NumBlocks(A). The first block in the SUNMatrix is index 0, the second block is index 1, and so on.
-
cusparseMatDescr_t SUNMatrix_cuSparse_MatDescr(SUNMatrix A)
This function returns the
cusparseMatDescr_tobject associated with the matrix.
-
int SUNMatrix_cuSparse_CopyToDevice(SUNMatrix A, realtype *h_data, int *h_idxptrs, int *h_idxvals)
This functions copies the matrix information to the GPU device from the provided host arrays. A user may provide
NULLfor any ofh_data,h_idxptrs, orh_idxvalsto avoid copying that information.The function returns
SUNMAT_SUCCESSif the copy operation(s) were successful, or a nonzero error code otherwise.
-
int SUNMatrix_cuSparse_CopyFromDevice(SUNMatrix A, realtype *h_data, int *h_idxptrs, int *h_idxvals)
This functions copies the matrix information from the GPU device to the provided host arrays. A user may provide
NULLfor any ofh_data,h_idxptrs, orh_idxvalsto avoid copying that information. Otherwise:The
h_dataarray must be at leastSUNMatrix_cuSparse_NNZ(A)*sizeof(realtype)bytes.The
h_idxptrsarray must be at least(SUNMatrix_cuSparse_BlockDim(A)+1)*sizeof(int)bytes.The
h_idxvalsarray must be at least(SUNMatrix_cuSparse_BlockNNZ(A))*sizeof(int)bytes.
The function returns
SUNMAT_SUCCESSif the copy operation(s) were successful, or a nonzero error code otherwise.
-
int SUNMatrix_cuSparse_SetFixedPattern(SUNMatrix A, booleantype yesno)
This function changes the behavior of the the
SUNMatZerooperation on the objectA. By default the matrix sparsity pattern is not considered to be fixed, thus, theSUNMatZerooperation zeros out alldataarray as well as theindexvaluesandindexpointersarrays. Providing a value of1orSUNTRUEfor theyesnoargument changes the behavior ofSUNMatZeroonAso that only the data is zeroed out, but not theindexvaluesorindexpointersarrays. Providing a value of0orSUNFALSEfor theyesnoargument is equivalent to the default behavior.
-
int SUNMatrix_cuSparse_SetKernelExecPolicy(SUNMatrix A, SUNCudaExecPolicy *exec_policy)
This function sets the execution policies which control the kernel parameters utilized when launching the CUDA kernels. By default the matrix is setup to use a policy which tries to leverage the structure of the matrix. See §9.15.2 for more information about the
SUNCudaExecPolicyclass.
10.13.3. SUNMATRIX_CUSPARSE Usage Notes
The SUNMATRIX_CUSPARSE module only supports 32-bit indexing, thus SUNDIALS must be built for 32-bit indexing to use this module.
The SUNMATRIX_CUSPARSE module can be used with CUDA streams by calling the cuSPARSE
function cusparseSetStream on the cusparseHandle_t that is provided to the
SUNMATRIX_CUSPARSE constructor.
Warning
When using the SUNMATRIX_CUSPARSE module with a SUNDIALS package (e.g. ARKODE), the
stream given to cuSPARSE should be the same stream used for the NVECTOR object that
is provided to the package, and the NVECTOR object given to the SUNMatvec operation.
If different streams are utilized, synchronization issues may occur.
10.14. The SUNMATRIX_SPARSE Module
The sparse implementation of the SUNMatrix module, SUNMATRIX_SPARSE,
is designed to work with either compressed-sparse-column (CSC) or
compressed-sparse-row (CSR) sparse matrix formats. To this end, it
defines the content field of SUNMatrix to be the following
structure:
struct _SUNMatrixContent_Sparse {
sunindextype M;
sunindextype N;
sunindextype NNZ;
sunindextype NP;
realtype *data;
int sparsetype;
sunindextype *indexvals;
sunindextype *indexptrs;
/* CSC indices */
sunindextype **rowvals;
sunindextype **colptrs;
/* CSR indices */
sunindextype **colvals;
sunindextype **rowptrs;
};
A diagram of the underlying data representation in a sparse matrix is shown in Fig. 10.2. A more complete description of the parts of this content field is given below:
M- number of rowsN- number of columnsNNZ- maximum number of nonzero entries in the matrix (allocated length ofdataandindexvalsarrays)NP- number of index pointers (e.g. number of column pointers for CSC matrix). For CSC matricesNP=N, and for CSR matricesNP=M. This value is set automatically at construction based the input choice forsparsetype.data- pointer to a contiguous block ofrealtypevariables (of lengthNNZ), containing the values of the nonzero entries in the matrixsparsetype- type of the sparse matrix (CSC_MATorCSR_MAT)indexvals- pointer to a contiguous block ofintvariables (of lengthNNZ), containing the row indices (if CSC) or column indices (if CSR) of each nonzero matrix entry held indataindexptrs- pointer to a contiguous block ofintvariables (of lengthNP+1). For CSC matrices each entry provides the index of the first column entry into thedataandindexvalsarrays, e.g. ifindexptr[3]=7, then the first nonzero entry in the fourth column of the matrix is located indata[7], and is located in rowindexvals[7]of the matrix. The last entry contains the total number of nonzero values in the matrix and hence points one past the end of the active data in thedataandindexvalsarrays. For CSR matrices, each entry provides the index of the first row entry into thedataandindexvalsarrays.
The following pointers are added to the SUNMATRIX_SPARSE content
structure for user convenience, to provide a more intuitive interface
to the CSC and CSR sparse matrix data structures. They are set
automatically when creating a sparse SUNMatrix, based on the
sparse matrix storage type.
rowvals- pointer toindexvalswhensparsetypeisCSC_MAT, otherwise set toNULL.colptrs- pointer toindexptrswhensparsetypeisCSC_MAT, otherwise set toNULL.colvals- pointer toindexvalswhensparsetypeisCSR_MAT, otherwise set toNULL.rowptrs- pointer toindexptrswhensparsetypeisCSR_MAT, otherwise set toNULL.
For example, the \(5\times 4\) matrix
could be stored as a CSC matrix in this structure as either
M = 5;
N = 4;
NNZ = 8;
NP = N;
data = {3.0, 1.0, 3.0, 7.0, 1.0, 2.0, 9.0, 5.0};
sparsetype = CSC_MAT;
indexvals = {1, 3, 0, 2, 0, 1, 3, 4};
indexptrs = {0, 2, 4, 5, 8};
or
M = 5;
N = 4;
NNZ = 10;
NP = N;
data = {3.0, 1.0, 3.0, 7.0, 1.0, 2.0, 9.0, 5.0, *, *};
sparsetype = CSC_MAT;
indexvals = {1, 3, 0, 2, 0, 1, 3, 4, *, *};
indexptrs = {0, 2, 4, 5, 8};
where the first has no unused space, and the second has additional
storage (the entries marked with * may contain any values).
Note in both cases that the final value in indexptrs is 8,
indicating the total number of nonzero entries in the matrix.
Similarly, in CSR format, the same matrix could be stored as
M = 5;
N = 4;
NNZ = 8;
NP = M;
data = {3.0, 1.0, 3.0, 2.0, 7.0, 1.0, 9.0, 5.0};
sparsetype = CSR_MAT;
indexvals = {1, 2, 0, 3, 1, 0, 3, 3};
indexptrs = {0, 2, 4, 5, 7, 8};
Fig. 10.2 Diagram of the storage for a compressed-sparse-column matrix of
type SUNMATRIX_SPARSE: Here A is an \(M \times N\) sparse
CSC matrix with storage for up to NNZ nonzero entries (the
allocated length of both data and indexvals). The entries
in indexvals may assume values from 0 to M-1,
corresponding to the row index (zero-based) of
each nonzero value. The entries in data contain the values of
the nonzero entries, with the row i, column j entry of
A (again, zero-based) denoted as A(i,j). The indexptrs
array contains N+1 entries; the first N denote the starting
index of each column within the indexvals and data arrays,
while the final entry points one past the final nonzero entry.
Here, although NNZ values are allocated, only nz are
actually filled in; the greyed-out portions of data and
indexvals indicate extra allocated space.
The header file to be included when using this module is
sunmatrix/sunmatrix_sparse.h.
The following macros are provided to access the content of a
SUNMATRIX_SPARSE matrix. The prefix SM_ in the names
denotes that these macros are for SUNMatrix implementations,
and the suffix _S denotes that these are specific to
the sparse version.
-
SM_CONTENT_S(A)
This macro gives access to the contents of the sparse
SUNMatrixA.The assignment
A_cont = SM_CONTENT_S(A)setsA_contto be a pointer to the sparseSUNMatrixcontent structure.Implementation:
#define SM_CONTENT_S(A) ( (SUNMatrixContent_Sparse)(A->content) )
-
SM_ROWS_S(A)
Access the number of rows in the sparse
SUNMatrixA.This may be used either to retrieve or to set the value. For example, the assignment
A_rows = SM_ROWS_S(A)setsA_rowsto be the number of rows in the matrix A. Similarly, the assignmentSM_ROWS_S(A) = A_rowssets the number of columns in A to equalA_rows.Implementation:
#define SM_ROWS_S(A) ( SM_CONTENT_S(A)->M )
-
SM_COLUMNS_S(A)
Access the number of columns in the sparse
SUNMatrixA. As withSM_ROWS_S, this may be used either to retrieve or to set the value.Implementation:
#define SM_COLUMNS_S(A) ( SM_CONTENT_S(A)->N )
-
SM_NNZ_S(A)
Access the allocated number of nonzeros in the sparse
SUNMatrixA. As withSM_ROWS_S, this may be used either to retrieve or to set the value.Implementation:
#define SM_NNZ_S(A) ( SM_CONTENT_S(A)->NNZ )
-
SM_NP_S(A)
Access the number of index pointers
NPin the sparseSUNMatrixA. As withSM_ROWS_S, this may be used either to retrieve or to set the value.Implementation:
#define SM_NP_S(A) ( SM_CONTENT_S(A)->NP )
-
SM_SPARSETYPE_S(A)
Access the sparsity type parameter in the sparse
SUNMatrixA. As withSM_ROWS_S, this may be used either to retrieve or to set the value.Implementation:
#define SM_SPARSETYPE_S(A) ( SM_CONTENT_S(A)->sparsetype )
-
SM_DATA_S(A)
This macro gives access to the
datapointer for the matrix entries.The assignment
A_data = SM_DATA_S(A)setsA_datato be a pointer to the first component of the data array for the sparseSUNMatrix A. The assignmentSM_DATA_S(A) = A_datasets the data array of A to beA_databy storing the pointerA_data.Implementation:
#define SM_DATA_S(A) ( SM_CONTENT_S(A)->data )
-
SM_INDEXVALS_S(A)
This macro gives access to the
indexvalspointer for the matrix entries.The assignment
A_indexvals = SM_INDEXVALS_S(A)setsA_indexvalsto be a pointer to the array of index values (i.e. row indices for a CSC matrix, or column indices for a CSR matrix) for the sparseSUNMatrixA.Implementation:
#define SM_INDEXVALS_S(A) ( SM_CONTENT_S(A)->indexvals )
-
SM_INDEXPTRS_S(A)
This macro gives access to the
indexptrspointer for the matrix entries.The assignment
A_indexptrs = SM_INDEXPTRS_S(A)setsA_indexptrsto be a pointer to the array of index pointers (i.e. the starting indices in the data/indexvals arrays for each row or column in CSR or CSC formats, respectively).Implementation:
#define SM_INDEXPTRS_S(A) ( SM_CONTENT_S(A)->indexptrs )
The SUNMATRIX_SPARSE module defines sparse implementations of all matrix
operations listed in §10.2. Their names are
obtained from those in that section by appending the suffix _Sparse
(e.g. SUNMatCopy_Sparse). The module SUNMATRIX_SPARSE provides the
following additional user-callable routines:
-
SUNMatrix SUNSparseMatrix(sunindextype M, sunindextype N, sunindextype NNZ, int sparsetype, SUNContext sunctx)
This constructor function creates and allocates memory for a sparse
SUNMatrix. Its arguments are the number of rows and columns of the matrix, M and N, the maximum number of nonzeros to be stored in the matrix, NNZ, and a flag sparsetype indicating whether to use CSR or CSC format (valid choices areCSR_MATorCSC_MAT).
-
SUNMatrix SUNSparseFromDenseMatrix(SUNMatrix A, realtype droptol, int sparsetype)
This constructor function creates a new sparse matrix from an existing SUNMATRIX_DENSE object by copying all values with magnitude larger than droptol into the sparse matrix structure.
Requirements:
A must have type
SUNMATRIX_DENSEdroptol must be non-negative
sparsetype must be either
CSC_MATorCSR_MAT
The function returns
NULLif any requirements are violated, or if the matrix storage request cannot be satisfied.
-
SUNMatrix SUNSparseFromBandMatrix(SUNMatrix A, realtype droptol, int sparsetype)
This constructor function creates a new sparse matrix from an existing SUNMATRIX_BAND object by copying all values with magnitude larger than droptol into the sparse matrix structure.
Requirements:
A must have type
SUNMATRIX_BANDdroptol must be non-negative
sparsetype must be either
CSC_MATorCSR_MAT.
The function returns
NULLif any requirements are violated, or if the matrix storage request cannot be satisfied.
-
int SUNSparseMatrix_Realloc(SUNMatrix A)
This function reallocates internal storage arrays in a sparse matrix so that the resulting sparse matrix has no wasted space (i.e. the space allocated for nonzero entries equals the actual number of nonzeros,
indexptrs[NP]). Returns 0 on success and 1 on failure (e.g. if the input matrix is not sparse).
-
void SUNSparseMatrix_Print(SUNMatrix A, FILE *outfile)
This function prints the content of a sparse
SUNMatrixto the output stream specified byoutfile. Note:stdoutorstderrmay be used as arguments foroutfileto print directly to standard output or standard error, respectively.
-
sunindextype SUNSparseMatrix_Rows(SUNMatrix A)
This function returns the number of rows in the sparse
SUNMatrix.
-
sunindextype SUNSparseMatrix_Columns(SUNMatrix A)
This function returns the number of columns in the sparse
SUNMatrix.
-
sunindextype SUNSparseMatrix_NNZ(SUNMatrix A)
This function returns the number of entries allocated for nonzero storage for the sparse
SUNMatrix.
-
sunindextype SUNSparseMatrix_NP(SUNMatrix A)
This function returns the number of index pointers for the sparse
SUNMatrix(theindexptrsarray hasNP+1entries).
-
int SUNSparseMatrix_SparseType(SUNMatrix A)
This function returns the storage type (
CSR_MATorCSC_MAT) for the sparseSUNMatrix.
-
realtype *SUNSparseMatrix_Data(SUNMatrix A)
This function returns a pointer to the data array for the sparse
SUNMatrix.
-
sunindextype *SUNSparseMatrix_IndexValues(SUNMatrix A)
This function returns a pointer to index value array for the sparse
SUNMatrix– for CSR format this is the column index for each nonzero entry, for CSC format this is the row index for each nonzero entry.
-
sunindextype *SUNSparseMatrix_IndexPointers(SUNMatrix A)
This function returns a pointer to the index pointer array for the sparse
SUNMatrix– for CSR format this is the location of the first entry of each row in thedataandindexvaluesarrays, for CSC format this is the location of the first entry of each column.
Note
Within the SUNMatMatvec_Sparse routine, internal
consistency checks are performed to ensure that the matrix
is called with consistent N_Vector implementations.
These are currently limited to: NVECTOR_SERIAL,
NVECTOR_OPENMP, NVECTOR_PTHREADS, and NVECTOR_CUDA when using
managed memory. As additional compatible vector implementations
are added to SUNDIALS, these will be included within this
compatibility check.
10.15. The SUNMATRIX_SLUNRLOC Module
The SUNMATRIX_SLUNRLOC module is an interface to the SuperMatrix
structure provided by the SuperLU_DIST sparse matrix factorization and
solver library written by X. Sherry Li and collaborators
[43, 68, 69, 102].
It is designed to be used with the SuperLU_DIST SUNLinearSolver
module discussed in §11.20. To this end, it
defines the content field of SUNMatrix to be the following
structure:
struct _SUNMatrixContent_SLUNRloc {
booleantype own_data;
gridinfo_t *grid;
sunindextype *row_to_proc;
pdgsmv_comm_t *gsmv_comm;
SuperMatrix *A_super;
SuperMatrix *ACS_super;
};
A more complete description of the this content field is given below:
own_data– a flag which indicates if the SUNMatrix is responsible for freeingA_supergrid– pointer to the SuperLU_DIST structure that stores the 2D process gridrow_to_proc– a mapping between the rows in the matrix and the process it resides on; will beNULLuntil theSUNMatMatvecSetuproutine is calledgsmv_comm– pointer to the SuperLU_DIST structure that stores the communication information needed for matrix-vector multiplication; will beNULLuntil theSUNMatMatvecSetuproutine is calledA_super– pointer to the underlying SuperLU_DISTSuperMatrixwithStype = SLU_NR_loc,Dtype = SLU_D,Mtype = SLU_GE; must have the full diagonal present to be used withSUNMatScaleAddIroutineACS_super– a column-sorted version of the matrix needed to perform matrix-vector multiplication; will beNULLuntil the routineSUNMatMatvecSetuproutine is called
The header file to include when using this module is sunmatrix/sunmatrix_slunrloc.h.
The installed module library to link to is libsundials_sunmatrixslunrloc .lib
where .lib is typically .so for shared libraries and .a for static libraries.
10.15.1. SUNMATRIX_SLUNRLOC Functions
The SUNMATRIX_SLUNRLOC module provides the following user-callable routines:
-
SUNMatrix SUNMatrix_SLUNRloc(SuperMatrix *Asuper, gridinfo_t *grid, SUNContext sunctx)
This constructor function creates and allocates memory for a SUNMATRIX_SLUNRLOC object. Its arguments are a fully-allocated SuperLU_DIST
SuperMatrixwithStype = SLU_NR_loc, Dtype = SLU_D, Mtype = SLU_GEand an initialized SuperLU_DIST 2D process grid structure. It returns aSUNMatrixobject ifAsuperis compatible else it returnsNULL.
-
void SUNMatrix_SLUNRloc_Print(SUNMatrix A, FILE *fp)
This function prints the underlying
SuperMatrixcontent. It is useful for debugging. Its arguments are theSUNMatrixobject and aFILEpointer to print to. It returns void.
-
SuperMatrix *SUNMatrix_SLUNRloc_SuperMatrix(SUNMatrix A)
This function returns the underlying
SuperMatrixofA. Its only argument is theSUNMatrixobject to access.
-
gridinfo_t *SUNMatrix_SLUNRloc_ProcessGrid(SUNMatrix A)
This function returns the SuperLU_DIST 2D process grid associated with
A. Its only argument is theSUNMatrixobject to access.
-
booleantype SUNMatrix_SLUNRloc_OwnData(SUNMatrix A)
This function returns true if the
SUNMatrixobject is responsible for freeing the underlyingSuperMatrix, otherwise it returns false. Its only argument is theSUNMatrixobject to access.
The SUNMATRIX_SLUNRLOC module also defines implementations of all generic
SUNMatrix operations listed in §10.2:
SUNMatGetID_SLUNRloc– returnsSUNMATRIX_SLUNRLOCSUNMatClone_SLUNRlocSUNMatDestroy_SLUNRlocSUNMatSpace_SLUNRloc– this only returns information for the storage within the matrix interface, i.e. storage forrow_to_procSUNMatZero_SLUNRlocSUNMatCopy_SLUNRlocSUNMatScaleAdd_SLUNRloc– performs \(A = cA + B\), where \(A\) and \(B\) must have the same sparsity patternSUNMatScaleAddI_SLUNRloc– performs \(A = cA + I\), where the diagonal of \(A\) must be presentSUNMatMatvecSetup_SLUNRloc– initializes the SuperLU_DIST parallel communication structures needed to perform a matrix-vector product; only needs to be called before the first call toSUNMatMatvec()or if the matrix changed since the last setupSUNMatMatvec_SLUNRloc
10.16. SUNMATRIX Examples
There are SUNMatrix examples that may be installed for each
implementation, that make use of the functions in test_sunmatrix.c.
These example functions show simple usage of the SUNMatrix family
of functions. The inputs to the examples depend on the matrix type,
and are output to stdout if the example is run without the
appropriate number of command-line arguments.
The following is a list of the example functions in test_sunmatrix.c:
Test_SUNMatGetID: Verifies the returned matrix ID against the value that should be returned.Test_SUNMatClone: Creates clone of an existing matrix, copies the data, and checks that their values match.Test_SUNMatZero: Zeros out an existing matrix and checks that each entry equals 0.0.Test_SUNMatCopy: Clones an input matrix, copies its data to a clone, and verifies that all values match.Test_SUNMatScaleAdd: Given an input matrix \(A\) and an input identity matrix \(I\), this test clones and copies \(A\) to a new matrix \(B\), computes \(B = -B+B\), and verifies that the resulting matrix entries equal 0. Additionally, if the matrix is square, this test clones and copies \(A\) to a new matrix \(D\), clones and copies \(I\) to a new matrix \(C\), computes \(D = D+I\) and \(C = C+A\) usingSUNMatScaleAdd(), and then verifies that \(C=D\).Test_SUNMatScaleAddI: Given an input matrix \(A\) and an input identity matrix \(I\), this clones and copies \(I\) to a new matrix \(B\), computes \(B = -B+I\) usingSUNMatScaleAddI(), and verifies that the resulting matrix entries equal 0.Test_SUNMatMatvecSetup: verifies thatSUNMatMatvecSetup()can be called.Test_SUNMatMatvecGiven an input matrix \(A\) and input vectors \(x\) and \(y\) such that \(y=Ax\), this test has different behavior depending on whether \(A\) is square. If it is square, it clones and copies \(A\) to a new matrix \(B\), computes \(B = 3B+I\) usingSUNMatScaleAddI(), clones \(y\) to new vectors \(w\) and \(z\), computes \(z = Bx\) usingSUNMatMatvec(), computes \(w = 3y+x\) usingN_VLinearSum, and verifies that \(w==z\). If \(A\) is not square, it just clones \(y\) to a new vector \(z\), computes :math:`z=Ax usingSUNMatMatvec(), and verifies that \(y=z\).Test_SUNMatSpace: verifies thatSUNMatSpace()can be called, and outputs the results tostdout.