Actual source code: compressedrow.c

      1: #define PETSCMAT_DLL

     3:  #include src/mat/matimpl.h

      7: /*@C
      8:    Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used.
      9:       If the format is to be used, this routine creates Mat_CompressedRow struct.
     10:       Compressed row format provides high performance routines by taking advantage of zero rows.
     11:       Supported types are MATAIJ, MATBAIJ and MATSBAIJ.

     13:    Collective

     15:    Input Parameters:
     16: +  A             - the matrix
     17: .  compressedrow - pointer to the struct Mat_CompressedRow
     18: .  ai            - row pointer used by seqaij and seqbaij
     19: .  mbs           - number of (block) rows represented by ai
     20: -  ratio         - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used

     22:    Level: developer
     23: @*/
     24: PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio)
     25: {
     27:   PetscInt       nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row;

     30:   if (!compressedrow->use) return(0);
     31:   if (compressedrow->checked){
     32:     if (!A->same_nonzero){
     33:       PetscFree(compressedrow->i);
     34:       compressedrow->rindex = PETSC_NULL;
     35:       PetscLogInfo((A,"Mat_CheckCompressedRow: Mat structure might be changed. Free memory and recheck.\n"));
     36:     } else if (compressedrow->i == PETSC_NULL) {
     37:       /* Don't know why this occures. For safe, recheck. */
     38:       PetscLogInfo((A,"Mat_CheckCompressedRow: compressedrow.checked, but compressedrow.i==null. Recheck.\n"));
     39:     } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */
     40:       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));
     41:       return(0);
     42:     }
     43:   }
     44:   compressedrow->checked = PETSC_TRUE;

     46:   /* compute number of zero rows */
     47:   nrows = 0;
     48:   for (i=0; i<mbs; i++){        /* for each row */
     49:     nz = ai[i+1] - ai[i];       /* number of nonzeros */
     50:     if (nz == 0) nrows++;
     51:   }
     52:   /* if a large number of zero rows is found, use compressedrow data structure */
     53:   if (nrows < ratio*mbs) {
     54:     compressedrow->use = PETSC_FALSE;
     55:     PetscLogInfo((A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) < %g. Do not use CompressedRow routines.\n",nrows,mbs,ratio));
     56:   } else {
     57:     compressedrow->use = PETSC_TRUE;
     58:     PetscLogInfo((A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) > %g. Use CompressedRow routines.\n",nrows,mbs,ratio));

     60:     /* set compressed row format */
     61:     nrows = mbs - nrows; /* num of non-zero rows */
     62:     PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);
     63:     ridx = cpi + nrows + 1;
     64:     row    = 0;
     65:     cpi[0] = 0;
     66:     for (i=0; i<mbs; i++){
     67:       nz = ai[i+1] - ai[i];
     68:       if (nz == 0) continue;
     69:       cpi[row+1]  = ai[i+1];    /* compressed row pointer */
     70:       ridx[row++] = i;          /* compressed row local index */
     71:     }
     72:     compressedrow->nrows  = nrows;
     73:     compressedrow->i      = cpi;
     74:     compressedrow->rindex = ridx;
     75:   }
     76:
     77:   return(0);
     78: }