Actual source code: partitioner.c
1: #include <petsc/private/partitionerimpl.h>
3: /*@C
4: PetscPartitionerSetType - Builds a particular PetscPartitioner
6: Collective on PetscPartitioner
8: Input Parameters:
9: + part - The PetscPartitioner object
10: - name - The kind of partitioner
12: Options Database Key:
13: . -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types
15: Note:
16: $ PETSCPARTITIONERCHACO - The Chaco partitioner (--download-chaco)
17: $ PETSCPARTITIONERPARMETIS - The ParMetis partitioner (--download-parmetis)
18: $ PETSCPARTITIONERSHELL - A shell partitioner implemented by the user
19: $ PETSCPARTITIONERSIMPLE - A simple partitioner that divides cells into equal, contiguous chunks
20: $ PETSCPARTITIONERGATHER - Gathers all cells onto process 0
22: Level: intermediate
24: .seealso: PetscPartitionerGetType(), PetscPartitionerCreate()
25: @*/
26: PetscErrorCode PetscPartitionerSetType(PetscPartitioner part, PetscPartitionerType name)
27: {
28: PetscErrorCode (*r)(PetscPartitioner);
29: PetscBool match;
32: PetscObjectTypeCompare((PetscObject) part, name, &match);
33: if (match) return 0;
35: PetscPartitionerRegisterAll();
36: PetscFunctionListFind(PetscPartitionerList, name, &r);
39: if (part->ops->destroy) {
40: (*part->ops->destroy)(part);
41: }
42: part->noGraph = PETSC_FALSE;
43: PetscMemzero(part->ops, sizeof(*part->ops));
44: PetscObjectChangeTypeName((PetscObject) part, name);
45: (*r)(part);
46: return 0;
47: }
49: /*@C
50: PetscPartitionerGetType - Gets the PetscPartitioner type name (as a string) from the object.
52: Not Collective
54: Input Parameter:
55: . part - The PetscPartitioner
57: Output Parameter:
58: . name - The PetscPartitioner type name
60: Level: intermediate
62: .seealso: PetscPartitionerSetType(), PetscPartitionerCreate()
63: @*/
64: PetscErrorCode PetscPartitionerGetType(PetscPartitioner part, PetscPartitionerType *name)
65: {
68: *name = ((PetscObject) part)->type_name;
69: return 0;
70: }
72: /*@C
73: PetscPartitionerViewFromOptions - View from Options
75: Collective on PetscPartitioner
77: Input Parameters:
78: + A - the PetscPartitioner object
79: . obj - Optional object
80: - name - command line option
82: Level: intermediate
83: .seealso: PetscPartitionerView(), PetscObjectViewFromOptions()
84: @*/
85: PetscErrorCode PetscPartitionerViewFromOptions(PetscPartitioner A,PetscObject obj,const char name[])
86: {
88: PetscObjectViewFromOptions((PetscObject)A,obj,name);
89: return 0;
90: }
92: /*@
93: PetscPartitionerView - Views a PetscPartitioner
95: Collective on PetscPartitioner
97: Input Parameters:
98: + part - the PetscPartitioner object to view
99: - v - the viewer
101: Level: developer
103: .seealso: PetscPartitionerDestroy()
104: @*/
105: PetscErrorCode PetscPartitionerView(PetscPartitioner part, PetscViewer v)
106: {
107: PetscMPIInt size;
108: PetscBool isascii;
111: if (!v) PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject) part), &v);
112: PetscObjectTypeCompare((PetscObject) v, PETSCVIEWERASCII, &isascii);
113: if (isascii) {
114: MPI_Comm_size(PetscObjectComm((PetscObject) part), &size);
115: PetscViewerASCIIPrintf(v, "Graph Partitioner: %d MPI Process%s\n", size, size > 1 ? "es" : "");
116: PetscViewerASCIIPrintf(v, " type: %s\n", ((PetscObject)part)->type_name);
117: PetscViewerASCIIPrintf(v, " edge cut: %D\n", part->edgeCut);
118: PetscViewerASCIIPrintf(v, " balance: %.2g\n", part->balance);
119: PetscViewerASCIIPrintf(v, " use vertex weights: %d\n", part->usevwgt);
120: }
121: if (part->ops->view) (*part->ops->view)(part, v);
122: return 0;
123: }
125: static PetscErrorCode PetscPartitionerGetDefaultType(MPI_Comm comm, const char **defaultType)
126: {
127: PetscMPIInt size;
129: MPI_Comm_size(comm, &size);
130: if (size == 1) {
131: *defaultType = PETSCPARTITIONERSIMPLE;
132: } else {
133: #if defined(PETSC_HAVE_PARMETIS)
134: *defaultType = PETSCPARTITIONERPARMETIS;
135: #elif defined(PETSC_HAVE_PTSCOTCH)
136: *defaultType = PETSCPARTITIONERPTSCOTCH;
137: #elif defined(PETSC_HAVE_CHACO)
138: *defaultType = PETSCPARTITIONERCHACO;
139: #else
140: *defaultType = PETSCPARTITIONERSIMPLE;
141: #endif
142: }
143: return 0;
144: }
146: /*@
147: PetscPartitionerSetFromOptions - sets parameters in a PetscPartitioner from the options database
149: Collective on PetscPartitioner
151: Input Parameter:
152: . part - the PetscPartitioner object to set options for
154: Options Database Keys:
155: + -petscpartitioner_type <type> - Sets the PetscPartitioner type; use -help for a list of available types
156: . -petscpartitioner_use_vertex_weights - Uses weights associated with the graph vertices
157: - -petscpartitioner_view_graph - View the graph each time PetscPartitionerPartition is called. Viewer can be customized, see PetscOptionsGetViewer()
159: Level: developer
161: .seealso: PetscPartitionerView(), PetscPartitionerSetType(), PetscPartitionerPartition()
162: @*/
163: PetscErrorCode PetscPartitionerSetFromOptions(PetscPartitioner part)
164: {
165: const char *currentType = NULL;
166: char name[256];
167: PetscBool flg;
171: PetscObjectOptionsBegin((PetscObject) part);
172: PetscPartitionerGetType(part, ¤tType);
173: PetscOptionsFList("-petscpartitioner_type", "Graph partitioner", "PetscPartitionerSetType", PetscPartitionerList, currentType, name, sizeof(name), &flg);
174: if (flg) {
175: PetscPartitionerSetType(part, name);
176: }
177: PetscOptionsBool("-petscpartitioner_use_vertex_weights","Use vertex weights","",part->usevwgt,&part->usevwgt,NULL);
178: if (part->ops->setfromoptions) {
179: (*part->ops->setfromoptions)(PetscOptionsObject,part);
180: }
181: PetscViewerDestroy(&part->viewer);
182: PetscViewerDestroy(&part->viewerGraph);
183: PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view", &part->viewer, NULL, NULL);
184: PetscOptionsGetViewer(((PetscObject) part)->comm, ((PetscObject) part)->options, ((PetscObject) part)->prefix, "-petscpartitioner_view_graph", &part->viewerGraph, NULL, &part->viewGraph);
185: /* process any options handlers added with PetscObjectAddOptionsHandler() */
186: PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject) part);
187: PetscOptionsEnd();
188: return 0;
189: }
191: /*@
192: PetscPartitionerSetUp - Construct data structures for the PetscPartitioner
194: Collective on PetscPartitioner
196: Input Parameter:
197: . part - the PetscPartitioner object to setup
199: Level: developer
201: .seealso: PetscPartitionerView(), PetscPartitionerDestroy()
202: @*/
203: PetscErrorCode PetscPartitionerSetUp(PetscPartitioner part)
204: {
206: if (part->ops->setup) (*part->ops->setup)(part);
207: return 0;
208: }
210: /*@
211: PetscPartitionerReset - Resets data structures for the PetscPartitioner
213: Collective on PetscPartitioner
215: Input Parameter:
216: . part - the PetscPartitioner object to reset
218: Level: developer
220: .seealso: PetscPartitionerSetUp(), PetscPartitionerDestroy()
221: @*/
222: PetscErrorCode PetscPartitionerReset(PetscPartitioner part)
223: {
225: if (part->ops->reset) (*part->ops->reset)(part);
226: return 0;
227: }
229: /*@
230: PetscPartitionerDestroy - Destroys a PetscPartitioner object
232: Collective on PetscPartitioner
234: Input Parameter:
235: . part - the PetscPartitioner object to destroy
237: Level: developer
239: .seealso: PetscPartitionerView()
240: @*/
241: PetscErrorCode PetscPartitionerDestroy(PetscPartitioner *part)
242: {
243: if (!*part) return 0;
246: if (--((PetscObject)(*part))->refct > 0) {*part = NULL; return 0;}
247: ((PetscObject) (*part))->refct = 0;
249: PetscPartitionerReset(*part);
251: PetscViewerDestroy(&(*part)->viewer);
252: PetscViewerDestroy(&(*part)->viewerGraph);
253: if ((*part)->ops->destroy) (*(*part)->ops->destroy)(*part);
254: PetscHeaderDestroy(part);
255: return 0;
256: }
258: /*@
259: PetscPartitionerPartition - Partition a graph
261: Collective on PetscPartitioner
263: Input Parameters:
264: + part - The PetscPartitioner
265: . nparts - Number of partitions
266: . numVertices - Number of vertices in the local part of the graph
267: . start - row pointers for the local part of the graph (CSR style)
268: . adjacency - adjacency list (CSR style)
269: . vertexSection - PetscSection describing the absolute weight of each local vertex (can be NULL)
270: - targetSection - PetscSection describing the absolute weight of each partition (can be NULL)
272: Output Parameters:
273: + partSection - The PetscSection giving the division of points by partition
274: - partition - The list of points by partition
276: Options Database:
277: + -petscpartitioner_view - View the partitioner information
278: - -petscpartitioner_view_graph - View the graph we are partitioning
280: Notes:
281: 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.
282: 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.
284: Level: developer
286: .seealso PetscPartitionerCreate(), PetscPartitionerSetType(), PetscSectionCreate(), PetscSectionSetChart(), PetscSectionSetDof()
287: @*/
288: PetscErrorCode PetscPartitionerPartition(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertexSection, PetscSection targetSection, PetscSection partSection, IS *partition)
289: {
294: if (numVertices && !part->noGraph) {
298: }
299: if (vertexSection) {
300: PetscInt s,e;
303: PetscSectionGetChart(vertexSection, &s, &e);
305: }
306: if (targetSection) {
307: PetscInt s,e;
310: PetscSectionGetChart(targetSection, &s, &e);
312: }
316: PetscSectionReset(partSection);
317: PetscSectionSetChart(partSection, 0, nparts);
318: if (nparts == 1) { /* quick */
319: PetscSectionSetDof(partSection, 0, numVertices);
320: ISCreateStride(PetscObjectComm((PetscObject)part),numVertices,0,1,partition);
321: } else {
323: (*part->ops->partition)(part, nparts, numVertices, start, adjacency, vertexSection, targetSection, partSection, partition);
324: }
325: PetscSectionSetUp(partSection);
326: if (part->viewerGraph) {
327: PetscViewer viewer = part->viewerGraph;
328: PetscBool isascii;
329: PetscInt v, i;
330: PetscMPIInt rank;
332: MPI_Comm_rank(PetscObjectComm((PetscObject) viewer), &rank);
333: PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &isascii);
334: if (isascii) {
335: PetscViewerASCIIPushSynchronized(viewer);
336: PetscViewerASCIISynchronizedPrintf(viewer, "[%d]Nv: %D\n", rank, numVertices);
337: for (v = 0; v < numVertices; ++v) {
338: const PetscInt s = start[v];
339: const PetscInt e = start[v+1];
341: PetscViewerASCIISynchronizedPrintf(viewer, "[%d] ", rank);
342: for (i = s; i < e; ++i) PetscViewerASCIISynchronizedPrintf(viewer, "%D ", adjacency[i]);
343: PetscViewerASCIISynchronizedPrintf(viewer, "[%D-%D)\n", s, e);
344: }
345: PetscViewerFlush(viewer);
346: PetscViewerASCIIPopSynchronized(viewer);
347: }
348: }
349: if (part->viewer) {
350: PetscPartitionerView(part,part->viewer);
351: }
352: return 0;
353: }
355: /*@
356: PetscPartitionerCreate - Creates an empty PetscPartitioner object. The type can then be set with PetscPartitionerSetType().
358: Collective
360: Input Parameter:
361: . comm - The communicator for the PetscPartitioner object
363: Output Parameter:
364: . part - The PetscPartitioner object
366: Level: beginner
368: .seealso: PetscPartitionerSetType(), PetscPartitionerDestroy()
369: @*/
370: PetscErrorCode PetscPartitionerCreate(MPI_Comm comm, PetscPartitioner *part)
371: {
372: PetscPartitioner p;
373: const char *partitionerType = NULL;
376: *part = NULL;
377: PetscPartitionerInitializePackage();
379: PetscHeaderCreate(p, PETSCPARTITIONER_CLASSID, "PetscPartitioner", "Graph Partitioner", "PetscPartitioner", comm, PetscPartitionerDestroy, PetscPartitionerView);
380: PetscPartitionerGetDefaultType(comm, &partitionerType);
381: PetscPartitionerSetType(p, partitionerType);
383: p->edgeCut = 0;
384: p->balance = 0.0;
385: p->usevwgt = PETSC_TRUE;
387: *part = p;
388: return 0;
389: }