Actual source code: chaco.c


  2: #include <../src/mat/impls/adj/mpi/mpiadj.h>

  4: #if defined(PETSC_HAVE_UNISTD_H)
  5:   #include <unistd.h>
  6: #endif

  8: #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
  9:   #include <chaco.h>
 10: #else
 11: /* Older versions of Chaco do not have an include file */
 12: 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);
 13: #endif

 15: extern int FREE_GRAPH;

 17: /*
 18: int       nvtxs;                number of vertices in full graph
 19: int      *start;                start of edge list for each vertex
 20: int      *adjacency;            edge list data
 21: int      *vwgts;                weights for all vertices
 22: float    *ewgts;                weights for all edges
 23: float    *x, *y, *z;            coordinates for inertial method
 24: char     *outassignname;        name of assignment output file
 25: char     *outfilename;          output file name
 26: short    *assignment;           set number of each vtx (length n)
 27: int       architecture;         0 => hypercube, d => d-dimensional mesh
 28: int       ndims_tot;            total number of cube dimensions to divide
 29: int       mesh_dims[3];         dimensions of mesh of processors
 30: double   *goal;                 desired set sizes for each set
 31: int       global_method;        global partitioning algorithm
 32: int       local_method;         local partitioning algorithm
 33: int       rqi_flag;             should I use RQI/Symmlq eigensolver?
 34: int       vmax;                 how many vertices to coarsen down to?
 35: int       ndims;                number of eigenvectors (2^d sets)
 36: double    eigtol;               tolerance on eigenvectors
 37: long      seed;                 for random graph mutations
 38: */

 40: typedef struct {
 41:   PetscBool         verbose;
 42:   PetscInt          eignum;
 43:   PetscReal         eigtol;
 44:   MPChacoGlobalType global_method; /* global method */
 45:   MPChacoLocalType  local_method;  /* local method */
 46:   MPChacoEigenType  eigen_method;  /* eigensolver */
 47:   PetscInt          nbvtxcoarsed;  /* number of vertices for the coarse graph */
 48: } MatPartitioning_Chaco;

 50: #define SIZE_LOG 10000 /* size of buffer for mesg_log */

 52: static PetscErrorCode MatPartitioningApply_Chaco(MatPartitioning part, IS *partitioning)
 53: {
 54:   int                    cerr;
 55:   PetscInt              *parttab, *locals, i, nb_locals, M, N;
 56:   PetscMPIInt            size, rank;
 57:   Mat                    mat = part->adj, matAdj, matSeq, *A;
 58:   Mat_MPIAdj            *adj;
 59:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
 60:   PetscBool              flg;
 61:   IS                     isrow, iscol;
 62:   int                    nvtxs, *start, *adjacency, *vwgts, architecture, ndims_tot;
 63:   int                    mesh_dims[3], global_method, local_method, rqi_flag, vmax, ndims;
 64: #if defined(PETSC_HAVE_CHACO_INT_ASSIGNMENT)
 65:   int *assignment;
 66: #else
 67:   short *assignment;
 68: #endif
 69:   double eigtol;
 70:   long   seed;
 71:   char  *mesg_log;
 72: #if defined(PETSC_HAVE_UNISTD_H)
 73:   int fd_stdout, fd_pipe[2], count, err;
 74: #endif

 77:   FREE_GRAPH = 0; /* otherwise Chaco will attempt to free memory for adjacency graph */
 78:   MPI_Comm_size(PetscObjectComm((PetscObject)mat), &size);
 79:   MPI_Comm_rank(PetscObjectComm((PetscObject)mat), &rank);
 80:   PetscObjectTypeCompare((PetscObject)mat, MATMPIADJ, &flg);
 81:   if (size > 1) {
 82:     if (flg) {
 83:       MatMPIAdjToSeq(mat, &matSeq);
 84:     } else {
 85:       PetscInfo(part, "Converting distributed matrix to sequential: this could be a performance loss\n");
 86:       MatGetSize(mat, &M, &N);
 87:       ISCreateStride(PETSC_COMM_SELF, M, 0, 1, &isrow);
 88:       ISCreateStride(PETSC_COMM_SELF, N, 0, 1, &iscol);
 89:       MatCreateSubMatrices(mat, 1, &isrow, &iscol, MAT_INITIAL_MATRIX, &A);
 90:       ISDestroy(&isrow);
 91:       ISDestroy(&iscol);
 92:       matSeq = *A;
 93:       PetscFree(A);
 94:     }
 95:   } else {
 96:     PetscObjectReference((PetscObject)mat);
 97:     matSeq = mat;
 98:   }

100:   if (!flg) { /* convert regular matrix to MPIADJ */
101:     MatConvert(matSeq, MATMPIADJ, MAT_INITIAL_MATRIX, &matAdj);
102:   } else {
103:     PetscObjectReference((PetscObject)matSeq);
104:     matAdj = matSeq;
105:   }

107:   adj = (Mat_MPIAdj *)matAdj->data; /* finaly adj contains adjacency graph */

109:   /* arguments for Chaco library */
110:   nvtxs         = mat->rmap->N;         /* number of vertices in full graph */
111:   start         = adj->i;               /* start of edge list for each vertex */
112:   vwgts         = part->vertex_weights; /* weights for all vertices */
113:   architecture  = 1;                    /* 0 => hypercube, d => d-dimensional mesh */
114:   ndims_tot     = 0;                    /* total number of cube dimensions to divide */
115:   mesh_dims[0]  = part->n;              /* dimensions of mesh of processors */
116:   global_method = chaco->global_method; /* global partitioning algorithm */
117:   local_method  = chaco->local_method;  /* local partitioning algorithm */
118:   rqi_flag      = chaco->eigen_method;  /* should I use RQI/Symmlq eigensolver? */
119:   vmax          = chaco->nbvtxcoarsed;  /* how many vertices to coarsen down to? */
120:   ndims         = chaco->eignum;        /* number of eigenvectors (2^d sets) */
121:   eigtol        = chaco->eigtol;        /* tolerance on eigenvectors */
122:   seed          = 123636512;            /* for random graph mutations */

124:   PetscMalloc1(mat->rmap->N, &assignment);
125:   PetscMalloc1(start[nvtxs], &adjacency);
126:   for (i = 0; i < start[nvtxs]; i++) adjacency[i] = (adj->j)[i] + 1; /* 1-based indexing */

128:     /* redirect output to buffer */
129: #if defined(PETSC_HAVE_UNISTD_H)
130:   fd_stdout = dup(1);
132:   close(1);
133:   dup2(fd_pipe[1], 1);
134:   PetscMalloc1(SIZE_LOG, &mesg_log);
135: #endif

137:   /* library call */
138:   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);

140: #if defined(PETSC_HAVE_UNISTD_H)
141:   err = fflush(stdout);
143:   count = read(fd_pipe[0], mesg_log, (SIZE_LOG - 1) * sizeof(char));
144:   if (count < 0) count = 0;
145:   mesg_log[count] = 0;
146:   close(1);
147:   dup2(fd_stdout, 1);
148:   close(fd_stdout);
149:   close(fd_pipe[0]);
150:   close(fd_pipe[1]);
151:   if (chaco->verbose) PetscPrintf(PetscObjectComm((PetscObject)mat), "%s", mesg_log);
152:   PetscFree(mesg_log);
153: #endif

156:   PetscMalloc1(mat->rmap->N, &parttab);
157:   for (i = 0; i < nvtxs; i++) parttab[i] = assignment[i];

159:   /* creation of the index set */
160:   nb_locals = mat->rmap->n;
161:   locals    = parttab + mat->rmap->rstart;
162:   ISCreateGeneral(PetscObjectComm((PetscObject)part), nb_locals, locals, PETSC_COPY_VALUES, partitioning);

164:   /* clean up */
165:   PetscFree(parttab);
166:   PetscFree(adjacency);
167:   PetscFree(assignment);
168:   MatDestroy(&matSeq);
169:   MatDestroy(&matAdj);
170:   return 0;
171: }

173: PetscErrorCode MatPartitioningView_Chaco(MatPartitioning part, PetscViewer viewer)
174: {
175:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
176:   PetscBool              isascii;

178:   PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii);
179:   if (isascii) {
180:     PetscViewerASCIIPrintf(viewer, "  Global method: %s\n", MPChacoGlobalTypes[chaco->global_method]);
181:     PetscViewerASCIIPrintf(viewer, "  Local method: %s\n", MPChacoLocalTypes[chaco->local_method]);
182:     PetscViewerASCIIPrintf(viewer, "  Number of vertices for the coarse graph: %" PetscInt_FMT "\n", chaco->nbvtxcoarsed);
183:     PetscViewerASCIIPrintf(viewer, "  Eigensolver: %s\n", MPChacoEigenTypes[chaco->eigen_method]);
184:     PetscViewerASCIIPrintf(viewer, "  Tolerance for eigensolver: %g\n", chaco->eigtol);
185:     PetscViewerASCIIPrintf(viewer, "  Number of eigenvectors: %" PetscInt_FMT "\n", chaco->eignum);
186:   }
187:   return 0;
188: }

190: /*@
191:    MatPartitioningChacoSetGlobal - Set the global method for Chaco partitioner.

193:    Collective

195:    Input Parameters:
196: +  part - the partitioning context
197: -  method - one of `MP_CHACO_MULTILEVEL`, `MP_CHACO_SPECTRAL`, `MP_CHACO_LINEAR`,
198:             `MP_CHACO_RANDOM` or `MP_CHACO_SCATTERED`

200:    Options Database Key:
201: .  -mat_partitioning_chaco_global <method> - the global method

203:    Level: advanced

205:    Note:
206:    The default is the multi-level method. See Chaco documentation for
207:    additional details.

209: .seealso: `MatPartitioning`, `MatPartioningSetType()`, `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`, `MatPartitioningChacoGetGlobal()`
210: @*/
211: PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part, MPChacoGlobalType method)
212: {
215:   PetscTryMethod(part, "MatPartitioningChacoSetGlobal_C", (MatPartitioning, MPChacoGlobalType), (part, method));
216:   return 0;
217: }

219: PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType method)
220: {
221:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

223:   switch (method) {
224:   case MP_CHACO_MULTILEVEL:
225:   case MP_CHACO_SPECTRAL:
226:   case MP_CHACO_LINEAR:
227:   case MP_CHACO_RANDOM:
228:   case MP_CHACO_SCATTERED:
229:     chaco->global_method = method;
230:     break;
231:   default:
232:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
233:   }
234:   return 0;
235: }

237: /*@
238:    MatPartitioningChacoGetGlobal - Get the global method used by the Chaco partitioner.

240:    Not Collective

242:    Input Parameter:
243: .  part - the partitioning context

245:    Output Parameter:
246: .  method - the method

248:    Level: advanced

250: .seealso:  `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`
251: @*/
252: PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part, MPChacoGlobalType *method)
253: {
256:   PetscTryMethod(part, "MatPartitioningChacoGetGlobal_C", (MatPartitioning, MPChacoGlobalType *), (part, method));
257:   return 0;
258: }

260: PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part, MPChacoGlobalType *method)
261: {
262:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

264:   *method = chaco->global_method;
265:   return 0;
266: }

268: /*@
269:    MatPartitioningChacoSetLocal - Set the local method for the Chaco partitioner.

271:    Collective

273:    Input Parameters:
274: +  part - the partitioning context
275: -  method - one of `MP_CHACO_KERNIGHAN` or `MP_CHACO_NONE`

277:    Options Database Key:
278: .  -mat_partitioning_chaco_local <method> - the local method

280:    Level: advanced

282:    Note:
283:    The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
284:    for additional details.

286: .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetGlobal()`, `MatPartitioningChacoGetLocal()`
287: @*/
288: PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part, MPChacoLocalType method)
289: {
292:   PetscTryMethod(part, "MatPartitioningChacoSetLocal_C", (MatPartitioning, MPChacoLocalType), (part, method));
293:   return 0;
294: }

296: PetscErrorCode MatPartitioningChacoSetLocal_Chaco(MatPartitioning part, MPChacoLocalType method)
297: {
298:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

300:   switch (method) {
301:   case MP_CHACO_KERNIGHAN:
302:   case MP_CHACO_NONE:
303:     chaco->local_method = method;
304:     break;
305:   default:
306:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
307:   }
308:   return 0;
309: }

311: /*@
312:    MatPartitioningChacoGetLocal - Get local method used by the Chaco partitioner.

314:    Not Collective

316:    Input Parameter:
317: .  part - the partitioning context

319:    Output Parameter:
320: .  method - the method

322:    Level: advanced

324: .seealso: `MatPartitioningType`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetLocal()`
325: @*/
326: PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part, MPChacoLocalType *method)
327: {
330:   PetscUseMethod(part, "MatPartitioningChacoGetLocal_C", (MatPartitioning, MPChacoLocalType *), (part, method));
331:   return 0;
332: }

334: PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part, MPChacoLocalType *method)
335: {
336:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

338:   *method = chaco->local_method;
339:   return 0;
340: }

342: /*@
343:    MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
344:    Chaco partitioner.

346:    Collective

348:    Input Parameters:
349: +  part - the partitioning context
350: -  level - the coarse level in range [0.0,1.0]

352:    Options Database Key:
353: .  -mat_partitioning_chaco_coarse <l> - Coarse level

355:    Level: advanced

357: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`
358: @*/
359: PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part, PetscReal level)
360: {
363:   PetscTryMethod(part, "MatPartitioningChacoSetCoarseLevel_C", (MatPartitioning, PetscReal), (part, level));
364:   return 0;
365: }

367: PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part, PetscReal level)
368: {
369:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

372:   chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
373:   if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
374:   return 0;
375: }

377: /*@
378:    MatPartitioningChacoSetEigenSolver - Set the eigensolver method for Chaco partitioner.

380:    Collective

382:    Input Parameters:
383: +  part - the partitioning context
384: -  method - one of `MP_CHACO_LANCZOS` or `MP_CHACO_RQI`

386:    Options Database Key:
387: .  -mat_partitioning_chaco_eigen_solver <method> - the eigensolver

389:    Level: advanced

391:    Note:
392:    The default is to use a Lanczos method. See Chaco documentation for details.

394: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`, `MatPartitioningChacoSetEigenNumber()`,
395:           `MatPartitioningChacoGetEigenSolver()`
396: @*/
397: PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part, MPChacoEigenType method)
398: {
401:   PetscTryMethod(part, "MatPartitioningChacoSetEigenSolver_C", (MatPartitioning, MPChacoEigenType), (part, method));
402:   return 0;
403: }

405: PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType method)
406: {
407:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

409:   switch (method) {
410:   case MP_CHACO_LANCZOS:
411:   case MP_CHACO_RQI:
412:     chaco->eigen_method = method;
413:     break;
414:   default:
415:     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Chaco: Unknown or unsupported option");
416:   }
417:   return 0;
418: }

420: /*@
421:    MatPartitioningChacoGetEigenSolver - Get the eigensolver used by the Chaco partitioner.

423:    Not Collective

425:    Input Parameter:
426: .  part - the partitioning context

428:    Output Parameter:
429: .  method - the method

431:    Level: advanced

433: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`
434: @*/
435: PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part, MPChacoEigenType *method)
436: {
439:   PetscUseMethod(part, "MatPartitioningChacoGetEigenSolver_C", (MatPartitioning, MPChacoEigenType *), (part, method));
440:   return 0;
441: }

443: PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part, MPChacoEigenType *method)
444: {
445:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

447:   *method = chaco->eigen_method;
448:   return 0;
449: }

451: /*@
452:    MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver used by Chaco

454:    Collective

456:    Input Parameters:
457: +  part - the partitioning context
458: -  tol  - the tolerance

460:    Options Database Key:
461: .  -mat_partitioning_chaco_eigen_tol <tol> - Tolerance for eigensolver

463:    Note:
464:    Must be positive. The default value is 0.001.

466:    Level: advanced

468: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
469: @*/
470: PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part, PetscReal tol)
471: {
474:   PetscTryMethod(part, "MatPartitioningChacoSetEigenTol_C", (MatPartitioning, PetscReal), (part, tol));
475:   return 0;
476: }

478: PetscErrorCode MatPartitioningChacoSetEigenTol_Chaco(MatPartitioning part, PetscReal tol)
479: {
480:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

482:   if (tol == PETSC_DEFAULT) chaco->eigtol = 0.001;
483:   else {
485:     chaco->eigtol = tol;
486:   }
487:   return 0;
488: }

490: /*@
491:    MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance used by Chaco

493:    Not Collective

495:    Input Parameter:
496: .  part - the partitioning context

498:    Output Parameter:
499: .  tol  - the tolerance

501:    Level: advanced

503: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenTol()`
504: @*/
505: PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part, PetscReal *tol)
506: {
509:   PetscUseMethod(part, "MatPartitioningChacoGetEigenTol_C", (MatPartitioning, PetscReal *), (part, tol));
510:   return 0;
511: }

513: PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part, PetscReal *tol)
514: {
515:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

517:   *tol = chaco->eigtol;
518:   return 0;
519: }

521: /*@
522:    MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute by Chaco during partioning
523:    during partitioning.

525:    Collective

527:    Input Parameters:
528: +  part - the partitioning context
529: -  num  - the number of eigenvectors

531:    Options Database Key:
532: .  -mat_partitioning_chaco_eigen_number <n> - Number of eigenvectors

534:    Note:
535:    Accepted values are 1, 2 or 3, indicating partitioning by bisection,
536:    quadrisection, or octosection.

538:    Level: advanced

540: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenSolver()`, `MatPartitioningChacoGetEigenTol()`
541: @*/
542: PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part, PetscInt num)
543: {
546:   PetscTryMethod(part, "MatPartitioningChacoSetEigenNumber_C", (MatPartitioning, PetscInt), (part, num));
547:   return 0;
548: }

550: PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part, PetscInt num)
551: {
552:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

554:   if (num == PETSC_DEFAULT) chaco->eignum = 1;
555:   else {
557:     chaco->eignum = num;
558:   }
559:   return 0;
560: }

562: /*@
563:    MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.

565:    Not Collective

567:    Input Parameter:
568: .  part - the partitioning context

570:    Output Parameter:
571: .  num  - number of eigenvectors

573:    Level: advanced

575: .seealso: `MatPartitioningType`, `MatPartitioning`, `MATPARTITIONINGCHACO`, `MatPartitioningChacoSetEigenNumber()`
576: @*/
577: PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part, PetscInt *num)
578: {
581:   PetscUseMethod(part, "MatPartitioningChacoGetEigenNumber_C", (MatPartitioning, PetscInt *), (part, num));
582:   return 0;
583: }

585: PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part, PetscInt *num)
586: {
587:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

589:   *num = chaco->eignum;
590:   return 0;
591: }

593: PetscErrorCode MatPartitioningSetFromOptions_Chaco(MatPartitioning part, PetscOptionItems *PetscOptionsObject)
594: {
595:   PetscInt               i;
596:   PetscReal              r;
597:   PetscBool              flag;
598:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;
599:   MPChacoGlobalType      global;
600:   MPChacoLocalType       local;
601:   MPChacoEigenType       eigen;

603:   PetscOptionsHeadBegin(PetscOptionsObject, "Chaco partitioning options");
604:   PetscOptionsEnum("-mat_partitioning_chaco_global", "Global method", "MatPartitioningChacoSetGlobal", MPChacoGlobalTypes, (PetscEnum)chaco->global_method, (PetscEnum *)&global, &flag);
605:   if (flag) MatPartitioningChacoSetGlobal(part, global);
606:   PetscOptionsEnum("-mat_partitioning_chaco_local", "Local method", "MatPartitioningChacoSetLocal", MPChacoLocalTypes, (PetscEnum)chaco->local_method, (PetscEnum *)&local, &flag);
607:   if (flag) MatPartitioningChacoSetLocal(part, local);
608:   PetscOptionsReal("-mat_partitioning_chaco_coarse", "Coarse level", "MatPartitioningChacoSetCoarseLevel", 0.0, &r, &flag);
609:   if (flag) MatPartitioningChacoSetCoarseLevel(part, r);
610:   PetscOptionsEnum("-mat_partitioning_chaco_eigen_solver", "Eigensolver method", "MatPartitioningChacoSetEigenSolver", MPChacoEigenTypes, (PetscEnum)chaco->eigen_method, (PetscEnum *)&eigen, &flag);
611:   if (flag) MatPartitioningChacoSetEigenSolver(part, eigen);
612:   PetscOptionsReal("-mat_partitioning_chaco_eigen_tol", "Eigensolver tolerance", "MatPartitioningChacoSetEigenTol", chaco->eigtol, &r, &flag);
613:   if (flag) MatPartitioningChacoSetEigenTol(part, r);
614:   PetscOptionsInt("-mat_partitioning_chaco_eigen_number", "Number of eigenvectors: 1, 2, or 3 (bi-, quadri-, or octosection)", "MatPartitioningChacoSetEigenNumber", chaco->eignum, &i, &flag);
615:   if (flag) MatPartitioningChacoSetEigenNumber(part, i);
616:   PetscOptionsBool("-mat_partitioning_chaco_verbose", "Show library output", "", chaco->verbose, &chaco->verbose, NULL);
617:   PetscOptionsHeadEnd();
618:   return 0;
619: }

621: PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
622: {
623:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco *)part->data;

625:   PetscFree(chaco);
626:   /* clear composed functions */
627:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", NULL);
628:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", NULL);
629:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", NULL);
630:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", NULL);
631:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", NULL);
632:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", NULL);
633:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", NULL);
634:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", NULL);
635:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", NULL);
636:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", NULL);
637:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", NULL);
638:   return 0;
639: }

641: /*MC
642:    MATPARTITIONINGCHACO - Creates a partitioning context that uses the external package Chaco.

644:    Level: beginner

646:    Note:
647:    Does not use the `MatPartitioningSetUseEdgeWeights()` option

649:    References:
650: .   * -  http://www.cs.sandia.gov/CRF/chac.html

652: .seealso: `MatPartitioningSetType()`, `MatPartitioningType`
653: M*/

655: PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Chaco(MatPartitioning part)
656: {
657:   MatPartitioning_Chaco *chaco;

659:   PetscNew(&chaco);
660:   part->data = (void *)chaco;

662:   chaco->global_method = MP_CHACO_MULTILEVEL;
663:   chaco->local_method  = MP_CHACO_KERNIGHAN;
664:   chaco->eigen_method  = MP_CHACO_LANCZOS;
665:   chaco->nbvtxcoarsed  = 200;
666:   chaco->eignum        = 1;
667:   chaco->eigtol        = 0.001;
668:   chaco->verbose       = PETSC_FALSE;

670:   part->ops->apply          = MatPartitioningApply_Chaco;
671:   part->ops->view           = MatPartitioningView_Chaco;
672:   part->ops->destroy        = MatPartitioningDestroy_Chaco;
673:   part->ops->setfromoptions = MatPartitioningSetFromOptions_Chaco;

675:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetGlobal_C", MatPartitioningChacoSetGlobal_Chaco);
676:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetGlobal_C", MatPartitioningChacoGetGlobal_Chaco);
677:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetLocal_C", MatPartitioningChacoSetLocal_Chaco);
678:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetLocal_C", MatPartitioningChacoGetLocal_Chaco);
679:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetCoarseLevel_C", MatPartitioningChacoSetCoarseLevel_Chaco);
680:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenSolver_C", MatPartitioningChacoSetEigenSolver_Chaco);
681:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenSolver_C", MatPartitioningChacoGetEigenSolver_Chaco);
682:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenTol_C", MatPartitioningChacoSetEigenTol_Chaco);
683:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenTol_C", MatPartitioningChacoGetEigenTol_Chaco);
684:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoSetEigenNumber_C", MatPartitioningChacoSetEigenNumber_Chaco);
685:   PetscObjectComposeFunction((PetscObject)part, "MatPartitioningChacoGetEigenNumber_C", MatPartitioningChacoGetEigenNumber_Chaco);
686:   return 0;
687: }