170c3da92SBarry Smith 270c3da92SBarry Smith #ifndef lint 3*43a90d84SBarry Smith static char vcid[] = "$Id: fdaij.c,v 1.3 1996/11/19 20:03:06 balay Exp bsmith $"; 470c3da92SBarry Smith #endif 570c3da92SBarry Smith 670c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 770c3da92SBarry Smith #include "src/vec/vecimpl.h" 870c3da92SBarry Smith #include "petsc.h" 9639f9d9dSBarry Smith 10*43a90d84SBarry Smith extern int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 11*43a90d84SBarry Smith extern int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 12*43a90d84SBarry Smith 13639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 14639f9d9dSBarry Smith { 15639f9d9dSBarry Smith int i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg; 16639f9d9dSBarry Smith int nis = iscoloring->n,*rowhit,*columnsforrow; 17639f9d9dSBarry Smith IS *isa = iscoloring->is; 18639f9d9dSBarry Smith PetscTruth done; 19639f9d9dSBarry Smith 20639f9d9dSBarry Smith c->ncolors = nis; 21639f9d9dSBarry Smith c->ncolumns = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->ncolumns); 22639f9d9dSBarry Smith c->columns = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns); 23639f9d9dSBarry Smith c->nrows = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->nrows); 24639f9d9dSBarry Smith c->rows = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows); 25639f9d9dSBarry Smith c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow); 26*43a90d84SBarry Smith 27*43a90d84SBarry Smith /* 28*43a90d84SBarry Smith Calls the _SeqAIJ() version of these routines to make sure it does not 29*43a90d84SBarry Smith get the reduced (by inodes) version of I and J 30*43a90d84SBarry Smith */ 31*43a90d84SBarry Smith ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 3270c3da92SBarry Smith 3370c3da92SBarry Smith /* 34639f9d9dSBarry Smith Temporary option to allow for debugging/testing 3570c3da92SBarry Smith */ 36639f9d9dSBarry Smith ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg); 3770c3da92SBarry Smith 38639f9d9dSBarry Smith rowhit = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit); 39639f9d9dSBarry Smith columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow); 4070c3da92SBarry Smith 41639f9d9dSBarry Smith for ( i=0; i<nis; i++ ) { 42639f9d9dSBarry Smith ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr); 43639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr); 44639f9d9dSBarry Smith c->ncolumns[i] = n; 45639f9d9dSBarry Smith if (n) { 46639f9d9dSBarry Smith c->columns[i] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]); 47639f9d9dSBarry Smith PetscMemcpy(c->columns[i],is,n*sizeof(int)); 4870c3da92SBarry Smith } else { 49639f9d9dSBarry Smith c->columns[i] = 0; 5070c3da92SBarry Smith } 5170c3da92SBarry Smith 52639f9d9dSBarry Smith if (flg) { /* ------------------------------------------------------------------------------*/ 53639f9d9dSBarry Smith /* crude version requires O(N*N) work */ 54639f9d9dSBarry Smith PetscMemzero(rowhit,N*sizeof(int)); 55639f9d9dSBarry Smith /* loop over columns*/ 56639f9d9dSBarry Smith for ( j=0; j<n; j++ ) { 57639f9d9dSBarry Smith col = is[j]; 58639f9d9dSBarry Smith rows = cj + ci[col]; 59639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 60639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 61639f9d9dSBarry Smith for ( k=0; k<m; k++ ) { 62639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 6370c3da92SBarry Smith } 6470c3da92SBarry Smith } 65639f9d9dSBarry Smith /* count the number of hits */ 66639f9d9dSBarry Smith nrows = 0; 6770c3da92SBarry Smith for ( j=0; j<N; j++ ) { 68639f9d9dSBarry Smith if (rowhit[j]) nrows++; 69639f9d9dSBarry Smith } 70639f9d9dSBarry Smith c->nrows[i] = nrows; 71639f9d9dSBarry Smith c->rows[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]); 72639f9d9dSBarry Smith c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]); 73639f9d9dSBarry Smith nrows = 0; 74639f9d9dSBarry Smith for ( j=0; j<N; j++ ) { 75639f9d9dSBarry Smith if (rowhit[j]) { 76639f9d9dSBarry Smith c->rows[i][nrows] = j; 77639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 78639f9d9dSBarry Smith nrows++; 7970c3da92SBarry Smith } 8070c3da92SBarry Smith } 81639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 82639f9d9dSBarry Smith /* efficient version, using rowhit as a linked list */ 83639f9d9dSBarry Smith int currentcol,fm,mfm; 84639f9d9dSBarry Smith rowhit[N] = N; 85639f9d9dSBarry Smith nrows = 0; 86639f9d9dSBarry Smith /* loop over columns */ 87639f9d9dSBarry Smith for ( j=0; j<n; j++ ) { 88639f9d9dSBarry Smith col = is[j]; 89639f9d9dSBarry Smith rows = cj + ci[col]; 90639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 91639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 92639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 93639f9d9dSBarry Smith for ( k=0; k<m; k++ ) { 94639f9d9dSBarry Smith currentcol = *rows++; 95639f9d9dSBarry Smith /* is it already in the list? */ 96639f9d9dSBarry Smith do { 97639f9d9dSBarry Smith mfm = fm; 98639f9d9dSBarry Smith fm = rowhit[fm]; 99639f9d9dSBarry Smith } while (fm < currentcol); 100639f9d9dSBarry Smith /* not in list so add it */ 101639f9d9dSBarry Smith if (fm != currentcol) { 102639f9d9dSBarry Smith nrows++; 103639f9d9dSBarry Smith columnsforrow[currentcol] = col; 104639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 105639f9d9dSBarry Smith rowhit[mfm] = currentcol; 106639f9d9dSBarry Smith rowhit[currentcol] = fm; 107639f9d9dSBarry Smith fm = currentcol; 108639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 10970c3da92SBarry Smith } else { 110639f9d9dSBarry Smith SETERRQ(1,"MatFDColoringCreate_SeqAIJ:Invalid coloring"); 11170c3da92SBarry Smith } 112639f9d9dSBarry Smith 113639f9d9dSBarry Smith } 114639f9d9dSBarry Smith } 115639f9d9dSBarry Smith c->nrows[i] = nrows; 116639f9d9dSBarry Smith c->rows[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]); 117639f9d9dSBarry Smith c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]); 118639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 119639f9d9dSBarry Smith nrows = 0; 120639f9d9dSBarry Smith fm = rowhit[N]; 121639f9d9dSBarry Smith do { 122639f9d9dSBarry Smith c->rows[i][nrows] = fm; 123639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 124639f9d9dSBarry Smith fm = rowhit[fm]; 125639f9d9dSBarry Smith } while (fm < N); 126639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 127639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr); 128639f9d9dSBarry Smith } 129*43a90d84SBarry Smith ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 130639f9d9dSBarry Smith 131639f9d9dSBarry Smith PetscFree(rowhit); 132639f9d9dSBarry Smith PetscFree(columnsforrow); 133639f9d9dSBarry Smith 134639f9d9dSBarry Smith c->scale = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale); 135639f9d9dSBarry Smith c->wscale = c->scale + N; 136639f9d9dSBarry Smith 13770c3da92SBarry Smith return 0; 13870c3da92SBarry Smith } 13970c3da92SBarry Smith 140639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 14170c3da92SBarry Smith { 142639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 143639f9d9dSBarry Smith int n = a->n,*sizes,i,**ii,ierr,tag; 144639f9d9dSBarry Smith IS *is; 14570c3da92SBarry Smith 146639f9d9dSBarry Smith /* construct the index sets from the coloring array */ 147639f9d9dSBarry Smith sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes); 148639f9d9dSBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 14970c3da92SBarry Smith for ( i=0; i<n; i++ ) { 150639f9d9dSBarry Smith sizes[coloring[i]-1]++; 15170c3da92SBarry Smith } 152639f9d9dSBarry Smith ii = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii); 153639f9d9dSBarry Smith ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]); 154639f9d9dSBarry Smith for ( i=1; i<ncolors; i++ ) { 155639f9d9dSBarry Smith ii[i] = ii[i-1] + sizes[i-1]; 156639f9d9dSBarry Smith } 157639f9d9dSBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 158639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 159639f9d9dSBarry Smith ii[coloring[i]-1][sizes[coloring[i]-1]++] = i; 160639f9d9dSBarry Smith } 161775f6a71SSatish Balay is = (IS *) PetscMalloc( ncolors*sizeof(IS) ); CHKPTRQ(is); 162639f9d9dSBarry Smith for ( i=0; i<ncolors; i++ ) { 163639f9d9dSBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr); 164639f9d9dSBarry Smith } 165639f9d9dSBarry Smith 166639f9d9dSBarry Smith *iscoloring = (ISColoring) PetscMalloc(sizeof(struct _ISColoring));CHKPTRQ(*iscoloring); 167639f9d9dSBarry Smith (*iscoloring)->n = ncolors; 168639f9d9dSBarry Smith (*iscoloring)->is = is; 169639f9d9dSBarry Smith PetscCommDup_Private(mat->comm,&(*iscoloring)->comm,&tag); 170639f9d9dSBarry Smith PetscFree(sizes); 171639f9d9dSBarry Smith PetscFree(ii[0]); 172639f9d9dSBarry Smith PetscFree(ii); 17370c3da92SBarry Smith return 0; 17470c3da92SBarry Smith } 17570c3da92SBarry Smith 176639f9d9dSBarry Smith /* 177639f9d9dSBarry Smith Makes a longer coloring[] array and calls the usual code with that 178639f9d9dSBarry Smith */ 179639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 18070c3da92SBarry Smith { 181639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 182639f9d9dSBarry Smith int n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row; 183639f9d9dSBarry Smith int *colorused,i,*newcolor; 18470c3da92SBarry Smith 185639f9d9dSBarry Smith newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor); 18670c3da92SBarry Smith 187639f9d9dSBarry Smith /* loop over inodes, marking a color for each column*/ 188639f9d9dSBarry Smith row = 0; 18970c3da92SBarry Smith for ( i=0; i<m; i++){ 190639f9d9dSBarry Smith for ( j=0; j<ns[i]; j++) { 191639f9d9dSBarry Smith newcolor[row++] = coloring[i] + j*ncolors; 19270c3da92SBarry Smith } 19370c3da92SBarry Smith } 19470c3da92SBarry Smith 195639f9d9dSBarry Smith /* eliminate unneeded colors */ 196639f9d9dSBarry Smith colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused); 197639f9d9dSBarry Smith PetscMemzero(colorused,5*ncolors*sizeof(int)); 198639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 199639f9d9dSBarry Smith colorused[newcolor[i]-1] = 1; 200639f9d9dSBarry Smith } 20170c3da92SBarry Smith 202639f9d9dSBarry Smith for ( i=1; i<5*ncolors; i++ ) { 203639f9d9dSBarry Smith colorused[i] += colorused[i-1]; 20470c3da92SBarry Smith } 205639f9d9dSBarry Smith ncolors = colorused[5*ncolors-1]; 206639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 207639f9d9dSBarry Smith newcolor[i] = colorused[newcolor[i]-1]; 20870c3da92SBarry Smith } 209639f9d9dSBarry Smith PetscFree(colorused); 21070c3da92SBarry Smith 211639f9d9dSBarry Smith ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr); 212639f9d9dSBarry Smith PetscFree(newcolor); 213639f9d9dSBarry Smith 21470c3da92SBarry Smith return 0; 21570c3da92SBarry Smith } 21670c3da92SBarry Smith 217