Actual source code: chaco.c

petsc-master 2016-12-02
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 */

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

 83:   FREE_GRAPH = 0; /* otherwise Chaco will attempt to free memory for adjacency graph */
 84:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
 85:   MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);
 86:   PetscObjectTypeCompare((PetscObject)mat,MATMPIADJ,&flg);
 87:   if (size>1) {
 88:     if (flg) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Distributed matrix format MPIAdj is not supported for sequential partitioners");
 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:     MatGetSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&A);
 94:     ISDestroy(&isrow);
 95:     ISDestroy(&iscol);
 96:     matSeq = *A;
 97:     PetscFree(A);
 98:   } else {
 99:     PetscObjectReference((PetscObject)mat);
100:     matSeq = mat;
101:   }

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

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

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

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

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

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

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

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

166:   /* creation of the index set */
167:   nb_locals = mat->rmap->N / size;
168:   locals    = parttab + rank*nb_locals;
169:   if (rank < mat->rmap->N % size) {
170:     nb_locals++;
171:     locals += rank;
172:   } else locals += mat->rmap->N % size;

174:   ISCreateGeneral(PetscObjectComm((PetscObject)part),nb_locals,locals,PETSC_COPY_VALUES,partitioning);

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

187: PetscErrorCode MatPartitioningView_Chaco(MatPartitioning part, PetscViewer viewer)
188: {
189:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;
190:   PetscErrorCode        ierr;
191:   PetscBool             isascii;

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

208: /*@
209:    MatPartitioningChacoSetGlobal - Set global method for Chaco partitioner.

211:    Collective on MatPartitioning

213:    Input Parameters:
214: +  part - the partitioning context
215: -  method - one of MP_CHACO_MULTILEVEL, MP_CHACO_SPECTRAL, MP_CHACO_LINEAR,
216:             MP_CHACO_RANDOM or MP_CHACO_SCATTERED

218:    Options Database:
219: .  -mat_partitioning_chaco_global <method> - the global method

221:    Level: advanced

223:    Notes:
224:    The default is the multi-level method. See Chaco documentation for
225:    additional details.

227: .seealso: MatPartitioningChacoSetLocal(),MatPartitioningChacoGetGlobal()
228: @*/
229: PetscErrorCode MatPartitioningChacoSetGlobal(MatPartitioning part,MPChacoGlobalType method)
230: {

236:   PetscTryMethod(part,"MatPartitioningChacoSetGlobal_C",(MatPartitioning,MPChacoGlobalType),(part,method));
237:   return(0);
238: }

242: PetscErrorCode MatPartitioningChacoSetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType method)
243: {
244:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

247:   switch (method) {
248:   case MP_CHACO_MULTILEVEL:
249:   case MP_CHACO_SPECTRAL:
250:   case MP_CHACO_LINEAR:
251:   case MP_CHACO_RANDOM:
252:   case MP_CHACO_SCATTERED:
253:     chaco->global_method = method; break;
254:   default:
255:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
256:   }
257:   return(0);
258: }

262: /*@
263:    MatPartitioningChacoGetGlobal - Get global method for Chaco partitioner.

265:    Not Collective

267:    Input Parameter:
268: .  part - the partitioning context

270:    Output Parameter:
271: .  method - the method

273:    Level: advanced

275: .seealso: MatPartitioningChacoSetGlobal()
276: @*/
277: PetscErrorCode MatPartitioningChacoGetGlobal(MatPartitioning part,MPChacoGlobalType *method)
278: {

284:   PetscTryMethod(part,"MatPartitioningChacoGetGlobal_C",(MatPartitioning,MPChacoGlobalType*),(part,method));
285:   return(0);
286: }

290: PetscErrorCode MatPartitioningChacoGetGlobal_Chaco(MatPartitioning part,MPChacoGlobalType *method)
291: {
292:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

295:   *method = chaco->global_method;
296:   return(0);
297: }

301: /*@
302:    MatPartitioningChacoSetLocal - Set local method for Chaco partitioner.

304:    Collective on MatPartitioning

306:    Input Parameters:
307: +  part - the partitioning context
308: -  method - one of MP_CHACO_KERNIGHAN or MP_CHACO_NONE

310:    Options Database:
311: .  -mat_partitioning_chaco_local <method> - the local method

313:    Level: advanced

315:    Notes:
316:    The default is to apply the Kernighan-Lin heuristic. See Chaco documentation
317:    for additional details.

319: .seealso: MatPartitioningChacoSetGlobal(),MatPartitioningChacoGetLocal()
320: @*/
321: PetscErrorCode MatPartitioningChacoSetLocal(MatPartitioning part,MPChacoLocalType method)
322: {

328:   PetscTryMethod(part,"MatPartitioningChacoSetLocal_C",(MatPartitioning,MPChacoLocalType),(part,method));
329:   return(0);
330: }

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

339:   switch (method) {
340:   case MP_CHACO_KERNIGHAN:
341:   case MP_CHACO_NONE:
342:     chaco->local_method = method; break;
343:   default:
344:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
345:   }
346:   return(0);
347: }

351: /*@
352:    MatPartitioningChacoGetLocal - Get local method for Chaco partitioner.

354:    Not Collective

356:    Input Parameter:
357: .  part - the partitioning context

359:    Output Parameter:
360: .  method - the method

362:    Level: advanced

364: .seealso: MatPartitioningChacoSetLocal()
365: @*/
366: PetscErrorCode MatPartitioningChacoGetLocal(MatPartitioning part,MPChacoLocalType *method)
367: {

373:   PetscUseMethod(part,"MatPartitioningChacoGetLocal_C",(MatPartitioning,MPChacoLocalType*),(part,method));
374:   return(0);
375: }

379: PetscErrorCode MatPartitioningChacoGetLocal_Chaco(MatPartitioning part,MPChacoLocalType *method)
380: {
381:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

384:   *method = chaco->local_method;
385:   return(0);
386: }

390: /*@
391:    MatPartitioningChacoSetCoarseLevel - Set the coarse level parameter for the
392:    Chaco partitioner.

394:    Collective on MatPartitioning

396:    Input Parameters:
397: +  part - the partitioning context
398: -  level - the coarse level in range [0.0,1.0]

400:    Options Database:
401: .  -mat_partitioning_chaco_coarse <l> - Coarse level

403:    Level: advanced
404: @*/
405: PetscErrorCode MatPartitioningChacoSetCoarseLevel(MatPartitioning part,PetscReal level)
406: {

412:   PetscTryMethod(part,"MatPartitioningChacoSetCoarseLevel_C",(MatPartitioning,PetscReal),(part,level));
413:   return(0);
414: }

418: PetscErrorCode MatPartitioningChacoSetCoarseLevel_Chaco(MatPartitioning part,PetscReal level)
419: {
420:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

423:   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]");
424:   chaco->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
425:   if (chaco->nbvtxcoarsed < 20) chaco->nbvtxcoarsed = 20;
426:   return(0);
427: }

431: /*@
432:    MatPartitioningChacoSetEigenSolver - Set eigensolver method for Chaco partitioner.

434:    Collective on MatPartitioning

436:    Input Parameters:
437: +  part - the partitioning context
438: -  method - one of MP_CHACO_LANCZOS or MP_CHACO_RQI

440:    Options Database:
441: .  -mat_partitioning_chaco_eigen_solver <method> - the eigensolver

443:    Level: advanced

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

448: .seealso: MatPartitioningChacoSetEigenTol(),MatPartitioningChacoSetEigenNumber(),
449:           MatPartitioningChacoGetEigenSolver()
450: @*/
451: PetscErrorCode MatPartitioningChacoSetEigenSolver(MatPartitioning part,MPChacoEigenType method)
452: {

458:   PetscTryMethod(part,"MatPartitioningChacoSetEigenSolver_C",(MatPartitioning,MPChacoEigenType),(part,method));
459:   return(0);
460: }

464: PetscErrorCode MatPartitioningChacoSetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType method)
465: {
466:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

469:   switch (method) {
470:   case MP_CHACO_LANCZOS:
471:   case MP_CHACO_RQI:
472:     chaco->eigen_method = method; break;
473:   default:
474:     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Chaco: Unknown or unsupported option");
475:   }
476:   return(0);
477: }

481: /*@
482:    MatPartitioningChacoGetEigenSolver - Get local method for Chaco partitioner.

484:    Not Collective

486:    Input Parameter:
487: .  part - the partitioning context

489:    Output Parameter:
490: .  method - the method

492:    Level: advanced

494: .seealso: MatPartitioningChacoSetEigenSolver()
495: @*/
496: PetscErrorCode MatPartitioningChacoGetEigenSolver(MatPartitioning part,MPChacoEigenType *method)
497: {

503:   PetscUseMethod(part,"MatPartitioningChacoGetEigenSolver_C",(MatPartitioning,MPChacoEigenType*),(part,method));
504:   return(0);
505: }

509: PetscErrorCode MatPartitioningChacoGetEigenSolver_Chaco(MatPartitioning part,MPChacoEigenType *method)
510: {
511:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

514:   *method = chaco->eigen_method;
515:   return(0);
516: }

520: /*@
521:    MatPartitioningChacoSetEigenTol - Sets the tolerance for the eigensolver.

523:    Collective on MatPartitioning

525:    Input Parameters:
526: +  part - the partitioning context
527: -  tol  - the tolerance

529:    Options Database:
530: .  -mat_partitioning_chaco_eigen_tol <tol>: Tolerance for eigensolver

532:    Note:
533:    Must be positive. The default value is 0.001.

535:    Level: advanced

537: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
538: @*/
539: PetscErrorCode MatPartitioningChacoSetEigenTol(MatPartitioning part,PetscReal tol)
540: {

546:   PetscTryMethod(part,"MatPartitioningChacoSetEigenTol_C",(MatPartitioning,PetscReal),(part,tol));
547:   return(0);
548: }

552: PetscErrorCode MatPartitioningChacoSetEigenTol_Chaco(MatPartitioning part,PetscReal tol)
553: {
554:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

557:   if (tol==PETSC_DEFAULT) chaco->eigtol = 0.001;
558:   else {
559:     if (tol<=0.0) SETERRQ(PetscObjectComm((PetscObject)part),PETSC_ERR_ARG_OUTOFRANGE,"Tolerance must be positive");
560:     chaco->eigtol = tol;
561:   }
562:   return(0);
563: }

567: /*@
568:    MatPartitioningChacoGetEigenTol - Gets the eigensolver tolerance.

570:    Not Collective

572:    Input Parameter:
573: .  part - the partitioning context

575:    Output Parameter:
576: .  tol  - the tolerance

578:    Level: advanced

580: .seealso: MatPartitioningChacoSetEigenTol()
581: @*/
582: PetscErrorCode MatPartitioningChacoGetEigenTol(MatPartitioning part,PetscReal *tol)
583: {

589:   PetscUseMethod(part,"MatPartitioningChacoGetEigenTol_C",(MatPartitioning,PetscReal*),(part,tol));
590:   return(0);
591: }

595: PetscErrorCode MatPartitioningChacoGetEigenTol_Chaco(MatPartitioning part,PetscReal *tol)
596: {
597:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

600:   *tol = chaco->eigtol;
601:   return(0);
602: }

606: /*@
607:    MatPartitioningChacoSetEigenNumber - Sets the number of eigenvectors to compute
608:    during partitioning.

610:    Collective on MatPartitioning

612:    Input Parameters:
613: +  part - the partitioning context
614: -  num  - the number of eigenvectors

616:    Options Database:
617: .  -mat_partitioning_chaco_eigen_number <n>: Number of eigenvectors

619:    Note:
620:    Accepted values are 1, 2 or 3, indicating partitioning by bisection,
621:    quadrisection, or octosection.

623:    Level: advanced

625: .seealso: MatPartitioningChacoSetEigenSolver(), MatPartitioningChacoGetEigenTol()
626: @*/
627: PetscErrorCode MatPartitioningChacoSetEigenNumber(MatPartitioning part,PetscInt num)
628: {

634:   PetscTryMethod(part,"MatPartitioningChacoSetEigenNumber_C",(MatPartitioning,PetscInt),(part,num));
635:   return(0);
636: }

640: PetscErrorCode MatPartitioningChacoSetEigenNumber_Chaco(MatPartitioning part,PetscInt num)
641: {
642:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

645:   if (num==PETSC_DEFAULT) chaco->eignum = 1;
646:   else {
647:     if (num<1 || num>3) SETERRQ(PetscObjectComm((PetscObject)part),PETSC_ERR_ARG_OUTOFRANGE,"Can only specify 1, 2 or 3 eigenvectors");
648:     chaco->eignum = num;
649:   }
650:   return(0);
651: }

655: /*@
656:    MatPartitioningChacoGetEigenNumber - Gets the number of eigenvectors used by Chaco.

658:    Not Collective

660:    Input Parameter:
661: .  part - the partitioning context

663:    Output Parameter:
664: .  num  - number of eigenvectors

666:    Level: advanced

668: .seealso: MatPartitioningChacoSetEigenNumber()
669: @*/
670: PetscErrorCode MatPartitioningChacoGetEigenNumber(MatPartitioning part,PetscInt *num)
671: {

677:   PetscUseMethod(part,"MatPartitioningChacoGetEigenNumber_C",(MatPartitioning,PetscInt*),(part,num));
678:   return(0);
679: }

683: PetscErrorCode MatPartitioningChacoGetEigenNumber_Chaco(MatPartitioning part,PetscInt *num)
684: {
685:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;

688:   *num = chaco->eignum;
689:   return(0);
690: }

694: PetscErrorCode MatPartitioningSetFromOptions_Chaco(PetscOptionItems *PetscOptionsObject,MatPartitioning part)
695: {
696:   PetscErrorCode        ierr;
697:   PetscInt              i;
698:   PetscReal             r;
699:   PetscBool             flag;
700:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*)part->data;
701:   MPChacoGlobalType     global;
702:   MPChacoLocalType      local;
703:   MPChacoEigenType      eigen;

706:   PetscOptionsHead(PetscOptionsObject,"Chaco partitioning options");
707:   PetscOptionsEnum("-mat_partitioning_chaco_global","Global method","MatPartitioningChacoSetGlobal",MPChacoGlobalTypes,(PetscEnum)chaco->global_method,(PetscEnum*)&global,&flag);
708:   if (flag) { MatPartitioningChacoSetGlobal(part,global); }
709:   PetscOptionsEnum("-mat_partitioning_chaco_local","Local method","MatPartitioningChacoSetLocal",MPChacoLocalTypes,(PetscEnum)chaco->local_method,(PetscEnum*)&local,&flag);
710:   if (flag) { MatPartitioningChacoSetLocal(part,local); }
711:   PetscOptionsReal("-mat_partitioning_chaco_coarse","Coarse level","MatPartitioningChacoSetCoarseLevel",0.0,&r,&flag);
712:   if (flag) { MatPartitioningChacoSetCoarseLevel(part,r); }
713:   PetscOptionsEnum("-mat_partitioning_chaco_eigen_solver","Eigensolver method","MatPartitioningChacoSetEigenSolver",MPChacoEigenTypes,(PetscEnum)chaco->eigen_method,(PetscEnum*)&eigen,&flag);
714:   if (flag) { MatPartitioningChacoSetEigenSolver(part,eigen); }
715:   PetscOptionsReal("-mat_partitioning_chaco_eigen_tol","Eigensolver tolerance","MatPartitioningChacoSetEigenTol",chaco->eigtol,&r,&flag);
716:   if (flag) { MatPartitioningChacoSetEigenTol(part,r); }
717:   PetscOptionsInt("-mat_partitioning_chaco_eigen_number","Number of eigenvectors: 1, 2, or 3 (bi-, quadri-, or octosection)","MatPartitioningChacoSetEigenNumber",chaco->eignum,&i,&flag);
718:   if (flag) { MatPartitioningChacoSetEigenNumber(part,i); }
719:   PetscOptionsBool("-mat_partitioning_chaco_verbose","Show library output","",chaco->verbose,&chaco->verbose,NULL);
720:   PetscOptionsTail();
721:   return(0);
722: }

726: PetscErrorCode MatPartitioningDestroy_Chaco(MatPartitioning part)
727: {
728:   MatPartitioning_Chaco *chaco = (MatPartitioning_Chaco*) part->data;
729:   PetscErrorCode        ierr;

732:   PetscFree(chaco);
733:   /* clear composed functions */
734:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetGlobal_C",NULL);
735:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetGlobal_C",NULL);
736:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetLocal_C",NULL);
737:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetLocal_C",NULL);
738:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetCoarseLevel_C",NULL);
739:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenSolver_C",NULL);
740:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenSolver_C",NULL);
741:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenTol_C",NULL);
742:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenTol_C",NULL);
743:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenNumber_C",NULL);
744:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenNumber_C",NULL);
745:   return(0);
746: }

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

751:    Level: beginner

753:    Notes: See http://www.cs.sandia.gov/CRF/chac.html

755: .keywords: Partitioning, create, context

757: .seealso: MatPartitioningSetType(), MatPartitioningType
758: M*/

762: PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Chaco(MatPartitioning part)
763: {
764:   PetscErrorCode        ierr;
765:   MatPartitioning_Chaco *chaco;

768:   PetscNewLog(part,&chaco);
769:   part->data = (void*)chaco;

771:   chaco->global_method = MP_CHACO_MULTILEVEL;
772:   chaco->local_method  = MP_CHACO_KERNIGHAN;
773:   chaco->eigen_method  = MP_CHACO_LANCZOS;
774:   chaco->nbvtxcoarsed  = 200;
775:   chaco->eignum        = 1;
776:   chaco->eigtol        = 0.001;
777:   chaco->verbose       = PETSC_FALSE;

779:   part->ops->apply          = MatPartitioningApply_Chaco;
780:   part->ops->view           = MatPartitioningView_Chaco;
781:   part->ops->destroy        = MatPartitioningDestroy_Chaco;
782:   part->ops->setfromoptions = MatPartitioningSetFromOptions_Chaco;

784:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetGlobal_C",MatPartitioningChacoSetGlobal_Chaco);
785:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetGlobal_C",MatPartitioningChacoGetGlobal_Chaco);
786:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetLocal_C",MatPartitioningChacoSetLocal_Chaco);
787:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetLocal_C",MatPartitioningChacoGetLocal_Chaco);
788:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetCoarseLevel_C",MatPartitioningChacoSetCoarseLevel_Chaco);
789:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenSolver_C",MatPartitioningChacoSetEigenSolver_Chaco);
790:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenSolver_C",MatPartitioningChacoGetEigenSolver_Chaco);
791:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenTol_C",MatPartitioningChacoSetEigenTol_Chaco);
792:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenTol_C",MatPartitioningChacoGetEigenTol_Chaco);
793:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoSetEigenNumber_C",MatPartitioningChacoSetEigenNumber_Chaco);
794:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningChacoGetEigenNumber_C",MatPartitioningChacoGetEigenNumber_Chaco);
795:   return(0);
796: }