170c3da92SBarry Smith 2c6db04a5SJed Brown #include <../src/mat/impls/aij/seq/aij.h> 3639f9d9dSBarry Smith 4*79c1e64dSHong Zhang /* 5*79c1e64dSHong Zhang Redundant - remove later! 6*79c1e64dSHong Zhang */ 7*79c1e64dSHong Zhang #undef __FUNCT__ 8*79c1e64dSHong Zhang #define __FUNCT__ "MatGetColumnIJ_SeqAIJ_Color_Redundant" 9*79c1e64dSHong Zhang PetscErrorCode MatGetColumnIJ_SeqAIJ_Color_Redundant(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *nn,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 10*79c1e64dSHong Zhang { 11*79c1e64dSHong Zhang Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 12*79c1e64dSHong Zhang PetscErrorCode ierr; 13*79c1e64dSHong Zhang PetscInt i,*collengths,*cia,*cja,n = A->cmap->n,m = A->rmap->n; 14*79c1e64dSHong Zhang PetscInt nz = a->i[m],row,*jj,mr,col; 15*79c1e64dSHong Zhang PetscInt *cspidx; 16*79c1e64dSHong Zhang 17*79c1e64dSHong Zhang PetscFunctionBegin; 18*79c1e64dSHong Zhang *nn = n; 19*79c1e64dSHong Zhang if (!ia) PetscFunctionReturn(0); 20*79c1e64dSHong Zhang if (symmetric) { 21*79c1e64dSHong Zhang SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatGetColumnIJ_SeqAIJ_Color() not supported for the case symmetric"); 22*79c1e64dSHong Zhang ierr = MatToSymmetricIJ_SeqAIJ(A->rmap->n,a->i,a->j,0,oshift,(PetscInt**)ia,(PetscInt**)ja);CHKERRQ(ierr); 23*79c1e64dSHong Zhang } else { 24*79c1e64dSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&collengths);CHKERRQ(ierr); 25*79c1e64dSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 26*79c1e64dSHong Zhang ierr = PetscMalloc((n+1)*sizeof(PetscInt),&cia);CHKERRQ(ierr); 27*79c1e64dSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cja);CHKERRQ(ierr); 28*79c1e64dSHong Zhang ierr = PetscMalloc((nz+1)*sizeof(PetscInt),&cspidx);CHKERRQ(ierr); 29*79c1e64dSHong Zhang jj = a->j; 30*79c1e64dSHong Zhang for (i=0; i<nz; i++) { 31*79c1e64dSHong Zhang collengths[jj[i]]++; 32*79c1e64dSHong Zhang } 33*79c1e64dSHong Zhang cia[0] = oshift; 34*79c1e64dSHong Zhang for (i=0; i<n; i++) { 35*79c1e64dSHong Zhang cia[i+1] = cia[i] + collengths[i]; 36*79c1e64dSHong Zhang } 37*79c1e64dSHong Zhang ierr = PetscMemzero(collengths,n*sizeof(PetscInt));CHKERRQ(ierr); 38*79c1e64dSHong Zhang jj = a->j; 39*79c1e64dSHong Zhang for (row=0; row<m; row++) { 40*79c1e64dSHong Zhang mr = a->i[row+1] - a->i[row]; 41*79c1e64dSHong Zhang for (i=0; i<mr; i++) { 42*79c1e64dSHong Zhang col = *jj++; 43*79c1e64dSHong Zhang 44*79c1e64dSHong Zhang cspidx[cia[col] + collengths[col] - oshift] = a->i[row] + i; /* index of a->j */ 45*79c1e64dSHong Zhang cja[cia[col] + collengths[col]++ - oshift] = row + oshift; 46*79c1e64dSHong Zhang } 47*79c1e64dSHong Zhang } 48*79c1e64dSHong Zhang ierr = PetscFree(collengths);CHKERRQ(ierr); 49*79c1e64dSHong Zhang *ia = cia; *ja = cja; 50*79c1e64dSHong Zhang *spidx = cspidx; 51*79c1e64dSHong Zhang } 52*79c1e64dSHong Zhang PetscFunctionReturn(0); 53*79c1e64dSHong Zhang } 54*79c1e64dSHong Zhang 55*79c1e64dSHong Zhang #undef __FUNCT__ 56*79c1e64dSHong Zhang #define __FUNCT__ "MatRestoreColumnIJ_SeqAIJ_Color_Redundant" 57*79c1e64dSHong Zhang PetscErrorCode MatRestoreColumnIJ_SeqAIJ_Color_Redundant(Mat A,PetscInt oshift,PetscBool symmetric,PetscBool inodecompressed,PetscInt *n,const PetscInt *ia[],const PetscInt *ja[],PetscInt *spidx[],PetscBool *done) 58*79c1e64dSHong Zhang { 59*79c1e64dSHong Zhang PetscErrorCode ierr; 60*79c1e64dSHong Zhang 61*79c1e64dSHong Zhang PetscFunctionBegin; 62*79c1e64dSHong Zhang if (!ia) PetscFunctionReturn(0); 63*79c1e64dSHong Zhang 64*79c1e64dSHong Zhang ierr = PetscFree(*ia);CHKERRQ(ierr); 65*79c1e64dSHong Zhang ierr = PetscFree(*ja);CHKERRQ(ierr); 66*79c1e64dSHong Zhang ierr = PetscFree(*spidx);CHKERRQ(ierr); 67*79c1e64dSHong Zhang PetscFunctionReturn(0); 68*79c1e64dSHong Zhang } 69*79c1e64dSHong Zhang 70*79c1e64dSHong Zhang /* -------------------------------------------*/ 71*79c1e64dSHong Zhang 72*79c1e64dSHong Zhang #undef __FUNCT__ 73*79c1e64dSHong Zhang #define __FUNCT__ "MatFDColoringCreate_SeqAIJ_den2sp" 74*79c1e64dSHong Zhang /* 75*79c1e64dSHong Zhang This routine optimizes MatFDColoringCreate_SeqAIJ() by using den2sp array 76*79c1e64dSHong Zhang */ 77*79c1e64dSHong Zhang PetscErrorCode MatFDColoringCreate_SeqAIJ_den2sp(Mat mat,ISColoring iscoloring,MatFDColoring c) 78*79c1e64dSHong Zhang { 79*79c1e64dSHong Zhang PetscErrorCode ierr; 80*79c1e64dSHong Zhang PetscInt i,n,nrows,N,j,k,m,ncols,col; 81*79c1e64dSHong Zhang const PetscInt *is,*rows,*ci,*cj; 82*79c1e64dSHong Zhang PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1,*spidx,*spidxhit,*den2sp,*den2sp_i; 83*79c1e64dSHong Zhang IS *isa; 84*79c1e64dSHong Zhang PetscBool flg1,flg2; 85*79c1e64dSHong Zhang Mat_SeqAIJ *csp = (Mat_SeqAIJ*)mat->data; 86*79c1e64dSHong Zhang 87*79c1e64dSHong Zhang PetscFunctionBegin; 88*79c1e64dSHong Zhang printf("MatFDColoringCreate_SeqAIJ_den2sp ...\n"); 89*79c1e64dSHong Zhang if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 90*79c1e64dSHong Zhang 91*79c1e64dSHong Zhang ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 92*79c1e64dSHong Zhang /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ 93*79c1e64dSHong Zhang ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); 94*79c1e64dSHong Zhang ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); 95*79c1e64dSHong Zhang if (flg1 || flg2) { 96*79c1e64dSHong Zhang ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 97*79c1e64dSHong Zhang } 98*79c1e64dSHong Zhang 99*79c1e64dSHong Zhang N = mat->cmap->N/bs; 100*79c1e64dSHong Zhang c->M = mat->rmap->N/bs; /* set total rows, columns and local rows */ 101*79c1e64dSHong Zhang c->N = mat->cmap->N/bs; 102*79c1e64dSHong Zhang c->m = mat->rmap->N/bs; 103*79c1e64dSHong Zhang c->rstart = 0; 104*79c1e64dSHong Zhang 105*79c1e64dSHong Zhang c->ncolors = nis; 106*79c1e64dSHong Zhang ierr = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr); 107*79c1e64dSHong Zhang ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr); 108*79c1e64dSHong Zhang ierr = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr); 109*79c1e64dSHong Zhang ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr); 110*79c1e64dSHong Zhang ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr); 111*79c1e64dSHong Zhang ierr = PetscMalloc((csp->nz+1)*sizeof(PetscInt),&den2sp);CHKERRQ(ierr); 112*79c1e64dSHong Zhang den2sp_i = den2sp; 113*79c1e64dSHong Zhang 114*79c1e64dSHong Zhang ierr = MatGetColumnIJ_SeqAIJ_Color_Redundant(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&spidx,NULL);CHKERRQ(ierr); 115*79c1e64dSHong Zhang 116*79c1e64dSHong Zhang ierr = PetscMalloc((c->m+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr); 117*79c1e64dSHong Zhang ierr = PetscMemzero(rowhit,c->m*sizeof(PetscInt));CHKERRQ(ierr); 118*79c1e64dSHong Zhang ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr); // N=mat->cmap->N/bs or c->M ? 119*79c1e64dSHong Zhang ierr = PetscMalloc((c->m+1)*sizeof(PetscInt),&spidxhit);CHKERRQ(ierr); 120*79c1e64dSHong Zhang 121*79c1e64dSHong Zhang for (i=0; i<nis; i++) { /* loop over colors */ 122*79c1e64dSHong Zhang ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 123*79c1e64dSHong Zhang ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 124*79c1e64dSHong Zhang 125*79c1e64dSHong Zhang c->ncolumns[i] = n; 126*79c1e64dSHong Zhang if (n) { 127*79c1e64dSHong Zhang ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr); 128*79c1e64dSHong Zhang ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr); 129*79c1e64dSHong Zhang } else { 130*79c1e64dSHong Zhang c->columns[i] = 0; 131*79c1e64dSHong Zhang } 132*79c1e64dSHong Zhang 133*79c1e64dSHong Zhang /* fast, crude version requires O(N*N) work */ 134*79c1e64dSHong Zhang for (j=0; j<n; j++) { /* loop over columns */ 135*79c1e64dSHong Zhang col = is[j]; 136*79c1e64dSHong Zhang rows = cj + ci[col]; 137*79c1e64dSHong Zhang m = ci[col+1] - ci[col]; 138*79c1e64dSHong Zhang for (k=0; k<m; k++) { /* loop over columns marking them in rowhit */ 139*79c1e64dSHong Zhang rowhit[*rows] = col + 1; 140*79c1e64dSHong Zhang spidxhit[*rows] = spidx[ci[col] + k]; 141*79c1e64dSHong Zhang rows++; 142*79c1e64dSHong Zhang } 143*79c1e64dSHong Zhang } 144*79c1e64dSHong Zhang /* get num of rows by counting the number of hits */ 145*79c1e64dSHong Zhang nrows = 0; 146*79c1e64dSHong Zhang for (j=0; j<N; j++) { 147*79c1e64dSHong Zhang if (rowhit[j]) nrows++; 148*79c1e64dSHong Zhang } 149*79c1e64dSHong Zhang c->nrows[i] = nrows; 150*79c1e64dSHong Zhang 151*79c1e64dSHong Zhang ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 152*79c1e64dSHong Zhang ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 153*79c1e64dSHong Zhang nrows = 0; 154*79c1e64dSHong Zhang for (j=0; j<N; j++) { /* loop over rows */ 155*79c1e64dSHong Zhang if (rowhit[j]) { 156*79c1e64dSHong Zhang c->rows[i][nrows] = j; /* row index */ 157*79c1e64dSHong Zhang c->columnsforrow[i][nrows] = rowhit[j] - 1; /* column index */ 158*79c1e64dSHong Zhang den2sp_i[nrows++] = spidxhit[j]; 159*79c1e64dSHong Zhang rowhit[j] = 0.0; /* zero rowhit for reuse */ 160*79c1e64dSHong Zhang } 161*79c1e64dSHong Zhang } 162*79c1e64dSHong Zhang den2sp_i += nrows; 163*79c1e64dSHong Zhang ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 164*79c1e64dSHong Zhang } 165*79c1e64dSHong Zhang ierr = MatRestoreColumnIJ_SeqAIJ_Color_Redundant(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&spidx,NULL);CHKERRQ(ierr); 166*79c1e64dSHong Zhang 167*79c1e64dSHong Zhang ierr = PetscFree(rowhit);CHKERRQ(ierr); 168*79c1e64dSHong Zhang ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 169*79c1e64dSHong Zhang ierr = PetscFree(spidxhit);CHKERRQ(ierr); 170*79c1e64dSHong Zhang 171*79c1e64dSHong Zhang /* Optimize by adding the vscale, and scaleforrow[][] fields -- needed for seqaij??? */ 172*79c1e64dSHong Zhang /* 173*79c1e64dSHong Zhang see the version for MPIAIJ 174*79c1e64dSHong Zhang */ 175*79c1e64dSHong Zhang ierr = VecCreateGhost(PetscObjectComm((PetscObject)mat),mat->rmap->n,PETSC_DETERMINE,0,NULL,&c->vscale);CHKERRQ(ierr); 176*79c1e64dSHong Zhang ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr); 177*79c1e64dSHong Zhang for (k=0; k<c->ncolors; k++) { 178*79c1e64dSHong Zhang ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr); 179*79c1e64dSHong Zhang for (l=0; l<c->nrows[k]; l++) { 180*79c1e64dSHong Zhang col = c->columnsforrow[k][l]; 181*79c1e64dSHong Zhang 182*79c1e64dSHong Zhang c->vscaleforrow[k][l] = col; 183*79c1e64dSHong Zhang } 184*79c1e64dSHong Zhang } 185*79c1e64dSHong Zhang ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 186*79c1e64dSHong Zhang c->den2sp = den2sp; 187*79c1e64dSHong Zhang mat->ops->fdcoloringapply = MatFDColoringApply_SeqAIJ; 188*79c1e64dSHong Zhang PetscFunctionReturn(0); 189*79c1e64dSHong Zhang } 190*79c1e64dSHong Zhang 191*79c1e64dSHong Zhang /* --------------------------------------------------------------- */ 192*79c1e64dSHong Zhang 1934a2ae208SSatish Balay #undef __FUNCT__ 1944a2ae208SSatish Balay #define __FUNCT__ "MatFDColoringCreate_SeqAIJ" 1953acb8795SBarry Smith /* 1963acb8795SBarry Smith This routine is shared by AIJ and BAIJ matrices, since it operators only on the nonzero structure of the elements or blocks. 1973acb8795SBarry Smith This is why it has the ugly code with the MatGetBlockSize() 1983acb8795SBarry Smith */ 199dfbe8321SBarry Smith PetscErrorCode MatFDColoringCreate_SeqAIJ(Mat mat,ISColoring iscoloring,MatFDColoring c) 200639f9d9dSBarry Smith { 2016849ba73SBarry Smith PetscErrorCode ierr; 2021a83f524SJed Brown PetscInt i,n,nrows,N,j,k,m,ncols,col; 2031a83f524SJed Brown const PetscInt *is,*rows,*ci,*cj; 2043acb8795SBarry Smith PetscInt nis = iscoloring->n,*rowhit,*columnsforrow,l,bs = 1; 205b9617806SBarry Smith IS *isa; 206ace3abfcSBarry Smith PetscBool done,flg = PETSC_FALSE; 207ace3abfcSBarry Smith PetscBool flg1,flg2; 208*79c1e64dSHong Zhang PetscBool new_impl=PETSC_FALSE; 209639f9d9dSBarry Smith 2103a40ed3dSBarry Smith PetscFunctionBegin; 211*79c1e64dSHong Zhang printf("MatFDColoringCreate_SeqAIJ ...\n"); 212*79c1e64dSHong Zhang ierr = PetscOptionsName("-new","using new impls","",&new_impl);CHKERRQ(ierr); 213*79c1e64dSHong Zhang if (new_impl){ 214*79c1e64dSHong Zhang ierr = MatFDColoringCreate_SeqAIJ_den2sp(mat,iscoloring,c);CHKERRQ(ierr); 215*79c1e64dSHong Zhang PetscFunctionReturn(0); 216*79c1e64dSHong Zhang } 217e7e72b3dSBarry Smith if (!mat->assembled) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be assembled by calls to MatAssemblyBegin/End();"); 218522c5e43SBarry Smith 219b9617806SBarry Smith ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&isa);CHKERRQ(ierr); 2203acb8795SBarry Smith /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ 221251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); 222251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); 2233acb8795SBarry Smith if (flg1 || flg2) { 2243acb8795SBarry Smith ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); 2253acb8795SBarry Smith } 2263acb8795SBarry Smith 2273acb8795SBarry Smith N = mat->cmap->N/bs; 2283acb8795SBarry Smith c->M = mat->rmap->N/bs; /* set total rows, columns and local rows */ 2293acb8795SBarry Smith c->N = mat->cmap->N/bs; 2303acb8795SBarry Smith c->m = mat->rmap->N/bs; 231005c665bSBarry Smith c->rstart = 0; 232005c665bSBarry Smith 233639f9d9dSBarry Smith c->ncolors = nis; 23438baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->ncolumns);CHKERRQ(ierr); 23538baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columns);CHKERRQ(ierr); 23638baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt),&c->nrows);CHKERRQ(ierr); 23738baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->rows);CHKERRQ(ierr); 23838baddfdSBarry Smith ierr = PetscMalloc(nis*sizeof(PetscInt*),&c->columnsforrow);CHKERRQ(ierr); 23943a90d84SBarry Smith 2403acb8795SBarry Smith ierr = MatGetColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 241ce94432eSBarry Smith if (!done) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"MatGetColumnIJ() not supported for matrix type %s",((PetscObject)mat)->type_name); 24270c3da92SBarry Smith 24370c3da92SBarry Smith /* 244639f9d9dSBarry Smith Temporary option to allow for debugging/testing 24570c3da92SBarry Smith */ 2460298fd71SBarry Smith ierr = PetscOptionsGetBool(NULL,"-matfdcoloring_slow",&flg,NULL);CHKERRQ(ierr); 24770c3da92SBarry Smith 24838baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&rowhit);CHKERRQ(ierr); 24938baddfdSBarry Smith ierr = PetscMalloc((N+1)*sizeof(PetscInt),&columnsforrow);CHKERRQ(ierr); 25070c3da92SBarry Smith 251639f9d9dSBarry Smith for (i=0; i<nis; i++) { 252b9b97703SBarry Smith ierr = ISGetLocalSize(isa[i],&n);CHKERRQ(ierr); 253639f9d9dSBarry Smith ierr = ISGetIndices(isa[i],&is);CHKERRQ(ierr); 2542205254eSKarl Rupp 255639f9d9dSBarry Smith c->ncolumns[i] = n; 256639f9d9dSBarry Smith if (n) { 25738baddfdSBarry Smith ierr = PetscMalloc(n*sizeof(PetscInt),&c->columns[i]);CHKERRQ(ierr); 25838baddfdSBarry Smith ierr = PetscMemcpy(c->columns[i],is,n*sizeof(PetscInt));CHKERRQ(ierr); 25970c3da92SBarry Smith } else { 260639f9d9dSBarry Smith c->columns[i] = 0; 26170c3da92SBarry Smith } 26270c3da92SBarry Smith 2633a7fca6bSBarry Smith if (!flg) { /* ------------------------------------------------------------------------------*/ 2643a7fca6bSBarry Smith /* fast, crude version requires O(N*N) work */ 26538baddfdSBarry Smith ierr = PetscMemzero(rowhit,N*sizeof(PetscInt));CHKERRQ(ierr); 266639f9d9dSBarry Smith /* loop over columns*/ 267639f9d9dSBarry Smith for (j=0; j<n; j++) { 268639f9d9dSBarry Smith col = is[j]; 269639f9d9dSBarry Smith rows = cj + ci[col]; 270639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 271639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 272639f9d9dSBarry Smith for (k=0; k<m; k++) { 273639f9d9dSBarry Smith rowhit[*rows++] = col + 1; 27470c3da92SBarry Smith } 27570c3da92SBarry Smith } 276639f9d9dSBarry Smith /* count the number of hits */ 277639f9d9dSBarry Smith nrows = 0; 27870c3da92SBarry Smith for (j=0; j<N; j++) { 279639f9d9dSBarry Smith if (rowhit[j]) nrows++; 280639f9d9dSBarry Smith } 281639f9d9dSBarry Smith c->nrows[i] = nrows; 28238baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 28338baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 284639f9d9dSBarry Smith nrows = 0; 285639f9d9dSBarry Smith for (j=0; j<N; j++) { 286639f9d9dSBarry Smith if (rowhit[j]) { 287639f9d9dSBarry Smith c->rows[i][nrows] = j; 288639f9d9dSBarry Smith c->columnsforrow[i][nrows] = rowhit[j] - 1; 289639f9d9dSBarry Smith nrows++; 29070c3da92SBarry Smith } 29170c3da92SBarry Smith } 292639f9d9dSBarry Smith } else { /*-------------------------------------------------------------------------------*/ 2933a7fca6bSBarry Smith /* slow version, using rowhit as a linked list */ 29438baddfdSBarry Smith PetscInt currentcol,fm,mfm; 295639f9d9dSBarry Smith rowhit[N] = N; 296639f9d9dSBarry Smith nrows = 0; 297639f9d9dSBarry Smith /* loop over columns */ 298639f9d9dSBarry Smith for (j=0; j<n; j++) { 299639f9d9dSBarry Smith col = is[j]; 300639f9d9dSBarry Smith rows = cj + ci[col]; 301639f9d9dSBarry Smith m = ci[col+1] - ci[col]; 302639f9d9dSBarry Smith /* loop over columns marking them in rowhit */ 303639f9d9dSBarry Smith fm = N; /* fm points to first entry in linked list */ 304639f9d9dSBarry Smith for (k=0; k<m; k++) { 305639f9d9dSBarry Smith currentcol = *rows++; 306639f9d9dSBarry Smith /* is it already in the list? */ 307639f9d9dSBarry Smith do { 308639f9d9dSBarry Smith mfm = fm; 309639f9d9dSBarry Smith fm = rowhit[fm]; 310639f9d9dSBarry Smith } while (fm < currentcol); 311639f9d9dSBarry Smith /* not in list so add it */ 312639f9d9dSBarry Smith if (fm != currentcol) { 313639f9d9dSBarry Smith nrows++; 314639f9d9dSBarry Smith columnsforrow[currentcol] = col; 315639f9d9dSBarry Smith /* next three lines insert new entry into linked list */ 316639f9d9dSBarry Smith rowhit[mfm] = currentcol; 317639f9d9dSBarry Smith rowhit[currentcol] = fm; 318639f9d9dSBarry Smith fm = currentcol; 319639f9d9dSBarry Smith /* fm points to present position in list since we know the columns are sorted */ 32071cd77b2SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Detected invalid coloring"); 321639f9d9dSBarry Smith } 322639f9d9dSBarry Smith } 323639f9d9dSBarry Smith c->nrows[i] = nrows; 32438baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->rows[i]);CHKERRQ(ierr); 32538baddfdSBarry Smith ierr = PetscMalloc((nrows+1)*sizeof(PetscInt),&c->columnsforrow[i]);CHKERRQ(ierr); 326639f9d9dSBarry Smith /* now store the linked list of rows into c->rows[i] */ 327639f9d9dSBarry Smith nrows = 0; 328639f9d9dSBarry Smith fm = rowhit[N]; 329639f9d9dSBarry Smith do { 330639f9d9dSBarry Smith c->rows[i][nrows] = fm; 331639f9d9dSBarry Smith c->columnsforrow[i][nrows++] = columnsforrow[fm]; 332639f9d9dSBarry Smith fm = rowhit[fm]; 333639f9d9dSBarry Smith } while (fm < N); 334639f9d9dSBarry Smith } /* ---------------------------------------------------------------------------------------*/ 335639f9d9dSBarry Smith ierr = ISRestoreIndices(isa[i],&is);CHKERRQ(ierr); 336639f9d9dSBarry Smith } 3373acb8795SBarry Smith ierr = MatRestoreColumnIJ(mat,0,PETSC_FALSE,PETSC_FALSE,&ncols,&ci,&cj,&done);CHKERRQ(ierr); 338639f9d9dSBarry Smith 339606d414cSSatish Balay ierr = PetscFree(rowhit);CHKERRQ(ierr); 340606d414cSSatish Balay ierr = PetscFree(columnsforrow);CHKERRQ(ierr); 341639f9d9dSBarry Smith 34230b34957SBarry Smith /* Optimize by adding the vscale, and scaleforrow[][] fields */ 34330b34957SBarry Smith /* 34430b34957SBarry Smith see the version for MPIAIJ 34530b34957SBarry Smith */ 346ce94432eSBarry Smith ierr = VecCreateGhost(PetscObjectComm((PetscObject)mat),mat->rmap->n,PETSC_DETERMINE,0,NULL,&c->vscale);CHKERRQ(ierr); 34738baddfdSBarry Smith ierr = PetscMalloc(c->ncolors*sizeof(PetscInt*),&c->vscaleforrow);CHKERRQ(ierr); 34830b34957SBarry Smith for (k=0; k<c->ncolors; k++) { 34938baddfdSBarry Smith ierr = PetscMalloc((c->nrows[k]+1)*sizeof(PetscInt),&c->vscaleforrow[k]);CHKERRQ(ierr); 35030b34957SBarry Smith for (l=0; l<c->nrows[k]; l++) { 35130b34957SBarry Smith col = c->columnsforrow[k][l]; 3522205254eSKarl Rupp 35330b34957SBarry Smith c->vscaleforrow[k][l] = col; 35430b34957SBarry Smith } 35530b34957SBarry Smith } 356b9617806SBarry Smith ierr = ISColoringRestoreIS(iscoloring,&isa);CHKERRQ(ierr); 3573a40ed3dSBarry Smith PetscFunctionReturn(0); 35870c3da92SBarry Smith } 359*79c1e64dSHong Zhang 360