Actual source code: chaco.c

petsc-main 2021-04-20
Report Typos and Errors

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

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

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

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

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

133:   /* redirect output to buffer */
134: #if defined(PETSC_HAVE_UNISTD_H)
135:   fd_stdout = dup(1);
136:   if (pipe(fd_pipe)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Could not open pipe");
137:   close(1);
138:   dup2(fd_pipe[1],1);
139:   PetscMalloc1(SIZE_LOG,&mesg_log);
140: #endif

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

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

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

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

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

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

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

201: /*@
202:    MatPartitioningChacoSetGlobal - Set global method for Chaco partitioner.

204:    Collective on MatPartitioning

206:    Input Parameters:
207: +  part - the partitioning context
208: -  method - one of MP_CHACO_MULTILEVEL, MP_CHACO_SPECTRAL, MP_CHACO_LINEAR,
209:             MP_CHACO_RANDOM or MP_CHACO_SCATTERED

211:    Options Database:
212: .  -mat_partitioning_chaco_global <method> - the global method

214:    Level: advanced

216:    Notes:
217:    The default is the multi-level method. See Chaco documentation for
218:    additional details.

220: .seealso: MatPartitioningChacoSetLocal(),MatPartitioningChacoGetGlobal()
221: @*/
222: PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part,MPChacoGlobalType method)
223: {

229:   PetscTryMethod(part,"MatPartitioningChacoSetGlobal_C",(MatPartitioning,MPChacoGlobalType),(part,method));
230:   return(0);
231: }

233: PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType method)
234: {
235:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

238:   switch (method) {
239:   case MP_CHACO_MULTILEVEL:
240:   case MP_CHACO_SPECTRAL:
241:   case MP_CHACO_LINEAR:
242:   case MP_CHACO_RANDOM:
243:   case MP_CHACO_SCATTERED:
244:     chaco->global_method = method; break;
245:   default:
246:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
247:   }
248:   return(0);
249: }

251: /*@
252:    MatPartitioningChacoGetGlobal - Get global method for Chaco partitioner.

254:    Not Collective

256:    Input Parameter:
257: .  part - the partitioning context

259:    Output Parameter:
260: .  method - the method

262:    Level: advanced

264: .seealso: MatPartitioningChacoSetGlobal()
265: @*/
266: PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part,MPChacoGlobalType *method)
267: {

273:   PetscTryMethod(part,"MatPartitioningChacoGetGlobal_C",(MatPartitioning,MPChacoGlobalType*),(part,method));
274:   return(0);
275: }

277: PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType *method)
278: {
279:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

282:   *method = chaco->global_method;
283:   return(0);
284: }

286: /*@
287:    MatPartitioningChacoSetLocal - Set local method for Chaco partitioner.

289:    Collective on MatPartitioning

291:    Input Parameters:
292: +  part - the partitioning context
293: -  method - one of MP_CHACO_KERNIGHAN or MP_CHACO_NONE

295:    Options Database:
296: .  -mat_partitioning_chaco_local <method> - the local method

298:    Level: advanced

300:    Notes:
301:    The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
302:    for additional details.

304: .seealso: MatPartitioningChacoSetGlobal(),MatPartitioningChacoGetLocal()
305: @*/
306: PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part,MPChacoLocalType method)
307: {

313:   PetscTryMethod(part,"MatPartitioningChacoSetLocal_C",(MatPartitioning,MPChacoLocalType),(part,method));
314:   return(0);
315: }

317: PetscErrorCode MatPartitioningChacoSetLocal_Chaco(MatPartitioning part,MPChacoLocalType method)
318: {
319:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

322:   switch (method) {
323:   case MP_CHACO_KERNIGHAN:
324:   case MP_CHACO_NONE:
325:     chaco->local_method = method; break;
326:   default:
327:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
328:   }
329:   return(0);
330: }

332: /*@
333:    MatPartitioningChacoGetLocal - Get local method for Chaco partitioner.

335:    Not Collective

337:    Input Parameter:
338: .  part - the partitioning context

340:    Output Parameter:
341: .  method - the method

343:    Level: advanced

345: .seealso: MatPartitioningChacoSetLocal()
346: @*/
347: PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part,MPChacoLocalType *method)
348: {

354:   PetscUseMethod(part,"MatPartitioningChacoGetLocal_C",(MatPartitioning,MPChacoLocalType*),(part,method));
355:   return(0);
356: }

358: PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part,MPChacoLocalType *method)
359: {
360:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

363:   *method = chaco->local_method;
364:   return(0);
365: }

367: /*@
368:    MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
369:    Chaco partitioner.

371:    Collective on MatPartitioning

373:    Input Parameters:
374: +  part - the partitioning context
375: -  level - the coarse level in range [0.0,1.0]

377:    Options Database:
378: .  -mat_partitioning_chaco_coarse <l> - Coarse level

380:    Level: advanced
381: @*/
382: PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part,PetscReal level)
383: {

389:   PetscTryMethod(part,"MatPartitioningChacoSetCoarseLevel_C",(MatPartitioning,PetscReal),(part,level));
390:   return(0);
391: }

393: PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part,PetscReal level)
394: {
395:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

398:   if (level<0.0 || level>1.0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Chaco: level of coarsening out of range [0.0-1.0]");
399:   chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
400:   if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
401:   return(0);
402: }

404: /*@
405:    MatPartitioningChacoSetEigenSolver - Set eigensolver method for Chaco partitioner.

407:    Collective on MatPartitioning

409:    Input Parameters:
410: +  part - the partitioning context
411: -  method - one of MP_CHACO_LANCZOS or MP_CHACO_RQI

413:    Options Database:
414: .  -mat_partitioning_chaco_eigen_solver <method> - the eigensolver

416:    Level: advanced

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

421: .seealso: MatPartitioningChacoSetEigenTol(),MatPartitioningChacoSetEigenNumber(),
422:           MatPartitioningChacoGetEigenSolver()
423: @*/
424: PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part,MPChacoEigenType method)
425: {

431:   PetscTryMethod(part,"MatPartitioningChacoSetEigenSolver_C",(MatPartitioning,MPChacoEigenType),(part,method));
432:   return(0);
433: }

435: PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType method)
436: {
437:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

440:   switch (method) {
441:   case MP_CHACO_LANCZOS:
442:   case MP_CHACO_RQI:
443:     chaco->eigen_method = method; break;
444:   default:
445:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
446:   }
447:   return(0);
448: }

450: /*@
451:    MatPartitioningChacoGetEigenSolver - Get local method for Chaco partitioner.

453:    Not Collective

455:    Input Parameter:
456: .  part - the partitioning context

458:    Output Parameter:
459: .  method - the method

461:    Level: advanced

463: .seealso: MatPartitioningChacoSetEigenSolver()
464: @*/
465: PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part,MPChacoEigenType *method)
466: {

472:   PetscUseMethod(part,"MatPartitioningChacoGetEigenSolver_C",(MatPartitioning,MPChacoEigenType*),(part,method));
473:   return(0);
474: }

476: PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType *method)
477: {
478:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

481:   *method = chaco->eigen_method;
482:   return(0);
483: }

485: /*@
486:    MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver.

488:    Collective on MatPartitioning

490:    Input Parameters:
491: +  part - the partitioning context
492: -  tol  - the tolerance

494:    Options Database:
495: .  -mat_partitioning_chaco_eigen_tol <tol>: Tolerance for eigensolver

497:    Note:
498:    Must be positive. The default value is 0.001.

500:    Level: advanced

502: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
503: @*/
504: PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part,PetscReal tol)
505: {

511:   PetscTryMethod(part,"MatPartitioningChacoSetEigenTol_C",(MatPartitioning,PetscReal),(part,tol));
512:   return(0);
513: }

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

520:   if (tol==PETSC_DEFAULT) chaco->eigtol = 0.001;
521:   else {
522:     if (tol<=0.0) SETERRQ(PetscObjectComm((PetscObject)part),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance must be positive");
523:     chaco->eigtol = tol;
524:   }
525:   return(0);
526: }

528: /*@
529:    MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance.

531:    Not Collective

533:    Input Parameter:
534: .  part - the partitioning context

536:    Output Parameter:
537: .  tol  - the tolerance

539:    Level: advanced

541: .seealso: MatPartitioningChacoSetEigenTol()
542: @*/
543: PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part,PetscReal *tol)
544: {

550:   PetscUseMethod(part,"MatPartitioningChacoGetEigenTol_C",(MatPartitioning,PetscReal*),(part,tol));
551:   return(0);
552: }

554: PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part,PetscReal *tol)
555: {
556:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

559:   *tol = chaco->eigtol;
560:   return(0);
561: }

563: /*@
564:    MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute
565:    during partitioning.

567:    Collective on MatPartitioning

569:    Input Parameters:
570: +  part - the partitioning context
571: -  num  - the number of eigenvectors

573:    Options Database:
574: .  -mat_partitioning_chaco_eigen_number <n>: Number of eigenvectors

576:    Note:
577:    Accepted values are 1, 2 or 3, indicating partitioning by bisection,
578:    quadrisection, or octosection.

580:    Level: advanced

582: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
583: @*/
584: PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part,PetscInt num)
585: {

591:   PetscTryMethod(part,"MatPartitioningChacoSetEigenNumber_C",(MatPartitioning,PetscInt),(part,num));
592:   return(0);
593: }

595: PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part,PetscInt num)
596: {
597:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

600:   if (num==PETSC_DEFAULT) chaco->eignum = 1;
601:   else {
602:     if (num<1 || num>3) SETERRQ(PetscObjectComm((PetscObject)part),PETSC_ERR_ARG_OUTOFRANGE,"Can only specify 1, 2 or 3 eigenvectors");
603:     chaco->eignum = num;
604:   }
605:   return(0);
606: }

608: /*@
609:    MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.

611:    Not Collective

613:    Input Parameter:
614: .  part - the partitioning context

616:    Output Parameter:
617: .  num  - number of eigenvectors

619:    Level: advanced

621: .seealso: MatPartitioningChacoSetEigenNumber()
622: @*/
623: PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part,PetscInt *num)
624: {

630:   PetscUseMethod(part,"MatPartitioningChacoGetEigenNumber_C",(MatPartitioning,PetscInt*),(part,num));
631:   return(0);
632: }

634: PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part,PetscInt *num)
635: {
636:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

639:   *num = chaco->eignum;
640:   return(0);
641: }

643: PetscErrorCode MatPartitioningSetFromOptions_Chaco(PetscOptionItems *PetscOptionsObject,MatPartitioning part)
644: {
645:   PetscErrorCode        ierr;
646:   PetscInt              i;
647:   PetscReal             r;
648:   PetscBool             flag;
649:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;
650:   MPChacoGlobalType     global;
651:   MPChacoLocalType      local;
652:   MPChacoEigenType      eigen;

655:   PetscOptionsHead(PetscOptionsObject,"Chaco partitioning options");
656:   PetscOptionsEnum("-mat_partitioning_chaco_global","Global method","MatPartitioningChacoSetGlobal",MPChacoGlobalTypes,(PetscEnum)chaco->global_method,(PetscEnum*)&global,&flag);
657:   if (flag) { MatPartitioningChacoSetGlobal(part,global); }
658:   PetscOptionsEnum("-mat_partitioning_chaco_local","Local method","MatPartitioningChacoSetLocal",MPChacoLocalTypes,(PetscEnum)chaco->local_method,(PetscEnum*)&local,&flag);
659:   if (flag) { MatPartitioningChacoSetLocal(part,local); }
660:   PetscOptionsReal("-mat_partitioning_chaco_coarse","Coarse level","MatPartitioningChacoSetCoarseLevel",0.0,&r,&flag);
661:   if (flag) { MatPartitioningChacoSetCoarseLevel(part,r); }
662:   PetscOptionsEnum("-mat_partitioning_chaco_eigen_solver","Eigensolver method","MatPartitioningChacoSetEigenSolver",MPChacoEigenTypes,(PetscEnum)chaco->eigen_method,(PetscEnum*)&eigen,&flag);
663:   if (flag) { MatPartitioningChacoSetEigenSolver(part,eigen); }
664:   PetscOptionsReal("-mat_partitioning_chaco_eigen_tol","Eigensolver tolerance","MatPartitioningChacoSetEigenTol",chaco->eigtol,&r,&flag);
665:   if (flag) { MatPartitioningChacoSetEigenTol(part,r); }
666:   PetscOptionsInt("-mat_partitioning_chaco_eigen_number","Number of eigenvectors: 1, 2, or 3 (bi-, quadri-, or octosection)","MatPartitioningChacoSetEigenNumber",chaco->eignum,&i,&flag);
667:   if (flag) { MatPartitioningChacoSetEigenNumber(part,i); }
668:   PetscOptionsBool("-mat_partitioning_chaco_verbose","Show library output","",chaco->verbose,&chaco->verbose,NULL);
669:   PetscOptionsTail();
670:   return(0);
671: }

673: PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
674: {
675:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*) part->data;
676:   PetscErrorCode        ierr;

679:   PetscFree(chaco);
680:   /* clear composed functions */
681:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetGlobal_C",NULL);
682:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetGlobal_C",NULL);
683:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetLocal_C",NULL);
684:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetLocal_C",NULL);
685:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetCoarseLevel_C",NULL);
686:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenSolver_C",NULL);
687:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenSolver_C",NULL);
688:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenTol_C",NULL);
689:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenTol_C",NULL);
690:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenNumber_C",NULL);
691:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenNumber_C",NULL);
692:   return(0);
693: }

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

698:    Level: beginner

700:    Notes:
701:     See http://www.cs.sandia.gov/CRF/chac.html
702:     Does not using MatPartitioningSetUseEdgeWeights()

704: .seealso: MatPartitioningSetType(), MatPartitioningType
705: M*/

707: PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Chaco(MatPartitioning part)
708: {
709:   PetscErrorCode        ierr;
710:   MatPartitioning_Chaco *chaco;

713:   PetscNewLog(part,&chaco);
714:   part->data = (void*)chaco;

716:   chaco->global_method = MP_CHACO_MULTILEVEL;
717:   chaco->local_method  = MP_CHACO_KERNIGHAN;
718:   chaco->eigen_method  = MP_CHACO_LANCZOS;
719:   chaco->nbvtxcoarsed  = 200;
720:   chaco->eignum        = 1;
721:   chaco->eigtol        = 0.001;
722:   chaco->verbose       = PETSC_FALSE;

724:   part->ops->apply          = MatPartitioningApply_Chaco;
725:   part->ops->view           = MatPartitioningView_Chaco;
726:   part->ops->destroy        = MatPartitioningDestroy_Chaco;
727:   part->ops->setfromoptions = MatPartitioningSetFromOptions_Chaco;

729:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetGlobal_C",MatPartitioningChacoSetGlobal_Chaco);
730:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetGlobal_C",MatPartitioningChacoGetGlobal_Chaco);
731:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetLocal_C",MatPartitioningChacoSetLocal_Chaco);
732:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetLocal_C",MatPartitioningChacoGetLocal_Chaco);
733:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetCoarseLevel_C",MatPartitioningChacoSetCoarseLevel_Chaco);
734:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenSolver_C",MatPartitioningChacoSetEigenSolver_Chaco);
735:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenSolver_C",MatPartitioningChacoGetEigenSolver_Chaco);
736:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenTol_C",MatPartitioningChacoSetEigenTol_Chaco);
737:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenTol_C",MatPartitioningChacoGetEigenTol_Chaco);
738:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenNumber_C",MatPartitioningChacoSetEigenNumber_Chaco);
739:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenNumber_C",MatPartitioningChacoGetEigenNumber_Chaco);
740:   return(0);
741: }