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" 7*3acb8795SBarry Smith /* 8*3acb8795SBarry Smith This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks. 9*3acb8795SBarry Smith This is why it has the ugly code with the MatGetBlockSize() 10*3acb8795SBarry Smith */ 11dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 12639f9d9dSBarry Smith { 136849ba73SBarry Smith PetscErrorCode ierr; 14*3acb8795SBarry Smith PetscInt i,n,nrows,N,j,k,m,*rows,*ci,*cj,ncols,col; 155d0c19d7SBarry Smith const PetscInt *is; 16*3acb8795SBarry Smith PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1; 17b9617806SBarry Smith IS *isa; 1890d69ab7SBarry Smith PetscTruth done,flg = PETSC_FALSE; 19*3acb8795SBarry Smith PetscTruth flg1,flg2; 20639f9d9dSBarry Smith 213a40ed3dSBarry Smith PetscFunctionBegin; 22522c5e43SBarry Smith if (!mat->assembled) { 2329bbc08cSBarry Smith SETERRQ(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); 27*3acb8795SBarry Smith /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ 28*3acb8795SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); 29*3acb8795SBarry Smith ierr = PetscTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); 30*3acb8795SBarry Smith if (flg1 || flg2) { 31*3acb8795SBarry Smith ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 32*3acb8795SBarry Smith } 33*3acb8795SBarry Smith 34*3acb8795SBarry Smith N = mat->cmap->N/bs; 35*3acb8795SBarry Smith c->M = mat->rmap->N/bs; /* set total rows, columns and local rows */ 36*3acb8795SBarry Smith c->N = mat->cmap->N/bs; 37*3acb8795SBarry 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 47*3acb8795SBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 48*3acb8795SBarry Smith if (!done) SETERRQ1(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 { 12729bbc08cSBarry Smith SETERRQ(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 } 146*3acb8795SBarry 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