void GrowBisectionNode2(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, j, k, nvtxs, bestcut=0, mincut, inbfs; idx_t *xadj, *where, *bndind, *bestwhere; WCOREPUSH; nvtxs = graph->nvtxs; xadj = graph->xadj; /* Allocate refinement memory. Allocate sufficient memory for both edge and node */ graph->pwgts = imalloc(3, "GrowBisectionNode: pwgts"); graph->where = imalloc(nvtxs, "GrowBisectionNode: where"); graph->bndptr = imalloc(nvtxs, "GrowBisectionNode: bndptr"); graph->bndind = imalloc(nvtxs, "GrowBisectionNode: bndind"); graph->id = imalloc(nvtxs, "GrowBisectionNode: id"); graph->ed = imalloc(nvtxs, "GrowBisectionNode: ed"); graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "GrowBisectionNode: nrinfo"); bestwhere = iwspacemalloc(ctrl, nvtxs); where = graph->where; bndind = graph->bndind; for (inbfs=0; inbfs<niparts; inbfs++) { iset(nvtxs, 1, where); if (inbfs > 0) where[irandInRange(nvtxs)] = 0; Compute2WayPartitionParams(ctrl, graph); General2WayBalance(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, ctrl->niter); /* Construct and refine the vertex separator */ for (i=0; i<graph->nbnd; i++) { j = bndind[i]; if (xadj[j+1]-xadj[j] > 0) /* ignore islands */ where[j] = 2; } Compute2WayNodePartitionParams(ctrl, graph); FM_2WayNodeRefine2Sided(ctrl, graph, 4); /* printf("ISep: [%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"] %"PRIDX"\n", inbfs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ if (inbfs == 0 || bestcut > graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }
void Refine2WayNode(ctrl_t *ctrl, graph_t *orggraph, graph_t *graph) { IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->UncoarsenTmr)); if (graph == orggraph) { Compute2WayNodePartitionParams(ctrl, graph); } else { do { graph = graph->finer; IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->ProjectTmr)); Project2WayNodePartition(ctrl, graph); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->ProjectTmr)); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startcputimer(ctrl->RefTmr)); FM_2WayNodeBalance(ctrl, graph); ASSERT(CheckNodePartitionParams(graph)); switch (ctrl->rtype) { case METIS_RTYPE_SEP2SIDED: FM_2WayNodeRefine2Sided(ctrl, graph, ctrl->niter); break; case METIS_RTYPE_SEP1SIDED: FM_2WayNodeRefine1Sided(ctrl, graph, ctrl->niter); break; default: gk_errexit(SIGERR, "Unknown rtype of %d\n", ctrl->rtype); } IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->RefTmr)); } while (graph != orggraph); } IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopcputimer(ctrl->UncoarsenTmr)); }
void GrowBisectionNode(ctrl_t *ctrl, graph_t *graph, real_t *ntpwgts, idx_t niparts) { idx_t i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], oneminpwgt, onemaxpwgt, from, me, bestcut=0, icut, mincut, inbfs; idx_t *xadj, *vwgt, *adjncy, *where, *bndind; idx_t *queue, *touched, *gain, *bestwhere; WCOREPUSH; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; // adjwgt = graph->adjwgt; bestwhere = iwspacemalloc(ctrl, nvtxs); queue = iwspacemalloc(ctrl, nvtxs); touched = iwspacemalloc(ctrl, nvtxs); onemaxpwgt = ctrl->ubfactors[0]*graph->tvwgt[0]*0.5; oneminpwgt = (1.0/ctrl->ubfactors[0])*graph->tvwgt[0]*0.5; /* Allocate refinement memory. Allocate sufficient memory for both edge and node */ graph->pwgts = imalloc(3, "GrowBisectionNode: pwgts"); graph->where = imalloc(nvtxs, "GrowBisectionNode: where"); graph->bndptr = imalloc(nvtxs, "GrowBisectionNode: bndptr"); graph->bndind = imalloc(nvtxs, "GrowBisectionNode: bndind"); graph->id = imalloc(nvtxs, "GrowBisectionNode: id"); graph->ed = imalloc(nvtxs, "GrowBisectionNode: ed"); graph->nrinfo = (nrinfo_t *)gk_malloc(nvtxs*sizeof(nrinfo_t), "GrowBisectionNode: nrinfo"); where = graph->where; bndind = graph->bndind; for (inbfs=0; inbfs<niparts; inbfs++) { iset(nvtxs, 1, where); iset(nvtxs, 0, touched); pwgts[1] = graph->tvwgt[0]; pwgts[0] = 0; queue[0] = irandInRange(nvtxs); touched[queue[0]] = 1; first = 0; last = 1; nleft = nvtxs-1; drain = 0; /* Start the BFS from queue to get a partition */ for (;;) { if (first == last) { /* Empty. Disconnected graph! */ if (nleft == 0 || drain) break; k = irandInRange(nleft); for (i=0; i<nvtxs; i++) { /* select the kth untouched vertex */ if (touched[i] == 0) { if (k == 0) break; else k--; } } queue[0] = i; touched[i] = 1; first = 0; last = 1; nleft--; } i = queue[first++]; if (pwgts[1]-vwgt[i] < oneminpwgt) { drain = 1; continue; } where[i] = 0; INC_DEC(pwgts[0], pwgts[1], vwgt[i]); if (pwgts[1] <= onemaxpwgt) break; drain = 0; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (touched[k] == 0) { queue[last++] = k; touched[k] = 1; nleft--; } } } /************************************************************* * Do some partition refinement **************************************************************/ Compute2WayPartitionParams(ctrl, graph); Balance2Way(ctrl, graph, ntpwgts); FM_2WayRefine(ctrl, graph, ntpwgts, 4); /* Construct and refine the vertex separator */ for (i=0; i<graph->nbnd; i++) { j = bndind[i]; if (xadj[j+1]-xadj[j] > 0) /* ignore islands */ where[j] = 2; } Compute2WayNodePartitionParams(ctrl, graph); FM_2WayNodeRefine2Sided(ctrl, graph, 1); FM_2WayNodeRefine1Sided(ctrl, graph, 4); /* printf("ISep: [%"PRIDX" %"PRIDX" %"PRIDX" %"PRIDX"] %"PRIDX"\n", inbfs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ if (inbfs == 0 || bestcut > graph->mincut) { bestcut = graph->mincut; icopy(nvtxs, where, bestwhere); } } graph->mincut = bestcut; icopy(nvtxs, bestwhere, where); WCOREPOP; }