PetscErrorCode DMCreateColoring_Composite(DM dm,ISColoringType ctype,MatType mtype,ISColoring *coloring) { PetscErrorCode ierr; PetscInt n,i,cnt; ISColoringValue *colors; PetscBool dense = PETSC_FALSE; ISColoringValue maxcol = 0; DM_Composite *com = (DM_Composite*)dm->data; PetscFunctionBegin; PetscValidHeaderSpecific(dm,DM_CLASSID,1); if (ctype == IS_COLORING_GHOSTED) SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_SUP,"Only global coloring supported" ); else if (ctype == IS_COLORING_GLOBAL) { n = com->n; } else SETERRQ(((PetscObject)dm)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Unknown ISColoringType"); ierr = PetscMalloc(n*sizeof(ISColoringValue),&colors);CHKERRQ(ierr); /* freed in ISColoringDestroy() */ ierr = PetscOptionsGetBool(PETSC_NULL,"-dmcomposite_dense_jacobian",&dense,PETSC_NULL);CHKERRQ(ierr); if (dense) { for (i=0; i<n; i++) { colors[i] = (ISColoringValue)(com->rstart + i); } maxcol = com->N; } else { struct DMCompositeLink *next = com->next; PetscMPIInt rank; ierr = MPI_Comm_rank(((PetscObject)dm)->comm,&rank);CHKERRQ(ierr); cnt = 0; while (next) { ISColoring lcoloring; ierr = DMCreateColoring(next->dm,IS_COLORING_GLOBAL,mtype,&lcoloring);CHKERRQ(ierr); for (i=0; i<lcoloring->N; i++) { colors[cnt++] = maxcol + lcoloring->colors[i]; } maxcol += lcoloring->n; ierr = ISColoringDestroy(&lcoloring);CHKERRQ(ierr); next = next->next; } } ierr = ISColoringCreate(((PetscObject)dm)->comm,maxcol,n,colors,coloring);CHKERRQ(ierr); PetscFunctionReturn(0); }
static PetscErrorCode MatColoringApply_Greedy(MatColoring mc,ISColoring *iscoloring) { PetscErrorCode ierr; PetscInt finalcolor,finalcolor_global; ISColoringValue *colors; PetscInt ncolstotal,ncols; PetscReal *wts; PetscInt i,*lperm; PetscFunctionBegin; ierr = MatGetSize(mc->mat,NULL,&ncolstotal);CHKERRQ(ierr); ierr = MatGetLocalSize(mc->mat,NULL,&ncols);CHKERRQ(ierr); if (!mc->user_weights) { ierr = MatColoringCreateWeights(mc,&wts,&lperm);CHKERRQ(ierr); } else { wts = mc->user_weights; lperm = mc->user_lperm; } ierr = PetscMalloc1(ncols,&colors);CHKERRQ(ierr); if (mc->dist == 1) { ierr = GreedyColoringLocalDistanceOne_Private(mc,wts,lperm,colors);CHKERRQ(ierr); } else if (mc->dist == 2) { ierr = GreedyColoringLocalDistanceTwo_Private(mc,wts,lperm,colors);CHKERRQ(ierr); } else SETERRQ(PetscObjectComm((PetscObject)mc),PETSC_ERR_ARG_OUTOFRANGE,"Only distance 1 and distance 2 supported by MatColoringGreedy"); finalcolor=0; for (i=0;i<ncols;i++) { if (colors[i] > finalcolor) finalcolor=colors[i]; } finalcolor_global=0; ierr = MPIU_Allreduce(&finalcolor,&finalcolor_global,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)mc));CHKERRQ(ierr); ierr = PetscLogEventBegin(MATCOLORING_ISCreate,mc,0,0,0);CHKERRQ(ierr); ierr = ISColoringCreate(PetscObjectComm((PetscObject)mc),finalcolor_global+1,ncols,colors,PETSC_OWN_POINTER,iscoloring);CHKERRQ(ierr); ierr = PetscLogEventEnd(MATCOLORING_ISCreate,mc,0,0,0);CHKERRQ(ierr); if (!mc->user_weights) { ierr = PetscFree(wts);CHKERRQ(ierr); ierr = PetscFree(lperm);CHKERRQ(ierr); } PetscFunctionReturn(0); }
static PetscErrorCode DMCreateColoring_Redundant(DM dm,ISColoringType ctype,ISColoring *coloring) { DM_Redundant *red = (DM_Redundant*)dm->data; PetscErrorCode ierr; PetscInt i,nloc; ISColoringValue *colors; PetscFunctionBegin; switch (ctype) { case IS_COLORING_GLOBAL: nloc = red->n; break; case IS_COLORING_GHOSTED: nloc = red->N; break; default: SETERRQ1(PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONG,"Unknown ISColoringType %d",(int)ctype); } ierr = PetscMalloc1(nloc,&colors);CHKERRQ(ierr); for (i=0; i<nloc; i++) colors[i] = i; ierr = ISColoringCreate(PetscObjectComm((PetscObject)dm),red->N,nloc,colors,coloring);CHKERRQ(ierr); ierr = ISColoringSetType(*coloring,ctype);CHKERRQ(ierr); PetscFunctionReturn(0); }
EXTERN_C_BEGIN /* ----------------------------------------------------------------------------*/ /* MatGetColoring_SL_Minpack - Uses the smallest-last (SL) coloring of minpack */ #undef __FUNCT__ #define __FUNCT__ "MatGetColoring_SL_Minpack" PetscErrorCode MatGetColoring_SL_Minpack(Mat mat,MatColoringType name,ISColoring *iscoloring) { PetscErrorCode ierr; PetscInt *list,*work,clique,*seq,*coloring,n; const PetscInt *ria,*rja,*cia,*cja; PetscInt ncolors,i; PetscBool done; Mat mat_seq = mat; PetscMPIInt size; MPI_Comm comm; ISColoring iscoloring_seq; PetscInt bs = 1,rstart,rend,N_loc,nc; ISColoringValue *colors_loc; PetscBool flg1,flg2; PetscFunctionBegin; /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); } ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); if (size > 1){ /* create a sequential iscoloring on all processors */ ierr = MatGetSeqNonzeroStructure(mat,&mat_seq);CHKERRQ(ierr); } ierr = MatGetRowIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&ria,&rja,&done);CHKERRQ(ierr); ierr = MatGetColumnIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&cia,&cja,&done);CHKERRQ(ierr); if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Ordering requires IJ"); ierr = MatFDColoringDegreeSequence_Minpack(n,cja,cia,rja,ria,&seq);CHKERRQ(ierr); ierr = PetscMalloc2(n,PetscInt,&list,4*n,PetscInt,&work);CHKERRQ(ierr); MINPACKslo(&n,cja,cia,rja,ria,seq,list,&clique,work,work+n,work+2*n,work+3*n); ierr = PetscMalloc(n*sizeof(PetscInt),&coloring);CHKERRQ(ierr); MINPACKseq(&n,cja,cia,rja,ria,list,coloring,&ncolors,work); ierr = PetscFree2(list,work);CHKERRQ(ierr); ierr = PetscFree(seq);CHKERRQ(ierr); ierr = MatRestoreRowIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&ria,&rja,&done);CHKERRQ(ierr); ierr = MatRestoreColumnIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&cia,&cja,&done);CHKERRQ(ierr); /* shift coloring numbers to start at zero and shorten */ if (ncolors > IS_COLORING_MAX-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Maximum color size exceeded"); { ISColoringValue *s = (ISColoringValue*) coloring; for (i=0; i<n; i++) { s[i] = (ISColoringValue) (coloring[i]-1); } ierr = MatColoringPatch(mat_seq,ncolors,n,s,iscoloring);CHKERRQ(ierr); } if (size > 1) { ierr = MatDestroySeqNonzeroStructure(&mat_seq);CHKERRQ(ierr); /* convert iscoloring_seq to a parallel iscoloring */ iscoloring_seq = *iscoloring; rstart = mat->rmap->rstart/bs; rend = mat->rmap->rend/bs; N_loc = rend - rstart; /* number of local nodes */ /* get local colors for each local node */ ierr = PetscMalloc((N_loc+1)*sizeof(ISColoringValue),&colors_loc);CHKERRQ(ierr); for (i=rstart; i<rend; i++){ colors_loc[i-rstart] = iscoloring_seq->colors[i]; } /* create a parallel iscoloring */ nc=iscoloring_seq->n; ierr = ISColoringCreate(comm,nc,N_loc,colors_loc,iscoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring_seq);CHKERRQ(ierr); } PetscFunctionReturn(0); }
EXTERN_C_END EXTERN_C_BEGIN /* Simplest coloring, each column of the matrix gets its own unique color. */ #undef __FUNCT__ #define __FUNCT__ "MatGetColoring_Natural" PetscErrorCode MatGetColoring_Natural(Mat mat,MatColoringType color, ISColoring *iscoloring) { PetscErrorCode ierr; PetscInt start,end,i,bs = 1,n; ISColoringValue *colors; MPI_Comm comm; PetscBool flg1,flg2; Mat mat_seq = mat; PetscMPIInt size; ISColoring iscoloring_seq; ISColoringValue *colors_loc; PetscInt rstart,rend,N_loc,nc; PetscFunctionBegin; /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); } ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); if (size > 1){ /* create a sequential iscoloring on all processors */ ierr = MatGetSeqNonzeroStructure(mat,&mat_seq);CHKERRQ(ierr); } ierr = MatGetSize(mat_seq,PETSC_NULL,&n);CHKERRQ(ierr); ierr = MatGetOwnershipRange(mat_seq,&start,&end);CHKERRQ(ierr); n = n/bs; if (n > IS_COLORING_MAX-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Maximum color size exceeded"); start = start/bs; end = end/bs; ierr = PetscMalloc((end-start+1)*sizeof(PetscInt),&colors);CHKERRQ(ierr); for (i=start; i<end; i++) { colors[i-start] = (ISColoringValue)i; } ierr = ISColoringCreate(comm,n,end-start,colors,iscoloring);CHKERRQ(ierr); if (size > 1) { ierr = MatDestroySeqNonzeroStructure(&mat_seq);CHKERRQ(ierr); /* convert iscoloring_seq to a parallel iscoloring */ iscoloring_seq = *iscoloring; rstart = mat->rmap->rstart/bs; rend = mat->rmap->rend/bs; N_loc = rend - rstart; /* number of local nodes */ /* get local colors for each local node */ ierr = PetscMalloc((N_loc+1)*sizeof(ISColoringValue),&colors_loc);CHKERRQ(ierr); for (i=rstart; i<rend; i++){ colors_loc[i-rstart] = iscoloring_seq->colors[i]; } /* create a parallel iscoloring */ nc=iscoloring_seq->n; ierr = ISColoringCreate(comm,nc,N_loc,colors_loc,iscoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring_seq);CHKERRQ(ierr); } PetscFunctionReturn(0); }
PETSC_EXTERN PetscErrorCode MatColoringApply_LF(MatColoring mc,ISColoring *iscoloring) { PetscErrorCode ierr; PetscInt *list,*work,*seq,*coloring,n; const PetscInt *ria,*rja,*cia,*cja; PetscInt n1, none,ncolors,i; PetscBool done; Mat mat = mc->mat; Mat mat_seq = mat; PetscMPIInt size; MPI_Comm comm; ISColoring iscoloring_seq; PetscInt bs = 1,rstart,rend,N_loc,nc; ISColoringValue *colors_loc; PetscBool flg1,flg2; PetscFunctionBegin; if (mc->dist != 2) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LF may only do distance 2 coloring"); /* this is ugly way to get blocksize but cannot call MatGetBlockSize() because AIJ can have bs > 1 */ ierr = PetscObjectTypeCompare((PetscObject)mat,MATSEQBAIJ,&flg1);CHKERRQ(ierr); ierr = PetscObjectTypeCompare((PetscObject)mat,MATMPIBAIJ,&flg2);CHKERRQ(ierr); if (flg1 || flg2) { ierr = MatGetBlockSize(mat,&bs);CHKERRQ(ierr); } ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); if (size > 1) { /* create a sequential iscoloring on all processors */ ierr = MatGetSeqNonzeroStructure(mat,&mat_seq);CHKERRQ(ierr); } ierr = MatGetRowIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&ria,&rja,&done);CHKERRQ(ierr); ierr = MatGetColumnIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,&n,&cia,&cja,&done);CHKERRQ(ierr); if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Ordering requires IJ"); ierr = MatFDColoringDegreeSequence_Minpack(n,cja,cia,rja,ria,&seq);CHKERRQ(ierr); ierr = PetscMalloc2(n,&list,4*n,&work);CHKERRQ(ierr); n1 = n - 1; none = -1; MINPACKnumsrt(&n,&n1,seq,&none,list,work+2*n,work+n); ierr = PetscMalloc1(n,&coloring);CHKERRQ(ierr); MINPACKseq(&n,cja,cia,rja,ria,list,coloring,&ncolors,work); ierr = PetscFree2(list,work);CHKERRQ(ierr); ierr = PetscFree(seq);CHKERRQ(ierr); ierr = MatRestoreRowIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,NULL,&ria,&rja,&done);CHKERRQ(ierr); ierr = MatRestoreColumnIJ(mat_seq,1,PETSC_FALSE,PETSC_TRUE,NULL,&cia,&cja,&done);CHKERRQ(ierr); /* shift coloring numbers to start at zero and shorten */ if (ncolors > IS_COLORING_MAX-1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Maximum color size exceeded"); { ISColoringValue *s = (ISColoringValue*) coloring; for (i=0; i<n; i++) s[i] = (ISColoringValue) (coloring[i]-1); ierr = MatColoringPatch(mat_seq,ncolors,n,s,iscoloring);CHKERRQ(ierr); } if (size > 1) { ierr = MatDestroySeqNonzeroStructure(&mat_seq);CHKERRQ(ierr); /* convert iscoloring_seq to a parallel iscoloring */ iscoloring_seq = *iscoloring; rstart = mat->rmap->rstart/bs; rend = mat->rmap->rend/bs; N_loc = rend - rstart; /* number of local nodes */ /* get local colors for each local node */ ierr = PetscMalloc1((N_loc+1),&colors_loc);CHKERRQ(ierr); for (i=rstart; i<rend; i++) colors_loc[i-rstart] = iscoloring_seq->colors[i]; /* create a parallel iscoloring */ nc = iscoloring_seq->n; ierr = ISColoringCreate(comm,nc,N_loc,colors_loc,iscoloring);CHKERRQ(ierr); ierr = ISColoringDestroy(&iscoloring_seq);CHKERRQ(ierr); } PetscFunctionReturn(0); }