xref: /petsc/src/mat/graphops/partition/impls/chaco/chaco.c (revision 8be712e46db5d855f641c6bd97b4543e0efe65bd)
1*8be712e4SBarry Smith #include <../src/mat/impls/adj/mpi/mpiadj.h> /*I "petscmat.h" I*/
2*8be712e4SBarry Smith 
3*8be712e4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H)
4*8be712e4SBarry Smith   #include <unistd.h>
5*8be712e4SBarry Smith #endif
6*8be712e4SBarry Smith 
7*8be712e4SBarry Smith #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
8*8be712e4SBarry Smith   #include <chaco.h>
9*8be712e4SBarry Smith #else
10*8be712e4SBarry Smith /* Older versions of Chaco do not have an include file */
11*8be712e4SBarry Smith PETSC_EXTERN int interface(int nvtxs, int *start, int *adjacency, int *vwgts, float *ewgts, float *x, float *y, float *z, char *outassignname, char *outfilename, short *assignment, int architecture, int ndims_tot, int mesh_dims[3], double *goal, int global_method, int local_method, int rqi_flag, int vmax, int ndims, double eigtol, long seed);
12*8be712e4SBarry Smith #endif
13*8be712e4SBarry Smith 
14*8be712e4SBarry Smith extern int FREE_GRAPH;
15*8be712e4SBarry Smith 
16*8be712e4SBarry Smith /*
17*8be712e4SBarry Smith int       nvtxs;                number of vertices in full graph
18*8be712e4SBarry Smith int      *start;                start of edge list for each vertex
19*8be712e4SBarry Smith int      *adjacency;            edge list data
20*8be712e4SBarry Smith int      *vwgts;                weights for all vertices
21*8be712e4SBarry Smith float    *ewgts;                weights for all edges
22*8be712e4SBarry Smith float    *x, *y, *z;            coordinates for inertial method
23*8be712e4SBarry Smith char     *outassignname;        name of assignment output file
24*8be712e4SBarry Smith char     *outfilename;          output file name
25*8be712e4SBarry Smith short    *assignment;           set number of each vtx (length n)
26*8be712e4SBarry Smith int       architecture;         0 => hypercube, d => d-dimensional mesh
27*8be712e4SBarry Smith int       ndims_tot;            total number of cube dimensions to divide
28*8be712e4SBarry Smith int       mesh_dims[3];         dimensions of mesh of processors
29*8be712e4SBarry Smith double   *goal;                 desired set sizes for each set
30*8be712e4SBarry Smith int       global_method;        global partitioning algorithm
31*8be712e4SBarry Smith int       local_method;         local partitioning algorithm
32*8be712e4SBarry Smith int       rqi_flag;             should I use RQI/Symmlq eigensolver?
33*8be712e4SBarry Smith int       vmax;                 how many vertices to coarsen down to?
34*8be712e4SBarry Smith int       ndims;                number of eigenvectors (2^d sets)
35*8be712e4SBarry Smith double    eigtol;               tolerance on eigenvectors
36*8be712e4SBarry Smith long      seed;                 for random graph mutations
37*8be712e4SBarry Smith */
38*8be712e4SBarry Smith 
39*8be712e4SBarry Smith typedef struct {
40*8be712e4SBarry Smith   PetscBool         verbose;
41*8be712e4SBarry Smith   PetscInt          eignum;
42*8be712e4SBarry Smith   PetscReal         eigtol;
43*8be712e4SBarry Smith   MPChacoGlobalType global_method; /* global method */
44*8be712e4SBarry Smith   MPChacoLocalType  local_method;  /* local method */
45*8be712e4SBarry Smith   MPChacoEigenType  eigen_method;  /* eigensolver */
46*8be712e4SBarry Smith   PetscInt          nbvtxcoarsed;  /* number of vertices for the coarse graph */
47*8be712e4SBarry Smith } MatPartitioning_Chaco;
48*8be712e4SBarry Smith 
49*8be712e4SBarry Smith #define SIZE_LOG 10000 /* size of buffer for mesg_log */
50*8be712e4SBarry Smith 
51*8be712e4SBarry Smith static PetscErrorCode MatPartitioningApply_Chaco(MatPartitioning part, IS *partitioning)
52*8be712e4SBarry Smith {
53*8be712e4SBarry Smith   int                    cerr;
54*8be712e4SBarry Smith   PetscInt              *parttab, *locals, i, nb_locals, M, N;
55*8be712e4SBarry Smith   PetscMPIInt            size, rank;
56*8be712e4SBarry Smith   Mat                    mat = part->adj, matAdj, matSeq, *A;
57*8be712e4SBarry Smith   Mat_MPIAdj            *adj;
58*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
59*8be712e4SBarry Smith   PetscBool              flg;
60*8be712e4SBarry Smith   IS                     isrow, iscol;
61*8be712e4SBarry Smith   int                    nvtxs, *start, *adjacency, *vwgts, architecture, ndims_tot;
62*8be712e4SBarry Smith   int                    mesh_dims[3], global_method, local_method, rqi_flag, vmax, ndims;
63*8be712e4SBarry Smith #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
64*8be712e4SBarry Smith   int *assignment;
65*8be712e4SBarry Smith #else
66*8be712e4SBarry Smith   short *assignment;
67*8be712e4SBarry Smith #endif
68*8be712e4SBarry Smith   double eigtol;
69*8be712e4SBarry Smith   long   seed;
70*8be712e4SBarry Smith   char  *mesg_log;
71*8be712e4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H)
72*8be712e4SBarry Smith   int fd_stdout, fd_pipe[2], count;
73*8be712e4SBarry Smith #endif
74*8be712e4SBarry Smith 
75*8be712e4SBarry Smith   PetscFunctionBegin;
76*8be712e4SBarry Smith   PetscCheck(!part->use_edge_weights, PetscObjectComm((PetscObject)part), PETSC_ERR_SUP, "Chaco does not support edge weights");
77*8be712e4SBarry Smith   FREE_GRAPH = 0; /* otherwise Chaco will attempt to free memory for adjacency graph */
78*8be712e4SBarry Smith   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size));
79*8be712e4SBarry Smith   PetscCallMPI(MPI_Comm_rank(PetscObjectComm((PetscObject)mat), &rank));
80*8be712e4SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)mat, MATMPIADJ, &flg));
81*8be712e4SBarry Smith   if (size > 1) {
82*8be712e4SBarry Smith     if (flg) {
83*8be712e4SBarry Smith       PetscCall(MatMPIAdjToSeq(mat, &matSeq));
84*8be712e4SBarry Smith     } else {
85*8be712e4SBarry Smith       PetscCall(PetscInfo(part, "Converting distributed matrix to sequential: this could be a performance loss\n"));
86*8be712e4SBarry Smith       PetscCall(MatGetSize(mat, &M, &N));
87*8be712e4SBarry Smith       PetscCall(ISCreateStride(PETSC_COMM_SELF, M, 0, 1, &isrow));
88*8be712e4SBarry Smith       PetscCall(ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol));
89*8be712e4SBarry Smith       PetscCall(MatCreateSubMatrices(mat, 1, &isrow, &iscol, MAT_INITIAL_MATRIX, &A));
90*8be712e4SBarry Smith       PetscCall(ISDestroy(&isrow));
91*8be712e4SBarry Smith       PetscCall(ISDestroy(&iscol));
92*8be712e4SBarry Smith       matSeq = *A;
93*8be712e4SBarry Smith       PetscCall(PetscFree(A));
94*8be712e4SBarry Smith     }
95*8be712e4SBarry Smith   } else {
96*8be712e4SBarry Smith     PetscCall(PetscObjectReference((PetscObject)mat));
97*8be712e4SBarry Smith     matSeq = mat;
98*8be712e4SBarry Smith   }
99*8be712e4SBarry Smith 
100*8be712e4SBarry Smith   if (!flg) { /* convert regular matrix to MPIADJ */
101*8be712e4SBarry Smith     PetscCall(MatConvert(matSeq, MATMPIADJ, MAT_INITIAL_MATRIX, &matAdj));
102*8be712e4SBarry Smith   } else {
103*8be712e4SBarry Smith     PetscCall(PetscObjectReference((PetscObject)matSeq));
104*8be712e4SBarry Smith     matAdj = matSeq;
105*8be712e4SBarry Smith   }
106*8be712e4SBarry Smith 
107*8be712e4SBarry Smith   adj = (Mat_MPIAdj *)matAdj->data; /* finally adj contains adjacency graph */
108*8be712e4SBarry Smith 
109*8be712e4SBarry Smith   /* arguments for Chaco library */
110*8be712e4SBarry Smith   nvtxs         = mat->rmap->N;         /* number of vertices in full graph */
111*8be712e4SBarry Smith   start         = adj->i;               /* start of edge list for each vertex */
112*8be712e4SBarry Smith   vwgts         = part->vertex_weights; /* weights for all vertices */
113*8be712e4SBarry Smith   architecture  = 1;                    /* 0 => hypercube, d => d-dimensional mesh */
114*8be712e4SBarry Smith   ndims_tot     = 0;                    /* total number of cube dimensions to divide */
115*8be712e4SBarry Smith   mesh_dims[0]  = part->n;              /* dimensions of mesh of processors */
116*8be712e4SBarry Smith   global_method = chaco->global_method; /* global partitioning algorithm */
117*8be712e4SBarry Smith   local_method  = chaco->local_method;  /* local partitioning algorithm */
118*8be712e4SBarry Smith   rqi_flag      = chaco->eigen_method;  /* should I use RQI/Symmlq eigensolver? */
119*8be712e4SBarry Smith   vmax          = chaco->nbvtxcoarsed;  /* how many vertices to coarsen down to? */
120*8be712e4SBarry Smith   ndims         = chaco->eignum;        /* number of eigenvectors (2^d sets) */
121*8be712e4SBarry Smith   eigtol        = chaco->eigtol;        /* tolerance on eigenvectors */
122*8be712e4SBarry Smith   seed          = 123636512;            /* for random graph mutations */
123*8be712e4SBarry Smith 
124*8be712e4SBarry Smith   PetscCall(PetscMalloc1(mat->rmap->N, &assignment));
125*8be712e4SBarry Smith   PetscCall(PetscMalloc1(start[nvtxs], &adjacency));
126*8be712e4SBarry Smith   for (i = 0; i < start[nvtxs]; i++) adjacency[i] = (adj->j)[i] + 1; /* 1-based indexing */
127*8be712e4SBarry Smith 
128*8be712e4SBarry Smith     /* redirect output to buffer */
129*8be712e4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H)
130*8be712e4SBarry Smith   fd_stdout = dup(1);
131*8be712e4SBarry Smith   PetscCheck(!pipe(fd_pipe), PETSC_COMM_SELF, PETSC_ERR_SYS, "Could not open pipe");
132*8be712e4SBarry Smith   close(1);
133*8be712e4SBarry Smith   dup2(fd_pipe[1], 1);
134*8be712e4SBarry Smith   PetscCall(PetscMalloc1(SIZE_LOG, &mesg_log));
135*8be712e4SBarry Smith #endif
136*8be712e4SBarry Smith 
137*8be712e4SBarry Smith   /* library call */
138*8be712e4SBarry Smith   cerr = interface(nvtxs, start, adjacency, vwgts, NULL, NULL, NULL, NULL, NULL, NULL, assignment, architecture, ndims_tot, mesh_dims, NULL, global_method, local_method, rqi_flag, vmax, ndims, eigtol, seed);
139*8be712e4SBarry Smith 
140*8be712e4SBarry Smith #if defined(PETSC_HAVE_UNISTD_H)
141*8be712e4SBarry Smith   PetscCall(PetscFFlush(stdout));
142*8be712e4SBarry Smith   count = read(fd_pipe[0], mesg_log, (SIZE_LOG - 1) * sizeof(char));
143*8be712e4SBarry Smith   if (count < 0) count = 0;
144*8be712e4SBarry Smith   mesg_log[count] = 0;
145*8be712e4SBarry Smith   close(1);
146*8be712e4SBarry Smith   dup2(fd_stdout, 1);
147*8be712e4SBarry Smith   close(fd_stdout);
148*8be712e4SBarry Smith   close(fd_pipe[0]);
149*8be712e4SBarry Smith   close(fd_pipe[1]);
150*8be712e4SBarry Smith   if (chaco->verbose) PetscCall(PetscPrintf(PetscObjectComm((PetscObject)mat), "%s", mesg_log));
151*8be712e4SBarry Smith   PetscCall(PetscFree(mesg_log));
152*8be712e4SBarry Smith #endif
153*8be712e4SBarry Smith   PetscCheck(!cerr, PETSC_COMM_SELF, PETSC_ERR_LIB, "Chaco failed");
154*8be712e4SBarry Smith 
155*8be712e4SBarry Smith   PetscCall(PetscMalloc1(mat->rmap->N, &parttab));
156*8be712e4SBarry Smith   for (i = 0; i < nvtxs; i++) parttab[i] = assignment[i];
157*8be712e4SBarry Smith 
158*8be712e4SBarry Smith   /* creation of the index set */
159*8be712e4SBarry Smith   nb_locals = mat->rmap->n;
160*8be712e4SBarry Smith   locals    = parttab + mat->rmap->rstart;
161*8be712e4SBarry Smith   PetscCall(ISCreateGeneral(PetscObjectComm((PetscObject)part), nb_locals, locals, PETSC_COPY_VALUES, partitioning));
162*8be712e4SBarry Smith 
163*8be712e4SBarry Smith   /* clean up */
164*8be712e4SBarry Smith   PetscCall(PetscFree(parttab));
165*8be712e4SBarry Smith   PetscCall(PetscFree(adjacency));
166*8be712e4SBarry Smith   PetscCall(PetscFree(assignment));
167*8be712e4SBarry Smith   PetscCall(MatDestroy(&matSeq));
168*8be712e4SBarry Smith   PetscCall(MatDestroy(&matAdj));
169*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
170*8be712e4SBarry Smith }
171*8be712e4SBarry Smith 
172*8be712e4SBarry Smith static PetscErrorCode MatPartitioningView_Chaco(MatPartitioning part, PetscViewer viewer)
173*8be712e4SBarry Smith {
174*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
175*8be712e4SBarry Smith   PetscBool              isascii;
176*8be712e4SBarry Smith 
177*8be712e4SBarry Smith   PetscFunctionBegin;
178*8be712e4SBarry Smith   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
179*8be712e4SBarry Smith   if (isascii) {
180*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Global method: %s\n", MPChacoGlobalTypes[chaco->global_method]));
181*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Local method: %s\n", MPChacoLocalTypes[chaco->local_method]));
182*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Number of vertices for the coarse graph: %" PetscInt_FMT "\n", chaco->nbvtxcoarsed));
183*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Eigensolver: %s\n", MPChacoEigenTypes[chaco->eigen_method]));
184*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Tolerance for eigensolver: %g\n", chaco->eigtol));
185*8be712e4SBarry Smith     PetscCall(PetscViewerASCIIPrintf(viewer, "  Number of eigenvectors: %" PetscInt_FMT "\n", chaco->eignum));
186*8be712e4SBarry Smith   }
187*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
188*8be712e4SBarry Smith }
189*8be712e4SBarry Smith 
190*8be712e4SBarry Smith /*@
191*8be712e4SBarry Smith   MatPartitioningChacoSetGlobal - Set the global method for Chaco partitioner.
192*8be712e4SBarry Smith 
193*8be712e4SBarry Smith   Collective
194*8be712e4SBarry Smith 
195*8be712e4SBarry Smith   Input Parameters:
196*8be712e4SBarry Smith + part   - the partitioning context
197*8be712e4SBarry Smith - method - one of `MP_CHACO_MULTILEVEL`, `MP_CHACO_SPECTRAL`, `MP_CHACO_LINEAR`,
198*8be712e4SBarry Smith             `MP_CHACO_RANDOM` or `MP_CHACO_SCATTERED`
199*8be712e4SBarry Smith 
200*8be712e4SBarry Smith   Options Database Key:
201*8be712e4SBarry Smith . -mat_partitioning_chaco_global <method> - the global method
202*8be712e4SBarry Smith 
203*8be712e4SBarry Smith   Level: advanced
204*8be712e4SBarry Smith 
205*8be712e4SBarry Smith   Note:
206*8be712e4SBarry Smith   The default is the multi-level method. See Chaco documentation for
207*8be712e4SBarry Smith   additional details.
208*8be712e4SBarry Smith 
209*8be712e4SBarry Smith .seealso: `MatPartitioning`, `MatPartioningSetType()`, `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`, `MatPartitioningChacoGetGlobal()`
210*8be712e4SBarry Smith @*/
211*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part, MPChacoGlobalType method)
212*8be712e4SBarry Smith {
213*8be712e4SBarry Smith   PetscFunctionBegin;
214*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
215*8be712e4SBarry Smith   PetscValidLogicalCollectiveEnum(part, method, 2);
216*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetGlobal_C", (MatPartitioning, MPChacoGlobalType), (part, method));
217*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
218*8be712e4SBarry Smith }
219*8be712e4SBarry Smith 
220*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType method)
221*8be712e4SBarry Smith {
222*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
223*8be712e4SBarry Smith 
224*8be712e4SBarry Smith   PetscFunctionBegin;
225*8be712e4SBarry Smith   switch (method) {
226*8be712e4SBarry Smith   case MP_CHACO_MULTILEVEL:
227*8be712e4SBarry Smith   case MP_CHACO_SPECTRAL:
228*8be712e4SBarry Smith   case MP_CHACO_LINEAR:
229*8be712e4SBarry Smith   case MP_CHACO_RANDOM:
230*8be712e4SBarry Smith   case MP_CHACO_SCATTERED:
231*8be712e4SBarry Smith     chaco->global_method = method;
232*8be712e4SBarry Smith     break;
233*8be712e4SBarry Smith   default:
234*8be712e4SBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
235*8be712e4SBarry Smith   }
236*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
237*8be712e4SBarry Smith }
238*8be712e4SBarry Smith 
239*8be712e4SBarry Smith /*@
240*8be712e4SBarry Smith   MatPartitioningChacoGetGlobal - Get the global method used by the Chaco partitioner.
241*8be712e4SBarry Smith 
242*8be712e4SBarry Smith   Not Collective
243*8be712e4SBarry Smith 
244*8be712e4SBarry Smith   Input Parameter:
245*8be712e4SBarry Smith . part - the partitioning context
246*8be712e4SBarry Smith 
247*8be712e4SBarry Smith   Output Parameter:
248*8be712e4SBarry Smith . method - the method
249*8be712e4SBarry Smith 
250*8be712e4SBarry Smith   Level: advanced
251*8be712e4SBarry Smith 
252*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`
253*8be712e4SBarry Smith @*/
254*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part, MPChacoGlobalType *method)
255*8be712e4SBarry Smith {
256*8be712e4SBarry Smith   PetscFunctionBegin;
257*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
258*8be712e4SBarry Smith   PetscAssertPointer(method, 2);
259*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoGetGlobal_C", (MatPartitioning, MPChacoGlobalType *), (part, method));
260*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
261*8be712e4SBarry Smith }
262*8be712e4SBarry Smith 
263*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType *method)
264*8be712e4SBarry Smith {
265*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
266*8be712e4SBarry Smith 
267*8be712e4SBarry Smith   PetscFunctionBegin;
268*8be712e4SBarry Smith   *method = chaco->global_method;
269*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
270*8be712e4SBarry Smith }
271*8be712e4SBarry Smith 
272*8be712e4SBarry Smith /*@
273*8be712e4SBarry Smith   MatPartitioningChacoSetLocal - Set the local method for the Chaco partitioner.
274*8be712e4SBarry Smith 
275*8be712e4SBarry Smith   Collective
276*8be712e4SBarry Smith 
277*8be712e4SBarry Smith   Input Parameters:
278*8be712e4SBarry Smith + part   - the partitioning context
279*8be712e4SBarry Smith - method - one of `MP_CHACO_KERNIGHAN` or `MP_CHACO_NONE`
280*8be712e4SBarry Smith 
281*8be712e4SBarry Smith   Options Database Key:
282*8be712e4SBarry Smith . -mat_partitioning_chaco_local <method> - the local method
283*8be712e4SBarry Smith 
284*8be712e4SBarry Smith   Level: advanced
285*8be712e4SBarry Smith 
286*8be712e4SBarry Smith   Note:
287*8be712e4SBarry Smith   The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
288*8be712e4SBarry Smith   for additional details.
289*8be712e4SBarry Smith 
290*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`, `MatPartitioningChacoGetLocal()`
291*8be712e4SBarry Smith @*/
292*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part, MPChacoLocalType method)
293*8be712e4SBarry Smith {
294*8be712e4SBarry Smith   PetscFunctionBegin;
295*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
296*8be712e4SBarry Smith   PetscValidLogicalCollectiveEnum(part, method, 2);
297*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetLocal_C", (MatPartitioning, MPChacoLocalType), (part, method));
298*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
299*8be712e4SBarry Smith }
300*8be712e4SBarry Smith 
301*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetLocal_Chaco(MatPartitioning part, MPChacoLocalType method)
302*8be712e4SBarry Smith {
303*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
304*8be712e4SBarry Smith 
305*8be712e4SBarry Smith   PetscFunctionBegin;
306*8be712e4SBarry Smith   switch (method) {
307*8be712e4SBarry Smith   case MP_CHACO_KERNIGHAN:
308*8be712e4SBarry Smith   case MP_CHACO_NONE:
309*8be712e4SBarry Smith     chaco->local_method = method;
310*8be712e4SBarry Smith     break;
311*8be712e4SBarry Smith   default:
312*8be712e4SBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
313*8be712e4SBarry Smith   }
314*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
315*8be712e4SBarry Smith }
316*8be712e4SBarry Smith 
317*8be712e4SBarry Smith /*@
318*8be712e4SBarry Smith   MatPartitioningChacoGetLocal - Get local method used by the Chaco partitioner.
319*8be712e4SBarry Smith 
320*8be712e4SBarry Smith   Not Collective
321*8be712e4SBarry Smith 
322*8be712e4SBarry Smith   Input Parameter:
323*8be712e4SBarry Smith . part - the partitioning context
324*8be712e4SBarry Smith 
325*8be712e4SBarry Smith   Output Parameter:
326*8be712e4SBarry Smith . method - the method
327*8be712e4SBarry Smith 
328*8be712e4SBarry Smith   Level: advanced
329*8be712e4SBarry Smith 
330*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`
331*8be712e4SBarry Smith @*/
332*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part, MPChacoLocalType *method)
333*8be712e4SBarry Smith {
334*8be712e4SBarry Smith   PetscFunctionBegin;
335*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
336*8be712e4SBarry Smith   PetscAssertPointer(method, 2);
337*8be712e4SBarry Smith   PetscUseMethod(part, "MatPartitioningChacoGetLocal_C", (MatPartitioning, MPChacoLocalType *), (part, method));
338*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
339*8be712e4SBarry Smith }
340*8be712e4SBarry Smith 
341*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part, MPChacoLocalType *method)
342*8be712e4SBarry Smith {
343*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
344*8be712e4SBarry Smith 
345*8be712e4SBarry Smith   PetscFunctionBegin;
346*8be712e4SBarry Smith   *method = chaco->local_method;
347*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
348*8be712e4SBarry Smith }
349*8be712e4SBarry Smith 
350*8be712e4SBarry Smith /*@
351*8be712e4SBarry Smith   MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
352*8be712e4SBarry Smith   Chaco partitioner.
353*8be712e4SBarry Smith 
354*8be712e4SBarry Smith   Collective
355*8be712e4SBarry Smith 
356*8be712e4SBarry Smith   Input Parameters:
357*8be712e4SBarry Smith + part  - the partitioning context
358*8be712e4SBarry Smith - level - the coarse level in range [0.0,1.0]
359*8be712e4SBarry Smith 
360*8be712e4SBarry Smith   Options Database Key:
361*8be712e4SBarry Smith . -mat_partitioning_chaco_coarse <l> - Coarse level
362*8be712e4SBarry Smith 
363*8be712e4SBarry Smith   Level: advanced
364*8be712e4SBarry Smith 
365*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`
366*8be712e4SBarry Smith @*/
367*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part, PetscReal level)
368*8be712e4SBarry Smith {
369*8be712e4SBarry Smith   PetscFunctionBegin;
370*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
371*8be712e4SBarry Smith   PetscValidLogicalCollectiveReal(part, level, 2);
372*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetCoarseLevel_C", (MatPartitioning, PetscReal), (part, level));
373*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
374*8be712e4SBarry Smith }
375*8be712e4SBarry Smith 
376*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part, PetscReal level)
377*8be712e4SBarry Smith {
378*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
379*8be712e4SBarry Smith 
380*8be712e4SBarry Smith   PetscFunctionBegin;
381*8be712e4SBarry Smith   PetscCheck(level >= 0.0 && level < 1.0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Chaco: level of coarsening out of range [0.0-1.0]");
382*8be712e4SBarry Smith   chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
383*8be712e4SBarry Smith   if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
384*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
385*8be712e4SBarry Smith }
386*8be712e4SBarry Smith 
387*8be712e4SBarry Smith /*@
388*8be712e4SBarry Smith   MatPartitioningChacoSetEigenSolver - Set the eigensolver method for Chaco partitioner.
389*8be712e4SBarry Smith 
390*8be712e4SBarry Smith   Collective
391*8be712e4SBarry Smith 
392*8be712e4SBarry Smith   Input Parameters:
393*8be712e4SBarry Smith + part   - the partitioning context
394*8be712e4SBarry Smith - method - one of `MP_CHACO_LANCZOS` or `MP_CHACO_RQI`
395*8be712e4SBarry Smith 
396*8be712e4SBarry Smith   Options Database Key:
397*8be712e4SBarry Smith . -mat_partitioning_chaco_eigen_solver <method> - the eigensolver
398*8be712e4SBarry Smith 
399*8be712e4SBarry Smith   Level: advanced
400*8be712e4SBarry Smith 
401*8be712e4SBarry Smith   Note:
402*8be712e4SBarry Smith   The default is to use a Lanczos method. See Chaco documentation for details.
403*8be712e4SBarry Smith 
404*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`, `MatPartitioningChacoSetEigenNumber()`,
405*8be712e4SBarry Smith           `MatPartitioningChacoGetEigenSolver()`
406*8be712e4SBarry Smith @*/
407*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part, MPChacoEigenType method)
408*8be712e4SBarry Smith {
409*8be712e4SBarry Smith   PetscFunctionBegin;
410*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
411*8be712e4SBarry Smith   PetscValidLogicalCollectiveEnum(part, method, 2);
412*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetEigenSolver_C", (MatPartitioning, MPChacoEigenType), (part, method));
413*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
414*8be712e4SBarry Smith }
415*8be712e4SBarry Smith 
416*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType method)
417*8be712e4SBarry Smith {
418*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
419*8be712e4SBarry Smith 
420*8be712e4SBarry Smith   PetscFunctionBegin;
421*8be712e4SBarry Smith   switch (method) {
422*8be712e4SBarry Smith   case MP_CHACO_LANCZOS:
423*8be712e4SBarry Smith   case MP_CHACO_RQI:
424*8be712e4SBarry Smith     chaco->eigen_method = method;
425*8be712e4SBarry Smith     break;
426*8be712e4SBarry Smith   default:
427*8be712e4SBarry Smith     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
428*8be712e4SBarry Smith   }
429*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
430*8be712e4SBarry Smith }
431*8be712e4SBarry Smith 
432*8be712e4SBarry Smith /*@
433*8be712e4SBarry Smith   MatPartitioningChacoGetEigenSolver - Get the eigensolver used by the Chaco partitioner.
434*8be712e4SBarry Smith 
435*8be712e4SBarry Smith   Not Collective
436*8be712e4SBarry Smith 
437*8be712e4SBarry Smith   Input Parameter:
438*8be712e4SBarry Smith . part - the partitioning context
439*8be712e4SBarry Smith 
440*8be712e4SBarry Smith   Output Parameter:
441*8be712e4SBarry Smith . method - the method
442*8be712e4SBarry Smith 
443*8be712e4SBarry Smith   Level: advanced
444*8be712e4SBarry Smith 
445*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`
446*8be712e4SBarry Smith @*/
447*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part, MPChacoEigenType *method)
448*8be712e4SBarry Smith {
449*8be712e4SBarry Smith   PetscFunctionBegin;
450*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
451*8be712e4SBarry Smith   PetscAssertPointer(method, 2);
452*8be712e4SBarry Smith   PetscUseMethod(part, "MatPartitioningChacoGetEigenSolver_C", (MatPartitioning, MPChacoEigenType *), (part, method));
453*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
454*8be712e4SBarry Smith }
455*8be712e4SBarry Smith 
456*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType *method)
457*8be712e4SBarry Smith {
458*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
459*8be712e4SBarry Smith 
460*8be712e4SBarry Smith   PetscFunctionBegin;
461*8be712e4SBarry Smith   *method = chaco->eigen_method;
462*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
463*8be712e4SBarry Smith }
464*8be712e4SBarry Smith 
465*8be712e4SBarry Smith /*@
466*8be712e4SBarry Smith   MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver used by Chaco
467*8be712e4SBarry Smith 
468*8be712e4SBarry Smith   Collective
469*8be712e4SBarry Smith 
470*8be712e4SBarry Smith   Input Parameters:
471*8be712e4SBarry Smith + part - the partitioning context
472*8be712e4SBarry Smith - tol  - the tolerance
473*8be712e4SBarry Smith 
474*8be712e4SBarry Smith   Options Database Key:
475*8be712e4SBarry Smith . -mat_partitioning_chaco_eigen_tol <tol> - Tolerance for eigensolver
476*8be712e4SBarry Smith 
477*8be712e4SBarry Smith   Note:
478*8be712e4SBarry Smith   Must be positive. The default value is 0.001.
479*8be712e4SBarry Smith 
480*8be712e4SBarry Smith   Level: advanced
481*8be712e4SBarry Smith 
482*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
483*8be712e4SBarry Smith @*/
484*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part, PetscReal tol)
485*8be712e4SBarry Smith {
486*8be712e4SBarry Smith   PetscFunctionBegin;
487*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
488*8be712e4SBarry Smith   PetscValidLogicalCollectiveReal(part, tol, 2);
489*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetEigenTol_C", (MatPartitioning, PetscReal), (part, tol));
490*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
491*8be712e4SBarry Smith }
492*8be712e4SBarry Smith 
493*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetEigenTol_Chaco(MatPartitioning part, PetscReal tol)
494*8be712e4SBarry Smith {
495*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
496*8be712e4SBarry Smith 
497*8be712e4SBarry Smith   PetscFunctionBegin;
498*8be712e4SBarry Smith   if (tol == PETSC_DEFAULT) chaco->eigtol = 0.001;
499*8be712e4SBarry Smith   else {
500*8be712e4SBarry Smith     PetscCheck(tol > 0.0, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_OUTOFRANGE, "Tolerance must be positive");
501*8be712e4SBarry Smith     chaco->eigtol = tol;
502*8be712e4SBarry Smith   }
503*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
504*8be712e4SBarry Smith }
505*8be712e4SBarry Smith 
506*8be712e4SBarry Smith /*@
507*8be712e4SBarry Smith   MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance used by Chaco
508*8be712e4SBarry Smith 
509*8be712e4SBarry Smith   Not Collective
510*8be712e4SBarry Smith 
511*8be712e4SBarry Smith   Input Parameter:
512*8be712e4SBarry Smith . part - the partitioning context
513*8be712e4SBarry Smith 
514*8be712e4SBarry Smith   Output Parameter:
515*8be712e4SBarry Smith . tol - the tolerance
516*8be712e4SBarry Smith 
517*8be712e4SBarry Smith   Level: advanced
518*8be712e4SBarry Smith 
519*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`
520*8be712e4SBarry Smith @*/
521*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part, PetscReal *tol)
522*8be712e4SBarry Smith {
523*8be712e4SBarry Smith   PetscFunctionBegin;
524*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
525*8be712e4SBarry Smith   PetscAssertPointer(tol, 2);
526*8be712e4SBarry Smith   PetscUseMethod(part, "MatPartitioningChacoGetEigenTol_C", (MatPartitioning, PetscReal *), (part, tol));
527*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
528*8be712e4SBarry Smith }
529*8be712e4SBarry Smith 
530*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part, PetscReal *tol)
531*8be712e4SBarry Smith {
532*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
533*8be712e4SBarry Smith 
534*8be712e4SBarry Smith   PetscFunctionBegin;
535*8be712e4SBarry Smith   *tol = chaco->eigtol;
536*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
537*8be712e4SBarry Smith }
538*8be712e4SBarry Smith 
539*8be712e4SBarry Smith /*@
540*8be712e4SBarry Smith   MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute by Chaco during partitioning
541*8be712e4SBarry Smith   during partitioning.
542*8be712e4SBarry Smith 
543*8be712e4SBarry Smith   Collective
544*8be712e4SBarry Smith 
545*8be712e4SBarry Smith   Input Parameters:
546*8be712e4SBarry Smith + part - the partitioning context
547*8be712e4SBarry Smith - num  - the number of eigenvectors
548*8be712e4SBarry Smith 
549*8be712e4SBarry Smith   Options Database Key:
550*8be712e4SBarry Smith . -mat_partitioning_chaco_eigen_number <n> - Number of eigenvectors
551*8be712e4SBarry Smith 
552*8be712e4SBarry Smith   Note:
553*8be712e4SBarry Smith   Accepted values are 1, 2 or 3, indicating partitioning by bisection,
554*8be712e4SBarry Smith   quadrisection, or octosection.
555*8be712e4SBarry Smith 
556*8be712e4SBarry Smith   Level: advanced
557*8be712e4SBarry Smith 
558*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
559*8be712e4SBarry Smith @*/
560*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part, PetscInt num)
561*8be712e4SBarry Smith {
562*8be712e4SBarry Smith   PetscFunctionBegin;
563*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
564*8be712e4SBarry Smith   PetscValidLogicalCollectiveInt(part, num, 2);
565*8be712e4SBarry Smith   PetscTryMethod(part, "MatPartitioningChacoSetEigenNumber_C", (MatPartitioning, PetscInt), (part, num));
566*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
567*8be712e4SBarry Smith }
568*8be712e4SBarry Smith 
569*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part, PetscInt num)
570*8be712e4SBarry Smith {
571*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
572*8be712e4SBarry Smith 
573*8be712e4SBarry Smith   PetscFunctionBegin;
574*8be712e4SBarry Smith   if (num == PETSC_DEFAULT) chaco->eignum = 1;
575*8be712e4SBarry Smith   else {
576*8be712e4SBarry Smith     PetscCheck(num >= 1 && num <= 3, PetscObjectComm((PetscObject)part), PETSC_ERR_ARG_OUTOFRANGE, "Can only specify 1, 2 or 3 eigenvectors");
577*8be712e4SBarry Smith     chaco->eignum = num;
578*8be712e4SBarry Smith   }
579*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
580*8be712e4SBarry Smith }
581*8be712e4SBarry Smith 
582*8be712e4SBarry Smith /*@
583*8be712e4SBarry Smith   MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.
584*8be712e4SBarry Smith 
585*8be712e4SBarry Smith   Not Collective
586*8be712e4SBarry Smith 
587*8be712e4SBarry Smith   Input Parameter:
588*8be712e4SBarry Smith . part - the partitioning context
589*8be712e4SBarry Smith 
590*8be712e4SBarry Smith   Output Parameter:
591*8be712e4SBarry Smith . num - number of eigenvectors
592*8be712e4SBarry Smith 
593*8be712e4SBarry Smith   Level: advanced
594*8be712e4SBarry Smith 
595*8be712e4SBarry Smith .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenNumber()`
596*8be712e4SBarry Smith @*/
597*8be712e4SBarry Smith PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part, PetscInt *num)
598*8be712e4SBarry Smith {
599*8be712e4SBarry Smith   PetscFunctionBegin;
600*8be712e4SBarry Smith   PetscValidHeaderSpecific(part, MAT_PARTITIONING_CLASSID, 1);
601*8be712e4SBarry Smith   PetscAssertPointer(num, 2);
602*8be712e4SBarry Smith   PetscUseMethod(part, "MatPartitioningChacoGetEigenNumber_C", (MatPartitioning, PetscInt *), (part, num));
603*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
604*8be712e4SBarry Smith }
605*8be712e4SBarry Smith 
606*8be712e4SBarry Smith static PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part, PetscInt *num)
607*8be712e4SBarry Smith {
608*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
609*8be712e4SBarry Smith 
610*8be712e4SBarry Smith   PetscFunctionBegin;
611*8be712e4SBarry Smith   *num = chaco->eignum;
612*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
613*8be712e4SBarry Smith }
614*8be712e4SBarry Smith 
615*8be712e4SBarry Smith static PetscErrorCode MatPartitioningSetFromOptions_Chaco(MatPartitioning part, PetscOptionItems *PetscOptionsObject)
616*8be712e4SBarry Smith {
617*8be712e4SBarry Smith   PetscInt               i;
618*8be712e4SBarry Smith   PetscReal              r;
619*8be712e4SBarry Smith   PetscBool              flag;
620*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
621*8be712e4SBarry Smith   MPChacoGlobalType      global;
622*8be712e4SBarry Smith   MPChacoLocalType       local;
623*8be712e4SBarry Smith   MPChacoEigenType       eigen;
624*8be712e4SBarry Smith 
625*8be712e4SBarry Smith   PetscFunctionBegin;
626*8be712e4SBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "Chaco partitioning options");
627*8be712e4SBarry Smith   PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_global", "Global method", "MatPartitioningChacoSetGlobal", MPChacoGlobalTypes, (PetscEnum)chaco->global_method, (PetscEnum *)&global, &flag));
628*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetGlobal(part, global));
629*8be712e4SBarry Smith   PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_local", "Local method", "MatPartitioningChacoSetLocal", MPChacoLocalTypes, (PetscEnum)chaco->local_method, (PetscEnum *)&local, &flag));
630*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetLocal(part, local));
631*8be712e4SBarry Smith   PetscCall(PetscOptionsReal("-mat_partitioning_chaco_coarse", "Coarse level", "MatPartitioningChacoSetCoarseLevel", 0.0, &r, &flag));
632*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetCoarseLevel(part, r));
633*8be712e4SBarry Smith   PetscCall(PetscOptionsEnum("-mat_partitioning_chaco_eigen_solver", "Eigensolver method", "MatPartitioningChacoSetEigenSolver", MPChacoEigenTypes, (PetscEnum)chaco->eigen_method, (PetscEnum *)&eigen, &flag));
634*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetEigenSolver(part, eigen));
635*8be712e4SBarry Smith   PetscCall(PetscOptionsReal("-mat_partitioning_chaco_eigen_tol", "Eigensolver tolerance", "MatPartitioningChacoSetEigenTol", chaco->eigtol, &r, &flag));
636*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetEigenTol(part, r));
637*8be712e4SBarry Smith   PetscCall(PetscOptionsInt("-mat_partitioning_chaco_eigen_number", "Number of eigenvectors: 1, 2, or 3 (bi-, quadri-, or octosection)", "MatPartitioningChacoSetEigenNumber", chaco->eignum, &i, &flag));
638*8be712e4SBarry Smith   if (flag) PetscCall(MatPartitioningChacoSetEigenNumber(part, i));
639*8be712e4SBarry Smith   PetscCall(PetscOptionsBool("-mat_partitioning_chaco_verbose", "Show library output", "", chaco->verbose, &chaco->verbose, NULL));
640*8be712e4SBarry Smith   PetscOptionsHeadEnd();
641*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
642*8be712e4SBarry Smith }
643*8be712e4SBarry Smith 
644*8be712e4SBarry Smith static PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
645*8be712e4SBarry Smith {
646*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
647*8be712e4SBarry Smith 
648*8be712e4SBarry Smith   PetscFunctionBegin;
649*8be712e4SBarry Smith   PetscCall(PetscFree(chaco));
650*8be712e4SBarry Smith   /* clear composed functions */
651*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", NULL));
652*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", NULL));
653*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", NULL));
654*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", NULL));
655*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", NULL));
656*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", NULL));
657*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", NULL));
658*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", NULL));
659*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", NULL));
660*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", NULL));
661*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", NULL));
662*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
663*8be712e4SBarry Smith }
664*8be712e4SBarry Smith 
665*8be712e4SBarry Smith /*MC
666*8be712e4SBarry Smith    MATPARTITIONINGCHACO - Creates a partitioning context that uses the external package Chaco.
667*8be712e4SBarry Smith 
668*8be712e4SBarry Smith    Level: beginner
669*8be712e4SBarry Smith 
670*8be712e4SBarry Smith    Note:
671*8be712e4SBarry Smith    Does not use the `MatPartitioningSetUseEdgeWeights()` option
672*8be712e4SBarry Smith 
673*8be712e4SBarry Smith    References:
674*8be712e4SBarry Smith .   * -  http://www.cs.sandia.gov/CRF/chac.html
675*8be712e4SBarry Smith 
676*8be712e4SBarry Smith .seealso: `MatPartitioningSetType()`, `MatPartitioningType`
677*8be712e4SBarry Smith M*/
678*8be712e4SBarry Smith 
679*8be712e4SBarry Smith PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Chaco(MatPartitioning part)
680*8be712e4SBarry Smith {
681*8be712e4SBarry Smith   MatPartitioning_Chaco *chaco;
682*8be712e4SBarry Smith 
683*8be712e4SBarry Smith   PetscFunctionBegin;
684*8be712e4SBarry Smith   PetscCall(PetscNew(&chaco));
685*8be712e4SBarry Smith   part->data = (void *)chaco;
686*8be712e4SBarry Smith 
687*8be712e4SBarry Smith   chaco->global_method = MP_CHACO_MULTILEVEL;
688*8be712e4SBarry Smith   chaco->local_method  = MP_CHACO_KERNIGHAN;
689*8be712e4SBarry Smith   chaco->eigen_method  = MP_CHACO_LANCZOS;
690*8be712e4SBarry Smith   chaco->nbvtxcoarsed  = 200;
691*8be712e4SBarry Smith   chaco->eignum        = 1;
692*8be712e4SBarry Smith   chaco->eigtol        = 0.001;
693*8be712e4SBarry Smith   chaco->verbose       = PETSC_FALSE;
694*8be712e4SBarry Smith 
695*8be712e4SBarry Smith   part->ops->apply          = MatPartitioningApply_Chaco;
696*8be712e4SBarry Smith   part->ops->view           = MatPartitioningView_Chaco;
697*8be712e4SBarry Smith   part->ops->destroy        = MatPartitioningDestroy_Chaco;
698*8be712e4SBarry Smith   part->ops->setfromoptions = MatPartitioningSetFromOptions_Chaco;
699*8be712e4SBarry Smith 
700*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", MatPartitioningChacoSetGlobal_Chaco));
701*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", MatPartitioningChacoGetGlobal_Chaco));
702*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", MatPartitioningChacoSetLocal_Chaco));
703*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", MatPartitioningChacoGetLocal_Chaco));
704*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", MatPartitioningChacoSetCoarseLevel_Chaco));
705*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", MatPartitioningChacoSetEigenSolver_Chaco));
706*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", MatPartitioningChacoGetEigenSolver_Chaco));
707*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", MatPartitioningChacoSetEigenTol_Chaco));
708*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", MatPartitioningChacoGetEigenTol_Chaco));
709*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", MatPartitioningChacoSetEigenNumber_Chaco));
710*8be712e4SBarry Smith   PetscCall(PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", MatPartitioningChacoGetEigenNumber_Chaco));
711*8be712e4SBarry Smith   PetscFunctionReturn(PETSC_SUCCESS);
712*8be712e4SBarry Smith }
713