Actual source code: partshell.c
1: #include <petsc/private/partitionerimpl.h>
3: typedef struct {
4: PetscSection section; /* Sizes for each partition */
5: IS partition; /* Points in each partition */
6: PetscBool random; /* Flag for a random partition */
7: } PetscPartitioner_Shell;
9: static PetscErrorCode PetscPartitionerReset_Shell(PetscPartitioner part)
10: {
11: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
13: PetscSectionDestroy(&p->section);
14: ISDestroy(&p->partition);
15: return 0;
16: }
18: static PetscErrorCode PetscPartitionerDestroy_Shell(PetscPartitioner part)
19: {
20: PetscPartitionerReset_Shell(part);
21: PetscFree(part->data);
22: return 0;
23: }
25: static PetscErrorCode PetscPartitionerView_Shell_ASCII(PetscPartitioner part, PetscViewer viewer)
26: {
27: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
29: if (p->random) {
30: PetscViewerASCIIPushTab(viewer);
31: PetscViewerASCIIPrintf(viewer, "using random partition\n");
32: PetscViewerASCIIPopTab(viewer);
33: }
34: return 0;
35: }
37: static PetscErrorCode PetscPartitionerView_Shell(PetscPartitioner part, PetscViewer viewer)
38: {
39: PetscBool iascii;
43: PetscObjectTypeCompare((PetscObject) viewer, PETSCVIEWERASCII, &iascii);
44: if (iascii) PetscPartitionerView_Shell_ASCII(part, viewer);
45: return 0;
46: }
48: static PetscErrorCode PetscPartitionerSetFromOptions_Shell(PetscOptionItems *PetscOptionsObject, PetscPartitioner part)
49: {
50: PetscBool random = PETSC_FALSE, set;
52: PetscOptionsHead(PetscOptionsObject, "PetscPartitioner Shell Options");
53: PetscPartitionerShellGetRandom(part, &random);
54: PetscOptionsBool("-petscpartitioner_shell_random", "Use a random partition", "PetscPartitionerView", PETSC_FALSE, &random, &set);
55: if (set) PetscPartitionerShellSetRandom(part, random);
56: PetscOptionsTail();
57: return 0;
58: }
60: static PetscErrorCode PetscPartitionerPartition_Shell(PetscPartitioner part, PetscInt nparts, PetscInt numVertices, PetscInt start[], PetscInt adjacency[], PetscSection vertSection, PetscSection targetSection, PetscSection partSection, IS *partition)
61: {
62: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
63: PetscInt np;
65: if (p->random) {
66: PetscRandom r;
67: PetscInt *sizes, *points, v, p;
68: PetscMPIInt rank;
70: MPI_Comm_rank(PetscObjectComm((PetscObject) part), &rank);
71: PetscRandomCreate(PETSC_COMM_SELF, &r);
72: PetscRandomSetInterval(r, 0.0, (PetscScalar) nparts);
73: PetscRandomSetFromOptions(r);
74: PetscCalloc2(nparts, &sizes, numVertices, &points);
75: for (v = 0; v < numVertices; ++v) {points[v] = v;}
76: for (p = 0; p < nparts; ++p) {sizes[p] = numVertices/nparts + (PetscInt) (p < numVertices % nparts);}
77: for (v = numVertices-1; v > 0; --v) {
78: PetscReal val;
79: PetscInt w, tmp;
81: PetscRandomSetInterval(r, 0.0, (PetscScalar) (v+1));
82: PetscRandomGetValueReal(r, &val);
83: w = PetscFloorReal(val);
84: tmp = points[v];
85: points[v] = points[w];
86: points[w] = tmp;
87: }
88: PetscRandomDestroy(&r);
89: PetscPartitionerShellSetPartition(part, nparts, sizes, points);
90: PetscFree2(sizes, points);
91: }
93: PetscSectionGetChart(p->section, NULL, &np);
95: ISGetLocalSize(p->partition, &np);
97: PetscSectionCopy(p->section, partSection);
98: *partition = p->partition;
99: PetscObjectReference((PetscObject) p->partition);
100: return 0;
101: }
103: static PetscErrorCode PetscPartitionerInitialize_Shell(PetscPartitioner part)
104: {
105: part->noGraph = PETSC_TRUE; /* PetscPartitionerShell cannot overload the partition call, so it is safe for now */
106: part->ops->view = PetscPartitionerView_Shell;
107: part->ops->setfromoptions = PetscPartitionerSetFromOptions_Shell;
108: part->ops->reset = PetscPartitionerReset_Shell;
109: part->ops->destroy = PetscPartitionerDestroy_Shell;
110: part->ops->partition = PetscPartitionerPartition_Shell;
111: return 0;
112: }
114: /*MC
115: PETSCPARTITIONERSHELL = "shell" - A PetscPartitioner object
117: Level: intermediate
119: Options Database Keys:
120: . -petscpartitioner_shell_random - Use a random partition
122: .seealso: PetscPartitionerType, PetscPartitionerCreate(), PetscPartitionerSetType()
123: M*/
125: PETSC_EXTERN PetscErrorCode PetscPartitionerCreate_Shell(PetscPartitioner part)
126: {
127: PetscPartitioner_Shell *p;
130: PetscNewLog(part, &p);
131: part->data = p;
133: PetscPartitionerInitialize_Shell(part);
134: p->random = PETSC_FALSE;
135: return 0;
136: }
138: /*@C
139: PetscPartitionerShellSetPartition - Set an artifical partition for a mesh
141: Collective on PetscPartitioner
143: Input Parameters:
144: + part - The PetscPartitioner
145: . size - The number of partitions
146: . sizes - array of length size (or NULL) providing the number of points in each partition
147: - points - array of length sum(sizes) (may be NULL iff sizes is NULL), a permutation of the points that groups those assigned to each partition in order (i.e., partition 0 first, partition 1 next, etc.)
149: Level: developer
151: Notes:
152: It is safe to free the sizes and points arrays after use in this routine.
154: .seealso DMPlexDistribute(), PetscPartitionerCreate()
155: @*/
156: PetscErrorCode PetscPartitionerShellSetPartition(PetscPartitioner part, PetscInt size, const PetscInt sizes[], const PetscInt points[])
157: {
158: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
159: PetscInt proc, numPoints;
164: PetscSectionDestroy(&p->section);
165: ISDestroy(&p->partition);
166: PetscSectionCreate(PetscObjectComm((PetscObject) part), &p->section);
167: PetscSectionSetChart(p->section, 0, size);
168: if (sizes) {
169: for (proc = 0; proc < size; ++proc) {
170: PetscSectionSetDof(p->section, proc, sizes[proc]);
171: }
172: }
173: PetscSectionSetUp(p->section);
174: PetscSectionGetStorageSize(p->section, &numPoints);
175: ISCreateGeneral(PetscObjectComm((PetscObject) part), numPoints, points, PETSC_COPY_VALUES, &p->partition);
176: return 0;
177: }
179: /*@
180: PetscPartitionerShellSetRandom - Set the flag to use a random partition
182: Collective on PetscPartitioner
184: Input Parameters:
185: + part - The PetscPartitioner
186: - random - The flag to use a random partition
188: Level: intermediate
190: .seealso PetscPartitionerShellGetRandom(), PetscPartitionerCreate()
191: @*/
192: PetscErrorCode PetscPartitionerShellSetRandom(PetscPartitioner part, PetscBool random)
193: {
194: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
197: p->random = random;
198: return 0;
199: }
201: /*@
202: PetscPartitionerShellGetRandom - get the flag to use a random partition
204: Collective on PetscPartitioner
206: Input Parameter:
207: . part - The PetscPartitioner
209: Output Parameter:
210: . random - The flag to use a random partition
212: Level: intermediate
214: .seealso PetscPartitionerShellSetRandom(), PetscPartitionerCreate()
215: @*/
216: PetscErrorCode PetscPartitionerShellGetRandom(PetscPartitioner part, PetscBool *random)
217: {
218: PetscPartitioner_Shell *p = (PetscPartitioner_Shell *) part->data;
222: *random = p->random;
223: return 0;
224: }