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