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/Programs/ptest.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/Programs/ptest.c')
| -rw-r--r-- | benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c | 477 |
1 files changed, 477 insertions, 0 deletions
diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c new file mode 100644 index 0000000..2eb8baa --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c @@ -0,0 +1,477 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * main.c + * + * This file contains code for testing teh adaptive partitioning routines + * + * Started 5/19/97 + * George + * + * $Id: ptest.c,v 1.3 2003/07/22 21:47:20 karypis Exp $ + * + */ + +#include <parmetisbin.h> + + +/************************************************************************* +* Let the game begin +**************************************************************************/ +int main(int argc, char *argv[]) +{ + int mype, npes; + MPI_Comm comm; + + MPI_Init(&argc, &argv); + MPI_Comm_dup(MPI_COMM_WORLD, &comm); + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + if (argc != 2) { + if (mype == 0) + printf("Usage: %s <graph-file>\n", argv[0]); + + MPI_Finalize(); + exit(0); + } + + TestParMetis_V3(argv[1], comm); + + MPI_Comm_free(&comm); + + MPI_Finalize(); + + return 0; +} + + + +/*********************************************************************************** +* This function is the testing routine for the adaptive multilevel partitioning code. +* It computes a partition from scratch, it then moves the graph and changes some +* of the vertex weights and then call the adaptive code. +************************************************************************************/ +void TestParMetis_V3(char *filename, MPI_Comm comm) +{ + int ncon, nparts, npes, mype, opt2, realcut; + GraphType graph, mgraph; + idxtype *part, *mpart, *savepart, *order, *sizes; + int numflag=0, wgtflag=0, options[10], edgecut, ndims; + float ipc2redist, *xyz, *tpwgts = NULL, ubvec[MAXNCON]; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + ndims = 2; + + ParallelReadGraph(&graph, filename, comm); + xyz = ReadTestCoordinates(&graph, filename, 2, comm); + MPI_Barrier(comm); + + part = idxmalloc(graph.nvtxs, "TestParMetis_V3: part"); + tpwgts = fmalloc(MAXNCON*npes*2, "TestParMetis_V3: tpwgts"); + sset(MAXNCON, 1.05, ubvec); + graph.vwgt = idxsmalloc(graph.nvtxs*5, 1, "TestParMetis_V3: vwgt"); + + + /*====================================================================== + / ParMETIS_V3_PartKway + /=======================================================================*/ + options[0] = 1; + options[1] = 3; + options[2] = 1; + wgtflag = 2; + numflag = 0; + edgecut = 0; + for (nparts=2*npes; nparts>=npes/2 && nparts > 0; nparts = nparts/2) { + for (ncon=1; ncon<=5; ncon+=2) { + + if (ncon > 1 && nparts > 1) + Mc_AdaptGraph(&graph, part, ncon, nparts, comm); + else + idxset(graph.nvtxs, 1, graph.vwgt); + + for (opt2=1; opt2<=2; opt2++) { + options[2] = opt2; + + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + if (mype == 0) + printf("\nTesting ParMETIS_V3_PartKway with options[1-2] = {%d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], ncon, nparts); + + ParMETIS_V3_PartKway(graph.vtxdist, graph.xadj, graph.adjncy, graph.vwgt, NULL, &wgtflag, + &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); + + if (mype == 0) { + printf("ParMETIS_V3_PartKway reported a cut of %d\n", edgecut); + } + } + } + } + + + /*====================================================================== + / ParMETIS_V3_PartGeomKway + /=======================================================================*/ + options[0] = 1; + options[1] = 3; + wgtflag = 2; + numflag = 0; + for (nparts=2*npes; nparts>=npes/2 && nparts > 0; nparts = nparts/2) { + for (ncon=1; ncon<=5; ncon+=2) { + + if (ncon > 1) + Mc_AdaptGraph(&graph, part, ncon, nparts, comm); + else + idxset(graph.nvtxs, 1, graph.vwgt); + + for (opt2=1; opt2<=2; opt2++) { + options[2] = opt2; + + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + if (mype == 0) + printf("\nTesting ParMETIS_V3_PartGeomKway with options[1-2] = {%d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], ncon, nparts); + + ParMETIS_V3_PartGeomKway(graph.vtxdist, graph.xadj, graph.adjncy, graph.vwgt, NULL, &wgtflag, + &numflag, &ndims, xyz, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); + + if (mype == 0) { + printf("ParMETIS_V3_PartGeomKway reported a cut of %d\n", edgecut); + } + } + } + } + + + + /*====================================================================== + / ParMETIS_V3_PartGeom + /=======================================================================*/ + wgtflag = 0; + numflag = 0; + if (mype == 0) + printf("\nTesting ParMETIS_V3_PartGeom\n"); + +/* ParMETIS_V3_PartGeom(graph.vtxdist, &ndims, xyz, part, &comm); */ + + if (mype == 0) + printf("ParMETIS_V3_PartGeom partition complete\n"); +/* + realcut = ComputeRealCut(graph.vtxdist, part, filename, comm); + if (mype == 0) + printf("ParMETIS_V3_PartGeom reported a cut of %d\n", realcut); +*/ + + /*====================================================================== + / ParMETIS_V3_RefineKway + /=======================================================================*/ + options[0] = 1; + options[1] = 3; + options[2] = 1; + options[3] = COUPLED; + nparts = npes; + wgtflag = 0; + numflag = 0; + ncon = 1; + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + + if (mype == 0) + printf("\nTesting ParMETIS_V3_RefineKway with default options (before move)\n"); + + ParMETIS_V3_RefineKway(graph.vtxdist, graph.xadj, graph.adjncy, NULL, NULL, &wgtflag, + &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); + + MALLOC_CHECK(NULL); + + if (mype == 0) { + printf("ParMETIS_V3_RefineKway reported a cut of %d\n", edgecut); + } + + + MALLOC_CHECK(NULL); + + /* Compute a good partition and move the graph. Do so quietly! */ + options[0] = 0; + nparts = npes; + wgtflag = 0; + numflag = 0; + ncon = 1; + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + ParMETIS_V3_PartKway(graph.vtxdist, graph.xadj, graph.adjncy, NULL, NULL, &wgtflag, + &numflag, &ncon, &npes, tpwgts, ubvec, options, &edgecut, part, &comm); + TestMoveGraph(&graph, &mgraph, part, comm); + GKfree((void *)&(graph.vwgt), LTERM); + mpart = idxsmalloc(mgraph.nvtxs, mype, "TestParMetis_V3: mpart"); + savepart = idxmalloc(mgraph.nvtxs, "TestParMetis_V3: savepart"); + + MALLOC_CHECK(NULL); + + /*====================================================================== + / ParMETIS_V3_RefineKway + /=======================================================================*/ + options[0] = 1; + options[1] = 3; + options[3] = COUPLED; + nparts = npes; + wgtflag = 0; + numflag = 0; + + for (ncon=1; ncon<=5; ncon+=2) { + for (opt2=1; opt2<=2; opt2++) { + options[2] = opt2; + + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + if (mype == 0) + printf("\nTesting ParMETIS_V3_RefineKway with options[1-3] = {%d %d %d}, Ncon: %d, Nparts: %d\n", options[1], options[2], options[3], ncon, nparts); + ParMETIS_V3_RefineKway(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, NULL, NULL, &wgtflag, + &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, mpart, &comm); + + if (mype == 0) { + printf("ParMETIS_V3_RefineKway reported a cut of %d\n", edgecut); + } + } + } + + + /*====================================================================== + / ParMETIS_V3_AdaptiveRepart + /=======================================================================*/ + mgraph.vwgt = idxsmalloc(mgraph.nvtxs*5, 1, "TestParMetis_V3: mgraph.vwgt"); + mgraph.vsize = idxsmalloc(mgraph.nvtxs, 1, "TestParMetis_V3: mgraph.vsize"); + AdaptGraph(&mgraph, 4, comm); + options[0] = 1; + options[1] = 7; + options[3] = COUPLED; + wgtflag = 2; + numflag = 0; + + for (nparts=2*npes; nparts>=npes/2; nparts = nparts/2) { + + ncon = 1; + wgtflag = 0; + options[0] = 0; + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + ParMETIS_V3_PartKway(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, NULL, NULL, + &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, options, &edgecut, savepart, &comm); + options[0] = 1; + wgtflag = 2; + + for (ncon=1; ncon<=3; ncon+=2) { + sset(nparts*ncon, 1.0/(float)nparts, tpwgts); + + if (ncon > 1) + Mc_AdaptGraph(&mgraph, savepart, ncon, nparts, comm); + else + AdaptGraph(&mgraph, 4, comm); +/* idxset(mgraph.nvtxs, 1, mgraph.vwgt); */ + + for (ipc2redist=1000.0; ipc2redist>=0.001; ipc2redist/=1000.0) { + for (opt2=1; opt2<=2; opt2++) { + idxcopy(mgraph.nvtxs, savepart, mpart); + options[2] = opt2; + + if (mype == 0) + printf("\nTesting ParMETIS_V3_AdaptiveRepart with options[1-3] = {%d %d %d}, ipc2redist: %.3f, Ncon: %d, Nparts: %d\n", options[1], options[2], options[3], ipc2redist, ncon, nparts); + + ParMETIS_V3_AdaptiveRepart(mgraph.vtxdist, mgraph.xadj, mgraph.adjncy, mgraph.vwgt, + mgraph.vsize, NULL, &wgtflag, &numflag, &ncon, &nparts, tpwgts, ubvec, &ipc2redist, + options, &edgecut, mpart, &comm); + + if (mype == 0) { + printf("ParMETIS_V3_AdaptiveRepart reported a cut of %d\n", edgecut); + } + } + } + } + } + + free(mgraph.vwgt); + free(mgraph.vsize); + + + + /*====================================================================== + / ParMETIS_V3_NodeND + /=======================================================================*/ + sizes = idxmalloc(2*npes, "TestParMetis_V3: sizes"); + order = idxmalloc(graph.nvtxs, "TestParMetis_V3: sizes"); + + options[0] = 1; + options[PMV3_OPTION_DBGLVL] = 3; + options[PMV3_OPTION_SEED] = 1; + numflag = 0; + + for (opt2=1; opt2<=2; opt2++) { + options[PMV3_OPTION_IPART] = opt2; + + if (mype == 0) + printf("\nTesting ParMETIS_V3_NodeND with options[1-3] = {%d %d %d}\n", options[1], options[2], options[3]); + + ParMETIS_V3_NodeND(graph.vtxdist, graph.xadj, graph.adjncy, &numflag, options, + order, sizes, &comm); + } + + + GKfree(&tpwgts, &part, &mpart, &savepart, &order, &sizes, LTERM); + +} + + + +/****************************************************************************** +* This function takes a partition vector that is distributed and reads in +* the original graph and computes the edgecut +*******************************************************************************/ +int ComputeRealCut(idxtype *vtxdist, idxtype *part, char *filename, MPI_Comm comm) +{ + int i, j, nvtxs, mype, npes, cut; + idxtype *xadj, *adjncy, *gpart; + MPI_Status status; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + if (mype != 0) { + MPI_Send((void *)part, vtxdist[mype+1]-vtxdist[mype], IDX_DATATYPE, 0, 1, comm); + } + else { /* Processor 0 does all the rest */ + gpart = idxmalloc(vtxdist[npes], "ComputeRealCut: gpart"); + idxcopy(vtxdist[1], part, gpart); + + for (i=1; i<npes; i++) + MPI_Recv((void *)(gpart+vtxdist[i]), vtxdist[i+1]-vtxdist[i], IDX_DATATYPE, i, 1, comm, &status); + + ReadMetisGraph(filename, &nvtxs, &xadj, &adjncy); + + /* OK, now compute the cut */ + for (cut=0, i=0; i<nvtxs; i++) { + for (j=xadj[i]; j<xadj[i+1]; j++) { + if (gpart[i] != gpart[adjncy[j]]) + cut++; + } + } + cut = cut/2; + + GKfree(&gpart, &xadj, &adjncy, LTERM); + + return cut; + } + return 0; +} + + +/****************************************************************************** +* This function takes a partition vector that is distributed and reads in +* the original graph and computes the edgecut +*******************************************************************************/ +int ComputeRealCut2(idxtype *vtxdist, idxtype *mvtxdist, idxtype *part, idxtype *mpart, char *filename, MPI_Comm comm) +{ + int i, j, nvtxs, mype, npes, cut; + idxtype *xadj, *adjncy, *gpart, *gmpart, *perm, *sizes; + MPI_Status status; + + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + if (mype != 0) { + MPI_Send((void *)part, vtxdist[mype+1]-vtxdist[mype], IDX_DATATYPE, 0, 1, comm); + MPI_Send((void *)mpart, mvtxdist[mype+1]-mvtxdist[mype], IDX_DATATYPE, 0, 1, comm); + } + else { /* Processor 0 does all the rest */ + gpart = idxmalloc(vtxdist[npes], "ComputeRealCut: gpart"); + idxcopy(vtxdist[1], part, gpart); + gmpart = idxmalloc(mvtxdist[npes], "ComputeRealCut: gmpart"); + idxcopy(mvtxdist[1], mpart, gmpart); + + for (i=1; i<npes; i++) { + MPI_Recv((void *)(gpart+vtxdist[i]), vtxdist[i+1]-vtxdist[i], IDX_DATATYPE, i, 1, comm, &status); + MPI_Recv((void *)(gmpart+mvtxdist[i]), mvtxdist[i+1]-mvtxdist[i], IDX_DATATYPE, i, 1, comm, &status); + } + + /* OK, now go and reconstruct the permutation to go from the graph to mgraph */ + perm = idxmalloc(vtxdist[npes], "ComputeRealCut: perm"); + sizes = idxsmalloc(npes+1, 0, "ComputeRealCut: sizes"); + + for (i=0; i<vtxdist[npes]; i++) + sizes[gpart[i]]++; + MAKECSR(i, npes, sizes); + for (i=0; i<vtxdist[npes]; i++) + perm[i] = sizes[gpart[i]]++; + + /* Ok, now read the graph from the file */ + ReadMetisGraph(filename, &nvtxs, &xadj, &adjncy); + + /* OK, now compute the cut */ + for (cut=0, i=0; i<nvtxs; i++) { + for (j=xadj[i]; j<xadj[i+1]; j++) { + if (gmpart[perm[i]] != gmpart[perm[adjncy[j]]]) + cut++; + } + } + cut = cut/2; + + GKfree(&gpart, &gmpart, &perm, &sizes, &xadj, &adjncy, LTERM); + + return cut; + } + + return 0; +} + + + +/****************************************************************************** +* This function takes a graph and its partition vector and creates a new +* graph corresponding to the one after the movement +*******************************************************************************/ +void TestMoveGraph(GraphType *ograph, GraphType *omgraph, idxtype *part, MPI_Comm comm) +{ + int npes, mype; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph, *mgraph; + int options[5] = {0, 0, 1, 0, 0}; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + SetUpCtrl(&ctrl, npes, 0, comm); + ctrl.CoarsenTo = 1; /* Needed by SetUpGraph, otherwise we can FP errors */ + graph = SetUpGraph(&ctrl, ograph->vtxdist, ograph->xadj, NULL, ograph->adjncy, NULL, 0); + PreAllocateMemory(&ctrl, graph, &wspace); + + SetUp(&ctrl, graph, &wspace); + graph->where = part; + graph->ncon = 1; + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); + + omgraph->gnvtxs = mgraph->gnvtxs; + omgraph->nvtxs = mgraph->nvtxs; + omgraph->nedges = mgraph->nedges; + omgraph->vtxdist = mgraph->vtxdist; + omgraph->xadj = mgraph->xadj; + omgraph->adjncy = mgraph->adjncy; + mgraph->vtxdist = NULL; + mgraph->xadj = NULL; + mgraph->adjncy = NULL; + FreeGraph(mgraph); + + graph->where = NULL; + FreeInitialGraphAndRemap(graph, 0); + FreeWSpace(&wspace); +} + +/***************************************************************************** +* This function sets up a graph data structure for partitioning +*****************************************************************************/ +GraphType *SetUpGraph(CtrlType *ctrl, idxtype *vtxdist, idxtype *xadj, + idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, int wgtflag) +{ + int mywgtflag; + + mywgtflag = wgtflag; + return Moc_SetUpGraph(ctrl, 1, vtxdist, xadj, vwgt, adjncy, adjwgt, &mywgtflag); +} + + |
