xref: /petsc/src/dm/partitioner/interface/partitioner.c (revision 1dca8a0504492127e77eac64bc165d7372dd6d63)
1abe9303eSLisandro Dalcin #include <petsc/private/partitionerimpl.h>        /*I "petscpartitioner.h" I*/
2abe9303eSLisandro Dalcin 
3abe9303eSLisandro Dalcin /*@C
4abe9303eSLisandro Dalcin   PetscPartitionerSetType - Builds a particular PetscPartitioner
5abe9303eSLisandro Dalcin 
6abe9303eSLisandro Dalcin   Collective on PetscPartitioner
7abe9303eSLisandro Dalcin 
8abe9303eSLisandro Dalcin   Input Parameters:
9abe9303eSLisandro Dalcin + part - The PetscPartitioner object
10abe9303eSLisandro Dalcin - name - The kind of partitioner
11abe9303eSLisandro Dalcin 
12abe9303eSLisandro Dalcin   Options Database Key:
13abe9303eSLisandro Dalcin . -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types
14abe9303eSLisandro Dalcin 
156e0dc72eSMatthew G. Knepley   Note:
166e0dc72eSMatthew G. Knepley $ PETSCPARTITIONERCHACO    - The Chaco partitioner (--download-chaco)
176e0dc72eSMatthew G. Knepley $ PETSCPARTITIONERPARMETIS - The ParMetis partitioner (--download-parmetis)
186e0dc72eSMatthew G. Knepley $ PETSCPARTITIONERSHELL    - A shell partitioner implemented by the user
196e0dc72eSMatthew G. Knepley $ PETSCPARTITIONERSIMPLE   - A simple partitioner that divides cells into equal, contiguous chunks
206e0dc72eSMatthew G. Knepley $ PETSCPARTITIONERGATHER   - Gathers all cells onto process 0
216e0dc72eSMatthew G. Knepley 
22abe9303eSLisandro Dalcin   Level: intermediate
23abe9303eSLisandro Dalcin 
24abe9303eSLisandro Dalcin .seealso: PetscPartitionerGetType(), PetscPartitionerCreate()
25abe9303eSLisandro Dalcin @*/
26abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetType(PetscPartitioner part, PetscPartitionerType name)
27abe9303eSLisandro Dalcin {
28abe9303eSLisandro Dalcin   PetscErrorCode (*r)(PetscPartitioner);
29abe9303eSLisandro Dalcin   PetscBool      match;
30abe9303eSLisandro Dalcin 
31abe9303eSLisandro Dalcin   PetscFunctionBegin;
32abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) part, name, &match));
34abe9303eSLisandro Dalcin   if (match) PetscFunctionReturn(0);
35abe9303eSLisandro Dalcin 
369566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerRegisterAll());
379566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PetscPartitionerList, name, &r));
3828b400f6SJacob Faibussowitsch   PetscCheck(r,PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unknown PetscPartitioner type: %s", name);
39abe9303eSLisandro Dalcin 
40abe9303eSLisandro Dalcin   if (part->ops->destroy) {
419566063dSJacob Faibussowitsch     PetscCall((*part->ops->destroy)(part));
42abe9303eSLisandro Dalcin   }
43abe9303eSLisandro Dalcin   part->noGraph = PETSC_FALSE;
449566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(part->ops, sizeof(*part->ops)));
459566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject) part, name));
469566063dSJacob Faibussowitsch   PetscCall((*r)(part));
47abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
48abe9303eSLisandro Dalcin }
49abe9303eSLisandro Dalcin 
50abe9303eSLisandro Dalcin /*@C
51abe9303eSLisandro Dalcin   PetscPartitionerGetType - Gets the PetscPartitioner type name (as a string) from the object.
52abe9303eSLisandro Dalcin 
53abe9303eSLisandro Dalcin   Not Collective
54abe9303eSLisandro Dalcin 
55abe9303eSLisandro Dalcin   Input Parameter:
56abe9303eSLisandro Dalcin . part - The PetscPartitioner
57abe9303eSLisandro Dalcin 
58abe9303eSLisandro Dalcin   Output Parameter:
59abe9303eSLisandro Dalcin . name - The PetscPartitioner type name
60abe9303eSLisandro Dalcin 
61abe9303eSLisandro Dalcin   Level: intermediate
62abe9303eSLisandro Dalcin 
63abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetType(), PetscPartitionerCreate()
64abe9303eSLisandro Dalcin @*/
65abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerGetType(PetscPartitioner part, PetscPartitionerType *name)
66abe9303eSLisandro Dalcin {
67abe9303eSLisandro Dalcin   PetscFunctionBegin;
68abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
69abe9303eSLisandro Dalcin   PetscValidPointer(name, 2);
70abe9303eSLisandro Dalcin   *name = ((PetscObject) part)->type_name;
71abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
72abe9303eSLisandro Dalcin }
73abe9303eSLisandro Dalcin 
74abe9303eSLisandro Dalcin /*@C
75abe9303eSLisandro Dalcin    PetscPartitionerViewFromOptions - View from Options
76abe9303eSLisandro Dalcin 
77abe9303eSLisandro Dalcin    Collective on PetscPartitioner
78abe9303eSLisandro Dalcin 
79abe9303eSLisandro Dalcin    Input Parameters:
80abe9303eSLisandro Dalcin +  A - the PetscPartitioner object
81abe9303eSLisandro Dalcin .  obj - Optional object
82abe9303eSLisandro Dalcin -  name - command line option
83abe9303eSLisandro Dalcin 
84abe9303eSLisandro Dalcin    Level: intermediate
85abe9303eSLisandro Dalcin .seealso:  PetscPartitionerView(), PetscObjectViewFromOptions()
86abe9303eSLisandro Dalcin @*/
87abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerViewFromOptions(PetscPartitioner A,PetscObject obj,const char name[])
88abe9303eSLisandro Dalcin {
89abe9303eSLisandro Dalcin   PetscFunctionBegin;
90abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(A,PETSCPARTITIONER_CLASSID,1);
919566063dSJacob Faibussowitsch   PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name));
92abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
93abe9303eSLisandro Dalcin }
94abe9303eSLisandro Dalcin 
95abe9303eSLisandro Dalcin /*@
96abe9303eSLisandro Dalcin   PetscPartitionerView - Views a PetscPartitioner
97abe9303eSLisandro Dalcin 
98abe9303eSLisandro Dalcin   Collective on PetscPartitioner
99abe9303eSLisandro Dalcin 
100d8d19677SJose E. Roman   Input Parameters:
101abe9303eSLisandro Dalcin + part - the PetscPartitioner object to view
102abe9303eSLisandro Dalcin - v    - the viewer
103abe9303eSLisandro Dalcin 
104abe9303eSLisandro Dalcin   Level: developer
105abe9303eSLisandro Dalcin 
106abe9303eSLisandro Dalcin .seealso: PetscPartitionerDestroy()
107abe9303eSLisandro Dalcin @*/
108abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerView(PetscPartitioner part, PetscViewer v)
109abe9303eSLisandro Dalcin {
110abe9303eSLisandro Dalcin   PetscMPIInt    size;
111abe9303eSLisandro Dalcin   PetscBool      isascii;
112abe9303eSLisandro Dalcin 
113abe9303eSLisandro Dalcin   PetscFunctionBegin;
114abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
1159566063dSJacob Faibussowitsch   if (!v) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) part), &v));
1169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &isascii));
117abe9303eSLisandro Dalcin   if (isascii) {
1189566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject) part), &size));
1199566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "Graph Partitioner: %d MPI Process%s\n", size, size > 1 ? "es" : ""));
1209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  type: %s\n", ((PetscObject)part)->type_name));
12163a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  edge cut: %" PetscInt_FMT "\n", part->edgeCut));
12263a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  balance: %.2g\n", (double)part->balance));
1239566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  use vertex weights: %d\n", part->usevwgt));
124abe9303eSLisandro Dalcin   }
1259566063dSJacob Faibussowitsch   if (part->ops->view) PetscCall((*part->ops->view)(part, v));
126abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
127abe9303eSLisandro Dalcin }
128abe9303eSLisandro Dalcin 
129d7cc930eSLisandro Dalcin static PetscErrorCode PetscPartitionerGetDefaultType(MPI_Comm comm, const char **defaultType)
130abe9303eSLisandro Dalcin {
131abe9303eSLisandro Dalcin   PetscMPIInt    size;
132abe9303eSLisandro Dalcin 
133abe9303eSLisandro Dalcin   PetscFunctionBegin;
1349566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm, &size));
135abe9303eSLisandro Dalcin   if (size == 1) {
136abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERSIMPLE;
137abe9303eSLisandro Dalcin   } else {
138abe9303eSLisandro Dalcin #if defined(PETSC_HAVE_PARMETIS)
139abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERPARMETIS;
140abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_PTSCOTCH)
141abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERPTSCOTCH;
142abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_CHACO)
143abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERCHACO;
144abe9303eSLisandro Dalcin #else
145abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERSIMPLE;
146abe9303eSLisandro Dalcin #endif
147abe9303eSLisandro Dalcin   }
148abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
149abe9303eSLisandro Dalcin }
150abe9303eSLisandro Dalcin 
151abe9303eSLisandro Dalcin /*@
152abe9303eSLisandro Dalcin   PetscPartitionerSetFromOptions - sets parameters in a PetscPartitioner from the options database
153abe9303eSLisandro Dalcin 
154abe9303eSLisandro Dalcin   Collective on PetscPartitioner
155abe9303eSLisandro Dalcin 
156abe9303eSLisandro Dalcin   Input Parameter:
157abe9303eSLisandro Dalcin . part - the PetscPartitioner object to set options for
158abe9303eSLisandro Dalcin 
159abe9303eSLisandro Dalcin   Options Database Keys:
160abe9303eSLisandro Dalcin +  -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types
161abe9303eSLisandro Dalcin .  -petscpartitioner_use_vertex_weights - Uses weights associated with the graph vertices
162abe9303eSLisandro Dalcin -  -petscpartitioner_view_graph - View the graph each time PetscPartitionerPartition is called. Viewer can be customized, see PetscOptionsGetViewer()
163abe9303eSLisandro Dalcin 
164abe9303eSLisandro Dalcin   Level: developer
165abe9303eSLisandro Dalcin 
166abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerSetType(), PetscPartitionerPartition()
167abe9303eSLisandro Dalcin @*/
168abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner part)
169abe9303eSLisandro Dalcin {
170d7cc930eSLisandro Dalcin   const char    *currentType = NULL;
171abe9303eSLisandro Dalcin   char           name[256];
172abe9303eSLisandro Dalcin   PetscBool      flg;
173abe9303eSLisandro Dalcin 
174abe9303eSLisandro Dalcin   PetscFunctionBegin;
175abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
176d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject) part);
1779566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerGetType(part, &currentType));
1789566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, currentType, name, sizeof(name), &flg));
179abe9303eSLisandro Dalcin   if (flg) {
1809566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerSetType(part, name));
181abe9303eSLisandro Dalcin   }
1829566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscpartitioner_use_vertex_weights","Use vertex weights","",part->usevwgt,&part->usevwgt,NULL));
183abe9303eSLisandro Dalcin   if (part->ops->setfromoptions) {
1849566063dSJacob Faibussowitsch     PetscCall((*part->ops->setfromoptions)(PetscOptionsObject,part));
185abe9303eSLisandro Dalcin   }
1869566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&part->viewer));
1879566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&part->viewerGraph));
1889566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view", &part->viewer, NULL, NULL));
1899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view_graph", &part->viewerGraph, NULL, &part->viewGraph));
190abe9303eSLisandro Dalcin   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1919566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) part));
192d0609cedSBarry Smith   PetscOptionsEnd();
193abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
194abe9303eSLisandro Dalcin }
195abe9303eSLisandro Dalcin 
196abe9303eSLisandro Dalcin /*@
197abe9303eSLisandro Dalcin   PetscPartitionerSetUp - Construct data structures for the PetscPartitioner
198abe9303eSLisandro Dalcin 
199abe9303eSLisandro Dalcin   Collective on PetscPartitioner
200abe9303eSLisandro Dalcin 
201abe9303eSLisandro Dalcin   Input Parameter:
202abe9303eSLisandro Dalcin . part - the PetscPartitioner object to setup
203abe9303eSLisandro Dalcin 
204abe9303eSLisandro Dalcin   Level: developer
205abe9303eSLisandro Dalcin 
206abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerDestroy()
207abe9303eSLisandro Dalcin @*/
208abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part)
209abe9303eSLisandro Dalcin {
210abe9303eSLisandro Dalcin   PetscFunctionBegin;
211abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
2129566063dSJacob Faibussowitsch   if (part->ops->setup) PetscCall((*part->ops->setup)(part));
213abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
214abe9303eSLisandro Dalcin }
215abe9303eSLisandro Dalcin 
216abe9303eSLisandro Dalcin /*@
217abe9303eSLisandro Dalcin   PetscPartitionerReset - Resets data structures for the PetscPartitioner
218abe9303eSLisandro Dalcin 
219abe9303eSLisandro Dalcin   Collective on PetscPartitioner
220abe9303eSLisandro Dalcin 
221abe9303eSLisandro Dalcin   Input Parameter:
222abe9303eSLisandro Dalcin . part - the PetscPartitioner object to reset
223abe9303eSLisandro Dalcin 
224abe9303eSLisandro Dalcin   Level: developer
225abe9303eSLisandro Dalcin 
226abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetUp(), PetscPartitionerDestroy()
227abe9303eSLisandro Dalcin @*/
228abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerReset(PetscPartitioner part)
229abe9303eSLisandro Dalcin {
230abe9303eSLisandro Dalcin   PetscFunctionBegin;
231abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
2329566063dSJacob Faibussowitsch   if (part->ops->reset) PetscCall((*part->ops->reset)(part));
233abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
234abe9303eSLisandro Dalcin }
235abe9303eSLisandro Dalcin 
236abe9303eSLisandro Dalcin /*@
237abe9303eSLisandro Dalcin   PetscPartitionerDestroy - Destroys a PetscPartitioner object
238abe9303eSLisandro Dalcin 
239abe9303eSLisandro Dalcin   Collective on PetscPartitioner
240abe9303eSLisandro Dalcin 
241abe9303eSLisandro Dalcin   Input Parameter:
242abe9303eSLisandro Dalcin . part - the PetscPartitioner object to destroy
243abe9303eSLisandro Dalcin 
244abe9303eSLisandro Dalcin   Level: developer
245abe9303eSLisandro Dalcin 
246abe9303eSLisandro Dalcin .seealso: PetscPartitionerView()
247abe9303eSLisandro Dalcin @*/
248abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part)
249abe9303eSLisandro Dalcin {
250abe9303eSLisandro Dalcin   PetscFunctionBegin;
251abe9303eSLisandro Dalcin   if (!*part) PetscFunctionReturn(0);
252abe9303eSLisandro Dalcin   PetscValidHeaderSpecific((*part), PETSCPARTITIONER_CLASSID, 1);
253abe9303eSLisandro Dalcin 
254ea78f98cSLisandro Dalcin   if (--((PetscObject)(*part))->refct > 0) {*part = NULL; PetscFunctionReturn(0);}
255abe9303eSLisandro Dalcin   ((PetscObject) (*part))->refct = 0;
256abe9303eSLisandro Dalcin 
2579566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerReset(*part));
258abe9303eSLisandro Dalcin 
2599566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*part)->viewer));
2609566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*part)->viewerGraph));
2619566063dSJacob Faibussowitsch   if ((*part)->ops->destroy) PetscCall((*(*part)->ops->destroy)(*part));
2629566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(part));
263abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
264abe9303eSLisandro Dalcin }
265abe9303eSLisandro Dalcin 
266abe9303eSLisandro Dalcin /*@
267abe9303eSLisandro Dalcin   PetscPartitionerPartition - Partition a graph
268abe9303eSLisandro Dalcin 
269abe9303eSLisandro Dalcin   Collective on PetscPartitioner
270abe9303eSLisandro Dalcin 
271abe9303eSLisandro Dalcin   Input Parameters:
272abe9303eSLisandro Dalcin + part    - The PetscPartitioner
273abe9303eSLisandro Dalcin . nparts  - Number of partitions
274abe9303eSLisandro Dalcin . numVertices - Number of vertices in the local part of the graph
275abe9303eSLisandro Dalcin . start - row pointers for the local part of the graph (CSR style)
276abe9303eSLisandro Dalcin . adjacency - adjacency list (CSR style)
277abe9303eSLisandro Dalcin . vertexSection - PetscSection describing the absolute weight of each local vertex (can be NULL)
278abe9303eSLisandro Dalcin - targetSection - PetscSection describing the absolute weight of each partition (can be NULL)
279abe9303eSLisandro Dalcin 
280abe9303eSLisandro Dalcin   Output Parameters:
281abe9303eSLisandro Dalcin + partSection     - The PetscSection giving the division of points by partition
282abe9303eSLisandro Dalcin - partition       - The list of points by partition
283abe9303eSLisandro Dalcin 
284abe9303eSLisandro Dalcin   Options Database:
285abe9303eSLisandro Dalcin + -petscpartitioner_view - View the partitioner information
286abe9303eSLisandro Dalcin - -petscpartitioner_view_graph - View the graph we are partitioning
287abe9303eSLisandro Dalcin 
288abe9303eSLisandro Dalcin   Notes:
289abe9303eSLisandro 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.
290abe9303eSLisandro 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.
291abe9303eSLisandro Dalcin 
292abe9303eSLisandro Dalcin   Level: developer
293abe9303eSLisandro Dalcin 
2946e0dc72eSMatthew G. Knepley .seealso PetscPartitionerCreate(), PetscPartitionerSetType(), PetscSectionCreate(), PetscSectionSetChart(), PetscSectionSetDof()
295abe9303eSLisandro Dalcin @*/
296abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertexSection, PetscSection targetSection, PetscSection partSection, IS *partition)
297abe9303eSLisandro Dalcin {
298abe9303eSLisandro Dalcin   PetscFunctionBegin;
299abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
300abe9303eSLisandro Dalcin   PetscValidLogicalCollectiveInt(part, nparts, 2);
30108401ef6SPierre Jolivet   PetscCheck(nparts > 0,PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_OUTOFRANGE, "Number of parts must be positive");
30208401ef6SPierre Jolivet   PetscCheck(numVertices >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices must be non-negative");
303abe9303eSLisandro Dalcin   if (numVertices && !part->noGraph) {
304abe9303eSLisandro Dalcin     PetscValidIntPointer(start, 4);
305abe9303eSLisandro Dalcin     PetscValidIntPointer(start + numVertices, 4);
306abe9303eSLisandro Dalcin     if (start[numVertices]) PetscValidIntPointer(adjacency, 5);
307abe9303eSLisandro Dalcin   }
308abe9303eSLisandro Dalcin   if (vertexSection) {
309abe9303eSLisandro Dalcin     PetscInt s,e;
310abe9303eSLisandro Dalcin 
311abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(vertexSection, PETSC_SECTION_CLASSID, 6);
3129566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetChart(vertexSection, &s, &e));
313*1dca8a05SBarry Smith     PetscCheck(s <= 0 && e >= numVertices,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid vertexSection chart [%" PetscInt_FMT ",%" PetscInt_FMT ")",s,e);
314abe9303eSLisandro Dalcin   }
315abe9303eSLisandro Dalcin   if (targetSection) {
316abe9303eSLisandro Dalcin     PetscInt s,e;
317abe9303eSLisandro Dalcin 
318abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(targetSection, PETSC_SECTION_CLASSID, 7);
3199566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetChart(targetSection, &s, &e));
320*1dca8a05SBarry Smith     PetscCheck(s <= 0 && e >= nparts,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid targetSection chart [%" PetscInt_FMT ",%" PetscInt_FMT ")",s,e);
321abe9303eSLisandro Dalcin   }
322abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(partSection, PETSC_SECTION_CLASSID, 8);
323abe9303eSLisandro Dalcin   PetscValidPointer(partition, 9);
324abe9303eSLisandro Dalcin 
3259566063dSJacob Faibussowitsch   PetscCall(PetscSectionReset(partSection));
3269566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(partSection, 0, nparts));
327abe9303eSLisandro Dalcin   if (nparts == 1) { /* quick */
3289566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(partSection, 0, numVertices));
3299566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)part),numVertices,0,1,partition));
330abe9303eSLisandro Dalcin   } else {
33128b400f6SJacob Faibussowitsch     PetscCheck(part->ops->partition,PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "PetscPartitioner %s has no partitioning method", ((PetscObject)part)->type_name);
3329566063dSJacob Faibussowitsch     PetscCall((*part->ops->partition)(part, nparts, numVertices, start, adjacency, vertexSection, targetSection, partSection, partition));
333abe9303eSLisandro Dalcin   }
3349566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(partSection));
335abe9303eSLisandro Dalcin   if (part->viewerGraph) {
336abe9303eSLisandro Dalcin     PetscViewer viewer = part->viewerGraph;
337abe9303eSLisandro Dalcin     PetscBool   isascii;
338abe9303eSLisandro Dalcin     PetscInt    v, i;
339abe9303eSLisandro Dalcin     PetscMPIInt rank;
340abe9303eSLisandro Dalcin 
3419566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank));
3429566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii));
343abe9303eSLisandro Dalcin     if (isascii) {
3449566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushSynchronized(viewer));
34563a3b9bcSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %" PetscInt_FMT "\n", rank, numVertices));
346abe9303eSLisandro Dalcin       for (v = 0; v < numVertices; ++v) {
347abe9303eSLisandro Dalcin         const PetscInt s = start[v];
348abe9303eSLisandro Dalcin         const PetscInt e = start[v+1];
349abe9303eSLisandro Dalcin 
3509566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]  ", rank));
35163a3b9bcSJacob Faibussowitsch         for (i = s; i < e; ++i) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%" PetscInt_FMT " ", adjacency[i]));
35263a3b9bcSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%" PetscInt_FMT "-%" PetscInt_FMT ")\n", s, e));
353abe9303eSLisandro Dalcin       }
3549566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
3559566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopSynchronized(viewer));
356abe9303eSLisandro Dalcin     }
357abe9303eSLisandro Dalcin   }
358abe9303eSLisandro Dalcin   if (part->viewer) {
3599566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerView(part,part->viewer));
360abe9303eSLisandro Dalcin   }
361abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
362abe9303eSLisandro Dalcin }
363abe9303eSLisandro Dalcin 
364abe9303eSLisandro Dalcin /*@
365abe9303eSLisandro Dalcin   PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType().
366abe9303eSLisandro Dalcin 
367abe9303eSLisandro Dalcin   Collective
368abe9303eSLisandro Dalcin 
369abe9303eSLisandro Dalcin   Input Parameter:
370abe9303eSLisandro Dalcin . comm - The communicator for the PetscPartitioner object
371abe9303eSLisandro Dalcin 
372abe9303eSLisandro Dalcin   Output Parameter:
373abe9303eSLisandro Dalcin . part - The PetscPartitioner object
374abe9303eSLisandro Dalcin 
375abe9303eSLisandro Dalcin   Level: beginner
376abe9303eSLisandro Dalcin 
3776e0dc72eSMatthew G. Knepley .seealso: PetscPartitionerSetType(), PetscPartitionerDestroy()
378abe9303eSLisandro Dalcin @*/
379abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part)
380abe9303eSLisandro Dalcin {
381abe9303eSLisandro Dalcin   PetscPartitioner p;
382abe9303eSLisandro Dalcin   const char       *partitionerType = NULL;
383abe9303eSLisandro Dalcin 
384abe9303eSLisandro Dalcin   PetscFunctionBegin;
385abe9303eSLisandro Dalcin   PetscValidPointer(part, 2);
386abe9303eSLisandro Dalcin   *part = NULL;
3879566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerInitializePackage());
388abe9303eSLisandro Dalcin 
3899566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView));
3909566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerGetDefaultType(comm, &partitionerType));
3919566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerSetType(p, partitionerType));
392abe9303eSLisandro Dalcin 
393abe9303eSLisandro Dalcin   p->edgeCut = 0;
394abe9303eSLisandro Dalcin   p->balance = 0.0;
395abe9303eSLisandro Dalcin   p->usevwgt = PETSC_TRUE;
396abe9303eSLisandro Dalcin 
397abe9303eSLisandro Dalcin   *part = p;
398abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
399abe9303eSLisandro Dalcin }
400