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/ParMETISLib/remap.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/ParMETISLib/remap.c')
| -rw-r--r-- | benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c new file mode 100644 index 0000000..31f186b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c @@ -0,0 +1,181 @@ +/* + * premap.c + * + * This file contains code that computes the assignment of processors to + * partition numbers so that it will minimize the redistribution cost + * + * Started 4/16/98 + * George + * + * $Id: remap.c,v 1.2 2003/07/21 17:18:53 karypis Exp $ + * + */ + +#include <parmetislib.h> + +/************************************************************************* +* This function remaps that graph so that it will minimize the +* redistribution cost +**************************************************************************/ +void ParallelReMapGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, nvtxs, nparts; + idxtype *where, *vsize, *map, *lpwgts; + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RemapTmr)); + + if (ctrl->npes != ctrl->nparts) { + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RemapTmr)); + return; + } + + nvtxs = graph->nvtxs; + where = graph->where; + vsize = graph->vsize; + nparts = ctrl->nparts; + + map = wspace->pv1; + lpwgts = idxset(nparts, 0, wspace->pv2); + + for (i=0; i<nvtxs; i++) + lpwgts[where[i]] += (vsize == NULL) ? 1 : vsize[i]; + + ParallelTotalVReMap(ctrl, lpwgts, map, wspace, NREMAP_PASSES, graph->ncon); + + for (i=0; i<nvtxs; i++) + where[i] = map[where[i]]; + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RemapTmr)); +} + + +/************************************************************************* +* This function computes the assignment using the the objective the +* minimization of the total volume of data that needs to move +**************************************************************************/ +void ParallelTotalVReMap(CtrlType *ctrl, idxtype *lpwgts, idxtype *map, + WorkSpaceType *wspace, int npasses, int ncon) +{ + int i, ii, j, k, nparts, mype; + int pass, maxipwgt, nmapped, oldwgt, newwgt, done; + idxtype *rowmap, *mylpwgts; + KeyValueType *recv, send; + int nsaved, gnsaved; + + mype = ctrl->mype; + nparts = ctrl->nparts; + recv = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*nparts, "remap: recv"); + mylpwgts = idxmalloc(nparts, "mylpwgts"); + + done = nmapped = 0; + idxset(nparts, -1, map); + rowmap = idxset(nparts, -1, wspace->pv3); + idxcopy(nparts, lpwgts, mylpwgts); + for (pass=0; pass<npasses; pass++) { + maxipwgt = idxamax(nparts, mylpwgts); + + if (mylpwgts[maxipwgt] > 0 && !done) { + send.key = -mylpwgts[maxipwgt]; + send.val = mype*nparts+maxipwgt; + } + else { + send.key = 0; + send.val = -1; + } + + /* each processor sends its selection */ + MPI_Allgather((void *)&send, 2, IDX_DATATYPE, (void *)recv, 2, IDX_DATATYPE, ctrl->comm); + + ikeysort(nparts, recv); + if (recv[0].key == 0) + break; + + /* now make as many assignments as possible */ + for (ii=0; ii<nparts; ii++) { + i = recv[ii].val; + + if (i == -1) + continue; + + j = i % nparts; + k = i / nparts; + if (map[j] == -1 && rowmap[k] == -1 && SimilarTpwgts(ctrl->tpwgts, ncon, j, k)) { + map[j] = k; + rowmap[k] = j; + nmapped++; + mylpwgts[j] = 0; + if (mype == k) + done = 1; + } + + if (nmapped == nparts) + break; + } + + if (nmapped == nparts) + break; + } + + /* Map unmapped partitions */ + if (nmapped < nparts) { + for (i=j=0; j<nparts && nmapped<nparts; j++) { + if (map[j] == -1) { + for (; i<nparts; i++) { + if (rowmap[i] == -1 && SimilarTpwgts(ctrl->tpwgts, ncon, i, j)) { + map[j] = i; + rowmap[i] = j; + nmapped++; + break; + } + } + } + } + } + + /* check to see if remapping fails (due to dis-similar tpwgts) */ + /* if remapping fails, revert to original mapping */ + if (nmapped < nparts) { + for (i=0; i<nparts; i++) + map[i] = i; + IFSET(ctrl->dbglvl, DBG_REMAP, rprintf(ctrl, "Savings from parallel remapping: %0\n")); + } + else { + /* check for a savings */ + oldwgt = lpwgts[mype]; + newwgt = lpwgts[rowmap[mype]]; + nsaved = newwgt - oldwgt; + gnsaved = GlobalSESum(ctrl, nsaved); + + /* undo everything if we don't see a savings */ + if (gnsaved <= 0) { + for (i=0; i<nparts; i++) + map[i] = i; + } + IFSET(ctrl->dbglvl, DBG_REMAP, rprintf(ctrl, "Savings from parallel remapping: %d\n", amax(0,gnsaved))); + } + + GKfree((void **)&recv, (void **)&mylpwgts, LTERM); + +} + + +/************************************************************************* +* This function computes the assignment using the the objective the +* minimization of the total volume of data that needs to move +**************************************************************************/ +int SimilarTpwgts(float *tpwgts, int ncon, int s1, int s2) +{ + int i; + + for (i=0; i<ncon; i++) + if (fabs(tpwgts[s1*ncon+i]-tpwgts[s2*ncon+i]) > SMALLFLOAT) + break; + + if (i == ncon) + return 1; + + return 0; +} + |
