173f4d377SMatthew Knepley /*$Id: fdaij.c,v 1.40 2001/06/21 21:16:21 bsmith Exp $*/ 270c3da92SBarry Smith 370c3da92SBarry Smith #include "src/mat/impls/aij/seq/aij.h" 470c3da92SBarry Smith #include "src/vec/vecimpl.h" 5639f9d9dSBarry Smith 6ca44d042SBarry Smith EXTERN int MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 7ca44d042SBarry Smith EXTERN int MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int**,int**,PetscTruth*); 843a90d84SBarry Smith 94a2ae208SSatish Balay #undef __FUNCT__ 104a2ae208SSatish Balay #define __FUNCT__ "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; 1430b34957SBarry Smith int nis = iscoloring->n,*rowhit,*columnsforrow,l; 15b9617806SBarry Smith IS *isa; 16f1af5d2fSBarry Smith PetscTruth done,flg; 17639f9d9dSBarry Smith 183a40ed3dSBarry Smith PetscFunctionBegin; 19522c5e43SBarry Smith if (!mat->assembled) { 2029bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 21522c5e43SBarry Smith } 22522c5e43SBarry Smith 23b9617806SBarry Smith ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 24005c665bSBarry Smith c->M = mat->M; /* set total rows, columns and local rows */ 25005c665bSBarry Smith c->N = mat->N; 26005c665bSBarry Smith c->m = mat->M; 27005c665bSBarry Smith c->rstart = 0; 28005c665bSBarry Smith 29639f9d9dSBarry Smith c->ncolors = nis; 30b0a32e0cSBarry Smith ierr = PetscMalloc(nis*sizeof(int),&c->ncolumns);CHKERRQ(ierr); 31b0a32e0cSBarry Smith ierr = PetscMalloc(nis*sizeof(int*),&c->columns);CHKERRQ(ierr); 32b0a32e0cSBarry Smith ierr = PetscMalloc(nis*sizeof(int),&c->nrows);CHKERRQ(ierr); 33b0a32e0cSBarry Smith ierr = PetscMalloc(nis*sizeof(int*),&c->rows);CHKERRQ(ierr); 34b0a32e0cSBarry Smith ierr = PetscMalloc(nis*sizeof(int*),&c->columnsforrow);CHKERRQ(ierr); 3543a90d84SBarry Smith 3643a90d84SBarry Smith /* 3743a90d84SBarry Smith Calls the _SeqAIJ() version of these routines to make sure it does not 3843a90d84SBarry Smith get the reduced (by inodes) version of I and J 3943a90d84SBarry Smith */ 4043a90d84SBarry Smith ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 4170c3da92SBarry Smith 4270c3da92SBarry Smith /* 43639f9d9dSBarry Smith Temporary option to allow for debugging/testing 4470c3da92SBarry Smith */ 45b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr); 4670c3da92SBarry Smith 47b0a32e0cSBarry Smith ierr = PetscMalloc((N+1)*sizeof(int),&rowhit);CHKERRQ(ierr); 48b0a32e0cSBarry Smith ierr = PetscMalloc((N+1)*sizeof(int),&columnsforrow);CHKERRQ(ierr); 4970c3da92SBarry Smith 50639f9d9dSBarry Smith for (i=0; i<nis; i++) { 51b9b97703SBarry Smith ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 52639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 53639f9d9dSBarry Smith c->ncolumns[i] = n; 54639f9d9dSBarry Smith if (n) { 55b0a32e0cSBarry Smith ierr = PetscMalloc(n*sizeof(int),&c->columns[i]);CHKERRQ(ierr); 56549d3d68SSatish Balay ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr); 5770c3da92SBarry Smith } else { 58639f9d9dSBarry Smith c->columns[i] = 0; 5970c3da92SBarry Smith } 6070c3da92SBarry Smith 613a7fca6bSBarry Smith if (!flg) { /* ------------------------------------------------------------------------------*/ 623a7fca6bSBarry Smith /* fast, crude version requires O(N*N) work */ 63549d3d68SSatish Balay ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr); 64639f9d9dSBarry Smith /* loop over columns*/ 65639f9d9dSBarry Smith for (j=0; j<n; j++) { 66639f9d9dSBarry Smith col = is[j]; 67639f9d9dSBarry Smith rows = cj + ci[col]; 68639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 69639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 70639f9d9dSBarry Smith for (k=0; k<m; k++) { 71639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 7270c3da92SBarry Smith } 7370c3da92SBarry Smith } 74639f9d9dSBarry Smith /* count the number of hits */ 75639f9d9dSBarry Smith nrows = 0; 7670c3da92SBarry Smith for (j=0; j<N; j++) { 77639f9d9dSBarry Smith if (rowhit[j]) nrows++; 78639f9d9dSBarry Smith } 79639f9d9dSBarry Smith c->nrows[i] = nrows; 803a7fca6bSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr); 813a7fca6bSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); 82639f9d9dSBarry Smith nrows = 0; 83639f9d9dSBarry Smith for (j=0; j<N; j++) { 84639f9d9dSBarry Smith if (rowhit[j]) { 85639f9d9dSBarry Smith c->rows[i][nrows] = j; 86639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 87639f9d9dSBarry Smith nrows++; 8870c3da92SBarry Smith } 8970c3da92SBarry Smith } 90639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 913a7fca6bSBarry Smith /* slow version, using rowhit as a linked list */ 92639f9d9dSBarry Smith int currentcol,fm,mfm; 93639f9d9dSBarry Smith rowhit[N] = N; 94639f9d9dSBarry Smith nrows = 0; 95639f9d9dSBarry Smith /* loop over columns */ 96639f9d9dSBarry Smith for (j=0; j<n; j++) { 97639f9d9dSBarry Smith col = is[j]; 98639f9d9dSBarry Smith rows = cj + ci[col]; 99639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 100639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 101639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 102639f9d9dSBarry Smith for (k=0; k<m; k++) { 103639f9d9dSBarry Smith currentcol = *rows++; 104639f9d9dSBarry Smith /* is it already in the list? */ 105639f9d9dSBarry Smith do { 106639f9d9dSBarry Smith mfm = fm; 107639f9d9dSBarry Smith fm = rowhit[fm]; 108639f9d9dSBarry Smith } while (fm < currentcol); 109639f9d9dSBarry Smith /* not in list so add it */ 110639f9d9dSBarry Smith if (fm != currentcol) { 111639f9d9dSBarry Smith nrows++; 112639f9d9dSBarry Smith columnsforrow[currentcol] = col; 113639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 114639f9d9dSBarry Smith rowhit[mfm] = currentcol; 115639f9d9dSBarry Smith rowhit[currentcol] = fm; 116639f9d9dSBarry Smith fm = currentcol; 117639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 11870c3da92SBarry Smith } else { 11929bbc08cSBarry Smith SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring"); 12070c3da92SBarry Smith } 121639f9d9dSBarry Smith 122639f9d9dSBarry Smith } 123639f9d9dSBarry Smith } 124639f9d9dSBarry Smith c->nrows[i] = nrows; 125b0a32e0cSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr); 126b0a32e0cSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); 127639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 128639f9d9dSBarry Smith nrows = 0; 129639f9d9dSBarry Smith fm = rowhit[N]; 130639f9d9dSBarry Smith do { 131639f9d9dSBarry Smith c->rows[i][nrows] = fm; 132639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 133639f9d9dSBarry Smith fm = rowhit[fm]; 134639f9d9dSBarry Smith } while (fm < N); 135639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 136639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 137639f9d9dSBarry Smith } 13843a90d84SBarry Smith ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 139639f9d9dSBarry Smith 140606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 141606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 142639f9d9dSBarry Smith 14330b34957SBarry Smith /* Optimize by adding the vscale, and scaleforrow[][] fields */ 14430b34957SBarry Smith /* 14530b34957SBarry Smith see the version for MPIAIJ 14630b34957SBarry Smith */ 14730b34957SBarry Smith ierr = VecCreateGhost(mat->comm,mat->m,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr) 148b0a32e0cSBarry Smith ierr = PetscMalloc(c->ncolors*sizeof(int*),&c->vscaleforrow);CHKERRQ(ierr); 14930b34957SBarry Smith for (k=0; k<c->ncolors; k++) { 150b0a32e0cSBarry Smith ierr = PetscMalloc((c->nrows[k]+1)*sizeof(int),&c->vscaleforrow[k]);CHKERRQ(ierr); 15130b34957SBarry Smith for (l=0; l<c->nrows[k]; l++) { 15230b34957SBarry Smith col = c->columnsforrow[k][l]; 15330b34957SBarry Smith c->vscaleforrow[k][l] = col; 15430b34957SBarry Smith } 15530b34957SBarry Smith } 156b9617806SBarry Smith ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 1573a40ed3dSBarry Smith PetscFunctionReturn(0); 15870c3da92SBarry Smith } 15970c3da92SBarry Smith 160639f9d9dSBarry Smith /* 161639f9d9dSBarry Smith Makes a longer coloring[] array and calls the usual code with that 162639f9d9dSBarry Smith */ 1634a2ae208SSatish Balay #undef __FUNCT__ 1644a2ae208SSatish Balay #define __FUNCT__ "MatColoringPatch_SeqAIJ_Inode" 1654e7234bfSBarry Smith int MatColoringPatch_SeqAIJ_Inode(Mat mat,int nin,int ncolors,const ISColoringValue coloring[],ISColoring *iscoloring) 16670c3da92SBarry Smith { 167639f9d9dSBarry Smith Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 168273d9f13SBarry Smith int n = mat->n,ierr,m = a->inode.node_count,j,*ns = a->inode.size,row; 16908b6dcc0SBarry Smith int *colorused,i; 17008b6dcc0SBarry Smith ISColoringValue *newcolor; 17170c3da92SBarry Smith 1723a40ed3dSBarry Smith PetscFunctionBegin; 173b0a32e0cSBarry Smith ierr = PetscMalloc((n+1)*sizeof(int),&newcolor);CHKERRQ(ierr); 174639f9d9dSBarry Smith /* loop over inodes, marking a color for each column*/ 175639f9d9dSBarry Smith row = 0; 17670c3da92SBarry Smith for (i=0; i<m; i++){ 177639f9d9dSBarry Smith for (j=0; j<ns[i]; j++) { 178639f9d9dSBarry Smith newcolor[row++] = coloring[i] + j*ncolors; 17970c3da92SBarry Smith } 18070c3da92SBarry Smith } 18170c3da92SBarry Smith 182639f9d9dSBarry Smith /* eliminate unneeded colors */ 183b0a32e0cSBarry Smith ierr = PetscMalloc(5*ncolors*sizeof(int),&colorused);CHKERRQ(ierr); 184549d3d68SSatish Balay ierr = PetscMemzero(colorused,5*ncolors*sizeof(int));CHKERRQ(ierr); 185639f9d9dSBarry Smith for (i=0; i<n; i++) { 186b9617806SBarry Smith colorused[newcolor[i]] = 1; 187639f9d9dSBarry Smith } 18870c3da92SBarry Smith 189639f9d9dSBarry Smith for (i=1; i<5*ncolors; i++) { 190639f9d9dSBarry Smith colorused[i] += colorused[i-1]; 19170c3da92SBarry Smith } 192639f9d9dSBarry Smith ncolors = colorused[5*ncolors-1]; 193639f9d9dSBarry Smith for (i=0; i<n; i++) { 194b9617806SBarry Smith newcolor[i] = colorused[newcolor[i]]; 19570c3da92SBarry Smith } 196606d414cSSatish Balay ierr = PetscFree(colorused);CHKERRQ(ierr); 197b9617806SBarry Smith ierr = ISColoringCreate(mat->comm,n,newcolor,iscoloring);CHKERRQ(ierr); 198*82eb8622SBarry Smith ierr = PetscFree((void*)coloring);CHKERRQ(ierr); 1993a40ed3dSBarry Smith PetscFunctionReturn(0); 20070c3da92SBarry Smith } 20170c3da92SBarry Smith 2023a40ed3dSBarry Smith 2033a40ed3dSBarry Smith 2043a40ed3dSBarry Smith 2053a40ed3dSBarry Smith 2063a40ed3dSBarry Smith 207