Actual source code: compressedrow.c

  1: #include <petsc/private/matimpl.h>

  3: /*@C
  4:   MatCheckCompressedRow - Determines whether the compressed row matrix format should be used.
  5:   Compressed row format provides high performance routines by taking advantage of zero rows.

  7:   Collective

  9:   Input Parameters:
 10: + A             - the matrix
 11: . nrows         - number of rows with nonzero entries
 12: . compressedrow - pointer to the struct Mat_CompressedRow
 13: . ai            - row pointer used by `MATSEQAIJ` and `MATSEQBAIJ`
 14: . mbs           - number of (block) rows represented by `ai`
 15: - ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used

 17:   Level: developer

 19:   Note:
 20:   Supported types are `MATAIJ`, `MATBAIJ` and `MATSBAIJ`.

 22:   Developer Notes:
 23:   The reason this takes the `compressedrow`, `ai` and `mbs` arguments is because it is called by both the `MATSEQAIJ` and `MATSEQBAIJ` matrices and
 24:   the values are not therefore obtained by directly taking the values from the matrix object.
 25:   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
 26:   by some preconditioners and hence is labeled as `PETSC_EXTERN`

 28: .seealso: `Mat`, `MATAIJ`, `MATBAIJ`, `MATSBAIJ.`
 29: @*/
 30: PETSC_EXTERN PetscErrorCode MatCheckCompressedRow(Mat A, PetscInt nrows, Mat_CompressedRow *compressedrow, PetscInt *ai, PetscInt mbs, PetscReal ratio)
 31: {
 32:   PetscInt *cpi = NULL, *ridx = NULL, nz, i, row;

 34:   PetscFunctionBegin;
 35:   /* in case this is being reused, delete old space */
 36:   PetscCall(PetscFree2(compressedrow->i, compressedrow->rindex));

 38:   /* compute number of zero rows */
 39:   nrows = mbs - nrows;

 41:   /* if a large number of zero rows is found, use compressedrow data structure */
 42:   if (nrows < ratio * mbs) {
 43:     compressedrow->use = PETSC_FALSE;

 45:     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));
 46:   } else {
 47:     compressedrow->use = PETSC_TRUE;

 49:     PetscCall(PetscInfo(A, "Found the ratio (num_zerorows %" PetscInt_FMT ")/(num_localrows %" PetscInt_FMT ") > %g. Use CompressedRow routines.\n", nrows, mbs, (double)ratio));

 51:     /* set compressed row format */
 52:     nrows = mbs - nrows; /* num of non-zero rows */
 53:     PetscCall(PetscMalloc2(nrows + 1, &cpi, nrows, &ridx));
 54:     row    = 0;
 55:     cpi[0] = 0;
 56:     for (i = 0; i < mbs; i++) {
 57:       nz = ai[i + 1] - ai[i];
 58:       if (nz == 0) continue;
 59:       cpi[row + 1] = ai[i + 1]; /* compressed row pointer */
 60:       ridx[row++]  = i;         /* compressed row local index */
 61:     }
 62:     while (row < nrows) ridx[row++] = -1; // pad array
 63:     compressedrow->nrows  = nrows;
 64:     compressedrow->i      = cpi;
 65:     compressedrow->rindex = ridx;
 66:   }
 67:   PetscFunctionReturn(PETSC_SUCCESS);
 68: }