1 /* 2 * ex193.c 3 * 4 * Created on: Jul 29, 2015 5 * Author: Fande Kong fdkong.jd@gmail.com 6 */ 7 /* 8 * An example demonstrates how to use hierarchical partitioning approach 9 */ 10 11 #include <petscmat.h> 12 13 static char help[] = "Illustrates use of hierarchical partitioning.\n"; 14 15 int main(int argc, char **args) 16 { 17 Mat A; /* matrix */ 18 PetscInt m, n; /* mesh dimensions in x- and y- directions */ 19 PetscInt i, j, Ii, J, Istart, Iend; 20 PetscMPIInt size; 21 PetscScalar v; 22 MatPartitioning part; 23 IS coarseparts, fineparts; 24 IS is, isn, isrows; 25 MPI_Comm comm; 26 27 PetscFunctionBeginUser; 28 PetscCall(PetscInitialize(&argc, &args, (char *)0, help)); 29 comm = PETSC_COMM_WORLD; 30 PetscCallMPI(MPI_Comm_size(comm, &size)); 31 PetscOptionsBegin(comm, NULL, "ex193", "hierarchical partitioning"); 32 m = 15; 33 PetscCall(PetscOptionsInt("-M", "Number of mesh points in the x-direction", "partitioning", m, &m, NULL)); 34 n = 15; 35 PetscCall(PetscOptionsInt("-N", "Number of mesh points in the y-direction", "partitioning", n, &n, NULL)); 36 PetscOptionsEnd(); 37 38 /* 39 Assemble the matrix for the five point stencil (finite difference), YET AGAIN 40 */ 41 PetscCall(MatCreate(comm, &A)); 42 PetscCall(MatSetSizes(A, PETSC_DECIDE, PETSC_DECIDE, m * n, m * n)); 43 PetscCall(MatSetFromOptions(A)); 44 PetscCall(MatSetUp(A)); 45 PetscCall(MatGetOwnershipRange(A, &Istart, &Iend)); 46 for (Ii = Istart; Ii < Iend; Ii++) { 47 v = -1.0; 48 i = Ii / n; 49 j = Ii - i * n; 50 if (i > 0) { 51 J = Ii - n; 52 PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 53 } 54 if (i < m - 1) { 55 J = Ii + n; 56 PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 57 } 58 if (j > 0) { 59 J = Ii - 1; 60 PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 61 } 62 if (j < n - 1) { 63 J = Ii + 1; 64 PetscCall(MatSetValues(A, 1, &Ii, 1, &J, &v, INSERT_VALUES)); 65 } 66 v = 4.0; 67 PetscCall(MatSetValues(A, 1, &Ii, 1, &Ii, &v, INSERT_VALUES)); 68 } 69 PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 70 PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 71 PetscCall(MatView(A, PETSC_VIEWER_STDOUT_WORLD)); 72 /* 73 Partition the graph of the matrix 74 */ 75 PetscCall(MatPartitioningCreate(comm, &part)); 76 PetscCall(MatPartitioningSetAdjacency(part, A)); 77 PetscCall(MatPartitioningSetType(part, MATPARTITIONINGHIERARCH)); 78 PetscCall(MatPartitioningHierarchicalSetNcoarseparts(part, 2)); 79 PetscCall(MatPartitioningHierarchicalSetNfineparts(part, 4)); 80 PetscCall(MatPartitioningSetFromOptions(part)); 81 /* get new processor owner number of each vertex */ 82 PetscCall(MatPartitioningApply(part, &is)); 83 /* coarse parts */ 84 PetscCall(MatPartitioningHierarchicalGetCoarseparts(part, &coarseparts)); 85 PetscCall(ISView(coarseparts, PETSC_VIEWER_STDOUT_WORLD)); 86 /* fine parts */ 87 PetscCall(MatPartitioningHierarchicalGetFineparts(part, &fineparts)); 88 PetscCall(ISView(fineparts, PETSC_VIEWER_STDOUT_WORLD)); 89 /* partitioning */ 90 PetscCall(ISView(is, PETSC_VIEWER_STDOUT_WORLD)); 91 /* get new global number of each old global number */ 92 PetscCall(ISPartitioningToNumbering(is, &isn)); 93 PetscCall(ISView(isn, PETSC_VIEWER_STDOUT_WORLD)); 94 PetscCall(ISBuildTwoSided(is, NULL, &isrows)); 95 PetscCall(ISView(isrows, PETSC_VIEWER_STDOUT_WORLD)); 96 PetscCall(ISDestroy(&is)); 97 PetscCall(ISDestroy(&coarseparts)); 98 PetscCall(ISDestroy(&fineparts)); 99 PetscCall(ISDestroy(&isrows)); 100 PetscCall(ISDestroy(&isn)); 101 PetscCall(MatPartitioningDestroy(&part)); 102 PetscCall(MatDestroy(&A)); 103 PetscCall(PetscFinalize()); 104 return 0; 105 } 106 107 /*TEST 108 109 test: 110 nsize: 4 111 args: -mat_partitioning_hierarchical_Nfineparts 2 112 requires: parmetis 113 TODO: cannot run because parmetis does reproduce across all machines, probably due to nonportable random number generator 114 115 TEST*/ 116