xref: /petsc/src/mat/utils/compressedrow.c (revision 317fbc4c7bd1b0884a0390148045ff7a4bc8ee74)
173e7a558SHong Zhang 
226e093fcSHong Zhang #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
326e093fcSHong Zhang 
473e7a558SHong Zhang #undef __FUNCT__
573e7a558SHong Zhang #define __FUNCT__ "Mat_CheckCompressedRow"
673e7a558SHong Zhang /*@C
7f38b99b6SHong Zhang    Mat_CheckCompressedRow - 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
18*317fbc4cSHong 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 
2173e7a558SHong Zhang    Level: developer
2273e7a558SHong Zhang @*/
23*317fbc4cSHong Zhang PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
2473e7a558SHong Zhang {
2573e7a558SHong Zhang   PetscErrorCode ierr;
26*317fbc4cSHong Zhang   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row;
2773e7a558SHong Zhang 
2873e7a558SHong Zhang   PetscFunctionBegin;
2988e51ccdSHong Zhang   if (!compressedrow->use) PetscFunctionReturn(0);
302f53aa61SHong Zhang   if (compressedrow->checked){
312f53aa61SHong Zhang     if (!A->same_nonzero){
3288e51ccdSHong Zhang       ierr = PetscFree(compressedrow->i);CHKERRQ(ierr);
3388e51ccdSHong Zhang       compressedrow->rindex = PETSC_NULL;
3488e51ccdSHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: Mat structure might be changed. Free memory and recheck.\n");
352f53aa61SHong Zhang     } else if (compressedrow->i == PETSC_NULL) {
362f53aa61SHong Zhang       /* Don't know why this occures. For safe, recheck. */
372f53aa61SHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: compressedrow.checked, but compressedrow.i==null. Recheck.\n");
38f38b99b6SHong Zhang     } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */
39f38b99b6SHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: Skip check. m: %d, n: %d,M: %d, N: %d,nrows: %d, ii: %p, type: %s\n",A->m,A->n,A->M,A->N,compressedrow->nrows,compressedrow->i,A->type_name);
402f53aa61SHong Zhang       PetscFunctionReturn(0);
412f53aa61SHong Zhang     }
4288e51ccdSHong Zhang   }
4373e7a558SHong Zhang   compressedrow->checked = PETSC_TRUE;
4473e7a558SHong Zhang 
4573e7a558SHong Zhang   /* compute number of zero rows */
4673e7a558SHong Zhang   nrows = 0;
47*317fbc4cSHong Zhang   for (i=0; i<mbs; i++){        /* for each row */
4873e7a558SHong Zhang     nz = ai[i+1] - ai[i];       /* number of nonzeros */
4973e7a558SHong Zhang     if (nz == 0) nrows++;
5073e7a558SHong Zhang   }
51*317fbc4cSHong Zhang   /* if a large number of zero rows is found, use compressedrow data structure */
52*317fbc4cSHong Zhang   if (nrows < ratio*mbs) {
5373e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
54*317fbc4cSHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) < %g. Do not use CompressedRow routines.\n",nrows,mbs,ratio);
5573e7a558SHong Zhang   } else {
5673e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
57*317fbc4cSHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) > %g. Use CompressedRow routines.\n",nrows,mbs,ratio);
5873e7a558SHong Zhang 
5973e7a558SHong Zhang     /* set compressed row format */
60*317fbc4cSHong Zhang     nrows = mbs - nrows; /* num of non-zero rows */
6173e7a558SHong Zhang     ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr);
627b2bb3b9SHong Zhang     ridx = cpi + nrows + 1;
6373e7a558SHong Zhang     row    = 0;
6473e7a558SHong Zhang     cpi[0] = 0;
65*317fbc4cSHong Zhang     for (i=0; i<mbs; i++){
6673e7a558SHong Zhang       nz = ai[i+1] - ai[i];
6773e7a558SHong Zhang       if (nz == 0) continue;
6873e7a558SHong Zhang       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
697b2bb3b9SHong Zhang       ridx[row++] = i;          /* compressed row local index */
7073e7a558SHong Zhang     }
7173e7a558SHong Zhang     compressedrow->nrows  = nrows;
7273e7a558SHong Zhang     compressedrow->i      = cpi;
737b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
7473e7a558SHong Zhang   }
75f38b99b6SHong Zhang 
7673e7a558SHong Zhang   PetscFunctionReturn(0);
7773e7a558SHong Zhang }
78