1*a64fbb32SBarry Smith 2*a64fbb32SBarry Smith 3*a64fbb32SBarry Smith #ifndef lint 4*a64fbb32SBarry Smith static char vcid[] = "$Id: fdaij.c,v 1.1 1996/10/09 18:09:59 bsmith Exp bsmith $"; 5*a64fbb32SBarry Smith #endif 6*a64fbb32SBarry Smith 7*a64fbb32SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 8*a64fbb32SBarry Smith #include "src/vec/vecimpl.h" 9*a64fbb32SBarry Smith #include "petsc.h" 10*a64fbb32SBarry Smith 11*a64fbb32SBarry Smith 12*a64fbb32SBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 13*a64fbb32SBarry Smith { 14*a64fbb32SBarry Smith int i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg; 15*a64fbb32SBarry Smith int nis = iscoloring->n; 16*a64fbb32SBarry Smith IS *isa = iscoloring->is; 17*a64fbb32SBarry Smith PetscTruth done; 18*a64fbb32SBarry Smith 19*a64fbb32SBarry Smith c->ncolors = nis; 20*a64fbb32SBarry Smith c->ncolumns = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->ncolumns); 21*a64fbb32SBarry Smith c->columns = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns); 22*a64fbb32SBarry Smith c->nrows = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->nrows); 23*a64fbb32SBarry Smith c->rows = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows); 24*a64fbb32SBarry Smith c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow); 25*a64fbb32SBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 26*a64fbb32SBarry Smith /* 27*a64fbb32SBarry Smith Temporary option to allow for debugging/testing 28*a64fbb32SBarry Smith */ 29*a64fbb32SBarry Smith ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg); 30*a64fbb32SBarry Smith for ( i=0; i<nis; i++ ) { 31*a64fbb32SBarry Smith ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr); 32*a64fbb32SBarry Smith ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr); 33*a64fbb32SBarry Smith c->ncolumns[i] = n; 34*a64fbb32SBarry Smith if (n) { 35*a64fbb32SBarry Smith c->columns[i] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]); 36*a64fbb32SBarry Smith PetscMemcpy(c->columns[i],is,n*sizeof(int)); 37*a64fbb32SBarry Smith } else { 38*a64fbb32SBarry Smith c->columns[i] = 0; 39*a64fbb32SBarry Smith } 40*a64fbb32SBarry Smith 41*a64fbb32SBarry Smith if (flg) { /* --------------------------------------------------------------------------------*/ 42*a64fbb32SBarry Smith /* crude version requires O(N*N) work */ 43*a64fbb32SBarry Smith int *rowhit = (int *) PetscMalloc( N*sizeof(int) ); CHKPTRQ(rowhit); 44*a64fbb32SBarry Smith PetscMemzero(rowhit,N*sizeof(int)); 45*a64fbb32SBarry Smith /* loop over columns*/ 46*a64fbb32SBarry Smith for ( j=0; j<n; j++ ) { 47*a64fbb32SBarry Smith col = is[j]; 48*a64fbb32SBarry Smith rows = cj + ci[col]; 49*a64fbb32SBarry Smith m = ci[col+1] - ci[col]; 50*a64fbb32SBarry Smith /* loop over columns marking them in rowhit */ 51*a64fbb32SBarry Smith for ( k=0; k<m; k++ ) { 52*a64fbb32SBarry Smith rowhit[*rows++] = col + 1; 53*a64fbb32SBarry Smith } 54*a64fbb32SBarry Smith } 55*a64fbb32SBarry Smith /* count the number of hits */ 56*a64fbb32SBarry Smith nrows = 0; 57*a64fbb32SBarry Smith for ( j=0; j<N; j++ ) { 58*a64fbb32SBarry Smith if (rowhit[j]) nrows++; 59*a64fbb32SBarry Smith } 60*a64fbb32SBarry Smith c->nrows[i] = nrows; 61*a64fbb32SBarry Smith c->rows[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]); 62*a64fbb32SBarry Smith c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]); 63*a64fbb32SBarry Smith nrows = 0; 64*a64fbb32SBarry Smith for ( j=0; j<N; j++ ) { 65*a64fbb32SBarry Smith if (rowhit[j]) { 66*a64fbb32SBarry Smith c->rows[i][nrows] = j; 67*a64fbb32SBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 68*a64fbb32SBarry Smith nrows++; 69*a64fbb32SBarry Smith } 70*a64fbb32SBarry Smith } 71*a64fbb32SBarry Smith PetscFree(rowhit); 72*a64fbb32SBarry Smith } else { /*-------------------------------------------------------------------------------*/ 73*a64fbb32SBarry Smith /* efficient version, using rowhit as a linked list */ 74*a64fbb32SBarry Smith int currentcol,fm,mfm,*rowhit,*columnsforrow; 75*a64fbb32SBarry Smith rowhit = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit); 76*a64fbb32SBarry Smith columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow); 77*a64fbb32SBarry Smith rowhit[N] = N; 78*a64fbb32SBarry Smith nrows = 0; 79*a64fbb32SBarry Smith /* loop over columns */ 80*a64fbb32SBarry Smith for ( j=0; j<n; j++ ) { 81*a64fbb32SBarry Smith col = is[j]; 82*a64fbb32SBarry Smith rows = cj + ci[col]; 83*a64fbb32SBarry Smith m = ci[col+1] - ci[col]; 84*a64fbb32SBarry Smith /* loop over columns marking them in rowhit */ 85*a64fbb32SBarry Smith fm = N; /* fm points to first entry in linked list */ 86*a64fbb32SBarry Smith for ( k=0; k<m; k++ ) { 87*a64fbb32SBarry Smith currentcol = *rows++; 88*a64fbb32SBarry Smith /* is it already in the list? */ 89*a64fbb32SBarry Smith do { 90*a64fbb32SBarry Smith mfm = fm; 91*a64fbb32SBarry Smith fm = rowhit[fm]; 92*a64fbb32SBarry Smith } while (fm < currentcol); 93*a64fbb32SBarry Smith /* not in list so add it */ 94*a64fbb32SBarry Smith if (fm != currentcol) { 95*a64fbb32SBarry Smith nrows++; 96*a64fbb32SBarry Smith columnsforrow[currentcol] = col; 97*a64fbb32SBarry Smith /* next three lines insert new entry into linked list */ 98*a64fbb32SBarry Smith rowhit[mfm] = currentcol; 99*a64fbb32SBarry Smith rowhit[currentcol] = fm; 100*a64fbb32SBarry Smith fm = currentcol; 101*a64fbb32SBarry Smith /* fm points to present position in list since we know the columns are sorted */ 102*a64fbb32SBarry Smith } else { 103*a64fbb32SBarry Smith SETERRQ(1,"MatFDColoringCreate_SeqAIJ:Invalid coloring"); 104*a64fbb32SBarry Smith } 105*a64fbb32SBarry Smith 106*a64fbb32SBarry Smith } 107*a64fbb32SBarry Smith } 108*a64fbb32SBarry Smith c->nrows[i] = nrows; 109*a64fbb32SBarry Smith c->rows[i] = (int *) PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->rows[i]); 110*a64fbb32SBarry Smith c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int));CHKPTRQ(c->columnsforrow[i]); 111*a64fbb32SBarry Smith /* now store the linked list of rows into c->rows[i] */ 112*a64fbb32SBarry Smith nrows = 0; 113*a64fbb32SBarry Smith fm = rowhit[N]; 114*a64fbb32SBarry Smith do { 115*a64fbb32SBarry Smith c->rows[i][nrows] = fm; 116*a64fbb32SBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 117*a64fbb32SBarry Smith fm = rowhit[fm]; 118*a64fbb32SBarry Smith } while (fm < N); 119*a64fbb32SBarry Smith PetscFree(rowhit); 120*a64fbb32SBarry Smith PetscFree(columnsforrow); 121*a64fbb32SBarry Smith } /* ---------------------------------------------------------------------------------------*/ 122*a64fbb32SBarry Smith ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr); 123*a64fbb32SBarry Smith } 124*a64fbb32SBarry Smith ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 125*a64fbb32SBarry Smith 126*a64fbb32SBarry Smith c->scale = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale); 127*a64fbb32SBarry Smith c->wscale = c->scale + N; 128*a64fbb32SBarry Smith 129*a64fbb32SBarry Smith return 0; 130*a64fbb32SBarry Smith } 131*a64fbb32SBarry Smith 132*a64fbb32SBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 133*a64fbb32SBarry Smith { 134*a64fbb32SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 135*a64fbb32SBarry Smith int n = a->n,*sizes,i,**ii,ierr; 136*a64fbb32SBarry Smith IS *is; 137*a64fbb32SBarry Smith 138*a64fbb32SBarry Smith /* construct the index sets from the coloring array */ 139*a64fbb32SBarry Smith sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes); 140*a64fbb32SBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 141*a64fbb32SBarry Smith for ( i=0; i<n; i++ ) { 142*a64fbb32SBarry Smith sizes[coloring[i]-1]++; 143*a64fbb32SBarry Smith } 144*a64fbb32SBarry Smith ii = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii); 145*a64fbb32SBarry Smith ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]); 146*a64fbb32SBarry Smith for ( i=1; i<ncolors; i++ ) { 147*a64fbb32SBarry Smith ii[i] = ii[i-1] + sizes[i-1]; 148*a64fbb32SBarry Smith } 149*a64fbb32SBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 150*a64fbb32SBarry Smith for ( i=0; i<n; i++ ) { 151*a64fbb32SBarry Smith ii[coloring[i]-1][sizes[coloring[i]-1]++] = i; 152*a64fbb32SBarry Smith } 153*a64fbb32SBarry Smith is = (IS *) PetscMalloc( ncolors*sizeof(is) ); CHKPTRQ(is); 154*a64fbb32SBarry Smith for ( i=0; i<ncolors; i++ ) { 155*a64fbb32SBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr); 156*a64fbb32SBarry Smith } 157*a64fbb32SBarry Smith 158*a64fbb32SBarry Smith *iscoloring = (ISColoring) PetscMalloc(sizeof(struct _ISColoring));CHKPTRQ(*iscoloring); 159*a64fbb32SBarry Smith (*iscoloring)->n = ncolors; 160*a64fbb32SBarry Smith (*iscoloring)->is = is; 161*a64fbb32SBarry Smith (*iscoloring)->comm = MPI_COMM_SELF; 162*a64fbb32SBarry Smith PetscFree(sizes); 163*a64fbb32SBarry Smith PetscFree(ii[0]); 164*a64fbb32SBarry Smith PetscFree(ii); 165*a64fbb32SBarry Smith return 0; 166*a64fbb32SBarry Smith } 167*a64fbb32SBarry Smith 168*a64fbb32SBarry Smith /* 169*a64fbb32SBarry Smith Makes a longer coloring[] array and calls the usual code with that 170*a64fbb32SBarry Smith */ 171*a64fbb32SBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 172*a64fbb32SBarry Smith { 173*a64fbb32SBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 174*a64fbb32SBarry Smith int n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row; 175*a64fbb32SBarry Smith int *colorused,i,*newcolor; 176*a64fbb32SBarry Smith 177*a64fbb32SBarry Smith newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor); 178*a64fbb32SBarry Smith 179*a64fbb32SBarry Smith /* loop over inodes, marking a color for each column*/ 180*a64fbb32SBarry Smith row = 0; 181*a64fbb32SBarry Smith for ( i=0; i<m; i++){ 182*a64fbb32SBarry Smith for ( j=0; j<ns[i]; j++) { 183*a64fbb32SBarry Smith newcolor[row++] = coloring[i] + j*ncolors; 184*a64fbb32SBarry Smith } 185*a64fbb32SBarry Smith } 186*a64fbb32SBarry Smith 187*a64fbb32SBarry Smith /* eliminate unneeded colors */ 188*a64fbb32SBarry Smith colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused); 189*a64fbb32SBarry Smith PetscMemzero(colorused,5*ncolors*sizeof(int)); 190*a64fbb32SBarry Smith for ( i=0; i<n; i++ ) { 191*a64fbb32SBarry Smith colorused[newcolor[i]-1] = 1; 192*a64fbb32SBarry Smith } 193*a64fbb32SBarry Smith 194*a64fbb32SBarry Smith for ( i=1; i<5*ncolors; i++ ) { 195*a64fbb32SBarry Smith colorused[i] += colorused[i-1]; 196*a64fbb32SBarry Smith } 197*a64fbb32SBarry Smith ncolors = colorused[5*ncolors-1]; 198*a64fbb32SBarry Smith for ( i=0; i<n; i++ ) { 199*a64fbb32SBarry Smith newcolor[i] = colorused[newcolor[i]-1]; 200*a64fbb32SBarry Smith } 201*a64fbb32SBarry Smith PetscFree(colorused); 202*a64fbb32SBarry Smith 203*a64fbb32SBarry Smith ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr); 204*a64fbb32SBarry Smith PetscFree(newcolor); 205*a64fbb32SBarry Smith 206*a64fbb32SBarry Smith return 0; 207*a64fbb32SBarry Smith } 208*a64fbb32SBarry Smith 209