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