xref: /petsc/src/mat/utils/compressedrow.c (revision 02477ebbb21fa13a3b107e40dce1c3d726eb3600)
1af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I   "petscmat.h"  I*/
226e093fcSHong Zhang 
373e7a558SHong Zhang /*@C
4cd6b891eSBarry Smith   MatCheckCompressedRow - Determines whether the compressed row matrix format should be used.
5f38b99b6SHong Zhang   Compressed row format provides high performance routines by taking advantage of zero rows.
673e7a558SHong Zhang 
773e7a558SHong Zhang   Collective
873e7a558SHong Zhang 
973e7a558SHong Zhang   Input Parameters:
1073e7a558SHong Zhang + A             - the matrix
1111e456e1SBarry Smith . nrows         - number of rows with nonzero entries
1273e7a558SHong Zhang . compressedrow - pointer to the struct Mat_CompressedRow
132ef1f0ffSBarry Smith . ai            - row pointer used by `MATSEQAIJ` and `MATSEQBAIJ`
142ef1f0ffSBarry Smith . mbs           - number of (block) rows represented by `ai`
1573e7a558SHong Zhang - ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
1673e7a558SHong Zhang 
172fe279fdSBarry Smith   Level: developer
182fe279fdSBarry Smith 
1920f4b53cSBarry Smith   Note:
2020f4b53cSBarry Smith   Supported types are `MATAIJ`, `MATBAIJ` and `MATSBAIJ`.
2120f4b53cSBarry Smith 
22*fe59aa6dSJacob Faibussowitsch   Developer Notes:
2320f4b53cSBarry Smith   The reason this takes the `compressedrow`, `ai` and `mbs` arguments is because it is called by both the `MATSEQAIJ` and `MATSEQBAIJ` matrices and
24340b11eeSBarry Smith   the values are not therefore obtained by directly taking the values from the matrix object.
258aea9937SBarry Smith   This is not a general public routine and hence is not listed in petscmat.h (it exposes a private data structure) but it is used
262fe279fdSBarry Smith   by some preconditioners and hence is labeled as `PETSC_EXTERN`
2720f4b53cSBarry Smith 
28*fe59aa6dSJacob Faibussowitsch .seealso: `Mat`, `MATAIJ`, `MATBAIJ`, `MATSBAIJ.`
2973e7a558SHong Zhang @*/
MatCheckCompressedRow(Mat A,PetscInt nrows,Mat_CompressedRow * compressedrow,PetscInt * ai,PetscInt mbs,PetscReal ratio)30d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatCheckCompressedRow(Mat A, PetscInt nrows, Mat_CompressedRow *compressedrow, PetscInt *ai, PetscInt mbs, PetscReal ratio)
31d71ae5a4SJacob Faibussowitsch {
3211e456e1SBarry Smith   PetscInt *cpi = NULL, *ridx = NULL, nz, i, row;
3373e7a558SHong Zhang 
3473e7a558SHong Zhang   PetscFunctionBegin;
35cd6b891eSBarry Smith   /* in case this is being reused, delete old space */
369566063dSJacob Faibussowitsch   PetscCall(PetscFree2(compressedrow->i, compressedrow->rindex));
378865f1eaSKarl Rupp 
3873e7a558SHong Zhang   /* compute number of zero rows */
3911e456e1SBarry Smith   nrows = mbs - nrows;
40baa4e9faSMark F. Adams 
41317fbc4cSHong Zhang   /* if a large number of zero rows is found, use compressedrow data structure */
42317fbc4cSHong Zhang   if (nrows < ratio * mbs) {
4373e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
448865f1eaSKarl Rupp 
4563a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(A, "Found the ratio (num_zerorows %" PetscInt_FMT ")/(num_localrows %" PetscInt_FMT ") < %g. Do not use CompressedRow routines.\n", nrows, mbs, (double)ratio));
4673e7a558SHong Zhang   } else {
4773e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
488865f1eaSKarl Rupp 
4963a3b9bcSJacob Faibussowitsch     PetscCall(PetscInfo(A, "Found the ratio (num_zerorows %" PetscInt_FMT ")/(num_localrows %" PetscInt_FMT ") > %g. Use CompressedRow routines.\n", nrows, mbs, (double)ratio));
5073e7a558SHong Zhang 
5173e7a558SHong Zhang     /* set compressed row format */
52317fbc4cSHong Zhang     nrows = mbs - nrows; /* num of non-zero rows */
539566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nrows + 1, &cpi, nrows, &ridx));
5473e7a558SHong Zhang     row    = 0;
5573e7a558SHong Zhang     cpi[0] = 0;
56317fbc4cSHong Zhang     for (i = 0; i < mbs; i++) {
5773e7a558SHong Zhang       nz = ai[i + 1] - ai[i];
5873e7a558SHong Zhang       if (nz == 0) continue;
5973e7a558SHong Zhang       cpi[row + 1] = ai[i + 1]; /* compressed row pointer */
607b2bb3b9SHong Zhang       ridx[row++]  = i;         /* compressed row local index */
6173e7a558SHong Zhang     }
62bceecc9dSMark Adams     while (row < nrows) ridx[row++] = -1; // pad array
6373e7a558SHong Zhang     compressedrow->nrows  = nrows;
6473e7a558SHong Zhang     compressedrow->i      = cpi;
657b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
6673e7a558SHong Zhang   }
673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6873e7a558SHong Zhang }
69