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,
 13:                      float *ewgts, float *x, float *y, float *z, char *outassignname,
 14:                      char *outfilename, short *assignment, int architecture, int ndims_tot,
 15:                      int mesh_dims[3], double *goal, int global_method, int local_method,
 16:                      int rqi_flag, int vmax, int ndims, double eigtol, long seed);
 17: #endif

 19: extern int FREE_GRAPH;

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

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

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

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

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

104:   if (!flg) { /* convert regular matrix to MPIADJ */
105:     MatConvert(matSeq,MATMPIADJ,MAT_INITIAL_MATRIX,&matAdj);
106:   } else {
107:     PetscObjectReference((PetscObject)matSeq);
108:     matAdj = matSeq;
109:   }

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

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

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

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

141:   /* library call */
142:   interface(nvtxs,start,adjacency,vwgts,NULL,NULL,NULL,NULL,
143:                    NULL,NULL,assignment,architecture,ndims_tot,mesh_dims,
144:                    NULL,global_method,local_method,rqi_flag,vmax,ndims,eigtol,seed);

146: #if defined(PETSC_HAVE_UNISTD_H)
147:   err = fflush(stdout);
149:   count = read(fd_pipe[0],mesg_log,(SIZE_LOG-1)*sizeof(char));
150:   if (count<0) count = 0;
151:   mesg_log[count] = 0;
152:   close(1);
153:   dup2(fd_stdout,1);
154:   close(fd_stdout);
155:   close(fd_pipe[0]);
156:   close(fd_pipe[1]);
157:   if (chaco->verbose) {
158:     PetscPrintf(PetscObjectComm((PetscObject)mat),"%s",mesg_log);
159:   }
160:   PetscFree(mesg_log);
161: #endif

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

167:   /* creation of the index set */
168:   nb_locals = mat->rmap->n;
169:   locals    = parttab + mat->rmap->rstart;
170:   ISCreateGeneral(PetscObjectComm((PetscObject)part),nb_locals,locals,PETSC_COPY_VALUES,partitioning);

172:   /* clean up */
173:   PetscFree(parttab);
174:   PetscFree(adjacency);
175:   PetscFree(assignment);
176:   MatDestroy(&matSeq);
177:   MatDestroy(&matAdj);
178:   return 0;
179: }

181: PetscErrorCode MatPartitioningView_Chaco(MatPartitioning part, PetscViewer viewer)
182: {
183:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;
184:   PetscBool             isascii;

186:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
187:   if (isascii) {
188:     PetscViewerASCIIPrintf(viewer,"  Global method: %s\n",MPChacoGlobalTypes[chaco->global_method]);
189:     PetscViewerASCIIPrintf(viewer,"  Local method: %s\n",MPChacoLocalTypes[chaco->local_method]);
190:     PetscViewerASCIIPrintf(viewer,"  Number of vertices for the coarse graph: %" PetscInt_FMT "\n",chaco->nbvtxcoarsed);
191:     PetscViewerASCIIPrintf(viewer,"  Eigensolver: %s\n",MPChacoEigenTypes[chaco->eigen_method]);
192:     PetscViewerASCIIPrintf(viewer,"  Tolerance for eigensolver: %g\n",chaco->eigtol);
193:     PetscViewerASCIIPrintf(viewer,"  Number of eigenvectors: %" PetscInt_FMT "\n",chaco->eignum);
194:   }
195:   return 0;
196: }

198: /*@
199:    MatPartitioningChacoSetGlobal - Set global method for Chaco partitioner.

201:    Collective on MatPartitioning

203:    Input Parameters:
204: +  part - the partitioning context
205: -  method - one of MP_CHACO_MULTILEVEL, MP_CHACO_SPECTRAL, MP_CHACO_LINEAR,
206:             MP_CHACO_RANDOM or MP_CHACO_SCATTERED

208:    Options Database:
209: .  -mat_partitioning_chaco_global <method> - the global method

211:    Level: advanced

213:    Notes:
214:    The default is the multi-level method. See Chaco documentation for
215:    additional details.

217: .seealso: MatPartitioningChacoSetLocal(),MatPartitioningChacoGetGlobal()
218: @*/
219: PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part,MPChacoGlobalType method)
220: {
223:   PetscTryMethod(part,"MatPartitioningChacoSetGlobal_C",(MatPartitioning,MPChacoGlobalType),(part,method));
224:   return 0;
225: }

227: PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType method)
228: {
229:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

231:   switch (method) {
232:   case MP_CHACO_MULTILEVEL:
233:   case MP_CHACO_SPECTRAL:
234:   case MP_CHACO_LINEAR:
235:   case MP_CHACO_RANDOM:
236:   case MP_CHACO_SCATTERED:
237:     chaco->global_method = method; break;
238:   default:
239:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
240:   }
241:   return 0;
242: }

244: /*@
245:    MatPartitioningChacoGetGlobal - Get global method for Chaco partitioner.

247:    Not Collective

249:    Input Parameter:
250: .  part - the partitioning context

252:    Output Parameter:
253: .  method - the method

255:    Level: advanced

257: .seealso: MatPartitioningChacoSetGlobal()
258: @*/
259: PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part,MPChacoGlobalType *method)
260: {
263:   PetscTryMethod(part,"MatPartitioningChacoGetGlobal_C",(MatPartitioning,MPChacoGlobalType*),(part,method));
264:   return 0;
265: }

267: PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType *method)
268: {
269:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

271:   *method = chaco->global_method;
272:   return 0;
273: }

275: /*@
276:    MatPartitioningChacoSetLocal - Set local method for Chaco partitioner.

278:    Collective on MatPartitioning

280:    Input Parameters:
281: +  part - the partitioning context
282: -  method - one of MP_CHACO_KERNIGHAN or MP_CHACO_NONE

284:    Options Database:
285: .  -mat_partitioning_chaco_local <method> - the local method

287:    Level: advanced

289:    Notes:
290:    The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
291:    for additional details.

293: .seealso: MatPartitioningChacoSetGlobal(),MatPartitioningChacoGetLocal()
294: @*/
295: PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part,MPChacoLocalType method)
296: {
299:   PetscTryMethod(part,"MatPartitioningChacoSetLocal_C",(MatPartitioning,MPChacoLocalType),(part,method));
300:   return 0;
301: }

303: PetscErrorCode MatPartitioningChacoSetLocal_Chaco(MatPartitioning part,MPChacoLocalType method)
304: {
305:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

307:   switch (method) {
308:   case MP_CHACO_KERNIGHAN:
309:   case MP_CHACO_NONE:
310:     chaco->local_method = method; break;
311:   default:
312:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
313:   }
314:   return 0;
315: }

317: /*@
318:    MatPartitioningChacoGetLocal - Get local method for Chaco partitioner.

320:    Not Collective

322:    Input Parameter:
323: .  part - the partitioning context

325:    Output Parameter:
326: .  method - the method

328:    Level: advanced

330: .seealso: MatPartitioningChacoSetLocal()
331: @*/
332: PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part,MPChacoLocalType *method)
333: {
336:   PetscUseMethod(part,"MatPartitioningChacoGetLocal_C",(MatPartitioning,MPChacoLocalType*),(part,method));
337:   return 0;
338: }

340: PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part,MPChacoLocalType *method)
341: {
342:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

344:   *method = chaco->local_method;
345:   return 0;
346: }

348: /*@
349:    MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
350:    Chaco partitioner.

352:    Collective on MatPartitioning

354:    Input Parameters:
355: +  part - the partitioning context
356: -  level - the coarse level in range [0.0,1.0]

358:    Options Database:
359: .  -mat_partitioning_chaco_coarse <l> - Coarse level

361:    Level: advanced
362: @*/
363: PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part,PetscReal level)
364: {
367:   PetscTryMethod(part,"MatPartitioningChacoSetCoarseLevel_C",(MatPartitioning,PetscReal),(part,level));
368:   return 0;
369: }

371: PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part,PetscReal level)
372: {
373:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

376:   chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
377:   if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
378:   return 0;
379: }

381: /*@
382:    MatPartitioningChacoSetEigenSolver - Set eigensolver method for Chaco partitioner.

384:    Collective on MatPartitioning

386:    Input Parameters:
387: +  part - the partitioning context
388: -  method - one of MP_CHACO_LANCZOS or MP_CHACO_RQI

390:    Options Database:
391: .  -mat_partitioning_chaco_eigen_solver <method> - the eigensolver

393:    Level: advanced

395:    Notes:
396:    The default is to use a Lanczos method. See Chaco documentation for details.

398: .seealso: MatPartitioningChacoSetEigenTol(),MatPartitioningChacoSetEigenNumber(),
399:           MatPartitioningChacoGetEigenSolver()
400: @*/
401: PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part,MPChacoEigenType method)
402: {
405:   PetscTryMethod(part,"MatPartitioningChacoSetEigenSolver_C",(MatPartitioning,MPChacoEigenType),(part,method));
406:   return 0;
407: }

409: PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType method)
410: {
411:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

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

423: /*@
424:    MatPartitioningChacoGetEigenSolver - Get local method for Chaco partitioner.

426:    Not Collective

428:    Input Parameter:
429: .  part - the partitioning context

431:    Output Parameter:
432: .  method - the method

434:    Level: advanced

436: .seealso: MatPartitioningChacoSetEigenSolver()
437: @*/
438: PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part,MPChacoEigenType *method)
439: {
442:   PetscUseMethod(part,"MatPartitioningChacoGetEigenSolver_C",(MatPartitioning,MPChacoEigenType*),(part,method));
443:   return 0;
444: }

446: PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType *method)
447: {
448:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

450:   *method = chaco->eigen_method;
451:   return 0;
452: }

454: /*@
455:    MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver.

457:    Collective on MatPartitioning

459:    Input Parameters:
460: +  part - the partitioning context
461: -  tol  - the tolerance

463:    Options Database:
464: .  -mat_partitioning_chaco_eigen_tol <tol> - Tolerance for eigensolver

466:    Note:
467:    Must be positive. The default value is 0.001.

469:    Level: advanced

471: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
472: @*/
473: PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part,PetscReal tol)
474: {
477:   PetscTryMethod(part,"MatPartitioningChacoSetEigenTol_C",(MatPartitioning,PetscReal),(part,tol));
478:   return 0;
479: }

481: PetscErrorCode MatPartitioningChacoSetEigenTol_Chaco(MatPartitioning part,PetscReal tol)
482: {
483:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

485:   if (tol==PETSC_DEFAULT) chaco->eigtol = 0.001;
486:   else {
488:     chaco->eigtol = tol;
489:   }
490:   return 0;
491: }

493: /*@
494:    MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance.

496:    Not Collective

498:    Input Parameter:
499: .  part - the partitioning context

501:    Output Parameter:
502: .  tol  - the tolerance

504:    Level: advanced

506: .seealso: MatPartitioningChacoSetEigenTol()
507: @*/
508: PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part,PetscReal *tol)
509: {
512:   PetscUseMethod(part,"MatPartitioningChacoGetEigenTol_C",(MatPartitioning,PetscReal*),(part,tol));
513:   return 0;
514: }

516: PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part,PetscReal *tol)
517: {
518:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

520:   *tol = chaco->eigtol;
521:   return 0;
522: }

524: /*@
525:    MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute
526:    during partitioning.

528:    Collective on MatPartitioning

530:    Input Parameters:
531: +  part - the partitioning context
532: -  num  - the number of eigenvectors

534:    Options Database:
535: .  -mat_partitioning_chaco_eigen_number <n> - Number of eigenvectors

537:    Note:
538:    Accepted values are 1, 2 or 3, indicating partitioning by bisection,
539:    quadrisection, or octosection.

541:    Level: advanced

543: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
544: @*/
545: PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part,PetscInt num)
546: {
549:   PetscTryMethod(part,"MatPartitioningChacoSetEigenNumber_C",(MatPartitioning,PetscInt),(part,num));
550:   return 0;
551: }

553: PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part,PetscInt num)
554: {
555:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

557:   if (num==PETSC_DEFAULT) chaco->eignum = 1;
558:   else {
560:     chaco->eignum = num;
561:   }
562:   return 0;
563: }

565: /*@
566:    MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.

568:    Not Collective

570:    Input Parameter:
571: .  part - the partitioning context

573:    Output Parameter:
574: .  num  - number of eigenvectors

576:    Level: advanced

578: .seealso: MatPartitioningChacoSetEigenNumber()
579: @*/
580: PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part,PetscInt *num)
581: {
584:   PetscUseMethod(part,"MatPartitioningChacoGetEigenNumber_C",(MatPartitioning,PetscInt*),(part,num));
585:   return 0;
586: }

588: PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part,PetscInt *num)
589: {
590:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

592:   *num = chaco->eignum;
593:   return 0;
594: }

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

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

624: PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
625: {
626:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*) part->data;

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

644: /*MC
645:    MATPARTITIONINGCHACO - Creates a partitioning context via the external package Chaco.

647:    Level: beginner

649:    Notes:
650:     See http://www.cs.sandia.gov/CRF/chac.html
651:     Does not using MatPartitioningSetUseEdgeWeights()

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

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

660:   PetscNewLog(part,&chaco);
661:   part->data = (void*)chaco;

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

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

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