xref: /petsc/src/mat/utils/compressedrow.c (revision 02477ebbb21fa13a3b107e40dce1c3d726eb3600)
1 #include <petsc/private/matimpl.h> /*I   "petscmat.h"  I*/
2 
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.
6 
7   Collective
8 
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
16 
17   Level: developer
18 
19   Note:
20   Supported types are `MATAIJ`, `MATBAIJ` and `MATSBAIJ`.
21 
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`
27 
28 .seealso: `Mat`, `MATAIJ`, `MATBAIJ`, `MATSBAIJ.`
29 @*/
MatCheckCompressedRow(Mat A,PetscInt nrows,Mat_CompressedRow * compressedrow,PetscInt * ai,PetscInt mbs,PetscReal ratio)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;
33 
34   PetscFunctionBegin;
35   /* in case this is being reused, delete old space */
36   PetscCall(PetscFree2(compressedrow->i, compressedrow->rindex));
37 
38   /* compute number of zero rows */
39   nrows = mbs - nrows;
40 
41   /* if a large number of zero rows is found, use compressedrow data structure */
42   if (nrows < ratio * mbs) {
43     compressedrow->use = PETSC_FALSE;
44 
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;
48 
49     PetscCall(PetscInfo(A, "Found the ratio (num_zerorows %" PetscInt_FMT ")/(num_localrows %" PetscInt_FMT ") > %g. Use CompressedRow routines.\n", nrows, mbs, (double)ratio));
50 
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 }
69