xref: /petsc/src/mat/utils/compressedrow.c (revision 2f53aa61faf3134337ec854123d12c3d410d20ec)
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
773e7a558SHong Zhang    Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used. If
873e7a558SHong Zhang                             the format is to be used, this routine creates Mat_CompressedRow struct.
973e7a558SHong Zhang 
1073e7a558SHong Zhang                             Compressed row format provides high performance routines by
1173e7a558SHong Zhang                             taking advantage of zero rows.
1273e7a558SHong Zhang 
1373e7a558SHong Zhang    Collective
1473e7a558SHong Zhang 
1573e7a558SHong Zhang    Input Parameters:
1673e7a558SHong Zhang +  A             - the matrix
1773e7a558SHong Zhang .  compressedrow - pointer to the struct Mat_CompressedRow
1873e7a558SHong Zhang .  ai            - row pointer used by seqaij and seqbaij
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 @*/
2373e7a558SHong Zhang PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscReal ratio)
2473e7a558SHong Zhang {
2573e7a558SHong Zhang   PetscErrorCode ierr;
267b2bb3b9SHong Zhang   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row,m=A->m/A->bs;
2773e7a558SHong Zhang 
2873e7a558SHong Zhang   PetscFunctionBegin;
2988e51ccdSHong Zhang   if (!compressedrow->use) PetscFunctionReturn(0);
30*2f53aa61SHong Zhang   if (compressedrow->checked){
31*2f53aa61SHong 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");
35*2f53aa61SHong Zhang     } else if (compressedrow->i == PETSC_NULL) {
36*2f53aa61SHong Zhang       /* Don't know why this occures. For safe, recheck. */
37*2f53aa61SHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: compressedrow.checked, but compressedrow.i==null. Recheck.\n");
38*2f53aa61SHong Zhang     } else { /* use compressedrow, checked, and A->same_nonzero = PETSC_TRUE. Skip check */
39*2f53aa61SHong Zhang       PetscFunctionReturn(0);
40*2f53aa61SHong Zhang     }
4188e51ccdSHong Zhang   }
4273e7a558SHong Zhang   compressedrow->checked = PETSC_TRUE;
4373e7a558SHong Zhang 
4473e7a558SHong Zhang   /* compute number of zero rows */
4573e7a558SHong Zhang   nrows = 0;
4673e7a558SHong Zhang   for (i=0; i<m; i++){                /* for each row */
4773e7a558SHong Zhang     nz = ai[i+1] - ai[i];       /* number of nonzeros */
4873e7a558SHong Zhang     if (nz == 0) nrows++;
4973e7a558SHong Zhang   }
5073e7a558SHong Zhang   /* if enough zero rows are found, use compressedrow data structure */
5173e7a558SHong Zhang   if (nrows < ratio*m) {
5273e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
5326e093fcSHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) < %g. Do not use CompressedRow routines.\n",nrows,m,ratio);
5473e7a558SHong Zhang   } else {
5573e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
5673e7a558SHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) > %g. Use CompressedRow routines.\n",nrows,m,ratio);
5773e7a558SHong Zhang 
5873e7a558SHong Zhang     /* set compressed row format */
5973e7a558SHong Zhang     nrows = m - nrows; /* num of non-zero rows */
6073e7a558SHong Zhang     ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr);
617b2bb3b9SHong Zhang     ridx = cpi + nrows + 1;
6273e7a558SHong Zhang     row    = 0;
6373e7a558SHong Zhang     cpi[0] = 0;
6473e7a558SHong Zhang     for (i=0; i<m; i++){
6573e7a558SHong Zhang       nz = ai[i+1] - ai[i];
6673e7a558SHong Zhang       if (nz == 0) continue;
6773e7a558SHong Zhang       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
687b2bb3b9SHong Zhang       ridx[row++] = i;          /* compressed row local index */
6973e7a558SHong Zhang     }
7073e7a558SHong Zhang     compressedrow->nrows  = nrows;
7173e7a558SHong Zhang     compressedrow->i      = cpi;
727b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
7373e7a558SHong Zhang   }
7473e7a558SHong Zhang   PetscFunctionReturn(0);
7573e7a558SHong Zhang }
76