xref: /petsc/src/mat/utils/compressedrow.c (revision 9895aa37ac365bac650f6bd8bf977519f7222510)
1 
2 #include <petsc-private/matimpl.h>  /*I   "petscmat.h"  I*/
3 
4 #undef __FUNCT__
5 #define __FUNCT__ "MatCheckCompressedRow"
6 /*@C
7    MatCheckCompressedRow - Determines whether the compressed row matrix format should be used.
8       If the format is to be used, this routine creates Mat_CompressedRow struct.
9       Compressed row format provides high performance routines by taking advantage of zero rows.
10       Supported types are MATAIJ, MATBAIJ and MATSBAIJ.
11 
12    Collective
13 
14    Input Parameters:
15 +  A             - the matrix
16 .  compressedrow - pointer to the struct Mat_CompressedRow
17 .  ai            - row pointer used by seqaij and seqbaij
18 .  mbs           - number of (block) rows represented by ai
19 -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
20 
21    Notes: By default PETSc will not check for compressed rows on sequential matrices. Call MatSetOption(Mat,MAT_CHECK_COMPRESSED_ROW,PETSC_TRUE); before
22           MatAssemblyBegin() to have it check.
23 
24    Developer Note: The reason this takes the compressedrow, ai and mbs arguments is because it is called by both the SeqAIJ and SEQBAIJ matrices and
25                    the values are not therefore obtained by directly taking the values from the matrix object.
26    Level: developer
27 @*/
28 PetscErrorCode MatCheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
29 {
30   PetscErrorCode ierr;
31   PetscInt       nrows,*cpi=NULL,*ridx=NULL,nz,i,row;
32 
33   PetscFunctionBegin;
34   if (!compressedrow->check) PetscFunctionReturn(0);
35 
36   /* in case this is being reused, delete old space */
37   ierr = PetscFree2(compressedrow->i,compressedrow->rindex);CHKERRQ(ierr);
38 
39   compressedrow->i      = NULL;
40   compressedrow->rindex = NULL;
41 
42 
43   /* compute number of zero rows */
44   nrows = 0;
45   for (i=0; i<mbs; i++) {        /* for each row */
46     nz = ai[i+1] - ai[i];       /* number of nonzeros */
47     if (nz == 0) nrows++;
48   }
49 
50   /* if a large number of zero rows is found, use compressedrow data structure */
51   if (nrows < ratio*mbs) {
52     compressedrow->use = PETSC_FALSE;
53 
54     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) < %G. Do not use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
55   } else {
56     compressedrow->use = PETSC_TRUE;
57 
58     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) > %G. Use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
59 
60     /* set compressed row format */
61     nrows  = mbs - nrows; /* num of non-zero rows */
62     ierr   = PetscMalloc2(nrows+1,PetscInt,&cpi,nrows,PetscInt,&ridx);CHKERRQ(ierr);
63     row    = 0;
64     cpi[0] = 0;
65     for (i=0; i<mbs; i++) {
66       nz = ai[i+1] - ai[i];
67       if (nz == 0) continue;
68       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
69       ridx[row++] = i;          /* compressed row local index */
70     }
71     compressedrow->nrows  = nrows;
72     compressedrow->i      = cpi;
73     compressedrow->rindex = ridx;
74   }
75   PetscFunctionReturn(0);
76 }
77