1 #define PETSCMAT_DLL 2 3 #include "private/matimpl.h" /*I "petscmat.h" I*/ 4 5 #undef __FUNCT__ 6 #define __FUNCT__ "Mat_CheckCompressedRow" 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. 12 13 Collective 14 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 21 22 Level: developer 23 @*/ 24 PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscInt mbs,PetscReal ratio) 25 { 26 PetscErrorCode ierr; 27 PetscInt nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row; 28 29 PetscFunctionBegin; 30 if (!compressedrow->use) PetscFunctionReturn(0); 31 if (compressedrow->checked){ 32 if (!A->same_nonzero){ 33 ierr = PetscFree(compressedrow->i);CHKERRQ(ierr); 34 compressedrow->rindex = PETSC_NULL; 35 ierr = PetscInfo(A,"Mat structure might be changed. Free memory and recheck.\n");CHKERRQ(ierr); 36 } else if (!compressedrow->i) { 37 /* Don't know why this occures. For safe, recheck. */ 38 ierr = PetscInfo(A,"compressedrow.checked, but compressedrow.i==null. Recheck.\n");CHKERRQ(ierr); 39 } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */ 40 ierr = PetscInfo7(A,"Skip check. m: %d, n: %d,M: %d, N: %d,nrows: %d, ii: %p, type: %s\n",A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N,compressedrow->nrows,compressedrow->i,((PetscObject)A)->type_name);CHKERRQ(ierr); 41 PetscFunctionReturn(0); 42 } 43 } 44 compressedrow->checked = PETSC_TRUE; 45 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 ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) < %G. Do not use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr); 56 } else { 57 compressedrow->use = PETSC_TRUE; 58 ierr = PetscInfo3(A,"Found the ratio (num_zerorows %d)/(num_localrows %d) > %G. Use CompressedRow routines.\n",nrows,mbs,ratio);CHKERRQ(ierr); 59 60 /* set compressed row format */ 61 nrows = mbs - nrows; /* num of non-zero rows */ 62 ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr); 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 PetscFunctionReturn(0); 78 } 79