xref: /petsc/src/mat/tests/ex193.c (revision 8fb5bd83c3955fefcf33a54e3bb66920a9fa884b)
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