xref: /petsc/src/mat/utils/compressedrow.c (revision f38b99b6b94dabc01f01602ad2c04e26fc81962c)
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
7*f38b99b6SHong Zhang    Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used.
8*f38b99b6SHong Zhang       If the format is to be used, this routine creates Mat_CompressedRow struct.
9*f38b99b6SHong Zhang       Compressed row format provides high performance routines by taking advantage of zero rows.
10*f38b99b6SHong 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
1873e7a558SHong Zhang -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
1973e7a558SHong Zhang 
2073e7a558SHong Zhang    Level: developer
2173e7a558SHong Zhang @*/
2273e7a558SHong Zhang PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscReal ratio)
2373e7a558SHong Zhang {
2473e7a558SHong Zhang   PetscErrorCode ierr;
25*f38b99b6SHong Zhang   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row,m=A->m;
26*f38b99b6SHong Zhang   MatType        mtype;
27*f38b99b6SHong Zhang   PetscMPIInt    size;
28*f38b99b6SHong Zhang   PetscTruth     aij;
2973e7a558SHong Zhang 
3073e7a558SHong Zhang   PetscFunctionBegin;
3188e51ccdSHong Zhang   if (!compressedrow->use) PetscFunctionReturn(0);
322f53aa61SHong Zhang   if (compressedrow->checked){
332f53aa61SHong Zhang     if (!A->same_nonzero){
3488e51ccdSHong Zhang       ierr = PetscFree(compressedrow->i);CHKERRQ(ierr);
3588e51ccdSHong Zhang       compressedrow->rindex = PETSC_NULL;
3688e51ccdSHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: Mat structure might be changed. Free memory and recheck.\n");
372f53aa61SHong Zhang     } else if (compressedrow->i == PETSC_NULL) {
382f53aa61SHong Zhang       /* Don't know why this occures. For safe, recheck. */
392f53aa61SHong Zhang       PetscLogInfo(A,"Mat_CheckCompressedRow: compressedrow.checked, but compressedrow.i==null. Recheck.\n");
40*f38b99b6SHong Zhang     } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */
41*f38b99b6SHong 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);
422f53aa61SHong Zhang       PetscFunctionReturn(0);
432f53aa61SHong Zhang     }
4488e51ccdSHong Zhang   }
4573e7a558SHong Zhang   compressedrow->checked = PETSC_TRUE;
4673e7a558SHong Zhang 
47*f38b99b6SHong Zhang   /* set m=A->m/A->bs for BAIJ and SBAIJ matrices */
48*f38b99b6SHong Zhang   ierr = MatGetType(A,&mtype);CHKERRQ(ierr);
49*f38b99b6SHong Zhang   ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr);
50*f38b99b6SHong Zhang   ierr = MPI_Comm_size(A->comm,&size);CHKERRQ(ierr);
51*f38b99b6SHong Zhang   if (!aij){
52*f38b99b6SHong Zhang     if (size == 1){
53*f38b99b6SHong Zhang       ierr = PetscStrcmp(mtype,MATSEQAIJ,&aij);CHKERRQ(ierr);
54*f38b99b6SHong Zhang     } else {
55*f38b99b6SHong Zhang       ierr = PetscStrcmp(mtype,MATMPIAIJ,&aij);CHKERRQ(ierr);
56*f38b99b6SHong Zhang     }
57*f38b99b6SHong Zhang   }
58*f38b99b6SHong Zhang   if (!aij){
59*f38b99b6SHong Zhang     m = m/A->bs;
60*f38b99b6SHong Zhang   }
61*f38b99b6SHong Zhang 
6273e7a558SHong Zhang   /* compute number of zero rows */
6373e7a558SHong Zhang   nrows = 0;
6473e7a558SHong Zhang   for (i=0; i<m; i++){                /* for each row */
6573e7a558SHong Zhang     nz = ai[i+1] - ai[i];       /* number of nonzeros */
6673e7a558SHong Zhang     if (nz == 0) nrows++;
6773e7a558SHong Zhang   }
6873e7a558SHong Zhang   /* if enough zero rows are found, use compressedrow data structure */
6973e7a558SHong Zhang   if (nrows < ratio*m) {
7073e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
7126e093fcSHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) < %g. Do not use CompressedRow routines.\n",nrows,m,ratio);
7273e7a558SHong Zhang   } else {
7373e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
7473e7a558SHong Zhang     PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) > %g. Use CompressedRow routines.\n",nrows,m,ratio);
7573e7a558SHong Zhang 
7673e7a558SHong Zhang     /* set compressed row format */
7773e7a558SHong Zhang     nrows = m - nrows; /* num of non-zero rows */
7873e7a558SHong Zhang     ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr);
797b2bb3b9SHong Zhang     ridx = cpi + nrows + 1;
8073e7a558SHong Zhang     row    = 0;
8173e7a558SHong Zhang     cpi[0] = 0;
8273e7a558SHong Zhang     for (i=0; i<m; i++){
8373e7a558SHong Zhang       nz = ai[i+1] - ai[i];
8473e7a558SHong Zhang       if (nz == 0) continue;
8573e7a558SHong Zhang       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
867b2bb3b9SHong Zhang       ridx[row++] = i;          /* compressed row local index */
8773e7a558SHong Zhang     }
8873e7a558SHong Zhang     compressedrow->nrows  = nrows;
8973e7a558SHong Zhang     compressedrow->i      = cpi;
907b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
9173e7a558SHong Zhang   }
92*f38b99b6SHong Zhang 
9373e7a558SHong Zhang   PetscFunctionReturn(0);
9473e7a558SHong Zhang }
95