1*ca44d042SBarry Smith /*$Id: fdaij.c,v 1.29 2000/05/04 16:25:26 bsmith Exp bsmith $*/ 270c3da92SBarry Smith 370c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 470c3da92SBarry Smith #include "src/vec/vecimpl.h" 5639f9d9dSBarry Smith 6*ca44d042SBarry Smith EXTERN int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 7*ca44d042SBarry Smith EXTERN int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 843a90d84SBarry Smith 95615d1e5SSatish Balay #undef __FUNC__ 10b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatFDColoringCreate_SeqAIJ" 11639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 12639f9d9dSBarry Smith { 13f1af5d2fSBarry Smith int i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col; 14639f9d9dSBarry Smith int nis = iscoloring->n,*rowhit,*columnsforrow; 15639f9d9dSBarry Smith IS *isa = iscoloring->is; 16f1af5d2fSBarry Smith PetscTruth done,flg; 17639f9d9dSBarry Smith 183a40ed3dSBarry Smith PetscFunctionBegin; 19522c5e43SBarry Smith if (!mat->assembled) { 20a8c6a408SBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,1,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 21522c5e43SBarry Smith } 22522c5e43SBarry Smith 23005c665bSBarry Smith c->M = mat->M; /* set total rows, columns and local rows */ 24005c665bSBarry Smith c->N = mat->N; 25005c665bSBarry Smith c->m = mat->M; 26005c665bSBarry Smith c->rstart = 0; 27005c665bSBarry Smith 28639f9d9dSBarry Smith c->ncolors = nis; 29639f9d9dSBarry Smith c->ncolumns = (int*)PetscMalloc(nis*sizeof(int));CHKPTRQ(c->ncolumns); 30639f9d9dSBarry Smith c->columns = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->columns); 31639f9d9dSBarry Smith c->nrows = (int*)PetscMalloc(nis*sizeof(int));CHKPTRQ(c->nrows); 32639f9d9dSBarry Smith c->rows = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->rows); 33639f9d9dSBarry Smith c->columnsforrow = (int**)PetscMalloc(nis*sizeof(int *));CHKPTRQ(c->columnsforrow); 3443a90d84SBarry Smith 3543a90d84SBarry Smith /* 3643a90d84SBarry Smith Calls the _SeqAIJ() version of these routines to make sure it does not 3743a90d84SBarry Smith get the reduced (by inodes) version of I and J 3843a90d84SBarry Smith */ 3943a90d84SBarry Smith ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 4070c3da92SBarry Smith 4170c3da92SBarry Smith /* 42639f9d9dSBarry Smith Temporary option to allow for debugging/testing 4370c3da92SBarry Smith */ 44454a90a3SBarry Smith ierr = OptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr); 4570c3da92SBarry Smith 46639f9d9dSBarry Smith rowhit = (int*)PetscMalloc((N+1)*sizeof(int));CHKPTRQ(rowhit); 47639f9d9dSBarry Smith columnsforrow = (int*)PetscMalloc((N+1)*sizeof(int));CHKPTRQ(columnsforrow); 4870c3da92SBarry Smith 49639f9d9dSBarry Smith for (i=0; i<nis; i++) { 50639f9d9dSBarry Smith ierr = ISGetSize(isa[i],&n);CHKERRQ(ierr); 51639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 52639f9d9dSBarry Smith c->ncolumns[i] = n; 53639f9d9dSBarry Smith if (n) { 54639f9d9dSBarry Smith c->columns[i] = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(c->columns[i]); 55549d3d68SSatish Balay ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr); 5670c3da92SBarry Smith } else { 57639f9d9dSBarry Smith c->columns[i] = 0; 5870c3da92SBarry Smith } 5970c3da92SBarry Smith 60639f9d9dSBarry Smith if (flg) { /* ------------------------------------------------------------------------------*/ 61639f9d9dSBarry Smith /* crude version requires O(N*N) work */ 62549d3d68SSatish Balay ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr); 63639f9d9dSBarry Smith /* loop over columns*/ 64639f9d9dSBarry Smith for (j=0; j<n; j++) { 65639f9d9dSBarry Smith col = is[j]; 66639f9d9dSBarry Smith rows = cj + ci[col]; 67639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 68639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 69639f9d9dSBarry Smith for (k=0; k<m; k++) { 70639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 7170c3da92SBarry Smith } 7270c3da92SBarry Smith } 73639f9d9dSBarry Smith /* count the number of hits */ 74639f9d9dSBarry Smith nrows = 0; 7570c3da92SBarry Smith for (j=0; j<N; j++) { 76639f9d9dSBarry Smith if (rowhit[j]) nrows++; 77639f9d9dSBarry Smith } 78639f9d9dSBarry Smith c->nrows[i] = nrows; 79639f9d9dSBarry Smith c->rows[i] = (int*)PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->rows[i]); 80639f9d9dSBarry Smith c->columnsforrow[i] = (int*)PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->columnsforrow[i]); 81639f9d9dSBarry Smith nrows = 0; 82639f9d9dSBarry Smith for (j=0; j<N; j++) { 83639f9d9dSBarry Smith if (rowhit[j]) { 84639f9d9dSBarry Smith c->rows[i][nrows] = j; 85639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 86639f9d9dSBarry Smith nrows++; 8770c3da92SBarry Smith } 8870c3da92SBarry Smith } 89639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 90639f9d9dSBarry Smith /* efficient version, using rowhit as a linked list */ 91639f9d9dSBarry Smith int currentcol,fm,mfm; 92639f9d9dSBarry Smith rowhit[N] = N; 93639f9d9dSBarry Smith nrows = 0; 94639f9d9dSBarry Smith /* loop over columns */ 95639f9d9dSBarry Smith for (j=0; j<n; j++) { 96639f9d9dSBarry Smith col = is[j]; 97639f9d9dSBarry Smith rows = cj + ci[col]; 98639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 99639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 100639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 101639f9d9dSBarry Smith for (k=0; k<m; k++) { 102639f9d9dSBarry Smith currentcol = *rows++; 103639f9d9dSBarry Smith /* is it already in the list? */ 104639f9d9dSBarry Smith do { 105639f9d9dSBarry Smith mfm = fm; 106639f9d9dSBarry Smith fm = rowhit[fm]; 107639f9d9dSBarry Smith } while (fm < currentcol); 108639f9d9dSBarry Smith /* not in list so add it */ 109639f9d9dSBarry Smith if (fm != currentcol) { 110639f9d9dSBarry Smith nrows++; 111639f9d9dSBarry Smith columnsforrow[currentcol] = col; 112639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 113639f9d9dSBarry Smith rowhit[mfm] = currentcol; 114639f9d9dSBarry Smith rowhit[currentcol] = fm; 115639f9d9dSBarry Smith fm = currentcol; 116639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 11770c3da92SBarry Smith } else { 118a8c6a408SBarry Smith SETERRQ(PETSC_ERR_PLIB,0,"Detected invalid coloring"); 11970c3da92SBarry Smith } 120639f9d9dSBarry Smith 121639f9d9dSBarry Smith } 122639f9d9dSBarry Smith } 123639f9d9dSBarry Smith c->nrows[i] = nrows; 124639f9d9dSBarry Smith c->rows[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]); 125639f9d9dSBarry Smith c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]); 126639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 127639f9d9dSBarry Smith nrows = 0; 128639f9d9dSBarry Smith fm = rowhit[N]; 129639f9d9dSBarry Smith do { 130639f9d9dSBarry Smith c->rows[i][nrows] = fm; 131639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 132639f9d9dSBarry Smith fm = rowhit[fm]; 133639f9d9dSBarry Smith } while (fm < N); 134639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 135639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 136639f9d9dSBarry Smith } 13743a90d84SBarry Smith ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 138639f9d9dSBarry Smith 139606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 140606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 141639f9d9dSBarry Smith 142639f9d9dSBarry Smith c->scale = (Scalar*)PetscMalloc(2*N*sizeof(Scalar));CHKPTRQ(c->scale); 143639f9d9dSBarry Smith c->wscale = c->scale + N; 144639f9d9dSBarry Smith 1453a40ed3dSBarry Smith PetscFunctionReturn(0); 14670c3da92SBarry Smith } 14770c3da92SBarry Smith 1485615d1e5SSatish Balay #undef __FUNC__ 149b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatColoringPatch_SeqAIJ" 150639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 15170c3da92SBarry Smith { 152639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 153639f9d9dSBarry Smith int n = a->n,*sizes,i,**ii,ierr,tag; 154639f9d9dSBarry Smith IS *is; 15570c3da92SBarry Smith 1563a40ed3dSBarry Smith PetscFunctionBegin; 157639f9d9dSBarry Smith /* construct the index sets from the coloring array */ 158639f9d9dSBarry Smith sizes = (int*)PetscMalloc(ncolors*sizeof(int));CHKPTRQ(sizes); 159549d3d68SSatish Balay ierr = PetscMemzero(sizes,ncolors*sizeof(int));CHKERRQ(ierr); 16070c3da92SBarry Smith for (i=0; i<n; i++) { 161639f9d9dSBarry Smith sizes[coloring[i]-1]++; 16270c3da92SBarry Smith } 163639f9d9dSBarry Smith ii = (int**)PetscMalloc(ncolors*sizeof(int*));CHKPTRQ(ii); 164639f9d9dSBarry Smith ii[0] = (int*)PetscMalloc(n*sizeof(int));CHKPTRQ(ii[0]); 165639f9d9dSBarry Smith for (i=1; i<ncolors; i++) { 166639f9d9dSBarry Smith ii[i] = ii[i-1] + sizes[i-1]; 167639f9d9dSBarry Smith } 168549d3d68SSatish Balay ierr = PetscMemzero(sizes,ncolors*sizeof(int));CHKERRQ(ierr); 169639f9d9dSBarry Smith for (i=0; i<n; i++) { 170639f9d9dSBarry Smith ii[coloring[i]-1][sizes[coloring[i]-1]++] = i; 171639f9d9dSBarry Smith } 172775f6a71SSatish Balay is = (IS*)PetscMalloc(ncolors*sizeof(IS));CHKPTRQ(is); 173639f9d9dSBarry Smith for (i=0; i<ncolors; i++) { 174029af93fSBarry Smith ierr = ISCreateGeneral(PETSC_COMM_SELF,sizes[i],ii[i],is+i);CHKERRQ(ierr); 175639f9d9dSBarry Smith } 176639f9d9dSBarry Smith 177f09e8eb9SSatish Balay *iscoloring = (ISColoring)PetscMalloc(sizeof(struct _p_ISColoring));CHKPTRQ(*iscoloring); 178639f9d9dSBarry Smith (*iscoloring)->n = ncolors; 179639f9d9dSBarry Smith (*iscoloring)->is = is; 1804be1940cSBarry Smith ierr = PetscCommDuplicate_Private(mat->comm,&(*iscoloring)->comm,&tag);CHKERRQ(ierr); 181606d414cSSatish Balay ierr = PetscFree(sizes);CHKERRQ(ierr); 182606d414cSSatish Balay ierr = PetscFree(ii[0]);CHKERRQ(ierr); 183606d414cSSatish Balay ierr = PetscFree(ii);CHKERRQ(ierr); 1843a40ed3dSBarry Smith PetscFunctionReturn(0); 18570c3da92SBarry Smith } 18670c3da92SBarry Smith 187639f9d9dSBarry Smith /* 188639f9d9dSBarry Smith Makes a longer coloring[] array and calls the usual code with that 189639f9d9dSBarry Smith */ 1905615d1e5SSatish Balay #undef __FUNC__ 191b2863d3aSBarry Smith #define __FUNC__ /*<a name=""></a>*/"MatColoringPatch_SeqAIJ_Inode" 192639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 19370c3da92SBarry Smith { 194639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 195639f9d9dSBarry Smith int n = a->n,ierr,m = a->inode.node_count,j,*ns = a->inode.size,row; 196639f9d9dSBarry Smith int *colorused,i,*newcolor; 19770c3da92SBarry Smith 1983a40ed3dSBarry Smith PetscFunctionBegin; 199639f9d9dSBarry Smith newcolor = (int*)PetscMalloc((n+1)*sizeof(int));CHKPTRQ(newcolor); 20070c3da92SBarry Smith 201639f9d9dSBarry Smith /* loop over inodes, marking a color for each column*/ 202639f9d9dSBarry Smith row = 0; 20370c3da92SBarry Smith for (i=0; i<m; i++){ 204639f9d9dSBarry Smith for (j=0; j<ns[i]; j++) { 205639f9d9dSBarry Smith newcolor[row++] = coloring[i] + j*ncolors; 20670c3da92SBarry Smith } 20770c3da92SBarry Smith } 20870c3da92SBarry Smith 209639f9d9dSBarry Smith /* eliminate unneeded colors */ 210639f9d9dSBarry Smith colorused = (int*)PetscMalloc(5*ncolors*sizeof(int));CHKPTRQ(colorused); 211549d3d68SSatish Balay ierr = PetscMemzero(colorused,5*ncolors*sizeof(int));CHKERRQ(ierr); 212639f9d9dSBarry Smith for (i=0; i<n; i++) { 213639f9d9dSBarry Smith colorused[newcolor[i]-1] = 1; 214639f9d9dSBarry Smith } 21570c3da92SBarry Smith 216639f9d9dSBarry Smith for (i=1; i<5*ncolors; i++) { 217639f9d9dSBarry Smith colorused[i] += colorused[i-1]; 21870c3da92SBarry Smith } 219639f9d9dSBarry Smith ncolors = colorused[5*ncolors-1]; 220639f9d9dSBarry Smith for (i=0; i<n; i++) { 221639f9d9dSBarry Smith newcolor[i] = colorused[newcolor[i]-1]; 22270c3da92SBarry Smith } 223606d414cSSatish Balay ierr = PetscFree(colorused);CHKERRQ(ierr); 22470c3da92SBarry Smith 225639f9d9dSBarry Smith ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring);CHKERRQ(ierr); 226606d414cSSatish Balay ierr = PetscFree(newcolor);CHKERRQ(ierr); 227639f9d9dSBarry Smith 2283a40ed3dSBarry Smith PetscFunctionReturn(0); 22970c3da92SBarry Smith } 23070c3da92SBarry Smith 2313a40ed3dSBarry Smith 2323a40ed3dSBarry Smith 2333a40ed3dSBarry Smith 2343a40ed3dSBarry Smith 2353a40ed3dSBarry Smith 236