Actual source code: party.c
petsc-3.10.5 2019-03-28
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: /*
      9:    Currently using Party-1.99
     10: */
     11: EXTERN_C_BEGIN
     12: #include <party_lib.h>
     13: EXTERN_C_END

     15: typedef struct {
     16:   PetscBool redm;
     17:   PetscBool redo;
     18:   PetscBool recursive;
     19:   PetscBool verbose;
     20:   char      global[15];         /* global method */
     21:   char      local[15];          /* local method */
     22:   PetscInt  nbvtxcoarsed;       /* number of vertices for the coarse graph */
     23: } MatPartitioning_Party;

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

     27: static PetscErrorCode MatPartitioningApply_Party(MatPartitioning part,IS *partitioning)
     28: {
     29:   PetscErrorCode        ierr;
     30:   PetscInt              i,*parttab,*locals,nb_locals,M,N;
     31:   PetscMPIInt           size,rank;
     32:   Mat                   mat = part->adj,matAdj,matSeq,*A;
     33:   Mat_MPIAdj            *adj;
     34:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;
     35:   PetscBool             flg;
     36:   IS                    isrow, iscol;
     37:   int                   n,*edge_p,*edge,*vertex_w,p,*part_party,cutsize,redl,rec;
     38:   const char            *redm,*redo;
     39:   char                  *mesg_log;
     40: #if defined(PETSC_HAVE_UNISTD_H)
     41:   int                   fd_stdout,fd_pipe[2],count,err;
     42: #endif

     45:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
     46:   MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);
     47:   PetscObjectTypeCompare((PetscObject)mat,MATMPIADJ,&flg);
     48:   if (size>1) {
     49:     if (flg) {
     50:       MatMPIAdjToSeq(mat,&matSeq);
     51:      } else {
     52:       PetscInfo(part,"Converting distributed matrix to sequential: this could be a performance loss\n");
     53:       MatGetSize(mat,&M,&N);
     54:       ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);
     55:       ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
     56:       MatCreateSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&A);
     57:       ISDestroy(&isrow);
     58:       ISDestroy(&iscol);
     59:       matSeq = *A;
     60:       PetscFree(A);
     61:      }
     62:   } else {
     63:     PetscObjectReference((PetscObject)mat);
     64:     matSeq = mat;
     65:   }

     67:   if (!flg) { /* convert regular matrix to MPIADJ */
     68:     MatConvert(matSeq,MATMPIADJ,MAT_INITIAL_MATRIX,&matAdj);
     69:   } else {
     70:     PetscObjectReference((PetscObject)matSeq);
     71:     matAdj = matSeq;
     72:   }

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

     76:   /* arguments for Party library */
     77:   n        = mat->rmap->N;             /* number of vertices in full graph */
     78:   edge_p   = adj->i;                   /* start of edge list for each vertex */
     79:   edge     = adj->j;                   /* edge list data */
     80:   vertex_w = part->vertex_weights;     /* weights for all vertices */
     81:   p        = part->n;                  /* number of parts to create */
     82:   redl     = party->nbvtxcoarsed;      /* how many vertices to coarsen down to? */
     83:   rec      = party->recursive ? 1 : 0; /* recursive bisection */
     84:   redm     = party->redm ? "lam" : ""; /* matching method */
     85:   redo     = party->redo ? "w3" : "";  /* matching optimization method */

     87:   PetscMalloc1(mat->rmap->N,&part_party);

     89:   /* redirect output to buffer */
     90: #if defined(PETSC_HAVE_UNISTD_H)
     91:   fd_stdout = dup(1);
     92:   if (pipe(fd_pipe)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Could not open pipe");
     93:   close(1);
     94:   dup2(fd_pipe[1],1);
     95:   PetscMalloc1(SIZE_LOG,&mesg_log);
     96: #endif

     98:   /* library call */
     99:   party_lib_times_start();
    100:   party_lib(n,vertex_w,NULL,NULL,NULL,edge_p,edge,NULL,p,part_party,&cutsize,redl,(char*)redm,(char*)redo,party->global,party->local,rec,1);

    102:   party_lib_times_output(1);
    103:   part_info(n,vertex_w,edge_p,edge,NULL,p,part_party,1);

    105: #if defined(PETSC_HAVE_UNISTD_H)
    106:   err = fflush(stdout);
    107:   if (err) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"fflush() failed on stdout");
    108:   count = read(fd_pipe[0],mesg_log,(SIZE_LOG-1)*sizeof(char));
    109:   if (count<0) count = 0;
    110:   mesg_log[count] = 0;
    111:   close(1);
    112:   dup2(fd_stdout,1);
    113:   close(fd_stdout);
    114:   close(fd_pipe[0]);
    115:   close(fd_pipe[1]);
    116:   if (party->verbose) {
    117:     PetscPrintf(PetscObjectComm((PetscObject)mat),mesg_log);
    118:   }
    119:   PetscFree(mesg_log);
    120: #endif
    121:   if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Party failed");

    123:   PetscMalloc1(mat->rmap->N,&parttab);
    124:   for (i=0; i<mat->rmap->N; i++) parttab[i] = part_party[i];

    126:   /* creation of the index set */
    127:   nb_locals = mat->rmap->n;
    128:   locals    = parttab + mat->rmap->rstart;

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

    132:   /* clean up */
    133:   PetscFree(parttab);
    134:   PetscFree(part_party);
    135:   MatDestroy(&matSeq);
    136:   MatDestroy(&matAdj);
    137:   return(0);
    138: }

    140: PetscErrorCode MatPartitioningView_Party(MatPartitioning part,PetscViewer viewer)
    141: {
    142:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;
    143:   PetscErrorCode        ierr;
    144:   PetscBool             isascii;

    147:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);
    148:   if (isascii) {
    149:     PetscViewerASCIIPrintf(viewer,"  Global method: %s\n",party->global);
    150:     PetscViewerASCIIPrintf(viewer,"  Local method: %s\n",party->local);
    151:     PetscViewerASCIIPrintf(viewer,"  Number of vertices for the coarse graph: %d\n",party->nbvtxcoarsed);
    152:     if (party->redm) {
    153:       PetscViewerASCIIPrintf(viewer,"  Using matching method for graph reduction\n");
    154:     }
    155:     if (party->redo) {
    156:       PetscViewerASCIIPrintf(viewer,"  Using matching optimization\n");
    157:     }
    158:     if (party->recursive) {
    159:       PetscViewerASCIIPrintf(viewer,"  Using recursive bipartitioning\n");
    160:     }
    161:   }
    162:   return(0);
    163: }

    165: /*@C
    166:    MatPartitioningPartySetGlobal - Set global method for Party partitioner.

    168:    Collective on MatPartitioning

    170:    Input Parameters:
    171: +  part - the partitioning context
    172: -  method - a string representing the method

    174:    Options Database:
    175: .  -mat_partitioning_party_global <method> - the global method

    177:    Level: advanced

    179:    Notes:
    180:    The method may be one of MP_PARTY_OPT, MP_PARTY_LIN, MP_PARTY_SCA,
    181:    MP_PARTY_RAN, MP_PARTY_GBF, MP_PARTY_GCF, MP_PARTY_BUB or MP_PARTY_DEF, or
    182:    alternatively a string describing the method. Two or more methods can be
    183:    combined like "gbf,gcf". Check the Party Library Users Manual for details.

    185: .seealso: MatPartitioningPartySetLocal()
    186: @*/
    187: PetscErrorCode MatPartitioningPartySetGlobal(MatPartitioning part,const char *global)
    188: {

    193:   PetscTryMethod(part,"MatPartitioningPartySetGlobal_C",(MatPartitioning,const char*),(part,global));
    194:   return(0);
    195: }

    197: PetscErrorCode MatPartitioningPartySetGlobal_Party(MatPartitioning part,const char *global)
    198: {
    199:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;
    200:   PetscErrorCode        ierr;

    203:   PetscStrncpy(party->global,global,15);
    204:   return(0);
    205: }

    207: /*@C
    208:    MatPartitioningPartySetLocal - Set local method for Party partitioner.

    210:    Collective on MatPartitioning

    212:    Input Parameters:
    213: +  part - the partitioning context
    214: -  method - a string representing the method

    216:    Options Database:
    217: .  -mat_partitioning_party_local <method> - the local method

    219:    Level: advanced

    221:    Notes:
    222:    The method may be one of MP_PARTY_HELPFUL_SETS, MP_PARTY_KERNIGHAN_LIN, or
    223:    MP_PARTY_NONE. Check the Party Library Users Manual for details.

    225: .seealso: MatPartitioningPartySetGlobal()
    226: @*/
    227: PetscErrorCode MatPartitioningPartySetLocal(MatPartitioning part,const char *local)
    228: {

    233:   PetscTryMethod(part,"MatPartitioningPartySetLocal_C",(MatPartitioning,const char*),(part,local));
    234:   return(0);
    235: }

    237: PetscErrorCode MatPartitioningPartySetLocal_Party(MatPartitioning part,const char *local)

    239: {
    240:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;
    241:   PetscErrorCode        ierr;

    244:   PetscStrncpy(party->local,local,15);
    245:   return(0);
    246: }

    248: /*@
    249:    MatPartitioningPartySetCoarseLevel - Set the coarse level parameter for the
    250:    Party partitioner.

    252:    Collective on MatPartitioning

    254:    Input Parameters:
    255: +  part - the partitioning context
    256: -  level - the coarse level in range [0.0,1.0]

    258:    Options Database:
    259: .  -mat_partitioning_party_coarse <l> - Coarse level

    261:    Level: advanced
    262: @*/
    263: PetscErrorCode MatPartitioningPartySetCoarseLevel(MatPartitioning part,PetscReal level)
    264: {

    270:   PetscTryMethod(part,"MatPartitioningPartySetCoarseLevel_C",(MatPartitioning,PetscReal),(part,level));
    271:   return(0);
    272: }

    274: PetscErrorCode MatPartitioningPartySetCoarseLevel_Party(MatPartitioning part,PetscReal level)
    275: {
    276:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;

    279:   if (level<0.0 || level>1.0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Party: level of coarsening out of range [0.0-1.0]");
    280:   party->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
    281:   if (party->nbvtxcoarsed < 20) party->nbvtxcoarsed = 20;
    282:   return(0);
    283: }

    285: /*@
    286:    MatPartitioningPartySetMatchOptimization - Activate matching optimization for
    287:    graph reduction.

    289:    Collective on MatPartitioning

    291:    Input Parameters:
    292: +  part - the partitioning context
    293: -  opt - boolean flag

    295:    Options Database:
    296: .  -mat_partitioning_party_match_optimization - Matching optimization on/off

    298:    Level: advanced
    299: @*/
    300: PetscErrorCode MatPartitioningPartySetMatchOptimization(MatPartitioning part,PetscBool opt)
    301: {

    307:   PetscTryMethod(part,"MatPartitioningPartySetMatchOptimization_C",(MatPartitioning,PetscBool),(part,opt));
    308:   return(0);
    309: }

    311: PetscErrorCode MatPartitioningPartySetMatchOptimization_Party(MatPartitioning part,PetscBool opt)
    312: {
    313:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;

    316:   party->redo = opt;
    317:   return(0);
    318: }

    320: /*@
    321:    MatPartitioningPartySetBipart - Activate or deactivate recursive bisection.

    323:    Collective on MatPartitioning

    325:    Input Parameters:
    326: +  part - the partitioning context
    327: -  bp - boolean flag

    329:    Options Database:
    330: -  -mat_partitioning_party_bipart - Bipartitioning option on/off

    332:    Level: advanced
    333: @*/
    334: PetscErrorCode MatPartitioningPartySetBipart(MatPartitioning part,PetscBool bp)
    335: {

    341:   PetscTryMethod(part,"MatPartitioningPartySetBipart_C",(MatPartitioning,PetscBool),(part,bp));
    342:   return(0);
    343: }

    345: PetscErrorCode MatPartitioningPartySetBipart_Party(MatPartitioning part,PetscBool bp)
    346: {
    347:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;

    350:   party->recursive = bp;
    351:   return(0);
    352: }

    354: PetscErrorCode MatPartitioningSetFromOptions_Party(PetscOptionItems *PetscOptionsObject,MatPartitioning part)
    355: {
    356:   PetscErrorCode        ierr;
    357:   PetscBool             flag;
    358:   char                  value[256];
    359:   PetscReal             r;
    360:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;

    363:   PetscOptionsHead(PetscOptionsObject,"Set Party partitioning options");
    364:   PetscOptionsString("-mat_partitioning_party_global","Global method","MatPartitioningPartySetGlobal",party->global,value,256,&flag);
    365:   if (flag) { MatPartitioningPartySetGlobal(part,value); }
    366:   PetscOptionsString("-mat_partitioning_party_local","Local method","MatPartitioningPartySetLocal",party->local,value,256,&flag);
    367:   if (flag) { MatPartitioningPartySetLocal(part,value); }
    368:   PetscOptionsReal("-mat_partitioning_party_coarse","Coarse level","MatPartitioningPartySetCoarseLevel",0.0,&r,&flag);
    369:   if (flag) { MatPartitioningPartySetCoarseLevel(part,r); }
    370:   PetscOptionsBool("-mat_partitioning_party_match_optimization","Matching optimization on/off","MatPartitioningPartySetMatchOptimization",party->redo,&party->redo,NULL);
    371:   PetscOptionsBool("-mat_partitioning_party_bipart","Bipartitioning on/off","MatPartitioningPartySetBipart",party->recursive,&party->recursive,NULL);
    372:   PetscOptionsBool("-mat_partitioning_party_verbose","Show library output","",party->verbose,&party->verbose,NULL);
    373:   PetscOptionsTail();
    374:   return(0);
    375: }

    377: PetscErrorCode MatPartitioningDestroy_Party(MatPartitioning part)
    378: {
    379:   MatPartitioning_Party *party = (MatPartitioning_Party*)part->data;
    380:   PetscErrorCode        ierr;

    383:   PetscFree(party);
    384:   /* clear composed functions */
    385:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetGlobal_C",NULL);
    386:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetLocal_C",NULL);
    387:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetCoarseLevel_C",NULL);
    388:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetMatchOptimization_C",NULL);
    389:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetBipart_C",NULL);
    390:   return(0);
    391: }

    393: /*MC
    394:    MATPARTITIONINGPARTY - Creates a partitioning context via the external package Party.

    396:    Level: beginner

    398:    Notes:
    399:     See http://wwwcs.upb.de/fachbereich/AG/monien/RESEARCH/PART/party.html

    401: .keywords: Partitioning, create, context

    403: .seealso: MatPartitioningSetType(), MatPartitioningType

    405: M*/

    407: PETSC_EXTERN PetscErrorCode MatPartitioningCreate_Party(MatPartitioning part)
    408: {
    409:   PetscErrorCode        ierr;
    410:   MatPartitioning_Party *party;

    413:   PetscNewLog(part,&party);
    414:   part->data = (void*)party;

    416:   PetscStrcpy(party->global,"gcf,gbf");
    417:   PetscStrcpy(party->local,"kl");

    419:   party->redm         = PETSC_TRUE;
    420:   party->redo         = PETSC_TRUE;
    421:   party->recursive    = PETSC_TRUE;
    422:   party->verbose      = PETSC_FALSE;
    423:   party->nbvtxcoarsed = 200;

    425:   part->ops->apply          = MatPartitioningApply_Party;
    426:   part->ops->view           = MatPartitioningView_Party;
    427:   part->ops->destroy        = MatPartitioningDestroy_Party;
    428:   part->ops->setfromoptions = MatPartitioningSetFromOptions_Party;

    430:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetGlobal_C",MatPartitioningPartySetGlobal_Party);
    431:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetLocal_C",MatPartitioningPartySetLocal_Party);
    432:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetCoarseLevel_C",MatPartitioningPartySetCoarseLevel_Party);
    433:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetMatchOptimization_C",MatPartitioningPartySetMatchOptimization_Party);
    434:   PetscObjectComposeFunction((PetscObject)part,"MatPartitioningPartySetBipart_C",MatPartitioningPartySetBipart_Party);
    435:   return(0);
    436: }