Actual source code: ex82.c
1: static char help[] = "Partition a tiny grid using hierarchical partitioning.\n\n";
3: /*
4: Include "petscmat.h" so that we can use matrices. Note that this file
5: automatically includes:
6: petscsys.h - base PETSc routines
7: petscvec.h - vectors
8: petscis.h - index sets
9: */
10: #include <petscmat.h>
12: int main(int argc, char **args)
13: {
14: Mat A;
15: PetscMPIInt rank, size;
16: PetscInt *ia, *ja;
17: MatPartitioning part;
18: IS is, isn, isrows;
19: IS coarseparts, fineparts;
20: MPI_Comm comm;
22: PetscFunctionBeginUser;
23: PetscCall(PetscInitialize(&argc, &args, NULL, help));
24: comm = PETSC_COMM_WORLD;
25: PetscCallMPI(MPI_Comm_size(comm, &size));
26: PetscCheck(size == 4, comm, PETSC_ERR_WRONG_MPI_SIZE, "Must run with 4 processors");
27: PetscCallMPI(MPI_Comm_rank(comm, &rank));
29: PetscCall(PetscMalloc1(5, &ia));
30: PetscCall(PetscMalloc1(16, &ja));
31: if (rank == 0) {
32: ja[0] = 1;
33: ja[1] = 4;
34: ja[2] = 0;
35: ja[3] = 2;
36: ja[4] = 5;
37: ja[5] = 1;
38: ja[6] = 3;
39: ja[7] = 6;
40: ja[8] = 2;
41: ja[9] = 7;
42: ia[0] = 0;
43: ia[1] = 2;
44: ia[2] = 5;
45: ia[3] = 8;
46: ia[4] = 10;
47: } else if (rank == 1) {
48: ja[0] = 0;
49: ja[1] = 5;
50: ja[2] = 8;
51: ja[3] = 1;
52: ja[4] = 4;
53: ja[5] = 6;
54: ja[6] = 9;
55: ja[7] = 2;
56: ja[8] = 5;
57: ja[9] = 7;
58: ja[10] = 10;
59: ja[11] = 3;
60: ja[12] = 6;
61: ja[13] = 11;
62: ia[0] = 0;
63: ia[1] = 3;
64: ia[2] = 7;
65: ia[3] = 11;
66: ia[4] = 14;
67: } else if (rank == 2) {
68: ja[0] = 4;
69: ja[1] = 9;
70: ja[2] = 12;
71: ja[3] = 5;
72: ja[4] = 8;
73: ja[5] = 10;
74: ja[6] = 13;
75: ja[7] = 6;
76: ja[8] = 9;
77: ja[9] = 11;
78: ja[10] = 14;
79: ja[11] = 7;
80: ja[12] = 10;
81: ja[13] = 15;
82: ia[0] = 0;
83: ia[1] = 3;
84: ia[2] = 7;
85: ia[3] = 11;
86: ia[4] = 14;
87: } else {
88: ja[0] = 8;
89: ja[1] = 13;
90: ja[2] = 9;
91: ja[3] = 12;
92: ja[4] = 14;
93: ja[5] = 10;
94: ja[6] = 13;
95: ja[7] = 15;
96: ja[8] = 11;
97: ja[9] = 14;
98: ia[0] = 0;
99: ia[1] = 2;
100: ia[2] = 5;
101: ia[3] = 8;
102: ia[4] = 10;
103: }
104: PetscCall(MatCreateMPIAdj(comm, 4, 16, ia, ja, NULL, &A));
105: PetscCall(MatView(A, PETSC_VIEWER_STDOUT_WORLD));
106: /*
107: Partition the graph of the matrix
108: */
109: PetscCall(MatPartitioningCreate(comm, &part));
110: PetscCall(MatPartitioningSetAdjacency(part, A));
111: PetscCall(MatPartitioningSetType(part, MATPARTITIONINGHIERARCH));
112: PetscCall(MatPartitioningHierarchicalSetNcoarseparts(part, 2));
113: PetscCall(MatPartitioningHierarchicalSetNfineparts(part, 2));
114: PetscCall(MatPartitioningSetFromOptions(part));
115: /* get new processor owner number of each vertex */
116: PetscCall(MatPartitioningApply(part, &is));
117: /* coarse parts */
118: PetscCall(MatPartitioningHierarchicalGetCoarseparts(part, &coarseparts));
119: PetscCall(ISView(coarseparts, PETSC_VIEWER_STDOUT_WORLD));
120: /* fine parts */
121: PetscCall(MatPartitioningHierarchicalGetFineparts(part, &fineparts));
122: PetscCall(ISView(fineparts, PETSC_VIEWER_STDOUT_WORLD));
123: /* partitioning */
124: PetscCall(ISView(is, PETSC_VIEWER_STDOUT_WORLD));
125: /* get new global number of each old global number */
126: PetscCall(ISPartitioningToNumbering(is, &isn));
127: PetscCall(ISView(isn, PETSC_VIEWER_STDOUT_WORLD));
128: PetscCall(ISBuildTwoSided(is, NULL, &isrows));
129: PetscCall(ISView(isrows, PETSC_VIEWER_STDOUT_WORLD));
130: PetscCall(ISDestroy(&is));
131: PetscCall(ISDestroy(&coarseparts));
132: PetscCall(ISDestroy(&fineparts));
133: PetscCall(ISDestroy(&isrows));
134: PetscCall(ISDestroy(&isn));
135: PetscCall(MatPartitioningDestroy(&part));
136: /*
137: Free work space. All PETSc objects should be destroyed when they
138: are no longer needed.
139: */
140: PetscCall(MatDestroy(&A));
141: PetscCall(PetscFinalize());
142: return 0;
143: }
145: /*TEST
147: test:
148: nsize: 4
149: requires: parmetis
150: TODO: tests cannot use ParMETIS because it produces different results on different machines
152: TEST*/