/************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ int MlevelVolKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor) { GraphType *cgraph; int wgtflag=3, numflag=0, options[10], edgecut; cgraph = Coarsen2Way(ctrl, graph); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); AllocateVolKWayPartitionMemory(ctrl, cgraph, nparts); options[0] = 1; options[OPTION_CTYPE] = MATCH_SHEMKWAY; options[OPTION_ITYPE] = IPART_GGPKL; options[OPTION_RTYPE] = RTYPE_FM; options[OPTION_DBGLVL] = 0; METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, &edgecut, cgraph->where); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); RefineVolKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor); idxcopy(graph->nvtxs, graph->where, part); GKfree((void **)&graph->gdata, &graph->rdata, LTERM); return graph->minvol; }
/************************************************************************* * This function projects a partition, and at the same time computes the * parameters for refinement. **************************************************************************/ void ProjectVolKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) { int i, j, k, nvtxs, me, other, istart, iend, ndegrees; idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; idxtype *cmap, *where; idxtype *cwhere; GraphType *cgraph; VRInfoType *crinfo, *rinfo, *myrinfo; VEDegreeType *myedegrees; idxtype *htable; cgraph = graph->coarser; cwhere = cgraph->where; crinfo = cgraph->vrinfo; nvtxs = graph->nvtxs; cmap = graph->cmap; xadj = graph->xadj; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; AllocateVolKWayPartitionMemory(ctrl, graph, nparts); where = graph->where; rinfo = graph->vrinfo; /* Go through and project partition and compute id/ed for the nodes */ for (i=0; i<nvtxs; i++) { k = cmap[i]; where[i] = cwhere[k]; cmap[i] = crinfo[k].ed; /* For optimization */ } htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); ctrl->wspace.cdegree = 0; for (i=0; i<nvtxs; i++) { me = where[i]; myrinfo = rinfo+i; myrinfo->id = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0; myrinfo->edegrees = NULL; myrinfo->id = adjwgtsum[i]; myrinfo->nid = xadj[i+1]-xadj[i]; if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ istart = xadj[i]; iend = xadj[i+1]; myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; ctrl->wspace.cdegree += iend-istart; ndegrees = 0; for (j=istart; j<iend; j++) { other = where[adjncy[j]]; if (me != other) { myrinfo->ed += adjwgt[j]; myrinfo->nid--; if ((k = htable[other]) == -1) { htable[other] = ndegrees; myedegrees[ndegrees].gv = 0; myedegrees[ndegrees].pid = other; myedegrees[ndegrees].ed = adjwgt[j]; myedegrees[ndegrees++].ned = 1; } else { myedegrees[k].ed += adjwgt[j]; myedegrees[k].ned++; } } } myrinfo->id -= myrinfo->ed; /* Remove space for edegrees if it was interior */ if (myrinfo->ed == 0) { myrinfo->edegrees = NULL; ctrl->wspace.cdegree -= iend-istart; } else { myrinfo->ndegrees = ndegrees; for (j=0; j<ndegrees; j++) htable[myedegrees[j].pid] = -1; } } } ComputeKWayVolGains(ctrl, graph, nparts); idxcopy(nparts, cgraph->pwgts, graph->pwgts); graph->mincut = cgraph->mincut; FreeGraph(graph->coarser); graph->coarser = NULL; idxwspacefree(ctrl, nparts); }