xref: /petsc/src/mat/utils/compressedrow.c (revision c8c5c547f526914c69472d8cade615559dc64129)
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       If the format is to be used, this routine creates Mat_CompressedRow struct.
6       Compressed row format provides high performance routines by taking advantage of zero rows.
7       Supported types are `MATAIJ`, `MATBAIJ` and `MATSBAIJ`.
8 
9    Collective
10 
11    Input Parameters:
12 +  A             - the matrix
13 .  nrows         - number of rows with nonzero entries
14 .  compressedrow - pointer to the struct Mat_CompressedRow
15 .  ai            - row pointer used by `MATSEQAIJ` and `MATSEQBAIJ`
16 .  mbs           - number of (block) rows represented by `ai`
17 -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
18 
19    Developer Note: The reason this takes the compressedrow, ai and mbs arguments is because it is called by both the `MATSEQAIJ` and `MATSEQBAIJ` matrices and
20                    the values are not therefore obtained by directly taking the values from the matrix object.
21                    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
22                    by some preconditioners and hence is labeled as PETSC_EXTERN
23 
24    Level: developer
25 @*/
26 PETSC_EXTERN PetscErrorCode MatCheckCompressedRow(Mat A, PetscInt nrows, Mat_CompressedRow *compressedrow, PetscInt *ai, PetscInt mbs, PetscReal ratio)
27 {
28   PetscInt *cpi = NULL, *ridx = NULL, nz, i, row;
29 
30   PetscFunctionBegin;
31   /* in case this is being reused, delete old space */
32   PetscCall(PetscFree2(compressedrow->i, compressedrow->rindex));
33 
34   /* compute number of zero rows */
35   nrows = mbs - nrows;
36 
37   /* if a large number of zero rows is found, use compressedrow data structure */
38   if (nrows < ratio * mbs) {
39     compressedrow->use = PETSC_FALSE;
40 
41     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));
42   } else {
43     compressedrow->use = PETSC_TRUE;
44 
45     PetscCall(PetscInfo(A, "Found the ratio (num_zerorows %" PetscInt_FMT ")/(num_localrows %" PetscInt_FMT ") > %g. Use CompressedRow routines.\n", nrows, mbs, (double)ratio));
46 
47     /* set compressed row format */
48     nrows = mbs - nrows; /* num of non-zero rows */
49     PetscCall(PetscMalloc2(nrows + 1, &cpi, nrows, &ridx));
50     row    = 0;
51     cpi[0] = 0;
52     for (i = 0; i < mbs; i++) {
53       nz = ai[i + 1] - ai[i];
54       if (nz == 0) continue;
55       cpi[row + 1] = ai[i + 1]; /* compressed row pointer */
56       ridx[row++]  = i;         /* compressed row local index */
57     }
58     compressedrow->nrows  = nrows;
59     compressedrow->i      = cpi;
60     compressedrow->rindex = ridx;
61   }
62   PetscFunctionReturn(PETSC_SUCCESS);
63 }
64