170c3da92SBarry Smith 270c3da92SBarry Smith #ifndef lint 3*639f9d9dSBarry Smith static char vcid[] = "$Id: fdaij.c,v 1.1 1996/10/09 18:09:59 bsmith 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" 9*639f9d9dSBarry Smith 10*639f9d9dSBarry Smith int MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 11*639f9d9dSBarry Smith { 12*639f9d9dSBarry Smith int i,*is,n,nrows,N = mat->N,j,k,m,*rows,ierr,*ci,*cj,ncols,col,flg; 13*639f9d9dSBarry Smith int nis = iscoloring->n,*rowhit,*columnsforrow; 14*639f9d9dSBarry Smith IS *isa = iscoloring->is; 15*639f9d9dSBarry Smith PetscTruth done; 16*639f9d9dSBarry Smith 17*639f9d9dSBarry Smith c->ncolors = nis; 18*639f9d9dSBarry Smith c->ncolumns = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->ncolumns); 19*639f9d9dSBarry Smith c->columns = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columns); 20*639f9d9dSBarry Smith c->nrows = (int *) PetscMalloc( nis*sizeof(int) ); CHKPTRQ(c->nrows); 21*639f9d9dSBarry Smith c->rows = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->rows); 22*639f9d9dSBarry Smith c->columnsforrow = (int **) PetscMalloc( nis*sizeof(int *)); CHKPTRQ(c->columnsforrow); 23*639f9d9dSBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 2470c3da92SBarry Smith 2570c3da92SBarry Smith /* 26*639f9d9dSBarry Smith Temporary option to allow for debugging/testing 2770c3da92SBarry Smith */ 28*639f9d9dSBarry Smith ierr = OptionsHasName(0,"-matfdcoloring_slow",&flg); 2970c3da92SBarry Smith 30*639f9d9dSBarry Smith rowhit = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(rowhit); 31*639f9d9dSBarry Smith columnsforrow = (int *) PetscMalloc( (N+1)*sizeof(int) ); CHKPTRQ(columnsforrow); 3270c3da92SBarry Smith 33*639f9d9dSBarry Smith for ( i=0; i<nis; i++ ) { 34*639f9d9dSBarry Smith ierr = ISGetSize(isa[i],&n); CHKERRQ(ierr); 35*639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is); CHKERRQ(ierr); 36*639f9d9dSBarry Smith c->ncolumns[i] = n; 37*639f9d9dSBarry Smith if (n) { 38*639f9d9dSBarry Smith c->columns[i] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(c->columns[i]); 39*639f9d9dSBarry Smith PetscMemcpy(c->columns[i],is,n*sizeof(int)); 4070c3da92SBarry Smith } else { 41*639f9d9dSBarry Smith c->columns[i] = 0; 4270c3da92SBarry Smith } 4370c3da92SBarry Smith 44*639f9d9dSBarry Smith if (flg) { /* ------------------------------------------------------------------------------*/ 45*639f9d9dSBarry Smith /* crude version requires O(N*N) work */ 46*639f9d9dSBarry Smith PetscMemzero(rowhit,N*sizeof(int)); 47*639f9d9dSBarry Smith /* loop over columns*/ 48*639f9d9dSBarry Smith for ( j=0; j<n; j++ ) { 49*639f9d9dSBarry Smith col = is[j]; 50*639f9d9dSBarry Smith rows = cj + ci[col]; 51*639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 52*639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 53*639f9d9dSBarry Smith for ( k=0; k<m; k++ ) { 54*639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 5570c3da92SBarry Smith } 5670c3da92SBarry Smith } 57*639f9d9dSBarry Smith /* count the number of hits */ 58*639f9d9dSBarry Smith nrows = 0; 5970c3da92SBarry Smith for ( j=0; j<N; j++ ) { 60*639f9d9dSBarry Smith if (rowhit[j]) nrows++; 61*639f9d9dSBarry Smith } 62*639f9d9dSBarry Smith c->nrows[i] = nrows; 63*639f9d9dSBarry Smith c->rows[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->rows[i]); 64*639f9d9dSBarry Smith c->columnsforrow[i] = (int *) PetscMalloc(nrows*sizeof(int)); CHKPTRQ(c->columnsforrow[i]); 65*639f9d9dSBarry Smith nrows = 0; 66*639f9d9dSBarry Smith for ( j=0; j<N; j++ ) { 67*639f9d9dSBarry Smith if (rowhit[j]) { 68*639f9d9dSBarry Smith c->rows[i][nrows] = j; 69*639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 70*639f9d9dSBarry Smith nrows++; 7170c3da92SBarry Smith } 7270c3da92SBarry Smith } 73*639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 74*639f9d9dSBarry Smith /* efficient version, using rowhit as a linked list */ 75*639f9d9dSBarry Smith int currentcol,fm,mfm; 76*639f9d9dSBarry Smith rowhit[N] = N; 77*639f9d9dSBarry Smith nrows = 0; 78*639f9d9dSBarry Smith /* loop over columns */ 79*639f9d9dSBarry Smith for ( j=0; j<n; j++ ) { 80*639f9d9dSBarry Smith col = is[j]; 81*639f9d9dSBarry Smith rows = cj + ci[col]; 82*639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 83*639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 84*639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 85*639f9d9dSBarry Smith for ( k=0; k<m; k++ ) { 86*639f9d9dSBarry Smith currentcol = *rows++; 87*639f9d9dSBarry Smith /* is it already in the list? */ 88*639f9d9dSBarry Smith do { 89*639f9d9dSBarry Smith mfm = fm; 90*639f9d9dSBarry Smith fm = rowhit[fm]; 91*639f9d9dSBarry Smith } while (fm < currentcol); 92*639f9d9dSBarry Smith /* not in list so add it */ 93*639f9d9dSBarry Smith if (fm != currentcol) { 94*639f9d9dSBarry Smith nrows++; 95*639f9d9dSBarry Smith columnsforrow[currentcol] = col; 96*639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 97*639f9d9dSBarry Smith rowhit[mfm] = currentcol; 98*639f9d9dSBarry Smith rowhit[currentcol] = fm; 99*639f9d9dSBarry Smith fm = currentcol; 100*639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 10170c3da92SBarry Smith } else { 102*639f9d9dSBarry Smith SETERRQ(1,"MatFDColoringCreate_SeqAIJ:Invalid coloring"); 10370c3da92SBarry Smith } 104*639f9d9dSBarry Smith 105*639f9d9dSBarry Smith } 106*639f9d9dSBarry Smith } 107*639f9d9dSBarry Smith c->nrows[i] = nrows; 108*639f9d9dSBarry Smith c->rows[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->rows[i]); 109*639f9d9dSBarry Smith c->columnsforrow[i] = (int *)PetscMalloc((nrows+1)*sizeof(int));CHKPTRQ(c->columnsforrow[i]); 110*639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 111*639f9d9dSBarry Smith nrows = 0; 112*639f9d9dSBarry Smith fm = rowhit[N]; 113*639f9d9dSBarry Smith do { 114*639f9d9dSBarry Smith c->rows[i][nrows] = fm; 115*639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 116*639f9d9dSBarry Smith fm = rowhit[fm]; 117*639f9d9dSBarry Smith } while (fm < N); 118*639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 119*639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is); CHKERRQ(ierr); 120*639f9d9dSBarry Smith } 121*639f9d9dSBarry Smith ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done); CHKERRQ(ierr); 122*639f9d9dSBarry Smith 123*639f9d9dSBarry Smith PetscFree(rowhit); 124*639f9d9dSBarry Smith PetscFree(columnsforrow); 125*639f9d9dSBarry Smith 126*639f9d9dSBarry Smith c->scale = (Scalar *) PetscMalloc( 2*N*sizeof(Scalar) ); CHKPTRQ(c->scale); 127*639f9d9dSBarry Smith c->wscale = c->scale + N; 128*639f9d9dSBarry Smith 12970c3da92SBarry Smith return 0; 13070c3da92SBarry Smith } 13170c3da92SBarry Smith 132*639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 13370c3da92SBarry Smith { 134*639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 135*639f9d9dSBarry Smith int n = a->n,*sizes,i,**ii,ierr,tag; 136*639f9d9dSBarry Smith IS *is; 13770c3da92SBarry Smith 138*639f9d9dSBarry Smith /* construct the index sets from the coloring array */ 139*639f9d9dSBarry Smith sizes = (int *) PetscMalloc( ncolors*sizeof(int) ); CHKPTRQ(sizes); 140*639f9d9dSBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 14170c3da92SBarry Smith for ( i=0; i<n; i++ ) { 142*639f9d9dSBarry Smith sizes[coloring[i]-1]++; 14370c3da92SBarry Smith } 144*639f9d9dSBarry Smith ii = (int **) PetscMalloc( ncolors*sizeof(int*) ); CHKPTRQ(ii); 145*639f9d9dSBarry Smith ii[0] = (int *) PetscMalloc( n*sizeof(int) ); CHKPTRQ(ii[0]); 146*639f9d9dSBarry Smith for ( i=1; i<ncolors; i++ ) { 147*639f9d9dSBarry Smith ii[i] = ii[i-1] + sizes[i-1]; 148*639f9d9dSBarry Smith } 149*639f9d9dSBarry Smith PetscMemzero(sizes,ncolors*sizeof(int)); 150*639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 151*639f9d9dSBarry Smith ii[coloring[i]-1][sizes[coloring[i]-1]++] = i; 152*639f9d9dSBarry Smith } 153*639f9d9dSBarry Smith is = (IS *) PetscMalloc( ncolors*sizeof(is) ); CHKPTRQ(is); 154*639f9d9dSBarry Smith for ( i=0; i<ncolors; i++ ) { 155*639f9d9dSBarry Smith ierr = ISCreateGeneral(MPI_COMM_SELF,sizes[i],ii[i],is+i); CHKERRQ(ierr); 156*639f9d9dSBarry Smith } 157*639f9d9dSBarry Smith 158*639f9d9dSBarry Smith *iscoloring = (ISColoring) PetscMalloc(sizeof(struct _ISColoring));CHKPTRQ(*iscoloring); 159*639f9d9dSBarry Smith (*iscoloring)->n = ncolors; 160*639f9d9dSBarry Smith (*iscoloring)->is = is; 161*639f9d9dSBarry Smith PetscCommDup_Private(mat->comm,&(*iscoloring)->comm,&tag); 162*639f9d9dSBarry Smith PetscFree(sizes); 163*639f9d9dSBarry Smith PetscFree(ii[0]); 164*639f9d9dSBarry Smith PetscFree(ii); 16570c3da92SBarry Smith return 0; 16670c3da92SBarry Smith } 16770c3da92SBarry Smith 168*639f9d9dSBarry Smith /* 169*639f9d9dSBarry Smith Makes a longer coloring[] array and calls the usual code with that 170*639f9d9dSBarry Smith */ 171*639f9d9dSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int ncolors,int *coloring,ISColoring *iscoloring) 17270c3da92SBarry Smith { 173*639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ *) mat->data; 174*639f9d9dSBarry Smith int n = a->n,ierr, m = a->inode.node_count,j,*ns = a->inode.size,row; 175*639f9d9dSBarry Smith int *colorused,i,*newcolor; 17670c3da92SBarry Smith 177*639f9d9dSBarry Smith newcolor = (int *) PetscMalloc((n+1)*sizeof(int)); CHKPTRQ(newcolor); 17870c3da92SBarry Smith 179*639f9d9dSBarry Smith /* loop over inodes, marking a color for each column*/ 180*639f9d9dSBarry Smith row = 0; 18170c3da92SBarry Smith for ( i=0; i<m; i++){ 182*639f9d9dSBarry Smith for ( j=0; j<ns[i]; j++) { 183*639f9d9dSBarry Smith newcolor[row++] = coloring[i] + j*ncolors; 18470c3da92SBarry Smith } 18570c3da92SBarry Smith } 18670c3da92SBarry Smith 187*639f9d9dSBarry Smith /* eliminate unneeded colors */ 188*639f9d9dSBarry Smith colorused = (int *) PetscMalloc( 5*ncolors*sizeof(int) ); CHKPTRQ(colorused); 189*639f9d9dSBarry Smith PetscMemzero(colorused,5*ncolors*sizeof(int)); 190*639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 191*639f9d9dSBarry Smith colorused[newcolor[i]-1] = 1; 192*639f9d9dSBarry Smith } 19370c3da92SBarry Smith 194*639f9d9dSBarry Smith for ( i=1; i<5*ncolors; i++ ) { 195*639f9d9dSBarry Smith colorused[i] += colorused[i-1]; 19670c3da92SBarry Smith } 197*639f9d9dSBarry Smith ncolors = colorused[5*ncolors-1]; 198*639f9d9dSBarry Smith for ( i=0; i<n; i++ ) { 199*639f9d9dSBarry Smith newcolor[i] = colorused[newcolor[i]-1]; 20070c3da92SBarry Smith } 201*639f9d9dSBarry Smith PetscFree(colorused); 20270c3da92SBarry Smith 203*639f9d9dSBarry Smith ierr = MatColoringPatch_SeqAIJ(mat,ncolors,newcolor,iscoloring); CHKERRQ(ierr); 204*639f9d9dSBarry Smith PetscFree(newcolor); 205*639f9d9dSBarry Smith 20670c3da92SBarry Smith return 0; 20770c3da92SBarry Smith } 20870c3da92SBarry Smith 209