1be1d678aSKris Buschelman #define PETSCMAT_DLL 270c3da92SBarry Smith 37c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h" 4639f9d9dSBarry Smith 54a2ae208SSatish Balay #undef __FUNCT__ 64a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ" 73acb8795SBarry Smith /* 83acb8795SBarry Smith This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks. 93acb8795SBarry Smith This is why it has the ugly code with the MatGetBlockSize() 103acb8795SBarry Smith */ 11dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 12639f9d9dSBarry Smith { 136849ba73SBarry Smith PetscErrorCode ierr; 143acb8795SBarry Smith PetscInt i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col; 155d0c19d7SBarry Smith const PetscInt *is; 163acb8795SBarry Smith PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1; 17b9617806SBarry Smith IS *isa; 1890d69ab7SBarry Smith PetscTruth done,flg = PETSC_FALSE; 193acb8795SBarry Smith PetscTruth flg1,flg2; 20639f9d9dSBarry Smith 213a40ed3dSBarry Smith PetscFunctionBegin; 22522c5e43SBarry Smith if (!mat->assembled) { 23*e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 24522c5e43SBarry Smith } 25522c5e43SBarry Smith 26b9617806SBarry Smith ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 273acb8795SBarry Smith /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ 283acb8795SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); 293acb8795SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); 303acb8795SBarry Smith if (flg1 || flg2) { 313acb8795SBarry Smith ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 323acb8795SBarry Smith } 333acb8795SBarry Smith 343acb8795SBarry Smith N = mat->cmap->N/bs; 353acb8795SBarry Smith c->M = mat->rmap->N/bs; /* set total rows, columns and local rows */ 363acb8795SBarry Smith c->N = mat->cmap->N/bs; 373acb8795SBarry Smith c->m = mat->rmap->N/bs; 38005c665bSBarry Smith c->rstart = 0; 39005c665bSBarry Smith 40639f9d9dSBarry Smith c->ncolors = nis; 4138baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr); 4238baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr); 4338baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr); 4438baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr); 4538baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr); 4643a90d84SBarry Smith 473acb8795SBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 48*e32f2f54SBarry Smith if (!done) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name); 4970c3da92SBarry Smith 5070c3da92SBarry Smith /* 51639f9d9dSBarry Smith Temporary option to allow for debugging/testing 5270c3da92SBarry Smith */ 5390d69ab7SBarry Smith ierr = PetscOptionsGetTruth(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);CHKERRQ(ierr); 5470c3da92SBarry Smith 5538baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr); 5638baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr); 5770c3da92SBarry Smith 58639f9d9dSBarry Smith for (i=0; i<nis; i++) { 59b9b97703SBarry Smith ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 60639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 61639f9d9dSBarry Smith c->ncolumns[i] = n; 62639f9d9dSBarry Smith if (n) { 6338baddfdSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr); 6438baddfdSBarry Smith ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr); 6570c3da92SBarry Smith } else { 66639f9d9dSBarry Smith c->columns[i] = 0; 6770c3da92SBarry Smith } 6870c3da92SBarry Smith 693a7fca6bSBarry Smith if (!flg) { /* ------------------------------------------------------------------------------*/ 703a7fca6bSBarry Smith /* fast, crude version requires O(N*N) work */ 7138baddfdSBarry Smith ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr); 72639f9d9dSBarry Smith /* loop over columns*/ 73639f9d9dSBarry Smith for (j=0; j<n; j++) { 74639f9d9dSBarry Smith col = is[j]; 75639f9d9dSBarry Smith rows = cj + ci[col]; 76639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 77639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 78639f9d9dSBarry Smith for (k=0; k<m; k++) { 79639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 8070c3da92SBarry Smith } 8170c3da92SBarry Smith } 82639f9d9dSBarry Smith /* count the number of hits */ 83639f9d9dSBarry Smith nrows = 0; 8470c3da92SBarry Smith for (j=0; j<N; j++) { 85639f9d9dSBarry Smith if (rowhit[j]) nrows++; 86639f9d9dSBarry Smith } 87639f9d9dSBarry Smith c->nrows[i] = nrows; 8838baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 8938baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 90639f9d9dSBarry Smith nrows = 0; 91639f9d9dSBarry Smith for (j=0; j<N; j++) { 92639f9d9dSBarry Smith if (rowhit[j]) { 93639f9d9dSBarry Smith c->rows[i][nrows] = j; 94639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 95639f9d9dSBarry Smith nrows++; 9670c3da92SBarry Smith } 9770c3da92SBarry Smith } 98639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 993a7fca6bSBarry Smith /* slow version, using rowhit as a linked list */ 10038baddfdSBarry Smith PetscInt currentcol,fm,mfm; 101639f9d9dSBarry Smith rowhit[N] = N; 102639f9d9dSBarry Smith nrows = 0; 103639f9d9dSBarry Smith /* loop over columns */ 104639f9d9dSBarry Smith for (j=0; j<n; j++) { 105639f9d9dSBarry Smith col = is[j]; 106639f9d9dSBarry Smith rows = cj + ci[col]; 107639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 108639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 109639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 110639f9d9dSBarry Smith for (k=0; k<m; k++) { 111639f9d9dSBarry Smith currentcol = *rows++; 112639f9d9dSBarry Smith /* is it already in the list? */ 113639f9d9dSBarry Smith do { 114639f9d9dSBarry Smith mfm = fm; 115639f9d9dSBarry Smith fm = rowhit[fm]; 116639f9d9dSBarry Smith } while (fm < currentcol); 117639f9d9dSBarry Smith /* not in list so add it */ 118639f9d9dSBarry Smith if (fm != currentcol) { 119639f9d9dSBarry Smith nrows++; 120639f9d9dSBarry Smith columnsforrow[currentcol] = col; 121639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 122639f9d9dSBarry Smith rowhit[mfm] = currentcol; 123639f9d9dSBarry Smith rowhit[currentcol] = fm; 124639f9d9dSBarry Smith fm = currentcol; 125639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 12670c3da92SBarry Smith } else { 127*e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring"); 12870c3da92SBarry Smith } 129639f9d9dSBarry Smith 130639f9d9dSBarry Smith } 131639f9d9dSBarry Smith } 132639f9d9dSBarry Smith c->nrows[i] = nrows; 13338baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 13438baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 135639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 136639f9d9dSBarry Smith nrows = 0; 137639f9d9dSBarry Smith fm = rowhit[N]; 138639f9d9dSBarry Smith do { 139639f9d9dSBarry Smith c->rows[i][nrows] = fm; 140639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 141639f9d9dSBarry Smith fm = rowhit[fm]; 142639f9d9dSBarry Smith } while (fm < N); 143639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 144639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 145639f9d9dSBarry Smith } 1463acb8795SBarry Smith ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 147639f9d9dSBarry Smith 148606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 149606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 150639f9d9dSBarry Smith 15130b34957SBarry Smith /* Optimize by adding the vscale, and scaleforrow[][] fields */ 15230b34957SBarry Smith /* 15330b34957SBarry Smith see the version for MPIAIJ 15430b34957SBarry Smith */ 155d0f46423SBarry Smith ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr) 15638baddfdSBarry Smith ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr); 15730b34957SBarry Smith for (k=0; k<c->ncolors; k++) { 15838baddfdSBarry Smith ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr); 15930b34957SBarry Smith for (l=0; l<c->nrows[k]; l++) { 16030b34957SBarry Smith col = c->columnsforrow[k][l]; 16130b34957SBarry Smith c->vscaleforrow[k][l] = col; 16230b34957SBarry Smith } 16330b34957SBarry Smith } 164b9617806SBarry Smith ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 1653a40ed3dSBarry Smith PetscFunctionReturn(0); 16670c3da92SBarry Smith } 167