/* * 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 * */ #include /************************************************************************* * This function creates the coarser graph **************************************************************************/ void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, idxtype cnvtxs, idxtype *match, idxtype *perm) { idxtype 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, gk_startcputimer(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= 0 && cadjncy[jj] != cnvtxs) { for (jj=0; 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; jnedges = cnedges; ReAdjustMemory(graph, cgraph, dovsize); IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->ContractTmr)); idxwspacefree(ctrl, mask+1); } /************************************************************************* * This function creates the coarser graph **************************************************************************/ void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, idxtype cnvtxs, idxtype *match, idxtype *perm) { idxtype 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, gk_startcputimer(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; inedges = cnedges; ReAdjustMemory(graph, cgraph, dovsize); IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->ContractTmr)); idxwspacefree(ctrl, cnvtxs); } /************************************************************************* * This function creates the coarser graph **************************************************************************/ void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph, idxtype cnvtxs, idxtype *match, idxtype *perm) { idxtype i, j, jj, k, kk, l, m, istart, iend, nvtxs, nedges, ncon, cnedges, v, u, mask; idxtype *xadj, *adjncy, *adjwgtsum, *auxadj; idxtype *cmap, *htable; idxtype *cxadj, *cvwgt, *cadjncy, *cadjwgt, *cadjwgtsum; float *nvwgt, *cnvwgt; GraphType *cgraph; IFSET(ctrl->dbglvl, DBG_TIME, gk_startcputimer(ctrl->ContractTmr)); nvtxs = graph->nvtxs; ncon = graph->ncon; xadj = graph->xadj; nvwgt = graph->nvwgt; adjncy = graph->adjncy; adjwgtsum = graph->adjwgtsum; cmap = graph->cmap; /* Initialize the coarser graph */ cgraph = SetUpCoarseGraph(graph, cnvtxs, 0); cxadj = cgraph->xadj; cvwgt = cgraph->vwgt; 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= 0 && cadjncy[jj] != cnvtxs) { for (jj=0; 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; jnedges = cnedges; ReAdjustMemory(graph, cgraph, 0); IFSET(ctrl->dbglvl, DBG_TIME, gk_stopcputimer(ctrl->ContractTmr)); idxwspacefree(ctrl, mask+1); } /************************************************************************* * Setup the various arrays for the coarse graph **************************************************************************/ GraphType *SetUpCoarseGraph(GraphType *graph, idxtype cnvtxs, idxtype dovsize) { GraphType *cgraph; cgraph = CreateGraph(); cgraph->nvtxs = cnvtxs; cgraph->ncon = graph->ncon; cgraph->finer = graph; graph->coarser = cgraph; /* Allocate memory for the coarser graph */ cgraph->xadj = idxmalloc(cnvtxs+1, "SetUpCoarseGraph: xadj"); cgraph->adjwgtsum = idxmalloc(cnvtxs, "SetUpCoarseGraph: adjwgtsum"); cgraph->cmap = idxmalloc(cnvtxs, "SetUpCoarseGraph: cmap"); cgraph->adjncy = idxmalloc(graph->nedges, "SetUpCoarseGraph: adjncy"); cgraph->adjwgt = idxmalloc(graph->nedges, "SetUpCoarseGraph: adjwgt"); if (graph->ncon == 1) cgraph->vwgt = idxmalloc(cnvtxs, "SetUpCoarseGraph: vwgt"); else cgraph->nvwgt = gk_fmalloc(graph->ncon*cnvtxs, "SetUpCoarseGraph: nvwgt"); if (dovsize) cgraph->vsize = idxmalloc(cnvtxs, "SetUpCoarseGraph: vsize"); return cgraph; } /************************************************************************* * This function re-adjusts the amount of memory that was allocated if * it will lead to significant savings **************************************************************************/ void ReAdjustMemory(GraphType *graph, GraphType *cgraph, idxtype dovsize) { if (cgraph->nedges > 10000 && cgraph->nedges < 0.8*graph->nedges) { cgraph->adjncy = idxrealloc(cgraph->adjncy, cgraph->nedges, "ReAdjustMemory: adjncy"); cgraph->adjwgt = idxrealloc(cgraph->adjwgt, cgraph->nedges, "ReAdjustMemory: adjwgt"); } }