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