/************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ void MlevelNestedDissection(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx) { int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2]; idxtype *label, *bndind; GraphType lgraph, rgraph; nvtxs = graph->nvtxs; /* Determine the weights of the partitions */ tvwgt = idxsum(nvtxs, graph->vwgt); tpwgts2[0] = tvwgt/2; tpwgts2[1] = tvwgt-tpwgts2[0]; switch (ctrl->optype) { case OP_OEMETIS: MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); ConstructMinCoverSeparator(ctrl, graph, ubfactor); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); break; case OP_ONMETIS: MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); break; } /* Order the nodes in the separator */ nbnd = graph->nbnd; bndind = graph->bndind; label = graph->label; for (i=0; i<nbnd; i++) order[label[bndind[i]]] = --lastvtx; SplitGraphOrder(ctrl, graph, &lgraph, &rgraph); /* Free the memory of the top level graph */ /*GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);*/ GKfree3((void **)&graph->gdata, (void**)&graph->rdata, (void **)&graph->label); if (rgraph.nvtxs > MMDSWITCH) MlevelNestedDissection(ctrl, &rgraph, order, ubfactor, lastvtx); else { MMDOrder(ctrl, &rgraph, order, lastvtx); /*GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM);*/ GKfree3((void**)&rgraph.gdata, (void**)&rgraph.rdata, (void**)&rgraph.label); } if (lgraph.nvtxs > MMDSWITCH) MlevelNestedDissection(ctrl, &lgraph, order, ubfactor, lastvtx-rgraph.nvtxs); else { MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); /*GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM);*/ GKfree3((void**)&lgraph.gdata, (void**)&lgraph.rdata, (void**)&lgraph.label); } }
/************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx) { int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs; idxtype *label, *bndind; idxtype *cptr, *cind; GraphType *sgraphs; nvtxs = graph->nvtxs; /* Determine the weights of the partitions */ tvwgt = idxsum(nvtxs, graph->vwgt); tpwgts2[0] = tvwgt/2; tpwgts2[1] = tvwgt-tpwgts2[0]; MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); /* Order the nodes in the separator */ nbnd = graph->nbnd; bndind = graph->bndind; label = graph->label; for (i=0; i<nbnd; i++) order[label[bndind[i]]] = --lastvtx; cptr = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cptr"); cind = idxmalloc(nvtxs, "MlevelNestedDissectionCC: cind"); ncmps = FindComponents(ctrl, graph, cptr, cind); /* if (ncmps > 2) printf("[%5d] has %3d components\n", nvtxs, ncmps); */ sgraphs = (GraphType *)GKmalloc(ncmps*sizeof(GraphType), "MlevelNestedDissectionCC: sgraphs"); nsgraphs = SplitGraphOrderCC(ctrl, graph, sgraphs, ncmps, cptr, cind); /*GKfree(&cptr, &cind, LTERM);*/ GKfree2((void **)&cptr, (void **)&cind); /* Free the memory of the top level graph */ /*GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM);*/ GKfree3((void**)&graph->gdata, (void**)&graph->rdata, (void**)&graph->label); /* Go and process the subgraphs */ for (rnvtxs=i=0; i<nsgraphs; i++) { if (sgraphs[i].adjwgt == NULL) { MMDOrder(ctrl, sgraphs+i, order, lastvtx-rnvtxs); /*GKfree(&sgraphs[i].gdata, &sgraphs[i].label, LTERM);*/ GKfree2((void**)&sgraphs[i].gdata, (void**)&sgraphs[i].label); } else { MlevelNestedDissectionCC(ctrl, sgraphs+i, order, ubfactor, lastvtx-rnvtxs); } rnvtxs += sgraphs[i].nvtxs; } free(sgraphs); }
void MlevelNestedDissectionCC(ctrl_t *ctrl, graph_t *graph, idx_t *order, idx_t lastvtx) { idx_t i, j, nvtxs, nbnd, ncmps, rnvtxs, snvtxs; idx_t *label, *bndind; idx_t *cptr, *cind; graph_t **sgraphs; nvtxs = graph->nvtxs; MlevelNodeBisectionMultiple(ctrl, graph); IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO, printf("Nvtxs: %6"PRIDX", [%6"PRIDX" %6"PRIDX" %6"PRIDX"]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); /* Order the nodes in the separator */ nbnd = graph->nbnd; bndind = graph->bndind; label = graph->label; for (i=0; i<nbnd; i++) order[label[bndind[i]]] = --lastvtx; WCOREPUSH; cptr = iwspacemalloc(ctrl, nvtxs+1); cind = iwspacemalloc(ctrl, nvtxs); ncmps = FindSepInducedComponents(ctrl, graph, cptr, cind); if (ctrl->dbglvl&METIS_DBG_INFO) { if (ncmps > 2) printf(" Bisection resulted in %"PRIDX" connected components\n", ncmps); } sgraphs = SplitGraphOrderCC(ctrl, graph, ncmps, cptr, cind); WCOREPOP; /* Free the memory of the top level graph */ FreeGraph(&graph); /* Go and process the subgraphs */ for (rnvtxs=i=0; i<ncmps; i++) { /* Save the number of vertices in sgraphs[i] because sgraphs[i] is freed inside MlevelNestedDissectionCC, and as such it will be undefined. */ snvtxs = sgraphs[i]->nvtxs; if (sgraphs[i]->nvtxs > MMDSWITCH && sgraphs[i]->nedges > 0) { MlevelNestedDissectionCC(ctrl, sgraphs[i], order, lastvtx-rnvtxs); } else { MMDOrder(ctrl, sgraphs[i], order, lastvtx-rnvtxs); FreeGraph(&sgraphs[i]); } rnvtxs += snvtxs; } gk_free((void **)&sgraphs, LTERM); }
void MlevelNestedDissection(ctrl_t *ctrl, graph_t *graph, idx_t *order, idx_t lastvtx) { idx_t i, j, nvtxs, nbnd; idx_t *label, *bndind; graph_t *lgraph, *rgraph; nvtxs = graph->nvtxs; MlevelNodeBisectionMultiple(ctrl, graph); IFSET(ctrl->dbglvl, METIS_DBG_SEPINFO, printf("Nvtxs: %6"PRIDX", [%6"PRIDX" %6"PRIDX" %6"PRIDX"]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); /* Order the nodes in the separator */ nbnd = graph->nbnd; bndind = graph->bndind; label = graph->label; for (i=0; i<nbnd; i++) order[label[bndind[i]]] = --lastvtx; SplitGraphOrder(ctrl, graph, &lgraph, &rgraph); /* Free the memory of the top level graph */ FreeGraph(&graph); /* Recurse on lgraph first, as its lastvtx depends on rgraph->nvtxs, which will not be defined upon return from MlevelNestedDissection. */ if (lgraph->nvtxs > MMDSWITCH && lgraph->nedges > 0) MlevelNestedDissection(ctrl, lgraph, order, lastvtx-rgraph->nvtxs); else { MMDOrder(ctrl, lgraph, order, lastvtx-rgraph->nvtxs); FreeGraph(&lgraph); } if (rgraph->nvtxs > MMDSWITCH && rgraph->nedges > 0) MlevelNestedDissection(ctrl, rgraph, order, lastvtx); else { MMDOrder(ctrl, rgraph, order, lastvtx); FreeGraph(&rgraph); } }
/************************************************************************* * This function takes a graph and produces a bisection of it **************************************************************************/ void MlevelNestedDissectionP(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx, int npes, int cpos, idxtype *sizes) { int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2]; idxtype *label, *bndind; GraphType lgraph, rgraph; float ubfactor; nvtxs = graph->nvtxs; if (nvtxs == 0) { GKfree((void**)&graph->gdata, &graph->rdata, &graph->label, LTERM); return; } /* Determine the weights of the partitions */ tvwgt = idxsum(nvtxs, graph->vwgt); tpwgts2[0] = tvwgt/2; tpwgts2[1] = tvwgt-tpwgts2[0]; if (cpos >= npes-1) ubfactor = ORDER_UNBALANCE_FRACTION; else ubfactor = 1.05; MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); if (cpos < npes-1) { sizes[2*npes-2-cpos] = graph->pwgts[2]; sizes[2*npes-2-(2*cpos+1)] = graph->pwgts[1]; sizes[2*npes-2-(2*cpos+2)] = graph->pwgts[0]; } /* Order the nodes in the separator */ nbnd = graph->nbnd; bndind = graph->bndind; label = graph->label; for (i=0; i<nbnd; i++) order[label[bndind[i]]] = --lastvtx; SplitGraphOrder(ctrl, graph, &lgraph, &rgraph); /* Free the memory of the top level graph */ GKfree((void**)&graph->gdata, &graph->rdata, &graph->label, LTERM); if (rgraph.nvtxs > MMDSWITCH || 2*cpos+1 < npes-1) MlevelNestedDissectionP(ctrl, &rgraph, order, lastvtx, npes, 2*cpos+1, sizes); else { MMDOrder(ctrl, &rgraph, order, lastvtx); GKfree((void**)&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM); } if (lgraph.nvtxs > MMDSWITCH || 2*cpos+2 < npes-1) MlevelNestedDissectionP(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs, npes, 2*cpos+2, sizes); else { MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); GKfree((void**)&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM); } }