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 PetscCall(PetscInitialize(&argc,&args,(char*)0,help)); 28 comm = PETSC_COMM_WORLD; 29 PetscCallMPI(MPI_Comm_size(comm,&size)); 30 PetscOptionsBegin(comm,NULL,"ex193","hierarchical partitioning"); 31 m = 15; 32 PetscCall(PetscOptionsInt("-M","Number of mesh points in the x-direction","partitioning",m,&m,NULL)); 33 n = 15; 34 PetscCall(PetscOptionsInt("-N","Number of mesh points in the y-direction","partitioning",n,&n,NULL)); 35 PetscOptionsEnd(); 36 37 /* 38 Assemble the matrix for the five point stencil (finite difference), YET AGAIN 39 */ 40 PetscCall(MatCreate(comm,&A)); 41 PetscCall(MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,m*n,m*n)); 42 PetscCall(MatSetFromOptions(A)); 43 PetscCall(MatSetUp(A)); 44 PetscCall(MatGetOwnershipRange(A,&Istart,&Iend)); 45 for (Ii=Istart; Ii<Iend; Ii++) { 46 v = -1.0; i = Ii/n; j = Ii - i*n; 47 if (i>0) {J = Ii - n; PetscCall(MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES));} 48 if (i<m-1) {J = Ii + n; PetscCall(MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES));} 49 if (j>0) {J = Ii - 1; PetscCall(MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES));} 50 if (j<n-1) {J = Ii + 1; PetscCall(MatSetValues(A,1,&Ii,1,&J,&v,INSERT_VALUES));} 51 v = 4.0; PetscCall(MatSetValues(A,1,&Ii,1,&Ii,&v,INSERT_VALUES)); 52 } 53 PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 54 PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 55 PetscCall(MatView(A,PETSC_VIEWER_STDOUT_WORLD)); 56 /* 57 Partition the graph of the matrix 58 */ 59 PetscCall(MatPartitioningCreate(comm,&part)); 60 PetscCall(MatPartitioningSetAdjacency(part,A)); 61 PetscCall(MatPartitioningSetType(part,MATPARTITIONINGHIERARCH)); 62 PetscCall(MatPartitioningHierarchicalSetNcoarseparts(part,2)); 63 PetscCall(MatPartitioningHierarchicalSetNfineparts(part,4)); 64 PetscCall(MatPartitioningSetFromOptions(part)); 65 /* get new processor owner number of each vertex */ 66 PetscCall(MatPartitioningApply(part,&is)); 67 /* coarse parts */ 68 PetscCall(MatPartitioningHierarchicalGetCoarseparts(part,&coarseparts)); 69 PetscCall(ISView(coarseparts,PETSC_VIEWER_STDOUT_WORLD)); 70 /* fine parts */ 71 PetscCall(MatPartitioningHierarchicalGetFineparts(part,&fineparts)); 72 PetscCall(ISView(fineparts,PETSC_VIEWER_STDOUT_WORLD)); 73 /* partitioning */ 74 PetscCall(ISView(is,PETSC_VIEWER_STDOUT_WORLD)); 75 /* get new global number of each old global number */ 76 PetscCall(ISPartitioningToNumbering(is,&isn)); 77 PetscCall(ISView(isn,PETSC_VIEWER_STDOUT_WORLD)); 78 PetscCall(ISBuildTwoSided(is,NULL,&isrows)); 79 PetscCall(ISView(isrows,PETSC_VIEWER_STDOUT_WORLD)); 80 PetscCall(ISDestroy(&is)); 81 PetscCall(ISDestroy(&coarseparts)); 82 PetscCall(ISDestroy(&fineparts)); 83 PetscCall(ISDestroy(&isrows)); 84 PetscCall(ISDestroy(&isn)); 85 PetscCall(MatPartitioningDestroy(&part)); 86 PetscCall(MatDestroy(&A)); 87 PetscCall(PetscFinalize()); 88 return 0; 89 } 90 91 /*TEST 92 93 test: 94 nsize: 4 95 args: -mat_partitioning_hierarchical_Nfineparts 2 96 requires: parmetis 97 TODO: cannot run because parmetis does reproduce across all machines, probably due to nonportable random number generator 98 99 TEST*/ 100