1*abe9303eSLisandro Dalcin #include <petsc/private/partitionerimpl.h> /*I "petscpartitioner.h" I*/ 2*abe9303eSLisandro Dalcin 3*abe9303eSLisandro Dalcin /*@C 4*abe9303eSLisandro Dalcin PetscPartitionerSetType - Builds a particular PetscPartitioner 5*abe9303eSLisandro Dalcin 6*abe9303eSLisandro Dalcin Collective on PetscPartitioner 7*abe9303eSLisandro Dalcin 8*abe9303eSLisandro Dalcin Input Parameters: 9*abe9303eSLisandro Dalcin + part - The PetscPartitioner object 10*abe9303eSLisandro Dalcin - name - The kind of partitioner 11*abe9303eSLisandro Dalcin 12*abe9303eSLisandro Dalcin Options Database Key: 13*abe9303eSLisandro Dalcin . -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types 14*abe9303eSLisandro Dalcin 15*abe9303eSLisandro Dalcin Level: intermediate 16*abe9303eSLisandro Dalcin 17*abe9303eSLisandro Dalcin .seealso: PetscPartitionerGetType(), PetscPartitionerCreate() 18*abe9303eSLisandro Dalcin @*/ 19*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetType(PetscPartitioner part, PetscPartitionerType name) 20*abe9303eSLisandro Dalcin { 21*abe9303eSLisandro Dalcin PetscErrorCode (*r)(PetscPartitioner); 22*abe9303eSLisandro Dalcin PetscBool match; 23*abe9303eSLisandro Dalcin PetscErrorCode ierr; 24*abe9303eSLisandro Dalcin 25*abe9303eSLisandro Dalcin PetscFunctionBegin; 26*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 27*abe9303eSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) part, name, &match);CHKERRQ(ierr); 28*abe9303eSLisandro Dalcin if (match) PetscFunctionReturn(0); 29*abe9303eSLisandro Dalcin 30*abe9303eSLisandro Dalcin ierr = PetscPartitionerRegisterAll();CHKERRQ(ierr); 31*abe9303eSLisandro Dalcin ierr = PetscFunctionListFind(PetscPartitionerList, name, &r);CHKERRQ(ierr); 32*abe9303eSLisandro Dalcin if (!r) SETERRQ1(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscPartitioner type: %s", name); 33*abe9303eSLisandro Dalcin 34*abe9303eSLisandro Dalcin if (part->ops->destroy) { 35*abe9303eSLisandro Dalcin ierr = (*part->ops->destroy)(part);CHKERRQ(ierr); 36*abe9303eSLisandro Dalcin } 37*abe9303eSLisandro Dalcin part->noGraph = PETSC_FALSE; 38*abe9303eSLisandro Dalcin ierr = PetscMemzero(part->ops, sizeof(*part->ops));CHKERRQ(ierr); 39*abe9303eSLisandro Dalcin ierr = PetscObjectChangeTypeName((PetscObject) part, name);CHKERRQ(ierr); 40*abe9303eSLisandro Dalcin ierr = (*r)(part);CHKERRQ(ierr); 41*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 42*abe9303eSLisandro Dalcin } 43*abe9303eSLisandro Dalcin 44*abe9303eSLisandro Dalcin /*@C 45*abe9303eSLisandro Dalcin PetscPartitionerGetType - Gets the PetscPartitioner type name (as a string) from the object. 46*abe9303eSLisandro Dalcin 47*abe9303eSLisandro Dalcin Not Collective 48*abe9303eSLisandro Dalcin 49*abe9303eSLisandro Dalcin Input Parameter: 50*abe9303eSLisandro Dalcin . part - The PetscPartitioner 51*abe9303eSLisandro Dalcin 52*abe9303eSLisandro Dalcin Output Parameter: 53*abe9303eSLisandro Dalcin . name - The PetscPartitioner type name 54*abe9303eSLisandro Dalcin 55*abe9303eSLisandro Dalcin Level: intermediate 56*abe9303eSLisandro Dalcin 57*abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetType(), PetscPartitionerCreate() 58*abe9303eSLisandro Dalcin @*/ 59*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerGetType(PetscPartitioner part, PetscPartitionerType *name) 60*abe9303eSLisandro Dalcin { 61*abe9303eSLisandro Dalcin PetscFunctionBegin; 62*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 63*abe9303eSLisandro Dalcin PetscValidPointer(name, 2); 64*abe9303eSLisandro Dalcin *name = ((PetscObject) part)->type_name; 65*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 66*abe9303eSLisandro Dalcin } 67*abe9303eSLisandro Dalcin 68*abe9303eSLisandro Dalcin /*@C 69*abe9303eSLisandro Dalcin PetscPartitionerViewFromOptions - View from Options 70*abe9303eSLisandro Dalcin 71*abe9303eSLisandro Dalcin Collective on PetscPartitioner 72*abe9303eSLisandro Dalcin 73*abe9303eSLisandro Dalcin Input Parameters: 74*abe9303eSLisandro Dalcin + A - the PetscPartitioner object 75*abe9303eSLisandro Dalcin . obj - Optional object 76*abe9303eSLisandro Dalcin - name - command line option 77*abe9303eSLisandro Dalcin 78*abe9303eSLisandro Dalcin Level: intermediate 79*abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscObjectViewFromOptions() 80*abe9303eSLisandro Dalcin @*/ 81*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerViewFromOptions(PetscPartitioner A,PetscObject obj,const char name[]) 82*abe9303eSLisandro Dalcin { 83*abe9303eSLisandro Dalcin PetscErrorCode ierr; 84*abe9303eSLisandro Dalcin 85*abe9303eSLisandro Dalcin PetscFunctionBegin; 86*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(A,PETSCPARTITIONER_CLASSID,1); 87*abe9303eSLisandro Dalcin ierr = PetscObjectViewFromOptions((PetscObject)A,obj,name);CHKERRQ(ierr); 88*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 89*abe9303eSLisandro Dalcin } 90*abe9303eSLisandro Dalcin 91*abe9303eSLisandro Dalcin /*@ 92*abe9303eSLisandro Dalcin PetscPartitionerView - Views a PetscPartitioner 93*abe9303eSLisandro Dalcin 94*abe9303eSLisandro Dalcin Collective on PetscPartitioner 95*abe9303eSLisandro Dalcin 96*abe9303eSLisandro Dalcin Input Parameter: 97*abe9303eSLisandro Dalcin + part - the PetscPartitioner object to view 98*abe9303eSLisandro Dalcin - v - the viewer 99*abe9303eSLisandro Dalcin 100*abe9303eSLisandro Dalcin Level: developer 101*abe9303eSLisandro Dalcin 102*abe9303eSLisandro Dalcin .seealso: PetscPartitionerDestroy() 103*abe9303eSLisandro Dalcin @*/ 104*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerView(PetscPartitioner part, PetscViewer v) 105*abe9303eSLisandro Dalcin { 106*abe9303eSLisandro Dalcin PetscMPIInt size; 107*abe9303eSLisandro Dalcin PetscBool isascii; 108*abe9303eSLisandro Dalcin PetscErrorCode ierr; 109*abe9303eSLisandro Dalcin 110*abe9303eSLisandro Dalcin PetscFunctionBegin; 111*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 112*abe9303eSLisandro Dalcin if (!v) {ierr = PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) part), &v);CHKERRQ(ierr);} 113*abe9303eSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 114*abe9303eSLisandro Dalcin if (isascii) { 115*abe9303eSLisandro Dalcin ierr = MPI_Comm_size(PetscObjectComm((PetscObject) part), &size);CHKERRQ(ierr); 116*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, "Graph Partitioner: %d MPI Process%s\n", size, size > 1 ? "es" : "");CHKERRQ(ierr); 117*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, " type: %s\n", ((PetscObject)part)->type_name);CHKERRQ(ierr); 118*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, " edge cut: %D\n", part->edgeCut);CHKERRQ(ierr); 119*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, " balance: %.2g\n", part->balance);CHKERRQ(ierr); 120*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPrintf(v, " use vertex weights: %d\n", part->usevwgt);CHKERRQ(ierr); 121*abe9303eSLisandro Dalcin } 122*abe9303eSLisandro Dalcin if (part->ops->view) {ierr = (*part->ops->view)(part, v);CHKERRQ(ierr);} 123*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 124*abe9303eSLisandro Dalcin } 125*abe9303eSLisandro Dalcin 126*abe9303eSLisandro Dalcin static PetscErrorCode PetscPartitionerGetDefaultType(MPI_Comm comm, const char *currentType, const char **defaultType) 127*abe9303eSLisandro Dalcin { 128*abe9303eSLisandro Dalcin PetscMPIInt size; 129*abe9303eSLisandro Dalcin PetscErrorCode ierr; 130*abe9303eSLisandro Dalcin 131*abe9303eSLisandro Dalcin PetscFunctionBegin; 132*abe9303eSLisandro Dalcin ierr = MPI_Comm_size(comm, &size);CHKERRQ(ierr); 133*abe9303eSLisandro Dalcin if (!currentType) { 134*abe9303eSLisandro Dalcin if (size == 1) { 135*abe9303eSLisandro Dalcin *defaultType = PETSCPARTITIONERSIMPLE; 136*abe9303eSLisandro Dalcin } else { 137*abe9303eSLisandro Dalcin #if defined(PETSC_HAVE_PARMETIS) 138*abe9303eSLisandro Dalcin *defaultType = PETSCPARTITIONERPARMETIS; 139*abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_PTSCOTCH) 140*abe9303eSLisandro Dalcin *defaultType = PETSCPARTITIONERPTSCOTCH; 141*abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_CHACO) 142*abe9303eSLisandro Dalcin *defaultType = PETSCPARTITIONERCHACO; 143*abe9303eSLisandro Dalcin #else 144*abe9303eSLisandro Dalcin *defaultType = PETSCPARTITIONERSIMPLE; 145*abe9303eSLisandro Dalcin #endif 146*abe9303eSLisandro Dalcin } 147*abe9303eSLisandro Dalcin } else { 148*abe9303eSLisandro Dalcin *defaultType = currentType; 149*abe9303eSLisandro Dalcin } 150*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 151*abe9303eSLisandro Dalcin } 152*abe9303eSLisandro Dalcin 153*abe9303eSLisandro Dalcin /*@ 154*abe9303eSLisandro Dalcin PetscPartitionerSetFromOptions - sets parameters in a PetscPartitioner from the options database 155*abe9303eSLisandro Dalcin 156*abe9303eSLisandro Dalcin Collective on PetscPartitioner 157*abe9303eSLisandro Dalcin 158*abe9303eSLisandro Dalcin Input Parameter: 159*abe9303eSLisandro Dalcin . part - the PetscPartitioner object to set options for 160*abe9303eSLisandro Dalcin 161*abe9303eSLisandro Dalcin Options Database Keys: 162*abe9303eSLisandro Dalcin + -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types 163*abe9303eSLisandro Dalcin . -petscpartitioner_use_vertex_weights - Uses weights associated with the graph vertices 164*abe9303eSLisandro Dalcin - -petscpartitioner_view_graph - View the graph each time PetscPartitionerPartition is called. Viewer can be customized, see PetscOptionsGetViewer() 165*abe9303eSLisandro Dalcin 166*abe9303eSLisandro Dalcin Level: developer 167*abe9303eSLisandro Dalcin 168*abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerSetType(), PetscPartitionerPartition() 169*abe9303eSLisandro Dalcin @*/ 170*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner part) 171*abe9303eSLisandro Dalcin { 172*abe9303eSLisandro Dalcin const char *defaultType; 173*abe9303eSLisandro Dalcin char name[256]; 174*abe9303eSLisandro Dalcin PetscBool flg; 175*abe9303eSLisandro Dalcin PetscErrorCode ierr; 176*abe9303eSLisandro Dalcin 177*abe9303eSLisandro Dalcin PetscFunctionBegin; 178*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 179*abe9303eSLisandro Dalcin ierr = PetscPartitionerGetDefaultType(((PetscObject) part)->comm, ((PetscObject) part)->type_name,&defaultType);CHKERRQ(ierr); 180*abe9303eSLisandro Dalcin ierr = PetscObjectOptionsBegin((PetscObject) part);CHKERRQ(ierr); 181*abe9303eSLisandro Dalcin ierr = PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, defaultType, name, sizeof(name), &flg);CHKERRQ(ierr); 182*abe9303eSLisandro Dalcin if (flg) { 183*abe9303eSLisandro Dalcin ierr = PetscPartitionerSetType(part, name);CHKERRQ(ierr); 184*abe9303eSLisandro Dalcin } else if (!((PetscObject) part)->type_name) { 185*abe9303eSLisandro Dalcin ierr = PetscPartitionerSetType(part, defaultType);CHKERRQ(ierr); 186*abe9303eSLisandro Dalcin } 187*abe9303eSLisandro Dalcin ierr = PetscOptionsBool("-petscpartitioner_use_vertex_weights","Use vertex weights","",part->usevwgt,&part->usevwgt,NULL);CHKERRQ(ierr); 188*abe9303eSLisandro Dalcin if (part->ops->setfromoptions) { 189*abe9303eSLisandro Dalcin ierr = (*part->ops->setfromoptions)(PetscOptionsObject,part);CHKERRQ(ierr); 190*abe9303eSLisandro Dalcin } 191*abe9303eSLisandro Dalcin ierr = PetscViewerDestroy(&part->viewer);CHKERRQ(ierr); 192*abe9303eSLisandro Dalcin ierr = PetscViewerDestroy(&part->viewerGraph);CHKERRQ(ierr); 193*abe9303eSLisandro Dalcin ierr = PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view", &part->viewer, NULL, NULL);CHKERRQ(ierr); 194*abe9303eSLisandro Dalcin ierr = PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view_graph", &part->viewerGraph, NULL, &part->viewGraph);CHKERRQ(ierr); 195*abe9303eSLisandro Dalcin /* process any options handlers added with PetscObjectAddOptionsHandler() */ 196*abe9303eSLisandro Dalcin ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) part);CHKERRQ(ierr); 197*abe9303eSLisandro Dalcin ierr = PetscOptionsEnd();CHKERRQ(ierr); 198*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 199*abe9303eSLisandro Dalcin } 200*abe9303eSLisandro Dalcin 201*abe9303eSLisandro Dalcin /*@ 202*abe9303eSLisandro Dalcin PetscPartitionerSetUp - Construct data structures for the PetscPartitioner 203*abe9303eSLisandro Dalcin 204*abe9303eSLisandro Dalcin Collective on PetscPartitioner 205*abe9303eSLisandro Dalcin 206*abe9303eSLisandro Dalcin Input Parameter: 207*abe9303eSLisandro Dalcin . part - the PetscPartitioner object to setup 208*abe9303eSLisandro Dalcin 209*abe9303eSLisandro Dalcin Level: developer 210*abe9303eSLisandro Dalcin 211*abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerDestroy() 212*abe9303eSLisandro Dalcin @*/ 213*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part) 214*abe9303eSLisandro Dalcin { 215*abe9303eSLisandro Dalcin PetscErrorCode ierr; 216*abe9303eSLisandro Dalcin 217*abe9303eSLisandro Dalcin PetscFunctionBegin; 218*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 219*abe9303eSLisandro Dalcin if (part->ops->setup) {ierr = (*part->ops->setup)(part);CHKERRQ(ierr);} 220*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 221*abe9303eSLisandro Dalcin } 222*abe9303eSLisandro Dalcin 223*abe9303eSLisandro Dalcin /*@ 224*abe9303eSLisandro Dalcin PetscPartitionerReset - Resets data structures for the PetscPartitioner 225*abe9303eSLisandro Dalcin 226*abe9303eSLisandro Dalcin Collective on PetscPartitioner 227*abe9303eSLisandro Dalcin 228*abe9303eSLisandro Dalcin Input Parameter: 229*abe9303eSLisandro Dalcin . part - the PetscPartitioner object to reset 230*abe9303eSLisandro Dalcin 231*abe9303eSLisandro Dalcin Level: developer 232*abe9303eSLisandro Dalcin 233*abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetUp(), PetscPartitionerDestroy() 234*abe9303eSLisandro Dalcin @*/ 235*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerReset(PetscPartitioner part) 236*abe9303eSLisandro Dalcin { 237*abe9303eSLisandro Dalcin PetscErrorCode ierr; 238*abe9303eSLisandro Dalcin 239*abe9303eSLisandro Dalcin PetscFunctionBegin; 240*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 241*abe9303eSLisandro Dalcin if (part->ops->reset) {ierr = (*part->ops->reset)(part);CHKERRQ(ierr);} 242*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 243*abe9303eSLisandro Dalcin } 244*abe9303eSLisandro Dalcin 245*abe9303eSLisandro Dalcin /*@ 246*abe9303eSLisandro Dalcin PetscPartitionerDestroy - Destroys a PetscPartitioner object 247*abe9303eSLisandro Dalcin 248*abe9303eSLisandro Dalcin Collective on PetscPartitioner 249*abe9303eSLisandro Dalcin 250*abe9303eSLisandro Dalcin Input Parameter: 251*abe9303eSLisandro Dalcin . part - the PetscPartitioner object to destroy 252*abe9303eSLisandro Dalcin 253*abe9303eSLisandro Dalcin Level: developer 254*abe9303eSLisandro Dalcin 255*abe9303eSLisandro Dalcin .seealso: PetscPartitionerView() 256*abe9303eSLisandro Dalcin @*/ 257*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part) 258*abe9303eSLisandro Dalcin { 259*abe9303eSLisandro Dalcin PetscErrorCode ierr; 260*abe9303eSLisandro Dalcin 261*abe9303eSLisandro Dalcin PetscFunctionBegin; 262*abe9303eSLisandro Dalcin if (!*part) PetscFunctionReturn(0); 263*abe9303eSLisandro Dalcin PetscValidHeaderSpecific((*part), PETSCPARTITIONER_CLASSID, 1); 264*abe9303eSLisandro Dalcin 265*abe9303eSLisandro Dalcin if (--((PetscObject)(*part))->refct > 0) {*part = 0; PetscFunctionReturn(0);} 266*abe9303eSLisandro Dalcin ((PetscObject) (*part))->refct = 0; 267*abe9303eSLisandro Dalcin 268*abe9303eSLisandro Dalcin ierr = PetscPartitionerReset(*part);CHKERRQ(ierr); 269*abe9303eSLisandro Dalcin 270*abe9303eSLisandro Dalcin ierr = PetscViewerDestroy(&(*part)->viewer);CHKERRQ(ierr); 271*abe9303eSLisandro Dalcin ierr = PetscViewerDestroy(&(*part)->viewerGraph);CHKERRQ(ierr); 272*abe9303eSLisandro Dalcin if ((*part)->ops->destroy) {ierr = (*(*part)->ops->destroy)(*part);CHKERRQ(ierr);} 273*abe9303eSLisandro Dalcin ierr = PetscHeaderDestroy(part);CHKERRQ(ierr); 274*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 275*abe9303eSLisandro Dalcin } 276*abe9303eSLisandro Dalcin 277*abe9303eSLisandro Dalcin /*@ 278*abe9303eSLisandro Dalcin PetscPartitionerPartition - Partition a graph 279*abe9303eSLisandro Dalcin 280*abe9303eSLisandro Dalcin Collective on PetscPartitioner 281*abe9303eSLisandro Dalcin 282*abe9303eSLisandro Dalcin Input Parameters: 283*abe9303eSLisandro Dalcin + part - The PetscPartitioner 284*abe9303eSLisandro Dalcin . nparts - Number of partitions 285*abe9303eSLisandro Dalcin . numVertices - Number of vertices in the local part of the graph 286*abe9303eSLisandro Dalcin . start - row pointers for the local part of the graph (CSR style) 287*abe9303eSLisandro Dalcin . adjacency - adjacency list (CSR style) 288*abe9303eSLisandro Dalcin . vertexSection - PetscSection describing the absolute weight of each local vertex (can be NULL) 289*abe9303eSLisandro Dalcin - targetSection - PetscSection describing the absolute weight of each partition (can be NULL) 290*abe9303eSLisandro Dalcin 291*abe9303eSLisandro Dalcin Output Parameters: 292*abe9303eSLisandro Dalcin + partSection - The PetscSection giving the division of points by partition 293*abe9303eSLisandro Dalcin - partition - The list of points by partition 294*abe9303eSLisandro Dalcin 295*abe9303eSLisandro Dalcin Options Database: 296*abe9303eSLisandro Dalcin + -petscpartitioner_view - View the partitioner information 297*abe9303eSLisandro Dalcin - -petscpartitioner_view_graph - View the graph we are partitioning 298*abe9303eSLisandro Dalcin 299*abe9303eSLisandro Dalcin Notes: 300*abe9303eSLisandro Dalcin The chart of the vertexSection (if present) must contain [0,numVertices), with the number of dofs in the section specifying the absolute weight for each vertex. 301*abe9303eSLisandro Dalcin The chart of the targetSection (if present) must contain [0,nparts), with the number of dofs in the section specifying the absolute weight for each partition. This information must be the same across processes, PETSc does not check it. 302*abe9303eSLisandro Dalcin 303*abe9303eSLisandro Dalcin Level: developer 304*abe9303eSLisandro Dalcin 305*abe9303eSLisandro Dalcin .seealso PetscPartitionerCreate(), PetscSectionCreate(), PetscSectionSetChart(), PetscSectionSetDof() 306*abe9303eSLisandro Dalcin @*/ 307*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertexSection, PetscSection targetSection, PetscSection partSection, IS *partition) 308*abe9303eSLisandro Dalcin { 309*abe9303eSLisandro Dalcin PetscErrorCode ierr; 310*abe9303eSLisandro Dalcin 311*abe9303eSLisandro Dalcin PetscFunctionBegin; 312*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1); 313*abe9303eSLisandro Dalcin PetscValidLogicalCollectiveInt(part, nparts, 2); 314*abe9303eSLisandro Dalcin if (nparts <= 0) SETERRQ(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_OUTOFRANGE, "Number of parts must be positive"); 315*abe9303eSLisandro Dalcin if (numVertices < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices must be non-negative"); 316*abe9303eSLisandro Dalcin if (numVertices && !part->noGraph) { 317*abe9303eSLisandro Dalcin PetscValidIntPointer(start, 4); 318*abe9303eSLisandro Dalcin PetscValidIntPointer(start + numVertices, 4); 319*abe9303eSLisandro Dalcin if (start[numVertices]) PetscValidIntPointer(adjacency, 5); 320*abe9303eSLisandro Dalcin } 321*abe9303eSLisandro Dalcin if (vertexSection) { 322*abe9303eSLisandro Dalcin PetscInt s,e; 323*abe9303eSLisandro Dalcin 324*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(vertexSection, PETSC_SECTION_CLASSID, 6); 325*abe9303eSLisandro Dalcin ierr = PetscSectionGetChart(vertexSection, &s, &e);CHKERRQ(ierr); 326*abe9303eSLisandro Dalcin if (s > 0 || e < numVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid vertexSection chart [%D,%D)",s,e); 327*abe9303eSLisandro Dalcin } 328*abe9303eSLisandro Dalcin if (targetSection) { 329*abe9303eSLisandro Dalcin PetscInt s,e; 330*abe9303eSLisandro Dalcin 331*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(targetSection, PETSC_SECTION_CLASSID, 7); 332*abe9303eSLisandro Dalcin ierr = PetscSectionGetChart(targetSection, &s, &e);CHKERRQ(ierr); 333*abe9303eSLisandro Dalcin if (s > 0 || e < nparts) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid targetSection chart [%D,%D)",s,e); 334*abe9303eSLisandro Dalcin } 335*abe9303eSLisandro Dalcin PetscValidHeaderSpecific(partSection, PETSC_SECTION_CLASSID, 8); 336*abe9303eSLisandro Dalcin PetscValidPointer(partition, 9); 337*abe9303eSLisandro Dalcin 338*abe9303eSLisandro Dalcin ierr = PetscSectionReset(partSection);CHKERRQ(ierr); 339*abe9303eSLisandro Dalcin ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr); 340*abe9303eSLisandro Dalcin if (nparts == 1) { /* quick */ 341*abe9303eSLisandro Dalcin ierr = PetscSectionSetDof(partSection, 0, numVertices);CHKERRQ(ierr); 342*abe9303eSLisandro Dalcin ierr = ISCreateStride(PetscObjectComm((PetscObject)part),numVertices,0,1,partition);CHKERRQ(ierr); 343*abe9303eSLisandro Dalcin } else { 344*abe9303eSLisandro Dalcin if (!part->ops->partition) SETERRQ1(PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "PetscPartitioner %s has no partitioning method", ((PetscObject)part)->type_name); 345*abe9303eSLisandro Dalcin ierr = (*part->ops->partition)(part, nparts, numVertices, start, adjacency, vertexSection, targetSection, partSection, partition);CHKERRQ(ierr); 346*abe9303eSLisandro Dalcin } 347*abe9303eSLisandro Dalcin ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr); 348*abe9303eSLisandro Dalcin if (part->viewerGraph) { 349*abe9303eSLisandro Dalcin PetscViewer viewer = part->viewerGraph; 350*abe9303eSLisandro Dalcin PetscBool isascii; 351*abe9303eSLisandro Dalcin PetscInt v, i; 352*abe9303eSLisandro Dalcin PetscMPIInt rank; 353*abe9303eSLisandro Dalcin 354*abe9303eSLisandro Dalcin ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank);CHKERRQ(ierr); 355*abe9303eSLisandro Dalcin ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr); 356*abe9303eSLisandro Dalcin if (isascii) { 357*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr); 358*abe9303eSLisandro Dalcin ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %D\n", rank, numVertices);CHKERRQ(ierr); 359*abe9303eSLisandro Dalcin for (v = 0; v < numVertices; ++v) { 360*abe9303eSLisandro Dalcin const PetscInt s = start[v]; 361*abe9303eSLisandro Dalcin const PetscInt e = start[v+1]; 362*abe9303eSLisandro Dalcin 363*abe9303eSLisandro Dalcin ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d] ", rank);CHKERRQ(ierr); 364*abe9303eSLisandro Dalcin for (i = s; i < e; ++i) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%D ", adjacency[i]);CHKERRQ(ierr);} 365*abe9303eSLisandro Dalcin ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%D-%D)\n", s, e);CHKERRQ(ierr); 366*abe9303eSLisandro Dalcin } 367*abe9303eSLisandro Dalcin ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 368*abe9303eSLisandro Dalcin ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr); 369*abe9303eSLisandro Dalcin } 370*abe9303eSLisandro Dalcin } 371*abe9303eSLisandro Dalcin if (part->viewer) { 372*abe9303eSLisandro Dalcin ierr = PetscPartitionerView(part,part->viewer);CHKERRQ(ierr); 373*abe9303eSLisandro Dalcin } 374*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 375*abe9303eSLisandro Dalcin } 376*abe9303eSLisandro Dalcin 377*abe9303eSLisandro Dalcin /*@ 378*abe9303eSLisandro Dalcin PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType(). 379*abe9303eSLisandro Dalcin 380*abe9303eSLisandro Dalcin Collective 381*abe9303eSLisandro Dalcin 382*abe9303eSLisandro Dalcin Input Parameter: 383*abe9303eSLisandro Dalcin . comm - The communicator for the PetscPartitioner object 384*abe9303eSLisandro Dalcin 385*abe9303eSLisandro Dalcin Output Parameter: 386*abe9303eSLisandro Dalcin . part - The PetscPartitioner object 387*abe9303eSLisandro Dalcin 388*abe9303eSLisandro Dalcin Level: beginner 389*abe9303eSLisandro Dalcin 390*abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetType(), PETSCPARTITIONERCHACO, PETSCPARTITIONERPARMETIS, PETSCPARTITIONERSHELL, PETSCPARTITIONERSIMPLE, PETSCPARTITIONERGATHER 391*abe9303eSLisandro Dalcin @*/ 392*abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part) 393*abe9303eSLisandro Dalcin { 394*abe9303eSLisandro Dalcin PetscPartitioner p; 395*abe9303eSLisandro Dalcin const char *partitionerType = NULL; 396*abe9303eSLisandro Dalcin PetscErrorCode ierr; 397*abe9303eSLisandro Dalcin 398*abe9303eSLisandro Dalcin PetscFunctionBegin; 399*abe9303eSLisandro Dalcin PetscValidPointer(part, 2); 400*abe9303eSLisandro Dalcin *part = NULL; 401*abe9303eSLisandro Dalcin ierr = PetscPartitionerInitializePackage();CHKERRQ(ierr); 402*abe9303eSLisandro Dalcin 403*abe9303eSLisandro Dalcin ierr = PetscHeaderCreate(p, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView);CHKERRQ(ierr); 404*abe9303eSLisandro Dalcin ierr = PetscPartitionerGetDefaultType(comm, NULL, &partitionerType);CHKERRQ(ierr); 405*abe9303eSLisandro Dalcin ierr = PetscPartitionerSetType(p,partitionerType);CHKERRQ(ierr); 406*abe9303eSLisandro Dalcin 407*abe9303eSLisandro Dalcin p->edgeCut = 0; 408*abe9303eSLisandro Dalcin p->balance = 0.0; 409*abe9303eSLisandro Dalcin p->usevwgt = PETSC_TRUE; 410*abe9303eSLisandro Dalcin 411*abe9303eSLisandro Dalcin *part = p; 412*abe9303eSLisandro Dalcin PetscFunctionReturn(0); 413*abe9303eSLisandro Dalcin } 414*abe9303eSLisandro Dalcin 415