#define PETSCVEC_DLL #include "petscsys.h" /*I "petscsys.h" I*/ #include "petscis.h" /*I "petscis.h" I*/ const char *ISColoringTypes[] = {"global","ghosted","ISColoringType","IS_COLORING_",0}; #undef __FUNCT__ #define __FUNCT__ "ISColoringDestroy" /*@ ISColoringDestroy - Destroys a coloring context. Collective on ISColoring Input Parameter: . iscoloring - the coloring context Level: advanced .seealso: ISColoringView(), MatGetColoring() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISColoringDestroy(ISColoring iscoloring) { PetscInt i; PetscErrorCode ierr; PetscFunctionBegin; PetscValidPointer(iscoloring,1); if (--iscoloring->refct > 0) PetscFunctionReturn(0); if (iscoloring->is) { for (i=0; in; i++) { ierr = ISDestroy(iscoloring->is[i]);CHKERRQ(ierr); } ierr = PetscFree(iscoloring->is);CHKERRQ(ierr); } ierr = PetscFree(iscoloring->colors);CHKERRQ(ierr); PetscCommDestroy(&iscoloring->comm); ierr = PetscFree(iscoloring);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "ISColoringView" /*@C ISColoringView - Views a coloring context. Collective on ISColoring Input Parameters: + iscoloring - the coloring context - viewer - the viewer Level: advanced .seealso: ISColoringDestroy(), ISColoringGetIS(), MatGetColoring() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISColoringView(ISColoring iscoloring,PetscViewer viewer) { PetscInt i; PetscErrorCode ierr; PetscTruth iascii; IS *is; PetscFunctionBegin; PetscValidPointer(iscoloring,1); if (!viewer) { ierr = PetscViewerASCIIGetStdout(iscoloring->comm,&viewer);CHKERRQ(ierr); } PetscValidHeaderSpecific(viewer,PETSC_VIEWER_COOKIE,2); ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr); if (iascii) { MPI_Comm comm; PetscMPIInt rank; ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); ierr = PetscViewerASCIISynchronizedPrintf(viewer,"[%d] Number of colors %d\n",rank,iscoloring->n);CHKERRQ(ierr); ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); } else { SETERRQ1(PETSC_ERR_SUP,"Viewer type %s not supported for ISColoring",((PetscObject)viewer)->type_name); } ierr = ISColoringGetIS(iscoloring,PETSC_IGNORE,&is);CHKERRQ(ierr); for (i=0; in; i++) { ierr = ISView(iscoloring->is[i],viewer);CHKERRQ(ierr); } ierr = ISColoringRestoreIS(iscoloring,&is);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "ISColoringGetIS" /*@C ISColoringGetIS - Extracts index sets from the coloring context Collective on ISColoring Input Parameter: . iscoloring - the coloring context Output Parameters: + nn - number of index sets in the coloring context - is - array of index sets Level: advanced .seealso: ISColoringRestoreIS(), ISColoringView() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISColoringGetIS(ISColoring iscoloring,PetscInt *nn,IS *isis[]) { PetscErrorCode ierr; PetscFunctionBegin; PetscValidPointer(iscoloring,1); if (nn) *nn = iscoloring->n; if (isis) { if (!iscoloring->is) { PetscInt *mcolors,**ii,nc = iscoloring->n,i,base, n = iscoloring->N; ISColoringValue *colors = iscoloring->colors; IS *is; #if defined(PETSC_USE_DEBUG) for (i=0; i= nc) { SETERRQ3(PETSC_ERR_ARG_OUTOFRANGE,"Coloring is our of range index %d value %d number colors %d",(int)i,(int)colors[i],(int)nc); } } #endif /* generate the lists of nodes for each color */ ierr = PetscMalloc(nc*sizeof(PetscInt),&mcolors);CHKERRQ(ierr); ierr = PetscMemzero(mcolors,nc*sizeof(PetscInt));CHKERRQ(ierr); for (i=0; ictype == IS_COLORING_GLOBAL){ ierr = MPI_Scan(&iscoloring->N,&base,1,MPIU_INT,MPI_SUM,iscoloring->comm);CHKERRQ(ierr); base -= iscoloring->N; for (i=0; ictype == IS_COLORING_GHOSTED){ for (i=0; icomm,mcolors[i],ii[i],is+i);CHKERRQ(ierr); } iscoloring->is = is; ierr = PetscFree(ii[0]);CHKERRQ(ierr); ierr = PetscFree(ii);CHKERRQ(ierr); ierr = PetscFree(mcolors);CHKERRQ(ierr); } *isis = iscoloring->is; } PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "ISColoringRestoreIS" /*@C ISColoringRestoreIS - Restores the index sets extracted from the coloring context Collective on ISColoring Input Parameter: + iscoloring - the coloring context - is - array of index sets Level: advanced .seealso: ISColoringGetIS(), ISColoringView() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISColoringRestoreIS(ISColoring iscoloring,IS *is[]) { PetscFunctionBegin; PetscValidPointer(iscoloring,1); /* currently nothing is done here */ PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "ISColoringCreate" /*@C ISColoringCreate - Generates an ISColoring context from lists (provided by each processor) of colors for each node. Collective on MPI_Comm Input Parameters: + comm - communicator for the processors creating the coloring . ncolors - max color value . n - number of nodes on this processor - colors - array containing the colors for this processor, color numbers begin at 0. In C/C++ this array must have been obtained with PetscMalloc() and should NOT be freed (The ISColoringDestroy() will free it). Output Parameter: . iscoloring - the resulting coloring data structure Options Database Key: . -is_coloring_view - Activates ISColoringView() Level: advanced Notes: By default sets coloring type to IS_COLORING_GLOBAL .seealso: MatColoringCreate(), ISColoringView(), ISColoringDestroy(), ISColoringSetType() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISColoringCreate(MPI_Comm comm,PetscInt ncolors,PetscInt n,const ISColoringValue colors[],ISColoring *iscoloring) { PetscErrorCode ierr; PetscMPIInt size,rank,tag; PetscInt base,top,i; PetscInt nc,ncwork; PetscTruth flg; MPI_Status status; PetscFunctionBegin; if (ncolors != PETSC_DECIDE && ncolors > IS_COLORING_MAX) { if (ncolors > 65535) { SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Max color value exeeds 65535 limit. This number is unrealistic. Perhaps a bug in code?\nCurrent max: %d user rewuested: %d",IS_COLORING_MAX,ncolors); } else { SETERRQ2(PETSC_ERR_ARG_OUTOFRANGE,"Max color value exeeds limit. Perhaps reconfigure PETSc with --with-is-color-value-type=short?\n Current max: %d user rewuested: %d",IS_COLORING_MAX,ncolors); } } ierr = PetscNew(struct _n_ISColoring,iscoloring);CHKERRQ(ierr); ierr = PetscCommDuplicate(comm,&(*iscoloring)->comm,&tag);CHKERRQ(ierr); comm = (*iscoloring)->comm; /* compute the number of the first node on my processor */ ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); /* should use MPI_Scan() */ ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); if (!rank) { base = 0; top = n; } else { ierr = MPI_Recv(&base,1,MPIU_INT,rank-1,tag,comm,&status);CHKERRQ(ierr); top = base+n; } if (rank < size-1) { ierr = MPI_Send(&top,1,MPIU_INT,rank+1,tag,comm);CHKERRQ(ierr); } /* compute the total number of colors */ ncwork = 0; for (i=0; i ncolors) SETERRQ2(PETSC_ERR_ARG_INCOMP,"Number of colors passed in %D is less then the actual number of colors in array %D",ncolors,nc); (*iscoloring)->n = nc; (*iscoloring)->is = 0; (*iscoloring)->colors = (ISColoringValue *)colors; (*iscoloring)->N = n; (*iscoloring)->refct = 1; (*iscoloring)->ctype = IS_COLORING_GLOBAL; ierr = PetscOptionsHasName(PETSC_NULL,"-is_coloring_view",&flg);CHKERRQ(ierr); if (flg) { PetscViewer viewer; ierr = PetscViewerASCIIGetStdout((*iscoloring)->comm,&viewer);CHKERRQ(ierr); ierr = ISColoringView(*iscoloring,viewer);CHKERRQ(ierr); } ierr = PetscInfo1(0,"Number of colors %d\n",nc);CHKERRQ(ierr); PetscFunctionReturn(0); } #undef __FUNCT__ #define __FUNCT__ "ISPartitioningToNumbering" /*@ ISPartitioningToNumbering - Takes an ISPartitioning and on each processor generates an IS that contains a new global node number for each index based on the partitioing. Collective on IS Input Parameters . partitioning - a partitioning as generated by MatPartitioningApply() Output Parameter: . is - on each processor the index set that defines the global numbers (in the new numbering) for all the nodes currently (before the partitioning) on that processor Level: advanced .seealso: MatPartitioningCreate(), AOCreateBasic(), ISPartitioningCount() @*/ PetscErrorCode PETSCVEC_DLLEXPORT ISPartitioningToNumbering(IS part,IS *is) { MPI_Comm comm; PetscInt i,*indices = PETSC_NULL,np,npt,n,*starts = PETSC_NULL,*sums = PETSC_NULL,*lsizes = PETSC_NULL,*newi = PETSC_NULL; PetscErrorCode ierr; PetscFunctionBegin; ierr = PetscObjectGetComm((PetscObject)part,&comm);CHKERRQ(ierr); /* count the number of partitions, i.e., virtual processors */ ierr = ISGetLocalSize(part,&n);CHKERRQ(ierr); ierr = ISGetIndices(part,&indices);CHKERRQ(ierr); np = 0; for (i=0; i