/************************************************************************* * This function performs multilevel bisection **************************************************************************/ void MlevelNodeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) { GraphType *cgraph; ctrl->CoarsenTo = graph->nvtxs/8; if (ctrl->CoarsenTo > 100) ctrl->CoarsenTo = 100; else if (ctrl->CoarsenTo < 40) ctrl->CoarsenTo = 40; ctrl->maxvwgt = 1.5*((tpwgts[0]+tpwgts[1])/ctrl->CoarsenTo); cgraph = Coarsen2Way(ctrl, graph); switch (ctrl->IType) { case IPART_GGPKL: Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); Compute2WayPartitionParams(ctrl, cgraph); ConstructSeparator(ctrl, cgraph, ubfactor); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); break; case IPART_GGPKLNODE: InitSeparator(ctrl, cgraph, ubfactor); break; } Refine2WayNode(ctrl, graph, cgraph, ubfactor); }
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 MlevelNodeBisectionL1(ctrl_t *ctrl, graph_t *graph, idx_t niparts) { graph_t *cgraph; ctrl->CoarsenTo = graph->nvtxs/8; if (ctrl->CoarsenTo > 100) ctrl->CoarsenTo = 100; else if (ctrl->CoarsenTo < 40) ctrl->CoarsenTo = 40; cgraph = CoarsenGraph(ctrl, graph); niparts = gk_max(1, (cgraph->nvtxs <= ctrl->CoarsenTo ? niparts/2: niparts)); /*niparts = (cgraph->nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS);*/ InitSeparator(ctrl, cgraph, niparts); Refine2WayNode(ctrl, graph, cgraph); }
/************************************************************************* * This function performs multilevel bisection. It performs multiple * bisections and selects the best. **************************************************************************/ void MlevelNodeBisectionMultiple(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) { int i, nvtxs, cnvtxs, mincut, tmp; GraphType *cgraph; idxtype *bestwhere; if (ctrl->nseps == 1 || graph->nvtxs < (ctrl->oflags&OFLAG_COMPRESS ? 1000 : 2000)) { MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); return; } nvtxs = graph->nvtxs; if (ctrl->oflags&OFLAG_COMPRESS) { /* Multiple separators at the original graph */ bestwhere = idxmalloc(nvtxs, "MlevelNodeBisection2: bestwhere"); mincut = nvtxs; for (i=ctrl->nseps; i>0; i--) { MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); /* printf("%5d ", cgraph->mincut); */ if (graph->mincut < mincut) { mincut = graph->mincut; idxcopy(nvtxs, graph->where, bestwhere); } GKfree(&graph->rdata, LTERM); if (mincut == 0) break; } /* printf("[%5d]\n", mincut); */ Allocate2WayNodePartitionMemory(ctrl, graph); idxcopy(nvtxs, bestwhere, graph->where); free(bestwhere); Compute2WayNodePartitionParams(ctrl, graph); } else { /* Coarsen it a bit */ ctrl->CoarsenTo = nvtxs-1; cgraph = Coarsen2Way(ctrl, graph); cnvtxs = cgraph->nvtxs; bestwhere = idxmalloc(cnvtxs, "MlevelNodeBisection2: bestwhere"); mincut = nvtxs; for (i=ctrl->nseps; i>0; i--) { ctrl->CType += 20; /* This is a hack. Look at coarsen.c */ MlevelNodeBisection(ctrl, cgraph, tpwgts, ubfactor); /* printf("%5d ", cgraph->mincut); */ if (cgraph->mincut < mincut) { mincut = cgraph->mincut; idxcopy(cnvtxs, cgraph->where, bestwhere); } GKfree(&cgraph->rdata, LTERM); if (mincut == 0) break; } /* printf("[%5d]\n", mincut); */ Allocate2WayNodePartitionMemory(ctrl, cgraph); idxcopy(cnvtxs, bestwhere, cgraph->where); free(bestwhere); Compute2WayNodePartitionParams(ctrl, cgraph); Refine2WayNode(ctrl, graph, cgraph, ubfactor); } }