From 69f2911e04ffb1b19eef1fafb8c040af271f656e Mon Sep 17 00:00:00 2001 From: Tor Aamodt Date: Thu, 15 Jul 2010 18:09:46 -0800 Subject: creating branch for adding support for CUDA 3.x and Fermi [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 6829] --- .../DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c | 485 +++++++++++++++++++++ 1 file changed, 485 insertions(+) create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c (limited to 'benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c') diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c new file mode 100644 index 0000000..70f48c2 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c @@ -0,0 +1,485 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mcoarsen.c + * + * This file contains code that performs graph coarsening + * + * Started 2/22/96 + * George + * + * $Id: coarsen.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void Moc_Global_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, + WorkSpaceType *wspace, int cnvtxs) +{ + int h, i, j, k, l, ii, jj, ll, nnbrs, nvtxs, nedges, ncon; + int firstvtx, lastvtx, cfirstvtx, clastvtx, otherlastvtx; + int npes=ctrl->npes, mype=ctrl->mype; + int cnedges, nsend, nrecv, nkeepsize, nrecvsize, nsendsize, v, u; + idxtype *xadj, *ladjncy, *adjwgt, *vwgt, *vsize, *vtxdist, *home; + idxtype *match, *cmap, *rcmap, *scmap; + idxtype *cxadj, *cadjncy, *cadjwgt, *cvwgt, *cvsize = NULL, *chome = NULL, *cvtxdist; + idxtype *rsizes, *ssizes, *rlens, *slens, *rgraph, *sgraph, *perm; + idxtype *peind, *recvptr, *recvind; + float *nvwgt, *cnvwgt; + GraphType *cgraph; + KeyValueType *scand, *rcand; + int mask=(1<<13)-1, htable[8192], htableidx[8192]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + vwgt = graph->vwgt; + vsize = graph->vsize; + nvwgt = graph->nvwgt; + home = graph->home; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + match = graph->match; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap"); + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvind = graph->recvind; + recvptr = graph->recvptr; + + /* Use wspace->indices as the tmp space for map of the boundary + * vertices that are sent and received */ + scmap = wspace->indices; + rcmap = cmap + nvtxs; + + + /* Initialize the coarser graph */ + cgraph = CreateGraph(); + cgraph->nvtxs = cnvtxs; + cgraph->ncon = ncon; + cgraph->level = graph->level+1; + cgraph->finer = graph; + graph->coarser = cgraph; + + + + /************************************************************* + * Obtain the vtxdist of the coarser graph + **************************************************************/ + cvtxdist = cgraph->vtxdist = idxmalloc(npes+1, "CreateCoarseGraph: cvtxdist"); + cvtxdist[npes] = cnvtxs; /* Use last position in the cvtxdist as a temp buffer */ + + MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); + + MAKECSR(i, npes, cvtxdist); + + cgraph->gnvtxs = cvtxdist[npes]; + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); +#endif + + + /************************************************************* + * Construct the cmap vector + **************************************************************/ + cfirstvtx = cvtxdist[mype]; + clastvtx = cvtxdist[mype+1]; + + /* Create the cmap of what you know so far locally */ + cnvtxs = 0; + for (i=0; i= KEEP_BIT) { + k = match[i] - KEEP_BIT; + if (k>=firstvtx && k=firstvtx && knrecv, recvind, match[i])]; + } + } + + CommInterfaceData(ctrl, graph, cmap, scmap, rcmap); + + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); +#endif + + + /************************************************************* + * Determine how many adjcency lists you need to send/receive. + **************************************************************/ + /* Use wspace->pairs as the tmp space for the boundary vertices that are sent and received */ + scand = wspace->pairs; + rcand = graph->rcand = (KeyValueType *)GKmalloc(recvptr[nnbrs]*sizeof(KeyValueType), "CreateCoarseGraph: rcand"); + + nkeepsize = nsend = nrecv = 0; + for (i=0; i=lastvtx) { /* This is comming from afar */ + rcand[nrecv].key = k; + rcand[nrecv].val = cmap[i] - cfirstvtx; /* Set it for use during the partition projection */ + ASSERT(ctrl, rcand[nrecv].val>=0 && rcand[nrecv].valpv1; + ssizes = wspace->pv2; + idxset(nnbrs, 0, ssizes); + idxset(nnbrs, 0, rsizes); + rlens = graph->rlens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->rlens"); + slens = graph->slens = idxmalloc(nnbrs+1, "CreateCoarseGraph: graph->slens"); + + /* Take care the sending data first */ + ikeyvalsort(nsend, scand); + slens[0] = 0; + for (k=i=0; i 0) /* Issue a receive only if you are getting something */ + MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); + } + + /* Take care the sending data next */ + for (i=0; i 0) /* Issue a send only if you are sending something */ + MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); + } + + /* OK, now get into the loop waiting for the operations to finish */ + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, nnbrs, 0, rsizes, "rsizes"); + PrintVector(ctrl, nnbrs, 0, ssizes, "ssizes"); +#endif + + /************************************************************* + * Allocate memory for received/sent graphs and start sending + * and receiving data. + * rgraph and sgraph is a different data structure than CSR + * to facilitate single message exchange. + **************************************************************/ + nrecvsize = idxsum(nnbrs, rsizes); + nsendsize = idxsum(nnbrs, ssizes); + if ((4+ncon)*(nrecv+nsend) + 2*(nrecvsize+nsendsize) <= wspace->nlarge) { + rgraph = (idxtype *)wspace->degrees; + sgraph = rgraph + (4+ncon)*nrecv+2*nrecvsize; + } + else { + rgraph = idxmalloc((4+ncon)*nrecv+2*nrecvsize, "CreateCoarseGraph: rgraph"); + sgraph = idxmalloc((4+ncon)*nsend+2*nsendsize, "CreateCoarseGraph: sgraph"); + } + + /* Deal with the received portion first */ + for (l=i=0; i 0) { + MPI_Irecv((void *)(rgraph+l), (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); + l += (4+ncon)*(rlens[i+1]-rlens[i])+2*rsizes[i]; + } + } + + + /* Deal with the sent portion now */ + for (ll=l=i=0; i 0) { /* Issue a send only if you are sending something */ + for (k=slens[i]; kpartType == STATIC_PARTITION) ? -1 : vsize[ii]; + sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; + for (jj=xadj[ii]; jjcomm, ctrl->sreq+i); + l = ll; + } + } + + /* OK, now get into the loop waiting for the operations to finish */ + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + + +#ifdef DEBUG_CONTRACT + rprintf(ctrl, "Graphs were sent!\n"); + PrintTransferedGraphs(ctrl, nnbrs, peind, slens, rlens, sgraph, rgraph); +#endif + + /************************************************************* + * Setup the mapping from indices returned by BSearch to + * those that are actually stored + **************************************************************/ + perm = idxsmalloc(recvptr[nnbrs], -1, "CreateCoarseGraph: perm"); + for (j=i=0; inrecv, recvind, rgraph[j]), j+ncon); */ + perm[BSearch(graph->nrecv, recvind, rgraph[j])] = j+1; + j += (4+ncon)+2*rgraph[j+1]; + } + + /************************************************************* + * Finally, create the coarser graph + **************************************************************/ + /* Allocate memory for the coarser graph, and fire up coarsening */ + cxadj = cgraph->xadj = idxmalloc(cnvtxs+1, "CreateCoarserGraph: cxadj"); + cvwgt = cgraph->vwgt = idxmalloc(cnvtxs*ncon, "CreateCoarserGraph: cvwgt"); + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize"); + chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome"); + } + cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); + cadjncy = idxmalloc(2*(nkeepsize+nrecvsize), "CreateCoarserGraph: cadjncy"); + cadjwgt = cadjncy + nkeepsize+nrecvsize; + + iset(8192, -1, htable); + + cxadj[0] = cnvtxs = cnedges = 0; + for (i=0; i= KEEP_BIT) { + v = firstvtx+i; + u = match[i]-KEEP_BIT; + + if (u>=firstvtx && u u) + continue; /* I have already collapsed it as (u,v) */ + + /* Collapse the v vertex first, which you know is local */ + for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] = vsize[i]; + chome[cnvtxs] = home[i]; + } + nedges = 0; + + for (j=xadj[i]; j=firstvtx && upartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] += vsize[u]; + /* chome[cnvtxs] = home[u]; */ + } + + for (j=xadj[u]; jnrecv, recvind, u)]; + for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + cvsize[cnvtxs] += rgraph[u+1+ncon]; + chome[cnvtxs] = rgraph[u+2+ncon]; + } + for (j=0; jnedges = cnedges; + + /* ADD: In order to keep from having to change this too much */ + /* ADD: I kept vwgt array and recomputed nvwgt for each coarser graph */ + for (j=0; jnvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); + + cgraph->adjncy = idxmalloc(cnedges, "CreateCoarserGraph: cadjncy"); + cgraph->adjwgt = idxmalloc(cnedges, "CreateCoarserGraph: cadjwgt"); + idxcopy(cnedges, cadjncy, cgraph->adjncy); + idxcopy(cnedges, cadjwgt, cgraph->adjwgt); + free(cadjncy); + + free(perm); + + if (rgraph != (idxtype *)wspace->degrees) + GKfree((void **)&rgraph, (void **)&sgraph, LTERM); + +} + + -- cgit v1.3