1be1d678aSKris Buschelman #define PETSCMAT_DLL 270c3da92SBarry Smith 3*7c4f633dSBarry Smith #include "../src/mat/impls/aij/seq/aij.h" 4639f9d9dSBarry Smith 54a2ae208SSatish Balay #undef __FUNCT__ 64a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ" 7dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 8639f9d9dSBarry Smith { 96849ba73SBarry Smith PetscErrorCode ierr; 105d0c19d7SBarry Smith PetscInt i,n,nrows,N = mat->cmap->N,j,k,m,*rows,*ci,*cj,ncols,col; 115d0c19d7SBarry Smith const PetscInt *is; 1238baddfdSBarry Smith PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l; 13b9617806SBarry Smith IS *isa; 14f1af5d2fSBarry Smith PetscTruth done,flg; 15639f9d9dSBarry Smith 163a40ed3dSBarry Smith PetscFunctionBegin; 17522c5e43SBarry Smith if (!mat->assembled) { 1829bbc08cSBarry Smith SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 19522c5e43SBarry Smith } 20522c5e43SBarry Smith 21b9617806SBarry Smith ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 22d0f46423SBarry Smith c->M = mat->rmap->N; /* set total rows, columns and local rows */ 23d0f46423SBarry Smith c->N = mat->cmap->N; 24d0f46423SBarry Smith c->m = mat->rmap->N; 25005c665bSBarry Smith c->rstart = 0; 26005c665bSBarry Smith 27639f9d9dSBarry Smith c->ncolors = nis; 2838baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr); 2938baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr); 3038baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr); 3138baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr); 3238baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr); 3343a90d84SBarry Smith 3443a90d84SBarry Smith /* 3543a90d84SBarry Smith Calls the _SeqAIJ() version of these routines to make sure it does not 3643a90d84SBarry Smith get the reduced (by inodes) version of I and J 3743a90d84SBarry Smith */ 388f7157efSSatish Balay ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 3970c3da92SBarry Smith 4070c3da92SBarry Smith /* 41639f9d9dSBarry Smith Temporary option to allow for debugging/testing 4270c3da92SBarry Smith */ 43b0a32e0cSBarry Smith ierr = PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr); 4470c3da92SBarry Smith 4538baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr); 4638baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr); 4770c3da92SBarry Smith 48639f9d9dSBarry Smith for (i=0; i<nis; i++) { 49b9b97703SBarry Smith ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 50639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 51639f9d9dSBarry Smith c->ncolumns[i] = n; 52639f9d9dSBarry Smith if (n) { 5338baddfdSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr); 5438baddfdSBarry Smith ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr); 5570c3da92SBarry Smith } else { 56639f9d9dSBarry Smith c->columns[i] = 0; 5770c3da92SBarry Smith } 5870c3da92SBarry Smith 593a7fca6bSBarry Smith if (!flg) { /* ------------------------------------------------------------------------------*/ 603a7fca6bSBarry Smith /* fast, crude version requires O(N*N) work */ 6138baddfdSBarry Smith ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr); 62639f9d9dSBarry Smith /* loop over columns*/ 63639f9d9dSBarry Smith for (j=0; j<n; j++) { 64639f9d9dSBarry Smith col = is[j]; 65639f9d9dSBarry Smith rows = cj + ci[col]; 66639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 67639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 68639f9d9dSBarry Smith for (k=0; k<m; k++) { 69639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 7070c3da92SBarry Smith } 7170c3da92SBarry Smith } 72639f9d9dSBarry Smith /* count the number of hits */ 73639f9d9dSBarry Smith nrows = 0; 7470c3da92SBarry Smith for (j=0; j<N; j++) { 75639f9d9dSBarry Smith if (rowhit[j]) nrows++; 76639f9d9dSBarry Smith } 77639f9d9dSBarry Smith c->nrows[i] = nrows; 7838baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 7938baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 80639f9d9dSBarry Smith nrows = 0; 81639f9d9dSBarry Smith for (j=0; j<N; j++) { 82639f9d9dSBarry Smith if (rowhit[j]) { 83639f9d9dSBarry Smith c->rows[i][nrows] = j; 84639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 85639f9d9dSBarry Smith nrows++; 8670c3da92SBarry Smith } 8770c3da92SBarry Smith } 88639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 893a7fca6bSBarry Smith /* slow version, using rowhit as a linked list */ 9038baddfdSBarry Smith PetscInt currentcol,fm,mfm; 91639f9d9dSBarry Smith rowhit[N] = N; 92639f9d9dSBarry Smith nrows = 0; 93639f9d9dSBarry Smith /* loop over columns */ 94639f9d9dSBarry Smith for (j=0; j<n; j++) { 95639f9d9dSBarry Smith col = is[j]; 96639f9d9dSBarry Smith rows = cj + ci[col]; 97639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 98639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 99639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 100639f9d9dSBarry Smith for (k=0; k<m; k++) { 101639f9d9dSBarry Smith currentcol = *rows++; 102639f9d9dSBarry Smith /* is it already in the list? */ 103639f9d9dSBarry Smith do { 104639f9d9dSBarry Smith mfm = fm; 105639f9d9dSBarry Smith fm = rowhit[fm]; 106639f9d9dSBarry Smith } while (fm < currentcol); 107639f9d9dSBarry Smith /* not in list so add it */ 108639f9d9dSBarry Smith if (fm != currentcol) { 109639f9d9dSBarry Smith nrows++; 110639f9d9dSBarry Smith columnsforrow[currentcol] = col; 111639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 112639f9d9dSBarry Smith rowhit[mfm] = currentcol; 113639f9d9dSBarry Smith rowhit[currentcol] = fm; 114639f9d9dSBarry Smith fm = currentcol; 115639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 11670c3da92SBarry Smith } else { 11729bbc08cSBarry Smith SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring"); 11870c3da92SBarry Smith } 119639f9d9dSBarry Smith 120639f9d9dSBarry Smith } 121639f9d9dSBarry Smith } 122639f9d9dSBarry Smith c->nrows[i] = nrows; 12338baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 12438baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 125639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 126639f9d9dSBarry Smith nrows = 0; 127639f9d9dSBarry Smith fm = rowhit[N]; 128639f9d9dSBarry Smith do { 129639f9d9dSBarry Smith c->rows[i][nrows] = fm; 130639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 131639f9d9dSBarry Smith fm = rowhit[fm]; 132639f9d9dSBarry Smith } while (fm < N); 133639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 134639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 135639f9d9dSBarry Smith } 1368f7157efSSatish Balay ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 137639f9d9dSBarry Smith 138606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 139606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 140639f9d9dSBarry Smith 14130b34957SBarry Smith /* Optimize by adding the vscale, and scaleforrow[][] fields */ 14230b34957SBarry Smith /* 14330b34957SBarry Smith see the version for MPIAIJ 14430b34957SBarry Smith */ 145d0f46423SBarry Smith ierr = VecCreateGhost(((PetscObject)mat)->comm,mat->rmap->n,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr) 14638baddfdSBarry Smith ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr); 14730b34957SBarry Smith for (k=0; k<c->ncolors; k++) { 14838baddfdSBarry Smith ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr); 14930b34957SBarry Smith for (l=0; l<c->nrows[k]; l++) { 15030b34957SBarry Smith col = c->columnsforrow[k][l]; 15130b34957SBarry Smith c->vscaleforrow[k][l] = col; 15230b34957SBarry Smith } 15330b34957SBarry Smith } 154b9617806SBarry Smith ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 1553a40ed3dSBarry Smith PetscFunctionReturn(0); 15670c3da92SBarry Smith } 157