static int Zoltan_Preprocess_Scale_Weights (ZOLTAN_Third_Graph *gr, float *flt_wgt, weighttype** rnd_wgt, int number, int ndim, int mode, ZZ* zz, char * name, int offset) { static char * yo = "Zoltan_Preprocess_Scale_Weights"; int ierr = ZOLTAN_OK; int i99; int k; char msg[256]; if (ndim == 0) return ierr; if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL){ for (i99=0; i99 < (number <3 ? number : 3); i99++){ for (k=0; k<gr->obj_wgt_dim; k++) sprintf(msg+10*k, "%.9f ", flt_wgt[i99*gr->obj_wgt_dim+k]); printf("[%1d] Debug: before scaling weights for %s %d = %s\n", zz->Proc, name, offset+i99, msg); } } *rnd_wgt = (weighttype *)ZOLTAN_MALLOC(ndim * number * sizeof(weighttype)); if ((number >0 ) && (*rnd_wgt == NULL)){ /* Not enough memory */ ZOLTAN_THIRD_ERROR(ZOLTAN_MEMERR, "Out of memory."); } ierr = scale_round_weights(flt_wgt, *rnd_wgt, number, ndim, mode, (int) MAX_WGT_SUM, zz->Debug_Level, zz->Communicator); if (ierr != ZOLTAN_OK && ierr != ZOLTAN_WARN){ ZOLTAN_FREE(rnd_wgt); /* Return error code */ ZOLTAN_THIRD_ERROR(ierr, "Error in scaling of weights."); } if (zz->Debug_Level >= ZOLTAN_DEBUG_ALL){ for (i99=0; i99 < (number < 3 ? number : 3); i99++){ for (k=0; k<gr->obj_wgt_dim; k++) sprintf(msg+10*k, "%9d ", (*rnd_wgt)[i99*gr->obj_wgt_dim+k]); printf("[%1d] Debug: scaled weights for %s %d = %s\n", zz->Proc, name, offset+i99, msg); } } return (ierr); }
int Zoltan_PHG_ParKway( ZZ *zz, HGraph *hg, int nparts, /* # of desired partitions */ Partition partvec, /* Output: partition assignment vector */ PHGPartParams *hgp /* Input: hypergraph parameters */ ) { int ierr = ZOLTAN_OK; char *yo = "Zoltan_HG_ParKway"; #ifndef ZOLTAN_PARKWAY ZOLTAN_PRINT_ERROR(zz->Proc, yo, "ParKway method selected but Zoltan is not" "built and linked with ParKway."); return ZOLTAN_FATAL; #else int options[29]; /* ParKway options */ int *ivwgts = NULL, *iewgts = NULL; /* ParKway expects integer weights. */ int *pvector=NULL; /* partvec for "local" vertices */ int cut; /* Diagnostics from ParKway */ double constraint; /* imbalance ratio */ int i, anVtx, nVtx; /* counter and local vertex cnt (for first k-1 parts)*/ PHGComm *hgc=hg->comm; int *disp=NULL, *recv_size=NULL; /* for allgatherv */ static int seed=1; /* ParKway expects integer weights; convert if weights are provided. */ ivwgts = (int *) ZOLTAN_MALLOC(hg->nVtx * sizeof(int)); iewgts = (int *) ZOLTAN_MALLOC(hg->nEdge * sizeof(int)); if (!ivwgts || !iewgts) ZOLTAN_PARKWAY_ERROR("Memory error.", ZOLTAN_MEMERR); if (hg->VtxWeightDim > 1) { ZOLTAN_PARKWAY_ERROR("ParKway supports Vtx_Weight_Dim == 0 or 1 only.", ZOLTAN_FATAL); } else if (hg->VtxWeightDim == 1) scale_round_weights(hg->vwgt, ivwgts, hg->nVtx, hg->VtxWeightDim, 0); else for (i=0; i<hg->nVtx; ++i) ivwgts[i] = 1; if (hg->EdgeWeightDim > 1) { ZOLTAN_PARKWAY_ERROR("ParKway supports Edge_Weight_Dim == 0 or 1 only.", ZOLTAN_FATAL); } else if (hg->EdgeWeightDim == 1) scale_round_weights(hg->ewgt, iewgts, hg->nEdge, hg->EdgeWeightDim, 0); else for (i=0; i<hg->nEdge; ++i) iewgts[i] = 1; anVtx = hg->nVtx / hgc->nProc; nVtx = (hgc->myProc==hgc->nProc-1) ? hg->nVtx-(anVtx*(hgc->nProc-1)) : anVtx; pvector = (int *) ZOLTAN_MALLOC(nVtx * sizeof(int)); disp = (int *) ZOLTAN_MALLOC(hgc->nProc * sizeof(int)); recv_size = (int *) ZOLTAN_MALLOC(hgc->nProc * sizeof(int)); if ((nVtx && !pvector) || !disp || !recv_size) ZOLTAN_PARKWAY_ERROR("Memory error.", ZOLTAN_MEMERR); /* ----- Set ParKway's options --------------- */ options[0] = 1;//0 -> all options use default, else user define options[1] = seed++;//0 -> seed chosen by sprng, else use options[1] as seed options[2] = 0;//0 -> no disp info, 1 -> some, 2 -> lots options[3] = 1;//0 -> do not write partition to disk, 1 -> do write options[4] = 1;//number of parallel runs options[5] = 0;//vertex to processor allocation: 0 -> as read in, 1 -> random 2 -> as prescribed in partition file options[6] = 100;//hyperedge length percentile for approx para coarsening and refinement options[7] = 1;//increment in percentile options[6] options[8] = 200;//numParts*options[5] -> min number of vertices in coarse hypergraph options[9] = 7;//[9] and [10] specify reduction ratio in parallel coarsening options[10] = 4;//r = [9]/[10] options[11] = 3;//vertex visit order: 3 -> random, 1/2 inc/dec by vertex id, 4/5 inc/dec by vertex wt options[12] = 3;//divide connectivity by cluster weight/hyperedge length: 0-neither, 1-only cluster, 2-only hedge len, 3-both options[13] = 3;//matching request resolution order: 3 -> random, 2 -> as they arrive options[14] = 1;//number serial partitioning runs options[15] = 5;//serial partitioning routine, 1-3 RB, 4 khmetis, 5 patoh, see manual if (!strcasecmp(hgp->parkway_serpart, "patoh")) options[15] = 5; else if (!strcasecmp(hgp->parkway_serpart, "hmetis")) options[15] = 4; else if (!strcasecmp(hgp->parkway_serpart, "generic")) options[15] = 1; else if (!strcasecmp(hgp->parkway_serpart, "genericv")) options[15] = 2; else if (!strcasecmp(hgp->parkway_serpart, "genericmv")) options[15] = 3; else { ZOLTAN_PARKWAY_ERROR("Invalid ParKway serial partitioner. It should be one of; generic, genericv, genericmv, hmetis, patoh.", ZOLTAN_FATAL); } /* uprintf(hgc, "ParKway serpart='%s' options[13]=%d\n", hgp->parkway_serpart, options[13]); */ options[16] = 2;//serial coarsening algorithm (only if [15] = RB, see manual) options[17] = 2;//num bisection runs in RB (only if [15] = RB, see manual) options[18] = 10;//num initial partitioning runs in RB (only if [13] = RB, see manual) options[19] = 2;//hmetis_PartKway coarsening option, vals 1-5, see manual (only if [15] = 4) options[20] = 2;//hmetis_PartKway refinement option, vals 0-3, see manual (only if [15] = 4) options[21] = 3;//patoh_partition parameter settings, vals 1-3, see manual (only if [15] = 5) options[22] = 1;//parallel uncoarsening algorithm, 1 simple, 2 only final V-Cycle, 3 all V-Cycle options[23] = 5;//limit on number of V-Cycle iterations (only if [22] = 2/3) options[24] = 0;//min allowed gain for V-Cycle (percentage, see manual, only if [21] = 2/3) options[25] = 0;//percentage threshold used to reject partitions from a number of runs (see manual) options[26] = 0;//reduction in [23] as partitions propagate by factor [24]/100 (see manual) options[27] = 100;//early exit criterion in parallel refinement, will exit if see ([25]*num vert)/100 consecutive -ve moves options[28] = 0;//parallel refinement 0->basic, 1->use approx 2->use early exit 3->use approx and early exit constraint = hgp->bal_tol-1.0; Zoltan_ParaPartKway(nVtx, hg->nEdge, &ivwgts[hgc->myProc*anVtx], iewgts, hg->hindex, hg->hvertex, nparts, constraint, &cut, options, pvector, NULL, hgc->Communicator); /* KDDKDD uprintf(hgc, "ParaPartKway cut=%d\n", cut); */ /* after partitioning Zoltan needs partvec exist on all procs for nProc_x=1 */ disp[0] = 0; for (i = 1; i < hgc->nProc; ++i) disp[i] = disp[i-1] + anVtx; MPI_Allgather (&nVtx, 1, MPI_INT, recv_size, 1, MPI_INT, hgc->Communicator); MPI_Allgatherv(pvector, nVtx, MPI_INT, partvec, recv_size, disp, MPI_INT, hgc->Communicator); /* HERE: Check whether imbalance criteria were met. */ End: Zoltan_Multifree(__FILE__,__LINE__, 5, &ivwgts, &iewgts, &pvector, &disp, &recv_size); #endif return ierr; }