1 2 #include "src/mat/impls/aij/seq/aij.h" 3 4 EXTERN PetscErrorCode MatGetColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int*[],int*[],PetscTruth*); 5 EXTERN PetscErrorCode MatRestoreColumnIJ_SeqAIJ(Mat,int,PetscTruth,int*,int*[],int*[],PetscTruth*); 6 7 #undef __FUNCT__ 8 #define __FUNCT__ "MatFDColoringCreate_SeqAIJ" 9 PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 10 { 11 PetscErrorCode ierr; 12 int i,*is,n,nrows,N = mat->N,j,k,m,*rows,*ci,*cj,ncols,col; 13 int nis = iscoloring->n,*rowhit,*columnsforrow,l; 14 IS *isa; 15 PetscTruth done,flg; 16 17 PetscFunctionBegin; 18 if (!mat->assembled) { 19 SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 20 } 21 22 ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 23 c->M = mat->M; /* set total rows, columns and local rows */ 24 c->N = mat->N; 25 c->m = mat->M; 26 c->rstart = 0; 27 28 c->ncolors = nis; 29 ierr = PetscMalloc(nis*sizeof(int),&c->ncolumns);CHKERRQ(ierr); 30 ierr = PetscMalloc(nis*sizeof(int*),&c->columns);CHKERRQ(ierr); 31 ierr = PetscMalloc(nis*sizeof(int),&c->nrows);CHKERRQ(ierr); 32 ierr = PetscMalloc(nis*sizeof(int*),&c->rows);CHKERRQ(ierr); 33 ierr = PetscMalloc(nis*sizeof(int*),&c->columnsforrow);CHKERRQ(ierr); 34 35 /* 36 Calls the _SeqAIJ() version of these routines to make sure it does not 37 get the reduced (by inodes) version of I and J 38 */ 39 ierr = MatGetColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 40 41 /* 42 Temporary option to allow for debugging/testing 43 */ 44 ierr = PetscOptionsHasName(PETSC_NULL,"-matfdcoloring_slow",&flg);CHKERRQ(ierr); 45 46 ierr = PetscMalloc((N+1)*sizeof(int),&rowhit);CHKERRQ(ierr); 47 ierr = PetscMalloc((N+1)*sizeof(int),&columnsforrow);CHKERRQ(ierr); 48 49 for (i=0; i<nis; i++) { 50 ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 51 ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 52 c->ncolumns[i] = n; 53 if (n) { 54 ierr = PetscMalloc(n*sizeof(int),&c->columns[i]);CHKERRQ(ierr); 55 ierr = PetscMemcpy(c->columns[i],is,n*sizeof(int));CHKERRQ(ierr); 56 } else { 57 c->columns[i] = 0; 58 } 59 60 if (!flg) { /* ------------------------------------------------------------------------------*/ 61 /* fast, crude version requires O(N*N) work */ 62 ierr = PetscMemzero(rowhit,N*sizeof(int));CHKERRQ(ierr); 63 /* loop over columns*/ 64 for (j=0; j<n; j++) { 65 col = is[j]; 66 rows = cj + ci[col]; 67 m = ci[col+1] - ci[col]; 68 /* loop over columns marking them in rowhit */ 69 for (k=0; k<m; k++) { 70 rowhit[*rows++] = col + 1; 71 } 72 } 73 /* count the number of hits */ 74 nrows = 0; 75 for (j=0; j<N; j++) { 76 if (rowhit[j]) nrows++; 77 } 78 c->nrows[i] = nrows; 79 ierr = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr); 80 ierr = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); 81 nrows = 0; 82 for (j=0; j<N; j++) { 83 if (rowhit[j]) { 84 c->rows[i][nrows] = j; 85 c->columnsforrow[i][nrows] = rowhit[j] - 1; 86 nrows++; 87 } 88 } 89 } else { /*-------------------------------------------------------------------------------*/ 90 /* slow version, using rowhit as a linked list */ 91 int currentcol,fm,mfm; 92 rowhit[N] = N; 93 nrows = 0; 94 /* loop over columns */ 95 for (j=0; j<n; j++) { 96 col = is[j]; 97 rows = cj + ci[col]; 98 m = ci[col+1] - ci[col]; 99 /* loop over columns marking them in rowhit */ 100 fm = N; /* fm points to first entry in linked list */ 101 for (k=0; k<m; k++) { 102 currentcol = *rows++; 103 /* is it already in the list? */ 104 do { 105 mfm = fm; 106 fm = rowhit[fm]; 107 } while (fm < currentcol); 108 /* not in list so add it */ 109 if (fm != currentcol) { 110 nrows++; 111 columnsforrow[currentcol] = col; 112 /* next three lines insert new entry into linked list */ 113 rowhit[mfm] = currentcol; 114 rowhit[currentcol] = fm; 115 fm = currentcol; 116 /* fm points to present position in list since we know the columns are sorted */ 117 } else { 118 SETERRQ(PETSC_ERR_PLIB,"Detected invalid coloring"); 119 } 120 121 } 122 } 123 c->nrows[i] = nrows; 124 ierr = PetscMalloc((nrows+1)*sizeof(int),&c->rows[i]);CHKERRQ(ierr); 125 ierr = PetscMalloc((nrows+1)*sizeof(int),&c->columnsforrow[i]);CHKERRQ(ierr); 126 /* now store the linked list of rows into c->rows[i] */ 127 nrows = 0; 128 fm = rowhit[N]; 129 do { 130 c->rows[i][nrows] = fm; 131 c->columnsforrow[i][nrows++] = columnsforrow[fm]; 132 fm = rowhit[fm]; 133 } while (fm < N); 134 } /* ---------------------------------------------------------------------------------------*/ 135 ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 136 } 137 ierr = MatRestoreColumnIJ_SeqAIJ(mat,0,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 138 139 ierr = PetscFree(rowhit);CHKERRQ(ierr); 140 ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 141 142 /* Optimize by adding the vscale, and scaleforrow[][] fields */ 143 /* 144 see the version for MPIAIJ 145 */ 146 ierr = VecCreateGhost(mat->comm,mat->m,PETSC_DETERMINE,0,PETSC_NULL,&c->vscale);CHKERRQ(ierr) 147 ierr = PetscMalloc(c->ncolors*sizeof(int*),&c->vscaleforrow);CHKERRQ(ierr); 148 for (k=0; k<c->ncolors; k++) { 149 ierr = PetscMalloc((c->nrows[k]+1)*sizeof(int),&c->vscaleforrow[k]);CHKERRQ(ierr); 150 for (l=0; l<c->nrows[k]; l++) { 151 col = c->columnsforrow[k][l]; 152 c->vscaleforrow[k][l] = col; 153 } 154 } 155 ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 156 PetscFunctionReturn(0); 157 } 158 159 /* 160 Makes a longer coloring[] array and calls the usual code with that 161 */ 162 #undef __FUNCT__ 163 #define __FUNCT__ "MatColoringPatch_SeqAIJ_Inode" 164 PetscErrorCode MatColoringPatch_SeqAIJ_Inode(Mat mat,int nin,int ncolors,const ISColoringValue coloring[],ISColoring *iscoloring) 165 { 166 Mat_SeqAIJ *a = (Mat_SeqAIJ*)mat->data; 167 PetscErrorCode ierr; 168 int n = mat->n,m = a->inode.node_count,j,*ns = a->inode.size,row; 169 int *colorused,i; 170 ISColoringValue *newcolor; 171 172 PetscFunctionBegin; 173 ierr = PetscMalloc((n+1)*sizeof(int),&newcolor);CHKERRQ(ierr); 174 /* loop over inodes, marking a color for each column*/ 175 row = 0; 176 for (i=0; i<m; i++){ 177 for (j=0; j<ns[i]; j++) { 178 newcolor[row++] = coloring[i] + j*ncolors; 179 } 180 } 181 182 /* eliminate unneeded colors */ 183 ierr = PetscMalloc(5*ncolors*sizeof(int),&colorused);CHKERRQ(ierr); 184 ierr = PetscMemzero(colorused,5*ncolors*sizeof(int));CHKERRQ(ierr); 185 for (i=0; i<n; i++) { 186 colorused[newcolor[i]] = 1; 187 } 188 189 for (i=1; i<5*ncolors; i++) { 190 colorused[i] += colorused[i-1]; 191 } 192 ncolors = colorused[5*ncolors-1]; 193 for (i=0; i<n; i++) { 194 newcolor[i] = colorused[newcolor[i]]; 195 } 196 ierr = PetscFree(colorused);CHKERRQ(ierr); 197 ierr = ISColoringCreate(mat->comm,n,newcolor,iscoloring);CHKERRQ(ierr); 198 ierr = PetscFree((void*)coloring);CHKERRQ(ierr); 199 PetscFunctionReturn(0); 200 } 201 202 203 204 205 206 207