/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_HEM(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, nvtxs, cnvtxs, maxidx, dim; idxtype *xadj, *vwgt, *adjncy; idxtype *match, *cmap, *perm, *tperm; realtype curwgt, maxwgt; realtype *vvol, *vsurf, *adjwgt, *adjwgtsum; dim = ctrl->dim; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; vvol = graph->vvol; vsurf = graph->vsurf; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; cmap = graph->cmap = idxsmalloc(nvtxs, -1, "cmap"); match = idxsmalloc(nvtxs, -1, "match"); perm = idxmalloc(nvtxs, "perm"); tperm = idxmalloc(nvtxs, "tperm"); RandomPermute(nvtxs, tperm, 1); BucketSortKeysInc(nvtxs, vwgt[iamax(nvtxs, vwgt)], vwgt, tperm, perm); /* RandomPermute(nvtxs, perm, 1); */ cnvtxs = 0; /* Compute a heavy-edge style matching giving preferance to small vertices */ for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { maxidx = i; maxwgt = 0.0; /* Find a heavy-edge matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; curwgt = 1.0/ARATIO2(dim, vsurf[i]+vsurf[k]+adjwgtsum[i]+adjwgtsum[k]- 2.0*adjwgt[j], vvol[i]+vvol[k]); if (match[k] == UNMATCHED && vwgt[i]+vwgt[k] <= ctrl->maxsize && curwgt > maxwgt) { maxwgt = curwgt; maxidx = k; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } CreateCoarseGraph(graph, cnvtxs, match, perm); IMfree((void**)&tperm, &perm, &match, LTERM); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void MCMatch_HEM(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt; idxtype *xadj, *adjncy, *adjwgt; idxtype *match, *cmap, *perm; float *nvwgt; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; cmap = graph->cmap; match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); perm = idxwspacemalloc(ctrl, nvtxs); RandomPermute(nvtxs, perm, 1); cnvtxs = 0; for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ maxidx = i; maxwgt = 0; /* Find a heavy-edge matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (match[k] == UNMATCHED && maxwgt <= adjwgt[j] && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { maxwgt = adjwgt[j]; maxidx = adjncy[j]; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_RM(CtrlType *ctrl, GraphType *graph) { int i, ii, j, nvtxs, cnvtxs, maxidx; idxtype *xadj, *vwgt, *adjncy, *adjwgt; idxtype *match, *cmap, *perm; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; cmap = graph->cmap; match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); perm = idxwspacemalloc(ctrl, nvtxs); RandomPermute(nvtxs, perm, 1); cnvtxs = 0; for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ maxidx = i; /* Find a random matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { if (match[adjncy[j]] == UNMATCHED && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) { maxidx = adjncy[j]; break; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_RM(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, nvtxs, cnvtxs, maxidx; idxtype *xadj, *vwgt, *adjncy; idxtype *match, *cmap, *perm; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; cmap = graph->cmap = idxsmalloc(nvtxs, -1, "graph->cmap"); match = idxsmalloc(nvtxs, -1, "match"); perm = idxmalloc(nvtxs, "perm"); RandomPermute(nvtxs, perm, 1); cnvtxs = 0; for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { maxidx = i; /* Find a random matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (match[k] == UNMATCHED && vwgt[i]+vwgt[k] <= ctrl->maxsize) { maxidx = k; break; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } CreateCoarseGraph(graph, cnvtxs, match, perm); IMfree((void**)&match, &perm, LTERM); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_SHEM(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree; idxtype *xadj, *vwgt, *adjncy, *adjwgt; idxtype *match, *cmap, *degrees, *perm, *tperm; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; cmap = graph->cmap; match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); perm = idxwspacemalloc(ctrl, nvtxs); tperm = idxwspacemalloc(ctrl, nvtxs); degrees = idxwspacemalloc(ctrl, nvtxs); RandomPermute(nvtxs, tperm, 1); avgdegree = 0.7*(xadj[nvtxs]/nvtxs); for (i=0; i<nvtxs; i++) degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); cnvtxs = 0; /* Take care any islands. Islands are matched with non-islands due to coarsening */ for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ if (xadj[i] < xadj[i+1]) break; maxidx = i; for (j=nvtxs-1; j>ii; j--) { k = perm[j]; if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { maxidx = k; break; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } /* Continue with normal matching */ for (; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ maxidx = i; maxwgt = 0; /* Find a heavy-edge matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { if (match[adjncy[j]] == UNMATCHED && maxwgt < adjwgt[j] && vwgt[i]+vwgt[adjncy[j]] <= ctrl->maxvwgt) { maxwgt = adjwgt[j]; maxidx = adjncy[j]; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); idxwspacefree(ctrl, nvtxs); /* degrees */ idxwspacefree(ctrl, nvtxs); /* tperm */ CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm) { int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; idxtype *xadj, *adjncy, *adjwgt; idxtype *match, *cmap, *degrees, *perm, *tperm; float *nvwgt, vbal; IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; cmap = graph->cmap; match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); perm = idxwspacemalloc(ctrl, nvtxs); tperm = idxwspacemalloc(ctrl, nvtxs); degrees = idxwspacemalloc(ctrl, nvtxs); RandomPermute(nvtxs, tperm, 1); avgdegree = (int)(0.7*(xadj[nvtxs]/nvtxs)); for (i=0; i<nvtxs; i++) degrees[i] = (xadj[i+1]-xadj[i] > avgdegree ? avgdegree : xadj[i+1]-xadj[i]); BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); cnvtxs = 0; /* Take care any islands. Islands are matched with non-islands due to coarsening */ for (ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ if (xadj[i] < xadj[i+1]) break; maxidx = i; for (j=nvtxs-1; j>ii; j--) { k = perm[j]; if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { maxidx = k; break; } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } /* Continue with normal matching */ for (; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { /* Unmatched */ maxidx = i; maxwgt = -1; vbal = 0.0; /* Find a heavy-edge matching, subject to maxvwgt constraints */ for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (match[k] == UNMATCHED && AreAllVwgtsBelowFast(ncon, nvwgt+i*ncon, nvwgt+k*ncon, ctrl->nmaxvwgt)) { if (maxidx != i) vbal = BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon); if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) { maxwgt = adjwgt[j]; maxidx = k; } } } cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); idxwspacefree(ctrl, nvtxs); /* degrees */ idxwspacefree(ctrl, nvtxs); /* tperm */ CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); idxwspacefree(ctrl, nvtxs); idxwspacefree(ctrl, nvtxs); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_HEM_True(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, dim, nvtxs, cnvtxs, ncand; idxtype *xadj, *vwgt, *adjncy; idxtype *match, *cmap, *perm; realtype *vvol, *vsurf, *adjwgt, *adjwgtsum; FKeyValueType *cand; dim = ctrl->dim; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; vvol = graph->vvol; vsurf = graph->vsurf; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; cmap = graph->cmap = idxsmalloc(nvtxs, -1, "cmap"); match = idxsmalloc(nvtxs, -1, "match"); perm = idxmalloc(nvtxs, "perm"); RandomPermute(nvtxs, perm, 1); cand = (FKeyValueType *)IMmalloc((xadj[nvtxs]/2)*sizeof(FKeyValueType), "cand"); /* insert the vertices according to their aspect ratio */ for (ncand=0, ii=0; ii<nvtxs; ii++) { i = perm[ii]; for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (k > i || vwgt[i] + vwgt[k] > ctrl->maxsize) continue; cand[ncand].val1 = i; cand[ncand].val2 = k; cand[ncand].key = ARATIO2(dim, vsurf[i]+vsurf[k]+adjwgtsum[i]+adjwgtsum[k] -2.0*adjwgt[j], vvol[i]+vvol[k]); ncand++; } } ifkeysort(ncand, cand); /* Compute heaviest style matching */ idxset(nvtxs, -1, perm); for (cnvtxs=0, ii=0; ii<ncand; ii++) { if (cnvtxs > .25*nvtxs) break; i = cand[ii].val1; k = cand[ii].val2; if (match[i] == UNMATCHED && match[k] == UNMATCHED) { perm[cnvtxs] = i; perm[nvtxs-cnvtxs-1] = k; cmap[i] = cmap[k] = cnvtxs++; match[i] = k; match[k] = i; } } /* take care of the unmatched vertices */ for (i=0; i<nvtxs; i++) { if (match[i] == UNMATCHED) { perm[cnvtxs] = i; cmap[i] = cnvtxs++; match[i] = i; } } CreateCoarseGraph(graph, cnvtxs, match, perm); IMfree((void**)&cand, &perm, &match, LTERM); }
/************************************************************************* * This function finds a matching using the HEM heuristic **************************************************************************/ void Match_HEM_Slow_Restricted(CtrlType *ctrl, GraphType *graph) { int i, ii, j, k, dim, nvtxs, cnvtxs, maxidx, nmatched; idxtype *xadj, *vwgt, *adjncy, *where; idxtype *match, *cmap, *perm; realtype curwgt, maxwgt; realtype *vvol, *vsurf, *adjwgt, *adjwgtsum; dim = ctrl->dim; nvtxs = graph->nvtxs; xadj = graph->xadj; vwgt = graph->vwgt; vvol = graph->vvol; vsurf = graph->vsurf; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; where = graph->where; cmap = graph->cmap = idxsmalloc(nvtxs, -1, "cmap"); match = idxsmalloc(nvtxs, -1, "match"); perm = idxmalloc(nvtxs, "perm"); RandomPermute(nvtxs, perm, 1); cnvtxs = 0; /* Compute a heavy-edge style matching giving preferance to small vertices */ for (nmatched=0, ii=0; ii<nvtxs; ii++) { i = perm[ii]; if (match[i] == UNMATCHED) { maxidx = i; maxwgt = 0.0; /* Find a heavy-edge matching, subject to maxvwgt constraints */ if (nmatched < .3*nvtxs) { for (j=xadj[i]; j<xadj[i+1]; j++) { k = adjncy[j]; if (where[i] != where[k]) continue; /* perform a restricted matching */ curwgt = 1.0/ARATIO2(dim, vsurf[i]+vsurf[k]+adjwgtsum[i]+adjwgtsum[k] -2.0*adjwgt[j], vvol[i]+vvol[k]); if (match[k] == UNMATCHED && vwgt[i]+vwgt[k] <= ctrl->maxsize && curwgt > maxwgt) { maxwgt = curwgt; maxidx = k; } } } if (maxidx != i) nmatched++; cmap[i] = cmap[maxidx] = cnvtxs++; match[i] = maxidx; match[maxidx] = i; } } CreateCoarseGraph(graph, cnvtxs, match, perm); IMfree((void**)&perm, &match, LTERM); }