📄 ccgraph.c
字号:
/* * Copyright 1997, Regents of the University of Minnesota * * ccgraph.c * * This file contains the functions that create the coarse graph * * Started 8/11/97 * George * * $Id: ccgraph.c 2501 2007-11-20 02:33:29Z benkirk $ * */#include <metis.h>/************************************************************************** This function creates the coarser graph**************************************************************************/void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm){ int i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask, dovsize; idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj; idxtype *cmap, *htable; idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum; float *nvwgt, *cnvwgt; GraphType *cgraph; dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0); mask = HTLENGTH; if (cnvtxs < 8*mask || graph->nedges/graph->nvtxs > 15) { CreateCoarseGraphNoMask(ctrl, graph, cnvtxs, match, perm); return; } IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; vwgt = graph->vwgt; vsize = graph->vsize; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; cmap = graph->cmap; /* Initialize the coarser graph */ cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize); cxadj = cgraph->xadj; cvwgt = cgraph->vwgt; cvsize = cgraph->vsize; cnvwgt = cgraph->nvwgt; cadjwgtsum = cgraph->adjwgtsum; cadjncy = cgraph->adjncy; cadjwgt = cgraph->adjwgt; iend = xadj[nvtxs]; auxadj = ctrl->wspace.auxcore; memcpy(auxadj, adjncy, iend*sizeof(idxtype)); for (i=0; i<iend; i++) auxadj[i] = cmap[auxadj[i]]; htable = idxset(mask+1, -1, idxwspacemalloc(ctrl, mask+1)); cxadj[0] = cnvtxs = cnedges = 0; for (i=0; i<nvtxs; i++) { v = perm[i]; if (cmap[v] != cnvtxs) continue; u = match[v]; if (ncon == 1) cvwgt[cnvtxs] = vwgt[v]; else scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon); if (dovsize) cvsize[cnvtxs] = vsize[v]; cadjwgtsum[cnvtxs] = adjwgtsum[v]; nedges = 0; istart = xadj[v]; iend = xadj[v+1]; for (j=istart; j<iend; j++) { k = auxadj[j]; kk = k&mask; if ((m = htable[kk]) == -1) { cadjncy[nedges] = k; cadjwgt[nedges] = adjwgt[j]; htable[kk] = nedges++; } else if (cadjncy[m] == k) { cadjwgt[m] += adjwgt[j]; } else { for (jj=0; jj<nedges; jj++) { if (cadjncy[jj] == k) { cadjwgt[jj] += adjwgt[j]; break; } } if (jj == nedges) { cadjncy[nedges] = k; cadjwgt[nedges++] = adjwgt[j]; } } } if (v != u) { if (ncon == 1) cvwgt[cnvtxs] += vwgt[u]; else saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1); if (dovsize) cvsize[cnvtxs] += vsize[u]; cadjwgtsum[cnvtxs] += adjwgtsum[u]; istart = xadj[u]; iend = xadj[u+1]; for (j=istart; j<iend; j++) { k = auxadj[j]; kk = k&mask; if ((m = htable[kk]) == -1) { cadjncy[nedges] = k; cadjwgt[nedges] = adjwgt[j]; htable[kk] = nedges++; } else if (cadjncy[m] == k) { cadjwgt[m] += adjwgt[j]; } else { for (jj=0; jj<nedges; jj++) { if (cadjncy[jj] == k) { cadjwgt[jj] += adjwgt[j]; break; } } if (jj == nedges) { cadjncy[nedges] = k; cadjwgt[nedges++] = adjwgt[j]; } } } /* Remove the contracted adjacency weight */ jj = htable[cnvtxs&mask]; if (jj >= 0 && cadjncy[jj] != cnvtxs) { for (jj=0; jj<nedges; jj++) { if (cadjncy[jj] == cnvtxs) break; } } if (jj >= 0 && cadjncy[jj] == cnvtxs) { /* This 2nd check is needed for non-adjacent matchings */ cadjwgtsum[cnvtxs] -= cadjwgt[jj]; cadjncy[jj] = cadjncy[--nedges]; cadjwgt[jj] = cadjwgt[nedges]; } } ASSERTP(cadjwgtsum[cnvtxs] == idxsum(nedges, cadjwgt), ("%d %d %d %d %d\n", cnvtxs, cadjwgtsum[cnvtxs], idxsum(nedges, cadjwgt), adjwgtsum[u], adjwgtsum[v])); for (j=0; j<nedges; j++) htable[cadjncy[j]&mask] = -1; /* Zero out the htable */ htable[cnvtxs&mask] = -1; cnedges += nedges; cxadj[++cnvtxs] = cnedges; cadjncy += nedges; cadjwgt += nedges; } cgraph->nedges = cnedges; ReAdjustMemory(graph, cgraph, dovsize); IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); idxwspacefree(ctrl, mask+1);}/************************************************************************** This function creates the coarser graph**************************************************************************/void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm){ int i, j, k, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, dovsize; idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *adjwgtsum, *auxadj; idxtype *cmap, *htable; idxtype *cxadj, *cvwgt, *cvsize, *cadjncy, *cadjwgt, *cadjwgtsum; float *nvwgt, *cnvwgt; GraphType *cgraph; dovsize = (ctrl->optype == OP_KVMETIS ? 1 : 0); IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; vwgt = graph->vwgt; vsize = graph->vsize; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgt = graph->adjwgt; adjwgtsum = graph->adjwgtsum; cmap = graph->cmap; /* Initialize the coarser graph */ cgraph = SetUpCoarseGraph(graph, cnvtxs, dovsize); cxadj = cgraph->xadj; cvwgt = cgraph->vwgt; cvsize = cgraph->vsize; cnvwgt = cgraph->nvwgt; cadjwgtsum = cgraph->adjwgtsum; cadjncy = cgraph->adjncy; cadjwgt = cgraph->adjwgt; htable = idxset(cnvtxs, -1, idxwspacemalloc(ctrl, cnvtxs)); iend = xadj[nvtxs]; auxadj = ctrl->wspace.auxcore; memcpy(auxadj, adjncy, iend*sizeof(idxtype)); for (i=0; i<iend; i++) auxadj[i] = cmap[auxadj[i]]; cxadj[0] = cnvtxs = cnedges = 0; for (i=0; i<nvtxs; i++) { v = perm[i]; if (cmap[v] != cnvtxs) continue; u = match[v]; if (ncon == 1) cvwgt[cnvtxs] = vwgt[v]; else scopy(ncon, nvwgt+v*ncon, cnvwgt+cnvtxs*ncon); if (dovsize) cvsize[cnvtxs] = vsize[v]; cadjwgtsum[cnvtxs] = adjwgtsum[v]; nedges = 0; istart = xadj[v]; iend = xadj[v+1]; for (j=istart; j<iend; j++) { k = auxadj[j]; if ((m = htable[k]) == -1) { cadjncy[nedges] = k; cadjwgt[nedges] = adjwgt[j]; htable[k] = nedges++; } else { cadjwgt[m] += adjwgt[j]; } } if (v != u) { if (ncon == 1) cvwgt[cnvtxs] += vwgt[u]; else saxpy(ncon, 1.0, nvwgt+u*ncon, 1, cnvwgt+cnvtxs*ncon, 1); if (dovsize) cvsize[cnvtxs] += vsize[u]; cadjwgtsum[cnvtxs] += adjwgtsum[u]; istart = xadj[u]; iend = xadj[u+1]; for (j=istart; j<iend; j++) { k = auxadj[j]; if ((m = htable[k]) == -1) { cadjncy[nedges] = k; cadjwgt[nedges] = adjwgt[j]; htable[k] = nedges++; } else { cadjwgt[m] += adjwgt[j]; } } /* Remove the contracted adjacency weight */ if ((j = htable[cnvtxs]) != -1) { ASSERT(cadjncy[j] == cnvtxs); cadjwgtsum[cnvtxs] -= cadjwgt[j]; cadjncy[j] = cadjncy[--nedges];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -