Actual source code: party.c

petsc-3.14.6 2021-03-30
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:   if (part->use_edge_weights) SETERRQ(PetscObjectComm((PetscObject)part),PETSC_ERR_SUP,"Party does not support edge weights");
 46:   MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);
 47:   MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);
 48:   PetscObjectTypeCompare((PetscObject)mat,MATMPIADJ,&flg);
 49:   if (size>1) {
 50:     if (flg) {
 51:       MatMPIAdjToSeq(mat,&matSeq);
 52:      } else {
 53:       PetscInfo(part,"Converting distributed matrix to sequential: this could be a performance loss\n");
 54:       MatGetSize(mat,&M,&N);
 55:       ISCreateStride(PETSC_COMM_SELF,M,0,1,&isrow);
 56:       ISCreateStride(PETSC_COMM_SELF,N,0,1,&iscol);
 57:       MatCreateSubMatrices(mat,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&A);
 58:       ISDestroy(&isrow);
 59:       ISDestroy(&iscol);
 60:       matSeq = *A;
 61:       PetscFree(A);
 62:      }
 63:   } else {
 64:     PetscObjectReference((PetscObject)mat);
 65:     matSeq = mat;
 66:   }

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

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

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

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

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

 99:   /* library call */
100:   party_lib_times_start();
101:   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);

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

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

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

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

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

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

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

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

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

169:    Collective on MatPartitioning

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

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

178:    Level: advanced

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

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

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

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

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

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

211:    Collective on MatPartitioning

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

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

220:    Level: advanced

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

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

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

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

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

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

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

253:    Collective on MatPartitioning

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

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

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

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

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

280:   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]");
281:   party->nbvtxcoarsed = (PetscInt)(part->adj->cmap->N * level);
282:   if (party->nbvtxcoarsed < 20) party->nbvtxcoarsed = 20;
283:   return(0);
284: }

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

290:    Collective on MatPartitioning

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

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

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

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

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

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

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

324:    Collective on MatPartitioning

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

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

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

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

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

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

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

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

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

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

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

397:    Level: beginner

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

402:     Does not support using MatPartitioningSetUseEdgeWeights()

404: .seealso: MatPartitioningSetType(), MatPartitioningType

406: M*/

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

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

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

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

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

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