Date: 2021-03-03T22:26:41+00:00

Actual source code: chaco.c
petsc-3.14.5 2021-03-03
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: }