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