xref: /petsc/src/dm/partitioner/interface/partitioner.c (revision d7cc930e14e615e9907267aaa472dd0ccceeab82)
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 
126*d7cc930eSLisandro Dalcin static PetscErrorCode PetscPartitionerGetDefaultType(MPI_Comm comm, 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 (size == 1) {
134abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERSIMPLE;
135abe9303eSLisandro Dalcin   } else {
136abe9303eSLisandro Dalcin #if defined(PETSC_HAVE_PARMETIS)
137abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERPARMETIS;
138abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_PTSCOTCH)
139abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERPTSCOTCH;
140abe9303eSLisandro Dalcin #elif defined(PETSC_HAVE_CHACO)
141abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERCHACO;
142abe9303eSLisandro Dalcin #else
143abe9303eSLisandro Dalcin     *defaultType = PETSCPARTITIONERSIMPLE;
144abe9303eSLisandro Dalcin #endif
145abe9303eSLisandro Dalcin   }
146abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
147abe9303eSLisandro Dalcin }
148abe9303eSLisandro Dalcin 
149abe9303eSLisandro Dalcin /*@
150abe9303eSLisandro Dalcin   PetscPartitionerSetFromOptions - sets parameters in a PetscPartitioner from the options database
151abe9303eSLisandro Dalcin 
152abe9303eSLisandro Dalcin   Collective on PetscPartitioner
153abe9303eSLisandro Dalcin 
154abe9303eSLisandro Dalcin   Input Parameter:
155abe9303eSLisandro Dalcin . part - the PetscPartitioner object to set options for
156abe9303eSLisandro Dalcin 
157abe9303eSLisandro Dalcin   Options Database Keys:
158abe9303eSLisandro Dalcin +  -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types
159abe9303eSLisandro Dalcin .  -petscpartitioner_use_vertex_weights - Uses weights associated with the graph vertices
160abe9303eSLisandro Dalcin -  -petscpartitioner_view_graph - View the graph each time PetscPartitionerPartition is called. Viewer can be customized, see PetscOptionsGetViewer()
161abe9303eSLisandro Dalcin 
162abe9303eSLisandro Dalcin   Level: developer
163abe9303eSLisandro Dalcin 
164abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerSetType(), PetscPartitionerPartition()
165abe9303eSLisandro Dalcin @*/
166abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner part)
167abe9303eSLisandro Dalcin {
168*d7cc930eSLisandro Dalcin   const char    *currentType = NULL;
169abe9303eSLisandro Dalcin   char           name[256];
170abe9303eSLisandro Dalcin   PetscBool      flg;
171abe9303eSLisandro Dalcin   PetscErrorCode ierr;
172abe9303eSLisandro Dalcin 
173abe9303eSLisandro Dalcin   PetscFunctionBegin;
174abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
175abe9303eSLisandro Dalcin   ierr = PetscObjectOptionsBegin((PetscObject) part);CHKERRQ(ierr);
176*d7cc930eSLisandro Dalcin   ierr = PetscPartitionerGetType(part, &currentType);CHKERRQ(ierr);
177*d7cc930eSLisandro Dalcin   ierr = PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, currentType, name, sizeof(name), &flg);CHKERRQ(ierr);
178abe9303eSLisandro Dalcin   if (flg) {
179abe9303eSLisandro Dalcin     ierr = PetscPartitionerSetType(part, name);CHKERRQ(ierr);
180abe9303eSLisandro Dalcin   }
181abe9303eSLisandro Dalcin   ierr = PetscOptionsBool("-petscpartitioner_use_vertex_weights","Use vertex weights","",part->usevwgt,&part->usevwgt,NULL);CHKERRQ(ierr);
182abe9303eSLisandro Dalcin   if (part->ops->setfromoptions) {
183abe9303eSLisandro Dalcin     ierr = (*part->ops->setfromoptions)(PetscOptionsObject,part);CHKERRQ(ierr);
184abe9303eSLisandro Dalcin   }
185abe9303eSLisandro Dalcin   ierr = PetscViewerDestroy(&part->viewer);CHKERRQ(ierr);
186abe9303eSLisandro Dalcin   ierr = PetscViewerDestroy(&part->viewerGraph);CHKERRQ(ierr);
187abe9303eSLisandro Dalcin   ierr = PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view", &part->viewer, NULL, NULL);CHKERRQ(ierr);
188abe9303eSLisandro Dalcin   ierr = PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view_graph", &part->viewerGraph, NULL, &part->viewGraph);CHKERRQ(ierr);
189abe9303eSLisandro Dalcin   /* process any options handlers added with PetscObjectAddOptionsHandler() */
190abe9303eSLisandro Dalcin   ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) part);CHKERRQ(ierr);
191abe9303eSLisandro Dalcin   ierr = PetscOptionsEnd();CHKERRQ(ierr);
192abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
193abe9303eSLisandro Dalcin }
194abe9303eSLisandro Dalcin 
195abe9303eSLisandro Dalcin /*@
196abe9303eSLisandro Dalcin   PetscPartitionerSetUp - Construct data structures for the PetscPartitioner
197abe9303eSLisandro Dalcin 
198abe9303eSLisandro Dalcin   Collective on PetscPartitioner
199abe9303eSLisandro Dalcin 
200abe9303eSLisandro Dalcin   Input Parameter:
201abe9303eSLisandro Dalcin . part - the PetscPartitioner object to setup
202abe9303eSLisandro Dalcin 
203abe9303eSLisandro Dalcin   Level: developer
204abe9303eSLisandro Dalcin 
205abe9303eSLisandro Dalcin .seealso: PetscPartitionerView(), PetscPartitionerDestroy()
206abe9303eSLisandro Dalcin @*/
207abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part)
208abe9303eSLisandro Dalcin {
209abe9303eSLisandro Dalcin   PetscErrorCode ierr;
210abe9303eSLisandro Dalcin 
211abe9303eSLisandro Dalcin   PetscFunctionBegin;
212abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
213abe9303eSLisandro Dalcin   if (part->ops->setup) {ierr = (*part->ops->setup)(part);CHKERRQ(ierr);}
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   PetscErrorCode ierr;
232abe9303eSLisandro Dalcin 
233abe9303eSLisandro Dalcin   PetscFunctionBegin;
234abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
235abe9303eSLisandro Dalcin   if (part->ops->reset) {ierr = (*part->ops->reset)(part);CHKERRQ(ierr);}
236abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
237abe9303eSLisandro Dalcin }
238abe9303eSLisandro Dalcin 
239abe9303eSLisandro Dalcin /*@
240abe9303eSLisandro Dalcin   PetscPartitionerDestroy - Destroys a PetscPartitioner object
241abe9303eSLisandro Dalcin 
242abe9303eSLisandro Dalcin   Collective on PetscPartitioner
243abe9303eSLisandro Dalcin 
244abe9303eSLisandro Dalcin   Input Parameter:
245abe9303eSLisandro Dalcin . part - the PetscPartitioner object to destroy
246abe9303eSLisandro Dalcin 
247abe9303eSLisandro Dalcin   Level: developer
248abe9303eSLisandro Dalcin 
249abe9303eSLisandro Dalcin .seealso: PetscPartitionerView()
250abe9303eSLisandro Dalcin @*/
251abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part)
252abe9303eSLisandro Dalcin {
253abe9303eSLisandro Dalcin   PetscErrorCode ierr;
254abe9303eSLisandro Dalcin 
255abe9303eSLisandro Dalcin   PetscFunctionBegin;
256abe9303eSLisandro Dalcin   if (!*part) PetscFunctionReturn(0);
257abe9303eSLisandro Dalcin   PetscValidHeaderSpecific((*part), PETSCPARTITIONER_CLASSID, 1);
258abe9303eSLisandro Dalcin 
259ea78f98cSLisandro Dalcin   if (--((PetscObject)(*part))->refct > 0) {*part = NULL; PetscFunctionReturn(0);}
260abe9303eSLisandro Dalcin   ((PetscObject) (*part))->refct = 0;
261abe9303eSLisandro Dalcin 
262abe9303eSLisandro Dalcin   ierr = PetscPartitionerReset(*part);CHKERRQ(ierr);
263abe9303eSLisandro Dalcin 
264abe9303eSLisandro Dalcin   ierr = PetscViewerDestroy(&(*part)->viewer);CHKERRQ(ierr);
265abe9303eSLisandro Dalcin   ierr = PetscViewerDestroy(&(*part)->viewerGraph);CHKERRQ(ierr);
266abe9303eSLisandro Dalcin   if ((*part)->ops->destroy) {ierr = (*(*part)->ops->destroy)(*part);CHKERRQ(ierr);}
267abe9303eSLisandro Dalcin   ierr = PetscHeaderDestroy(part);CHKERRQ(ierr);
268abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
269abe9303eSLisandro Dalcin }
270abe9303eSLisandro Dalcin 
271abe9303eSLisandro Dalcin /*@
272abe9303eSLisandro Dalcin   PetscPartitionerPartition - Partition a graph
273abe9303eSLisandro Dalcin 
274abe9303eSLisandro Dalcin   Collective on PetscPartitioner
275abe9303eSLisandro Dalcin 
276abe9303eSLisandro Dalcin   Input Parameters:
277abe9303eSLisandro Dalcin + part    - The PetscPartitioner
278abe9303eSLisandro Dalcin . nparts  - Number of partitions
279abe9303eSLisandro Dalcin . numVertices - Number of vertices in the local part of the graph
280abe9303eSLisandro Dalcin . start - row pointers for the local part of the graph (CSR style)
281abe9303eSLisandro Dalcin . adjacency - adjacency list (CSR style)
282abe9303eSLisandro Dalcin . vertexSection - PetscSection describing the absolute weight of each local vertex (can be NULL)
283abe9303eSLisandro Dalcin - targetSection - PetscSection describing the absolute weight of each partition (can be NULL)
284abe9303eSLisandro Dalcin 
285abe9303eSLisandro Dalcin   Output Parameters:
286abe9303eSLisandro Dalcin + partSection     - The PetscSection giving the division of points by partition
287abe9303eSLisandro Dalcin - partition       - The list of points by partition
288abe9303eSLisandro Dalcin 
289abe9303eSLisandro Dalcin   Options Database:
290abe9303eSLisandro Dalcin + -petscpartitioner_view - View the partitioner information
291abe9303eSLisandro Dalcin - -petscpartitioner_view_graph - View the graph we are partitioning
292abe9303eSLisandro Dalcin 
293abe9303eSLisandro Dalcin   Notes:
294abe9303eSLisandro 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.
295abe9303eSLisandro 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.
296abe9303eSLisandro Dalcin 
297abe9303eSLisandro Dalcin   Level: developer
298abe9303eSLisandro Dalcin 
299abe9303eSLisandro Dalcin .seealso PetscPartitionerCreate(), PetscSectionCreate(), PetscSectionSetChart(), PetscSectionSetDof()
300abe9303eSLisandro Dalcin @*/
301abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertexSection, PetscSection targetSection, PetscSection partSection, IS *partition)
302abe9303eSLisandro Dalcin {
303abe9303eSLisandro Dalcin   PetscErrorCode ierr;
304abe9303eSLisandro Dalcin 
305abe9303eSLisandro Dalcin   PetscFunctionBegin;
306abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(part, PETSCPARTITIONER_CLASSID, 1);
307abe9303eSLisandro Dalcin   PetscValidLogicalCollectiveInt(part, nparts, 2);
308abe9303eSLisandro Dalcin   if (nparts <= 0) SETERRQ(PetscObjectComm((PetscObject) part), PETSC_ERR_ARG_OUTOFRANGE, "Number of parts must be positive");
309abe9303eSLisandro Dalcin   if (numVertices < 0) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Number of vertices must be non-negative");
310abe9303eSLisandro Dalcin   if (numVertices && !part->noGraph) {
311abe9303eSLisandro Dalcin     PetscValidIntPointer(start, 4);
312abe9303eSLisandro Dalcin     PetscValidIntPointer(start + numVertices, 4);
313abe9303eSLisandro Dalcin     if (start[numVertices]) PetscValidIntPointer(adjacency, 5);
314abe9303eSLisandro Dalcin   }
315abe9303eSLisandro Dalcin   if (vertexSection) {
316abe9303eSLisandro Dalcin     PetscInt s,e;
317abe9303eSLisandro Dalcin 
318abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(vertexSection, PETSC_SECTION_CLASSID, 6);
319abe9303eSLisandro Dalcin     ierr = PetscSectionGetChart(vertexSection, &s, &e);CHKERRQ(ierr);
320abe9303eSLisandro Dalcin     if (s > 0 || e < numVertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid vertexSection chart [%D,%D)",s,e);
321abe9303eSLisandro Dalcin   }
322abe9303eSLisandro Dalcin   if (targetSection) {
323abe9303eSLisandro Dalcin     PetscInt s,e;
324abe9303eSLisandro Dalcin 
325abe9303eSLisandro Dalcin     PetscValidHeaderSpecific(targetSection, PETSC_SECTION_CLASSID, 7);
326abe9303eSLisandro Dalcin     ierr = PetscSectionGetChart(targetSection, &s, &e);CHKERRQ(ierr);
327abe9303eSLisandro Dalcin     if (s > 0 || e < nparts) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Invalid targetSection chart [%D,%D)",s,e);
328abe9303eSLisandro Dalcin   }
329abe9303eSLisandro Dalcin   PetscValidHeaderSpecific(partSection, PETSC_SECTION_CLASSID, 8);
330abe9303eSLisandro Dalcin   PetscValidPointer(partition, 9);
331abe9303eSLisandro Dalcin 
332abe9303eSLisandro Dalcin   ierr = PetscSectionReset(partSection);CHKERRQ(ierr);
333abe9303eSLisandro Dalcin   ierr = PetscSectionSetChart(partSection, 0, nparts);CHKERRQ(ierr);
334abe9303eSLisandro Dalcin   if (nparts == 1) { /* quick */
335abe9303eSLisandro Dalcin     ierr = PetscSectionSetDof(partSection, 0, numVertices);CHKERRQ(ierr);
336abe9303eSLisandro Dalcin     ierr = ISCreateStride(PetscObjectComm((PetscObject)part),numVertices,0,1,partition);CHKERRQ(ierr);
337abe9303eSLisandro Dalcin   } else {
338abe9303eSLisandro Dalcin     if (!part->ops->partition) SETERRQ1(PetscObjectComm((PetscObject) part), PETSC_ERR_SUP, "PetscPartitioner %s has no partitioning method", ((PetscObject)part)->type_name);
339abe9303eSLisandro Dalcin     ierr = (*part->ops->partition)(part, nparts, numVertices, start, adjacency, vertexSection, targetSection, partSection, partition);CHKERRQ(ierr);
340abe9303eSLisandro Dalcin   }
341abe9303eSLisandro Dalcin   ierr = PetscSectionSetUp(partSection);CHKERRQ(ierr);
342abe9303eSLisandro Dalcin   if (part->viewerGraph) {
343abe9303eSLisandro Dalcin     PetscViewer viewer = part->viewerGraph;
344abe9303eSLisandro Dalcin     PetscBool   isascii;
345abe9303eSLisandro Dalcin     PetscInt    v, i;
346abe9303eSLisandro Dalcin     PetscMPIInt rank;
347abe9303eSLisandro Dalcin 
348abe9303eSLisandro Dalcin     ierr = MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank);CHKERRQ(ierr);
349abe9303eSLisandro Dalcin     ierr = PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);CHKERRQ(ierr);
350abe9303eSLisandro Dalcin     if (isascii) {
351abe9303eSLisandro Dalcin       ierr = PetscViewerASCIIPushSynchronized(viewer);CHKERRQ(ierr);
352abe9303eSLisandro Dalcin       ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %D\n", rank, numVertices);CHKERRQ(ierr);
353abe9303eSLisandro Dalcin       for (v = 0; v < numVertices; ++v) {
354abe9303eSLisandro Dalcin         const PetscInt s = start[v];
355abe9303eSLisandro Dalcin         const PetscInt e = start[v+1];
356abe9303eSLisandro Dalcin 
357abe9303eSLisandro Dalcin         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%d]  ", rank);CHKERRQ(ierr);
358abe9303eSLisandro Dalcin         for (i = s; i < e; ++i) {ierr = PetscViewerASCIISynchronizedPrintf(viewer, "%D ", adjacency[i]);CHKERRQ(ierr);}
359abe9303eSLisandro Dalcin         ierr = PetscViewerASCIISynchronizedPrintf(viewer, "[%D-%D)\n", s, e);CHKERRQ(ierr);
360abe9303eSLisandro Dalcin       }
361abe9303eSLisandro Dalcin       ierr = PetscViewerFlush(viewer);CHKERRQ(ierr);
362abe9303eSLisandro Dalcin       ierr = PetscViewerASCIIPopSynchronized(viewer);CHKERRQ(ierr);
363abe9303eSLisandro Dalcin     }
364abe9303eSLisandro Dalcin   }
365abe9303eSLisandro Dalcin   if (part->viewer) {
366abe9303eSLisandro Dalcin     ierr = PetscPartitionerView(part,part->viewer);CHKERRQ(ierr);
367abe9303eSLisandro Dalcin   }
368abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
369abe9303eSLisandro Dalcin }
370abe9303eSLisandro Dalcin 
371abe9303eSLisandro Dalcin /*@
372abe9303eSLisandro Dalcin   PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType().
373abe9303eSLisandro Dalcin 
374abe9303eSLisandro Dalcin   Collective
375abe9303eSLisandro Dalcin 
376abe9303eSLisandro Dalcin   Input Parameter:
377abe9303eSLisandro Dalcin . comm - The communicator for the PetscPartitioner object
378abe9303eSLisandro Dalcin 
379abe9303eSLisandro Dalcin   Output Parameter:
380abe9303eSLisandro Dalcin . part - The PetscPartitioner object
381abe9303eSLisandro Dalcin 
382abe9303eSLisandro Dalcin   Level: beginner
383abe9303eSLisandro Dalcin 
384abe9303eSLisandro Dalcin .seealso: PetscPartitionerSetType(), PETSCPARTITIONERCHACO, PETSCPARTITIONERPARMETIS, PETSCPARTITIONERSHELL, PETSCPARTITIONERSIMPLE, PETSCPARTITIONERGATHER
385abe9303eSLisandro Dalcin @*/
386abe9303eSLisandro Dalcin PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part)
387abe9303eSLisandro Dalcin {
388abe9303eSLisandro Dalcin   PetscPartitioner p;
389abe9303eSLisandro Dalcin   const char       *partitionerType = NULL;
390abe9303eSLisandro Dalcin   PetscErrorCode   ierr;
391abe9303eSLisandro Dalcin 
392abe9303eSLisandro Dalcin   PetscFunctionBegin;
393abe9303eSLisandro Dalcin   PetscValidPointer(part, 2);
394abe9303eSLisandro Dalcin   *part = NULL;
395abe9303eSLisandro Dalcin   ierr = PetscPartitionerInitializePackage();CHKERRQ(ierr);
396abe9303eSLisandro Dalcin 
397abe9303eSLisandro Dalcin   ierr = PetscHeaderCreate(p, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView);CHKERRQ(ierr);
398*d7cc930eSLisandro Dalcin   ierr = PetscPartitionerGetDefaultType(comm, &partitionerType);CHKERRQ(ierr);
399abe9303eSLisandro Dalcin   ierr = PetscPartitionerSetType(p, partitionerType);CHKERRQ(ierr);
400abe9303eSLisandro Dalcin 
401abe9303eSLisandro Dalcin   p->edgeCut = 0;
402abe9303eSLisandro Dalcin   p->balance = 0.0;
403abe9303eSLisandro Dalcin   p->usevwgt = PETSC_TRUE;
404abe9303eSLisandro Dalcin 
405abe9303eSLisandro Dalcin   *part = p;
406abe9303eSLisandro Dalcin   PetscFunctionReturn(0);
407abe9303eSLisandro Dalcin }
408abe9303eSLisandro Dalcin 
409