diff options
| author | Tor Aamodt <[email protected]> | 2010-07-15 18:09:46 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-07-15 18:09:46 -0800 |
| commit | 69f2911e04ffb1b19eef1fafb8c040af271f656e (patch) | |
| tree | 231d3b6bdc3a202f7c255bfcf7bf2c36e32cee9e /benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c | |
creating branch for adding support for CUDA 3.x and Fermi
[git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829]
Diffstat (limited to 'benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c')
| -rw-r--r-- | benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c | 296 |
1 files changed, 296 insertions, 0 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c new file mode 100644 index 0000000..15836db --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c @@ -0,0 +1,296 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mkwayrefine.c + * + * This file contains the driving routines for multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: mkwayrefine.c,v 1.1 2003/07/16 15:55:11 karypis Exp $ + */ + +#include <metis.h> + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void MocRefineKWayHorizontal(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, + float *ubvec) +{ + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + MocComputeKWayPartitionParams(ctrl, graph, nparts); + + for (;;) { + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + + if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) { + MocComputeKWayBalanceBoundary(ctrl, graph, nparts); + MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); + ComputeKWayBoundary(ctrl, graph, nparts); + } + + MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + MocProjectKWayPartition(ctrl, graph, nparts); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + if (!MocIsHBalanced(graph->ncon, nparts, graph->npwgts, ubvec)) { + MocComputeKWayBalanceBoundary(ctrl, graph, nparts); + MCGreedy_KWayEdgeBalanceHorizontal(ctrl, graph, nparts, ubvec, 4); + ComputeKWayBoundary(ctrl, graph, nparts); + MCRandom_KWayEdgeRefineHorizontal(ctrl, graph, nparts, ubvec, 10); + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + + + +/************************************************************************* +* This function allocates memory for k-way edge refinement +**************************************************************************/ +void MocAllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int nvtxs, ncon, pad64; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + pad64 = (3*nvtxs+nparts)%2; + + graph->rdata = idxmalloc(3*nvtxs+ncon*nparts+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata"); + graph->npwgts = (float *)graph->rdata; + graph->where = graph->rdata + ncon*nparts; + graph->bndptr = graph->rdata + nvtxs + ncon*nparts; + graph->bndind = graph->rdata + 2*nvtxs + ncon*nparts; + graph->rinfo = (RInfoType *)(graph->rdata + 3*nvtxs+ncon*nparts + pad64); +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void MocComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, j, k, l, nvtxs, ncon, nbnd, mincut, me, other; + idxtype *xadj, *adjncy, *adjwgt, *where, *bndind, *bndptr; + RInfoType *rinfo, *myrinfo; + EDegreeType *myedegrees; + float *nvwgt, *npwgts; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + npwgts = sset(ncon*nparts, 0.0, graph->npwgts); + bndind = graph->bndind; + bndptr = idxset(nvtxs, -1, graph->bndptr); + rinfo = graph->rinfo; + + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + ctrl->wspace.cdegree = 0; + nbnd = mincut = 0; + for (i=0; i<nvtxs; i++) { + me = where[i]; + saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); + + myrinfo = rinfo+i; + myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + for (j=xadj[i]; j<xadj[i+1]; j++) { + if (me != where[adjncy[j]]) + myrinfo->ed += adjwgt[j]; + } + myrinfo->id = graph->adjwgtsum[i] - myrinfo->ed; + + if (myrinfo->ed > 0) + mincut += myrinfo->ed; + + if (myrinfo->ed-myrinfo->id >= 0) + BNDInsert(nbnd, bndind, bndptr, i); + + /* Time to compute the particular external degrees */ + if (myrinfo->ed > 0) { + myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; + + for (j=xadj[i]; j<xadj[i+1]; j++) { + other = where[adjncy[j]]; + if (me != other) { + for (k=0; k<myrinfo->ndegrees; k++) { + if (myedegrees[k].pid == other) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = other; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + } + + ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + } + } + + graph->mincut = mincut/2; + graph->nbnd = nbnd; + +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void MocProjectKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, j, k, nvtxs, nbnd, me, other, istart, iend, ndegrees; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where, *bndptr, *bndind; + idxtype *cwhere; + GraphType *cgraph; + RInfoType *crinfo, *rinfo, *myrinfo; + EDegreeType *myedegrees; + idxtype *htable; + + cgraph = graph->coarser; + cwhere = cgraph->where; + crinfo = cgraph->rinfo; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + MocAllocateKWayPartitionMemory(ctrl, graph, nparts); + where = graph->where; + rinfo = graph->rinfo; + bndind = graph->bndind; + bndptr = idxset(nvtxs, -1, graph->bndptr); + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; i<nvtxs; i++) { + k = cmap[i]; + where[i] = cwhere[k]; + cmap[i] = crinfo[k].ed; /* For optimization */ + } + + htable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); + + ctrl->wspace.cdegree = 0; + for (nbnd=0, i=0; i<nvtxs; i++) { + me = where[i]; + + myrinfo = rinfo+i; + myrinfo->id = myrinfo->ed = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + myrinfo->id = adjwgtsum[i]; + + if (cmap[i] > 0) { /* If it is an interface node. Note cmap[i] = crinfo[cmap[i]].ed */ + istart = xadj[i]; + iend = xadj[i+1]; + + myedegrees = myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += iend-istart; + + ndegrees = 0; + for (j=istart; j<iend; j++) { + other = where[adjncy[j]]; + if (me != other) { + myrinfo->ed += adjwgt[j]; + if ((k = htable[other]) == -1) { + htable[other] = ndegrees; + myedegrees[ndegrees].pid = other; + myedegrees[ndegrees++].ed = adjwgt[j]; + } + else { + myedegrees[k].ed += adjwgt[j]; + } + } + } + myrinfo->id -= myrinfo->ed; + + /* Remove space for edegrees if it was interior */ + if (myrinfo->ed == 0) { + myrinfo->edegrees = NULL; + ctrl->wspace.cdegree -= iend-istart; + } + else { + if (myrinfo->ed-myrinfo->id >= 0) + BNDInsert(nbnd, bndind, bndptr, i); + + myrinfo->ndegrees = ndegrees; + + for (j=0; j<ndegrees; j++) + htable[myedegrees[j].pid] = -1; + } + } + } + + scopy(graph->ncon*nparts, cgraph->npwgts, graph->npwgts); + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + + FreeGraph(graph->coarser); + graph->coarser = NULL; + + idxwspacefree(ctrl, nparts); + + ASSERT(CheckBnd2(graph)); + +} + + + +/************************************************************************* +* This function computes the boundary definition for balancing +**************************************************************************/ +void MocComputeKWayBalanceBoundary(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, nvtxs, nbnd; + idxtype *bndind, *bndptr; + + nvtxs = graph->nvtxs; + bndind = graph->bndind; + bndptr = idxset(nvtxs, -1, graph->bndptr); + + + /* Compute the new boundary */ + nbnd = 0; + for (i=0; i<nvtxs; i++) { + if (graph->rinfo[i].ed > 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + |
