1 2 #include "src/mat/matimpl.h" /*I "petscmat.h" I*/ 3 4 #undef __FUNCT__ 5 #define __FUNCT__ "Mat_CheckCompressedRow" 6 /*@C 7 Mat_CheckCompressedRow - Determines whether the compressed row matrix format should be used. 8 If the format is to be used, this routine creates Mat_CompressedRow struct. 9 Compressed row format provides high performance routines by taking advantage of zero rows. 10 Supported types are MATAIJ, MATBAIJ and MATSBAIJ. 11 12 Collective 13 14 Input Parameters: 15 + A - the matrix 16 . compressedrow - pointer to the struct Mat_CompressedRow 17 . ai - row pointer used by seqaij and seqbaij 18 - ratio - ratio of (num of zero rows)/m, used to determine if the compressed row format should be used 19 20 Level: developer 21 @*/ 22 PetscErrorCode Mat_CheckCompressedRow(Mat A,Mat_CompressedRow *compressedrow,PetscInt *ai,PetscReal ratio) 23 { 24 PetscErrorCode ierr; 25 PetscInt nrows,*cpi=PETSC_NULL,*ridx=PETSC_NULL,nz,i,row,m=A->m; 26 MatType mtype; 27 PetscMPIInt size; 28 PetscTruth aij; 29 30 PetscFunctionBegin; 31 if (!compressedrow->use) PetscFunctionReturn(0); 32 if (compressedrow->checked){ 33 if (!A->same_nonzero){ 34 ierr = PetscFree(compressedrow->i);CHKERRQ(ierr); 35 compressedrow->rindex = PETSC_NULL; 36 PetscLogInfo(A,"Mat_CheckCompressedRow: Mat structure might be changed. Free memory and recheck.\n"); 37 } else if (compressedrow->i == PETSC_NULL) { 38 /* Don't know why this occures. For safe, recheck. */ 39 PetscLogInfo(A,"Mat_CheckCompressedRow: compressedrow.checked, but compressedrow.i==null. Recheck.\n"); 40 } else { /* use compressedrow, checked, A->same_nonzero = PETSC_TRUE. Skip check */ 41 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); 42 PetscFunctionReturn(0); 43 } 44 } 45 compressedrow->checked = PETSC_TRUE; 46 47 /* set m=A->m/A->bs for BAIJ and SBAIJ matrices */ 48 ierr = MatGetType(A,&mtype);CHKERRQ(ierr); 49 ierr = PetscStrcmp(mtype,MATAIJ,&aij);CHKERRQ(ierr); 50 ierr = MPI_Comm_size(A->comm,&size);CHKERRQ(ierr); 51 if (!aij){ 52 if (size == 1){ 53 ierr = PetscStrcmp(mtype,MATSEQAIJ,&aij);CHKERRQ(ierr); 54 } else { 55 ierr = PetscStrcmp(mtype,MATMPIAIJ,&aij);CHKERRQ(ierr); 56 } 57 } 58 if (!aij){ 59 m = m/A->bs; 60 } 61 62 /* compute number of zero rows */ 63 nrows = 0; 64 for (i=0; i<m; i++){ /* for each row */ 65 nz = ai[i+1] - ai[i]; /* number of nonzeros */ 66 if (nz == 0) nrows++; 67 } 68 /* if enough zero rows are found, use compressedrow data structure */ 69 if (nrows < ratio*m) { 70 compressedrow->use = PETSC_FALSE; 71 PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) < %g. Do not use CompressedRow routines.\n",nrows,m,ratio); 72 } else { 73 compressedrow->use = PETSC_TRUE; 74 PetscLogInfo(A,"Mat_CheckCompressedRow: Found the ratio (num_zerorows %d)/(num_localrows %d) > %g. Use CompressedRow routines.\n",nrows,m,ratio); 75 76 /* set compressed row format */ 77 nrows = m - nrows; /* num of non-zero rows */ 78 ierr = PetscMalloc((2*nrows+1)*sizeof(PetscInt),&cpi);CHKERRQ(ierr); 79 ridx = cpi + nrows + 1; 80 row = 0; 81 cpi[0] = 0; 82 for (i=0; i<m; i++){ 83 nz = ai[i+1] - ai[i]; 84 if (nz == 0) continue; 85 cpi[row+1] = ai[i+1]; /* compressed row pointer */ 86 ridx[row++] = i; /* compressed row local index */ 87 } 88 compressedrow->nrows = nrows; 89 compressedrow->i = cpi; 90 compressedrow->rindex = ridx; 91 } 92 93 PetscFunctionReturn(0); 94 } 95