xref: /petsc/src/dm/partitioner/tests/ex33.c (revision 2364c0ea60aac9ca02209fd54097e2f2d71ae94a)
1 static char help[] = "Tests PetscPartitioner.\n\n";
2 
3 #include <petscpartitioner.h>
4 
main(int argc,char ** argv)5 int main(int argc, char **argv)
6 {
7   PetscPartitioner p;
8   PetscSection     partSection, vertexSection = NULL, targetSection = NULL;
9   IS               partition, is;
10   PetscMPIInt      size, rank;
11   PetscInt         nparts, i;
12   PetscInt         nv      = 4;
13   PetscInt         vv[5]   = {0, 2, 4, 6, 8};
14   PetscInt         vadj[8] = {3, 1, 0, 2, 1, 3, 2, 0};
15   PetscBool        sequential;
16   PetscBool        vwgts = PETSC_FALSE;
17   PetscBool        pwgts = PETSC_FALSE;
18 
19   PetscFunctionBeginUser;
20   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
21   PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
22   PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
23   nparts = size;
24   PetscCall(PetscOptionsGetInt(NULL, NULL, "-nparts", &nparts, NULL));
25   PetscCall(PetscOptionsGetBool(NULL, NULL, "-vwgts", &vwgts, NULL));
26   PetscCall(PetscOptionsGetBool(NULL, NULL, "-pwgts", &pwgts, NULL));
27 
28   /* create PetscPartitioner */
29   PetscCall(PetscPartitionerCreate(PETSC_COMM_WORLD, &p));
30   PetscCall(PetscPartitionerSetType(p, PETSCPARTITIONERSIMPLE));
31   PetscCall(PetscPartitionerSetFromOptions(p));
32 
33   /* create partition section */
34   PetscCall(PetscSectionCreate(PETSC_COMM_WORLD, &partSection));
35 
36   if (vwgts) { /* create vertex weights section */
37     PetscCall(PetscSectionCreate(PETSC_COMM_WORLD, &vertexSection));
38     PetscCall(PetscSectionSetChart(vertexSection, 0, nv));
39     for (i = 0; i < nv; i++) PetscCall(PetscSectionSetDof(vertexSection, i, 1));
40     PetscCall(PetscSectionSetUp(vertexSection));
41   }
42 
43   if (pwgts) { /* create partition weights section */
44     PetscCall(PetscSectionCreate(PETSC_COMM_WORLD, &targetSection));
45     PetscCall(PetscSectionSetChart(targetSection, 0, nparts));
46     for (i = 0; i < nparts; i++) PetscCall(PetscSectionSetDof(targetSection, i, 1));
47     PetscCall(PetscSectionSetUp(targetSection));
48   }
49 
50   if (PetscDefined(USE_LOG)) { /* Test logging */
51     PetscLogEvent event;
52 
53     PetscCall(PetscLogEventRegister("MyPartitionerEvent", PETSCPARTITIONER_CLASSID, &event));
54     { /* PetscLogEventExcludeClass is broken, new events are not deactivated */
55       char      logList[256];
56       PetscBool opt, pkg;
57 
58       PetscCall(PetscOptionsGetString(NULL, NULL, "-log_exclude", logList, sizeof(logList), &opt));
59       if (opt) {
60         PetscCall(PetscStrInList("partitioner", logList, ',', &pkg));
61         if (pkg) PetscCall(PetscLogEventExcludeClass(PETSCPARTITIONER_CLASSID));
62       }
63     }
64     PetscCall(PetscLogEventBegin(event, p, NULL, NULL, NULL));
65     PetscCall(PetscLogEventEnd(event, p, NULL, NULL, NULL));
66   }
67 
68   /* test setup and reset */
69   PetscCall(PetscPartitionerSetUp(p));
70   PetscCall(PetscPartitionerReset(p));
71 
72   /* test partitioning an empty graph */
73   PetscCall(PetscPartitionerPartition(p, nparts, 0, NULL, NULL, vertexSection, NULL, targetSection, partSection, &partition));
74   PetscCall(PetscObjectSetName((PetscObject)partSection, "NULL SECTION"));
75   PetscCall(PetscSectionView(partSection, NULL));
76   PetscCall(ISOnComm(partition, PETSC_COMM_WORLD, PETSC_USE_POINTER, &is));
77   PetscCall(PetscObjectSetName((PetscObject)is, "NULL PARTITION"));
78   PetscCall(ISView(is, NULL));
79   PetscCall(ISDestroy(&is));
80   PetscCall(ISDestroy(&partition));
81 
82   /* test view from options */
83   PetscCall(PetscPartitionerViewFromOptions(p, NULL, "-part_view"));
84 
85   /* test partitioning a graph on one process only (not main) */
86   if (rank == size - 1) {
87     PetscCall(PetscPartitionerPartition(p, nparts, nv, vv, vadj, vertexSection, NULL, targetSection, partSection, &partition));
88   } else {
89     PetscCall(PetscPartitionerPartition(p, nparts, 0, NULL, NULL, vertexSection, NULL, targetSection, partSection, &partition));
90   }
91   PetscCall(PetscObjectSetName((PetscObject)partSection, "SEQ SECTION"));
92   PetscCall(PetscSectionView(partSection, NULL));
93   PetscCall(ISOnComm(partition, PETSC_COMM_WORLD, PETSC_USE_POINTER, &is));
94   PetscCall(PetscObjectSetName((PetscObject)is, "SEQ PARTITION"));
95   PetscCall(ISView(is, NULL));
96   PetscCall(ISDestroy(&is));
97   PetscCall(ISDestroy(&partition));
98 
99   PetscCall(PetscObjectTypeCompareAny((PetscObject)p, &sequential, PETSCPARTITIONERCHACO, NULL));
100   if (sequential) goto finally;
101 
102   /* test partitioning a graph on a subset of the processes only */
103   if (rank % 2) {
104     PetscCall(PetscPartitionerPartition(p, nparts, 0, NULL, NULL, NULL, NULL, targetSection, partSection, &partition));
105   } else {
106     PetscInt i, totv = nv * ((size + 1) / 2), *pvadj;
107 
108     PetscCall(PetscMalloc1(2 * nv, &pvadj));
109     for (i = 0; i < nv; i++) {
110       pvadj[2 * i]     = (nv * (rank / 2) + totv + i - 1) % totv;
111       pvadj[2 * i + 1] = (nv * (rank / 2) + totv + i + 1) % totv;
112     }
113     PetscCall(PetscPartitionerPartition(p, nparts, nv, vv, pvadj, NULL, NULL, targetSection, partSection, &partition));
114     PetscCall(PetscFree(pvadj));
115   }
116   PetscCall(PetscObjectSetName((PetscObject)partSection, "PARVOID SECTION"));
117   PetscCall(PetscSectionView(partSection, NULL));
118   PetscCall(ISOnComm(partition, PETSC_COMM_WORLD, PETSC_USE_POINTER, &is));
119   PetscCall(PetscObjectSetName((PetscObject)is, "PARVOID PARTITION"));
120   PetscCall(ISView(is, NULL));
121   PetscCall(ISDestroy(&is));
122   PetscCall(ISDestroy(&partition));
123 
124 finally:
125   PetscCall(PetscSectionDestroy(&partSection));
126   PetscCall(PetscSectionDestroy(&vertexSection));
127   PetscCall(PetscSectionDestroy(&targetSection));
128   PetscCall(PetscPartitionerDestroy(&p));
129   PetscCall(PetscFinalize());
130   return 0;
131 }
132 
133 /*TEST
134 
135   test:
136     suffix: default
137 
138   testset:
139     requires: defined(PETSC_USE_LOG)
140     args: -petscpartitioner_type simple -log_view
141     filter: grep MyPartitionerEvent | cut -d " " -f 1
142     test:
143        suffix: log_include
144     test:
145       suffix: log_exclude
146       args: -log_exclude partitioner
147       output_file: output/empty.out
148 
149   test:
150     suffix: simple
151     nsize: {{1 2 3}separate output}
152     args: -nparts {{1 2 3}separate output} -pwgts {{false true}separate output} -petscpartitioner_type simple -petscpartitioner_view
153 
154   test:
155     suffix: shell
156     nsize: {{1 2 3}separate output}
157     args: -nparts {{1 2 3}separate output} -petscpartitioner_type shell -petscpartitioner_shell_random -petscpartitioner_view
158 
159   test:
160     suffix: gather
161     nsize: {{1 2 3}separate output}
162     args: -nparts {{1 2 3}separate output} -petscpartitioner_type gather -petscpartitioner_view -petscpartitioner_view_graph
163 
164   test:
165     requires: parmetis
166     suffix: parmetis
167     nsize: {{1 2 3}separate output}
168     args: -nparts {{1 2 3}separate output} -pwgts {{false true}} -vwgts {{false true}}
169     args: -petscpartitioner_type parmetis -petscpartitioner_view -petscpartitioner_view_graph
170 
171   test:
172     requires: parmetis
173     suffix: parmetis_type
174     nsize: {{1 2}}
175     args: -petscpartitioner_type parmetis -part_view
176     args: -petscpartitioner_parmetis_type {{kway rb}separate output}
177     filter: grep "ParMetis type"
178 
179   test:
180     requires: ptscotch
181     suffix: ptscotch
182     nsize: {{1 2 3}separate output}
183     args: -nparts {{1 2 3}separate output} -pwgts {{false true}separate output} -vwgts {{false true}}
184     args: -petscpartitioner_type ptscotch -petscpartitioner_view -petscpartitioner_view_graph
185 
186   test:
187     requires: ptscotch
188     suffix: ptscotch_strategy
189     nsize: {{1 2}}
190     args: -petscpartitioner_type ptscotch -part_view
191     args: -petscpartitioner_ptscotch_strategy {{DEFAULT QUALITY SPEED BALANCE SAFETY SCALABILITY RECURSIVE REMAP}separate output}
192     filter: grep "partitioning strategy"
193 
194   test:
195     requires: chaco
196     suffix: chaco
197     nsize: {{1 2 3}separate output}
198     args: -nparts {{1}separate output} -petscpartitioner_type chaco -petscpartitioner_view -petscpartitioner_view_graph
199 
200   test:
201     TODO: non reproducible (uses C stdlib rand())
202     requires: chaco
203     suffix: chaco
204     nsize: {{1 2 3}separate output}
205     args: -nparts {{2 3}separate output} -petscpartitioner_type chaco -petscpartitioner_view -petscpartitioner_view_graph
206 
207 TEST*/
208