xref: /petsc/src/dm/partitioner/interface/partitioner.c (revision 08401ef684002a709c6d3db98a0c9f54a8bcf1ec)
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));
1219566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  edge cut: %D\n", part->edgeCut));
1229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(v, "  balance: %.2g\n", 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   PetscErrorCode ierr;
174abe9303eSLisandro Dalcin 
175abe9303eSLisandro Dalcin   PetscFunctionBegin;
176abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
1779566063dSJacob Faibussowitsch   ierr = PetscObjectOptionsBegin((PetscObject) part);PetscCall(ierr);
1789566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerGetType(part, &currentType));
1799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, currentType, name, sizeof(name), &flg));
180abe9303eSLisandro Dalcin   if (flg) {
1819566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerSetType(part, name));
182abe9303eSLisandro Dalcin   }
1839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-petscpartitioner_use_vertex_weights","Use vertex weights","",part->usevwgt,&part->usevwgt,NULL));
184abe9303eSLisandro Dalcin   if (part->ops->setfromoptions) {
1859566063dSJacob Faibussowitsch     PetscCall((*part->ops->setfromoptions)(PetscOptionsObject,part));
186abe9303eSLisandro Dalcin   }
1879566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&part->viewer));
1889566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&part->viewerGraph));
1899566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view", &part->viewer, NULL, NULL));
1909566063dSJacob Faibussowitsch   PetscCall(PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view_graph", &part->viewerGraph, NULL, &part->viewGraph));
191abe9303eSLisandro Dalcin   /* process any options handlers added with PetscObjectAddOptionsHandler() */
1929566063dSJacob Faibussowitsch   PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) part));
1939566063dSJacob Faibussowitsch   ierr = PetscOptionsEnd();PetscCall(ierr);
194abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
195abe9303eSLisandro Dalcin }
196abe9303eSLisandro Dalcin 
197abe9303eSLisandro Dalcin /*@
198abe9303eSLisandro Dalcin   PetscPartitionerSetUp - Construct data structures for the PetscPartitioner
199abe9303eSLisandro Dalcin 
200abe9303eSLisandro Dalcin   Collective on PetscPartitioner
201abe9303eSLisandro Dalcin 
202abe9303eSLisandro Dalcin   Input Parameter:
203abe9303eSLisandro Dalcin . part - the PetscPartitioner object to setup
204abe9303eSLisandro Dalcin 
205abe9303eSLisandro Dalcin   Level: developer
206abe9303eSLisandro Dalcin 
207abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerDestroy()
208abe9303eSLisandro Dalcin @*/
209abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part)
210abe9303eSLisandro Dalcin {
211abe9303eSLisandro Dalcin   PetscFunctionBegin;
212abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
2139566063dSJacob Faibussowitsch   if (part->ops->setup) PetscCall((*part->ops->setup)(part));
214abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
215abe9303eSLisandro Dalcin }
216abe9303eSLisandro Dalcin 
217abe9303eSLisandro Dalcin /*@
218abe9303eSLisandro Dalcin   PetscPartitionerReset - Resets data structures for the PetscPartitioner
219abe9303eSLisandro Dalcin 
220abe9303eSLisandro Dalcin   Collective on PetscPartitioner
221abe9303eSLisandro Dalcin 
222abe9303eSLisandro Dalcin   Input Parameter:
223abe9303eSLisandro Dalcin . part - the PetscPartitioner object to reset
224abe9303eSLisandro Dalcin 
225abe9303eSLisandro Dalcin   Level: developer
226abe9303eSLisandro Dalcin 
227abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetUp(), PetscPartitionerDestroy()
228abe9303eSLisandro Dalcin @*/
229abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerReset(PetscPartitioner part)
230abe9303eSLisandro Dalcin {
231abe9303eSLisandro Dalcin   PetscFunctionBegin;
232abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
2339566063dSJacob Faibussowitsch   if (part->ops->reset) PetscCall((*part->ops->reset)(part));
234abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
235abe9303eSLisandro Dalcin }
236abe9303eSLisandro Dalcin 
237abe9303eSLisandro Dalcin /*@
238abe9303eSLisandro Dalcin   PetscPartitionerDestroy - Destroys a PetscPartitioner object
239abe9303eSLisandro Dalcin 
240abe9303eSLisandro Dalcin   Collective on PetscPartitioner
241abe9303eSLisandro Dalcin 
242abe9303eSLisandro Dalcin   Input Parameter:
243abe9303eSLisandro Dalcin . part - the PetscPartitioner object to destroy
244abe9303eSLisandro Dalcin 
245abe9303eSLisandro Dalcin   Level: developer
246abe9303eSLisandro Dalcin 
247abe9303eSLisandro Dalcin .seealso: PetscPartitionerView()
248abe9303eSLisandro Dalcin @*/
249abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part)
250abe9303eSLisandro Dalcin {
251abe9303eSLisandro Dalcin   PetscFunctionBegin;
252abe9303eSLisandro Dalcin   if (!*part) PetscFunctionReturn(0);
253abe9303eSLisandro Dalcin   PetscValidHeaderSpecific((*part), PETSCPARTITIONER_CLASSID, 1);
254abe9303eSLisandro Dalcin 
255ea78f98cSLisandro Dalcin   if (--((PetscObject)(*part))->refct > 0) {*part = NULL; PetscFunctionReturn(0);}
256abe9303eSLisandro Dalcin   ((PetscObject) (*part))->refct = 0;
257abe9303eSLisandro Dalcin 
2589566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerReset(*part));
259abe9303eSLisandro Dalcin 
2609566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*part)->viewer));
2619566063dSJacob Faibussowitsch   PetscCall(PetscViewerDestroy(&(*part)->viewerGraph));
2629566063dSJacob Faibussowitsch   if ((*part)->ops->destroy) PetscCall((*(*part)->ops->destroy)(*part));
2639566063dSJacob Faibussowitsch   PetscCall(PetscHeaderDestroy(part));
264abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
265abe9303eSLisandro Dalcin }
266abe9303eSLisandro Dalcin 
267abe9303eSLisandro Dalcin /*@
268abe9303eSLisandro Dalcin   PetscPartitionerPartition - Partition a graph
269abe9303eSLisandro Dalcin 
270abe9303eSLisandro Dalcin   Collective on PetscPartitioner
271abe9303eSLisandro Dalcin 
272abe9303eSLisandro Dalcin   Input Parameters:
273abe9303eSLisandro Dalcin + part    - The PetscPartitioner
274abe9303eSLisandro Dalcin . nparts  - Number of partitions
275abe9303eSLisandro Dalcin . numVertices - Number of vertices in the local part of the graph
276abe9303eSLisandro Dalcin . start - row pointers for the local part of the graph (CSR style)
277abe9303eSLisandro Dalcin . adjacency - adjacency list (CSR style)
278abe9303eSLisandro Dalcin . vertexSection - PetscSection describing the absolute weight of each local vertex (can be NULL)
279abe9303eSLisandro Dalcin - targetSection - PetscSection describing the absolute weight of each partition (can be NULL)
280abe9303eSLisandro Dalcin 
281abe9303eSLisandro Dalcin   Output Parameters:
282abe9303eSLisandro Dalcin + partSection     - The PetscSection giving the division of points by partition
283abe9303eSLisandro Dalcin - partition       - The list of points by partition
284abe9303eSLisandro Dalcin 
285abe9303eSLisandro Dalcin   Options Database:
286abe9303eSLisandro Dalcin + -petscpartitioner_view - View the partitioner information
287abe9303eSLisandro Dalcin - -petscpartitioner_view_graph - View the graph we are partitioning
288abe9303eSLisandro Dalcin 
289abe9303eSLisandro Dalcin   Notes:
290abe9303eSLisandro 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.
291abe9303eSLisandro 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.
292abe9303eSLisandro Dalcin 
293abe9303eSLisandro Dalcin   Level: developer
294abe9303eSLisandro Dalcin 
2956e0dc72eSMatthew G. Knepley .seealso PetscPartitionerCreate(), PetscPartitionerSetType(), PetscSectionCreate(), PetscSectionSetChart(), PetscSectionSetDof()
296abe9303eSLisandro Dalcin @*/
297abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertexSection, PetscSection targetSection, PetscSection partSection, IS *partition)
298abe9303eSLisandro Dalcin {
299abe9303eSLisandro Dalcin   PetscFunctionBegin;
300abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
301abe9303eSLisandro Dalcin   PetscValidLogicalCollectiveInt(part, nparts, 2);
302*08401ef6SPierre Jolivet   PetscCheck(nparts > 0,PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_OUTOFRANGE, "Number of parts must be positive");
303*08401ef6SPierre Jolivet   PetscCheck(numVertices >= 0,PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices must be non-negative");
304abe9303eSLisandro Dalcin   if (numVertices && !part->noGraph) {
305abe9303eSLisandro Dalcin     PetscValidIntPointer(start, 4);
306abe9303eSLisandro Dalcin     PetscValidIntPointer(start + numVertices, 4);
307abe9303eSLisandro Dalcin     if (start[numVertices]) PetscValidIntPointer(adjacency, 5);
308abe9303eSLisandro Dalcin   }
309abe9303eSLisandro Dalcin   if (vertexSection) {
310abe9303eSLisandro Dalcin     PetscInt s,e;
311abe9303eSLisandro Dalcin 
312abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(vertexSection, PETSC_SECTION_CLASSID, 6);
3139566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetChart(vertexSection, &s, &e));
3142c71b3e2SJacob Faibussowitsch     PetscCheckFalse(s > 0 || e < numVertices,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid vertexSection chart [%D,%D)",s,e);
315abe9303eSLisandro Dalcin   }
316abe9303eSLisandro Dalcin   if (targetSection) {
317abe9303eSLisandro Dalcin     PetscInt s,e;
318abe9303eSLisandro Dalcin 
319abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(targetSection, PETSC_SECTION_CLASSID, 7);
3209566063dSJacob Faibussowitsch     PetscCall(PetscSectionGetChart(targetSection, &s, &e));
3212c71b3e2SJacob Faibussowitsch     PetscCheckFalse(s > 0 || e < nparts,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid targetSection chart [%D,%D)",s,e);
322abe9303eSLisandro Dalcin   }
323abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(partSection, PETSC_SECTION_CLASSID, 8);
324abe9303eSLisandro Dalcin   PetscValidPointer(partition, 9);
325abe9303eSLisandro Dalcin 
3269566063dSJacob Faibussowitsch   PetscCall(PetscSectionReset(partSection));
3279566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetChart(partSection, 0, nparts));
328abe9303eSLisandro Dalcin   if (nparts == 1) { /* quick */
3299566063dSJacob Faibussowitsch     PetscCall(PetscSectionSetDof(partSection, 0, numVertices));
3309566063dSJacob Faibussowitsch     PetscCall(ISCreateStride(PetscObjectComm((PetscObject)part),numVertices,0,1,partition));
331abe9303eSLisandro Dalcin   } else {
33228b400f6SJacob Faibussowitsch     PetscCheck(part->ops->partition,PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "PetscPartitioner %s has no partitioning method", ((PetscObject)part)->type_name);
3339566063dSJacob Faibussowitsch     PetscCall((*part->ops->partition)(part, nparts, numVertices, start, adjacency, vertexSection, targetSection, partSection, partition));
334abe9303eSLisandro Dalcin   }
3359566063dSJacob Faibussowitsch   PetscCall(PetscSectionSetUp(partSection));
336abe9303eSLisandro Dalcin   if (part->viewerGraph) {
337abe9303eSLisandro Dalcin     PetscViewer viewer = part->viewerGraph;
338abe9303eSLisandro Dalcin     PetscBool   isascii;
339abe9303eSLisandro Dalcin     PetscInt    v, i;
340abe9303eSLisandro Dalcin     PetscMPIInt rank;
341abe9303eSLisandro Dalcin 
3429566063dSJacob Faibussowitsch     PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank));
3439566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii));
344abe9303eSLisandro Dalcin     if (isascii) {
3459566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPushSynchronized(viewer));
3469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %D\n", rank, numVertices));
347abe9303eSLisandro Dalcin       for (v = 0; v < numVertices; ++v) {
348abe9303eSLisandro Dalcin         const PetscInt s = start[v];
349abe9303eSLisandro Dalcin         const PetscInt e = start[v+1];
350abe9303eSLisandro Dalcin 
3519566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%d]  ", rank));
3529566063dSJacob Faibussowitsch         for (i = s; i < e; ++i) PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "%D ", adjacency[i]));
3539566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIISynchronizedPrintf(viewer, "[%D-%D)\n", s, e));
354abe9303eSLisandro Dalcin       }
3559566063dSJacob Faibussowitsch       PetscCall(PetscViewerFlush(viewer));
3569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPopSynchronized(viewer));
357abe9303eSLisandro Dalcin     }
358abe9303eSLisandro Dalcin   }
359abe9303eSLisandro Dalcin   if (part->viewer) {
3609566063dSJacob Faibussowitsch     PetscCall(PetscPartitionerView(part,part->viewer));
361abe9303eSLisandro Dalcin   }
362abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
363abe9303eSLisandro Dalcin }
364abe9303eSLisandro Dalcin 
365abe9303eSLisandro Dalcin /*@
366abe9303eSLisandro Dalcin   PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType().
367abe9303eSLisandro Dalcin 
368abe9303eSLisandro Dalcin   Collective
369abe9303eSLisandro Dalcin 
370abe9303eSLisandro Dalcin   Input Parameter:
371abe9303eSLisandro Dalcin . comm - The communicator for the PetscPartitioner object
372abe9303eSLisandro Dalcin 
373abe9303eSLisandro Dalcin   Output Parameter:
374abe9303eSLisandro Dalcin . part - The PetscPartitioner object
375abe9303eSLisandro Dalcin 
376abe9303eSLisandro Dalcin   Level: beginner
377abe9303eSLisandro Dalcin 
3786e0dc72eSMatthew G. Knepley .seealso: PetscPartitionerSetType(), PetscPartitionerDestroy()
379abe9303eSLisandro Dalcin @*/
380abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part)
381abe9303eSLisandro Dalcin {
382abe9303eSLisandro Dalcin   PetscPartitioner p;
383abe9303eSLisandro Dalcin   const char       *partitionerType = NULL;
384abe9303eSLisandro Dalcin 
385abe9303eSLisandro Dalcin   PetscFunctionBegin;
386abe9303eSLisandro Dalcin   PetscValidPointer(part, 2);
387abe9303eSLisandro Dalcin   *part = NULL;
3889566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerInitializePackage());
389abe9303eSLisandro Dalcin 
3909566063dSJacob Faibussowitsch   PetscCall(PetscHeaderCreate(p, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView));
3919566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerGetDefaultType(comm, &partitionerType));
3929566063dSJacob Faibussowitsch   PetscCall(PetscPartitionerSetType(p, partitionerType));
393abe9303eSLisandro Dalcin 
394abe9303eSLisandro Dalcin   p->edgeCut = 0;
395abe9303eSLisandro Dalcin   p->balance = 0.0;
396abe9303eSLisandro Dalcin   p->usevwgt = PETSC_TRUE;
397abe9303eSLisandro Dalcin 
398abe9303eSLisandro Dalcin   *part = p;
399abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
400abe9303eSLisandro Dalcin }
401