xref: /petsc/src/mat/utils/compressedrow.c (revision 8aea9937aef7918d6ce70e7f37aab7047107d0fd)
173e7a558SHong Zhang 
2b45d2f2cSJed Brown #include <petsc-private/matimpl.h>  /*I   "petscmat.h"  I*/
326e093fcSHong Zhang 
473e7a558SHong Zhang #undef __FUNCT__
5cd6b891eSBarry Smith #define __FUNCT__ "MatCheckCompressedRow"
673e7a558SHong Zhang /*@C
7cd6b891eSBarry Smith    MatCheckCompressedRow - Determines whether the compressed row matrix format should be used.
8f38b99b6SHong Zhang       If the format is to be used, this routine creates Mat_CompressedRow struct.
9f38b99b6SHong Zhang       Compressed row format provides high performance routines by taking advantage of zero rows.
10f38b99b6SHong Zhang       Supported types are MATAIJ, MATBAIJ and MATSBAIJ.
1173e7a558SHong Zhang 
1273e7a558SHong Zhang    Collective
1373e7a558SHong Zhang 
1473e7a558SHong Zhang    Input Parameters:
1573e7a558SHong Zhang +  A             - the matrix
1673e7a558SHong Zhang .  compressedrow - pointer to the struct Mat_CompressedRow
1773e7a558SHong Zhang .  ai            - row pointer used by seqaij and seqbaij
18317fbc4cSHong Zhang .  mbs           - number of (block) rows represented by ai
1973e7a558SHong Zhang -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
2073e7a558SHong Zhang 
21cd6b891eSBarry Smith    Notes: By default PETSc will not check for compressed rows on sequential matrices. Call MatSetOption(Mat,MAT_CHECK_COMPRESSED_ROW,PETSC_TRUE); before
22cd6b891eSBarry Smith           MatAssemblyBegin() to have it check.
23cd6b891eSBarry Smith 
24340b11eeSBarry Smith    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
25340b11eeSBarry Smith                    the values are not therefore obtained by directly taking the values from the matrix object.
26*8aea9937SBarry 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
27*8aea9937SBarry Smith                    by some preconditioners and hence is labeled as PETSC_EXTERN
28*8aea9937SBarry Smith 
2973e7a558SHong Zhang    Level: developer
3073e7a558SHong Zhang @*/
31*8aea9937SBarry Smith PETSC_EXTERN PetscErrorCode MatCheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
3273e7a558SHong Zhang {
3373e7a558SHong Zhang   PetscErrorCode ierr;
340298fd71SBarry Smith   PetscInt       nrows,*cpi=NULL,*ridx=NULL,nz,i,row;
3573e7a558SHong Zhang 
3673e7a558SHong Zhang   PetscFunctionBegin;
37cd6b891eSBarry Smith   if (!compressedrow->check) PetscFunctionReturn(0);
38cd6b891eSBarry Smith 
39cd6b891eSBarry Smith   /* in case this is being reused, delete old space */
400e83c824SBarry Smith   ierr = PetscFree2(compressedrow->i,compressedrow->rindex);CHKERRQ(ierr);
418865f1eaSKarl Rupp 
420298fd71SBarry Smith   compressedrow->i      = NULL;
430298fd71SBarry Smith   compressedrow->rindex = NULL;
44cd6b891eSBarry Smith 
4573e7a558SHong Zhang 
4673e7a558SHong Zhang   /* compute number of zero rows */
4773e7a558SHong Zhang   nrows = 0;
48317fbc4cSHong Zhang   for (i=0; i<mbs; i++) {        /* for each row */
4973e7a558SHong Zhang     nz = ai[i+1] - ai[i];       /* number of nonzeros */
5073e7a558SHong Zhang     if (nz == 0) nrows++;
5173e7a558SHong Zhang   }
52baa4e9faSMark F. Adams 
53317fbc4cSHong Zhang   /* if a large number of zero rows is found, use compressedrow data structure */
54317fbc4cSHong Zhang   if (nrows < ratio*mbs) {
5573e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
568865f1eaSKarl Rupp 
57ae15b995SBarry Smith     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) < %G. Do not use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
5873e7a558SHong Zhang   } else {
5973e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
608865f1eaSKarl Rupp 
61ae15b995SBarry Smith     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) > %G. Use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
6273e7a558SHong Zhang 
6373e7a558SHong Zhang     /* set compressed row format */
64317fbc4cSHong Zhang     nrows  = mbs - nrows; /* num of non-zero rows */
650e83c824SBarry Smith     ierr   = PetscMalloc2(nrows+1,PetscInt,&cpi,nrows,PetscInt,&ridx);CHKERRQ(ierr);
6673e7a558SHong Zhang     row    = 0;
6773e7a558SHong Zhang     cpi[0] = 0;
68317fbc4cSHong Zhang     for (i=0; i<mbs; i++) {
6973e7a558SHong Zhang       nz = ai[i+1] - ai[i];
7073e7a558SHong Zhang       if (nz == 0) continue;
7173e7a558SHong Zhang       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
727b2bb3b9SHong Zhang       ridx[row++] = i;          /* compressed row local index */
7373e7a558SHong Zhang     }
7473e7a558SHong Zhang     compressedrow->nrows  = nrows;
7573e7a558SHong Zhang     compressedrow->i      = cpi;
767b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
7773e7a558SHong Zhang   }
7873e7a558SHong Zhang   PetscFunctionReturn(0);
7973e7a558SHong Zhang }
80