xref: /petsc/src/mat/utils/compressedrow.c (revision ae15b995b5732fffd2de5a75cf61ef7190c6fef1)
1be1d678aSKris Buschelman #define PETSCMAT_DLL
273e7a558SHong Zhang 
326e093fcSHong Zhang #include "src/mat/matimpl.h"  /*I   "petscmat.h"  I*/
426e093fcSHong Zhang 
573e7a558SHong Zhang #undef __FUNCT__
673e7a558SHong Zhang #define __FUNCT__ "Mat_CheckCompressedRow"
773e7a558SHong Zhang /*@C
8f38b99b6SHong Zhang    Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used.
9f38b99b6SHong Zhang       If the format is to be used, this routine creates Mat_CompressedRow struct.
10f38b99b6SHong Zhang       Compressed row format provides high performance routines by taking advantage of zero rows.
11f38b99b6SHong Zhang       Supported types are MATAIJ, MATBAIJ and MATSBAIJ.
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
19317fbc4cSHong Zhang .  mbs           - number of (block) rows represented by ai
2073e7a558SHong Zhang -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used
2173e7a558SHong Zhang 
2273e7a558SHong Zhang    Level: developer
2373e7a558SHong Zhang @*/
24317fbc4cSHong Zhang PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
2573e7a558SHong Zhang {
2673e7a558SHong Zhang   PetscErrorCode ierr;
27317fbc4cSHong Zhang   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row;
2873e7a558SHong Zhang 
2973e7a558SHong Zhang   PetscFunctionBegin;
3088e51ccdSHong Zhang   if (!compressedrow->use) PetscFunctionReturn(0);
312f53aa61SHong Zhang   if (compressedrow->checked){
322f53aa61SHong Zhang     if (!A->same_nonzero){
3388e51ccdSHong Zhang       ierr = PetscFree(compressedrow->i);CHKERRQ(ierr);
3488e51ccdSHong Zhang       compressedrow->rindex = PETSC_NULL;
35*ae15b995SBarry Smith       ierr = PetscInfo(A,"Mat structure might be changed. Free memory and recheck.\n");CHKERRQ(ierr);
362f53aa61SHong Zhang     } else if (compressedrow->i == PETSC_NULL) {
372f53aa61SHong Zhang       /* Don't know why this occures. For safe, recheck. */
38*ae15b995SBarry Smith       ierr = PetscInfo(A,"compressedrow.checked, but compressedrow.i==null. Recheck.\n");CHKERRQ(ierr);
39f38b99b6SHong Zhang     } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */
40*ae15b995SBarry Smith       ierr = PetscInfo7(A,"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);CHKERRQ(ierr);
412f53aa61SHong Zhang       PetscFunctionReturn(0);
422f53aa61SHong Zhang     }
4388e51ccdSHong Zhang   }
4473e7a558SHong Zhang   compressedrow->checked = PETSC_TRUE;
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   }
52317fbc4cSHong Zhang   /* if a large number of zero rows is found, use compressedrow data structure */
53317fbc4cSHong Zhang   if (nrows < ratio*mbs) {
5473e7a558SHong Zhang     compressedrow->use = PETSC_FALSE;
55*ae15b995SBarry 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);
5673e7a558SHong Zhang   } else {
5773e7a558SHong Zhang     compressedrow->use = PETSC_TRUE;
58*ae15b995SBarry Smith     ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) > %G. Use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr);
5973e7a558SHong Zhang 
6073e7a558SHong Zhang     /* set compressed row format */
61317fbc4cSHong Zhang     nrows = mbs - nrows; /* num of non-zero rows */
6273e7a558SHong Zhang     ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr);
637b2bb3b9SHong Zhang     ridx = cpi + nrows + 1;
6473e7a558SHong Zhang     row    = 0;
6573e7a558SHong Zhang     cpi[0] = 0;
66317fbc4cSHong Zhang     for (i=0; i<mbs; i++){
6773e7a558SHong Zhang       nz = ai[i+1] - ai[i];
6873e7a558SHong Zhang       if (nz == 0) continue;
6973e7a558SHong Zhang       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
707b2bb3b9SHong Zhang       ridx[row++] = i;          /* compressed row local index */
7173e7a558SHong Zhang     }
7273e7a558SHong Zhang     compressedrow->nrows  = nrows;
7373e7a558SHong Zhang     compressedrow->i      = cpi;
747b2bb3b9SHong Zhang     compressedrow->rindex = ridx;
7573e7a558SHong Zhang   }
76f38b99b6SHong Zhang 
7773e7a558SHong Zhang   PetscFunctionReturn(0);
7873e7a558SHong Zhang }
79