void MlevelNodeBisectionL2(ctrl_t *ctrl, graph_t *graph, idx_t niparts) { idx_t i, mincut, nruns=5; graph_t *cgraph; idx_t *bestwhere; /* if the graph is small, just find a single vertex separator */ if (graph->nvtxs < 5000) { MlevelNodeBisectionL1(ctrl, graph, niparts); return; } WCOREPUSH; ctrl->CoarsenTo = gk_max(100, graph->nvtxs/30); cgraph = CoarsenGraphNlevels(ctrl, graph, 4); bestwhere = iwspacemalloc(ctrl, cgraph->nvtxs); mincut = graph->tvwgt[0]; for (i=0; i<nruns; i++) { MlevelNodeBisectionL1(ctrl, cgraph, 0.7*niparts); if (i == 0 || cgraph->mincut < mincut) { mincut = cgraph->mincut; if (i < nruns-1) icopy(cgraph->nvtxs, cgraph->where, bestwhere); } if (mincut == 0) break; if (i < nruns-1) FreeRData(cgraph); } if (mincut != cgraph->mincut) icopy(cgraph->nvtxs, bestwhere, cgraph->where); WCOREPOP; Refine2WayNode(ctrl, graph, cgraph); }
void MlevelNodeBisectionMultiple(ctrl_t *ctrl, graph_t *graph) { idx_t i, mincut; idx_t *bestwhere; /* if the graph is small, just find a single vertex separator */ if (ctrl->nseps == 1 || graph->nvtxs < (ctrl->compress ? 1000 : 2000)) { MlevelNodeBisectionL2(ctrl, graph, LARGENIPARTS); return; } WCOREPUSH; bestwhere = iwspacemalloc(ctrl, graph->nvtxs); mincut = graph->tvwgt[0]; for (i=0; i<ctrl->nseps; i++) { MlevelNodeBisectionL2(ctrl, graph, LARGENIPARTS); if (i == 0 || graph->mincut < mincut) { mincut = graph->mincut; if (i < ctrl->nseps-1) icopy(graph->nvtxs, graph->where, bestwhere); } if (mincut == 0) break; if (i < ctrl->nseps-1) FreeRData(graph); } if (mincut != graph->mincut) { icopy(graph->nvtxs, bestwhere, graph->where); Compute2WayNodePartitionParams(ctrl, graph); } WCOREPOP; }
idx_t MlevelKWayPartitioning(ctrl_t *ctrl, graph_t *graph, idx_t *part) { idx_t i, objval=0, curobj=0, bestobj=0; real_t curbal=0.0, bestbal=0.0; graph_t *cgraph; for (i=0; i<ctrl->ncuts; i++) { cgraph = CoarsenGraph(ctrl, graph); IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_startwctimer(ctrl->InitPartTmr)); AllocateKWayPartitionMemory(ctrl, cgraph); /* Compute the initial partitioning */ switch (ctrl->iptype) { case METIS_IPTYPE_METISRB: FreeWorkSpace(ctrl); /* Release the work space, for the recursive metis call */ InitKWayPartitioningRB(ctrl, cgraph); AllocateWorkSpace(ctrl, graph); /* Re-allocate the work space */ break; case METIS_IPTYPE_GROW: AllocateRefinementWorkSpace(ctrl, 2*cgraph->nedges); InitKWayPartitioningGrow(ctrl, cgraph); break; default: gk_errexit(SIGERR, "Unknown iptype: %d\n", ctrl->iptype); } IFSET(ctrl->dbglvl, METIS_DBG_TIME, gk_stopwctimer(ctrl->InitPartTmr)); IFSET(ctrl->dbglvl, METIS_DBG_IPART, printf("Initial %"PRIDX \ "-way partitioning cut: %"PRIDX"\n", ctrl->nparts, objval)); RefineKWay(ctrl, graph, cgraph); switch (ctrl->objtype) { case METIS_OBJTYPE_CUT: curobj = graph->mincut; break; case METIS_OBJTYPE_VOL: curobj = graph->minvol; break; default: gk_errexit(SIGERR, "Unknown objtype: %d\n", ctrl->objtype); } curbal = ComputeLoadImbalanceDiff(graph, ctrl->nparts, ctrl->pijbm, ctrl->ubfactors); if (i == 0 || (curbal <= 0.0005 && bestobj > curobj) || (bestbal > 0.0005 && curbal < bestbal)) { icopy(graph->nvtxs, graph->where, part); bestobj = curobj; bestbal = curbal; } FreeRData(graph); if (bestobj == 0) break; } FreeGraph(&graph); return bestobj; }