170c3da92SBarry Smith 2c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 3639f9d9dSBarry Smith 44a2ae208SSatish Balay #undef __FUNCT__ 54a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ" 63acb8795SBarry Smith /* 73acb8795SBarry Smith This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks. 83acb8795SBarry Smith This is why it has the ugly code with the MatGetBlockSize() 93acb8795SBarry Smith */ 10dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 11639f9d9dSBarry Smith { 126849ba73SBarry Smith PetscErrorCode ierr; 131a83f524SJed Brown PetscInt i,n,nrows,N,j,k,m,ncols,col; 141a83f524SJed Brown const PetscInt *is,*rows,*ci,*cj; 153acb8795SBarry Smith PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1; 16b9617806SBarry Smith IS *isa; 17ace3abfcSBarry Smith PetscBool done,flg = PETSC_FALSE; 18ace3abfcSBarry Smith PetscBool flg1,flg2; 19639f9d9dSBarry Smith 203a40ed3dSBarry Smith PetscFunctionBegin; 21e7e72b3dSBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 22522c5e43SBarry Smith 23b9617806SBarry Smith ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 243acb8795SBarry Smith /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ 25251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); 26251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); 273acb8795SBarry Smith if (flg1 || flg2) { 283acb8795SBarry Smith ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 293acb8795SBarry Smith } 303acb8795SBarry Smith 313acb8795SBarry Smith N = mat->cmap->N/bs; 323acb8795SBarry Smith c->M = mat->rmap->N/bs; /* set total rows, columns and local rows */ 333acb8795SBarry Smith c->N = mat->cmap->N/bs; 343acb8795SBarry Smith c->m = mat->rmap->N/bs; 35005c665bSBarry Smith c->rstart = 0; 36005c665bSBarry Smith 37639f9d9dSBarry Smith c->ncolors = nis; 3838baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr); 3938baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr); 4038baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr); 4138baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr); 4238baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr); 4343a90d84SBarry Smith 443acb8795SBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 4565e19b50SBarry Smith if (!done) SETERRQ1(((PetscObject)mat)->comm,PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name); 4670c3da92SBarry Smith 4770c3da92SBarry Smith /* 48639f9d9dSBarry Smith Temporary option to allow for debugging/testing 4970c3da92SBarry Smith */ 50acfcf0e5SJed Brown ierr = PetscOptionsGetBool(PETSC_NULL,"-matfdcoloring_slow",&flg,PETSC_NULL);CHKERRQ(ierr); 5170c3da92SBarry Smith 5238baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr); 5338baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr); 5470c3da92SBarry Smith 55639f9d9dSBarry Smith for (i=0; i<nis; i++) { 56b9b97703SBarry Smith ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 57639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 58*2205254eSKarl Rupp 59639f9d9dSBarry Smith c->ncolumns[i] = n; 60639f9d9dSBarry Smith if (n) { 6138baddfdSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr); 6238baddfdSBarry Smith ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr); 6370c3da92SBarry Smith } else { 64639f9d9dSBarry Smith c->columns[i] = 0; 6570c3da92SBarry Smith } 6670c3da92SBarry Smith 673a7fca6bSBarry Smith if (!flg) { /* ------------------------------------------------------------------------------*/ 683a7fca6bSBarry Smith /* fast, crude version requires O(N*N) work */ 6938baddfdSBarry Smith ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr); 70639f9d9dSBarry Smith /* loop over columns*/ 71639f9d9dSBarry Smith for (j=0; j<n; j++) { 72639f9d9dSBarry Smith col = is[j]; 73639f9d9dSBarry Smith rows = cj + ci[col]; 74639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 75639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 76639f9d9dSBarry Smith for (k=0; k<m; k++) { 77639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 7870c3da92SBarry Smith } 7970c3da92SBarry Smith } 80639f9d9dSBarry Smith /* count the number of hits */ 81639f9d9dSBarry Smith nrows = 0; 8270c3da92SBarry Smith for (j=0; j<N; j++) { 83639f9d9dSBarry Smith if (rowhit[j]) nrows++; 84639f9d9dSBarry Smith } 85639f9d9dSBarry Smith c->nrows[i] = nrows; 8638baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 8738baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 88639f9d9dSBarry Smith nrows = 0; 89639f9d9dSBarry Smith for (j=0; j<N; j++) { 90639f9d9dSBarry Smith if (rowhit[j]) { 91639f9d9dSBarry Smith c->rows[i][nrows] = j; 92639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 93639f9d9dSBarry Smith nrows++; 9470c3da92SBarry Smith } 9570c3da92SBarry Smith } 96639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 973a7fca6bSBarry Smith /* slow version, using rowhit as a linked list */ 9838baddfdSBarry Smith PetscInt currentcol,fm,mfm; 99639f9d9dSBarry Smith rowhit[N] = N; 100639f9d9dSBarry Smith nrows = 0; 101639f9d9dSBarry Smith /* loop over columns */ 102639f9d9dSBarry Smith for (j=0; j<n; j++) { 103639f9d9dSBarry Smith col = is[j]; 104639f9d9dSBarry Smith rows = cj + ci[col]; 105639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 106639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 107639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 108639f9d9dSBarry Smith for (k=0; k<m; k++) { 109639f9d9dSBarry Smith currentcol = *rows++; 110639f9d9dSBarry Smith /* is it already in the list? */ 111639f9d9dSBarry Smith do { 112639f9d9dSBarry Smith mfm = fm; 113639f9d9dSBarry Smith fm = rowhit[fm]; 114639f9d9dSBarry Smith } while (fm < currentcol); 115639f9d9dSBarry Smith /* not in list so add it */ 116639f9d9dSBarry Smith if (fm != currentcol) { 117639f9d9dSBarry Smith nrows++; 118639f9d9dSBarry Smith columnsforrow[currentcol] = col; 119639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 120639f9d9dSBarry Smith rowhit[mfm] = currentcol; 121639f9d9dSBarry Smith rowhit[currentcol] = fm; 122639f9d9dSBarry Smith fm = currentcol; 123639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 12471cd77b2SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring"); 125639f9d9dSBarry Smith } 126639f9d9dSBarry Smith } 127639f9d9dSBarry Smith c->nrows[i] = nrows; 12838baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 12938baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 130639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 131639f9d9dSBarry Smith nrows = 0; 132639f9d9dSBarry Smith fm = rowhit[N]; 133639f9d9dSBarry Smith do { 134639f9d9dSBarry Smith c->rows[i][nrows] = fm; 135639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 136639f9d9dSBarry Smith fm = rowhit[fm]; 137639f9d9dSBarry Smith } while (fm < N); 138639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 139639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 140639f9d9dSBarry Smith } 1413acb8795SBarry Smith ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 142639f9d9dSBarry Smith 143606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 144606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 145639f9d9dSBarry Smith 14630b34957SBarry Smith /* Optimize by adding the vscale, and scaleforrow[][] fields */ 14730b34957SBarry Smith /* 14830b34957SBarry Smith see the version for MPIAIJ 14930b34957SBarry Smith */ 150cb9801acSJed Brown ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr); 15138baddfdSBarry Smith ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr); 15230b34957SBarry Smith for (k=0; k<c->ncolors; k++) { 15338baddfdSBarry Smith ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr); 15430b34957SBarry Smith for (l=0; l<c->nrows[k]; l++) { 15530b34957SBarry Smith col = c->columnsforrow[k][l]; 156*2205254eSKarl Rupp 15730b34957SBarry Smith c->vscaleforrow[k][l] = col; 15830b34957SBarry Smith } 15930b34957SBarry Smith } 160b9617806SBarry Smith ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 1613a40ed3dSBarry Smith PetscFunctionReturn(0); 16270c3da92SBarry Smith } 163