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] --- benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/CHANGES | 144 + benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/COPYRIGHT | 19 + .../CUDA/DG/3rdParty/ParMetis-3.1/Graphs/README | 1 + benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/INSTALL | 1961 ++++ .../DG/3rdParty/ParMetis-3.1/METISLib/Makefile | 45 + .../ParMetis-3.1/METISLib/NEW_checkgraph.c | 127 + .../DG/3rdParty/ParMetis-3.1/METISLib/NEW_memory.c | 208 + .../DG/3rdParty/ParMetis-3.1/METISLib/NEW_mfm.c | 341 + .../3rdParty/ParMetis-3.1/METISLib/NEW_mrefine.c | 219 + .../3rdParty/ParMetis-3.1/METISLib/NEW_parmetis.c | 155 + .../DG/3rdParty/ParMetis-3.1/METISLib/NEW_stats.c | 44 + .../DG/3rdParty/ParMetis-3.1/METISLib/balance.c | 278 + .../DG/3rdParty/ParMetis-3.1/METISLib/bucketsort.c | 43 + .../DG/3rdParty/ParMetis-3.1/METISLib/ccgraph.c | 599 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/checkgraph.c | 127 + .../DG/3rdParty/ParMetis-3.1/METISLib/coarsen.c | 86 + .../DG/3rdParty/ParMetis-3.1/METISLib/compress.c | 256 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/debug.c | 239 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/defs.h | 161 + .../DG/3rdParty/ParMetis-3.1/METISLib/estmem.c | 157 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fm.c | 194 + .../DG/3rdParty/ParMetis-3.1/METISLib/fortran.c | 141 + .../DG/3rdParty/ParMetis-3.1/METISLib/frename.c | 312 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c | 616 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/initpart.c | 425 + .../DG/3rdParty/ParMetis-3.1/METISLib/kmetis.c | 129 + .../DG/3rdParty/ParMetis-3.1/METISLib/kvmetis.c | 130 + .../DG/3rdParty/ParMetis-3.1/METISLib/kwayfm.c | 672 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/kwayrefine.c | 392 + .../DG/3rdParty/ParMetis-3.1/METISLib/kwayvolfm.c | 1778 ++++ .../3rdParty/ParMetis-3.1/METISLib/kwayvolrefine.c | 468 + .../DG/3rdParty/ParMetis-3.1/METISLib/macros.h | 138 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/match.c | 267 + .../DG/3rdParty/ParMetis-3.1/METISLib/mbalance.c | 260 + .../DG/3rdParty/ParMetis-3.1/METISLib/mbalance2.c | 328 + .../DG/3rdParty/ParMetis-3.1/METISLib/mcoarsen.c | 106 + .../DG/3rdParty/ParMetis-3.1/METISLib/memory.c | 208 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mesh.c | 399 + .../DG/3rdParty/ParMetis-3.1/METISLib/meshpart.c | 204 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/metis.h | 31 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm.c | 341 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm2.c | 349 + .../DG/3rdParty/ParMetis-3.1/METISLib/mincover.c | 259 + .../DG/3rdParty/ParMetis-3.1/METISLib/minitpart.c | 358 + .../DG/3rdParty/ParMetis-3.1/METISLib/minitpart2.c | 368 + .../DG/3rdParty/ParMetis-3.1/METISLib/mkmetis.c | 124 + .../DG/3rdParty/ParMetis-3.1/METISLib/mkwayfmh.c | 677 ++ .../3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c | 296 + .../DG/3rdParty/ParMetis-3.1/METISLib/mmatch.c | 501 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c | 593 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/mpmetis.c | 402 + .../DG/3rdParty/ParMetis-3.1/METISLib/mrefine.c | 219 + .../DG/3rdParty/ParMetis-3.1/METISLib/mrefine2.c | 55 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mutil.c | 101 + .../DG/3rdParty/ParMetis-3.1/METISLib/myqsort.c | 547 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/ometis.c | 764 ++ .../DG/3rdParty/ParMetis-3.1/METISLib/parmetis.c | 512 + .../DG/3rdParty/ParMetis-3.1/METISLib/pmetis.c | 341 + .../DG/3rdParty/ParMetis-3.1/METISLib/pqueue.c | 579 ++ .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/proto.h | 511 + .../DG/3rdParty/ParMetis-3.1/METISLib/refine.c | 204 + .../DG/3rdParty/ParMetis-3.1/METISLib/rename.h | 424 + .../DG/3rdParty/ParMetis-3.1/METISLib/separator.c | 284 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/sfm.c | 1069 +++ .../DG/3rdParty/ParMetis-3.1/METISLib/srefine.c | 169 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stat.c | 316 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stats.c | 44 + .../DG/3rdParty/ParMetis-3.1/METISLib/stdheaders.h | 26 + .../DG/3rdParty/ParMetis-3.1/METISLib/struct.h | 253 + .../DG/3rdParty/ParMetis-3.1/METISLib/subdomains.c | 1295 +++ .../DG/3rdParty/ParMetis-3.1/METISLib/timing.c | 74 + .../CUDA/DG/3rdParty/ParMetis-3.1/METISLib/util.c | 511 + benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile | 13 + .../CUDA/DG/3rdParty/ParMetis-3.1/Makefile.in | 32 + .../CUDA/DG/3rdParty/ParMetis-3.1/Makefile.osx | 32 + .../CUDA/DG/3rdParty/ParMetis-3.1/Makefile.rtc | 33 + .../DG/3rdParty/ParMetis-3.1/Manual/manual.pdf | Bin 0 -> 187999 bytes .../CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.ps | 6812 ++++++++++++++ .../DG/3rdParty/ParMetis-3.1/ParMETISLib/Makefile | 48 + .../3rdParty/ParMetis-3.1/ParMETISLib/adrivers.c | 117 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/akwayfm.c | 629 ++ .../DG/3rdParty/ParMetis-3.1/ParMETISLib/ametis.c | 272 + .../3rdParty/ParMetis-3.1/ParMETISLib/backcompat.c | 517 ++ .../ParMetis-3.1/ParMETISLib/balancemylink.c | 342 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c | 485 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/comm.c | 213 + .../3rdParty/ParMetis-3.1/ParMETISLib/csrmatch.c | 88 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/debug.c | 247 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/defs.h | 102 + .../3rdParty/ParMetis-3.1/ParMETISLib/diffutil.c | 298 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/fpqueue.c | 440 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/frename.c | 322 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/gkmetis.c | 331 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/grsetup.c | 274 + .../3rdParty/ParMetis-3.1/ParMETISLib/iidxsort.c | 152 + .../3rdParty/ParMetis-3.1/ParMETISLib/iintsort.c | 157 + .../3rdParty/ParMetis-3.1/ParMETISLib/ikeysort.c | 151 + .../ParMetis-3.1/ParMETISLib/ikeyvalsort.c | 151 + .../ParMetis-3.1/ParMETISLib/initbalance.c | 498 + .../ParMetis-3.1/ParMETISLib/initmsection.c | 242 + .../3rdParty/ParMetis-3.1/ParMETISLib/initpart.c | 252 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/kmetis.c | 274 + .../ParMetis-3.1/ParMETISLib/kwaybalance.c | 456 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayfm.c | 599 ++ .../3rdParty/ParMetis-3.1/ParMETISLib/kwayrefine.c | 239 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/lmatch.c | 364 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/macros.h | 163 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/match.c | 320 + .../3rdParty/ParMetis-3.1/ParMETISLib/mdiffusion.c | 455 + .../3rdParty/ParMetis-3.1/ParMETISLib/mdrivers.c | 116 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/memory.c | 216 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/mesh.c | 335 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/mmetis.c | 95 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/move.c | 338 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/msetup.c | 95 + .../ParMetis-3.1/ParMETISLib/node_refine.c | 383 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/ometis.c | 188 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/order.c | 348 + .../ParMetis-3.1/ParMETISLib/parmetislib.h | 31 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/proto.h | 352 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/pspases.c | 167 + .../3rdParty/ParMetis-3.1/ParMETISLib/redomylink.c | 175 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c | 181 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/rename.h | 290 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/rmetis.c | 165 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/selectq.c | 340 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/serial.c | 1251 +++ .../DG/3rdParty/ParMetis-3.1/ParMETISLib/setup.c | 219 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/stat.c | 332 + .../3rdParty/ParMetis-3.1/ParMETISLib/stdheaders.h | 25 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/struct.h | 290 + .../CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/sync | 186 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/timer.c | 90 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/util.c | 983 ++ .../DG/3rdParty/ParMetis-3.1/ParMETISLib/wave.c | 241 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/weird.c | 275 + .../DG/3rdParty/ParMetis-3.1/ParMETISLib/xyzpart.c | 257 + .../DG/3rdParty/ParMetis-3.1/Programs/Makefile | 56 + .../DG/3rdParty/ParMetis-3.1/Programs/adaptgraph.c | 171 + .../CUDA/DG/3rdParty/ParMetis-3.1/Programs/io.c | 951 ++ .../CUDA/DG/3rdParty/ParMetis-3.1/Programs/mtest.c | 96 + .../3rdParty/ParMetis-3.1/Programs/parmetisbin.h | 31 + .../CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c | 477 + benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/README | 9 + benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/VERSION | 5 + .../CUDA/DG/3rdParty/ParMetis-3.1/parmetis.h | 193 + benchmarks/CUDA/DG/Makefile | 62 + benchmarks/CUDA/DG/MakefileCPU2d | 51 + benchmarks/CUDA/DG/MakefileGPU2d | 57 + benchmarks/CUDA/DG/Makefiles/Makefile | 49 + benchmarks/CUDA/DG/Makefiles/MakefileCPU3d | 51 + benchmarks/CUDA/DG/Makefiles/MakefileGPU3d | 54 + benchmarks/CUDA/DG/Meshes/F072.neu | 186 + benchmarks/CUDA/DG/Meshes/FS_K01022.neu | 1929 ++++ benchmarks/CUDA/DG/Meshes/block2.neu | 443 + benchmarks/CUDA/DG/Meshes/block3.neu | 9764 ++++++++++++++++++++ benchmarks/CUDA/DG/Meshes/cubeK268.neu | 565 ++ benchmarks/CUDA/DG/README.GPGPU-Sim | 14 + benchmarks/CUDA/DG/buildsource.m | 106 + benchmarks/CUDA/DG/data/F072.neu | 186 + benchmarks/CUDA/DG/data/FS_K01022.neu | 1929 ++++ benchmarks/CUDA/DG/data/block2.neu | 443 + benchmarks/CUDA/DG/data/block3.neu | 9764 ++++++++++++++++++++ benchmarks/CUDA/DG/data/cubeK268.neu | 565 ++ benchmarks/CUDA/DG/include/Mesh.h | 98 + benchmarks/CUDA/DG/include/data3dN06.h | 349 + benchmarks/CUDA/DG/include/defs.h | 102 + benchmarks/CUDA/DG/include/fem.h | 109 + benchmarks/CUDA/DG/include/macros.h | 163 + benchmarks/CUDA/DG/include/parmetis.h | 193 + benchmarks/CUDA/DG/include/parmetisbin.h | 31 + benchmarks/CUDA/DG/include/proto.h | 352 + benchmarks/CUDA/DG/include/rename.h | 290 + benchmarks/CUDA/DG/include/stdheaders.h | 25 + benchmarks/CUDA/DG/include/struct.h | 290 + benchmarks/CUDA/DG/license.midg | 20 + benchmarks/CUDA/DG/readme | 73 + benchmarks/CUDA/DG/src/BuildMaps2d.c | 231 + benchmarks/CUDA/DG/src/BuildMaps3d.c | 279 + benchmarks/CUDA/DG/src/FacePair2d.c | 154 + benchmarks/CUDA/DG/src/FacePair3d.c | 201 + benchmarks/CUDA/DG/src/InitCPU3d.c | 152 + benchmarks/CUDA/DG/src/LoadBalance3d.c | 243 + benchmarks/CUDA/DG/src/MaxwellsDriver3d.c | 110 + benchmarks/CUDA/DG/src/MaxwellsKernel3d.cu | 551 ++ benchmarks/CUDA/DG/src/MaxwellsMPI3d.c | 71 + benchmarks/CUDA/DG/src/MaxwellsRHS3d.c | 220 + benchmarks/CUDA/DG/src/MaxwellsRun3d.c | 60 + benchmarks/CUDA/DG/src/Mesh3d.c | 195 + benchmarks/CUDA/DG/src/ParallelPairs.c | 124 + benchmarks/CUDA/DG/src/StartUp3d.c | 123 + benchmarks/CUDA/DG/src/Utils.c | 155 + benchmarks/CUDA/DG/src/buildsource.m | 106 + benchmarks/CUDA/DG/src/gpuDG.vpj | 173 + benchmarks/CUDA/DG/src/tictoc.cu | 23 + 195 files changed, 82531 insertions(+) create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/CHANGES create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/COPYRIGHT create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Graphs/README create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/INSTALL create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/Makefile create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_checkgraph.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_memory.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_mfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_mrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_parmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_stats.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/balance.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/bucketsort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/ccgraph.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/checkgraph.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/coarsen.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/compress.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/debug.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/defs.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/estmem.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fortran.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/frename.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/initpart.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kvmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/macros.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/match.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mbalance.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mbalance2.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mcoarsen.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/memory.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mesh.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/meshpart.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/metis.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm2.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/minitpart.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/minitpart2.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayfmh.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmatch.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mpmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine2.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mutil.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/myqsort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/ometis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/parmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pqueue.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/proto.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/refine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/rename.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/separator.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/sfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/srefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stat.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stats.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stdheaders.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/struct.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/subdomains.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/timing.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/util.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.in create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.osx create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.rtc create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.pdf create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.ps create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/Makefile create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/adrivers.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/akwayfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ametis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/backcompat.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/balancemylink.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/coarsen.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/comm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/csrmatch.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/debug.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/defs.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/diffutil.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/fpqueue.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/frename.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/gkmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/grsetup.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iidxsort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iintsort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeysort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeyvalsort.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initbalance.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initmsection.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initpart.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwaybalance.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayfm.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayrefine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/lmatch.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/macros.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/match.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdiffusion.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdrivers.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/memory.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mesh.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/move.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/msetup.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/node_refine.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ometis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/order.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/parmetislib.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/proto.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/pspases.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/redomylink.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/remap.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rename.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rmetis.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/selectq.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/serial.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/setup.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stat.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stdheaders.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/struct.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/sync create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/timer.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/util.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/wave.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/weird.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/xyzpart.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/Makefile create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/adaptgraph.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/io.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/mtest.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/parmetisbin.h create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/ptest.c create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/README create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/VERSION create mode 100644 benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/parmetis.h create mode 100644 benchmarks/CUDA/DG/Makefile create mode 100644 benchmarks/CUDA/DG/MakefileCPU2d create mode 100644 benchmarks/CUDA/DG/MakefileGPU2d create mode 100644 benchmarks/CUDA/DG/Makefiles/Makefile create mode 100644 benchmarks/CUDA/DG/Makefiles/MakefileCPU3d create mode 100644 benchmarks/CUDA/DG/Makefiles/MakefileGPU3d create mode 100644 benchmarks/CUDA/DG/Meshes/F072.neu create mode 100644 benchmarks/CUDA/DG/Meshes/FS_K01022.neu create mode 100755 benchmarks/CUDA/DG/Meshes/block2.neu create mode 100644 benchmarks/CUDA/DG/Meshes/block3.neu create mode 100644 benchmarks/CUDA/DG/Meshes/cubeK268.neu create mode 100644 benchmarks/CUDA/DG/README.GPGPU-Sim create mode 100644 benchmarks/CUDA/DG/buildsource.m create mode 100644 benchmarks/CUDA/DG/data/F072.neu create mode 100644 benchmarks/CUDA/DG/data/FS_K01022.neu create mode 100755 benchmarks/CUDA/DG/data/block2.neu create mode 100644 benchmarks/CUDA/DG/data/block3.neu create mode 100644 benchmarks/CUDA/DG/data/cubeK268.neu create mode 100644 benchmarks/CUDA/DG/include/Mesh.h create mode 100644 benchmarks/CUDA/DG/include/data3dN06.h create mode 100644 benchmarks/CUDA/DG/include/defs.h create mode 100644 benchmarks/CUDA/DG/include/fem.h create mode 100644 benchmarks/CUDA/DG/include/macros.h create mode 100644 benchmarks/CUDA/DG/include/parmetis.h create mode 100644 benchmarks/CUDA/DG/include/parmetisbin.h create mode 100644 benchmarks/CUDA/DG/include/proto.h create mode 100644 benchmarks/CUDA/DG/include/rename.h create mode 100644 benchmarks/CUDA/DG/include/stdheaders.h create mode 100644 benchmarks/CUDA/DG/include/struct.h create mode 100644 benchmarks/CUDA/DG/license.midg create mode 100644 benchmarks/CUDA/DG/readme create mode 100644 benchmarks/CUDA/DG/src/BuildMaps2d.c create mode 100644 benchmarks/CUDA/DG/src/BuildMaps3d.c create mode 100644 benchmarks/CUDA/DG/src/FacePair2d.c create mode 100644 benchmarks/CUDA/DG/src/FacePair3d.c create mode 100644 benchmarks/CUDA/DG/src/InitCPU3d.c create mode 100644 benchmarks/CUDA/DG/src/LoadBalance3d.c create mode 100644 benchmarks/CUDA/DG/src/MaxwellsDriver3d.c create mode 100644 benchmarks/CUDA/DG/src/MaxwellsKernel3d.cu create mode 100644 benchmarks/CUDA/DG/src/MaxwellsMPI3d.c create mode 100644 benchmarks/CUDA/DG/src/MaxwellsRHS3d.c create mode 100644 benchmarks/CUDA/DG/src/MaxwellsRun3d.c create mode 100644 benchmarks/CUDA/DG/src/Mesh3d.c create mode 100644 benchmarks/CUDA/DG/src/ParallelPairs.c create mode 100644 benchmarks/CUDA/DG/src/StartUp3d.c create mode 100644 benchmarks/CUDA/DG/src/Utils.c create mode 100644 benchmarks/CUDA/DG/src/buildsource.m create mode 100644 benchmarks/CUDA/DG/src/gpuDG.vpj create mode 100644 benchmarks/CUDA/DG/src/tictoc.cu (limited to 'benchmarks/CUDA/DG') diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/CHANGES b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/CHANGES new file mode 100644 index 0000000..1b1e6d0 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/CHANGES @@ -0,0 +1,144 @@ + +Changes in version 3.1 +- The mesh partitioning and dual creation routines have changed to support mixed + element meshes. + +- The parmetis.h header file has been restructured and is now C++ friendly. + +- Fortran bindings/renamings for various routines have been added. + +- A number of bugs have been fixed. + - tpwgts are now respected for small graphs. + - fixed various divide by zero errors. + - removed dependency on the old drand48() routines. + - fixed some memory leaks. + + + +Changes in version 3.0 + +- The names and calling sequence of all the routines have changed due to expanded + functionality that has been provided in this release. However, the 2.0 API calls + have been mapped to the new routines. However, the expanded functionality provided + with this release is only available by using the new calling sequences. + +- The four adaptive repartitioning routines: + ParMETIS_RepartLDiffusion, + ParMETIS_RepartGDiffusion, + ParMETIS_RepartRemap, and + ParMETIS_RepartMLRemap, + have been replaced by a single routine called ParMETIS_V3_AdpativeRepart that + implements a unified repartitioning algorithm which combines the best features + of the previous routines. + +- Multiple vertex weights/balance constraints are supported for most of the + routines. This allows ParMETIS to be used to partition graphs for multi-phase + and multi-physics simulations. + +- In order to optimize partitionings for specific heterogeneous computing + architectures, it is now possible to specify the target sub-domain weights + for each of the sub-domains and for each balance constraint. This feature, + for example, allows the user to compute a partitioning in which one of the + sub-domains is twice the size of all of the others. + +- The number of sub-domains has been de-coupled from the number of processors + in both the static and the adaptive partitioning schemes. Hence, it is now + possible to use the parallel partitioning and repartitioning algorithms + to compute a k-way partitioning independent of the number of processors + that are used. Note that Version 2.0 provided this functionality for the + static partitioning schemes only. + +- Routines are provided for both directly partitioning a finite element mesh, + and for constructing the dual graph of a mesh in parallel. + + + +Changes in version 2.0 + +- Changed the names and calling sequences of all the routines to make it + easier to use ParMETIS with Fortran. + +- Improved the performance of the diffusive adaptive repartitioning + algorithms. + +- Added a new set of adaptive repartitioning routines that are based on the + remapping paradigm. These routines are called ParMETIS_RepartRemap and + ParMETIS_RepartMLRemap + +- The number of partitions has been de-coupled from the number of processors. + You can now use the parallel partitioning algorithms to compute a k-way + partitioning independent of the number of processors that you use. + +- The partitioning and ordering algorithms in ParMETIS now utilize various + portions of the serial METIS library. As a result of this, the quality + of the produced partitionings and orderings have been improved. + Remember to link your code with both libmetis.a and libparmetis.a + + +Changes in version 1.0 + +- Added partitioning routines that take advantage of coordinate information. + These routines are based on space-filling curves and they are used to + quickly compute a initial distribution for PARKMETIS. + A total of three routines have been added called PARGKMETIS, PARGRMETIS, + and PARGMETIS + +- Added a fill-reducing ordering routine that is based on multilevel nested + dissection. This is similar to the ordering routine in the serial Metis + with the difference that is directly computes and refines vertex + separators. The new routine is called PAROMETIS and returns the new ordering + of the local nodes plus a vector describing the sizes of the various + separators that form the elimination tree. + +- Changed the calling sequence again! I found it awkward to require that + communicators and other scalar quantities being passed by reference. + +- Fixed a number of memory leaks. + + + +Changes in version 0.3 + +- Incorporated parallel multilevel diffusion algorithms for repartitioning + adaptively refined meshes. Two routines have been added for this purpose: + PARUAMETIS that performs undirected multilevel diffusion + PARDAMETIS that performs directed multilevel diffusion + +- Changed the names and calling sequences of the parallel partitioning + and refinement algorithms. Now they are called PARKMETIS for the + k-way partitioning and PARRMETIS for the k-way refinement. + Also the calling sequence has been changed slightly to make ParMETIS + Fortran callable. + +- Added an additional option for selecting the algorithm for initial + partitioning at the coarsest graph. Now you have the choice of selecting + either a serial or a parallel algorithm. The parallel initial partitioning + speeds up the algorithm especially for large number of processors. + NOTE that the parallel initial partitioning works only for partitions that + are power of two. If you want partitions that are not power of two you must + use the old serial initial partitioning option. + +- Fixed some bugs in the initial partitioning code. + +- Made parallel k-way refinement more robust by randomly ordering the + processors at each phase + + +Changes in version 0.2 + +- A complete reworking of the primary algorithms. The performance + of the code has improved considerably. Over 30% on 128 processor + Cray T3D. Improvement should be higher on machines with high + latencies. + + Here are some performance numbers on T3D using Cray's MPI + for 2 graphs, mdual (0.25M vertices) and mdual2 (1.0M vertices) + + 16PEs 32PEs 64PEs 128PEs + mdual 4.07 2.97 2.82 + mdual2 15.02 8.89 6.12 5.75 + +- The quality of the produced partitions has been improved. +- Added options[2] to specify C or Fortran style numbering. + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/COPYRIGHT b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/COPYRIGHT new file mode 100644 index 0000000..e6cdd3b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/COPYRIGHT @@ -0,0 +1,19 @@ +Copyright Notice +---------------- + +The ParMETIS/METIS package is copyrighted by the Regents of the +University of Minnesota. It can be freely used for educational and +research purposes by non-profit institutions and US government agencies +only. Other organizations are allowed to use ParMETIS/METIS only for +evaluation purposes, and any further uses will require prior approval. +The software may not be sold or redistributed without prior approval. +One may make copies of the software for their use provided that the +copies, are not sold or distributed, are used under the same terms +and conditions. + +As unestablished research software, this code is provided on an +``as is'' basis without warranty of any kind, either expressed or +implied. The downloading, or executing any part of this software +constitutes an implicit agreement to these terms. These terms and +conditions are subject to change at any time without prior notice. + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Graphs/README b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Graphs/README new file mode 100644 index 0000000..afa7e16 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Graphs/README @@ -0,0 +1 @@ +../Programs/Makefile craps out if it can't find this directory, so this dummy file is in perforce to make sure directory is added -GY diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/INSTALL b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/INSTALL new file mode 100644 index 0000000..8af32a4 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/INSTALL @@ -0,0 +1,1961 @@ + +INSTALLATION +------------ + + To build ParMetis you need to edit the Makefile.in and set the appropriate + parameters for 'CC'. The default is to use mpicc from MPICH. + After that just type 'make' to build the libraries (libmetis.a and + libparmetis.a). + + The header file parmetis.h can be used to provided the prototypes for + the various routines in ParMetis. + + +TESTING THE LIBRARY +------------------- + + To test the library go to the directory Graphs and execute the program + 'ptest' that is in that directory. You can test the direct mesh partitioning + routines by using the program 'meshtest'. + Sample output of these two tests have been appended in this file. + + NOTE-1: You must have at least 256MB per node in order for the test + to go through. + + NOTE-2: The results on your machine will most likely look different + because of differences in the random number generators. + Look if the test programs reports any 'incorrect' results. + If the test goes through correctly, then you have compiled + ParMetis successfully! + + + + +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- +% mpirun -np 4 ptest rotor.graph + + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 8 + Setup: Max: 0.291, Sum: 0.789, Balance: 1.477 + Matching: Max: 0.618, Sum: 2.386, Balance: 1.035 +Contraction: Max: 0.522, Sum: 2.037, Balance: 1.026 + InitPart: Max: 0.044, Sum: 0.142, Balance: 1.248 + Project: Max: 0.024, Sum: 0.026, Balance: 3.641 + Initialize: Max: 0.212, Sum: 0.664, Balance: 1.275 + K-way: Max: 0.838, Sum: 3.210, Balance: 1.044 + Remap: Max: 0.000, Sum: -0.016, Balance: -0.021 + Total: Max: 2.476, Sum: 9.885, Balance: 1.002 +Final 8-way CUT: 14620 Balance: 1.049 avg: 1.049 +ParMETIS_V3_PartKway reported a cut of 14620 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 8 + Setup: Max: 0.244, Sum: 0.737, Balance: 1.325 + Matching: Max: 0.565, Sum: 2.201, Balance: 1.028 +Contraction: Max: 0.494, Sum: 1.967, Balance: 1.004 + InitPart: Max: 0.024, Sum: 0.089, Balance: 1.095 + Project: Max: 0.050, Sum: 0.127, Balance: 1.579 + Initialize: Max: 0.204, Sum: 0.708, Balance: 1.152 + K-way: Max: 0.783, Sum: 3.089, Balance: 1.014 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.213 + Total: Max: 2.361, Sum: 9.427, Balance: 1.002 +Final 8-way CUT: 15371 Balance: 1.046 avg: 1.046 +ParMETIS_V3_PartKway reported a cut of 15371 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 8 + Setup: Max: 0.216, Sum: 0.713, Balance: 1.212 + Matching: Max: 0.523, Sum: 2.042, Balance: 1.024 +Contraction: Max: 0.485, Sum: 1.909, Balance: 1.017 + InitPart: Max: 0.227, Sum: 0.902, Balance: 1.006 + Project: Max: 0.053, Sum: 0.141, Balance: 1.506 + Initialize: Max: 0.292, Sum: 1.058, Balance: 1.105 + K-way: Max: 0.858, Sum: 3.224, Balance: 1.065 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.016 + Total: Max: 2.601, Sum: 10.395, Balance: 1.001 +Final 8-way CUT: 24400 Balance: 1.047 1.044 1.046 avg: 1.046 +ParMETIS_V3_PartKway reported a cut of 24400 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 8 + Setup: Max: 0.224, Sum: 0.725, Balance: 1.234 + Matching: Max: 0.761, Sum: 3.014, Balance: 1.009 +Contraction: Max: 0.440, Sum: 1.732, Balance: 1.017 + InitPart: Max: 0.213, Sum: 0.847, Balance: 1.008 + Project: Max: 0.045, Sum: 0.072, Balance: 2.515 + Initialize: Max: 0.215, Sum: 0.673, Balance: 1.278 + K-way: Max: 0.857, Sum: 3.289, Balance: 1.042 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.010 + Total: Max: 2.696, Sum: 10.771, Balance: 1.001 +Final 8-way CUT: 23755 Balance: 1.050 1.047 1.048 avg: 1.048 +ParMETIS_V3_PartKway reported a cut of 23755 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 8 + Setup: Max: 0.258, Sum: 0.708, Balance: 1.455 + Matching: Max: 0.459, Sum: 1.797, Balance: 1.023 +Contraction: Max: 0.478, Sum: 1.841, Balance: 1.038 + InitPart: Max: 0.451, Sum: 1.800, Balance: 1.003 + Project: Max: 0.046, Sum: 0.123, Balance: 1.487 + Initialize: Max: 0.199, Sum: 0.699, Balance: 1.138 + K-way: Max: 0.854, Sum: 3.387, Balance: 1.009 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.039 + Total: Max: 2.725, Sum: 10.881, Balance: 1.002 +Final 8-way CUT: 25897 Balance: 1.049 1.050 1.044 1.047 1.049 avg: 1.048 +ParMETIS_V3_PartKway reported a cut of 25897 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 8 + Setup: Max: 0.225, Sum: 0.718, Balance: 1.255 + Matching: Max: 0.601, Sum: 2.350, Balance: 1.022 +Contraction: Max: 0.480, Sum: 1.885, Balance: 1.019 + InitPart: Max: 0.493, Sum: 1.967, Balance: 1.004 + Project: Max: 0.045, Sum: 0.150, Balance: 1.211 + Initialize: Max: 0.194, Sum: 0.648, Balance: 1.198 + K-way: Max: 0.857, Sum: 3.333, Balance: 1.029 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.016 + Total: Max: 2.869, Sum: 11.443, Balance: 1.003 +Final 8-way CUT: 26340 Balance: 1.049 1.043 1.044 1.050 1.050 avg: 1.047 +ParMETIS_V3_PartKway reported a cut of 26340 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 4 + Setup: Max: 0.284, Sum: 0.947, Balance: 1.198 + Matching: Max: 0.660, Sum: 2.609, Balance: 1.012 +Contraction: Max: 0.471, Sum: 1.824, Balance: 1.033 + InitPart: Max: 0.014, Sum: 0.054, Balance: 1.064 + Project: Max: 0.074, Sum: 0.183, Balance: 1.609 + Initialize: Max: 0.144, Sum: 0.491, Balance: 1.175 + K-way: Max: 0.785, Sum: 3.094, Balance: 1.014 + Remap: Max: 0.014, Sum: 0.050, Balance: 1.082 + Total: Max: 2.488, Sum: 9.937, Balance: 1.001 +Final 4-way CUT: 7782 Balance: 1.050 avg: 1.050 +ParMETIS_V3_PartKway reported a cut of 7782 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 4 + Setup: Max: 0.264, Sum: 0.883, Balance: 1.194 + Matching: Max: 0.574, Sum: 2.170, Balance: 1.057 +Contraction: Max: 0.459, Sum: 1.829, Balance: 1.004 + InitPart: Max: 0.016, Sum: 0.062, Balance: 1.060 + Project: Max: 0.048, Sum: 0.103, Balance: 1.884 + Initialize: Max: 0.148, Sum: 0.537, Balance: 1.106 + K-way: Max: 0.821, Sum: 3.186, Balance: 1.030 + Remap: Max: 0.010, Sum: 0.036, Balance: 1.138 + Total: Max: 2.348, Sum: 9.364, Balance: 1.003 +Final 4-way CUT: 8448 Balance: 1.034 avg: 1.034 +ParMETIS_V3_PartKway reported a cut of 8448 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 4 + Setup: Max: 0.278, Sum: 0.875, Balance: 1.269 + Matching: Max: 0.946, Sum: 3.670, Balance: 1.031 +Contraction: Max: 0.897, Sum: 3.577, Balance: 1.003 + InitPart: Max: 0.198, Sum: 0.790, Balance: 1.003 + Project: Max: 0.051, Sum: 0.174, Balance: 1.167 + Initialize: Max: 0.289, Sum: 1.127, Balance: 1.024 + K-way: Max: 1.475, Sum: 5.855, Balance: 1.008 + Remap: Max: 0.001, Sum: 0.001, Balance: 3.525 + Total: Max: 4.194, Sum: 16.766, Balance: 1.001 +Final 4-way CUT: 12108 Balance: 1.033 1.047 1.031 avg: 1.037 +ParMETIS_V3_PartKway reported a cut of 12108 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 4 + Setup: Max: 0.251, Sum: 0.797, Balance: 1.258 + Matching: Max: 0.669, Sum: 2.493, Balance: 1.074 +Contraction: Max: 0.601, Sum: 2.346, Balance: 1.025 + InitPart: Max: 0.102, Sum: 0.407, Balance: 1.003 + Project: Max: 0.082, Sum: 0.220, Balance: 1.499 + Initialize: Max: 0.194, Sum: 0.729, Balance: 1.067 + K-way: Max: 0.869, Sum: 3.317, Balance: 1.048 + Remap: Max: 0.012, Sum: 0.043, Balance: 1.093 + Total: Max: 2.719, Sum: 10.868, Balance: 1.001 +Final 4-way CUT: 13048 Balance: 1.049 1.048 1.035 avg: 1.044 +ParMETIS_V3_PartKway reported a cut of 13048 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 4 + Setup: Max: 0.251, Sum: 0.724, Balance: 1.388 + Matching: Max: 0.628, Sum: 2.416, Balance: 1.040 +Contraction: Max: 0.474, Sum: 1.887, Balance: 1.005 + InitPart: Max: 0.161, Sum: 0.637, Balance: 1.009 + Project: Max: 0.081, Sum: 0.236, Balance: 1.376 + Initialize: Max: 0.241, Sum: 0.789, Balance: 1.223 + K-way: Max: 1.024, Sum: 3.929, Balance: 1.043 + Remap: Max: 0.012, Sum: 0.044, Balance: 1.079 + Total: Max: 2.794, Sum: 11.162, Balance: 1.001 +Final 4-way CUT: 14978 Balance: 1.043 1.037 1.042 1.025 1.030 avg: 1.035 +ParMETIS_V3_PartKway reported a cut of 14978 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 4 + Setup: Max: 0.298, Sum: 0.779, Balance: 1.529 + Matching: Max: 0.652, Sum: 2.570, Balance: 1.015 +Contraction: Max: 0.699, Sum: 2.778, Balance: 1.007 + InitPart: Max: 0.164, Sum: 0.652, Balance: 1.005 + Project: Max: 0.056, Sum: 0.133, Balance: 1.682 + Initialize: Max: 0.202, Sum: 0.704, Balance: 1.145 + K-way: Max: 0.820, Sum: 3.143, Balance: 1.043 + Remap: Max: 0.012, Sum: 0.044, Balance: 1.063 + Total: Max: 2.855, Sum: 11.407, Balance: 1.001 +Final 4-way CUT: 14768 Balance: 1.017 1.028 1.018 1.027 1.035 avg: 1.025 +ParMETIS_V3_PartKway reported a cut of 14768 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 2 + Setup: Max: 0.251, Sum: 0.813, Balance: 1.237 + Matching: Max: 0.631, Sum: 2.385, Balance: 1.059 +Contraction: Max: 0.443, Sum: 1.757, Balance: 1.008 + InitPart: Max: 0.023, Sum: 0.086, Balance: 1.051 + Project: Max: 0.061, Sum: 0.190, Balance: 1.287 + Initialize: Max: 0.140, Sum: 0.483, Balance: 1.162 + K-way: Max: 0.618, Sum: 2.374, Balance: 1.042 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.022 + Total: Max: 2.195, Sum: 8.766, Balance: 1.001 +Final 2-way CUT: 2314 Balance: 1.048 avg: 1.048 +ParMETIS_V3_PartKway reported a cut of 2314 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 2 + Setup: Max: 0.247, Sum: 0.727, Balance: 1.362 + Matching: Max: 0.573, Sum: 2.272, Balance: 1.008 +Contraction: Max: 0.502, Sum: 1.982, Balance: 1.012 + InitPart: Max: 0.010, Sum: 0.037, Balance: 1.077 + Project: Max: 0.040, Sum: 0.149, Balance: 1.062 + Initialize: Max: 0.141, Sum: 0.527, Balance: 1.067 + K-way: Max: 0.612, Sum: 2.410, Balance: 1.015 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.078 + Total: Max: 2.150, Sum: 8.572, Balance: 1.003 +Final 2-way CUT: 2068 Balance: 1.047 avg: 1.047 +ParMETIS_V3_PartKway reported a cut of 2068 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 2 + Setup: Max: 0.268, Sum: 0.889, Balance: 1.204 + Matching: Max: 0.548, Sum: 2.108, Balance: 1.039 +Contraction: Max: 0.446, Sum: 1.775, Balance: 1.004 + InitPart: Max: 0.062, Sum: 0.243, Balance: 1.013 + Project: Max: 0.054, Sum: 0.156, Balance: 1.392 + Initialize: Max: 0.168, Sum: 0.574, Balance: 1.174 + K-way: Max: 0.791, Sum: 3.038, Balance: 1.042 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.032 + Total: Max: 2.358, Sum: 9.416, Balance: 1.002 +Final 2-way CUT: 6503 Balance: 1.028 1.035 1.041 avg: 1.035 +ParMETIS_V3_PartKway reported a cut of 6503 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 2 + Setup: Max: 0.200, Sum: 0.636, Balance: 1.258 + Matching: Max: 0.664, Sum: 2.539, Balance: 1.047 +Contraction: Max: 0.452, Sum: 1.783, Balance: 1.015 + InitPart: Max: 0.046, Sum: 0.182, Balance: 1.005 + Project: Max: 0.044, Sum: 0.129, Balance: 1.345 + Initialize: Max: 0.166, Sum: 0.558, Balance: 1.191 + K-way: Max: 0.704, Sum: 2.778, Balance: 1.014 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.013 + Total: Max: 2.317, Sum: 9.258, Balance: 1.001 +Final 2-way CUT: 5999 Balance: 1.013 1.018 1.044 avg: 1.025 +ParMETIS_V3_PartKway reported a cut of 5999 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 2 + Setup: Max: 0.209, Sum: 0.701, Balance: 1.190 + Matching: Max: 0.503, Sum: 1.942, Balance: 1.037 +Contraction: Max: 0.567, Sum: 2.220, Balance: 1.022 + InitPart: Max: 0.066, Sum: 0.262, Balance: 1.005 + Project: Max: 0.095, Sum: 0.257, Balance: 1.473 + Initialize: Max: 0.150, Sum: 0.501, Balance: 1.201 + K-way: Max: 0.652, Sum: 2.539, Balance: 1.027 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.084 + Total: Max: 2.220, Sum: 8.872, Balance: 1.001 +Final 2-way CUT: 2482 Balance: 1.020 1.021 1.018 1.020 1.022 avg: 1.020 +ParMETIS_V3_PartKway reported a cut of 2482 + +Testing ParMETIS_V3_PartKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 2 + Setup: Max: 0.286, Sum: 0.807, Balance: 1.416 + Matching: Max: 0.518, Sum: 1.977, Balance: 1.049 +Contraction: Max: 0.507, Sum: 1.978, Balance: 1.026 + InitPart: Max: 0.065, Sum: 0.254, Balance: 1.029 + Project: Max: 0.051, Sum: 0.112, Balance: 1.832 + Initialize: Max: 0.175, Sum: 0.502, Balance: 1.390 + K-way: Max: 0.721, Sum: 2.753, Balance: 1.048 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.022 + Total: Max: 2.233, Sum: 8.916, Balance: 1.002 +Final 2-way CUT: 2539 Balance: 1.005 1.005 1.006 1.006 1.005 avg: 1.005 +ParMETIS_V3_PartKway reported a cut of 2539 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 8 + Setup: Max: 0.190, Sum: 0.460, Balance: 1.651 + Total: Max: 3.549, Sum: 14.190, Balance: 1.000 +XYZ Cut: 417088 Balance: 1.000 [24905 99617 4] + Setup: Max: 4.012, Sum: 15.364, Balance: 1.044 + Matching: Max: 1.522, Sum: 6.034, Balance: 1.009 +Contraction: Max: 2.588, Sum: 10.293, Balance: 1.006 + InitPart: Max: 0.016, Sum: 0.063, Balance: 1.047 + Project: Max: 0.943, Sum: 1.055, Balance: 3.578 + Initialize: Max: 1.195, Sum: 3.759, Balance: 1.272 + K-way: Max: 0.857, Sum: 3.297, Balance: 1.040 + Move: Max: 2.255, Sum: 8.985, Balance: 1.004 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.058 + Total: Max: 13.646, Sum: 54.574, Balance: 1.000 +Final 8-way CUT: 15378 Balance: 1.049 avg: 1.049 +ParMETIS_V3_PartGeomKway reported a cut of 15378 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 8 + Setup: Max: 0.107, Sum: 0.336, Balance: 1.273 + Total: Max: 0.316, Sum: 1.259, Balance: 1.003 +XYZ Cut: 419906 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.957, Sum: 3.774, Balance: 1.014 + Matching: Max: 1.233, Sum: 4.857, Balance: 1.015 +Contraction: Max: 2.783, Sum: 11.127, Balance: 1.000 + InitPart: Max: 0.018, Sum: 0.069, Balance: 1.033 + Project: Max: 0.170, Sum: 0.235, Balance: 2.883 + Initialize: Max: 0.443, Sum: 1.365, Balance: 1.297 + K-way: Max: 0.818, Sum: 3.127, Balance: 1.047 + Move: Max: 9.035, Sum: 36.117, Balance: 1.001 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.030 + Total: Max: 6.582, Sum: 26.301, Balance: 1.001 +Final 8-way CUT: 14413 Balance: 1.046 avg: 1.046 +ParMETIS_V3_PartGeomKway reported a cut of 14413 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 8 + Setup: Max: 0.147, Sum: 0.488, Balance: 1.205 + Total: Max: 0.299, Sum: 1.192, Balance: 1.005 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.936, Sum: 3.241, Balance: 1.155 + Matching: Max: 0.680, Sum: 2.642, Balance: 1.030 +Contraction: Max: 1.163, Sum: 4.652, Balance: 1.000 + InitPart: Max: 0.234, Sum: 0.935, Balance: 1.002 + Project: Max: 0.079, Sum: 0.169, Balance: 1.874 + Initialize: Max: 0.270, Sum: 0.983, Balance: 1.100 + K-way: Max: 0.868, Sum: 3.287, Balance: 1.056 + Move: Max: 3.337, Sum: 13.333, Balance: 1.001 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.022 + Total: Max: 4.428, Sum: 17.694, Balance: 1.001 +Final 8-way CUT: 23489 Balance: 1.046 1.047 1.050 avg: 1.048 +ParMETIS_V3_PartGeomKway reported a cut of 23489 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 8 + Setup: Max: 0.215, Sum: 0.671, Balance: 1.282 + Total: Max: 0.355, Sum: 1.418, Balance: 1.002 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.834, Sum: 2.604, Balance: 1.282 + Matching: Max: 0.780, Sum: 3.046, Balance: 1.025 +Contraction: Max: 1.036, Sum: 4.131, Balance: 1.003 + InitPart: Max: 0.221, Sum: 0.884, Balance: 1.002 + Project: Max: 0.078, Sum: 0.204, Balance: 1.523 + Initialize: Max: 0.355, Sum: 1.265, Balance: 1.123 + K-way: Max: 0.870, Sum: 3.364, Balance: 1.035 + Move: Max: 1.618, Sum: 6.456, Balance: 1.002 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.043 + Total: Max: 4.332, Sum: 17.312, Balance: 1.001 +Final 8-way CUT: 23546 Balance: 1.048 1.045 1.043 avg: 1.045 +ParMETIS_V3_PartGeomKway reported a cut of 23546 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 8 + Setup: Max: 0.168, Sum: 0.486, Balance: 1.382 + Total: Max: 0.298, Sum: 1.187, Balance: 1.003 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.704, Sum: 2.160, Balance: 1.303 + Matching: Max: 0.569, Sum: 2.209, Balance: 1.031 +Contraction: Max: 1.035, Sum: 4.134, Balance: 1.001 + InitPart: Max: 0.335, Sum: 1.338, Balance: 1.002 + Project: Max: 0.073, Sum: 0.195, Balance: 1.506 + Initialize: Max: 0.303, Sum: 1.071, Balance: 1.131 + K-way: Max: 0.933, Sum: 3.528, Balance: 1.058 + Move: Max: 1.039, Sum: 4.124, Balance: 1.008 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.049 + Total: Max: 4.035, Sum: 16.114, Balance: 1.002 +Final 8-way CUT: 28349 Balance: 1.048 1.041 1.046 1.050 1.047 avg: 1.046 +ParMETIS_V3_PartGeomKway reported a cut of 28349 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 8 + Setup: Max: 0.102, Sum: 0.312, Balance: 1.309 + Total: Max: 0.193, Sum: 0.770, Balance: 1.005 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.574, Sum: 1.851, Balance: 1.241 + Matching: Max: 0.500, Sum: 1.935, Balance: 1.034 +Contraction: Max: 0.658, Sum: 2.614, Balance: 1.007 + InitPart: Max: 0.326, Sum: 1.300, Balance: 1.001 + Project: Max: 0.048, Sum: 0.157, Balance: 1.209 + Initialize: Max: 0.266, Sum: 0.931, Balance: 1.144 + K-way: Max: 0.903, Sum: 3.442, Balance: 1.049 + Move: Max: 0.580, Sum: 2.295, Balance: 1.011 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.028 + Total: Max: 3.401, Sum: 13.572, Balance: 1.002 +Final 8-way CUT: 27483 Balance: 1.044 1.050 1.037 1.045 1.045 avg: 1.044 +ParMETIS_V3_PartGeomKway reported a cut of 27483 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 4 + Setup: Max: 0.100, Sum: 0.298, Balance: 1.343 + Total: Max: 0.194, Sum: 0.738, Balance: 1.051 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.596, Sum: 1.766, Balance: 1.350 + Matching: Max: 0.555, Sum: 2.169, Balance: 1.023 +Contraction: Max: 0.641, Sum: 2.517, Balance: 1.018 + InitPart: Max: 0.014, Sum: 0.054, Balance: 1.036 + Project: Max: 0.080, Sum: 0.181, Balance: 1.775 + Initialize: Max: 0.236, Sum: 0.704, Balance: 1.339 + K-way: Max: 0.766, Sum: 2.940, Balance: 1.042 + Move: Max: 0.262, Sum: 1.031, Balance: 1.018 + Remap: Max: -0.006, Sum: -0.027, Balance: 0.973 + Total: Max: 2.949, Sum: 11.769, Balance: 1.002 +Final 4-way CUT: 8815 Balance: 1.028 avg: 1.028 +ParMETIS_V3_PartGeomKway reported a cut of 8815 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 4 + Setup: Max: 0.181, Sum: 0.472, Balance: 1.531 + Total: Max: 0.283, Sum: 1.133, Balance: 1.001 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.655, Sum: 1.957, Balance: 1.338 + Matching: Max: 0.629, Sum: 2.387, Balance: 1.054 +Contraction: Max: 0.618, Sum: 2.438, Balance: 1.013 + InitPart: Max: 0.026, Sum: 0.102, Balance: 1.019 + Project: Max: 0.074, Sum: 0.198, Balance: 1.500 + Initialize: Max: 0.205, Sum: 0.733, Balance: 1.117 + K-way: Max: 0.839, Sum: 3.283, Balance: 1.022 + Move: Max: 1.827, Sum: 7.270, Balance: 1.005 + Remap: Max: 0.012, Sum: 0.048, Balance: 1.034 + Total: Max: 3.226, Sum: 12.876, Balance: 1.002 +Final 4-way CUT: 8442 Balance: 1.046 avg: 1.046 +ParMETIS_V3_PartGeomKway reported a cut of 8442 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 4 + Setup: Max: 0.160, Sum: 0.513, Balance: 1.247 + Total: Max: 0.299, Sum: 1.194, Balance: 1.001 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.648, Sum: 2.097, Balance: 1.235 + Matching: Max: 0.507, Sum: 2.008, Balance: 1.010 +Contraction: Max: 0.647, Sum: 2.541, Balance: 1.019 + InitPart: Max: 0.104, Sum: 0.416, Balance: 1.004 + Project: Max: 0.047, Sum: 0.033, Balance: 5.662 + Initialize: Max: 0.268, Sum: 0.862, Balance: 1.244 + K-way: Max: 0.851, Sum: 3.172, Balance: 1.074 + Move: Max: 0.940, Sum: 3.739, Balance: 1.005 + Remap: Max: -0.002, Sum: -0.008, Balance: 0.964 + Total: Max: 3.187, Sum: 12.722, Balance: 1.002 +Final 4-way CUT: 12726 Balance: 1.035 1.019 1.039 avg: 1.031 +ParMETIS_V3_PartGeomKway reported a cut of 12726 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 4 + Setup: Max: 0.105, Sum: 0.288, Balance: 1.451 + Total: Max: 0.184, Sum: 0.733, Balance: 1.003 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.574, Sum: 1.709, Balance: 1.345 + Matching: Max: 0.565, Sum: 2.180, Balance: 1.037 +Contraction: Max: 0.765, Sum: 3.044, Balance: 1.005 + InitPart: Max: 0.105, Sum: 0.417, Balance: 1.005 + Project: Max: 0.086, Sum: 0.217, Balance: 1.593 + Initialize: Max: 0.288, Sum: 0.906, Balance: 1.271 + K-way: Max: 0.798, Sum: 3.034, Balance: 1.052 + Move: Max: 0.767, Sum: 3.042, Balance: 1.009 + Remap: Max: 0.010, Sum: 0.040, Balance: 1.016 + Total: Max: 3.240, Sum: 12.933, Balance: 1.002 +Final 4-way CUT: 14695 Balance: 1.034 1.012 1.018 avg: 1.021 +ParMETIS_V3_PartGeomKway reported a cut of 14695 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 4 + Setup: Max: 0.113, Sum: 0.268, Balance: 1.688 + Total: Max: 0.188, Sum: 0.749, Balance: 1.002 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.703, Sum: 1.983, Balance: 1.418 + Matching: Max: 0.620, Sum: 2.423, Balance: 1.023 +Contraction: Max: 0.669, Sum: 2.631, Balance: 1.017 + InitPart: Max: 0.169, Sum: 0.675, Balance: 1.004 + Project: Max: 0.057, Sum: 0.129, Balance: 1.770 + Initialize: Max: 0.251, Sum: 0.842, Balance: 1.190 + K-way: Max: 0.867, Sum: 3.321, Balance: 1.044 + Move: Max: 0.330, Sum: 1.303, Balance: 1.015 + Remap: Max: -0.004, Sum: -0.017, Balance: 0.879 + Total: Max: 3.364, Sum: 13.428, Balance: 1.002 +Final 4-way CUT: 14470 Balance: 1.045 1.031 1.032 1.041 1.034 avg: 1.037 +ParMETIS_V3_PartGeomKway reported a cut of 14470 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 4 + Setup: Max: 0.159, Sum: 0.354, Balance: 1.803 + Total: Max: 0.254, Sum: 1.015, Balance: 1.002 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.722, Sum: 2.256, Balance: 1.280 + Matching: Max: 0.640, Sum: 2.453, Balance: 1.043 +Contraction: Max: 0.803, Sum: 3.153, Balance: 1.019 + InitPart: Max: 0.147, Sum: 0.586, Balance: 1.003 + Project: Max: 0.065, Sum: 0.111, Balance: 2.346 + Initialize: Max: 0.231, Sum: 0.822, Balance: 1.125 + K-way: Max: 0.888, Sum: 3.417, Balance: 1.039 + Move: Max: 1.576, Sum: 6.284, Balance: 1.003 + Remap: Max: 0.013, Sum: 0.052, Balance: 1.011 + Total: Max: 3.636, Sum: 14.520, Balance: 1.002 +Final 4-way CUT: 13886 Balance: 1.039 1.044 1.030 1.040 1.013 avg: 1.033 +ParMETIS_V3_PartGeomKway reported a cut of 13886 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 1, Nparts: 2 + Setup: Max: 0.140, Sum: 0.409, Balance: 1.370 + Total: Max: 0.225, Sum: 0.894, Balance: 1.008 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.634, Sum: 1.852, Balance: 1.369 + Matching: Max: 0.560, Sum: 2.169, Balance: 1.033 +Contraction: Max: 0.652, Sum: 2.573, Balance: 1.014 + InitPart: Max: 0.016, Sum: 0.061, Balance: 1.027 + Project: Max: 0.049, Sum: 0.150, Balance: 1.301 + Initialize: Max: 0.205, Sum: 0.693, Balance: 1.183 + K-way: Max: 0.627, Sum: 2.386, Balance: 1.051 + Move: Max: 0.755, Sum: 3.006, Balance: 1.004 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.018 + Total: Max: 2.863, Sum: 11.433, Balance: 1.001 +Final 2-way CUT: 2511 Balance: 1.019 avg: 1.019 +ParMETIS_V3_PartGeomKway reported a cut of 2511 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 1, Nparts: 2 + Setup: Max: 0.271, Sum: 0.682, Balance: 1.588 + Total: Max: 0.340, Sum: 1.358, Balance: 1.001 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.745, Sum: 2.226, Balance: 1.339 + Matching: Max: 0.625, Sum: 2.355, Balance: 1.062 +Contraction: Max: 0.701, Sum: 2.619, Balance: 1.071 + InitPart: Max: 0.018, Sum: 0.071, Balance: 1.030 + Project: Max: 0.134, Sum: 0.313, Balance: 1.713 + Initialize: Max: 0.264, Sum: 0.893, Balance: 1.184 + K-way: Max: 1.009, Sum: 3.929, Balance: 1.028 + Move: Max: 2.843, Sum: 11.330, Balance: 1.004 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.019 + Total: Max: 3.507, Sum: 13.989, Balance: 1.003 +Final 2-way CUT: 2964 Balance: 1.000 avg: 1.000 +ParMETIS_V3_PartGeomKway reported a cut of 2964 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 3, Nparts: 2 + Setup: Max: 0.113, Sum: 0.373, Balance: 1.213 + Total: Max: 0.209, Sum: 0.835, Balance: 1.002 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.706, Sum: 2.162, Balance: 1.305 + Matching: Max: 0.603, Sum: 2.342, Balance: 1.030 +Contraction: Max: 0.645, Sum: 2.574, Balance: 1.003 + InitPart: Max: 0.053, Sum: 0.209, Balance: 1.012 + Project: Max: 0.056, Sum: 0.056, Balance: 4.037 + Initialize: Max: 0.229, Sum: 0.770, Balance: 1.192 + K-way: Max: 0.828, Sum: 3.080, Balance: 1.075 + Move: Max: 0.656, Sum: 2.568, Balance: 1.022 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.009 + Total: Max: 3.174, Sum: 12.646, Balance: 1.004 +Final 2-way CUT: 6395 Balance: 1.038 1.036 1.035 avg: 1.036 +ParMETIS_V3_PartGeomKway reported a cut of 6395 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 3, Nparts: 2 + Setup: Max: 0.214, Sum: 0.509, Balance: 1.683 + Total: Max: 0.324, Sum: 1.294, Balance: 1.001 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.682, Sum: 2.004, Balance: 1.362 + Matching: Max: 0.591, Sum: 2.258, Balance: 1.046 +Contraction: Max: 0.938, Sum: 3.709, Balance: 1.012 + InitPart: Max: 0.045, Sum: 0.178, Balance: 1.009 + Project: Max: 0.067, Sum: 0.183, Balance: 1.473 + Initialize: Max: 0.221, Sum: 0.762, Balance: 1.158 + K-way: Max: 0.764, Sum: 2.969, Balance: 1.030 + Move: Max: 0.710, Sum: 2.799, Balance: 1.015 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.018 + Total: Max: 3.443, Sum: 13.742, Balance: 1.002 +Final 2-way CUT: 6299 Balance: 1.003 1.003 1.004 avg: 1.003 +ParMETIS_V3_PartGeomKway reported a cut of 6299 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 1}, Ncon: 5, Nparts: 2 + Setup: Max: 0.134, Sum: 0.348, Balance: 1.539 + Total: Max: 0.221, Sum: 0.849, Balance: 1.039 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.600, Sum: 1.930, Balance: 1.243 + Matching: Max: 0.551, Sum: 2.096, Balance: 1.052 +Contraction: Max: 0.655, Sum: 2.576, Balance: 1.017 + InitPart: Max: 0.067, Sum: 0.268, Balance: 1.006 + Project: Max: 0.041, Sum: 0.048, Balance: 3.451 + Initialize: Max: 0.216, Sum: 0.684, Balance: 1.264 + K-way: Max: 0.702, Sum: 2.757, Balance: 1.018 + Move: Max: 0.803, Sum: 3.178, Balance: 1.010 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.024 + Total: Max: 2.977, Sum: 11.877, Balance: 1.003 +Final 2-way CUT: 2626 Balance: 1.022 1.029 1.029 1.030 1.038 avg: 1.029 +ParMETIS_V3_PartGeomKway reported a cut of 2626 + +Testing ParMETIS_V3_PartGeomKway with options[1-2] = {3 2}, Ncon: 5, Nparts: 2 + Setup: Max: 0.107, Sum: 0.263, Balance: 1.623 + Total: Max: 0.181, Sum: 0.723, Balance: 1.002 +XYZ Cut: 418507 Balance: 1.000 [24905 99617 4] + Setup: Max: 0.629, Sum: 1.818, Balance: 1.383 + Matching: Max: 0.567, Sum: 2.172, Balance: 1.044 +Contraction: Max: 0.663, Sum: 2.543, Balance: 1.043 + InitPart: Max: 0.066, Sum: 0.261, Balance: 1.006 + Project: Max: 0.051, Sum: 0.152, Balance: 1.341 + Initialize: Max: 0.166, Sum: 0.585, Balance: 1.137 + K-way: Max: 0.742, Sum: 2.856, Balance: 1.039 + Move: Max: 0.909, Sum: 3.611, Balance: 1.006 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.034 + Total: Max: 2.963, Sum: 11.818, Balance: 1.003 +Final 2-way CUT: 2423 Balance: 1.031 1.020 1.020 1.019 1.008 avg: 1.020 +ParMETIS_V3_PartGeomKway reported a cut of 2423 + +Testing ParMETIS_V3_PartGeom +ParMETIS_V3_PartGeom partition complete + +Testing ParMETIS_V3_RefineKway with default options (before move) + Setup: Max: 0.329, Sum: 0.914, Balance: 1.441 + Matching: Max: 0.247, Sum: 0.760, Balance: 1.301 +Contraction: Max: 0.345, Sum: 0.997, Balance: 1.383 + Project: Max: 0.011, Sum: 0.036, Balance: 1.200 + Initialize: Max: 0.302, Sum: 1.016, Balance: 1.189 + K-way: Max: 0.867, Sum: 3.290, Balance: 1.055 + Remap: Max: 0.010, Sum: 0.037, Balance: 1.112 + Total: Max: 2.032, Sum: 8.123, Balance: 1.001 +Final 4-way Cut: 20449 Balance: 1.050 +NMoved: 32025 11910 11068 22978 +ParMETIS_V3_RefineKway reported a cut of 20449 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 1 1}, Ncon: 1, Nparts: 4 + Setup: Max: 0.075, Sum: 0.233, Balance: 1.288 + Matching: Max: 0.163, Sum: 0.622, Balance: 1.048 +Contraction: Max: 0.274, Sum: 0.767, Balance: 1.427 + Project: Max: 0.007, Sum: -0.015, Balance: -1.810 + Initialize: Max: 0.201, Sum: 0.667, Balance: 1.204 + K-way: Max: 0.435, Sum: 1.594, Balance: 1.093 + Remap: Max: -0.001, Sum: -0.011, Balance: 0.255 + Total: Max: 1.135, Sum: 4.536, Balance: 1.001 +Final 4-way Cut: 9124 Balance: 1.046 +NMoved: 140 77 91 168 +ParMETIS_V3_RefineKway reported a cut of 9124 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 2 1}, Ncon: 1, Nparts: 4 + Setup: Max: 0.086, Sum: 0.274, Balance: 1.259 + Matching: Max: 0.089, Sum: 0.339, Balance: 1.048 +Contraction: Max: 0.338, Sum: 0.929, Balance: 1.456 + Project: Max: 0.007, Sum: 0.017, Balance: 1.758 + Initialize: Max: 0.191, Sum: 0.705, Balance: 1.083 + K-way: Max: 0.431, Sum: 1.635, Balance: 1.055 + Remap: Max: 0.010, Sum: 0.036, Balance: 1.156 + Total: Max: 1.167, Sum: 4.652, Balance: 1.003 +Final 4-way Cut: 9106 Balance: 1.045 +NMoved: 172 123 93 216 +ParMETIS_V3_RefineKway reported a cut of 9106 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 1 1}, Ncon: 3, Nparts: 4 + Setup: Max: 0.120, Sum: 0.315, Balance: 1.526 + Matching: Max: 0.179, Sum: 0.666, Balance: 1.074 +Contraction: Max: 0.260, Sum: 0.769, Balance: 1.353 + Project: Max: 0.010, Sum: 0.033, Balance: 1.255 + Initialize: Max: 0.137, Sum: 0.487, Balance: 1.123 + K-way: Max: 0.518, Sum: 1.964, Balance: 1.056 + Remap: Max: 0.013, Sum: 0.031, Balance: 1.670 + Total: Max: 1.273, Sum: 5.088, Balance: 1.001 +Final 4-way Cut: 9018 Balance: 1.043 1.043 1.043 +NMoved: 260 135 100 235 +ParMETIS_V3_RefineKway reported a cut of 9018 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 2 1}, Ncon: 3, Nparts: 4 + Setup: Max: 0.105, Sum: 0.347, Balance: 1.210 + Matching: Max: 0.213, Sum: 0.805, Balance: 1.058 +Contraction: Max: 0.310, Sum: 0.825, Balance: 1.504 + Project: Max: 0.009, Sum: -0.003, Balance: -12.691 + Initialize: Max: 0.135, Sum: 0.470, Balance: 1.150 + K-way: Max: 0.488, Sum: 1.774, Balance: 1.100 + Remap: Max: 0.011, Sum: 0.040, Balance: 1.107 + Total: Max: 1.304, Sum: 5.210, Balance: 1.001 +Final 4-way Cut: 9024 Balance: 1.043 1.043 1.043 +NMoved: 267 135 118 253 +ParMETIS_V3_RefineKway reported a cut of 9024 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 1 1}, Ncon: 5, Nparts: 4 + Setup: Max: 0.113, Sum: 0.333, Balance: 1.364 + Matching: Max: 0.252, Sum: 0.916, Balance: 1.102 +Contraction: Max: 0.328, Sum: 0.814, Balance: 1.614 + Project: Max: 0.009, Sum: 0.002, Balance: 21.632 + Initialize: Max: 0.142, Sum: 0.500, Balance: 1.140 + K-way: Max: 0.557, Sum: 2.030, Balance: 1.097 + Remap: Max: 0.010, Sum: 0.035, Balance: 1.098 + Total: Max: 1.365, Sum: 5.454, Balance: 1.001 +Final 4-way Cut: 9081 Balance: 1.046 1.046 1.046 1.046 1.046 +NMoved: 192 135 100 235 +ParMETIS_V3_RefineKway reported a cut of 9081 + +Testing ParMETIS_V3_RefineKway with options[1-3] = {3 2 1}, Ncon: 5, Nparts: 4 + Setup: Max: 0.148, Sum: 0.373, Balance: 1.583 + Matching: Max: 0.226, Sum: 0.836, Balance: 1.084 +Contraction: Max: 0.330, Sum: 0.852, Balance: 1.549 + Project: Max: 0.011, Sum: 0.019, Balance: 2.309 + Initialize: Max: 0.134, Sum: 0.472, Balance: 1.137 + K-way: Max: 0.555, Sum: 2.154, Balance: 1.031 + Remap: Max: -0.006, Sum: -0.028, Balance: 0.854 + Total: Max: 1.408, Sum: 5.630, Balance: 1.001 +Final 4-way Cut: 9090 Balance: 1.045 1.045 1.045 1.045 1.045 +NMoved: 200 138 121 259 +ParMETIS_V3_RefineKway reported a cut of 9090 +Initial Load Imbalance: 1.3148, [26344 47967 145931] for afactor: 4 +Initial Load Imbalance: 1.6407, [35080 135843 331187] for afactor: 4 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51520 769504 12144 13427][400] +[ 26858 411494 6350 6981][400] +[ 14060 218252 3344 3633][400] +[ 7404 115538 1780 1896][400] +[ 3912 60528 960 993][400] +[ 2101 31812 521 530][400] +[ 1146 16602 283 291][400] +[ 641 8632 157 167][400] +[ 365 4570 88 96][400] +nvtxs: 365, balance: 1.019 +nvtxs: 641, cut: 23753, balance: 1.050 +nvtxs: 1146, cut: 23103, balance: 1.052 +nvtxs: 2101, cut: 22312, balance: 1.049 +nvtxs: 3912, cut: 21159, balance: 1.050 +nvtxs: 7404, cut: 20171, balance: 1.050 +nvtxs: 14060, cut: 19304, balance: 1.050 +nvtxs: 26858, cut: 18461, balance: 1.050 +nvtxs: 51520, cut: 17456, balance: 1.050 +nvtxs: 99617, cut: 16161, balance: 1.050 + Setup: Max: 0.097, Sum: 0.252, Balance: 1.544 + Matching: Max: 0.281, Sum: 1.081, Balance: 1.040 +Contraction: Max: 0.457, Sum: 1.793, Balance: 1.020 + InitPart: Max: 0.032, Sum: 0.124, Balance: 1.049 + Project: Max: 0.022, Sum: 0.044, Balance: 2.022 + Initialize: Max: 0.177, Sum: 0.590, Balance: 1.200 + K-way: Max: 0.743, Sum: 2.885, Balance: 1.031 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.292 + Total: Max: 1.964, Sum: 7.851, Balance: 1.001 +Final 8-way Cut: 16161 Balance: 1.050 +NMoved: 27541 7332 7369 14701 +ParMETIS_V3_AdaptiveRepart reported a cut of 16161 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51526 769238 12122 13433][400] +[ 26833 410954 6315 6981][400] +[ 14029 218176 3309 3638][400] +[ 7393 115482 1741 1919][400] +[ 3925 60784 921 1014][400] +[ 2098 31932 494 538][400] +[ 1137 16642 269 292][400] +[ 627 8640 149 161][400] +[ 355 4468 85 90][400] +nvtxs: 355, balance: 1.017 +nvtxs: 627, cut: 24572, balance: 1.048 +nvtxs: 1137, cut: 23125, balance: 1.046 +nvtxs: 2098, cut: 22008, balance: 1.049 +nvtxs: 3925, cut: 21385, balance: 1.051 +nvtxs: 7393, cut: 20507, balance: 1.050 +nvtxs: 14029, cut: 19749, balance: 1.050 +nvtxs: 26833, cut: 18945, balance: 1.050 +nvtxs: 51526, cut: 18010, balance: 1.050 +nvtxs: 99617, cut: 16894, balance: 1.050 + Setup: Max: 0.068, Sum: 0.124, Balance: 2.194 + Matching: Max: 0.281, Sum: 1.063, Balance: 1.058 +Contraction: Max: 0.383, Sum: 1.522, Balance: 1.007 + InitPart: Max: 0.031, Sum: 0.092, Balance: 1.359 + Project: Max: 0.029, Sum: 0.092, Balance: 1.252 + Initialize: Max: 0.186, Sum: 0.633, Balance: 1.174 + K-way: Max: 0.743, Sum: 2.884, Balance: 1.031 + Remap: Max: 0.000, Sum: 0.001, Balance: 2.075 + Total: Max: 1.876, Sum: 7.499, Balance: 1.001 +Final 8-way Cut: 16894 Balance: 1.050 +NMoved: 20370 6382 6395 12777 +ParMETIS_V3_AdaptiveRepart reported a cut of 16894 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51520 769504 12144 13427][400] +[ 26858 411494 6350 6981][400] +[ 14060 218252 3344 3633][400] +[ 7404 115538 1780 1896][400] +[ 3912 60528 960 993][400] +[ 2101 31812 521 530][400] +[ 1146 16602 283 291][400] +[ 641 8632 157 167][400] +[ 365 4570 88 96][400] +nvtxs: 365, balance: 1.055 +nvtxs: 641, cut: 28724, balance: 1.049 +nvtxs: 1146, cut: 26926, balance: 1.050 +nvtxs: 2101, cut: 25830, balance: 1.050 +nvtxs: 3912, cut: 25333, balance: 1.050 +nvtxs: 7404, cut: 24637, balance: 1.051 +nvtxs: 14060, cut: 23627, balance: 1.050 +nvtxs: 26858, cut: 22880, balance: 1.050 +nvtxs: 51520, cut: 21888, balance: 1.050 +nvtxs: 99617, cut: 20532, balance: 1.050 + Setup: Max: 0.115, Sum: 0.290, Balance: 1.579 + Matching: Max: 0.268, Sum: 0.987, Balance: 1.084 +Contraction: Max: 0.369, Sum: 1.441, Balance: 1.025 + InitPart: Max: 0.034, Sum: 0.116, Balance: 1.177 + Project: Max: 0.023, Sum: 0.026, Balance: 3.561 + Initialize: Max: 0.210, Sum: 0.651, Balance: 1.289 + K-way: Max: 0.801, Sum: 2.982, Balance: 1.074 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.261 + Total: Max: 1.905, Sum: 7.612, Balance: 1.001 +Final 8-way Cut: 20532 Balance: 1.050 +NMoved: 12975 5875 4424 10299 +ParMETIS_V3_AdaptiveRepart reported a cut of 20532 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51526 769238 12122 13433][400] +[ 26833 410954 6315 6981][400] +[ 14029 218176 3309 3638][400] +[ 7393 115482 1741 1919][400] +[ 3925 60784 921 1014][400] +[ 2098 31932 494 538][400] +[ 1137 16642 269 292][400] +[ 627 8640 149 161][400] +[ 355 4468 85 90][400] +nvtxs: 355, balance: 1.078 +nvtxs: 627, cut: 26717, balance: 1.049 +nvtxs: 1137, cut: 25875, balance: 1.048 +nvtxs: 2098, cut: 23702, balance: 1.050 +nvtxs: 3925, cut: 22721, balance: 1.050 +nvtxs: 7393, cut: 21980, balance: 1.050 +nvtxs: 14029, cut: 20698, balance: 1.050 +nvtxs: 26833, cut: 19922, balance: 1.050 +nvtxs: 51526, cut: 19108, balance: 1.050 +nvtxs: 99617, cut: 18235, balance: 1.050 + Setup: Max: 0.124, Sum: 0.324, Balance: 1.526 + Matching: Max: 0.260, Sum: 0.971, Balance: 1.072 +Contraction: Max: 0.365, Sum: 1.433, Balance: 1.020 + InitPart: Max: 0.029, Sum: 0.073, Balance: 1.566 + Project: Max: 0.033, Sum: 0.060, Balance: 2.183 + Initialize: Max: 0.207, Sum: 0.664, Balance: 1.248 + K-way: Max: 0.717, Sum: 2.756, Balance: 1.040 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.367 + Total: Max: 1.862, Sum: 7.442, Balance: 1.001 +Final 8-way Cut: 18235 Balance: 1.050 +NMoved: 13188 5310 3945 9255 +ParMETIS_V3_AdaptiveRepart reported a cut of 18235 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51520 769504 12144 13427][400] +[ 26858 411494 6350 6981][400] +[ 14060 218252 3344 3633][400] +[ 7404 115538 1780 1896][400] +[ 3912 60528 960 993][400] +[ 2101 31812 521 530][400] +[ 1146 16602 283 291][400] +[ 641 8632 157 167][400] +[ 365 4570 88 96][400] +nvtxs: 365, balance: 1.055 +nvtxs: 641, cut: 35651, balance: 1.056 +nvtxs: 1146, cut: 35763, balance: 1.056 +nvtxs: 2101, cut: 35878, balance: 1.056 +nvtxs: 3912, cut: 35801, balance: 1.056 +nvtxs: 7404, cut: 35770, balance: 1.056 +nvtxs: 14060, cut: 35796, balance: 1.056 +nvtxs: 26858, cut: 35784, balance: 1.056 +nvtxs: 51520, cut: 35777, balance: 1.056 +nvtxs: 99617, cut: 35750, balance: 1.056 + Setup: Max: 0.096, Sum: 0.223, Balance: 1.714 + Matching: Max: 0.299, Sum: 1.111, Balance: 1.076 +Contraction: Max: 0.379, Sum: 1.483, Balance: 1.022 + InitPart: Max: 0.039, Sum: 0.150, Balance: 1.035 + Project: Max: 0.046, Sum: 0.091, Balance: 2.028 + Initialize: Max: 0.255, Sum: 0.704, Balance: 1.450 + K-way: Max: 0.694, Sum: 2.595, Balance: 1.070 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.424 + Total: Max: 1.841, Sum: 7.359, Balance: 1.000 +Final 8-way Cut: 35750 Balance: 1.056 +NMoved: 11612 4910 4255 9165 +ParMETIS_V3_AdaptiveRepart reported a cut of 35750 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 8 +[ 99617 1324862 23436 26023][400] +[ 51526 769238 12122 13433][400] +[ 26833 410954 6315 6981][400] +[ 14029 218176 3309 3638][400] +[ 7393 115482 1741 1919][400] +[ 3925 60784 921 1014][400] +[ 2098 31932 494 538][400] +[ 1137 16642 269 292][400] +[ 627 8640 149 161][400] +[ 355 4468 85 90][400] +nvtxs: 355, balance: 1.078 +nvtxs: 627, cut: 36167, balance: 1.077 +nvtxs: 1137, cut: 35876, balance: 1.077 +nvtxs: 2098, cut: 36252, balance: 1.071 +nvtxs: 3925, cut: 36197, balance: 1.071 +nvtxs: 7393, cut: 36104, balance: 1.071 +nvtxs: 14029, cut: 36147, balance: 1.071 +nvtxs: 26833, cut: 36042, balance: 1.070 +nvtxs: 51526, cut: 36100, balance: 1.070 +nvtxs: 99617, cut: 36211, balance: 1.069 + Setup: Max: 0.090, Sum: 0.285, Balance: 1.256 + Matching: Max: 0.284, Sum: 1.100, Balance: 1.031 +Contraction: Max: 0.366, Sum: 1.422, Balance: 1.030 + InitPart: Max: 0.035, Sum: 0.133, Balance: 1.044 + Project: Max: 0.032, Sum: 0.063, Balance: 2.018 + Initialize: Max: 0.244, Sum: 0.798, Balance: 1.225 + K-way: Max: 0.679, Sum: 2.596, Balance: 1.046 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.452 + Total: Max: 1.852, Sum: 7.379, Balance: 1.004 +Final 8-way Cut: 36211 Balance: 1.069 +NMoved: 11045 4330 3954 8284 +ParMETIS_V3_AdaptiveRepart reported a cut of 36211 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51520 769504 12144 13427][1200] +[ 26792 410272 6326 6969][1200] +[ 13981 216770 3319 3623][1200] +[ 7338 114436 1750 1897][1200] +[ 3870 60218 928 995][1200] +[ 2066 31410 500 530][1200] +[ 1120 16380 274 285][1200] +nvtxs: 1120, balance: 1.008 1.010 1.010 +nvtxs: 2066, cut: 36476, balance: 1.047 1.048 1.036 +nvtxs: 3870, cut: 34085, balance: 1.049 1.047 1.044 +nvtxs: 7338, cut: 31995, balance: 1.051 1.048 1.037 +nvtxs: 13981, cut: 30120, balance: 1.041 1.050 1.036 +nvtxs: 26792, cut: 28468, balance: 1.045 1.045 1.037 +nvtxs: 51520, cut: 26657, balance: 1.043 1.040 1.041 +nvtxs: 99617, cut: 24463, balance: 1.043 1.047 1.050 + Setup: Max: 0.096, Sum: 0.243, Balance: 1.577 + Matching: Max: 0.302, Sum: 1.147, Balance: 1.053 +Contraction: Max: 0.334, Sum: 1.315, Balance: 1.017 + InitPart: Max: 0.350, Sum: 1.393, Balance: 1.004 + Project: Max: 0.030, Sum: -0.007, Balance: -17.571 + Initialize: Max: 0.141, Sum: 0.503, Balance: 1.124 + K-way: Max: 0.824, Sum: 3.109, Balance: 1.060 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.408 + Total: Max: 2.216, Sum: 8.858, Balance: 1.001 +Final 8-way Cut: 24463 Balance: 1.043 1.047 1.050 +NMoved: 59087 8982 9669 18651 +ParMETIS_V3_AdaptiveRepart reported a cut of 24463 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51526 769238 12122 13433][1200] +[ 26780 409760 6306 6964][1200] +[ 13964 216890 3300 3618][1200] +[ 7324 114522 1749 1892][1200] +[ 3861 60152 931 996][1200] +[ 2067 31478 501 532][1200] +[ 1121 16376 274 285][1200] +nvtxs: 1121, balance: 1.007 1.008 1.014 +nvtxs: 2067, cut: 35458, balance: 1.049 1.045 1.038 +nvtxs: 3861, cut: 33140, balance: 1.049 1.046 1.030 +nvtxs: 7324, cut: 31642, balance: 1.050 1.044 1.037 +nvtxs: 13964, cut: 29859, balance: 1.049 1.045 1.041 +nvtxs: 26780, cut: 28382, balance: 1.050 1.044 1.039 +nvtxs: 51526, cut: 26891, balance: 1.046 1.050 1.037 +nvtxs: 99617, cut: 24686, balance: 1.046 1.049 1.045 + Setup: Max: 0.048, Sum: 0.148, Balance: 1.289 + Matching: Max: 0.323, Sum: 1.243, Balance: 1.038 +Contraction: Max: 0.350, Sum: 1.381, Balance: 1.015 + InitPart: Max: 0.321, Sum: 1.279, Balance: 1.004 + Project: Max: 0.022, Sum: 0.033, Balance: 2.685 + Initialize: Max: 0.144, Sum: 0.506, Balance: 1.141 + K-way: Max: 0.789, Sum: 2.986, Balance: 1.057 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.451 + Total: Max: 2.180, Sum: 8.712, Balance: 1.001 +Final 8-way Cut: 24686 Balance: 1.046 1.049 1.045 +NMoved: 61678 11392 11729 23121 +ParMETIS_V3_AdaptiveRepart reported a cut of 24686 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51520 769504 12144 13427][1200] +[ 26792 410272 6326 6969][1200] +[ 13981 216770 3319 3623][1200] +[ 7338 114436 1750 1897][1200] +[ 3870 60218 928 995][1200] +[ 2066 31410 500 530][1200] +[ 1120 16380 274 285][1200] +nvtxs: 1120, balance: 1.008 1.010 1.010 +nvtxs: 2066, cut: 36252, balance: 1.049 1.040 1.042 +nvtxs: 3870, cut: 34229, balance: 1.050 1.035 1.049 +nvtxs: 7338, cut: 31989, balance: 1.045 1.041 1.050 +nvtxs: 13981, cut: 30260, balance: 1.040 1.050 1.050 +nvtxs: 26792, cut: 28645, balance: 1.045 1.045 1.050 +nvtxs: 51520, cut: 26769, balance: 1.042 1.049 1.050 +nvtxs: 99617, cut: 24759, balance: 1.043 1.050 1.050 + Setup: Max: 0.053, Sum: 0.154, Balance: 1.370 + Matching: Max: 0.266, Sum: 1.039, Balance: 1.023 +Contraction: Max: 0.373, Sum: 1.491, Balance: 1.002 + InitPart: Max: 0.328, Sum: 1.310, Balance: 1.003 + Project: Max: 0.024, Sum: 0.059, Balance: 1.611 + Initialize: Max: 0.129, Sum: 0.453, Balance: 1.138 + K-way: Max: 0.819, Sum: 3.081, Balance: 1.063 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.367 + Total: Max: 2.226, Sum: 8.896, Balance: 1.001 +Final 8-way Cut: 24759 Balance: 1.043 1.050 1.050 +NMoved: 57772 8347 9197 17544 +ParMETIS_V3_AdaptiveRepart reported a cut of 24759 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51526 769238 12122 13433][1200] +[ 26780 409760 6306 6964][1200] +[ 13964 216890 3300 3618][1200] +[ 7324 114522 1749 1892][1200] +[ 3861 60152 931 996][1200] +[ 2067 31478 501 532][1200] +[ 1121 16376 274 285][1200] +nvtxs: 1121, balance: 1.007 1.008 1.014 +nvtxs: 2067, cut: 35452, balance: 1.029 1.025 1.048 +nvtxs: 3861, cut: 33287, balance: 1.041 1.032 1.049 +nvtxs: 7324, cut: 31629, balance: 1.049 1.042 1.050 +nvtxs: 13964, cut: 30125, balance: 1.044 1.040 1.050 +nvtxs: 26780, cut: 28710, balance: 1.044 1.039 1.050 +nvtxs: 51526, cut: 27075, balance: 1.043 1.050 1.050 +nvtxs: 99617, cut: 24948, balance: 1.043 1.050 1.050 + Setup: Max: 0.070, Sum: 0.147, Balance: 1.917 + Matching: Max: 0.302, Sum: 1.192, Balance: 1.013 +Contraction: Max: 0.329, Sum: 1.282, Balance: 1.026 + InitPart: Max: 0.331, Sum: 1.320, Balance: 1.004 + Project: Max: 0.032, Sum: 0.064, Balance: 1.990 + Initialize: Max: 0.146, Sum: 0.565, Balance: 1.030 + K-way: Max: 0.806, Sum: 3.051, Balance: 1.056 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.454 + Total: Max: 2.217, Sum: 8.851, Balance: 1.002 +Final 8-way Cut: 24948 Balance: 1.043 1.050 1.050 +NMoved: 60554 11264 11726 22990 +ParMETIS_V3_AdaptiveRepart reported a cut of 24948 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51520 769504 12144 13427][1200] +[ 26792 410272 6326 6969][1200] +[ 13981 216770 3319 3623][1200] +[ 7338 114436 1750 1897][1200] +[ 3870 60218 928 995][1200] +[ 2066 31410 500 530][1200] +[ 1120 16380 274 285][1200] +nvtxs: 1120, balance: 1.008 1.010 1.010 +nvtxs: 2066, cut: 52145, balance: 1.051 1.043 1.053 +nvtxs: 3870, cut: 52590, balance: 1.049 1.050 1.053 +nvtxs: 7338, cut: 52697, balance: 1.050 1.049 1.051 +nvtxs: 13981, cut: 52701, balance: 1.051 1.050 1.050 +nvtxs: 26792, cut: 52816, balance: 1.050 1.050 1.050 +nvtxs: 51520, cut: 52771, balance: 1.050 1.050 1.050 +nvtxs: 99617, cut: 52766, balance: 1.050 1.050 1.050 + Setup: Max: 0.086, Sum: 0.229, Balance: 1.496 + Matching: Max: 0.400, Sum: 1.565, Balance: 1.022 +Contraction: Max: 0.411, Sum: 1.639, Balance: 1.002 + InitPart: Max: 0.330, Sum: 1.315, Balance: 1.004 + Project: Max: 0.048, Sum: 0.098, Balance: 1.977 + Initialize: Max: 0.144, Sum: 0.565, Balance: 1.022 + K-way: Max: 0.711, Sum: 2.689, Balance: 1.058 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.404 + Total: Max: 2.369, Sum: 9.472, Balance: 1.001 +Final 8-way Cut: 52766 Balance: 1.050 1.050 1.050 +NMoved: 55215 8044 8937 16981 +ParMETIS_V3_AdaptiveRepart reported a cut of 52766 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 8 +[ 99617 1324862 23436 26023][1200] +[ 51526 769238 12122 13433][1200] +[ 26780 409760 6306 6964][1200] +[ 13964 216890 3300 3618][1200] +[ 7324 114522 1749 1892][1200] +[ 3861 60152 931 996][1200] +[ 2067 31478 501 532][1200] +[ 1121 16376 274 285][1200] +nvtxs: 1121, balance: 1.007 1.008 1.014 +nvtxs: 2067, cut: 54557, balance: 1.051 1.050 1.049 +nvtxs: 3861, cut: 54729, balance: 1.050 1.050 1.050 +nvtxs: 7324, cut: 54778, balance: 1.050 1.050 1.050 +nvtxs: 13964, cut: 54927, balance: 1.050 1.050 1.050 +nvtxs: 26780, cut: 54850, balance: 1.050 1.050 1.051 +nvtxs: 51526, cut: 54904, balance: 1.050 1.050 1.050 +nvtxs: 99617, cut: 54771, balance: 1.050 1.050 1.050 + Setup: Max: 0.084, Sum: 0.241, Balance: 1.399 + Matching: Max: 0.284, Sum: 1.075, Balance: 1.056 +Contraction: Max: 0.404, Sum: 1.607, Balance: 1.005 + InitPart: Max: 0.342, Sum: 1.357, Balance: 1.009 + Project: Max: 0.028, Sum: 0.051, Balance: 2.211 + Initialize: Max: 0.133, Sum: 0.511, Balance: 1.038 + K-way: Max: 0.838, Sum: 3.176, Balance: 1.056 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.446 + Total: Max: 2.343, Sum: 9.356, Balance: 1.002 +Final 8-way Cut: 54771 Balance: 1.050 1.050 1.050 +NMoved: 57592 10695 10795 21490 +ParMETIS_V3_AdaptiveRepart reported a cut of 54771 +Initial Load Imbalance: 1.5768, [214985 574403 1457095] for afactor: 4 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51494 769096 12134 13452][200] +[ 26776 410992 6313 7001][200] +[ 14000 218130 3303 3662][200] +[ 7354 114978 1737 1927][200] +[ 3887 60418 920 1018][200] +[ 2072 31328 495 543][200] +[ 1117 16208 267 293][200] +[ 615 8340 146 162][200] +[ 349 4308 81 94][200] +[ 203 2244 46 55][200] +nvtxs: 203, balance: 1.001 +nvtxs: 349, cut: 16162, balance: 1.037 +nvtxs: 615, cut: 15156, balance: 1.046 +nvtxs: 1117, cut: 14700, balance: 1.046 +nvtxs: 2072, cut: 13210, balance: 1.034 +nvtxs: 3887, cut: 12774, balance: 1.034 +nvtxs: 7354, cut: 12299, balance: 1.033 +nvtxs: 14000, cut: 11602, balance: 1.034 +nvtxs: 26776, cut: 10987, balance: 1.031 +nvtxs: 51494, cut: 10376, balance: 1.031 +nvtxs: 99617, cut: 9458, balance: 1.031 + Setup: Max: 0.133, Sum: 0.346, Balance: 1.543 + Matching: Max: 0.169, Sum: 0.604, Balance: 1.118 +Contraction: Max: 0.246, Sum: 0.665, Balance: 1.476 + InitPart: Max: 0.023, Sum: 0.046, Balance: 2.026 + Project: Max: 0.009, Sum: 0.016, Balance: 2.205 + Initialize: Max: 0.198, Sum: 0.567, Balance: 1.395 + K-way: Max: 0.732, Sum: 2.741, Balance: 1.068 + Remap: Max: 0.013, Sum: 0.047, Balance: 1.109 + Total: Max: 1.636, Sum: 6.517, Balance: 1.004 +Final 4-way Cut: 9458 Balance: 1.031 +NMoved: 47151 21129 25998 47127 +ParMETIS_V3_AdaptiveRepart reported a cut of 9458 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51513 768928 12122 13449][200] +[ 26792 410712 6304 7002][200] +[ 14015 218024 3307 3669][200] +[ 7368 115250 1741 1938][200] +[ 3896 60636 924 1032][200] +[ 2074 31366 497 549][200] +[ 1114 16162 268 296][200] +[ 614 8372 146 163][200] +[ 347 4332 82 94][200] +[ 202 2208 46 55][200] +nvtxs: 202, balance: 1.014 +nvtxs: 347, cut: 13219, balance: 1.049 +nvtxs: 614, cut: 12390, balance: 1.022 +nvtxs: 1114, cut: 11556, balance: 1.035 +nvtxs: 2074, cut: 10991, balance: 1.035 +nvtxs: 3896, cut: 10310, balance: 1.033 +nvtxs: 7368, cut: 9863, balance: 1.035 +nvtxs: 14015, cut: 9431, balance: 1.032 +nvtxs: 26792, cut: 8958, balance: 1.032 +nvtxs: 51513, cut: 8530, balance: 1.034 +nvtxs: 99617, cut: 7736, balance: 1.035 + Setup: Max: 0.057, Sum: 0.125, Balance: 1.814 + Matching: Max: 0.154, Sum: 0.568, Balance: 1.085 +Contraction: Max: 0.371, Sum: 0.986, Balance: 1.504 + InitPart: Max: 0.027, Sum: 0.058, Balance: 1.831 + Project: Max: 0.009, Sum: 0.018, Balance: 2.114 + Initialize: Max: 0.213, Sum: 0.593, Balance: 1.440 + K-way: Max: 0.677, Sum: 2.526, Balance: 1.071 + Remap: Max: 0.011, Sum: 0.016, Balance: 2.948 + Total: Max: 1.670, Sum: 6.673, Balance: 1.001 +Final 4-way Cut: 7736 Balance: 1.035 +NMoved: 39521 17820 13718 31538 +ParMETIS_V3_AdaptiveRepart reported a cut of 7736 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51494 769096 12134 13452][200] +[ 26776 410992 6313 7001][200] +[ 14000 218130 3303 3662][200] +[ 7354 114978 1737 1927][200] +[ 3887 60418 920 1018][200] +[ 2072 31328 495 543][200] +[ 1117 16208 267 293][200] +[ 615 8340 146 162][200] +[ 349 4308 81 94][200] +[ 203 2244 46 55][200] +nvtxs: 203, balance: 1.032 +nvtxs: 349, cut: 13934, balance: 1.051 +nvtxs: 615, cut: 13934, balance: 1.051 +nvtxs: 1117, cut: 13715, balance: 1.051 +nvtxs: 2072, cut: 13400, balance: 1.049 +nvtxs: 3887, cut: 13266, balance: 1.049 +nvtxs: 7354, cut: 12976, balance: 1.050 +nvtxs: 14000, cut: 12434, balance: 1.050 +nvtxs: 26776, cut: 12019, balance: 1.050 +nvtxs: 51494, cut: 11264, balance: 1.050 +nvtxs: 99617, cut: 10545, balance: 1.050 + Setup: Max: 0.124, Sum: 0.281, Balance: 1.765 + Matching: Max: 0.102, Sum: 0.381, Balance: 1.066 +Contraction: Max: 0.314, Sum: 0.823, Balance: 1.527 + InitPart: Max: 0.014, Sum: 0.047, Balance: 1.188 + Project: Max: 0.008, Sum: -0.017, Balance: -1.841 + Initialize: Max: 0.186, Sum: 0.597, Balance: 1.245 + K-way: Max: 0.726, Sum: 2.809, Balance: 1.033 + Remap: Max: -0.005, Sum: -0.026, Balance: 0.810 + Total: Max: 1.631, Sum: 6.494, Balance: 1.004 +Final 4-way Cut: 10545 Balance: 1.050 +NMoved: 8690 5183 7307 12490 +ParMETIS_V3_AdaptiveRepart reported a cut of 10545 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51513 768928 12122 13449][200] +[ 26792 410712 6304 7002][200] +[ 14015 218024 3307 3669][200] +[ 7368 115250 1741 1938][200] +[ 3896 60636 924 1032][200] +[ 2074 31366 497 549][200] +[ 1114 16162 268 296][200] +[ 614 8372 146 163][200] +[ 347 4332 82 94][200] +[ 202 2208 46 55][200] +nvtxs: 202, balance: 1.017 +nvtxs: 347, cut: 13505, balance: 1.047 +nvtxs: 614, cut: 12827, balance: 1.047 +nvtxs: 1114, cut: 11908, balance: 1.042 +nvtxs: 2074, cut: 11715, balance: 1.046 +nvtxs: 3896, cut: 11564, balance: 1.050 +nvtxs: 7368, cut: 11290, balance: 1.050 +nvtxs: 14015, cut: 11030, balance: 1.050 +nvtxs: 26792, cut: 10753, balance: 1.049 +nvtxs: 51513, cut: 10438, balance: 1.048 +nvtxs: 99617, cut: 10032, balance: 1.048 + Setup: Max: 0.082, Sum: 0.292, Balance: 1.128 + Matching: Max: 0.224, Sum: 0.862, Balance: 1.042 +Contraction: Max: 0.306, Sum: 0.802, Balance: 1.526 + InitPart: Max: 0.015, Sum: 0.052, Balance: 1.127 + Project: Max: 0.008, Sum: 0.019, Balance: 1.739 + Initialize: Max: 0.194, Sum: 0.579, Balance: 1.342 + K-way: Max: 0.675, Sum: 2.516, Balance: 1.074 + Remap: Max: 0.010, Sum: 0.010, Balance: 3.895 + Total: Max: 1.690, Sum: 6.748, Balance: 1.002 +Final 4-way Cut: 10032 Balance: 1.048 +NMoved: 8390 5353 8135 13488 +ParMETIS_V3_AdaptiveRepart reported a cut of 10032 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51494 769096 12134 13452][200] +[ 26776 410992 6313 7001][200] +[ 14000 218130 3303 3662][200] +[ 7354 114978 1737 1927][200] +[ 3887 60418 920 1018][200] +[ 2072 31328 495 543][200] +[ 1117 16208 267 293][200] +[ 615 8340 146 162][200] +[ 349 4308 81 94][200] +[ 203 2244 46 55][200] +nvtxs: 203, balance: 1.032 +nvtxs: 349, cut: 19274, balance: 1.044 +nvtxs: 615, cut: 19350, balance: 1.050 +nvtxs: 1117, cut: 19350, balance: 1.050 +nvtxs: 2072, cut: 19144, balance: 1.050 +nvtxs: 3887, cut: 19154, balance: 1.050 +nvtxs: 7354, cut: 19142, balance: 1.050 +nvtxs: 14000, cut: 19108, balance: 1.050 +nvtxs: 26776, cut: 19115, balance: 1.050 +nvtxs: 51494, cut: 19026, balance: 1.050 +nvtxs: 99617, cut: 18963, balance: 1.050 + Setup: Max: 0.141, Sum: 0.389, Balance: 1.450 + Matching: Max: 0.186, Sum: 0.697, Balance: 1.068 +Contraction: Max: 0.258, Sum: 0.667, Balance: 1.545 + InitPart: Max: 0.008, Sum: 0.027, Balance: 1.182 + Project: Max: 0.009, Sum: 0.017, Balance: 2.101 + Initialize: Max: 0.196, Sum: 0.678, Balance: 1.157 + K-way: Max: 0.546, Sum: 2.157, Balance: 1.012 + Remap: Max: 0.010, Sum: 0.007, Balance: 5.760 + Total: Max: 1.593, Sum: 6.366, Balance: 1.001 +Final 4-way Cut: 18963 Balance: 1.050 +NMoved: 7733 4841 7630 12471 +ParMETIS_V3_AdaptiveRepart reported a cut of 18963 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 4 +[ 99617 1324862 23436 26023][200] +[ 51513 768928 12122 13449][200] +[ 26792 410712 6304 7002][200] +[ 14015 218024 3307 3669][200] +[ 7368 115250 1741 1938][200] +[ 3896 60636 924 1032][200] +[ 2074 31366 497 549][200] +[ 1114 16162 268 296][200] +[ 614 8372 146 163][200] +[ 347 4332 82 94][200] +[ 202 2208 46 55][200] +nvtxs: 202, balance: 1.017 +nvtxs: 347, cut: 18114, balance: 1.048 +nvtxs: 614, cut: 16822, balance: 1.049 +nvtxs: 1114, cut: 16946, balance: 1.050 +nvtxs: 2074, cut: 16967, balance: 1.050 +nvtxs: 3896, cut: 16894, balance: 1.050 +nvtxs: 7368, cut: 16703, balance: 1.050 +nvtxs: 14015, cut: 16489, balance: 1.050 +nvtxs: 26792, cut: 16439, balance: 1.050 +nvtxs: 51513, cut: 16380, balance: 1.050 +nvtxs: 99617, cut: 16260, balance: 1.050 + Setup: Max: 0.092, Sum: 0.276, Balance: 1.335 + Matching: Max: 0.132, Sum: 0.445, Balance: 1.186 +Contraction: Max: 0.293, Sum: 0.744, Balance: 1.575 + InitPart: Max: 0.015, Sum: 0.057, Balance: 1.085 + Project: Max: 0.009, Sum: 0.017, Balance: 2.047 + Initialize: Max: 0.230, Sum: 0.729, Balance: 1.264 + K-way: Max: 0.591, Sum: 2.221, Balance: 1.064 + Remap: Max: 0.012, Sum: 0.042, Balance: 1.174 + Total: Max: 1.496, Sum: 5.981, Balance: 1.001 +Final 4-way Cut: 16260 Balance: 1.050 +NMoved: 7277 4459 7277 11736 +ParMETIS_V3_AdaptiveRepart reported a cut of 16260 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51499 769386 12144 13447][600] +[ 26728 409462 6315 6969][600] +[ 13941 216690 3313 3637][600] +[ 7302 114216 1747 1907][600] +[ 3855 59716 927 1007][600] +[ 2051 31140 496 537][600] +[ 1104 16236 267 290][600] +[ 600 8228 145 158][600] +nvtxs: 600, balance: 1.011 1.014 1.009 +nvtxs: 1104, cut: 20053, balance: 1.046 1.033 1.045 +nvtxs: 2051, cut: 18748, balance: 1.047 1.034 1.043 +nvtxs: 3855, cut: 17630, balance: 1.050 1.044 1.044 +nvtxs: 7302, cut: 16458, balance: 1.049 1.033 1.050 +nvtxs: 13941, cut: 15557, balance: 1.050 1.034 1.046 +nvtxs: 26728, cut: 14382, balance: 1.050 1.034 1.049 +nvtxs: 51499, cut: 13462, balance: 1.050 1.035 1.049 +nvtxs: 99617, cut: 12123, balance: 1.050 1.035 1.050 + Setup: Max: 0.081, Sum: 0.220, Balance: 1.466 + Matching: Max: 0.227, Sum: 0.858, Balance: 1.058 +Contraction: Max: 0.296, Sum: 0.770, Balance: 1.539 + InitPart: Max: 0.145, Sum: 0.576, Balance: 1.009 + Project: Max: 0.009, Sum: 0.018, Balance: 1.977 + Initialize: Max: 0.167, Sum: 0.615, Balance: 1.084 + K-way: Max: 0.768, Sum: 2.848, Balance: 1.078 + Remap: Max: 0.014, Sum: 0.050, Balance: 1.150 + Total: Max: 1.855, Sum: 7.409, Balance: 1.001 +Final 4-way Cut: 12123 Balance: 1.050 1.035 1.050 +NMoved: 55390 16752 20755 37507 +ParMETIS_V3_AdaptiveRepart reported a cut of 12123 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51520 769370 12126 13457][600] +[ 26721 409750 6303 6989][600] +[ 13940 216498 3302 3643][600] +[ 7302 113832 1728 1911][600] +[ 3846 59572 911 1007][600] +[ 2043 30980 486 534][600] +[ 1091 15974 265 282][600] +[ 599 8310 146 153][600] +nvtxs: 599, balance: 1.008 1.011 1.010 +nvtxs: 1091, cut: 21500, balance: 1.032 1.029 1.045 +nvtxs: 2043, cut: 19508, balance: 1.042 1.031 1.037 +nvtxs: 3846, cut: 18434, balance: 1.049 1.035 1.038 +nvtxs: 7302, cut: 17511, balance: 1.050 1.035 1.039 +nvtxs: 13940, cut: 16472, balance: 1.047 1.034 1.041 +nvtxs: 26721, cut: 15399, balance: 1.045 1.034 1.037 +nvtxs: 51520, cut: 14437, balance: 1.046 1.035 1.036 +nvtxs: 99617, cut: 13001, balance: 1.039 1.033 1.037 + Setup: Max: 0.089, Sum: 0.257, Balance: 1.389 + Matching: Max: 0.167, Sum: 0.634, Balance: 1.057 +Contraction: Max: 0.307, Sum: 0.795, Balance: 1.544 + InitPart: Max: 0.142, Sum: 0.532, Balance: 1.067 + Project: Max: 0.010, Sum: 0.004, Balance: 10.812 + Initialize: Max: 0.132, Sum: 0.470, Balance: 1.124 + K-way: Max: 0.756, Sum: 2.847, Balance: 1.062 + Remap: Max: 0.014, Sum: 0.048, Balance: 1.144 + Total: Max: 1.876, Sum: 7.478, Balance: 1.004 +Final 4-way Cut: 13001 Balance: 1.039 1.033 1.037 +NMoved: 54017 15326 19382 34708 +ParMETIS_V3_AdaptiveRepart reported a cut of 13001 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51499 769386 12144 13447][600] +[ 26728 409462 6315 6969][600] +[ 13941 216690 3313 3637][600] +[ 7302 114216 1747 1907][600] +[ 3855 59716 927 1007][600] +[ 2051 31140 496 537][600] +[ 1104 16236 267 290][600] +[ 600 8228 145 158][600] +nvtxs: 600, balance: 1.011 1.014 1.009 +nvtxs: 1104, cut: 19801, balance: 1.046 1.037 1.042 +nvtxs: 2051, cut: 18711, balance: 1.049 1.037 1.045 +nvtxs: 3855, cut: 17700, balance: 1.050 1.037 1.049 +nvtxs: 7302, cut: 16476, balance: 1.047 1.035 1.049 +nvtxs: 13941, cut: 15574, balance: 1.050 1.036 1.049 +nvtxs: 26728, cut: 14417, balance: 1.049 1.036 1.050 +nvtxs: 51499, cut: 13531, balance: 1.050 1.037 1.050 +nvtxs: 99617, cut: 12140, balance: 1.049 1.037 1.050 + Setup: Max: 0.155, Sum: 0.433, Balance: 1.436 + Matching: Max: 0.241, Sum: 0.911, Balance: 1.059 +Contraction: Max: 0.276, Sum: 0.778, Balance: 1.421 + InitPart: Max: 0.145, Sum: 0.576, Balance: 1.006 + Project: Max: 0.009, Sum: 0.021, Balance: 1.713 + Initialize: Max: 0.127, Sum: 0.491, Balance: 1.037 + K-way: Max: 0.747, Sum: 2.793, Balance: 1.070 + Remap: Max: 0.007, Sum: 0.020, Balance: 1.294 + Total: Max: 1.947, Sum: 7.785, Balance: 1.000 +Final 4-way Cut: 12140 Balance: 1.049 1.037 1.050 +NMoved: 54484 16279 20241 36520 +ParMETIS_V3_AdaptiveRepart reported a cut of 12140 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51520 769370 12126 13457][600] +[ 26721 409750 6303 6989][600] +[ 13940 216498 3302 3643][600] +[ 7302 113832 1728 1911][600] +[ 3846 59572 911 1007][600] +[ 2043 30980 486 534][600] +[ 1091 15974 265 282][600] +[ 599 8310 146 153][600] +nvtxs: 599, balance: 1.008 1.011 1.010 +nvtxs: 1091, cut: 20920, balance: 1.039 1.030 1.049 +nvtxs: 2043, cut: 19258, balance: 1.030 1.030 1.049 +nvtxs: 3846, cut: 18393, balance: 1.035 1.032 1.050 +nvtxs: 7302, cut: 17607, balance: 1.039 1.034 1.049 +nvtxs: 13940, cut: 16660, balance: 1.028 1.031 1.050 +nvtxs: 26721, cut: 15771, balance: 1.027 1.032 1.050 +nvtxs: 51520, cut: 14727, balance: 1.032 1.033 1.050 +nvtxs: 99617, cut: 13389, balance: 1.022 1.031 1.050 + Setup: Max: 0.102, Sum: 0.219, Balance: 1.857 + Matching: Max: 0.235, Sum: 0.860, Balance: 1.092 +Contraction: Max: 0.283, Sum: 0.749, Balance: 1.510 + InitPart: Max: 0.137, Sum: 0.540, Balance: 1.017 + Project: Max: 0.009, Sum: 0.002, Balance: 17.060 + Initialize: Max: 0.174, Sum: 0.575, Balance: 1.214 + K-way: Max: 0.828, Sum: 3.095, Balance: 1.070 + Remap: Max: -0.002, Sum: -0.015, Balance: 0.665 + Total: Max: 1.992, Sum: 7.938, Balance: 1.004 +Final 4-way Cut: 13389 Balance: 1.022 1.031 1.050 +NMoved: 52163 14831 18484 33315 +ParMETIS_V3_AdaptiveRepart reported a cut of 13389 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51499 769386 12144 13447][600] +[ 26728 409462 6315 6969][600] +[ 13941 216690 3313 3637][600] +[ 7302 114216 1747 1907][600] +[ 3855 59716 927 1007][600] +[ 2051 31140 496 537][600] +[ 1104 16236 267 290][600] +[ 600 8228 145 158][600] +nvtxs: 600, balance: 1.011 1.014 1.009 +nvtxs: 1104, cut: 45769, balance: 1.034 1.050 1.045 +nvtxs: 2051, cut: 46714, balance: 1.048 1.050 1.048 +nvtxs: 3855, cut: 47003, balance: 1.050 1.050 1.050 +nvtxs: 7302, cut: 47459, balance: 1.050 1.050 1.049 +nvtxs: 13941, cut: 47929, balance: 1.050 1.050 1.049 +nvtxs: 26728, cut: 47864, balance: 1.050 1.050 1.049 +nvtxs: 51499, cut: 48068, balance: 1.049 1.050 1.050 +nvtxs: 99617, cut: 47806, balance: 1.049 1.050 1.050 + Setup: Max: 0.126, Sum: 0.371, Balance: 1.362 + Matching: Max: 0.266, Sum: 0.965, Balance: 1.101 +Contraction: Max: 0.290, Sum: 0.696, Balance: 1.667 + InitPart: Max: 0.154, Sum: 0.578, Balance: 1.064 + Project: Max: 0.009, Sum: 0.020, Balance: 1.872 + Initialize: Max: 0.142, Sum: 0.522, Balance: 1.088 + K-way: Max: 0.830, Sum: 3.124, Balance: 1.063 + Remap: Max: -0.004, Sum: -0.021, Balance: 0.788 + Total: Max: 2.030, Sum: 8.117, Balance: 1.001 +Final 4-way Cut: 47806 Balance: 1.049 1.050 1.050 +NMoved: 44285 12496 14914 27410 +ParMETIS_V3_AdaptiveRepart reported a cut of 47806 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 4 +[ 99617 1324862 23436 26023][600] +[ 51520 769370 12126 13457][600] +[ 26721 409750 6303 6989][600] +[ 13940 216498 3302 3643][600] +[ 7302 113832 1728 1911][600] +[ 3846 59572 911 1007][600] +[ 2043 30980 486 534][600] +[ 1091 15974 265 282][600] +[ 599 8310 146 153][600] +nvtxs: 599, balance: 1.008 1.011 1.010 +nvtxs: 1091, cut: 37579, balance: 1.049 1.047 1.050 +nvtxs: 2043, cut: 38920, balance: 1.042 1.050 1.050 +nvtxs: 3846, cut: 40489, balance: 1.044 1.051 1.050 +nvtxs: 7302, cut: 41381, balance: 1.049 1.050 1.050 +nvtxs: 13940, cut: 41381, balance: 1.048 1.050 1.050 +nvtxs: 26721, cut: 41946, balance: 1.050 1.050 1.049 +nvtxs: 51520, cut: 42014, balance: 1.049 1.050 1.050 +nvtxs: 99617, cut: 41808, balance: 1.050 1.050 1.050 + Setup: Max: 0.129, Sum: 0.333, Balance: 1.543 + Matching: Max: 0.243, Sum: 0.935, Balance: 1.039 +Contraction: Max: 0.338, Sum: 0.892, Balance: 1.516 + InitPart: Max: 0.138, Sum: 0.552, Balance: 1.003 + Project: Max: 0.010, Sum: 0.037, Balance: 1.070 + Initialize: Max: 0.172, Sum: 0.604, Balance: 1.136 + K-way: Max: 0.806, Sum: 2.998, Balance: 1.075 + Remap: Max: -0.003, Sum: -0.015, Balance: 0.718 + Total: Max: 2.041, Sum: 8.160, Balance: 1.001 +Final 4-way Cut: 41808 Balance: 1.050 1.050 1.050 +NMoved: 46032 13318 16812 30130 +ParMETIS_V3_AdaptiveRepart reported a cut of 41808 +Initial Load Imbalance: 1.1933, [173610 310283 1040090] for afactor: 4 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51474 768976 12144 13415][200] +[ 26794 410198 6335 6975][200] +[ 13996 217118 3315 3639][200] +[ 7354 114922 1754 1922][200] +[ 3881 60458 933 1013][200] +[ 2070 31578 509 540][200] +[ 1118 16218 268 293][200] +[ 615 8424 146 161][200] +[ 344 4400 82 92][200] +[ 196 2260 44 55][200] +nvtxs: 196, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 615, cut: 2281, balance: 1.030 +nvtxs: 1118, cut: 2281, balance: 1.030 +nvtxs: 2070, cut: 2281, balance: 1.030 +nvtxs: 3881, cut: 2281, balance: 1.030 +nvtxs: 7354, cut: 2281, balance: 1.030 +nvtxs: 13996, cut: 2281, balance: 1.030 +nvtxs: 26794, cut: 2281, balance: 1.030 +nvtxs: 51474, cut: 2276, balance: 1.030 +nvtxs: 99617, cut: 2276, balance: 1.030 + Setup: Max: 0.069, Sum: 0.229, Balance: 1.213 + Matching: Max: 0.277, Sum: 1.043, Balance: 1.063 +Contraction: Max: 0.382, Sum: 1.494, Balance: 1.022 + Project: Max: 0.051, Sum: 0.103, Balance: 1.986 + Initialize: Max: 0.143, Sum: 0.503, Balance: 1.140 + K-way: Max: 0.250, Sum: 0.782, Balance: 1.279 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.298 + Total: Max: 1.315, Sum: 5.253, Balance: 1.001 +Final 2-way Cut: 2276 Balance: 1.030 +NMoved: 6 4 4 8 +ParMETIS_V3_AdaptiveRepart reported a cut of 2276 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51467 768770 12119 13407][200] +[ 26758 410182 6309 6966][200] +[ 13973 217278 3305 3631][200] +[ 7332 114684 1742 1901][200] +[ 3869 60258 930 995][200] +[ 2064 31426 502 526][200] +[ 1117 16294 274 285][200] +[ 611 8534 151 155][200] +[ 344 4442 83 87][200] +[ 197 2300 47 51][200] +nvtxs: 197, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 611, cut: 2281, balance: 1.030 +nvtxs: 1117, cut: 2281, balance: 1.030 +nvtxs: 2064, cut: 2281, balance: 1.030 +nvtxs: 3869, cut: 2281, balance: 1.030 +nvtxs: 7332, cut: 2281, balance: 1.030 +nvtxs: 13973, cut: 2281, balance: 1.030 +nvtxs: 26758, cut: 2281, balance: 1.030 +nvtxs: 51467, cut: 2280, balance: 1.030 +nvtxs: 99617, cut: 2280, balance: 1.030 + Setup: Max: 0.119, Sum: 0.377, Balance: 1.264 + Matching: Max: 0.378, Sum: 1.397, Balance: 1.083 +Contraction: Max: 0.498, Sum: 1.903, Balance: 1.046 + Project: Max: 0.015, Sum: 0.007, Balance: 8.124 + Initialize: Max: 0.141, Sum: 0.525, Balance: 1.073 + K-way: Max: 0.244, Sum: 0.859, Balance: 1.136 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.426 + Total: Max: 1.574, Sum: 6.254, Balance: 1.007 +Final 2-way Cut: 2280 Balance: 1.030 +NMoved: 2 2 2 4 +ParMETIS_V3_AdaptiveRepart reported a cut of 2280 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51474 768976 12144 13415][200] +[ 26794 410198 6335 6975][200] +[ 13996 217118 3315 3639][200] +[ 7354 114922 1754 1922][200] +[ 3881 60458 933 1013][200] +[ 2070 31578 509 540][200] +[ 1118 16218 268 293][200] +[ 615 8424 146 161][200] +[ 344 4400 82 92][200] +[ 196 2260 44 55][200] +nvtxs: 196, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 615, cut: 2281, balance: 1.030 +nvtxs: 1118, cut: 2281, balance: 1.030 +nvtxs: 2070, cut: 2281, balance: 1.030 +nvtxs: 3881, cut: 2281, balance: 1.030 +nvtxs: 7354, cut: 2281, balance: 1.030 +nvtxs: 13996, cut: 2281, balance: 1.030 +nvtxs: 26794, cut: 2281, balance: 1.030 +nvtxs: 51474, cut: 2276, balance: 1.030 +nvtxs: 99617, cut: 2276, balance: 1.030 + Setup: Max: 0.132, Sum: 0.304, Balance: 1.735 + Matching: Max: 0.301, Sum: 1.161, Balance: 1.036 +Contraction: Max: 0.348, Sum: 1.370, Balance: 1.015 + Project: Max: 0.029, Sum: 0.095, Balance: 1.210 + Initialize: Max: 0.129, Sum: 0.471, Balance: 1.097 + K-way: Max: 0.212, Sum: 0.824, Balance: 1.030 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.428 + Total: Max: 1.359, Sum: 5.405, Balance: 1.006 +Final 2-way Cut: 2276 Balance: 1.030 +NMoved: 6 4 4 8 +ParMETIS_V3_AdaptiveRepart reported a cut of 2276 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51467 768770 12119 13407][200] +[ 26758 410182 6309 6966][200] +[ 13973 217278 3305 3631][200] +[ 7332 114684 1742 1901][200] +[ 3869 60258 930 995][200] +[ 2064 31426 502 526][200] +[ 1117 16294 274 285][200] +[ 611 8534 151 155][200] +[ 344 4442 83 87][200] +[ 197 2300 47 51][200] +nvtxs: 197, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 611, cut: 2281, balance: 1.030 +nvtxs: 1117, cut: 2281, balance: 1.030 +nvtxs: 2064, cut: 2281, balance: 1.030 +nvtxs: 3869, cut: 2281, balance: 1.030 +nvtxs: 7332, cut: 2281, balance: 1.030 +nvtxs: 13973, cut: 2281, balance: 1.030 +nvtxs: 26758, cut: 2281, balance: 1.030 +nvtxs: 51467, cut: 2280, balance: 1.030 +nvtxs: 99617, cut: 2280, balance: 1.030 + Setup: Max: 0.101, Sum: 0.252, Balance: 1.601 + Matching: Max: 0.311, Sum: 1.127, Balance: 1.103 +Contraction: Max: 0.390, Sum: 1.511, Balance: 1.032 + Project: Max: 0.017, Sum: 0.011, Balance: 5.845 + Initialize: Max: 0.134, Sum: 0.463, Balance: 1.154 + K-way: Max: 0.256, Sum: 0.924, Balance: 1.109 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.312 + Total: Max: 1.349, Sum: 5.365, Balance: 1.006 +Final 2-way Cut: 2280 Balance: 1.030 +NMoved: 2 2 2 4 +ParMETIS_V3_AdaptiveRepart reported a cut of 2280 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51474 768976 12144 13415][200] +[ 26794 410198 6335 6975][200] +[ 13996 217118 3315 3639][200] +[ 7354 114922 1754 1922][200] +[ 3881 60458 933 1013][200] +[ 2070 31578 509 540][200] +[ 1118 16218 268 293][200] +[ 615 8424 146 161][200] +[ 344 4400 82 92][200] +[ 196 2260 44 55][200] +nvtxs: 196, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 615, cut: 2281, balance: 1.030 +nvtxs: 1118, cut: 2281, balance: 1.030 +nvtxs: 2070, cut: 2281, balance: 1.030 +nvtxs: 3881, cut: 2281, balance: 1.030 +nvtxs: 7354, cut: 2281, balance: 1.030 +nvtxs: 13996, cut: 2281, balance: 1.030 +nvtxs: 26794, cut: 2281, balance: 1.030 +nvtxs: 51474, cut: 2281, balance: 1.030 +nvtxs: 99617, cut: 2281, balance: 1.030 + Setup: Max: 0.136, Sum: 0.367, Balance: 1.482 + Matching: Max: 0.277, Sum: 1.068, Balance: 1.039 +Contraction: Max: 0.388, Sum: 1.512, Balance: 1.026 + Project: Max: 0.023, Sum: 0.028, Balance: 3.275 + Initialize: Max: 0.164, Sum: 0.500, Balance: 1.312 + K-way: Max: 0.178, Sum: 0.652, Balance: 1.092 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.391 + Total: Max: 1.332, Sum: 5.320, Balance: 1.001 +Final 2-way Cut: 2281 Balance: 1.030 +NMoved: 0 0 0 0 +ParMETIS_V3_AdaptiveRepart reported a cut of 2281 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 1, Nparts: 2 +[ 99617 1324862 23436 26023][200] +[ 51467 768770 12119 13407][200] +[ 26758 410182 6309 6966][200] +[ 13973 217278 3305 3631][200] +[ 7332 114684 1742 1901][200] +[ 3869 60258 930 995][200] +[ 2064 31426 502 526][200] +[ 1117 16294 274 285][200] +[ 611 8534 151 155][200] +[ 344 4442 83 87][200] +[ 197 2300 47 51][200] +nvtxs: 197, balance: 1.030 +nvtxs: 344, cut: 2281, balance: 1.030 +nvtxs: 611, cut: 2281, balance: 1.030 +nvtxs: 1117, cut: 2281, balance: 1.030 +nvtxs: 2064, cut: 2281, balance: 1.030 +nvtxs: 3869, cut: 2281, balance: 1.030 +nvtxs: 7332, cut: 2281, balance: 1.030 +nvtxs: 13973, cut: 2281, balance: 1.030 +nvtxs: 26758, cut: 2281, balance: 1.030 +nvtxs: 51467, cut: 2281, balance: 1.030 +nvtxs: 99617, cut: 2281, balance: 1.030 + Setup: Max: 0.112, Sum: 0.355, Balance: 1.263 + Matching: Max: 0.359, Sum: 1.391, Balance: 1.031 +Contraction: Max: 0.488, Sum: 1.901, Balance: 1.027 + Project: Max: 0.037, Sum: 0.074, Balance: 2.016 + Initialize: Max: 0.113, Sum: 0.446, Balance: 1.016 + K-way: Max: 0.201, Sum: 0.758, Balance: 1.062 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.434 + Total: Max: 1.555, Sum: 6.212, Balance: 1.001 +Final 2-way Cut: 2281 Balance: 1.030 +NMoved: 0 0 0 0 +ParMETIS_V3_AdaptiveRepart reported a cut of 2281 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51474 768976 12144 13415][600] +[ 26735 408876 6324 6959][600] +[ 13939 216334 3300 3611][600] +[ 7300 114028 1745 1893][600] +[ 3859 59852 936 999][600] +[ 2064 31208 510 527][600] +[ 1120 16180 274 288][600] +[ 615 8346 148 157][600] +nvtxs: 615, balance: 1.002 1.002 1.004 +nvtxs: 1120, cut: 9950, balance: 1.013 1.013 1.008 +nvtxs: 2064, cut: 9377, balance: 1.014 1.014 1.012 +nvtxs: 3859, cut: 8764, balance: 1.018 1.018 1.010 +nvtxs: 7300, cut: 8176, balance: 1.019 1.019 1.010 +nvtxs: 13939, cut: 7710, balance: 1.021 1.021 1.012 +nvtxs: 26735, cut: 7238, balance: 1.022 1.022 1.016 +nvtxs: 51474, cut: 6729, balance: 1.022 1.022 1.016 +nvtxs: 99617, cut: 6113, balance: 1.013 1.013 1.014 + Setup: Max: 0.096, Sum: 0.268, Balance: 1.435 + Matching: Max: 0.320, Sum: 1.241, Balance: 1.033 +Contraction: Max: 0.346, Sum: 1.380, Balance: 1.002 + InitPart: Max: 0.085, Sum: 0.299, Balance: 1.130 + Project: Max: 0.048, Sum: 0.138, Balance: 1.389 + Initialize: Max: 0.138, Sum: 0.517, Balance: 1.072 + K-way: Max: 0.666, Sum: 2.562, Balance: 1.040 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.516 + Total: Max: 1.883, Sum: 7.527, Balance: 1.001 +Final 2-way Cut: 6113 Balance: 1.013 1.013 1.014 +NMoved: 49732 24996 24996 49992 +ParMETIS_V3_AdaptiveRepart reported a cut of 6113 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1000.000, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51467 768770 12119 13407][600] +[ 26704 408982 6292 6955][600] +[ 13898 215874 3282 3616][600] +[ 7275 113570 1724 1890][600] +[ 3830 59564 910 983][600] +[ 2024 30990 484 522][600] +[ 1083 16046 263 279][600] +[ 586 8180 143 154][600] +nvtxs: 586, balance: 1.006 1.006 1.004 +nvtxs: 1083, cut: 9178, balance: 1.015 1.015 1.003 +nvtxs: 2024, cut: 8626, balance: 1.026 1.026 1.012 +nvtxs: 3830, cut: 8358, balance: 1.030 1.030 1.015 +nvtxs: 7275, cut: 7886, balance: 1.033 1.033 1.018 +nvtxs: 13898, cut: 7312, balance: 1.039 1.039 1.023 +nvtxs: 26704, cut: 6956, balance: 1.039 1.039 1.022 +nvtxs: 51467, cut: 6583, balance: 1.043 1.043 1.023 +nvtxs: 99617, cut: 5980, balance: 1.050 1.050 1.026 + Setup: Max: 0.098, Sum: 0.277, Balance: 1.419 + Matching: Max: 0.304, Sum: 1.170, Balance: 1.039 +Contraction: Max: 0.364, Sum: 1.440, Balance: 1.012 + InitPart: Max: 0.075, Sum: 0.295, Balance: 1.013 + Project: Max: 0.028, Sum: 0.062, Balance: 1.797 + Initialize: Max: 0.141, Sum: 0.464, Balance: 1.218 + K-way: Max: 0.671, Sum: 2.585, Balance: 1.039 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.232 + Total: Max: 1.830, Sum: 7.293, Balance: 1.004 +Final 2-way Cut: 5980 Balance: 1.050 1.050 1.026 +NMoved: 48535 25319 25319 50638 +ParMETIS_V3_AdaptiveRepart reported a cut of 5980 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51474 768976 12144 13415][600] +[ 26735 408876 6324 6959][600] +[ 13939 216334 3300 3611][600] +[ 7300 114028 1745 1893][600] +[ 3859 59852 936 999][600] +[ 2064 31208 510 527][600] +[ 1120 16180 274 288][600] +[ 615 8346 148 157][600] +nvtxs: 615, balance: 1.002 1.002 1.004 +nvtxs: 1120, cut: 10122, balance: 1.003 1.003 1.002 +nvtxs: 2064, cut: 9523, balance: 1.012 1.012 1.008 +nvtxs: 3859, cut: 8934, balance: 1.007 1.007 1.010 +nvtxs: 7300, cut: 8137, balance: 1.005 1.005 1.015 +nvtxs: 13939, cut: 7757, balance: 1.006 1.006 1.015 +nvtxs: 26735, cut: 7257, balance: 1.008 1.008 1.015 +nvtxs: 51474, cut: 6833, balance: 1.009 1.009 1.015 +nvtxs: 99617, cut: 6214, balance: 1.025 1.025 1.010 + Setup: Max: 0.092, Sum: 0.280, Balance: 1.319 + Matching: Max: 0.315, Sum: 1.201, Balance: 1.048 +Contraction: Max: 0.358, Sum: 1.396, Balance: 1.026 + InitPart: Max: 0.068, Sum: 0.269, Balance: 1.011 + Project: Max: 0.052, Sum: 0.156, Balance: 1.337 + Initialize: Max: 0.076, Sum: 0.244, Balance: 1.238 + K-way: Max: 0.694, Sum: 2.643, Balance: 1.051 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.429 + Total: Max: 1.855, Sum: 7.412, Balance: 1.001 +Final 2-way Cut: 6214 Balance: 1.025 1.025 1.010 +NMoved: 47999 24270 24270 48540 +ParMETIS_V3_AdaptiveRepart reported a cut of 6214 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 1.000, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51467 768770 12119 13407][600] +[ 26704 408982 6292 6955][600] +[ 13898 215874 3282 3616][600] +[ 7275 113570 1724 1890][600] +[ 3830 59564 910 983][600] +[ 2024 30990 484 522][600] +[ 1083 16046 263 279][600] +[ 586 8180 143 154][600] +nvtxs: 586, balance: 1.006 1.006 1.004 +nvtxs: 1083, cut: 9230, balance: 1.013 1.013 1.002 +nvtxs: 2024, cut: 8706, balance: 1.034 1.034 1.010 +nvtxs: 3830, cut: 8425, balance: 1.034 1.034 1.011 +nvtxs: 7275, cut: 7826, balance: 1.048 1.048 1.019 +nvtxs: 13898, cut: 7364, balance: 1.050 1.050 1.019 +nvtxs: 26704, cut: 7000, balance: 1.050 1.050 1.019 +nvtxs: 51467, cut: 6669, balance: 1.050 1.050 1.019 +nvtxs: 99617, cut: 6215, balance: 1.050 1.050 1.016 + Setup: Max: 0.132, Sum: 0.431, Balance: 1.225 + Matching: Max: 0.412, Sum: 1.572, Balance: 1.049 +Contraction: Max: 0.471, Sum: 1.861, Balance: 1.012 + InitPart: Max: 0.074, Sum: 0.291, Balance: 1.015 + Project: Max: 0.022, Sum: -0.000, Balance: -200.449 + Initialize: Max: 0.150, Sum: 0.499, Balance: 1.200 + K-way: Max: 0.656, Sum: 2.512, Balance: 1.045 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.305 + Total: Max: 2.187, Sum: 8.744, Balance: 1.001 +Final 2-way Cut: 6215 Balance: 1.050 1.050 1.016 +NMoved: 48036 24919 24919 49838 +ParMETIS_V3_AdaptiveRepart reported a cut of 6215 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 1 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51474 768976 12144 13415][600] +[ 26735 408876 6324 6959][600] +[ 13939 216334 3300 3611][600] +[ 7300 114028 1745 1893][600] +[ 3859 59852 936 999][600] +[ 2064 31208 510 527][600] +[ 1120 16180 274 288][600] +[ 615 8346 148 157][600] +nvtxs: 615, balance: 1.002 1.002 1.004 +nvtxs: 1120, cut: 24586, balance: 1.046 1.046 1.048 +nvtxs: 2064, cut: 24844, balance: 1.049 1.049 1.048 +nvtxs: 3859, cut: 25224, balance: 1.049 1.049 1.050 +nvtxs: 7300, cut: 25329, balance: 1.050 1.050 1.050 +nvtxs: 13939, cut: 25408, balance: 1.050 1.050 1.050 +nvtxs: 26735, cut: 25425, balance: 1.050 1.050 1.050 +nvtxs: 51474, cut: 25425, balance: 1.050 1.050 1.050 +nvtxs: 99617, cut: 25425, balance: 1.050 1.050 1.050 + Setup: Max: 0.073, Sum: 0.170, Balance: 1.719 + Matching: Max: 0.299, Sum: 1.169, Balance: 1.025 +Contraction: Max: 0.373, Sum: 1.487, Balance: 1.002 + InitPart: Max: 0.079, Sum: 0.311, Balance: 1.012 + Project: Max: 0.040, Sum: 0.110, Balance: 1.444 + Initialize: Max: 0.131, Sum: 0.443, Balance: 1.177 + K-way: Max: 0.455, Sum: 1.631, Balance: 1.116 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.358 + Total: Max: 1.629, Sum: 6.511, Balance: 1.001 +Final 2-way Cut: 25425 Balance: 1.050 1.050 1.050 +NMoved: 44489 22400 22400 44800 +ParMETIS_V3_AdaptiveRepart reported a cut of 25425 + +Testing ParMETIS_V3_AdaptiveRepart with options[1-3] = {7 2 1}, ipc2redist: 0.001, Ncon: 3, Nparts: 2 +[ 99617 1324862 23436 26023][600] +[ 51467 768770 12119 13407][600] +[ 26704 408982 6292 6955][600] +[ 13898 215874 3282 3616][600] +[ 7275 113570 1724 1890][600] +[ 3830 59564 910 983][600] +[ 2024 30990 484 522][600] +[ 1083 16046 263 279][600] +[ 586 8180 143 154][600] +nvtxs: 586, balance: 1.006 1.006 1.004 +nvtxs: 1083, cut: 24560, balance: 1.050 1.050 1.049 +nvtxs: 2024, cut: 24558, balance: 1.050 1.050 1.049 +nvtxs: 3830, cut: 24663, balance: 1.050 1.050 1.050 +nvtxs: 7275, cut: 24699, balance: 1.050 1.050 1.050 +nvtxs: 13898, cut: 24719, balance: 1.050 1.050 1.050 +nvtxs: 26704, cut: 24773, balance: 1.050 1.050 1.050 +nvtxs: 51467, cut: 24773, balance: 1.050 1.050 1.050 +nvtxs: 99617, cut: 24773, balance: 1.050 1.050 1.050 + Setup: Max: 0.120, Sum: 0.304, Balance: 1.585 + Matching: Max: 0.304, Sum: 1.145, Balance: 1.062 +Contraction: Max: 0.368, Sum: 1.393, Balance: 1.058 + InitPart: Max: 0.062, Sum: 0.244, Balance: 1.017 + Project: Max: 0.045, Sum: 0.093, Balance: 1.937 + Initialize: Max: 0.170, Sum: 0.606, Balance: 1.122 + K-way: Max: 0.420, Sum: 1.629, Balance: 1.030 + Remap: Max: 0.000, Sum: 0.000, Balance: 1.448 + Total: Max: 1.703, Sum: 6.803, Balance: 1.001 +Final 2-way Cut: 24773 Balance: 1.050 1.050 1.050 +NMoved: 44478 22395 22395 44790 +ParMETIS_V3_AdaptiveRepart reported a cut of 24773 + +Testing ParMETIS_V3_NodeND with options[1-3] = {3 1 1} + Setup: Max: 0.242, Sum: 0.818, Balance: 1.182 + Matching: Max: 0.485, Sum: 1.839, Balance: 1.055 +Contraction: Max: 0.499, Sum: 1.954, Balance: 1.022 + InitPart: Max: 0.018, Sum: 0.069, Balance: 1.018 + Project: Max: 0.039, Sum: 0.066, Balance: 2.352 + Initialize: Max: 0.244, Sum: 0.676, Balance: 1.443 + K-way: Max: 0.831, Sum: 3.129, Balance: 1.062 + Total: Max: 2.236, Sum: 8.943, Balance: 1.000 +SepSizes: 511 [47236 51870] +SepSizes: 901 [23636 22699] 570 [26836 24464] + Setup: Max: 0.450, Sum: 1.348, Balance: 1.334 + Matching: Max: 0.666, Sum: 2.290, Balance: 1.164 +Contraction: Max: 1.009, Sum: 3.461, Balance: 1.167 + InitPart: Max: 0.102, Sum: 0.395, Balance: 1.034 + Project: Max: 0.057, Sum: 0.108, Balance: 2.107 + Initialize: Max: 0.252, Sum: 0.799, Balance: 1.261 + K-way: Max: 1.304, Sum: 5.084, Balance: 1.026 + Move: Max: 4.609, Sum: 12.909, Balance: 1.428 + Total: Max: 6.972, Sum: 27.820, Balance: 1.002 + +Testing ParMETIS_V3_NodeND with options[1-3] = {3 1 2} + Setup: Max: 0.268, Sum: 0.820, Balance: 1.308 + Matching: Max: 0.440, Sum: 1.704, Balance: 1.032 +Contraction: Max: 0.560, Sum: 2.205, Balance: 1.016 + InitPart: Max: 0.012, Sum: 0.047, Balance: 1.024 + Project: Max: 0.066, Sum: 0.185, Balance: 1.435 + Initialize: Max: 0.187, Sum: 0.670, Balance: 1.114 + K-way: Max: 0.765, Sum: 3.004, Balance: 1.019 + Total: Max: 2.302, Sum: 9.206, Balance: 1.000 +SepSizes: 511 [47236 51870] +SepSizes: 901 [23636 22699] 570 [26836 24464] + Setup: Max: 0.394, Sum: 1.187, Balance: 1.328 + Matching: Max: 0.634, Sum: 2.294, Balance: 1.106 +Contraction: Max: 1.103, Sum: 3.570, Balance: 1.236 + InitPart: Max: 0.092, Sum: 0.313, Balance: 1.181 + Project: Max: 0.066, Sum: 0.191, Balance: 1.374 + Initialize: Max: 0.256, Sum: 0.867, Balance: 1.182 + K-way: Max: 1.234, Sum: 4.827, Balance: 1.023 + Move: Max: 2.786, Sum: 6.572, Balance: 1.696 + Total: Max: 6.896, Sum: 27.577, Balance: 1.000 + +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- +------------------------------------------------------------------------- +% mpirun -np 4 mtest bricks.hex3d 2 + +Nelements: 117649, Nnodes: 125000, EType: 3 +MGCNUM: 2 +Completed Dual Graph -- Nvtxs: 117649, Nedges: 2046222 +[117649 2046222 29412 29413] [100] [ 0.000] [ 0.000] +[ 60230 1195682 15032 15075] [100] [ 0.000] [ 0.000] +[ 30905 630126 7712 7738] [100] [ 0.000] [ 0.000] +[ 15878 308518 3958 3976] [100] [ 0.000] [ 0.000] +[ 8188 150574 2039 2055] [100] [ 0.000] [ 0.000] +[ 4240 74750 1057 1063] [100] [ 0.000] [ 0.000] +[ 2208 37340 547 555] [100] [ 0.000] [ 0.001] +[ 1155 18804 285 291] [100] [ 0.000] [ 0.001] +[ 606 9272 149 154] [100] [ 0.000] [ 0.002] +[ 321 4636 79 82] [100] [ 0.000] [ 0.004] +[ 175 2312 43 46] [100] [ 0.000] [ 0.008] +[ 96 1166 23 25] [100] [ 0.000] [ 0.016] +nvtxs: 96, balance: 1.029 +nvtxs: 175, cut: 52846, balance: 1.034 +nvtxs: 321, cut: 49105, balance: 1.044 +nvtxs: 606, cut: 46830, balance: 1.049 +nvtxs: 1155, cut: 44937, balance: 1.007 +nvtxs: 2208, cut: 42026, balance: 1.010 +nvtxs: 4240, cut: 39423, balance: 1.004 +nvtxs: 8188, cut: 36607, balance: 1.003 +nvtxs: 15878, cut: 34521, balance: 1.004 +nvtxs: 30905, cut: 32557, balance: 1.003 +nvtxs: 60230, cut: 30095, balance: 1.003 +nvtxs: 117649, cut: 27431, balance: 1.003 + Setup: Max: 0.085, Sum: 0.288, Balance: 1.179 + Matching: Max: 0.328, Sum: 1.220, Balance: 1.073 +Contraction: Max: 0.424, Sum: 1.680, Balance: 1.010 + InitPart: Max: 0.035, Sum: 0.130, Balance: 1.060 + Project: Max: 0.065, Sum: 0.150, Balance: 1.731 + Initialize: Max: 0.188, Sum: 0.646, Balance: 1.164 + K-way: Max: 0.668, Sum: 2.591, Balance: 1.031 + Remap: Max: 0.015, Sum: 0.057, Balance: 1.066 + Total: Max: 2.030, Sum: 8.085, Balance: 1.004 +Final 4-way CUT: 27431 Balance: 1.003 avg: 1.003 + Mesh2Dual: Max: 0.899, Sum: 3.592, Balance: 1.001 + ParMETIS: Max: 2.192, Sum: 8.754, Balance: 1.002 + Total: Max: 3.091, Sum: 12.347, Balance: 1.001 + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/Makefile b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/Makefile new file mode 100644 index 0000000..eafd97a --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/Makefile @@ -0,0 +1,45 @@ +include ../Makefile.in + + +CFLAGS = $(COPTIONS) $(OPTFLAGS) -I. $(INCDIR) + + +OBJS = coarsen.o fm.o initpart.o match.o ccgraph.o \ + pmetis.o pqueue.o refine.o util.o timing.o debug.o \ + bucketsort.o graph.o stat.o kmetis.o kwayrefine.o \ + kwayfm.o balance.o ometis.o srefine.o sfm.o separator.o \ + mincover.o mmd.o mesh.o meshpart.o frename.o fortran.o \ + myqsort.o compress.o parmetis.o estmem.o \ + mpmetis.o mcoarsen.o mmatch.o minitpart.o mbalance.o \ + mutil.o mkmetis.o mkwayrefine.o mkwayfmh.o \ + mrefine2.o minitpart2.o mbalance2.o mfm2.o \ + kvmetis.o kwayvolrefine.o kwayvolfm.o subdomains.o \ + mfm.o memory.o mrefine.o checkgraph.o + +.c.o: + $(CC) $(CFLAGS) -c $*.c + +../libmetis.a: $(OBJS) + $(AR) $@ $(OBJS) + $(RANLIB) $@ + +clean: + rm -f *.o + +realclean: + rm -f *.o ; rm -f ../libmetis.a + + +checkin: + @for file in *.[c,h]; \ + do \ + ci -u -m'Maintance' $$file;\ + done + +checkin2: + @for file in *.[c,h]; \ + do \ + ci $$file;\ + rcs -U $$file;\ + co $$file;\ + done diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_checkgraph.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_checkgraph.c new file mode 100644 index 0000000..aea0094 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_checkgraph.c @@ -0,0 +1,127 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * checkgraph.c + * + * This file contains routines related to I/O + * + * Started 8/28/94 + * George + * + * $Id: NEW_checkgraph.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function checks if a graph is valid +**************************************************************************/ +int CheckGraph(GraphType *graph) +{ + int i, j, k, l; + int nvtxs, ncon, err=0; + int minedge, maxedge, minewgt, maxewgt; + float minvwgt[MAXNCON], maxvwgt[MAXNCON]; + idxtype *xadj, *adjncy, *adjwgt, *htable; + float *nvwgt, ntvwgts[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + htable = idxsmalloc(nvtxs, 0, "htable"); + + if (ncon > 1) { + for (j=0; j 1) { + for (j=0; j maxvwgt[j]) ? nvwgt[i*ncon+j] : maxvwgt[j]; + } + } + + for (j=xadj[i]; j maxedge) ? k : maxedge; + minewgt = (adjwgt[j] < minewgt) ? adjwgt[j] : minewgt; + maxewgt = (adjwgt[j] > maxewgt) ? adjwgt[j] : maxewgt; + + if (i == k) { + printf("Vertex %d contains a self-loop (i.e., diagonal entry in the matrix)!\n", i); + err++; + } + else { + for (l=xadj[k]; l 1) { + for (j=0; j 0.0001) { + printf("Normalized vwgts don't sum to one. Weight %d = %.8f.\n", j, ntvwgts[j]); + err++; + } + } + } + +/* + printf("errs: %d, adjncy: [%d %d], adjwgt: [%d %d]\n", + err, minedge, maxedge, minewgt, maxewgt); + if (ncon > 1) { + for (j=0; j 0) { + printf("A total of %d errors exist in the input file. Correct them, and run again!\n", err); + } + + GKfree(&htable, LTERM); + return (err == 0 ? 1 : 0); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_memory.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_memory.c new file mode 100644 index 0000000..aa03b9d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_memory.c @@ -0,0 +1,208 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * memory.c + * + * This file contains routines that deal with memory allocation + * + * Started 2/24/96 + * George + * + * $Id: NEW_memory.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts) +{ + ctrl->wspace.pmat = NULL; + + if (ctrl->optype == OP_KMETIS) { + ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases + Coarsening + Matching: 4*nvtxs vectors + Contraction: 2*nvtxs vectors (from the above 4), 1*nparts, 1*Nedges + Total = MAX(4*nvtxs, 2*nvtxs+nparts+nedges) + + Refinement + Random Refinement/Balance: 5*nparts + 1*nvtxs + 2*nedges + Greedy Refinement/Balance: 5*nparts + 2*nvtxs + 2*nedges + 1*PQueue(==Nvtxs) + Total = 5*nparts + 3*nvtxs + 2*nedges + + Total = 5*nparts + 3*nvtxs + 2*nedges + */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 5*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else if (ctrl->optype == OP_KVMETIS) { + ctrl->wspace.edegrees = NULL; + ctrl->wspace.vedegrees = (VEDegreeType *)GKmalloc(graph->nedges*sizeof(VEDegreeType), "AllocateWorkSpace: vedegrees"); + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.vedegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases are identical to KMETIS */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 3*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else { + ctrl->wspace.edegrees = (EDegreeType *)idxmalloc(graph->nedges, "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.maxcore = 5*(graph->nvtxs+1) + /* Refinement vectors */ + 4*(nparts+1) + /* Partition weights etc */ + 2*graph->ncon*graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* 2-way refinement */ + 2*graph->ncon*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)) + /* 2-way refinement */ + 20 /* padding for 64 bit machines */ + ; + } + + ctrl->wspace.maxcore += HTLENGTH; + ctrl->wspace.core = idxmalloc(ctrl->wspace.maxcore, "AllocateWorkSpace: maxcore"); + ctrl->wspace.ccore = 0; +} + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void FreeWorkSpace(CtrlType *ctrl, GraphType *graph) +{ + GKfree(&ctrl->wspace.edegrees, &ctrl->wspace.vedegrees, &ctrl->wspace.core, &ctrl->wspace.pmat, LTERM); +} + +/************************************************************************* +* This function returns how may words are left in the workspace +**************************************************************************/ +int WspaceAvail(CtrlType *ctrl) +{ + return ctrl->wspace.maxcore - ctrl->wspace.ccore; +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +idxtype *idxwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return ctrl->wspace.core + ctrl->wspace.ccore - n; +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void idxwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +float *fwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return (float *) (ctrl->wspace.core + ctrl->wspace.ccore - n); +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void fwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +GraphType *CreateGraph(void) +{ + GraphType *graph; + + graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph"); + + InitGraph(graph); + + return graph; +} + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +void InitGraph(GraphType *graph) +{ + graph->gdata = graph->rdata = NULL; + + graph->nvtxs = graph->nedges = -1; + graph->mincut = graph->minvol = -1; + + graph->xadj = graph->vwgt = graph->adjncy = graph->adjwgt = NULL; + graph->adjwgtsum = NULL; + graph->label = NULL; + graph->cmap = NULL; + + graph->where = graph->pwgts = NULL; + graph->id = graph->ed = NULL; + graph->bndptr = graph->bndind = NULL; + graph->rinfo = NULL; + graph->vrinfo = NULL; + graph->nrinfo = NULL; + + graph->ncon = -1; + graph->nvwgt = NULL; + graph->npwgts = NULL; + + graph->vsize = NULL; + + graph->coarser = graph->finer = NULL; + +} + +/************************************************************************* +* This function deallocates any memory stored in a graph +**************************************************************************/ +void FreeGraph(GraphType *graph) +{ + + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, LTERM); + free(graph); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_mfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_mfm.c new file mode 100644 index 0000000..9f37848 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_mfm.c @@ -0,0 +1,341 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mfm.c + * + * This file contains code that implements the edge-based FM refinement + * + * Started 7/23/97 + * George + * + * $Id: NEW_mfm.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, initcut, newcut, mincutorder; + float rtpwgts[2]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 25), 150); + + /* Initialize the queues */ + for (i=0; idbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, origbal); + } + + idxset(nvtxs, -1, moved); + for (pass=0; passmincut; + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + /* Insert boundary nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[i] == 0); + ASSERT(bndptr[i] != -1); + PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); + } + + for (nswaps=0; nswaps limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (l=0; l 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); + } + } + } + + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + for (i=0; i= maxdiff) { + maxdiff = npwgts[part*ncon+i]-tpwgts[part]; + *from = part; + *cnum = i; + } + } + } + + /* printf("Selected %d(%d) -> %d\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from])); */ + + if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { + /* The desired queue is empty, select a node from that side anyway */ + for (i=0; i 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + break; + } + } + + for (i++; i max && PQueueGetSize(&queues[i][*from]) > 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + } + } + } + + /* Check to see if you can focus on the cut */ + if (maxdiff <= 0.0 || *from == -1) { + maxgain = -100000; + + for (part=0; part<2; part++) { + for (i=0; i 0 && PQueueGetKey(&queues[i][part]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][part]); + *from = part; + *cnum = i; + } + } + } + } +} + + + + + +/************************************************************************* +* This function checks if the balance achieved is better than the diff +* For now, it uses a 2-norm measure +**************************************************************************/ +int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff) +{ + int i; + float ndiff[MAXNCON]; + + for (i=0; i + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i; + float tubvec[MAXNCON]; + + for (i=0; incon; i++) + tubvec[i] = 1.0; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + MocCompute2WayPartitionParams(ctrl, graph); + + for (;;) { + ASSERT(CheckBnd(graph)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + switch (ctrl->RType) { + case RTYPE_FM: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + break; + case 2: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8); + break; + default: + errexit("Unknown refinement type: %d\n", ctrl->RType); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + MocProject2WayPartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + MocBalance2Way(ctrl, graph, tpwgts, 1.01); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for 2-way edge refinement +**************************************************************************/ +void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) +{ + int nvtxs, ncon; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata"); + graph->where = graph->rdata; + graph->id = graph->rdata + nvtxs; + graph->ed = graph->rdata + 2*nvtxs; + graph->bndptr = graph->rdata + 3*nvtxs; + graph->bndind = graph->rdata + 4*nvtxs; + + graph->npwgts = fmalloc(2*ncon, "npwgts"); +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, l, nvtxs, ncon, nbnd, mincut; + idxtype *xadj, *adjncy, *adjwgt; + float *nvwgt, *npwgts; + idxtype *id, *ed, *where; + idxtype *bndptr, *bndind; + int me, other; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + npwgts = sset(2*ncon, 0.0, graph->npwgts); + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nbnd = mincut = 0; + for (i=0; i= 0 && where[i] <= 1); + me = where[i]; + saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); + + for (j=xadj[i]; j 0 || xadj[i] == xadj[i+1]) { + mincut += ed[i]; + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + + graph->mincut = mincut/2; + graph->nbnd = nbnd; + +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, nvtxs, nbnd, me; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; + idxtype *cwhere, *cid, *ced, *cbndptr; + GraphType *cgraph; + + cgraph = graph->coarser; + cwhere = cgraph->where; + cid = cgraph->id; + ced = cgraph->ed; + cbndptr = cgraph->bndptr; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + MocAllocate2WayPartitionMemory(ctrl, graph); + + where = graph->where; + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; i 0 || xadj[i] == xadj[i+1]) { + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + } + } + + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts); + + FreeGraph(graph->coarser); + graph->coarser = NULL; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_parmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_parmetis.c new file mode 100644 index 0000000..bd97917 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_parmetis.c @@ -0,0 +1,155 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * parmetis.c + * + * This file contains the top level routines for the multilevel recursive + * bisection algorithm PMETIS. + * + * Started 7/24/97 + * George + * + * $Id: NEW_parmetis.c,v 1.1 2003/07/16 15:55:14 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCPartGraphRecursive2(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *mytpwgts; +idxtype wgt[2048], minwgt, maxwgt, sumwgt; +float avgwgt; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + graph.npwgts = NULL; + mytpwgts = fmalloc(*nparts, "mytpwgts"); + scopy(*nparts, tpwgts, mytpwgts); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = McPMETIS_CTYPE; + ctrl.IType = McPMETIS_ITYPE; + ctrl.RType = McPMETIS_RTYPE; + ctrl.dbglvl = McPMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + ASSERT(CheckGraph(&graph)); + *edgecut = MCMlevelRecursiveBisection2(&ctrl, &graph, *nparts, mytpwgts, part, 1.000, 0); +/* +printf("nvtxs: %d, nparts: %d, ncon: %d\n", graph.nvtxs, *nparts, *ncon); +for (i=0; i<(*nparts)*(*ncon); i++) + wgt[i] = 0; +for (i=0; i wgt[maxwgt*(*ncon)+j]) ? i : maxwgt; + sumwgt += wgt[i*(*ncon)+j]; + } + avgwgt = (float)sumwgt / (float)*nparts; + printf("min: %5d, max: %5d, avg: %5.2f, balance: %6.3f\n", wgt[minwgt*(*ncon)+j], wgt[maxwgt*(*ncon)+j], avgwgt, (float)wgt[maxwgt*(*ncon)+j] / avgwgt); +} +printf("\n"); +*/ + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + GKfree((void *)&mytpwgts, LTERM); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCMlevelRecursiveBisection2(CtrlType *ctrl, GraphType *graph, int nparts, + float *tpwgts, idxtype *part, float ubfactor, int fpart) +{ + int i, nvtxs, cut; + float wsum, tpwgts2[2]; + idxtype *label, *where; + GraphType lgraph, rgraph; + + nvtxs = graph->nvtxs; + if (nvtxs == 0) { +/* printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); */ + return 0; + } + + /* Determine the weights of the partitions */ + tpwgts2[0] = ssum(nparts/2, tpwgts); + tpwgts2[1] = 1.0-tpwgts2[0]; + + MCMlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); + cut = graph->mincut; + + label = graph->label; + where = graph->where; + for (i=0; i 2) + SplitGraphPart(ctrl, graph, &lgraph, &rgraph); + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->label, &graph->npwgts, LTERM); + + /* Scale the fractions in the tpwgts according to the true weight */ + wsum = ssum(nparts/2, tpwgts); + sscale(nparts/2, 1.0/wsum, tpwgts); + sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2); + + /* Do the recursive call */ + if (nparts > 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &lgraph, nparts/2, tpwgts, part, ubfactor, fpart); + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); + } + + return cut; + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_stats.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_stats.c new file mode 100644 index 0000000..9e04b23 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/NEW_stats.c @@ -0,0 +1,44 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stat.c + * + * This file computes various statistics + * + * Started 7/25/97 + * George + * + * $Id: NEW_stats.c,v 1.1 2003/07/16 15:55:15 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function computes the balance of the partitioning +**************************************************************************/ +void Moc_ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) +{ + int i, j, nvtxs, ncon; + float *kpwgts, *nvwgt; + float balance; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + nvwgt = graph->nvwgt; + + kpwgts = fmalloc(nparts, "ComputePartitionInfo: kpwgts"); + + for (j=0; jnvtxs; i++) + kpwgts[where[i]] += nvwgt[i*ncon+j]; + + ubvec[j] = (float)nparts*kpwgts[samax(nparts, kpwgts)]/ssum(nparts, kpwgts); + } + + free(kpwgts); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/balance.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/balance.c new file mode 100644 index 0000000..ac951da --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/balance.c @@ -0,0 +1,278 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * balance.c + * + * This file contains code that is used to forcefully balance either + * bisections or k-sections + * + * Started 7/29/97 + * George + * + * $Id: balance.c,v 1.1 2003/07/16 15:54:58 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function is the entry point of the bisection balancing algorithms. +**************************************************************************/ +void Balance2Way(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + int i, j, nvtxs, from, imax, gain, mindiff; + idxtype *id, *ed; + + /* Return right away if the balance is OK */ + mindiff = abs(tpwgts[0]-graph->pwgts[0]); + if (mindiff < 3*(graph->pwgts[0]+graph->pwgts[1])/graph->nvtxs) + return; + if (graph->pwgts[0] > tpwgts[0] && graph->pwgts[0] < (int)(ubfactor*tpwgts[0])) + return; + if (graph->pwgts[1] > tpwgts[1] && graph->pwgts[1] < (int)(ubfactor*tpwgts[1])) + return; + + if (graph->nbnd > 0) + Bnd2WayBalance(ctrl, graph, tpwgts); + else + General2WayBalance(ctrl, graph, tpwgts); + +} + + + +/************************************************************************* +* This function balances two partitions by moving boundary nodes +* from the domain that is overweight to the one that is underweight. +**************************************************************************/ +void Bnd2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts) +{ + int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; + idxtype *moved, *perm; + PQueueType parts; + int higain, oldgain, mincut, mindiff; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + pwgts = graph->pwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + /* Determine from which domain you will be moving data */ + mindiff = abs(tpwgts[0]-pwgts[0]); + from = (pwgts[0] < tpwgts[0] ? 1 : 0); + to = (from+1)%2; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n", + pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; + PQueueInit(ctrl, &parts, nvtxs, tmp); + + idxset(nvtxs, -1, moved); + + ASSERT(ComputeCut(graph, where) == graph->mincut); + ASSERT(CheckBnd(graph)); + + /* Insert the boundary nodes of the proper partition whose size is OK in the priority queue */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[bndind[i]] == 0); + ASSERT(bndptr[bndind[i]] != -1); + if (where[bndind[i]] == from && vwgt[bndind[i]] <= mindiff) + PQueueInsert(&parts, bndind[i], ed[bndind[i]]-id[bndind[i]]); + } + + mincut = graph->mincut; + for (nswaps=0; nswaps tpwgts[to]) + break; + + mincut -= (ed[higain]-id[higain]); + INC_DEC(pwgts[to], pwgts[from], vwgt[higain]); + + where[higain] = to; + moved[higain] = nswaps; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, + printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1])); + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1 && where[k] == from && vwgt[k] <= mindiff) + PQueueInsert(&parts, k, ed[k]-id[k]); + } + } + } + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + PQueueFree(ctrl, &parts); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function balances two partitions by moving the highest gain +* (including negative gain) vertices to the other domain. +* It is used only when tha unbalance is due to non contigous +* subdomains. That is, the are no boundary vertices. +* It moves vertices from the domain that is overweight to the one that +* is underweight. +**************************************************************************/ +void General2WayBalance(CtrlType *ctrl, GraphType *graph, int *tpwgts) +{ + int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, tmp; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; + idxtype *moved, *perm; + PQueueType parts; + int higain, oldgain, mincut, mindiff; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + pwgts = graph->pwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + /* Determine from which domain you will be moving data */ + mindiff = abs(tpwgts[0]-pwgts[0]); + from = (pwgts[0] < tpwgts[0] ? 1 : 0); + to = (from+1)%2; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d [B]\n", + pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; + PQueueInit(ctrl, &parts, nvtxs, tmp); + + idxset(nvtxs, -1, moved); + + ASSERT(ComputeCut(graph, where) == graph->mincut); + ASSERT(CheckBnd(graph)); + + /* Insert the nodes of the proper partition whose size is OK in the priority queue */ + RandomPermute(nvtxs, perm, 1); + for (ii=0; iimincut; + nbnd = graph->nbnd; + for (nswaps=0; nswaps tpwgts[to]) + break; + + mincut -= (ed[higain]-id[higain]); + INC_DEC(pwgts[to], pwgts[from], vwgt[higain]); + + where[higain] = to; + moved[higain] = nswaps; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, + printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], mincut, pwgts[0], pwgts[1])); + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\tMinimum cut: %6d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + PQueueFree(ctrl, &parts); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/bucketsort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/bucketsort.c new file mode 100644 index 0000000..14aa213 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/bucketsort.c @@ -0,0 +1,43 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * bucketsort.c + * + * This file contains code that implement a variety of counting sorting + * algorithms + * + * Started 7/25/97 + * George + * + * $Id: bucketsort.c,v 1.1 2003/07/16 15:55:00 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function uses simple counting sort to return a permutation array +* corresponding to the sorted order. The keys are assumed to start from +* 0 and they are positive. This sorting is used during matching. +**************************************************************************/ +void BucketSortKeysInc(int n, int max, idxtype *keys, idxtype *tperm, idxtype *perm) +{ + int i, ii; + idxtype *counts; + + counts = idxsmalloc(max+2, 0, "BucketSortKeysInc: counts"); + + for (i=0; i + + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) +{ + int 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, starttimer(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, stoptimer(ctrl->ContractTmr)); + + idxwspacefree(ctrl, mask+1); + +} + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void CreateCoarseGraphNoMask(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) +{ + int 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, starttimer(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, stoptimer(ctrl->ContractTmr)); + + idxwspacefree(ctrl, cnvtxs); +} + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void CreateCoarseGraph_NVW(CtrlType *ctrl, GraphType *graph, int cnvtxs, idxtype *match, idxtype *perm) +{ + int 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, starttimer(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, stoptimer(ctrl->ContractTmr)); + + idxwspacefree(ctrl, mask+1); + +} + + +/************************************************************************* +* Setup the various arrays for the coarse graph +**************************************************************************/ +GraphType *SetUpCoarseGraph(GraphType *graph, int cnvtxs, int dovsize) +{ + GraphType *cgraph; + + cgraph = CreateGraph(); + cgraph->nvtxs = cnvtxs; + cgraph->ncon = graph->ncon; + + cgraph->finer = graph; + graph->coarser = cgraph; + + + /* Allocate memory for the coarser graph */ + if (graph->ncon == 1) { + if (dovsize) { + cgraph->gdata = idxmalloc(5*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); + cgraph->xadj = cgraph->gdata; + cgraph->vwgt = cgraph->gdata + cnvtxs+1; + cgraph->vsize = cgraph->gdata + 2*cnvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 3*cnvtxs+1; + cgraph->cmap = cgraph->gdata + 4*cnvtxs+1; + cgraph->adjncy = cgraph->gdata + 5*cnvtxs+1; + cgraph->adjwgt = cgraph->gdata + 5*cnvtxs+1 + graph->nedges; + } + else { + cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); + cgraph->xadj = cgraph->gdata; + cgraph->vwgt = cgraph->gdata + cnvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1; + cgraph->cmap = cgraph->gdata + 3*cnvtxs+1; + cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1; + cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges; + } + } + else { + if (dovsize) { + cgraph->gdata = idxmalloc(4*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); + cgraph->xadj = cgraph->gdata; + cgraph->vsize = cgraph->gdata + cnvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 2*cnvtxs+1; + cgraph->cmap = cgraph->gdata + 3*cnvtxs+1; + cgraph->adjncy = cgraph->gdata + 4*cnvtxs+1; + cgraph->adjwgt = cgraph->gdata + 4*cnvtxs+1 + graph->nedges; + } + else { + cgraph->gdata = idxmalloc(3*cnvtxs+1 + 2*graph->nedges, "SetUpCoarseGraph: gdata"); + cgraph->xadj = cgraph->gdata; + cgraph->adjwgtsum = cgraph->gdata + cnvtxs+1; + cgraph->cmap = cgraph->gdata + 2*cnvtxs+1; + cgraph->adjncy = cgraph->gdata + 3*cnvtxs+1; + cgraph->adjwgt = cgraph->gdata + 3*cnvtxs+1 + graph->nedges; + } + + cgraph->nvwgt = fmalloc(graph->ncon*cnvtxs, "SetUpCoarseGraph: nvwgt"); + } + + 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, int dovsize) +{ + + if (cgraph->nedges > 100000 && graph->nedges < 0.7*graph->nedges) { + idxcopy(cgraph->nedges, cgraph->adjwgt, cgraph->adjncy+cgraph->nedges); + + if (graph->ncon == 1) { + if (dovsize) { + cgraph->gdata = realloc(cgraph->gdata, (5*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); + + /* Do this, in case everything was copied into new space */ + cgraph->xadj = cgraph->gdata; + cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1; + cgraph->vsize = cgraph->gdata + 2*cgraph->nvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 3*cgraph->nvtxs+1; + cgraph->cmap = cgraph->gdata + 4*cgraph->nvtxs+1; + cgraph->adjncy = cgraph->gdata + 5*cgraph->nvtxs+1; + cgraph->adjwgt = cgraph->gdata + 5*cgraph->nvtxs+1 + cgraph->nedges; + } + else { + cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); + + /* Do this, in case everything was copied into new space */ + cgraph->xadj = cgraph->gdata; + cgraph->vwgt = cgraph->gdata + cgraph->nvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1; + cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1; + cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1; + cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges; + } + } + else { + if (dovsize) { + cgraph->gdata = realloc(cgraph->gdata, (4*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); + + /* Do this, in case everything was copied into new space */ + cgraph->xadj = cgraph->gdata; + cgraph->vsize = cgraph->gdata + cgraph->nvtxs+1; + cgraph->adjwgtsum = cgraph->gdata + 2*cgraph->nvtxs+1; + cgraph->cmap = cgraph->gdata + 3*cgraph->nvtxs+1; + cgraph->adjncy = cgraph->gdata + 4*cgraph->nvtxs+1; + cgraph->adjwgt = cgraph->gdata + 4*cgraph->nvtxs+1 + cgraph->nedges; + } + else { + cgraph->gdata = realloc(cgraph->gdata, (3*cgraph->nvtxs+1 + 2*cgraph->nedges)*sizeof(idxtype)); + + /* Do this, in case everything was copied into new space */ + cgraph->xadj = cgraph->gdata; + cgraph->adjwgtsum = cgraph->gdata + cgraph->nvtxs+1; + cgraph->cmap = cgraph->gdata + 2*cgraph->nvtxs+1; + cgraph->adjncy = cgraph->gdata + 3*cgraph->nvtxs+1; + cgraph->adjwgt = cgraph->gdata + 3*cgraph->nvtxs+1 + cgraph->nedges; + } + } + } + +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/checkgraph.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/checkgraph.c new file mode 100644 index 0000000..0134ec1 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/checkgraph.c @@ -0,0 +1,127 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * checkgraph.c + * + * This file contains routines related to I/O + * + * Started 8/28/94 + * George + * + * $Id: checkgraph.c,v 1.1 2003/07/24 18:39:06 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function checks if a graph is valid +**************************************************************************/ +int CheckGraph(GraphType *graph) +{ + int i, j, k, l; + int nvtxs, ncon, err=0; + int minedge, maxedge, minewgt, maxewgt; + float minvwgt[MAXNCON], maxvwgt[MAXNCON]; + idxtype *xadj, *adjncy, *adjwgt, *htable; + float *nvwgt, ntvwgts[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + htable = idxsmalloc(nvtxs, 0, "htable"); + + if (ncon > 1) { + for (j=0; j 1) { + for (j=0; j maxvwgt[j]) ? nvwgt[i*ncon+j] : maxvwgt[j]; + } + } + + for (j=xadj[i]; j maxedge) ? k : maxedge; + minewgt = (adjwgt[j] < minewgt) ? adjwgt[j] : minewgt; + maxewgt = (adjwgt[j] > maxewgt) ? adjwgt[j] : maxewgt; + + if (i == k) { + printf("Vertex %d contains a self-loop (i.e., diagonal entry in the matrix)!\n", i); + err++; + } + else { + for (l=xadj[k]; l 1) { + for (j=0; j 0.0001) { + printf("Normalized vwgts don't sum to one. Weight %d = %.8f.\n", j, ntvwgts[j]); + err++; + } + } + } + +/* + printf("errs: %d, adjncy: [%d %d], adjwgt: [%d %d]\n", + err, minedge, maxedge, minewgt, maxewgt); + if (ncon > 1) { + for (j=0; j 0) { + printf("A total of %d errors exist in the input file. Correct them, and run again!\n", err); + } + + GKfree(&htable, LTERM); + return (err == 0 ? 1 : 0); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/coarsen.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/coarsen.c new file mode 100644 index 0000000..15f06d3 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/coarsen.c @@ -0,0 +1,86 @@ +/* + * coarsen.c + * + * This file contains the driving routines for the coarsening process + * + * Started 7/23/97 + * George + * + * $Id: coarsen.c,v 1.2 2003/07/31 16:23:29 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function takes a graph and creates a sequence of coarser graphs +**************************************************************************/ +GraphType *Coarsen2Way(CtrlType *ctrl, GraphType *graph) +{ + int clevel; + GraphType *cgraph; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr)); + + cgraph = graph; + + /* The following is ahack to allow the multiple bisections to go through with correct + coarsening */ + if (ctrl->CType > 20) { + clevel = 1; + ctrl->CType -= 20; + } + else + clevel = 0; + + do { + IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n", + cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, + (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs))); + + if (cgraph->adjwgt) { + switch (ctrl->CType) { + case MATCH_RM: + Match_RM(ctrl, cgraph); + break; + case MATCH_HEM: + if (clevel < 1 || cgraph->nedges == 0) + Match_RM(ctrl, cgraph); + else + Match_HEM(ctrl, cgraph); + break; + case MATCH_SHEM: + if (clevel < 1 || cgraph->nedges == 0) + Match_RM(ctrl, cgraph); + else + Match_SHEM(ctrl, cgraph); + break; + case MATCH_SHEMKWAY: + if (cgraph->nedges == 0) + Match_RM(ctrl, cgraph); + else + Match_SHEM(ctrl, cgraph); + break; + default: + errexit("Unknown CType: %d\n", ctrl->CType); + } + } + else { + Match_RM_NVW(ctrl, cgraph); + } + + cgraph = cgraph->coarser; + clevel++; + + } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); + + IFSET(ctrl->dbglvl, DBG_COARSEN, printf("%6d %7d [%d] [%d %d]\n", + cgraph->nvtxs, cgraph->nedges, ctrl->CoarsenTo, ctrl->maxvwgt, + (cgraph->vwgt ? idxsum(cgraph->nvtxs, cgraph->vwgt) : cgraph->nvtxs))); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr)); + + return cgraph; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/compress.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/compress.c new file mode 100644 index 0000000..6b1cf13 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/compress.c @@ -0,0 +1,256 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * compress.c + * + * This file contains code for compressing nodes with identical adjacency + * structure and for prunning dense columns + * + * Started 9/17/97 + * George + * + * $Id: compress.c,v 1.1 2003/07/16 15:55:01 karypis Exp $ + */ + +#include + +/************************************************************************* +* This function compresses a graph by merging identical vertices +* The compression should lead to at least 10% reduction. +**************************************************************************/ +void CompressGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *cptr, idxtype *cind) +{ + int i, ii, iii, j, jj, k, l, cnvtxs, cnedges; + idxtype *cxadj, *cadjncy, *cvwgt, *mark, *map; + KeyValueType *keys; + + mark = idxsmalloc(nvtxs, -1, "CompressGraph: mark"); + map = idxsmalloc(nvtxs, -1, "CompressGraph: map"); + keys = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "CompressGraph: keys"); + + /* Compute a key for each adjacency list */ + for (i=0; i= COMPRESSION_FRACTION*nvtxs) { + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = 1; + graph->xadj = xadj; + graph->adjncy = adjncy; + + graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata"); + graph->vwgt = graph->gdata; + graph->adjwgtsum = graph->gdata+nvtxs; + graph->cmap = graph->gdata+2*nvtxs; + graph->adjwgt = graph->gdata+3*nvtxs; + + idxset(nvtxs, 1, graph->vwgt); + idxset(graph->nedges, 1, graph->adjwgt); + for (i=0; iadjwgtsum[i] = xadj[i+1]-xadj[i]; + + graph->label = idxmalloc(nvtxs, "CompressGraph: label"); + for (i=0; ilabel[i] = i; + } + else { /* Ok, form the compressed graph */ + cnedges = 0; + for (i=0; igdata = idxmalloc(4*cnvtxs+1 + 2*cnedges, "CompressGraph: gdata"); + cxadj = graph->xadj = graph->gdata; + cvwgt = graph->vwgt = graph->gdata + cnvtxs+1; + graph->adjwgtsum = graph->gdata + 2*cnvtxs+1; + graph->cmap = graph->gdata + 3*cnvtxs+1; + cadjncy = graph->adjncy = graph->gdata + 4*cnvtxs+1; + graph->adjwgt = graph->gdata + 4*cnvtxs+1 + cnedges; + + /* Now go and compress the graph */ + idxset(nvtxs, -1, mark); + l = cxadj[0] = 0; + for (i=0; invtxs = cnvtxs; + graph->nedges = l; + graph->ncon = 1; + + idxset(graph->nedges, 1, graph->adjwgt); + for (i=0; iadjwgtsum[i] = cxadj[i+1]-cxadj[i]; + + graph->label = idxmalloc(cnvtxs, "CompressGraph: label"); + for (i=0; ilabel[i] = i; + + } + + GKfree(&keys, &map, &mark, LTERM); +} + + + +/************************************************************************* +* This function prunes all the vertices in a graph with degree greater +* than factor*average +**************************************************************************/ +void PruneGraph(CtrlType *ctrl, GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *iperm, float factor) +{ + int i, j, k, l, nlarge, pnvtxs, pnedges; + idxtype *pxadj, *padjncy, *padjwgt, *pvwgt; + idxtype *perm; + + perm = idxmalloc(nvtxs, "PruneGraph: perm"); + + factor = factor*xadj[nvtxs]/nvtxs; + + pnvtxs = pnedges = nlarge = 0; + for (i=0; invtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = 1; + graph->xadj = xadj; + graph->adjncy = adjncy; + + graph->gdata = idxmalloc(3*nvtxs+graph->nedges, "CompressGraph: gdata"); + graph->vwgt = graph->gdata; + graph->adjwgtsum = graph->gdata+nvtxs; + graph->cmap = graph->gdata+2*nvtxs; + graph->adjwgt = graph->gdata+3*nvtxs; + + idxset(nvtxs, 1, graph->vwgt); + idxset(graph->nedges, 1, graph->adjwgt); + for (i=0; iadjwgtsum[i] = xadj[i+1]-xadj[i]; + + graph->label = idxmalloc(nvtxs, "CompressGraph: label"); + for (i=0; ilabel[i] = i; + } + else { /* Prune the graph */ + /* Allocate memory for the compressed graph*/ + graph->gdata = idxmalloc(4*pnvtxs+1 + 2*pnedges, "PruneGraph: gdata"); + pxadj = graph->xadj = graph->gdata; + graph->vwgt = graph->gdata + pnvtxs+1; + graph->adjwgtsum = graph->gdata + 2*pnvtxs+1; + graph->cmap = graph->gdata + 3*pnvtxs+1; + padjncy = graph->adjncy = graph->gdata + 4*pnvtxs+1; + graph->adjwgt = graph->gdata + 4*pnvtxs+1 + pnedges; + + pxadj[0] = pnedges = l = 0; + for (i=0; invtxs = pnvtxs; + graph->nedges = pnedges; + graph->ncon = 1; + + idxset(pnvtxs, 1, graph->vwgt); + idxset(pnedges, 1, graph->adjwgt); + for (i=0; iadjwgtsum[i] = pxadj[i+1]-pxadj[i]; + + graph->label = idxmalloc(pnvtxs, "CompressGraph: label"); + for (i=0; ilabel[i] = i; + } + + free(perm); + +} + + + + + + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/debug.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/debug.c new file mode 100644 index 0000000..b71fe2f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/debug.c @@ -0,0 +1,239 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * debug.c + * + * This file contains code that performs self debuging + * + * Started 7/24/97 + * George + * + * $Id: debug.c,v 1.1 2003/07/16 15:55:01 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function computes the cut given the graph and a where vector +**************************************************************************/ +int ComputeCut(GraphType *graph, idxtype *where) +{ + int i, j, cut; + + if (graph->adjwgt == NULL) { + for (cut=0, i=0; invtxs; i++) { + for (j=graph->xadj[i]; jxadj[i+1]; j++) + if (where[i] != where[graph->adjncy[j]]) + cut++; + } + } + else { + for (cut=0, i=0; invtxs; i++) { + for (j=graph->xadj[i]; jxadj[i+1]; j++) + if (where[i] != where[graph->adjncy[j]]) + cut += graph->adjwgt[j]; + } + } + + return cut/2; +} + + +/************************************************************************* +* This function checks whether or not the boundary information is correct +**************************************************************************/ +int CheckBnd(GraphType *graph) +{ + int i, j, nvtxs, nbnd; + idxtype *xadj, *adjncy, *where, *bndptr, *bndind; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + + for (nbnd=0, i=0; inbnd, ("%d %d\n", nbnd, graph->nbnd)); + + return 1; +} + + + +/************************************************************************* +* This function checks whether or not the boundary information is correct +**************************************************************************/ +int CheckBnd2(GraphType *graph) +{ + int i, j, nvtxs, nbnd, id, ed; + idxtype *xadj, *adjncy, *where, *bndptr, *bndind; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + + for (nbnd=0, i=0; iadjwgt[j]; + else + id += graph->adjwgt[j]; + } + if (ed - id >= 0 && xadj[i] < xadj[i+1]) { + nbnd++; + ASSERTP(bndptr[i] != -1, ("%d %d %d\n", i, id, ed)); + ASSERT(bndind[bndptr[i]] == i); + } + } + + ASSERTP(nbnd == graph->nbnd, ("%d %d\n", nbnd, graph->nbnd)); + + return 1; +} + +/************************************************************************* +* This function checks whether or not the boundary information is correct +**************************************************************************/ +int CheckNodeBnd(GraphType *graph, int onbnd) +{ + int i, j, nvtxs, nbnd; + idxtype *xadj, *adjncy, *where, *bndptr, *bndind; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + + for (nbnd=0, i=0; indegrees; i++) { + for (j=i+1; jndegrees; j++) + ASSERTP(rinfo->edegrees[i].pid != rinfo->edegrees[j].pid, ("%d %d %d %d\n", i, j, rinfo->edegrees[i].pid, rinfo->edegrees[j].pid)); + } + + return 1; +} + + + +/************************************************************************* +* This function checks the correctness of the NodeFM data structures +**************************************************************************/ +int CheckNodePartitionParams(GraphType *graph) +{ + int i, j, k, l, nvtxs, me, other; + idxtype *xadj, *adjncy, *adjwgt, *vwgt, *where; + idxtype edegrees[2], pwgts[3]; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + + /*------------------------------------------------------------ + / Compute now the separator external degrees + /------------------------------------------------------------*/ + pwgts[0] = pwgts[1] = pwgts[2] = 0; + for (i=0; inrinfo[i].edegrees[0] || edegrees[1] != graph->nrinfo[i].edegrees[1]) { + printf("Something wrong with edegrees: %d %d %d %d %d\n", i, edegrees[0], edegrees[1], graph->nrinfo[i].edegrees[0], graph->nrinfo[i].edegrees[1]); + return 0; + } + } + } + + if (pwgts[0] != graph->pwgts[0] || pwgts[1] != graph->pwgts[1] || pwgts[2] != graph->pwgts[2]) + printf("Something wrong with part-weights: %d %d %d %d %d %d\n", pwgts[0], pwgts[1], pwgts[2], graph->pwgts[0], graph->pwgts[1], graph->pwgts[2]); + + return 1; +} + + +/************************************************************************* +* This function checks if the separator is indeed a separator +**************************************************************************/ +int IsSeparable(GraphType *graph) +{ + int i, j, nvtxs, other; + idxtype *xadj, *adjncy, *where; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + for (i=0; i + +/************************************************************************* +* This function computes how much memory will be required by the various +* routines in METIS +**************************************************************************/ +void METIS_EstimateMemory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) +{ + int i, j, k, nedges, nlevels; + float vfraction, efraction, vmult, emult; + int coresize, gdata, rdata; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + nedges = xadj[*nvtxs]; + + InitRandom(-1); + EstimateCFraction(*nvtxs, xadj, adjncy, &vfraction, &efraction); + + /* Estimate the amount of memory for coresize */ + if (*optype == 2) + coresize = nedges; + else + coresize = 0; + coresize += nedges + 11*(*nvtxs) + 4*1024 + 2*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)); + coresize += 2*(*nvtxs); /* add some more fore other vectors */ + + gdata = nedges; /* Assume that the user does not pass weights */ + + nlevels = (int)(log(100.0/(*nvtxs))/log(vfraction) + .5); + vmult = 0.5 + (1.0 - pow(vfraction, nlevels))/(1.0 - vfraction); + emult = 1.0 + (1.0 - pow(efraction, nlevels+1))/(1.0 - efraction); + + gdata += vmult*4*(*nvtxs) + emult*2*nedges; + if ((vmult-1.0)*4*(*nvtxs) + (emult-1.0)*2*nedges < 5*(*nvtxs)) + rdata = 0; + else + rdata = 5*(*nvtxs); + + *nbytes = sizeof(idxtype)*(coresize+gdata+rdata+(*nvtxs)); + + if (*numflag == 1) + Change2FNumbering2(*nvtxs, xadj, adjncy); +} + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void EstimateCFraction(int nvtxs, idxtype *xadj, idxtype *adjncy, float *vfraction, float *efraction) +{ + int i, ii, j, cnvtxs, cnedges, maxidx; + idxtype *match, *cmap, *perm; + + cmap = idxmalloc(nvtxs, "cmap"); + match = idxsmalloc(nvtxs, UNMATCHED, "match"); + perm = idxmalloc(nvtxs, "perm"); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; ii + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void FM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, int *tpwgts, int npasses) +{ + int i, ii, j, k, kwgt, nvtxs, nbnd, nswaps, from, to, pass, me, limit, tmp; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind, *pwgts; + idxtype *moved, *swaps, *perm; + PQueueType parts[2]; + int higain, oldgain, mincut, mindiff, origdiff, initcut, newcut, mincutorder, avgvwgt; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + pwgts = graph->pwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 15), 100); + avgvwgt = amin((pwgts[0]+pwgts[1])/20, 2*(pwgts[0]+pwgts[1])/nvtxs); + + tmp = graph->adjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]; + PQueueInit(ctrl, &parts[0], nvtxs, tmp); + PQueueInit(ctrl, &parts[1], nvtxs, tmp); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] T[%6d %6d], Nv-Nb[%6d %6d]. ICut: %6d\n", + pwgts[0], pwgts[1], tpwgts[0], tpwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + origdiff = abs(tpwgts[0]-pwgts[0]); + idxset(nvtxs, -1, moved); + for (pass=0; passmincut; + mindiff = abs(tpwgts[0]-pwgts[0]); + + ASSERT(ComputeCut(graph, where) == graph->mincut); + ASSERT(CheckBnd(graph)); + + /* Insert boundary nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[bndind[i]] == 0); + ASSERT(bndptr[bndind[i]] != -1); + PQueueInsert(&parts[where[bndind[i]]], bndind[i], ed[bndind[i]]-id[bndind[i]]); + } + + for (nswaps=0; nswaps limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + INC_DEC(pwgts[from], pwgts[to], vwgt[higain]); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, + printf("Moved %6d from %d. [%3d %3d] %5d [%4d %4d]\n", higain, from, ed[higain]-id[higain], vwgt[higain], newcut, pwgts[0], pwgts[1])); + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + PQueueInsert(&parts[where[k]], k, ed[k]-id[k]); + } + } + } + + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + INC_DEC(pwgts[to], pwgts[(to+1)%2], vwgt[higain]); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\tMinimum cut: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + PQueueFree(ctrl, &parts[0]); + PQueueFree(ctrl, &parts[1]); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fortran.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fortran.c new file mode 100644 index 0000000..46ebefd --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/fortran.c @@ -0,0 +1,141 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * fortran.c + * + * This file contains code for the fortran to C interface + * + * Started 8/19/97 + * George + * + * $Id: fortran.c,v 1.1 2003/07/16 15:55:02 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function changes the numbering to start from 0 instead of 1 +**************************************************************************/ +void Change2CNumbering(int nvtxs, idxtype *xadj, idxtype *adjncy) +{ + int i, nedges; + + for (i=0; i<=nvtxs; i++) + xadj[i]--; + + nedges = xadj[nvtxs]; + for (i=0; i + + +void METIS_PARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} + + +void METIS_WPARTGRAPHRECURSIVE(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphrecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphrecursive_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphrecursive__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} + + + +void METIS_PARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_partgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} + + + +void METIS_WPARTGRAPHKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphkway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphkway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} +void metis_wpartgraphkway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, tpwgts, options, edgecut, part); +} + + + +void METIS_EDGEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_edgend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_edgend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_edgend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_EdgeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} + + + +void METIS_NODEND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_nodend(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_nodend_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} +void metis_nodend__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeND(nvtxs, xadj, adjncy, numflag, options, perm, iperm); +} + + + +void METIS_NODEWND(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); +} +void metis_nodewnd(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); +} +void metis_nodewnd_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); +} +void metis_nodewnd__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, int *numflag, int *options, idxtype *perm, idxtype *iperm) +{ + METIS_NodeWND(nvtxs, xadj, adjncy, vwgt, numflag, options, perm, iperm); +} + + + +void METIS_PARTMESHNODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshnodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshnodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshnodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshNodal(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} + + +void METIS_PARTMESHDUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshdual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshdual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} +void metis_partmeshdual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + METIS_PartMeshDual(ne, nn, elmnts, etype, numflag, nparts, edgecut, epart, npart); +} + + +void METIS_MESHTONODAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtonodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtonodal_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtonodal__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToNodal(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} + + +void METIS_MESHTODUAL(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtodual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtodual_(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} +void metis_meshtodual__(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, idxtype *dxadj, idxtype *dadjncy) +{ + METIS_MeshToDual(ne, nn, elmnts, etype, numflag, dxadj, dadjncy); +} + + +void METIS_ESTIMATEMEMORY(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) +{ + METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); +} +void metis_estimatememory(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) +{ + METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); +} +void metis_estimatememory_(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) +{ + METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); +} +void metis_estimatememory__(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *optype, int *nbytes) +{ + METIS_EstimateMemory(nvtxs, xadj, adjncy, numflag, optype, nbytes); +} + + + +void METIS_MCPARTGRAPHRECURSIVE(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_mcpartgraphrecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_mcpartgraphrecursive_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} +void metis_mcpartgraphrecursive__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphRecursive(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, part); +} + + +void METIS_MCPARTGRAPHKWAY(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); +} +void metis_mcpartgraphkway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); +} +void metis_mcpartgraphkway_(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); +} +void metis_mcpartgraphkway__(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *rubvec, int *options, int *edgecut, idxtype *part) +{ + METIS_mCPartGraphKway(nvtxs, ncon, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, rubvec, options, edgecut, part); +} + + +void METIS_PARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) +{ + METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); +} +void metis_partgraphvkaway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) +{ + METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); +} +void metis_partgraphvkaway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) +{ + METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); +} +void metis_partgraphvkaway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, int *options, int *volume, idxtype *part) +{ + METIS_PartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, options, volume, part); +} + +void METIS_WPARTGRAPHVKWAY(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) +{ + METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); +} +void metis_wpartgraphvkaway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) +{ + METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); +} +void metis_wpartgraphvkaway_(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) +{ + METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); +} +void metis_wpartgraphvkaway__(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *volume, idxtype *part) +{ + METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, tpwgts, options, volume, part); +} + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c new file mode 100644 index 0000000..9a93784 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/graph.c @@ -0,0 +1,616 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * graph.c + * + * This file contains functions that deal with setting up the graphs + * for METIS. + * + * Started 7/25/97 + * George + * + * $Id: graph.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, + idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag) +{ + int i, j, k, sum, gsize; + float *nvwgt; + idxtype tvwgt[MAXNCON]; + + if (OpType == OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) { + SetUpGraphKway(graph, nvtxs, xadj, adjncy); + return; + } + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + + if (ncon == 1) { /* We are in the non mC mode */ + gsize = 0; + if ((wgtflag&2) == 0) + gsize += nvtxs; + if ((wgtflag&1) == 0) + gsize += graph->nedges; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + + /* Create the vertex/edge weight vectors if they are not supplied */ + gsize = 0; + if ((wgtflag&2) == 0) { + vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vwgt = vwgt; + + if ((wgtflag&1) == 0) { + adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); + gsize += graph->nedges; + } + else + graph->adjwgt = adjwgt; + + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; iadjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + else { /* Set up the graph in MOC mode */ + gsize = 0; + if ((wgtflag&1) == 0) + gsize += graph->nedges; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + gsize = 0; + + for (i=0; invwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); + + for (i=0; iadjwgt = idxset(graph->nedges, 1, graph->gdata+gsize); + gsize += graph->nedges; + } + else + graph->adjwgt = adjwgt; + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; iadjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + + if (OpType != OP_KMETIS && OpType != OP_KVMETIS) { + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + + for (i=0; ilabel[i] = i; + } + +} + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy) +{ + int i; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = 1; + graph->xadj = xadj; + graph->vwgt = NULL; + graph->adjncy = adjncy; + graph->adjwgt = NULL; + + graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); + graph->adjwgtsum = graph->gdata; + graph->cmap = graph->gdata + nvtxs; + + /* Compute the initial values of the adjwgtsum */ + for (i=0; iadjwgtsum[i] = xadj[i+1]-xadj[i]; + +} + + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, + idxtype *adjncy, float *nvwgt, idxtype *adjwgt) +{ + int i, j, sum; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + graph->adjwgt = adjwgt; + + graph->nvwgt = fmalloc(nvtxs*ncon, "SetUpGraph2: graph->nvwgt"); + scopy(nvtxs*ncon, nvwgt, graph->nvwgt); + + graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata"); + + /* Compute the initial values of the adjwgtsum */ + graph->adjwgtsum = graph->gdata; + for (i=0; iadjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata+nvtxs; + + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + for (i=0; ilabel[i] = i; + +} + + +/************************************************************************* +* This function sets up the graph from the user input +**************************************************************************/ +void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, + idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag) +{ + int i, j, k, sum, gsize; + idxtype *adjwgt; + float *nvwgt; + idxtype tvwgt[MAXNCON]; + + InitGraph(graph); + + graph->nvtxs = nvtxs; + graph->nedges = xadj[nvtxs]; + graph->ncon = ncon; + graph->xadj = xadj; + graph->adjncy = adjncy; + + if (ncon == 1) { /* We are in the non mC mode */ + gsize = graph->nedges; /* This is for the edge weights */ + if ((wgtflag&2) == 0) + gsize += nvtxs; /* vwgts */ + if ((wgtflag&1) == 0) + gsize += nvtxs; /* vsize */ + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + + /* Create the vertex/edge weight vectors if they are not supplied */ + gsize = 0; + if ((wgtflag&2) == 0) { + vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vwgt = vwgt; + + if ((wgtflag&1) == 0) { + vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vsize = vsize; + + /* Allocate memory for edge weights and initialize them to the sum of the vsize */ + adjwgt = graph->adjwgt = graph->gdata+gsize; + gsize += graph->nedges; + + for (i=0; iadjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; iadjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + else { /* Set up the graph in MOC mode */ + gsize = graph->nedges; + if ((wgtflag&1) == 0) + gsize += nvtxs; + + gsize += 2*nvtxs; + + graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata"); + gsize = 0; + + /* Create the normalized vertex weights along each constrain */ + if ((wgtflag&2) == 0) + vwgt = idxsmalloc(nvtxs, 1, "SetUpGraph: vwgt"); + + for (i=0; invwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt"); + + for (i=0; ivsize = idxset(nvtxs, 1, graph->gdata); + gsize += nvtxs; + } + else + graph->vsize = vsize; + + /* Allocate memory for edge weights and initialize them to the sum of the vsize */ + adjwgt = graph->adjwgt = graph->gdata+gsize; + gsize += graph->nedges; + + for (i=0; iadjwgtsum = graph->gdata + gsize; + gsize += nvtxs; + + for (i=0; iadjwgtsum[i] = sum; + } + + graph->cmap = graph->gdata + gsize; + gsize += nvtxs; + + } + + if (OpType != OP_KVMETIS) { + graph->label = idxmalloc(nvtxs, "SetUpGraph: label"); + + for (i=0; ilabel[i] = i; + } + +} + + +/************************************************************************* +* This function randomly permutes the adjacency lists of a graph +**************************************************************************/ +void RandomizeGraph(GraphType *graph) +{ + int i, j, k, l, tmp, nvtxs; + idxtype *xadj, *adjncy, *adjwgt; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + for (i=0; invtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + cptr = idxmalloc(nvtxs+1, "IsConnected: cptr"); + + nleft = 0; + for (i=0; i 1 && report) { + printf("The graph has %d connected components in partition %d:\t", ncmps, pid); + for (i=0; ivwgt[queue[j]]; + printf("[%5d %5d] ", cptr[i+1]-cptr[i], wgt); + /* + if (cptr[i+1]-cptr[i] == 1) + printf("[%d %d] ", queue[cptr[i]], xadj[queue[cptr[i]]+1]-xadj[queue[cptr[i]]]); + */ + } + printf("\n"); + } + + GKfree(&touched, &queue, &cptr, LTERM); + + return (ncmps == 1 ? 1 : 0); +} + + +/************************************************************************* +* This function checks whether a graph is contigous or not +**************************************************************************/ +int IsConnected(CtrlType *ctrl, GraphType *graph, int report) +{ + int i, j, k, nvtxs, first, last; + idxtype *xadj, *adjncy, *touched, *queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + + touched[0] = 1; + queue[0] = 0; + first = 0; last = 1; + + while (first < last) { + i = queue[first++]; + for (j=xadj[i]; jnvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: touched"); + queue = idxmalloc(nvtxs, "IsConnected: queue"); + cptr = idxmalloc(nvtxs+1, "IsConnected: cptr"); + + nleft = nvtxs; + touched[0] = 1; + queue[0] = 0; + first = 0; last = 1; + + cptr[0] = 0; /* This actually points to queue */ + ncmps = 0; + while (first != nleft) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + for (i=0; i 1 && report) { + printf("%d connected components:\t", ncmps); + for (i=0; i 200) + printf("[%5d] ", cptr[i+1]-cptr[i]); + } + printf("\n"); + } + + GKfree(&touched, &queue, &cptr, LTERM); + + return (ncmps == 1 ? 1 : 0); +} + + +/************************************************************************* +* This function returns the number of connected components in cptr,cind +* The separator of the graph is used to split it and then find its components. +**************************************************************************/ +int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind) +{ + int i, j, k, nvtxs, first, last, nleft, ncmps, wgt; + idxtype *xadj, *adjncy, *where, *touched, *queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + touched = idxsmalloc(nvtxs, 0, "IsConnected: queue"); + + for (i=0; inbnd; i++) + touched[graph->bndind[i]] = 1; + + queue = cind; + + nleft = 0; + for (i=0; i + +/************************************************************************* +* This function computes the initial bisection of the coarsest graph +**************************************************************************/ +void Init2WayPartition(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + int dbglvl; + + dbglvl = ctrl->dbglvl; + IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); + IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + switch (ctrl->IType) { + case IPART_GGPKL: + if (graph->nedges == 0) + RandomBisection(ctrl, graph, tpwgts, ubfactor); + else + GrowBisection(ctrl, graph, tpwgts, ubfactor); + break; + case 3: + RandomBisection(ctrl, graph, tpwgts, ubfactor); + break; + default: + errexit("Unknown initial partition type: %d\n", ctrl->IType); + } + + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + ctrl->dbglvl = dbglvl; + +/* + IsConnectedSubdomain(ctrl, graph, 0); + IsConnectedSubdomain(ctrl, graph, 1); +*/ +} + +/************************************************************************* +* This function computes the initial bisection of the coarsest graph +**************************************************************************/ +void InitSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int dbglvl; + + dbglvl = ctrl->dbglvl; + IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); + IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + GrowBisectionNode(ctrl, graph, ubfactor); + Compute2WayNodePartitionParams(ctrl, graph); + + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Sep: %d\n", graph->mincut)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + + ctrl->dbglvl = dbglvl; + +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void GrowBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; + idxtype *queue, *touched, *gain, *bestwhere; + + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + Allocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + queue = idxmalloc(nvtxs, "BisectGraph: queue"); + touched = idxmalloc(nvtxs, "BisectGraph: touched"); + + ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); + + maxpwgt[0] = ubfactor*tpwgts[0]; + maxpwgt[1] = ubfactor*tpwgts[1]; + minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; + minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; + + nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ + for (; nbfs>0; nbfs--) { + idxset(nvtxs, 0, touched); + + pwgts[1] = tpwgts[0]+tpwgts[1]; + pwgts[0] = 0; + + idxset(nvtxs, 1, where); + + queue[0] = RandomInRange(nvtxs); + touched[queue[0]] = 1; + first = 0; last = 1; + nleft = nvtxs-1; + drain = 0; + + /* Start the BFS from queue to get a partition */ + for (;;) { + if (first == last) { /* Empty. Disconnected graph! */ + if (nleft == 0 || drain) + break; + + k = RandomInRange(nleft); + for (i=0; i 0 && pwgts[1]-vwgt[i] < minpwgt[1]) { + drain = 1; + continue; + } + + where[i] = 0; + INC_DEC(pwgts[0], pwgts[1], vwgt[i]); + if (pwgts[1] <= maxpwgt[1]) + break; + + drain = 0; + for (j=xadj[i]; jnvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ + + Balance2Way(ctrl, graph, tpwgts, ubfactor); + /*printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ + + FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); + /*printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut);*/ + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, &queue, &touched, LTERM); +} + + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void GrowBisectionNode(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int i, j, k, nvtxs, drain, nleft, first, last, pwgts[2], tpwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where, *bndind; + idxtype *queue, *touched, *gain, *bestwhere; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + queue = idxmalloc(nvtxs, "BisectGraph: queue"); + touched = idxmalloc(nvtxs, "BisectGraph: touched"); + + tpwgts[0] = idxsum(nvtxs, vwgt); + tpwgts[1] = tpwgts[0]/2; + tpwgts[0] -= tpwgts[1]; + + maxpwgt[0] = ubfactor*tpwgts[0]; + maxpwgt[1] = ubfactor*tpwgts[1]; + minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; + minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; + + /* Allocate memory for graph->rdata. Allocate sufficient memory for both edge and node */ + graph->rdata = idxmalloc(5*nvtxs+3, "GrowBisectionNode: graph->rdata"); + graph->pwgts = graph->rdata; + graph->where = graph->rdata + 3; + graph->bndptr = graph->rdata + nvtxs + 3; + graph->bndind = graph->rdata + 2*nvtxs + 3; + graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3); + graph->id = graph->rdata + 3*nvtxs + 3; + graph->ed = graph->rdata + 4*nvtxs + 3; + + where = graph->where; + bndind = graph->bndind; + + nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = tpwgts[0]+tpwgts[1]; + for (nbfs++; nbfs>0; nbfs--) { + idxset(nvtxs, 0, touched); + + pwgts[1] = tpwgts[0]+tpwgts[1]; + pwgts[0] = 0; + + idxset(nvtxs, 1, where); + + queue[0] = RandomInRange(nvtxs); + touched[queue[0]] = 1; + first = 0; last = 1; + nleft = nvtxs-1; + drain = 0; + + /* Start the BFS from queue to get a partition */ + if (nbfs >= 1) { + for (;;) { + if (first == last) { /* Empty. Disconnected graph! */ + if (nleft == 0 || drain) + break; + + k = RandomInRange(nleft); + for (i=0; inbnd; i++) + where[bndind[i]] = 2; + + Compute2WayNodePartitionParams(ctrl, graph); + FM_2WayNodeRefine(ctrl, graph, ubfactor, 6); + + /* printf("ISep: [%d %d %d] %d\n", graph->pwgts[0], graph->pwgts[1], graph->pwgts[2], bestcut); */ + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + Compute2WayNodePartitionParams(ctrl, graph); + + GKfree(&bestwhere, &queue, &touched, LTERM); +} + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void RandomBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + int i, ii, j, k, nvtxs, pwgts[2], minpwgt[2], maxpwgt[2], from, bestcut, icut, mincut, me, pass, nbfs; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *where; + idxtype *perm, *bestwhere; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + Allocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + perm = idxmalloc(nvtxs, "BisectGraph: queue"); + + ASSERTP(tpwgts[0]+tpwgts[1] == idxsum(nvtxs, vwgt), ("%d %d\n", tpwgts[0]+tpwgts[1], idxsum(nvtxs, vwgt))); + + maxpwgt[0] = ubfactor*tpwgts[0]; + maxpwgt[1] = ubfactor*tpwgts[1]; + minpwgt[0] = (1.0/ubfactor)*tpwgts[0]; + minpwgt[1] = (1.0/ubfactor)*tpwgts[1]; + + nbfs = (nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(nvtxs, graph->adjwgtsum)+1; /* The +1 is for the 0 edges case */ + for (; nbfs>0; nbfs--) { + RandomPermute(nvtxs, perm, 1); + + idxset(nvtxs, 1, where); + pwgts[1] = tpwgts[0]+tpwgts[1]; + pwgts[0] = 0; + + + if (nbfs != 1) { + for (ii=0; ii minpwgt[0]) + break; + } + } + } + + /************************************************************* + * Do some partition refinement + **************************************************************/ + Compute2WayPartitionParams(ctrl, graph); + /* printf("IPART: %3d [%5d %5d] [%5d %5d] %5d\n", graph->nvtxs, pwgts[0], pwgts[1], graph->pwgts[0], graph->pwgts[1], graph->mincut); */ + + Balance2Way(ctrl, graph, tpwgts, ubfactor); + /* printf("BPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ + + FM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); + /* printf("RPART: [%5d %5d] %5d\n", graph->pwgts[0], graph->pwgts[1], graph->mincut); */ + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, &perm, LTERM); +} + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kmetis.c new file mode 100644 index 0000000..87c3a59 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kmetis.c @@ -0,0 +1,129 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * kmetis.c + * + * This file contains the top level routines for the multilevel k-way partitioning + * algorithm KMETIS. + * + * Started 7/28/97 + * George + * + * $Id: kmetis.c,v 1.1 2003/07/16 15:55:04 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for KMETIS +**************************************************************************/ +void METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ + int i; + float *tpwgts; + + tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); + for (i=0; i<*nparts; i++) + tpwgts[i] = 1.0/(1.0*(*nparts)); + + METIS_WPartGraphKway(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, + tpwgts, options, edgecut, part); + + free(tpwgts); +} + + +/************************************************************************* +* This function is the entry point for KWMETIS +**************************************************************************/ +void METIS_WPartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = KMETIS_CTYPE; + ctrl.IType = KMETIS_ITYPE; + ctrl.RType = KMETIS_RTYPE; + ctrl.dbglvl = KMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_KMETIS; + ctrl.CoarsenTo = amax((*nvtxs)/(40*log2Int(*nparts)), 20*(*nparts)); + ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor) +{ + int i, j, nvtxs, tvwgt, tpwgts2[2]; + GraphType *cgraph; + int wgtflag=3, numflag=0, options[10], edgecut; + + cgraph = Coarsen2Way(ctrl, graph); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + AllocateKWayPartitionMemory(ctrl, cgraph, nparts); + + options[0] = 1; + options[OPTION_CTYPE] = MATCH_SHEMKWAY; + options[OPTION_ITYPE] = IPART_GGPKL; + options[OPTION_RTYPE] = RTYPE_FM; + options[OPTION_DBGLVL] = 0; + + METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, + cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, + &edgecut, cgraph->where); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); + + IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); + + RefineKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor); + + idxcopy(graph->nvtxs, graph->where, part); + + GKfree(&graph->gdata, &graph->rdata, LTERM); + + return graph->mincut; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kvmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kvmetis.c new file mode 100644 index 0000000..5bc0a67 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kvmetis.c @@ -0,0 +1,130 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * kvmetis.c + * + * This file contains the top level routines for the multilevel k-way partitioning + * algorithm KMETIS. + * + * Started 7/28/97 + * George + * + * $Id: kvmetis.c,v 1.1 2003/07/16 15:55:04 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for KMETIS +**************************************************************************/ +void METIS_PartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *vsize, int *wgtflag, int *numflag, int *nparts, + int *options, int *volume, idxtype *part) +{ + int i; + float *tpwgts; + + tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); + for (i=0; i<*nparts; i++) + tpwgts[i] = 1.0/(1.0*(*nparts)); + + METIS_WPartGraphVKway(nvtxs, xadj, adjncy, vwgt, vsize, wgtflag, numflag, nparts, + tpwgts, options, volume, part); + + free(tpwgts); +} + + +/************************************************************************* +* This function is the entry point for KWMETIS +**************************************************************************/ +void METIS_WPartGraphVKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *vsize, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *volume, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + VolSetUpGraph(&graph, OP_KVMETIS, *nvtxs, 1, xadj, adjncy, vwgt, vsize, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = KVMETIS_CTYPE; + ctrl.IType = KVMETIS_ITYPE; + ctrl.RType = KVMETIS_RTYPE; + ctrl.dbglvl = KVMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_KVMETIS; + ctrl.CoarsenTo = amax((*nvtxs)/(40*log2Int(*nparts)), 20*(*nparts)); + ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *volume = MlevelVolKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.03); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MlevelVolKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, + float *tpwgts, float ubfactor) +{ + int i, j, nvtxs, tvwgt, tpwgts2[2]; + GraphType *cgraph; + int wgtflag=3, numflag=0, options[10], edgecut; + + cgraph = Coarsen2Way(ctrl, graph); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + AllocateVolKWayPartitionMemory(ctrl, cgraph, nparts); + + options[0] = 1; + options[OPTION_CTYPE] = MATCH_SHEMKWAY; + options[OPTION_ITYPE] = IPART_GGPKL; + options[OPTION_RTYPE] = RTYPE_FM; + options[OPTION_DBGLVL] = 0; + + METIS_WPartGraphRecursive(&cgraph->nvtxs, cgraph->xadj, cgraph->adjncy, cgraph->vwgt, + cgraph->adjwgt, &wgtflag, &numflag, &nparts, tpwgts, options, + &edgecut, cgraph->where); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); + + IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); + + RefineVolKWay(ctrl, graph, cgraph, nparts, tpwgts, ubfactor); + + idxcopy(graph->nvtxs, graph->where, part); + + GKfree(&graph->gdata, &graph->rdata, LTERM); + + return graph->minvol; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayfm.c new file mode 100644 index 0000000..170dcf3 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayfm.c @@ -0,0 +1,672 @@ +/* + * kwayfm.c + * + * This file contains code that implements the multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: kwayfm.c,v 1.1 2003/07/16 15:55:04 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Random_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; + int from, me, to, oldcut, vwgt, gain; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts; + EDegreeType *myedegrees; + RInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + for (i=0; idbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut)); + + for (pass=0; passmincut); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (nmoves=iii=0; iiinbnd; iii++) { + ii = perm[iii]; + if (ii >= nbnd) + continue; + i = bndind[ii]; + + myrinfo = graph->rinfo+i; + + if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ + from = where[i]; + vwgt = graph->vwgt[i]; + + if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + j = myrinfo->id; + for (k=0; kid. Allow good nodes to move */ + if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || + (myedegrees[j].ed == myedegrees[k].ed && + itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) + k = j; + } + + to = myedegrees[k].pid; + + j = 0; + if (myedegrees[k].ed-myrinfo->id > 0) + j = 1; + else if (myedegrees[k].ed-myrinfo->id == 0) { + if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) + j = 1; + } + if (j == 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + INC_DEC(pwgts[to], pwgts[from], vwgt); + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed-myrinfo->id < 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + + } + nmoves++; + } + } + + graph->nbnd = nbnd; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, ComputeVolume(graph, where))); + + if (graph->mincut == oldcut) + break; + } + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); +} + + + + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Greedy_KWayEdgeRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain; + int from, me, to, oldcut, vwgt; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; + EDegreeType *myedegrees; + RInfoType *myrinfo; + PQueueType queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut)); + + for (pass=0; passmincut); + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iirinfo[i].ed - graph->rinfo[i].id); + moved[i] = 2; + } + + for (iii=0;;iii++) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->rinfo+i; + from = where[i]; + vwgt = graph->vwgt[i]; + + if (pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + j = myrinfo->id; + for (k=0; kid. Allow good nodes to move */ + if (pwgts[to]+vwgt <= maxwgt[to]+gain && gain >= 0) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || + (myedegrees[j].ed == myedegrees[k].ed && + itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) + k = j; + } + + to = myedegrees[k].pid; + + j = 0; + if (myedegrees[k].ed-myrinfo->id > 0) + j = 1; + else if (myedegrees[k].ed-myrinfo->id == 0) { + if ((iii&7) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) + j = 1; + } + if (j == 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + INC_DEC(pwgts[to], pwgts[from], vwgt); + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed < myrinfo->id) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + oldgain = (myrinfo->ed-myrinfo->id); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + /* Update the queue */ + if (me == to || me == from) { + gain = myrinfo->ed-myrinfo->id; + if (moved[ii] == 2) { + if (gain >= 0) + PQueueUpdate(&queue, ii, oldgain, gain); + else { + PQueueDelete(&queue, ii, oldgain); + moved[ii] = -1; + } + } + else if (moved[ii] == -1 && gain >= 0) { + PQueueInsert(&queue, ii, gain); + moved[ii] = 2; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + + } + } + + graph->nbnd = nbnd; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Cut: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, graph->mincut)); + + if (graph->mincut == oldcut) + break; + } + + PQueueFree(ctrl, &queue); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + +} + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Greedy_KWayEdgeBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; + int from, me, to, oldcut, vwgt; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; + EDegreeType *myedegrees; + RInfoType *myrinfo; + PQueueType queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut)); + + for (pass=0; passmincut); + + /* Check to see if things are out of balance, given the tolerance */ + for (i=0; i maxwgt[i]) + break; + } + if (i == nparts) /* Things are balanced. Return right away */ + break; + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iirinfo[i].ed - graph->rinfo[i].id); + moved[i] = 2; + } + + nmoves = 0; + for (;;) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->rinfo+i; + from = where[i]; + vwgt = graph->vwgt[i]; + + if (pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; k minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + INC_DEC(pwgts[to], pwgts[from], vwgt); + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed == 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + oldgain = (myrinfo->ed-myrinfo->id); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed > 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed == 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + /* Update the queue */ + if (me == to || me == from) { + gain = myrinfo->ed-myrinfo->id; + if (moved[ii] == 2) { + if (myrinfo->ed > 0) + PQueueUpdate(&queue, ii, oldgain, gain); + else { + PQueueDelete(&queue, ii, oldgain); + moved[ii] = -1; + } + } + else if (moved[ii] == -1 && myrinfo->ed > 0) { + PQueueInsert(&queue, ii, gain); + moved[ii] = 2; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + } + nmoves++; + } + + graph->nbnd = nbnd; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut)); + } + + PQueueFree(ctrl, &queue); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayrefine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayrefine.c new file mode 100644 index 0000000..a6d58f7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayrefine.c @@ -0,0 +1,392 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * kwayrefine.c + * + * This file contains the driving routines for multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: kwayrefine.c,v 1.1 2003/07/16 15:55:05 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void RefineKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, float *tpwgts, float ubfactor) +{ + int i, nlevels, mustfree=0; + GraphType *ptr; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + ComputeKWayPartitionParams(ctrl, graph, nparts); + + /* Take care any non-contiguity */ + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr1)); + if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { + EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25); + EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts); + EliminateComponents(ctrl, graph, nparts, tpwgts, 1.25); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr1)); + + /* Determine how many levels are there */ + for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); + + for (i=0; ;i++) { + /* PrintSubDomainGraph(graph, nparts, graph->where); */ + if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN && (i == nlevels/2 || i == nlevels/2+1)) + EliminateSubDomainEdges(ctrl, graph, nparts, tpwgts); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + + if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) { + ComputeKWayBalanceBoundary(ctrl, graph, nparts); + if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) + Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); + else + Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); + ComputeKWayBoundary(ctrl, graph, nparts); + } + + switch (ctrl->RType) { + case RTYPE_KWAYRANDOM: + Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); + break; + case RTYPE_KWAYGREEDY: + Greedy_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10); + break; + case RTYPE_KWAYRANDOM_MCONN: + Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); + break; + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + GKfree(&graph->gdata, LTERM); /* Deallocate the graph related arrays */ + + graph = graph->finer; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + if (graph->vwgt == NULL) { + graph->vwgt = idxsmalloc(graph->nvtxs, 1, "RefineKWay: graph->vwgt"); + graph->adjwgt = idxsmalloc(graph->nedges, 1, "RefineKWay: graph->adjwgt"); + mustfree = 1; + } + ProjectKWayPartition(ctrl, graph, nparts); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) { + ComputeKWayBalanceBoundary(ctrl, graph, nparts); + if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { + Greedy_KWayEdgeBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); + Random_KWayEdgeRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); + } + else { + Greedy_KWayEdgeBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); + Random_KWayEdgeRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); + } + } + + /* Take care any trivial non-contiguity */ + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr2)); + EliminateComponents(ctrl, graph, nparts, tpwgts, ubfactor); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr2)); + + if (mustfree) + GKfree(&graph->vwgt, &graph->adjwgt, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for k-way edge refinement +**************************************************************************/ +void AllocateKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int nvtxs, pad64; + + nvtxs = graph->nvtxs; + + pad64 = (3*nvtxs+nparts)%2; + + graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(RInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateKWayPartitionMemory: rdata"); + graph->pwgts = graph->rdata; + graph->where = graph->rdata + nparts; + graph->bndptr = graph->rdata + nvtxs + nparts; + graph->bndind = graph->rdata + 2*nvtxs + nparts; + graph->rinfo = (RInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64); + +/* + if (ctrl->wspace.edegrees != NULL) + free(ctrl->wspace.edegrees); + ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateKWayPartitionMemory: edegrees"); +*/ +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void ComputeKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, j, k, l, nvtxs, nbnd, mincut, me, other; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where, *bndind, *bndptr; + RInfoType *rinfo, *myrinfo; + EDegreeType *myedegrees; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = idxset(nparts, 0, graph->pwgts); + 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; iid = myrinfo->ed = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + for (j=xadj[i]; jed += 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]; jndegrees; 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 ProjectKWayPartition(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; + + AllocateKWayPartitionMemory(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; iwspace.cdegree = 0; + for (nbnd=0, i=0; iid = 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; jed += 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; jpwgts, graph->pwgts); + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + + FreeGraph(graph->coarser); + graph->coarser = NULL; + + idxwspacefree(ctrl, nparts); + + ASSERT(CheckBnd2(graph)); + +} + + + +/************************************************************************* +* This function checks if the partition weights are within the balance +* contraints +**************************************************************************/ +int IsBalanced(idxtype *pwgts, int nparts, float *tpwgts, float ubfactor) +{ + int i, j, tvwgt; + + tvwgt = idxsum(nparts, pwgts); + for (i=0; i tpwgts[i]*tvwgt*(ubfactor+0.005)) + return 0; + } + + return 1; +} + + +/************************************************************************* +* This function computes the boundary definition for balancing +**************************************************************************/ +void ComputeKWayBoundary(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; irinfo[i].ed-graph->rinfo[i].id >= 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + +/************************************************************************* +* This function computes the boundary definition for balancing +**************************************************************************/ +void ComputeKWayBalanceBoundary(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; irinfo[i].ed > 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolfm.c new file mode 100644 index 0000000..4e1112d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolfm.c @@ -0,0 +1,1778 @@ +/* + * kwayvolfm.c + * + * This file contains code that implements the multilevel k-way refinement + * + * Started 7/8/98 + * George + * + * $Id: kwayvolfm.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Random_KWayVolRefine(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, + float ubfactor, int npasses, int ffactor) +{ + int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; + int from, me, to, oldcut, oldvol, vwgt; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; + VEDegreeType *myedegrees; + VRInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); + marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); + phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); + + for (i=0; idbglvl, DBG_REFINE, + printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut, graph->minvol)); + + for (pass=0; passmincut); + + oldcut = graph->mincut; + oldvol = graph->minvol; + + RandomPermute(graph->nbnd, perm, 1); + for (nmoves=iii=0; iiinbnd; iii++) { + ii = perm[iii]; + if (ii >= graph->nbnd) + continue; + i = bndind[ii]; + myrinfo = graph->vrinfo+i; + + if (myrinfo->gv >= 0) { /* Total volume gain is too high */ + from = where[i]; + vwgt = graph->vwgt[i]; + + if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; k= 0) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j maxwgt[to]) + continue; + if (myedegrees[j].gv > myedegrees[k].gv || + (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) || + (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed && + itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) + k = j; + } + + to = myedegrees[k].pid; + + j = 0; + if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0) + j = 1; + else if (myedegrees[k].ed-myrinfo->id == 0) { + if ((iii&5) == 0 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) + j = 1; + } + if (j == 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + INC_DEC(pwgts[to], pwgts[from], vwgt); + graph->mincut -= myedegrees[k].ed-myrinfo->id; + graph->minvol -= (xgain+myedegrees[k].gv); + where[i] = to; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", + i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); + + KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); + + nmoves++; + + /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */ + } + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, + graph->minvol)); + + if (graph->minvol == oldvol && graph->mincut == oldcut) + break; + } + + GKfree(&marker, &updind, &phtable, LTERM); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Random_KWayVolRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, + float ubfactor, int npasses, int ffactor) +{ + int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; + int from, me, to, oldcut, oldvol, vwgt, nadd, maxndoms; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; + idxtype *pmat, *pmatptr, *ndoms; + VEDegreeType *myedegrees; + VRInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); + marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); + phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); + + pmat = ctrl->wspace.pmat; + ndoms = idxwspacemalloc(ctrl, nparts); + + ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms); + + for (i=0; idbglvl, DBG_REFINE, + printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut, graph->minvol)); + + for (pass=0; passmincut); + + maxndoms = ndoms[idxamax(nparts, ndoms)]; + + oldcut = graph->mincut; + oldvol = graph->minvol; + + RandomPermute(graph->nbnd, perm, 1); + for (nmoves=iii=0; iiinbnd; iii++) { + ii = perm[iii]; + if (ii >= graph->nbnd) + continue; + i = bndind[ii]; + myrinfo = graph->vrinfo+i; + + if (myrinfo->gv >= 0) { /* Total volume gain is too high */ + from = where[i]; + vwgt = graph->vwgt[i]; + + if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + /* Determine the valid domains */ + for (j=0; j maxndoms-1) { + phtable[to] = 0; + nadd = maxndoms; + break; + } + nadd++; + } + } + if (ndoms[to]+nadd > maxndoms) + phtable[to] = 0; + if (nadd == 0) + phtable[to] = 2; + } + + for (k=0; k= 0) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j maxwgt[to]) + continue; + if (myedegrees[j].gv > myedegrees[k].gv || + (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed > myedegrees[k].ed) || + (myedegrees[j].gv == myedegrees[k].gv && myedegrees[j].ed == myedegrees[k].ed && + itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) + k = j; + } + + to = myedegrees[k].pid; + + j = 0; + if (xgain+myedegrees[k].gv > 0 || myedegrees[k].ed-myrinfo->id > 0) + j = 1; + else if (myedegrees[k].ed-myrinfo->id == 0) { + if ((iii&5) == 0 || phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) + j = 1; + } + + if (j == 0) + continue; + + for (j=0; jmincut -= myedegrees[k].ed-myrinfo->id; + graph->minvol -= (xgain+myedegrees[k].gv); + where[i] = to; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", + i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); + + /* Update pmat to reflect the move of 'i' */ + pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); + pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); + if (pmat[from*nparts+to] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[to*nparts+from] == 0) { + ndoms[to]--; + if (ndoms[to]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + for (j=xadj[i]; j maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms)); + maxndoms = ndoms[me]; + } + } + if (pmat[to*nparts+me] == 0) { + ndoms[to]++; + if (ndoms[to] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms)); + maxndoms = ndoms[to]; + } + } + pmat[me*nparts+to] += adjwgt[j]; + pmat[to*nparts+me] += adjwgt[j]; + } + } + + KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); + + nmoves++; + + /* CheckVolKWayPartitionParams(ctrl, graph, nparts); */ + } + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, + graph->minvol)); + + if (graph->minvol == oldvol && graph->mincut == oldcut) + break; + } + + GKfree(&marker, &updind, &phtable, LTERM); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); +} + + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Greedy_KWayVolBalance(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, + float ubfactor, int npasses) +{ + int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; + int from, me, to, vwgt, gain; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; + VEDegreeType *myedegrees; + VRInfoType *myrinfo; + PQueueType queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); + marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); + phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut, graph->minvol)); + + + for (pass=0; passmincut); + /* Check to see if things are out of balance, given the tolerance */ + for (i=0; i maxwgt[i]) + break; + } + if (i == nparts) /* Things are balanced. Return right away */ + break; + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + RandomPermute(graph->nbnd, perm, 1); + for (ii=0; iinbnd; ii++) { + i = bndind[perm[ii]]; + PQueueInsert(&queue, i, graph->vrinfo[i].gv); + moved[i] = 2; + } + + for (nmoves=0;;) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->vrinfo+i; + from = where[i]; + vwgt = graph->vwgt[i]; + + if (pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; k minwgt[to] && + (xgain+myedegrees[k].gv < 0 || + (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->id < 0)) + ) + continue; + + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + INC_DEC(pwgts[to], pwgts[from], vwgt); + graph->mincut -= myedegrees[k].ed-myrinfo->id; + graph->minvol -= (xgain+myedegrees[k].gv); + where[i] = to; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", + i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); + + KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); + + nmoves++; + + /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */ + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, + graph->minvol)); + + } + + GKfree(&marker, &updind, &phtable, LTERM); + + PQueueFree(ctrl, &queue); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Greedy_KWayVolBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, + float ubfactor, int npasses) +{ + int i, ii, iii, j, jj, k, kk, l, u, pass, nvtxs, nmoves, tvwgt, myndegrees, xgain; + int from, me, to, vwgt, gain, maxndoms, nadd; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *moved, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts, *updind, *marker, *phtable; + idxtype *pmat, *pmatptr, *ndoms; + VEDegreeType *myedegrees; + VRInfoType *myrinfo; + PQueueType queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + updind = idxmalloc(nvtxs, "Random_KWayVolRefine: updind"); + marker = idxsmalloc(nvtxs, 0, "Random_KWayVolRefine: marker"); + phtable = idxsmalloc(nparts, -1, "Random_KWayVolRefine: phtable"); + + pmat = ctrl->wspace.pmat; + ndoms = idxwspacemalloc(ctrl, nparts); + + ComputeVolSubDomainGraph(graph, nparts, pmat, ndoms); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("VolPart: [%5d %5d]-[%5d %5d], Balance: %3.2f, Nv-Nb[%5d %5d]. Cut: %5d, Vol: %5d [B]\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut, graph->minvol)); + + + for (pass=0; passmincut); + /* Check to see if things are out of balance, given the tolerance */ + for (i=0; i maxwgt[i]) + break; + } + if (i == nparts) /* Things are balanced. Return right away */ + break; + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + RandomPermute(graph->nbnd, perm, 1); + for (ii=0; iinbnd; ii++) { + i = bndind[perm[ii]]; + PQueueInsert(&queue, i, graph->vrinfo[i].gv); + moved[i] = 2; + } + + maxndoms = ndoms[idxamax(nparts, ndoms)]; + + for (nmoves=0;;) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->vrinfo+i; + from = where[i]; + vwgt = graph->vwgt[i]; + + if (pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + xgain = (myrinfo->id == 0 && myrinfo->ed > 0 ? graph->vsize[i] : 0); + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + /* Determine the valid domains */ + for (j=0; j maxndoms-1) { + phtable[to] = 0; + nadd = maxndoms; + break; + } + nadd++; + } + } + if (ndoms[to]+nadd > maxndoms) + phtable[to] = 0; + } + + for (k=0; k minwgt[to] && + (xgain+myedegrees[k].gv < 0 || + (xgain+myedegrees[k].gv == 0 && myedegrees[k].ed-myrinfo->id < 0)) + ) + continue; + + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + INC_DEC(pwgts[to], pwgts[from], vwgt); + graph->mincut -= myedegrees[k].ed-myrinfo->id; + graph->minvol -= (xgain+myedegrees[k].gv); + where[i] = to; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d from %3d to %3d. Gain: [%4d %4d]. Cut: %6d, Vol: %6d\n", + i, from, to, xgain+myedegrees[k].gv, myedegrees[k].ed-myrinfo->id, graph->mincut, graph->minvol)); + + /* Update pmat to reflect the move of 'i' */ + pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); + pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); + if (pmat[from*nparts+to] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[to*nparts+from] == 0) { + ndoms[to]--; + if (ndoms[to]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + for (j=xadj[i]; j maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms)); + maxndoms = ndoms[me]; + } + } + if (pmat[to*nparts+me] == 0) { + ndoms[to]++; + if (ndoms[to] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms)); + maxndoms = ndoms[to]; + } + } + pmat[me*nparts+to] += adjwgt[j]; + pmat[to*nparts+me] += adjwgt[j]; + } + } + + KWayVolUpdate(ctrl, graph, i, from, to, marker, phtable, updind); + + nmoves++; + + /*CheckVolKWayPartitionParams(ctrl, graph, nparts); */ + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, Vol: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut, + graph->minvol)); + + } + + GKfree(&marker, &updind, &phtable, LTERM); + + PQueueFree(ctrl, &queue); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + + +/************************************************************************* +* This function updates the edge and volume gains as a result of moving +* v from 'from' to 'to'. +* The working arrays marker and phtable are assumed to be initialized to +* -1, and they left to -1 upon return +**************************************************************************/ +void KWayVolUpdate(CtrlType *ctrl, GraphType *graph, int v, int from, int to, + idxtype *marker, idxtype *phtable, idxtype *updind) +{ + int ii, iii, j, jj, k, kk, l, u, nupd, other, me, myidx; + idxtype *xadj, *vsize, *adjncy, *adjwgt, *where; + VEDegreeType *myedegrees, *oedegrees; + VRInfoType *myrinfo, *orinfo; + + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vsize = graph->vsize; + where = graph->where; + + myrinfo = graph->vrinfo+v; + myedegrees = myrinfo->edegrees; + + + /*====================================================================== + * Remove the contributions on the gain made by 'v'. + *=====================================================================*/ + for (k=0; kndegrees; k++) + phtable[myedegrees[k].pid] = k; + phtable[from] = k; + + myidx = phtable[to]; /* Keep track of the index in myedegrees of the 'to' domain */ + + for (j=xadj[v]; jvrinfo+ii; + oedegrees = orinfo->edegrees; + + if (other == from) { + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] == -1) + oedegrees[k].gv += vsize[v]; + } + } + else { + ASSERT(phtable[other] != -1); + + if (myedegrees[phtable[other]].ned > 1) { + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] == -1) + oedegrees[k].gv += vsize[v]; + } + } + else { /* There is only one connection */ + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] != -1) + oedegrees[k].gv -= vsize[v]; + } + } + } + } + + for (k=0; kndegrees; k++) + phtable[myedegrees[k].pid] = -1; + phtable[from] = -1; + + + /*====================================================================== + * Update the id/ed of vertex 'v' + *=====================================================================*/ + myrinfo->ed += myrinfo->id-myedegrees[myidx].ed; + SWAP(myrinfo->id, myedegrees[myidx].ed, j); + SWAP(myrinfo->nid, myedegrees[myidx].ned, j); + if (myedegrees[myidx].ed == 0) + myedegrees[myidx] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[myidx].pid = from; + + /*====================================================================== + * Update the degrees of adjacent vertices and their volume gains + *=====================================================================*/ + marker[v] = 1; + updind[0] = v; + nupd = 1; + for (j=xadj[v]; jvrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + myrinfo->nid--; + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + myrinfo->nid++; + } + + /* Remove the edgeweight from the 'pid == from' entry of the vertex */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ned == 1) { + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + marker[ii] = 1; /* You do a complete .gv calculation */ + + /* All vertices adjacent to 'ii' need to be updated */ + for (jj=xadj[ii]; jjvrinfo+u; + oedegrees = orinfo->edegrees; + + for (kk=0; kkndegrees; kk++) { + if (oedegrees[kk].pid == from) { + oedegrees[kk].gv -= vsize[ii]; + break; + } + } + } + } + else { + myedegrees[k].ed -= adjwgt[j]; + myedegrees[k].ned--; + + /* Update the gv due to single 'ii' connection to 'from' */ + if (myedegrees[k].ned == 1) { + /* find the vertex 'u' that 'ii' was connected into 'from' */ + for (jj=xadj[ii]; jjvrinfo+u; + oedegrees = orinfo->edegrees; + + if (other == from) { + for (kk=0; kkndegrees; kk++) + oedegrees[kk].gv += vsize[ii]; + break; + } + } + } + } + + break; + } + } + } + + /* Add the edgeweight to the 'pid == to' entry of the vertex */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + myedegrees[k].ned++; + + /* Update the gv due to non-single 'ii' connection to 'to' */ + if (myedegrees[k].ned == 2) { + /* find the vertex 'u' that 'ii' was connected into 'to' */ + for (jj=xadj[ii]; jjvrinfo+u; + oedegrees = orinfo->edegrees; + + if (u != v && other == to) { + for (kk=0; kkndegrees; kk++) + oedegrees[kk].gv -= vsize[ii]; + break; + } + } + } + break; + } + } + + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees].ed = adjwgt[j]; + myedegrees[myrinfo->ndegrees++].ned = 1; + marker[ii] = 1; /* You do a complete .gv calculation */ + + /* All vertices adjacent to 'ii' need to be updated */ + for (jj=xadj[ii]; jjvrinfo+u; + oedegrees = orinfo->edegrees; + + for (kk=0; kkndegrees; kk++) { + if (oedegrees[kk].pid == to) { + oedegrees[kk].gv += vsize[ii]; + if (!marker[u]) { /* Need to update boundary etc */ + marker[u] = 2; + updind[nupd++] = u; + } + break; + } + } + } + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + } + + /*====================================================================== + * Add the contributions on the volume gain due to 'v' + *=====================================================================*/ + myrinfo = graph->vrinfo+v; + myedegrees = myrinfo->edegrees; + for (k=0; kndegrees; k++) + phtable[myedegrees[k].pid] = k; + phtable[to] = k; + + for (j=xadj[v]; jvrinfo+ii; + oedegrees = orinfo->edegrees; + + if (other == to) { + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] == -1) + oedegrees[k].gv -= vsize[v]; + } + } + else { + ASSERT(phtable[other] != -1); + + if (myedegrees[phtable[other]].ned > 1) { + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] == -1) + oedegrees[k].gv -= vsize[v]; + } + } + else { /* There is only one connection */ + for (k=0; kndegrees; k++) { + if (phtable[oedegrees[k].pid] != -1) + oedegrees[k].gv += vsize[v]; + } + } + } + } + for (k=0; kndegrees; k++) + phtable[myedegrees[k].pid] = -1; + phtable[to] = -1; + + + /*====================================================================== + * Recompute the volume information of the 'hard' nodes, and update the + * max volume gain for all the update vertices + *=====================================================================*/ + ComputeKWayVolume(graph, nupd, updind, marker, phtable); + + + /*====================================================================== + * Maintain a consistent boundary + *=====================================================================*/ + for (j=0; jvrinfo+k; + + if ((myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0) && graph->bndptr[k] == -1) + BNDInsert(graph->nbnd, graph->bndind, graph->bndptr, k); + + if (myrinfo->gv < 0 && myrinfo->ed-myrinfo->id < 0 && graph->bndptr[k] != -1) + BNDDelete(graph->nbnd, graph->bndind, graph->bndptr, k); + } + +} + + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void ComputeKWayVolume(GraphType *graph, int nupd, idxtype *updind, idxtype *marker, idxtype *phtable) +{ + int ii, iii, i, j, k, kk, l, nvtxs, me, other, pid; + idxtype *xadj, *vsize, *adjncy, *adjwgt, *where; + VRInfoType *rinfo, *myrinfo, *orinfo; + VEDegreeType *myedegrees, *oedegrees; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->vrinfo; + + + /*------------------------------------------------------------ + / Compute now the iv/ev degrees + /------------------------------------------------------------*/ + for (iii=0; iiiedegrees; + + if (marker[i] == 1) { /* Only complete gain updates go through */ + for (k=0; kndegrees; k++) + myedegrees[k].gv = 0; + + for (j=xadj[i]; jedegrees; + + for (kk=0; kkndegrees; kk++) + phtable[oedegrees[kk].pid] = kk; + phtable[other] = 1; + + if (me == other) { + /* Find which domains 'i' is connected and 'ii' is not and update their gain */ + for (k=0; kndegrees; k++) { + if (phtable[myedegrees[k].pid] == -1) + myedegrees[k].gv -= vsize[ii]; + } + } + else { + ASSERT(phtable[me] != -1); + + /* I'm the only connection of 'ii' in 'me' */ + if (oedegrees[phtable[me]].ned == 1) { + /* Increase the gains for all the common domains between 'i' and 'ii' */ + for (k=0; kndegrees; k++) { + if (phtable[myedegrees[k].pid] != -1) + myedegrees[k].gv += vsize[ii]; + } + } + else { + /* Find which domains 'i' is connected and 'ii' is not and update their gain */ + for (k=0; kndegrees; k++) { + if (phtable[myedegrees[k].pid] == -1) + myedegrees[k].gv -= vsize[ii]; + } + } + } + + for (kk=0; kkndegrees; kk++) + phtable[oedegrees[kk].pid] = -1; + phtable[other] = -1; + + } + } + + myrinfo->gv = -MAXIDX; + for (k=0; kndegrees; k++) { + if (myedegrees[k].gv > myrinfo->gv) + myrinfo->gv = myedegrees[k].gv; + } + if (myrinfo->ed > 0 && myrinfo->id == 0) + myrinfo->gv += vsize[i]; + + } + +} + + + +/************************************************************************* +* This function computes the total volume +**************************************************************************/ +int ComputeVolume(GraphType *graph, idxtype *where) +{ + int i, j, k, me, nvtxs, nparts, totalv; + idxtype *xadj, *adjncy, *vsize, *marker; + + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vsize = (graph->vsize == NULL ? graph->vwgt : graph->vsize); + + nparts = where[idxamax(nvtxs, where)]+1; + marker = idxsmalloc(nparts, -1, "ComputeVolume: marker"); + + totalv = 0; + + for (i=0; invtxs; + xadj = graph->xadj; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->vrinfo; + + tmpdegrees = (VEDegreeType *)GKmalloc(nparts*sizeof(VEDegreeType), "CheckVolKWayPartitionParams: tmpdegrees"); + + /*------------------------------------------------------------ + / Compute now the iv/ev degrees + /------------------------------------------------------------*/ + for (i=0; iedegrees; + + for (k=0; kndegrees; k++) + tmpdegrees[k] = myedegrees[k]; + + tmprinfo.ndegrees = myrinfo->ndegrees; + tmprinfo.id = myrinfo->id; + tmprinfo.ed = myrinfo->ed; + + myrinfo = &tmprinfo; + myedegrees = tmpdegrees; + + + for (k=0; kndegrees; k++) + myedegrees[k].gv = 0; + + for (j=xadj[i]; jedegrees; + + if (me == other) { + /* Find which domains 'i' is connected and 'ii' is not and update their gain */ + for (k=0; kndegrees; k++) { + pid = myedegrees[k].pid; + for (kk=0; kkndegrees; kk++) { + if (oedegrees[kk].pid == pid) + break; + } + if (kk == orinfo->ndegrees) + myedegrees[k].gv -= vsize[ii]; + } + } + else { + /* Find the orinfo[me].ed and see if I'm the only connection */ + for (k=0; kndegrees; k++) { + if (oedegrees[k].pid == me) + break; + } + + if (oedegrees[k].ned == 1) { /* I'm the only connection of 'ii' in 'me' */ + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == other) { + myedegrees[k].gv += vsize[ii]; + break; + } + } + + /* Increase the gains for all the common domains between 'i' and 'ii' */ + for (k=0; kndegrees; k++) { + if ((pid = myedegrees[k].pid) == other) + continue; + for (kk=0; kkndegrees; kk++) { + if (oedegrees[kk].pid == pid) { + myedegrees[k].gv += vsize[ii]; + break; + } + } + } + + } + else { + /* Find which domains 'i' is connected and 'ii' is not and update their gain */ + for (k=0; kndegrees; k++) { + if ((pid = myedegrees[k].pid) == other) + continue; + for (kk=0; kkndegrees; kk++) { + if (oedegrees[kk].pid == pid) + break; + } + if (kk == orinfo->ndegrees) + myedegrees[k].gv -= vsize[ii]; + } + } + } + } + + myrinfo = rinfo+i; + myedegrees = myrinfo->edegrees; + + for (k=0; kndegrees; k++) { + pid = myedegrees[k].pid; + for (kk=0; kknvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->vrinfo; + + idxset(nparts*nparts, 0, pmat); + + for (i=0; i 0) { + me = where[i]; + ndegrees = rinfo[i].ndegrees; + edegrees = rinfo[i].edegrees; + + k = me*nparts; + for (j=0; j 0) + ndoms[i]++; + } + } +} + + + +/************************************************************************* +* This function computes the subdomain graph +**************************************************************************/ +void EliminateVolSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts) +{ + int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd; + int min, move, cpwgt, tvwgt; + idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind; + KeyValueType *cand, *cand2; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = idxset(nparts, 0, graph->pwgts); + + maxpwgt = idxwspacemalloc(ctrl, nparts); + ndoms = idxwspacemalloc(ctrl, nparts); + otherpmat = idxwspacemalloc(ctrl, nparts); + ind = idxwspacemalloc(ctrl, nvtxs); + pmat = idxset(nparts*nparts, 0, ctrl->wspace.pmat); + + cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); + cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); + + /* Compute the pmat matrix */ + for (i=0; i 0) + k++; + } + ndoms[i] = k; + } + + /* Get into the loop eliminating subdomain connections */ + for (;;) { + total = idxsum(nparts, ndoms); + avg = total/nparts; + max = ndoms[idxamax(nparts, ndoms)]; + + /* printf("Adjacent Subdomain Stats: Total: %3d, Max: %3d, Avg: %3d\n", total, max, avg); */ + + if (max < 1.5*avg) + break; + + me = idxamax(nparts, ndoms); + mypmat = pmat + me*nparts; + totalout = idxsum(nparts, mypmat); + + /*printf("Me: %d, TotalOut: %d,\n", me, totalout);*/ + + /* Sort the connections according to their cut */ + for (ncand2=0, i=0; i 0) { + cand2[ncand2].key = mypmat[i]; + cand2[ncand2++].val = i; + } + } + ikeysort(ncand2, cand2); + + move = 0; + for (min=0; min totalout/(2*ndoms[me])) + break; + + other = cand2[min].val; + + /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/ + + idxset(nparts, 0, otherpmat); + + /* Go and find the vertices in 'other' that are connected in 'me' */ + for (nind=0, i=0; i 0) { + cand[ncand].key = -otherpmat[i]; + cand[ncand++].val = i; + } + } + ikeysort(ncand, cand); + + /* + * Go through and the select the first domain that is common with 'me', and + * does not increase the ndoms[target] higher than my ndoms, subject to the + * maxpwgt constraint. Traversal is done from the mostly connected to the least. + */ + target = target2 = -1; + for (i=0; i 0) { + if (pwgts[k] + cpwgt > maxpwgt[k]) /* Check if balance will go off */ + continue; + + for (j=0; j 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0) + break; + } + if (j == nparts) { /* No bad second level effects */ + for (nadd=0, j=0; j 0 && pmat[nparts*k+j] == 0) + nadd++; + } + + /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/ + if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) { + target2 = k; + } + if (nadd == 0) { + target = k; + break; + } + } + } + } + if (target == -1 && target2 != -1) + target = target2; + + if (target == -1) { + /* printf("\t\tCould not make the move\n");*/ + continue; + } + + /*printf("\t\tMoving to %d\n", target);*/ + + /* Update the partition weights */ + INC_DEC(pwgts[target], pwgts[other], cpwgt); + + /* Set all nind vertices to belong to 'target' */ + for (ii=0; iiwhere and tries to push them around to +* remove some of them +**************************************************************************/ +void EliminateVolComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor) +{ + int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, ncand, other, target, deltawgt; + idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt; + idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps; + KeyValueType *cand; + int recompute=0; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = idxset(nparts, 0, graph->pwgts); + + touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs)); + cptr = idxwspacemalloc(ctrl, nvtxs+1); + cind = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + todo = idxwspacemalloc(ctrl, nvtxs); + maxpwgt = idxwspacemalloc(ctrl, nparts); + cpvec = idxwspacemalloc(ctrl, nparts); + npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts)); + + for (i=0; i 0) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + ASSERT(touched[todo[0]] == 0); + i = todo[0]; + cind[last++] = i; + touched[i] = 1; + me = where[i]; + npcmps[me]++; + } + + i = cind[first++]; + k = perm[i]; + j = todo[k] = todo[--nleft]; + perm[j] = k; + + for (j=xadj[i]; j nparts) { /* There are more components than processors */ + cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); + + /* First determine the partition sizes and max allowed load imbalance */ + for (i=0; i .30*pwgts[me]) + continue; /* Skip the component if it is over 30% of the weight */ + + for (ncand=0, j=0; j 0) { + cand[ncand].key = -cpvec[j]; + cand[ncand++].val = j; + } + } + if (ncand == 0) + continue; + + ikeysort(ncand, cand); + + target = -1; + for (j=0; jmincut -= cpvec[target]; + recompute = 1; + } + } + + free(cand); + } + + if (recompute) { + int ttlv; + idxtype *marker; + + marker = idxset(nparts, -1, cpvec); + for (ttlv=0, i=0; ivsize[i]; + marker[where[adjncy[j]]] = i; + } + } + } + graph->minvol = ttlv; + } + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs+1); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolrefine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolrefine.c new file mode 100644 index 0000000..7cf248d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/kwayvolrefine.c @@ -0,0 +1,468 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * kwayvolrefine.c + * + * This file contains the driving routines for multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: kwayvolrefine.c,v 1.1 2003/07/16 15:55:05 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void RefineVolKWay(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int nparts, + float *tpwgts, float ubfactor) +{ + int i, nlevels; + GraphType *ptr; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Take care any non-contiguity */ + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->AuxTmr1)); + if (ctrl->RType == RTYPE_KWAYRANDOM_MCONN) { + ComputeVolKWayPartitionParams(ctrl, graph, nparts); + EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25); + EliminateVolSubDomainEdges(ctrl, graph, nparts, tpwgts); + EliminateVolComponents(ctrl, graph, nparts, tpwgts, 1.25); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->AuxTmr1)); + + + /* Determine how many levels are there */ + for (ptr=graph, nlevels=0; ptr!=orggraph; ptr=ptr->finer, nlevels++); + + /* Compute the parameters of the coarsest graph */ + ComputeVolKWayPartitionParams(ctrl, graph, nparts); + + for (i=0; ;i++) { + /*PrintSubDomainGraph(graph, nparts, graph->where);*/ + MALLOC_CHECK(NULL); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + + if (2*i >= nlevels && !IsBalanced(graph->pwgts, nparts, tpwgts, 1.04*ubfactor)) { + ComputeVolKWayBalanceBoundary(ctrl, graph, nparts); + switch (ctrl->RType) { + case RTYPE_KWAYRANDOM: + Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 1); + break; + case RTYPE_KWAYRANDOM_MCONN: + Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 1); + break; + } + ComputeVolKWayBoundary(ctrl, graph, nparts); + } + + switch (ctrl->RType) { + case RTYPE_KWAYRANDOM: + Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); + break; + case RTYPE_KWAYRANDOM_MCONN: + Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 1); + break; + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + GKfree(&graph->gdata, LTERM); /* Deallocate the graph related arrays */ + + graph = graph->finer; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + ProjectVolKWayPartition(ctrl, graph, nparts); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + if (!IsBalanced(graph->pwgts, nparts, tpwgts, ubfactor)) { + ComputeVolKWayBalanceBoundary(ctrl, graph, nparts); + switch (ctrl->RType) { + case RTYPE_KWAYRANDOM: + Greedy_KWayVolBalance(ctrl, graph, nparts, tpwgts, ubfactor, 8); + Random_KWayVolRefine(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); + break; + case RTYPE_KWAYRANDOM_MCONN: + Greedy_KWayVolBalanceMConn(ctrl, graph, nparts, tpwgts, ubfactor, 8); + Random_KWayVolRefineMConn(ctrl, graph, nparts, tpwgts, ubfactor, 10, 0); + break; + } + } + + EliminateVolComponents(ctrl, graph, nparts, tpwgts, ubfactor); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + + +/************************************************************************* +* This function allocates memory for k-way edge refinement +**************************************************************************/ +void AllocateVolKWayPartitionMemory(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int nvtxs, pad64; + + nvtxs = graph->nvtxs; + + pad64 = (3*nvtxs+nparts)%2; + + graph->rdata = idxmalloc(3*nvtxs+nparts+(sizeof(VRInfoType)/sizeof(idxtype))*nvtxs+pad64, "AllocateVolKWayPartitionMemory: rdata"); + graph->pwgts = graph->rdata; + graph->where = graph->rdata + nparts; + graph->bndptr = graph->rdata + nvtxs + nparts; + graph->bndind = graph->rdata + 2*nvtxs + nparts; + graph->vrinfo = (VRInfoType *)(graph->rdata + 3*nvtxs+nparts + pad64); + +} + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void ComputeVolKWayPartitionParams(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, ii, j, k, kk, l, nvtxs, nbnd, mincut, minvol, me, other, pid; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts, *where; + VRInfoType *rinfo, *myrinfo, *orinfo; + VEDegreeType *myedegrees, *oedegrees; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = idxset(nparts, 0, graph->pwgts); + rinfo = graph->vrinfo; + +starttimer(ctrl->AuxTmr1); + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + ctrl->wspace.cdegree = 0; + mincut = 0; + for (i=0; iid = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + for (j=xadj[i]; jid += adjwgt[j]; + myrinfo->nid++; + } + } + myrinfo->ed = graph->adjwgtsum[i] - myrinfo->id; + + mincut += myrinfo->ed; + + /* Time to compute the particular external degrees */ + if (myrinfo->ed > 0) { + myedegrees = myrinfo->edegrees = ctrl->wspace.vedegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; + + for (j=xadj[i]; jndegrees; k++) { + if (myedegrees[k].pid == other) { + myedegrees[k].ed += adjwgt[j]; + myedegrees[k].ned++; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].gv = 0; + myedegrees[myrinfo->ndegrees].pid = other; + myedegrees[myrinfo->ndegrees].ed = adjwgt[j]; + myedegrees[myrinfo->ndegrees++].ned = 1; + } + } + } + + ASSERT(myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + } + } + graph->mincut = mincut/2; + +stoptimer(ctrl->AuxTmr1); + + ComputeKWayVolGains(ctrl, graph, nparts); + +} + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void ComputeKWayVolGains(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, ii, j, k, kk, l, nvtxs, me, other, pid, myndegrees; + idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *bndind, *bndptr, *ophtable; + VRInfoType *rinfo, *myrinfo, *orinfo; + VEDegreeType *myedegrees, *oedegrees; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + bndind = graph->bndind; + bndptr = idxset(nvtxs, -1, graph->bndptr); + rinfo = graph->vrinfo; + +starttimer(ctrl->AuxTmr2); + + ophtable = idxset(nparts, -1, idxwspacemalloc(ctrl, nparts)); + + /*------------------------------------------------------------ + / Compute now the iv/ev degrees + /------------------------------------------------------------*/ + graph->minvol = graph->nbnd = 0; + for (i=0; igv = -MAXIDX; + + if (myrinfo->ndegrees > 0) { + me = where[i]; + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + graph->minvol += myndegrees*vsize[i]; + + for (j=xadj[i]; jedegrees; + + for (k=0; kndegrees; k++) + ophtable[oedegrees[k].pid] = k; + ophtable[other] = 1; /* this is to simplify coding */ + + if (me == other) { + /* Find which domains 'i' is connected and 'ii' is not and update their gain */ + for (k=0; kndegrees; kk++) + ophtable[oedegrees[kk].pid] = -1; + ophtable[other] = -1; + } + + /* Compute the max vgain */ + for (k=0; k myrinfo->gv) + myrinfo->gv = myedegrees[k].gv; + } + } + + if (myrinfo->ed > 0 && myrinfo->id == 0) + myrinfo->gv += vsize[i]; + + if (myrinfo->gv >= 0 || myrinfo->ed-myrinfo->id >= 0) + BNDInsert(graph->nbnd, bndind, bndptr, i); + } + +stoptimer(ctrl->AuxTmr2); + + idxwspacefree(ctrl, nparts); + +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void ProjectVolKWayPartition(CtrlType *ctrl, GraphType *graph, int nparts) +{ + int i, j, k, nvtxs, me, other, istart, iend, ndegrees; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where; + idxtype *cwhere; + GraphType *cgraph; + VRInfoType *crinfo, *rinfo, *myrinfo; + VEDegreeType *myedegrees; + idxtype *htable; + + cgraph = graph->coarser; + cwhere = cgraph->where; + crinfo = cgraph->vrinfo; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + AllocateVolKWayPartitionMemory(ctrl, graph, nparts); + where = graph->where; + rinfo = graph->vrinfo; + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; iwspace.cdegree = 0; + for (i=0; iid = myrinfo->ed = myrinfo->nid = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + myrinfo->id = adjwgtsum[i]; + myrinfo->nid = xadj[i+1]-xadj[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.vedegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += iend-istart; + + ndegrees = 0; + for (j=istart; jed += adjwgt[j]; + myrinfo->nid--; + if ((k = htable[other]) == -1) { + htable[other] = ndegrees; + myedegrees[ndegrees].gv = 0; + myedegrees[ndegrees].pid = other; + myedegrees[ndegrees].ed = adjwgt[j]; + myedegrees[ndegrees++].ned = 1; + } + else { + myedegrees[k].ed += adjwgt[j]; + myedegrees[k].ned++; + } + } + } + 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 { + myrinfo->ndegrees = ndegrees; + + for (j=0; jpwgts, graph->pwgts); + graph->mincut = cgraph->mincut; + + FreeGraph(graph->coarser); + graph->coarser = NULL; + + idxwspacefree(ctrl, nparts); + +} + + + +/************************************************************************* +* This function computes the boundary definition for balancing +**************************************************************************/ +void ComputeVolKWayBoundary(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; ivrinfo[i].gv >=0 || graph->vrinfo[i].ed-graph->vrinfo[i].id >= 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + +/************************************************************************* +* This function computes the boundary definition for balancing +**************************************************************************/ +void ComputeVolKWayBalanceBoundary(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; ivrinfo[i].ed > 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/macros.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/macros.h new file mode 100644 index 0000000..97e42a2 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/macros.h @@ -0,0 +1,138 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * macros.h + * + * This file contains macros used in multilevel + * + * Started 9/25/94 + * George + * + * $Id: macros.h,v 1.7 2003/07/21 19:11:40 karypis Exp $ + * + */ + + +/************************************************************************* +* The following macro returns a random number in the specified range +**************************************************************************/ +#define RandomInRange(u) ((int)(1.0*(u)*rand()/(RAND_MAX+1.0))) + +#define amax(a, b) ((a) >= (b) ? (a) : (b)) +#define amin(a, b) ((a) >= (b) ? (b) : (a)) + +#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) +#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) +#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) + +#define SWAP(a, b, tmp) \ + do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) + +#define INC_DEC(a, b, val) \ + do {(a) += (val); (b) -= (val);} while(0) + + +#define scopy(n, a, b) (float *)memcpy((void *)(b), (void *)(a), sizeof(float)*(n)) +#define idxcopy(n, a, b) (idxtype *)memcpy((void *)(b), (void *)(a), sizeof(idxtype)*(n)) + +#define HASHFCT(key, size) ((key)%(size)) + + +/************************************************************************* +* Timer macros +**************************************************************************/ +#define cleartimer(tmr) (tmr = 0.0) +#define starttimer(tmr) (tmr -= seconds()) +#define stoptimer(tmr) (tmr += seconds()) +#define gettimer(tmr) (tmr) + + +/************************************************************************* +* This macro is used to handle dbglvl +**************************************************************************/ +#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd); + +/************************************************************************* +* These macros are used for debuging memory leaks +**************************************************************************/ +#ifdef DMALLOC +#define imalloc(n, msg) (malloc(sizeof(int)*(n))) +#define fmalloc(n, msg) (malloc(sizeof(float)*(n))) +#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n))) +#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n)))) +#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n)))) +#define GKmalloc(a, b) (malloc((a))) +#endif + +#ifdef DMALLOC +# define MALLOC_CHECK(ptr); +/* +# define MALLOC_CHECK(ptr) \ + if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) { \ + printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +*/ +#else +# define MALLOC_CHECK(ptr) ; +#endif + + + +/************************************************************************* +* This macro converts a length array in a CSR one +**************************************************************************/ +#define MAKECSR(i, n, a) \ + do { \ + for (i=1; i0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + +/************************************************************************* +* These macros insert and remove nodes from the boundary list +**************************************************************************/ +#define BNDInsert(nbnd, bndind, bndptr, vtx) \ + do { \ + ASSERT(bndptr[vtx] == -1); \ + bndind[nbnd] = vtx; \ + bndptr[vtx] = nbnd++;\ + } while(0) + +#define BNDDelete(nbnd, bndind, bndptr, vtx) \ + do { \ + ASSERT(bndptr[vtx] != -1); \ + bndind[bndptr[vtx]] = bndind[--nbnd]; \ + bndptr[bndind[nbnd]] = bndptr[vtx]; \ + bndptr[vtx] = -1; \ + } while(0) + + + +/************************************************************************* +* These are debugging macros +**************************************************************************/ +#ifdef DEBUG +# define ASSERT(expr) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERT(expr) ; +#endif + +#ifdef DEBUG +# define ASSERTP(expr, msg) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + printf msg ; \ + abort(); \ + } +#else +# define ASSERTP(expr, msg) ; +#endif diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/match.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/match.c new file mode 100644 index 0000000..509f457 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/match.c @@ -0,0 +1,267 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * match.c + * + * This file contains the code that computes matchings and creates the next + * level coarse graph. + * + * Started 7/23/97 + * George + * + * $Id: match.c,v 1.1 2003/07/16 15:55:06 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void Match_RM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, nvtxs, cnvtxs, maxidx; + idxtype *xadj, *vwgt, *adjncy, *adjwgt; + idxtype *match, *cmap, *perm; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; iimaxvwgt) { + maxidx = adjncy[j]; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void Match_RM_NVW(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, nvtxs, cnvtxs, maxidx; + idxtype *xadj, *adjncy; + idxtype *match, *cmap, *perm; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; iidbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + CreateCoarseGraph_NVW(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void Match_HEM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt; + idxtype *xadj, *vwgt, *adjncy, *adjwgt; + idxtype *match, *cmap, *perm; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; iimaxvwgt) { + maxwgt = adjwgt[j]; + maxidx = adjncy[j]; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void Match_SHEM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, k, nvtxs, cnvtxs, maxidx, maxwgt, avgdegree; + idxtype *xadj, *vwgt, *adjncy, *adjwgt; + idxtype *match, *cmap, *degrees, *perm, *tperm; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + tperm = idxwspacemalloc(ctrl, nvtxs); + degrees = idxwspacemalloc(ctrl, nvtxs); + + RandomPermute(nvtxs, tperm, 1); + avgdegree = 0.7*(xadj[nvtxs]/nvtxs); + for (i=0; i avgdegree ? avgdegree : xadj[i+1]-xadj[i]); + BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); + + cnvtxs = 0; + + /* Take care any islands. Islands are matched with non-islands due to coarsening */ + for (ii=0; iiii; j--) { + k = perm[j]; + if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { + maxidx = k; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + /* Continue with normal matching */ + for (; iimaxvwgt) { + maxwgt = adjwgt[j]; + maxidx = adjncy[j]; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + idxwspacefree(ctrl, nvtxs); /* degrees */ + idxwspacefree(ctrl, nvtxs); /* tperm */ + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mbalance.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mbalance.c new file mode 100644 index 0000000..65e9961 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mbalance.c @@ -0,0 +1,260 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mbalance.c + * + * This file contains code that is used to forcefully balance either + * bisections or k-sections + * + * Started 7/29/97 + * George + * + * $Id: mbalance.c,v 1.1 2003/07/16 15:55:07 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point of the bisection balancing algorithms. +**************************************************************************/ +void MocBalance2Way(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor) +{ + + if (Compute2WayHLoadImbalance(graph->ncon, graph->npwgts, tpwgts) < lbfactor) + return; + + MocGeneral2WayBalance(ctrl, graph, tpwgts, lbfactor); + +} + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocGeneral2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts, float lbfactor) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, newcut, mincutorder; + int qsizes[MAXNCON][2]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 15), 100); + + /* Initialize the queues */ + for (i=0; i qsizes[j][from] && nvwgt[i*ncon+qnum[i]] < 1.3*nvwgt[i*ncon+j]) { + qsizes[qnum[i]][from]--; + qsizes[j][from]++; + qnum[i] = j; + } + } + } + } + } + +/* + printf("Weight Distribution (after):\t "); + for (i=0; imincut; + mincutorder = -1; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, origbal); + } + + idxset(nvtxs, -1, moved); + + ASSERT(ComputeCut(graph, where) == graph->mincut); + ASSERT(CheckBnd(graph)); + + /* Insert all nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nvtxs, perm, 1); + for (ii=0; ii limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (l=0; l 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + + for (i=0; i + + +/************************************************************************* +* This function is the entry point of the bisection balancing algorithms. +**************************************************************************/ +void MocBalance2Way2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i; + float tvec[MAXNCON]; + + Compute2WayHLoadImbalanceVec(graph->ncon, graph->npwgts, tpwgts, tvec); + if (!AreAllBelow(graph->ncon, tvec, ubvec)) + MocGeneral2WayBalance2(ctrl, graph, tpwgts, ubvec); +} + + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocGeneral2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, origbal[MAXNCON], minbal[MAXNCON], newbal[MAXNCON]; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, newcut, mincutorder; + float *maxwgt, *minwgt, tvec[MAXNCON]; + + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 15), 100); + + /* Setup the weight intervals of the two subdomains */ + minwgt = fwspacemalloc(ctrl, 2*ncon); + maxwgt = fwspacemalloc(ctrl, 2*ncon); + + for (i=0; i<2; i++) { + for (j=0; jmincut; + mincutorder = -1; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut); + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + /* Insert all nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nvtxs, perm, 1); + for (ii=0; ii limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (i=0; i 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + + } + + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (i=0; imincut = mincut; + graph->nbnd = nbnd; + + + for (i=0; i= maxdiff) { + maxdiff = diff; + *from = j; + *cnum = i; + } + } + } + +/* DELETE +j = *from; +for (i=0; i 0) { + maxdiff = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]); + *cnum = i; + break; + } + } + + for (i++; i maxdiff && PQueueGetSize(&queues[i][*from]) > 0) { + maxdiff = diff; + *cnum = i; + } + } + } + + /* If the constraints ar OK, select a high gain vertex */ + if (*from == -1) { + maxgain = -100000; + for (j=0; j<2; j++) { + for (i=0; i 0 && PQueueGetKey(&queues[i][j]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][0]); + *from = j; + *cnum = i; + } + } + } + + /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */ + } +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mcoarsen.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mcoarsen.c new file mode 100644 index 0000000..336e6c6 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mcoarsen.c @@ -0,0 +1,106 @@ +/* + * mcoarsen.c + * + * This file contains the driving routines for the coarsening process + * + * Started 7/23/97 + * George + * + * $Id: mcoarsen.c,v 1.2 2003/07/31 16:23:29 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function takes a graph and creates a sequence of coarser graphs +**************************************************************************/ +GraphType *MCCoarsen2Way(CtrlType *ctrl, GraphType *graph) +{ + int i, clevel; + GraphType *cgraph; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->CoarsenTmr)); + + cgraph = graph; + + clevel = 0; + do { + if (ctrl->dbglvl&DBG_COARSEN) { + printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, + idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt); + for (i=0; incon; i++) + printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon)); + printf("]\n"); + } + + switch (ctrl->CType) { + case MATCH_RM: + MCMatch_RM(ctrl, cgraph); + break; + case MATCH_HEM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_HEM(ctrl, cgraph); + break; + case MATCH_SHEM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SHEM(ctrl, cgraph); + break; + case MATCH_SHEMKWAY: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SHEM(ctrl, cgraph); + break; + case MATCH_SHEBM_ONENORM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SHEBM(ctrl, cgraph, 1); + break; + case MATCH_SHEBM_INFNORM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SHEBM(ctrl, cgraph, -1); + break; + case MATCH_SBHEM_ONENORM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SBHEM(ctrl, cgraph, 1); + break; + case MATCH_SBHEM_INFNORM: + if (clevel < 1 || cgraph->nedges == 0) + MCMatch_RM(ctrl, cgraph); + else + MCMatch_SBHEM(ctrl, cgraph, -1); + break; + default: + errexit("Unknown CType: %d\n", ctrl->CType); + } + + cgraph = cgraph->coarser; + clevel++; + + } while (cgraph->nvtxs > ctrl->CoarsenTo && cgraph->nvtxs < COARSEN_FRACTION2*cgraph->finer->nvtxs && cgraph->nedges > cgraph->nvtxs/2); + + if (ctrl->dbglvl&DBG_COARSEN) { + printf("%6d %7d %10d [%d] [%6.4f", cgraph->nvtxs, cgraph->nedges, + idxsum(cgraph->nvtxs, cgraph->adjwgtsum), ctrl->CoarsenTo, ctrl->nmaxvwgt); + for (i=0; incon; i++) + printf(" %5.3f", ssum_strd(cgraph->nvtxs, cgraph->nvwgt+i, cgraph->ncon)); + printf("]\n"); + } + + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->CoarsenTmr)); + + return cgraph; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/memory.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/memory.c new file mode 100644 index 0000000..0082b8c --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/memory.c @@ -0,0 +1,208 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * memory.c + * + * This file contains routines that deal with memory allocation + * + * Started 2/24/96 + * George + * + * $Id: memory.c,v 1.1 2003/07/24 18:39:08 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void AllocateWorkSpace(CtrlType *ctrl, GraphType *graph, int nparts) +{ + ctrl->wspace.pmat = NULL; + + if (ctrl->optype == OP_KMETIS) { + ctrl->wspace.edegrees = (EDegreeType *)GKmalloc(graph->nedges*sizeof(EDegreeType), "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases + Coarsening + Matching: 4*nvtxs vectors + Contraction: 2*nvtxs vectors (from the above 4), 1*nparts, 1*Nedges + Total = MAX(4*nvtxs, 2*nvtxs+nparts+nedges) + + Refinement + Random Refinement/Balance: 5*nparts + 1*nvtxs + 2*nedges + Greedy Refinement/Balance: 5*nparts + 2*nvtxs + 2*nedges + 1*PQueue(==Nvtxs) + Total = 5*nparts + 3*nvtxs + 2*nedges + + Total = 5*nparts + 3*nvtxs + 2*nedges + */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 5*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else if (ctrl->optype == OP_KVMETIS) { + ctrl->wspace.edegrees = NULL; + ctrl->wspace.vedegrees = (VEDegreeType *)GKmalloc(graph->nedges*sizeof(VEDegreeType), "AllocateWorkSpace: vedegrees"); + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.vedegrees; + + ctrl->wspace.pmat = idxmalloc(nparts*nparts, "AllocateWorkSpace: pmat"); + + /* Memory requirements for different phases are identical to KMETIS */ + ctrl->wspace.maxcore = 3*(graph->nvtxs+1) + /* Match/Refinement vectors */ + 3*(nparts+1) + /* Partition weights etc */ + graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* Greedy k-way balance/refine */ + 20 /* padding for 64 bit machines */ + ; + } + else { + ctrl->wspace.edegrees = (EDegreeType *)idxmalloc(graph->nedges, "AllocateWorkSpace: edegrees"); + ctrl->wspace.vedegrees = NULL; + ctrl->wspace.auxcore = (idxtype *)ctrl->wspace.edegrees; + + ctrl->wspace.maxcore = 5*(graph->nvtxs+1) + /* Refinement vectors */ + 4*(nparts+1) + /* Partition weights etc */ + 2*graph->ncon*graph->nvtxs*(sizeof(ListNodeType)/sizeof(idxtype)) + /* 2-way refinement */ + 2*graph->ncon*(NEG_GAINSPAN+PLUS_GAINSPAN+1)*(sizeof(ListNodeType *)/sizeof(idxtype)) + /* 2-way refinement */ + 20 /* padding for 64 bit machines */ + ; + } + + ctrl->wspace.maxcore += HTLENGTH; + ctrl->wspace.core = idxmalloc(ctrl->wspace.maxcore, "AllocateWorkSpace: maxcore"); + ctrl->wspace.ccore = 0; +} + + +/************************************************************************* +* This function allocates memory for the workspace +**************************************************************************/ +void FreeWorkSpace(CtrlType *ctrl, GraphType *graph) +{ + GKfree(&ctrl->wspace.edegrees, &ctrl->wspace.vedegrees, &ctrl->wspace.core, &ctrl->wspace.pmat, LTERM); +} + +/************************************************************************* +* This function returns how may words are left in the workspace +**************************************************************************/ +int WspaceAvail(CtrlType *ctrl) +{ + return ctrl->wspace.maxcore - ctrl->wspace.ccore; +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +idxtype *idxwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return ctrl->wspace.core + ctrl->wspace.ccore - n; +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void idxwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + +/************************************************************************* +* This function allocate space from the core +**************************************************************************/ +float *fwspacemalloc(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore += n; + ASSERT(ctrl->wspace.ccore <= ctrl->wspace.maxcore); + return (float *) (ctrl->wspace.core + ctrl->wspace.ccore - n); +} + +/************************************************************************* +* This function frees space from the core +**************************************************************************/ +void fwspacefree(CtrlType *ctrl, int n) +{ + n += n%2; /* This is a fix for 64 bit machines that require 8-byte pointer allignment */ + + ctrl->wspace.ccore -= n; + ASSERT(ctrl->wspace.ccore >= 0); +} + + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +GraphType *CreateGraph(void) +{ + GraphType *graph; + + graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph"); + + InitGraph(graph); + + return graph; +} + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +void InitGraph(GraphType *graph) +{ + graph->gdata = graph->rdata = NULL; + + graph->nvtxs = graph->nedges = -1; + graph->mincut = graph->minvol = -1; + + graph->xadj = graph->vwgt = graph->adjncy = graph->adjwgt = NULL; + graph->adjwgtsum = NULL; + graph->label = NULL; + graph->cmap = NULL; + + graph->where = graph->pwgts = NULL; + graph->id = graph->ed = NULL; + graph->bndptr = graph->bndind = NULL; + graph->rinfo = NULL; + graph->vrinfo = NULL; + graph->nrinfo = NULL; + + graph->ncon = -1; + graph->nvwgt = NULL; + graph->npwgts = NULL; + + graph->vsize = NULL; + + graph->coarser = graph->finer = NULL; + +} + +/************************************************************************* +* This function deallocates any memory stored in a graph +**************************************************************************/ +void FreeGraph(GraphType *graph) +{ + + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->npwgts, LTERM); + free(graph); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mesh.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mesh.c new file mode 100644 index 0000000..3d93628 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mesh.c @@ -0,0 +1,399 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mesh.c + * + * This file contains routines for converting 3D and 4D finite element + * meshes into dual or nodal graphs + * + * Started 8/18/97 + * George + * + * $Id: mesh.c,v 1.2 2003/07/22 20:29:03 karypis Exp $ + * + */ + +#include + +/***************************************************************************** +* This function creates a graph corresponding to the dual of a finite element +* mesh. At this point the supported elements are triangles, tetrahedrons, and +* bricks. +******************************************************************************/ +void METIS_MeshToDual(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, + idxtype *dxadj, idxtype *dadjncy) +{ + int esizes[] = {-1, 3, 4, 8, 4}; + + if (*numflag == 1) + ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts); + + GENDUALMETIS(*ne, *nn, *etype, elmnts, dxadj, dadjncy); + + if (*numflag == 1) + ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *ne, dxadj, dadjncy); +} + + +/***************************************************************************** +* This function creates a graph corresponding to the finite element mesh. +* At this point the supported elements are triangles, tetrahedrons. +******************************************************************************/ +void METIS_MeshToNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, + idxtype *dxadj, idxtype *dadjncy) +{ + int esizes[] = {-1, 3, 4, 8, 4}; + + if (*numflag == 1) + ChangeMesh2CNumbering((*ne)*esizes[*etype], elmnts); + + switch (*etype) { + case 1: + TRINODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); + break; + case 2: + TETNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); + break; + case 3: + HEXNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); + break; + case 4: + QUADNODALMETIS(*ne, *nn, elmnts, dxadj, dadjncy); + break; + } + + if (*numflag == 1) + ChangeMesh2FNumbering((*ne)*esizes[*etype], elmnts, *nn, dxadj, dadjncy); +} + + + +/***************************************************************************** +* This function creates the dual of a finite element mesh +******************************************************************************/ +void GENDUALMETIS(int nelmnts, int nvtxs, int etype, idxtype *elmnts, idxtype *dxadj, + idxtype *dadjncy) +{ + int i, j, jj, k, kk, kkk, l, m, n, nedges, mask; + idxtype *nptr, *nind; + idxtype *mark, ind[200], wgt[200]; + int esize, esizes[] = {-1, 3, 4, 8, 4}, + mgcnum, mgcnums[] = {-1, 2, 3, 4, 2}; + + mask = (1<<11)-1; + mark = idxsmalloc(mask+1, -1, "GENDUALMETIS: mark"); + + /* Get the element size and magic number for the particular element */ + esize = esizes[etype]; + mgcnum = mgcnums[etype]; + + /* Construct the node-element list first */ + nptr = idxsmalloc(nvtxs+1, 0, "GENDUALMETIS: nptr"); + for (j=esize*nelmnts, i=0; i0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + for (i=0; i=nptr[n]; k--) { + if ((kk = nind[k]) <= i) + break; + + kkk = kk&mask; + if ((l = mark[kkk]) == -1) { + ind[m] = kk; + wgt[m] = 1; + mark[kkk] = m++; + } + else if (ind[l] == kk) { + wgt[l]++; + } + else { + for (jj=0; jj0; i--) + dxadj[i] = dxadj[i-1]; + dxadj[0] = 0; + + free(mark); + free(nptr); + free(nind); + +} + + + + +/***************************************************************************** +* This function creates the nodal graph of a finite element mesh +******************************************************************************/ +void TRINODALMETIS(int nelmnts, int nvtxs, idxtype *elmnts, idxtype *dxadj, idxtype *dadjncy) +{ + int i, j, jj, k, kk, kkk, l, m, n, nedges; + idxtype *nptr, *nind; + idxtype *mark; + + /* Construct the node-element list first */ + nptr = idxsmalloc(nvtxs+1, 0, "TRINODALMETIS: nptr"); + for (j=3*nelmnts, i=0; i0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + + mark = idxsmalloc(nvtxs, -1, "TRINODALMETIS: mark"); + + nedges = dxadj[0] = 0; + for (i=0; i0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + + mark = idxsmalloc(nvtxs, -1, "TETNODALMETIS: mark"); + + nedges = dxadj[0] = 0; + for (i=0; i0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + + mark = idxsmalloc(nvtxs, -1, "HEXNODALMETIS: mark"); + + nedges = dxadj[0] = 0; + for (i=0; i0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + + mark = idxsmalloc(nvtxs, -1, "QUADNODALMETIS: mark"); + + nedges = dxadj[0] = 0; + for (i=0; i + + +/************************************************************************* +* This function partitions a finite element mesh by partitioning its nodal +* graph using KMETIS and then assigning elements in a load balanced fashion. +**************************************************************************/ +void METIS_PartMeshNodal(int *ne, int *nn, idxtype *elmnts, int *etype, int *numflag, + int *nparts, int *edgecut, idxtype *epart, idxtype *npart) +{ + int i, j, k, me; + idxtype *xadj, *adjncy, *pwgts; + int options[10], pnumflag=0, wgtflag=0; + int nnbrs, nbrind[200], nbrwgt[200], maxpwgt; + int esize, esizes[] = {-1, 3, 4, 8, 4}; + + esize = esizes[*etype]; + + if (*numflag == 1) + ChangeMesh2CNumbering((*ne)*esize, elmnts); + + xadj = idxmalloc(*nn+1, "METIS_MESHPARTNODAL: xadj"); + adjncy = idxmalloc(20*(*nn), "METIS_MESHPARTNODAL: adjncy"); + + METIS_MeshToNodal(ne, nn, elmnts, etype, &pnumflag, xadj, adjncy); + + adjncy = realloc(adjncy, xadj[*nn]*sizeof(idxtype)); + + options[0] = 0; + METIS_PartGraphKway(nn, xadj, adjncy, NULL, NULL, &wgtflag, &pnumflag, nparts, options, edgecut, npart); + + /* OK, now compute an element partition based on the nodal partition npart */ + idxset(*ne, -1, epart); + pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTNODAL: pwgts"); + for (i=0; i<*ne; i++) { + me = npart[elmnts[i*esize]]; + for (j=1; j0; i--) + nptr[i] = nptr[i-1]; + nptr[0] = 0; + + + /* OK, now compute a nodal partition based on the element partition npart */ + idxset(*nn, -1, npart); + pwgts = idxsmalloc(*nparts, 0, "METIS_MESHPARTDUAL: pwgts"); + for (i=0; i<*nn; i++) { + me = epart[nind[nptr[i]]]; + for (j=nptr[i]+1; j + +#ifdef DMALLOC +#include +#endif + +#include "../parmetis.h" /* Get the idxtype definition */ +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm.c new file mode 100644 index 0000000..d0047e5 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mfm.c @@ -0,0 +1,341 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mfm.c + * + * This file contains code that implements the edge-based FM refinement + * + * Started 7/23/97 + * George + * + * $Id: mfm.c,v 1.1 2003/07/24 18:39:09 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocFM_2WayEdgeRefine(CtrlType *ctrl, GraphType *graph, float *tpwgts, int npasses) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, initcut, newcut, mincutorder; + float rtpwgts[2]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 25), 150); + + /* Initialize the queues */ + for (i=0; idbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, origbal); + } + + idxset(nvtxs, -1, moved); + for (pass=0; passmincut; + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + /* Insert boundary nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[i] == 0); + ASSERT(bndptr[i] != -1); + PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); + } + + for (nswaps=0; nswaps limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (l=0; l 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); + } + } + } + + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + for (i=0; i= maxdiff) { + maxdiff = npwgts[part*ncon+i]-tpwgts[part]; + *from = part; + *cnum = i; + } + } + } + + /* printf("Selected %d(%d) -> %d\n", *from, *cnum, PQueueGetSize(&queues[*cnum][*from])); */ + + if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { + /* The desired queue is empty, select a node from that side anyway */ + for (i=0; i 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + break; + } + } + + for (i++; i max && PQueueGetSize(&queues[i][*from]) > 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + } + } + } + + /* Check to see if you can focus on the cut */ + if (maxdiff <= 0.0 || *from == -1) { + maxgain = -100000; + + for (part=0; part<2; part++) { + for (i=0; i 0 && PQueueGetKey(&queues[i][part]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][part]); + *from = part; + *cnum = i; + } + } + } + } +} + + + + + +/************************************************************************* +* This function checks if the balance achieved is better than the diff +* For now, it uses a 2-norm measure +**************************************************************************/ +int BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff) +{ + int i; + float ndiff[MAXNCON]; + + for (i=0; i + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void MocFM_2WayEdgeRefine2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *orgubvec, + int npasses) +{ + int i, ii, j, k, l, kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, me, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *perm, *qnum; + float *nvwgt, *npwgts, origdiff[MAXNCON], origbal[MAXNCON], minbal[MAXNCON]; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, initcut, newcut, mincutorder; + float *maxwgt, *minwgt, ubvec[MAXNCON], tvec[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + limit = amin(amax(0.01*nvtxs, 15), 100); + + Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, origbal); + for (i=0; idbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut); + for (i=0; imincut; + Compute2WayHLoadImbalanceVec(ncon, npwgts, tpwgts, minbal); + + ASSERT(ComputeCut(graph, where) == graph->mincut); + ASSERT(CheckBnd(graph)); + + /* Insert boundary nodes in the priority queues */ + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; ii 0 || id[i] == 0); + ASSERT(bndptr[i] != -1); + PQueueInsert(&parts[qnum[i]][where[i]], i, ed[i]-id[i]); + } + + for (nswaps=0; nswaps limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). Gain: %5d, Cut: %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], newcut); + for (l=0; l 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + PQueueInsert(&parts[qnum[k]][where[k]], k, ed[k]-id[k]); + } + } + } + + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d at %5d, NBND: %6d, NPwgts: [", mincut, mincutorder, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + for (i=0; i= maxdiff) { + maxdiff = diff; + *from = j; + *cnum = i; + } + } + } + + if (*from != -1 && PQueueGetSize(&queues[*cnum][*from]) == 0) { + /* The desired queue is empty, select a node from that side anyway */ + for (i=0; i 0) { + max = (npwgts[(*from)*ncon+i] - maxwgt[(*from)*ncon+i]); + *cnum = i; + break; + } + } + + for (i++; i max && PQueueGetSize(&queues[i][*from]) > 0) { + max = diff; + *cnum = i; + } + } + } + + /* Check to see if you can focus on the cut */ + if (maxdiff <= 0.0) { + maxgain = -100000; + + for (j=0; j<2; j++) { + for (i=0; i 0 && PQueueGetKey(&queues[i][j]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][j]); + *from = j; + *cnum = i; + } + } + } + + /* printf("(%2d %2d) %3d\n", *from, *cnum, maxgain); */ + } +} + + +/************************************************************************* +* This function checks if the newbal is better than oldbal given the +* ubvector ubvec +**************************************************************************/ +int IsBetter2wayBalance(int ncon, float *newbal, float *oldbal, float *ubvec) +{ + int i, j; + float max1=0.0, max2=0.0, sum1=0.0, sum2=0.0, tmp; + + for (i=0; i max2) + return 0; + else + return sum1 <= sum2; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c new file mode 100644 index 0000000..789022b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mincover.c @@ -0,0 +1,259 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mincover.c + * + * This file implements the minimum cover algorithm + * + * Started 8/1/97 + * George + * + * $Id: mincover.c,v 1.1 2003/07/16 15:55:09 karypis Exp $ + */ + +#include + +/************************************************************************* +* Constants used by mincover algorithm +**************************************************************************/ +#define INCOL 10 +#define INROW 20 +#define VC 1 +#define SC 2 +#define HC 3 +#define VR 4 +#define SR 5 +#define HR 6 + + +/************************************************************************* +* This function returns the min-cover of a bipartite graph. +* The algorithm used is due to Hopcroft and Karp as modified by Duff etal +* adj: the adjacency list of the bipartite graph +* asize: the number of vertices in the first part of the bipartite graph +* bsize-asize: the number of vertices in the second part +* 0..(asize-1) > A vertices +* asize..bsize > B vertices +* +* Returns: +* cover : the actual cover (array) +* csize : the size of the cover +**************************************************************************/ +void MinCover(idxtype *xadj, idxtype *adjncy, int asize, int bsize, idxtype *cover, int *csize) +{ + int i, j; + idxtype *mate, *queue, *flag, *level, *lst; + int fptr, rptr, lstptr; + int row, maxlevel, col; + + mate = idxsmalloc(bsize, -1, "MinCover: mate"); + flag = idxmalloc(bsize, "MinCover: flag"); + level = idxmalloc(bsize, "MinCover: level"); + queue = idxmalloc(bsize, "MinCover: queue"); + lst = idxmalloc(bsize, "MinCover: lst"); + + /* Get a cheap matching */ + for (i=0; i + +/************************************************************************* +* This function computes the initial bisection of the coarsest graph +**************************************************************************/ +void MocInit2WayPartition(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i, dbglvl; + + dbglvl = ctrl->dbglvl; + IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); + IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + switch (ctrl->IType) { + case IPART_GGPKL: + if (graph->nedges == 0) + MocRandomBisection(ctrl, graph, tpwgts, ubfactor); + else + MocGrowBisection(ctrl, graph, tpwgts, ubfactor); + break; + case IPART_RANDOM: + MocRandomBisection(ctrl, graph, tpwgts, ubfactor); + break; + default: + errexit("Unknown initial partition type: %d\n", ctrl->IType); + } + + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + ctrl->dbglvl = dbglvl; + +} + + + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void MocGrowBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; + idxtype *bestwhere, *where; + + nvtxs = graph->nvtxs; + + MocAllocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(graph->nedges, graph->adjwgt); + + for (; nbfs>0; nbfs--) { + idxset(nvtxs, 1, where); + where[RandomInRange(nvtxs)] = 0; + + MocCompute2WayPartitionParams(ctrl, graph); + + MocInit2WayBalance(ctrl, graph, tpwgts); + + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); + + MocBalance2Way(ctrl, graph, tpwgts, 1.02); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 4); + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, LTERM); +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void MocRandomBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i, ii, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs, qnum; + idxtype *bestwhere, *where, *perm; + int counts[MAXNCON]; + float *nvwgt; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + nvwgt = graph->nvwgt; + + MocAllocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(graph->nedges, graph->adjwgt); + perm = idxmalloc(nvtxs, "BisectGraph: perm"); + + for (; nbfs>0; nbfs--) { + for (i=0; imincut); + for (i=0; incon; i++) + printf("(%.3f %.3f) ", graph->npwgts[i], graph->npwgts[graph->ncon+i]); + printf("]\n"); + */ + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, &perm, LTERM); +} + + + + +/************************************************************************* +* This function balances two partitions by moving the highest gain +* (including negative gain) vertices to the other domain. +* It is used only when tha unbalance is due to non contigous +* subdomains. That is, the are no boundary vertices. +* It moves vertices from the domain that is overweight to the one that +* is underweight. +**************************************************************************/ +void MocInit2WayBalance(CtrlType *ctrl, GraphType *graph, float *tpwgts) +{ + int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *perm, *qnum; + float *nvwgt, *npwgts; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + nvwgt = graph->nvwgt; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + /* This is called for initial partitioning so we know from where to pick nodes */ + from = 1; + to = (from+1)%2; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, + Compute2WayHLoadImbalance(ncon, npwgts, tpwgts)); + } + + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + ASSERT(CheckGraph(graph)); + + /* Compute the queues in which each vertex will be assigned to */ + for (i=0; i 0) + PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]); + else + PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]); + } + } + + + mincut = graph->mincut; + nbnd = graph->nbnd; + for (nswaps=0; nswapsdbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut); + for (l=0; l 0) + printf("\t Pulled from the interior!\n"); + } + + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) { /* It moves in boundary */ + PQueueDelete(&parts[qnum[k]][1], k, oldgain); + PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]); + } + else { /* It must be in the boundary already */ + if (bndptr[k] == -1) + printf("What you thought was wrong!\n"); + PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]); + } + } + + /* Update its boundary information */ + if (ed[k] == 0 && bndptr[k] != -1) + BNDDelete(nbnd, bndind, bndptr, k); + else if (ed[k] > 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + + ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut)); + + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + + +/************************************************************************* +* This function selects the partition number and the queue from which +* we will move vertices out +**************************************************************************/ +int SelectQueueOneWay(int ncon, float *npwgts, float *tpwgts, int from, PQueueType queues[MAXNCON][2]) +{ + int i, cnum=-1; + float max=0.0; + + for (i=0; i= max && + PQueueGetSize(&queues[i][0]) + PQueueGetSize(&queues[i][1]) > 0) { + max = npwgts[from*ncon+i]-tpwgts[0]; + cnum = i; + } + } + + return cnum; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/minitpart2.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/minitpart2.c new file mode 100644 index 0000000..4c1e1b1 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/minitpart2.c @@ -0,0 +1,368 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * minitpart2.c + * + * This file contains code that performs the initial partition of the + * coarsest graph + * + * Started 7/23/97 + * George + * + * $Id: minitpart2.c,v 1.1 2003/07/16 15:55:10 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function computes the initial bisection of the coarsest graph +**************************************************************************/ +void MocInit2WayPartition2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int dbglvl; + + dbglvl = ctrl->dbglvl; + IFSET(ctrl->dbglvl, DBG_REFINE, ctrl->dbglvl -= DBG_REFINE); + IFSET(ctrl->dbglvl, DBG_MOVEINFO, ctrl->dbglvl -= DBG_MOVEINFO); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + switch (ctrl->IType) { + case IPART_GGPKL: + case IPART_RANDOM: + MocGrowBisection2(ctrl, graph, tpwgts, ubvec); + break; + case 3: + MocGrowBisectionNew2(ctrl, graph, tpwgts, ubvec); + break; + default: + errexit("Unknown initial partition type: %d\n", ctrl->IType); + } + + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial Cut: %d\n", graph->mincut)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + ctrl->dbglvl = dbglvl; + +} + + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void MocGrowBisection2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; + idxtype *bestwhere, *where; + + nvtxs = graph->nvtxs; + + MocAllocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(graph->nedges, graph->adjwgt); + + for (; nbfs>0; nbfs--) { + idxset(nvtxs, 1, where); + where[RandomInRange(nvtxs)] = 0; + + MocCompute2WayPartitionParams(ctrl, graph); + + MocBalance2Way2(ctrl, graph, tpwgts, ubvec); + + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); + + MocBalance2Way2(ctrl, graph, tpwgts, ubvec); + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, LTERM); +} + + + + + + +/************************************************************************* +* This function takes a graph and produces a bisection by using a region +* growing algorithm. The resulting partition is returned in +* graph->where +**************************************************************************/ +void MocGrowBisectionNew2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i, j, k, nvtxs, ncon, from, bestcut, mincut, nbfs; + idxtype *bestwhere, *where; + + nvtxs = graph->nvtxs; + + MocAllocate2WayPartitionMemory(ctrl, graph); + where = graph->where; + + bestwhere = idxmalloc(nvtxs, "BisectGraph: bestwhere"); + nbfs = 2*(nvtxs <= ctrl->CoarsenTo ? SMALLNIPARTS : LARGENIPARTS); + bestcut = idxsum(graph->nedges, graph->adjwgt); + + for (; nbfs>0; nbfs--) { + idxset(nvtxs, 1, where); + where[RandomInRange(nvtxs)] = 0; + + MocCompute2WayPartitionParams(ctrl, graph); + + MocInit2WayBalance2(ctrl, graph, tpwgts, ubvec); + + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 4); + + if (bestcut > graph->mincut) { + bestcut = graph->mincut; + idxcopy(nvtxs, where, bestwhere); + if (bestcut == 0) + break; + } + } + + graph->mincut = bestcut; + idxcopy(nvtxs, bestwhere, where); + + GKfree(&bestwhere, LTERM); +} + + + +/************************************************************************* +* This function balances two partitions by moving the highest gain +* (including negative gain) vertices to the other domain. +* It is used only when tha unbalance is due to non contigous +* subdomains. That is, the are no boundary vertices. +* It moves vertices from the domain that is overweight to the one that +* is underweight. +**************************************************************************/ +void MocInit2WayBalance2(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i, ii, j, k, l, kwgt, nvtxs, nbnd, ncon, nswaps, from, to, pass, me, cnum, tmp, imin; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *perm, *qnum; + float *nvwgt, *npwgts, minwgt; + PQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + nvwgt = graph->nvwgt; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->id; + ed = graph->ed; + npwgts = graph->npwgts; + bndptr = graph->bndptr; + bndind = graph->bndind; + + moved = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + qnum = idxwspacemalloc(ctrl, nvtxs); + + /* This is called for initial partitioning so we know from where to pick nodes */ + from = 1; + to = (from+1)%2; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("Parts: ["); + for (l=0; lnvtxs, graph->nbnd, graph->mincut, ComputeLoadImbalance(ncon, 2, npwgts, tpwgts)); + } + + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + ASSERT(CheckGraph(graph)); + + /* Compute the queues in which each vertex will be assigned to */ + for (i=0; i 0) + PQueueInsert(&parts[qnum[i]][0], i, ed[i]-id[i]); + else + PQueueInsert(&parts[qnum[i]][1], i, ed[i]-id[i]); + } + } + +/* + for (i=0; imincut; + nbnd = graph->nbnd; + for (nswaps=0; nswaps minwgt) + break; + + if ((cnum = SelectQueueOneWay2(ncon, npwgts+to*ncon, parts, ubvec)) == -1) + break; + + if ((higain = PQueueGetMax(&parts[cnum][0])) == -1) + higain = PQueueGetMax(&parts[cnum][1]); + + mincut -= (ed[higain]-id[higain]); + saxpy(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + + where[higain] = to; + moved[higain] = nswaps; + + if (ctrl->dbglvl&DBG_MOVEINFO) { + printf("Moved %6d from %d(%d). [%5d] %5d, NPwgts: ", higain, from, cnum, ed[higain]-id[higain], mincut); + for (l=0; l 0) + printf("\t Pulled from the interior!\n"); + } + + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) { /* It moves in boundary */ + PQueueDelete(&parts[qnum[k]][1], k, oldgain); + PQueueInsert(&parts[qnum[k]][0], k, ed[k]-id[k]); + } + else { /* It must be in the boundary already */ + if (bndptr[k] == -1) + printf("What you thought was wrong!\n"); + PQueueUpdate(&parts[qnum[k]][0], k, oldgain, ed[k]-id[k]); + } + } + + /* Update its boundary information */ + if (ed[k] == 0 && bndptr[k] != -1) + BNDDelete(nbnd, bndind, bndptr, k); + else if (ed[k] > 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + + ASSERTP(ComputeCut(graph, where) == mincut, ("%d != %d\n", ComputeCut(graph, where), mincut)); + + } + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\tMincut: %6d, NBND: %6d, NPwgts: ", mincut, nbnd); + for (l=0; lmincut = mincut; + graph->nbnd = nbnd; + + for (i=0; imincut); + ASSERT(CheckBnd(graph)); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function selects the partition number and the queue from which +* we will move vertices out +**************************************************************************/ +int SelectQueueOneWay2(int ncon, float *pto, PQueueType queues[MAXNCON][2], float *ubvec) +{ + int i, cnum=-1, imax, maxgain; + float max=0.0; + float twgt[MAXNCON]; + + for (i=0; i 0 || PQueueGetSize(&queues[i][1]) > 0)) { + max = twgt[i]; + cnum = i; + } + } + if (max > 1) + return cnum; + + /* optimize of cut */ + maxgain = -10000000; + for (i=0; i 0 && PQueueGetKey(&queues[i][0]) > maxgain) { + maxgain = PQueueGetKey(&queues[i][0]); + cnum = i; + } + } + + return cnum; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkmetis.c new file mode 100644 index 0000000..55c7c9b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkmetis.c @@ -0,0 +1,124 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mkmetis.c + * + * This file contains the top level routines for the multilevel k-way partitioning + * algorithm KMETIS. + * + * Started 7/28/97 + * George + * + * $Id: mkmetis.c,v 1.1 2003/07/16 15:55:10 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function is the entry point for KWMETIS +**************************************************************************/ +void METIS_mCPartGraphKway(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, + int *nparts, float *rubvec, int *options, int *edgecut, + idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_KMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = McKMETIS_CTYPE; + ctrl.IType = McKMETIS_ITYPE; + ctrl.RType = McKMETIS_RTYPE; + ctrl.dbglvl = McKMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_KMETIS; + ctrl.CoarsenTo = amax((*nvtxs)/(20*log2Int(*nparts)), 30*(*nparts)); + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + ASSERT(CheckGraph(&graph)); + *edgecut = MCMlevelKWayPartitioning(&ctrl, &graph, *nparts, part, rubvec); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCMlevelKWayPartitioning(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, + float *rubvec) +{ + int i, j, nvtxs; + GraphType *cgraph; + int options[10], edgecut; + + cgraph = MCCoarsen2Way(ctrl, graph); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + MocAllocateKWayPartitionMemory(ctrl, cgraph, nparts); + + options[0] = 1; + options[OPTION_CTYPE] = MATCH_SBHEM_INFNORM; + options[OPTION_ITYPE] = IPART_RANDOM; + options[OPTION_RTYPE] = RTYPE_FM; + options[OPTION_DBGLVL] = 0; + + /* Determine what you will use as the initial partitioner, based on tolerances */ + for (i=0; incon; i++) { + if (rubvec[i] > 1.2) + break; + } + if (i == graph->ncon) + METIS_mCPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, + cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, + options, &edgecut, cgraph->where); + else + METIS_mCHPartGraphRecursiveInternal(&cgraph->nvtxs, &cgraph->ncon, + cgraph->xadj, cgraph->adjncy, cgraph->nvwgt, cgraph->adjwgt, &nparts, + rubvec, options, &edgecut, cgraph->where); + + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + IFSET(ctrl->dbglvl, DBG_IPART, printf("Initial %d-way partitioning cut: %d\n", nparts, edgecut)); + + IFSET(ctrl->dbglvl, DBG_KWAYPINFO, ComputePartitionInfo(cgraph, nparts, cgraph->where)); + + MocRefineKWayHorizontal(ctrl, graph, cgraph, nparts, rubvec); + + idxcopy(graph->nvtxs, graph->where, part); + + GKfree(&graph->nvwgt, &graph->gdata, &graph->rdata, LTERM); + + return graph->mincut; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayfmh.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayfmh.c new file mode 100644 index 0000000..69a781a --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mkwayfmh.c @@ -0,0 +1,677 @@ +/* + * mkwayfmh.c + * + * This file contains code that implements the multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: mkwayfmh.c,v 1.1 2003/07/16 15:55:10 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void MCRandom_KWayEdgeRefineHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, + float *orgubvec, int npasses) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nmoves, nbnd, myndegrees, same; + int from, me, to, oldcut, gain; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *perm, *bndptr, *bndind; + EDegreeType *myedegrees; + RInfoType *myrinfo; + float *npwgts, *nvwgt, *minwgt, *maxwgt, maxlb, minlb, ubvec[MAXNCON], tvec[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + npwgts = graph->npwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = fwspacemalloc(ctrl, nparts*ncon); + maxwgt = fwspacemalloc(ctrl, nparts*ncon); + + /* See if the orgubvec consists of identical constraints */ + maxlb = minlb = orgubvec[0]; + for (i=1; i maxlb ? orgubvec[i] : maxlb); + } + same = (fabs(maxlb-minlb) < .01 ? 1 : 0); + + + /* Let's not get very optimistic. Let Balancing do the work */ + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec); + for (i=0; i maxlb ? ubvec[i] : maxlb); + + for (i=0; idbglvl&DBG_REFINE) { + printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ", + npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], + graph->nvtxs, graph->nbnd, graph->mincut); + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); + for (i=0; imincut); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (nmoves=iii=0; iiinbnd; iii++) { + ii = perm[iii]; + if (ii >= nbnd) + continue; + i = bndind[ii]; + + myrinfo = graph->rinfo+i; + + if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ + from = where[i]; + nvwgt = graph->nvwgt+i*ncon; + + if (myrinfo->id > 0 && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; kid; + if (gain >= 0 && + (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || + IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j myedegrees[k].ed && + (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || + IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec))) || + (myedegrees[j].ed == myedegrees[k].ed && + IsHBalanceBetterTT(ncon, nparts, npwgts+myedegrees[k].pid*ncon, npwgts+to*ncon, nvwgt, ubvec))) + k = j; + } + + to = myedegrees[k].pid; + + if (myedegrees[k].ed-myrinfo->id == 0 + && !IsHBalanceBetterFT(ncon, nparts, npwgts+from*ncon, npwgts+to*ncon, nvwgt, ubvec) + && AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, npwgts+from*ncon, maxwgt+from*ncon)) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update where, weight, and ID/ED information of the vertex you moved */ + saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1); + where[i] = to; + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed-myrinfo->id < 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + + } + nmoves++; + } + } + + graph->nbnd = nbnd; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ", + npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], + nbnd, nmoves, graph->mincut); + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); + for (i=0; imincut == oldcut) + break; + } + + fwspacefree(ctrl, ncon*nparts); + fwspacefree(ctrl, ncon*nparts); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *ctrl, GraphType *graph, int nparts, + float *ubvec, int npasses) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, ncon, nbnd, myndegrees, oldgain, gain, nmoves; + int from, me, to, oldcut; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *perm, *bndptr, *bndind, *moved; + EDegreeType *myedegrees; + RInfoType *myrinfo; + PQueueType queue; + float *npwgts, *nvwgt, *minwgt, *maxwgt, tvec[MAXNCON]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + + where = graph->where; + npwgts = graph->npwgts; + + /* Setup the weight intervals of the various subdomains */ + minwgt = fwspacemalloc(ctrl, ncon*nparts); + maxwgt = fwspacemalloc(ctrl, ncon*nparts); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + if (ctrl->dbglvl&DBG_REFINE) { + printf("Partitions: [%5.4f %5.4f], Nv-Nb[%6d %6d]. Cut: %6d, LB: ", + npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], + graph->nvtxs, graph->nbnd, graph->mincut); + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); + for (i=0; imincut); + + /* Check to see if things are out of balance, given the tolerance */ + if (MocIsHBalanced(ncon, nparts, npwgts, ubvec)) + break; + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iirinfo[i].ed - graph->rinfo[i].id); + moved[i] = 2; + } + + nmoves = 0; + for (;;) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->rinfo+i; + from = where[i]; + nvwgt = graph->nvwgt+i*ncon; + + if (AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; kid >= 0) + j++; + if (!AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) && + AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon)) + j++; + if (j == 0) + continue; + +/* DELETE + if (myedegrees[k].ed-myrinfo->id < 0 && + AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, 0.0, nvwgt, maxwgt+from*ncon) && + AreAllHVwgtsAbove(ncon, 1.0, npwgts+to*ncon, 0.0, nvwgt, minwgt+to*ncon) && + AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon)) + continue; +*/ + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update where, weight, and ID/ED information of the vertex you moved */ + saxpy(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1); + saxpy(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1); + where[i] = to; + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed == 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + oldgain = (myrinfo->ed-myrinfo->id); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed > 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed == 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + + /* Update the queue */ + if (me == to || me == from) { + gain = myrinfo->ed-myrinfo->id; + if (moved[ii] == 2) { + if (myrinfo->ed > 0) + PQueueUpdate(&queue, ii, oldgain, gain); + else { + PQueueDelete(&queue, ii, oldgain); + moved[ii] = -1; + } + } + else if (moved[ii] == -1 && myrinfo->ed > 0) { + PQueueInsert(&queue, ii, gain); + moved[ii] = 2; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + } + nmoves++; + } + + graph->nbnd = nbnd; + + if (ctrl->dbglvl&DBG_REFINE) { + printf("\t [%5.4f %5.4f], Nb: %6d, Nmoves: %5d, Cut: %6d, LB: ", + npwgts[samin(ncon*nparts, npwgts)], npwgts[samax(ncon*nparts, npwgts)], + nbnd, nmoves, graph->mincut); + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, tvec); + for (i=0; i limit[i]) + return 0; + + return 1; +} + + + +/************************************************************************* +* This function checks if the vertex weights of two vertices are above +* a given set of values +**************************************************************************/ +int AreAllHVwgtsAbove(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit) +{ + int i; + + for (i=0; i max) + max = npwgts[j*ncon+i]; + } + + lbvec[i] = max*nparts; + } +} + + +/************************************************************************* +* This function determines if a partitioning is horizontally balanced +**************************************************************************/ +int MocIsHBalanced(int ncon, int nparts, float *npwgts, float *ubvec) +{ + int i, j; + float max; + + for (i=0; i max) + max = npwgts[j*ncon+i]; + } + + if (ubvec[i] < max*nparts) + return 0; + } + + return 1; +} + + + + + +/************************************************************************* +* This function checks if the pairwise balance of the between the two +* partitions will improve by moving the vertex v from pfrom to pto, +* subject to the target partition weights of tfrom, and tto respectively +**************************************************************************/ +int IsHBalanceBetterFT(int ncon, int nparts, float *pfrom, float *pto, float *vwgt, float *ubvec) +{ + int i, j, k; + float blb1=0.0, alb1=0.0, sblb=0.0, salb=0.0; + float blb2=0.0, alb2=0.0; + float temp; + + for (i=0; i m11) + return 0; + if (m22 < m12) + return 1; + if (m22 > m12) + return 0; + + return sm2 < sm1; +} + 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 + + +/************************************************************************* +* 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; iid = myrinfo->ed = myrinfo->ndegrees = 0; + myrinfo->edegrees = NULL; + + for (j=xadj[i]; jed += 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]; jndegrees; 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; iwspace.cdegree = 0; + for (nbnd=0, i=0; iid = 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; jed += 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; jncon*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; irinfo[i].ed > 0) + BNDInsert(nbnd, bndind, bndptr, i); + } + + graph->nbnd = nbnd; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmatch.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmatch.c new file mode 100644 index 0000000..2666dd3 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmatch.c @@ -0,0 +1,501 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mmatch.c + * + * This file contains the code that computes matchings and creates the next + * level coarse graph. + * + * Started 7/23/97 + * George + * + * $Id: mmatch.c,v 1.1 2003/07/16 15:55:11 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void MCMatch_RM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, k, nvtxs, ncon, cnvtxs, maxidx; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *match, *cmap, *perm; + float *nvwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; iinmaxvwgt)) { + maxidx = k; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void MCMatch_HEM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, k, l, nvtxs, cnvtxs, ncon, maxidx, maxwgt; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *match, *cmap, *perm; + float *nvwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + RandomPermute(nvtxs, perm, 1); + + cnvtxs = 0; + for (ii=0; iinmaxvwgt)) { + maxwgt = adjwgt[j]; + maxidx = adjncy[j]; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void MCMatch_SHEM(CtrlType *ctrl, GraphType *graph) +{ + int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *match, *cmap, *degrees, *perm, *tperm; + float *nvwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + tperm = idxwspacemalloc(ctrl, nvtxs); + degrees = idxwspacemalloc(ctrl, nvtxs); + + RandomPermute(nvtxs, tperm, 1); + avgdegree = 0.7*(xadj[nvtxs]/nvtxs); + for (i=0; i avgdegree ? avgdegree : xadj[i+1]-xadj[i]); + BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); + + cnvtxs = 0; + + /* Take care any islands. Islands are matched with non-islands due to coarsening */ + for (ii=0; iiii; j--) { + k = perm[j]; + if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { + maxidx = k; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + /* Continue with normal matching */ + for (; iinmaxvwgt)) { + maxwgt = adjwgt[j]; + maxidx = adjncy[j]; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + idxwspacefree(ctrl, nvtxs); /* degrees */ + idxwspacefree(ctrl, nvtxs); /* tperm */ + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void MCMatch_SHEBM(CtrlType *ctrl, GraphType *graph, int norm) +{ + int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *match, *cmap, *degrees, *perm, *tperm; + float *nvwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + tperm = idxwspacemalloc(ctrl, nvtxs); + degrees = idxwspacemalloc(ctrl, nvtxs); + + RandomPermute(nvtxs, tperm, 1); + avgdegree = 0.7*(xadj[nvtxs]/nvtxs); + for (i=0; i avgdegree ? avgdegree : xadj[i+1]-xadj[i]); + BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); + + cnvtxs = 0; + + /* Take care any islands. Islands are matched with non-islands due to coarsening */ + for (ii=0; iiii; j--) { + k = perm[j]; + if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { + maxidx = k; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + /* Continue with normal matching */ + for (; iinmaxvwgt) && + (maxwgt < adjwgt[j] || + (maxwgt == adjwgt[j] && + BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon) >= 0 + ) + ) + ) { + maxwgt = adjwgt[j]; + maxidx = k; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + idxwspacefree(ctrl, nvtxs); /* degrees */ + idxwspacefree(ctrl, nvtxs); /* tperm */ + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void MCMatch_SBHEM(CtrlType *ctrl, GraphType *graph, int norm) +{ + int i, ii, j, k, nvtxs, cnvtxs, ncon, maxidx, maxwgt, avgdegree; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *match, *cmap, *degrees, *perm, *tperm; + float *nvwgt, vbal; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + cmap = graph->cmap; + match = idxset(nvtxs, UNMATCHED, idxwspacemalloc(ctrl, nvtxs)); + + perm = idxwspacemalloc(ctrl, nvtxs); + tperm = idxwspacemalloc(ctrl, nvtxs); + degrees = idxwspacemalloc(ctrl, nvtxs); + + RandomPermute(nvtxs, tperm, 1); + avgdegree = 0.7*(xadj[nvtxs]/nvtxs); + for (i=0; i avgdegree ? avgdegree : xadj[i+1]-xadj[i]); + BucketSortKeysInc(nvtxs, avgdegree, degrees, tperm, perm); + + cnvtxs = 0; + + /* Take care any islands. Islands are matched with non-islands due to coarsening */ + for (ii=0; iiii; j--) { + k = perm[j]; + if (match[k] == UNMATCHED && xadj[k] < xadj[k+1]) { + maxidx = k; + break; + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + /* Continue with normal matching */ + for (; iinmaxvwgt)) { + if (maxidx != i) + vbal = BetterVBalance(ncon, norm, nvwgt+i*ncon, nvwgt+maxidx*ncon, nvwgt+k*ncon); + + if (vbal > 0 || (vbal > -.01 && maxwgt < adjwgt[j])) { + maxwgt = adjwgt[j]; + maxidx = k; + } + } + } + + cmap[i] = cmap[maxidx] = cnvtxs++; + match[i] = maxidx; + match[maxidx] = i; + } + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + idxwspacefree(ctrl, nvtxs); /* degrees */ + idxwspacefree(ctrl, nvtxs); /* tperm */ + + CreateCoarseGraph(ctrl, graph, cnvtxs, match, perm); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + + + +/************************************************************************* +* This function checks if v+u2 provides a better balance in the weight +* vector that v+u1 +**************************************************************************/ +float BetterVBalance(int ncon, int norm, float *vwgt, float *u1wgt, float *u2wgt) +{ + int i; + float sum1, sum2, max1, max2, min1, min2, diff1, diff2; + + if (norm == -1) { + max1 = min1 = vwgt[0]+u1wgt[0]; + max2 = min2 = vwgt[0]+u2wgt[0]; + sum1 = vwgt[0]+u1wgt[0]; + sum2 = vwgt[0]+u2wgt[0]; + + for (i=1; i vwgt[i]+u1wgt[i]) + min1 = vwgt[i]+u1wgt[i]; + + if (max2 < vwgt[i]+u2wgt[i]) + max2 = vwgt[i]+u2wgt[i]; + if (min2 > vwgt[i]+u2wgt[i]) + min2 = vwgt[i]+u2wgt[i]; + + sum1 += vwgt[i]+u1wgt[i]; + sum2 += vwgt[i]+u2wgt[i]; + } + + return ((max1-min1)/sum1) - ((max2-min2)/sum2); + } + else if (norm == 1) { + sum1 = sum2 = 0.0; + for (i=0; i limit) + return 0; + + return 1; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c new file mode 100644 index 0000000..1b43618 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mmd.c @@ -0,0 +1,593 @@ +/* + * mmd.c + * + * ************************************************************** + * The following C function was developed from a FORTRAN subroutine + * in SPARSPAK written by Eleanor Chu, Alan George, Joseph Liu + * and Esmond Ng. + * + * The FORTRAN-to-C transformation and modifications such as dynamic + * memory allocation and deallocation were performed by Chunguang + * Sun. + * ************************************************************** + * + * Taken from SMMS, George 12/13/94 + * + * The meaning of invperm, and perm vectors is different from that + * in genqmd_ of SparsPak + * + * $Id: mmd.c,v 1.1 2003/07/16 15:55:11 karypis Exp $ + */ + +#include + + +/************************************************************************* +* genmmd -- multiple minimum external degree +* purpose -- this routine implements the minimum degree +* algorithm. it makes use of the implicit representation +* of elimination graphs by quotient graphs, and the notion +* of indistinguishable nodes. It also implements the modifications +* by multiple elimination and minimum external degree. +* Caution -- the adjacency vector adjncy will be destroyed. +* Input parameters -- +* neqns -- number of equations. +* (xadj, adjncy) -- the adjacency structure. +* delta -- tolerance value for multiple elimination. +* maxint -- maximum machine representable (short) integer +* (any smaller estimate will do) for marking nodes. +* Output parameters -- +* perm -- the minimum degree ordering. +* invp -- the inverse of perm. +* *ncsub -- an upper bound on the number of nonzero subscripts +* for the compressed storage scheme. +* Working parameters -- +* head -- vector for head of degree lists. +* invp -- used temporarily for degree forward link. +* perm -- used temporarily for degree backward link. +* qsize -- vector for size of supernodes. +* list -- vector for temporary linked lists. +* marker -- a temporary marker vector. +* Subroutines used -- mmdelm, mmdint, mmdnum, mmdupd. +**************************************************************************/ +void genmmd(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *invp, idxtype *perm, + int delta, idxtype *head, idxtype *qsize, idxtype *list, idxtype *marker, + int maxint, int *ncsub) +{ + int ehead, i, mdeg, mdlmt, mdeg_node, nextmd, num, tag; + + if (neqns <= 0) + return; + + /* Adjust from C to Fortran */ + xadj--; adjncy--; invp--; perm--; head--; qsize--; list--; marker--; + + /* initialization for the minimum degree algorithm. */ + *ncsub = 0; + mmdint(neqns, xadj, adjncy, head, invp, perm, qsize, list, marker); + + /* 'num' counts the number of ordered nodes plus 1. */ + num = 1; + + /* eliminate all isolated nodes. */ + nextmd = head[1]; + while (nextmd > 0) { + mdeg_node = nextmd; + nextmd = invp[mdeg_node]; + marker[mdeg_node] = maxint; + invp[mdeg_node] = -num; + num = num + 1; + } + + /* search for node of the minimum degree. 'mdeg' is the current */ + /* minimum degree; 'tag' is used to facilitate marking nodes. */ + if (num > neqns) + goto n1000; + tag = 1; + head[1] = 0; + mdeg = 2; + + /* infinite loop here ! */ + while (1) { + while (head[mdeg] <= 0) + mdeg++; + + /* use value of 'delta' to set up 'mdlmt', which governs */ + /* when a degree update is to be performed. */ + mdlmt = mdeg + delta; + ehead = 0; + +n500: + mdeg_node = head[mdeg]; + while (mdeg_node <= 0) { + mdeg++; + + if (mdeg > mdlmt) + goto n900; + mdeg_node = head[mdeg]; + }; + + /* remove 'mdeg_node' from the degree structure. */ + nextmd = invp[mdeg_node]; + head[mdeg] = nextmd; + if (nextmd > 0) + perm[nextmd] = -mdeg; + invp[mdeg_node] = -num; + *ncsub += mdeg + qsize[mdeg_node] - 2; + if ((num+qsize[mdeg_node]) > neqns) + goto n1000; + + /* eliminate 'mdeg_node' and perform quotient graph */ + /* transformation. reset 'tag' value if necessary. */ + tag++; + if (tag >= maxint) { + tag = 1; + for (i = 1; i <= neqns; i++) + if (marker[i] < maxint) + marker[i] = 0; + }; + + mmdelm(mdeg_node, xadj, adjncy, head, invp, perm, qsize, list, marker, maxint, tag); + + num += qsize[mdeg_node]; + list[mdeg_node] = ehead; + ehead = mdeg_node; + if (delta >= 0) + goto n500; + + n900: + /* update degrees of the nodes involved in the */ + /* minimum degree nodes elimination. */ + if (num > neqns) + goto n1000; + mmdupd( ehead, neqns, xadj, adjncy, delta, &mdeg, head, invp, perm, qsize, list, marker, maxint, &tag); + }; /* end of -- while ( 1 ) -- */ + +n1000: + mmdnum( neqns, perm, invp, qsize ); + + /* Adjust from Fortran back to C*/ + xadj++; adjncy++; invp++; perm++; head++; qsize++; list++; marker++; +} + + +/************************************************************************** +* mmdelm ...... multiple minimum degree elimination +* Purpose -- This routine eliminates the node mdeg_node of minimum degree +* from the adjacency structure, which is stored in the quotient +* graph format. It also transforms the quotient graph representation +* of the elimination graph. +* Input parameters -- +* mdeg_node -- node of minimum degree. +* maxint -- estimate of maximum representable (short) integer. +* tag -- tag value. +* Updated parameters -- +* (xadj, adjncy) -- updated adjacency structure. +* (head, forward, backward) -- degree doubly linked structure. +* qsize -- size of supernode. +* marker -- marker vector. +* list -- temporary linked list of eliminated nabors. +***************************************************************************/ +void mmdelm(int mdeg_node, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, + idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker, int maxint,int tag) +{ + int element, i, istop, istart, j, + jstop, jstart, link, + nabor, node, npv, nqnbrs, nxnode, + pvnode, rlmt, rloc, rnode, xqnbr; + + /* find the reachable set of 'mdeg_node' and */ + /* place it in the data structure. */ + marker[mdeg_node] = tag; + istart = xadj[mdeg_node]; + istop = xadj[mdeg_node+1] - 1; + + /* 'element' points to the beginning of the list of */ + /* eliminated nabors of 'mdeg_node', and 'rloc' gives the */ + /* storage location for the next reachable node. */ + element = 0; + rloc = istart; + rlmt = istop; + for ( i = istart; i <= istop; i++ ) { + nabor = adjncy[i]; + if ( nabor == 0 ) break; + if ( marker[nabor] < tag ) { + marker[nabor] = tag; + if ( forward[nabor] < 0 ) { + list[nabor] = element; + element = nabor; + } else { + adjncy[rloc] = nabor; + rloc++; + }; + }; /* end of -- if -- */ + }; /* end of -- for -- */ + + /* merge with reachable nodes from generalized elements. */ + while ( element > 0 ) { + adjncy[rlmt] = -element; + link = element; + +n400: + jstart = xadj[link]; + jstop = xadj[link+1] - 1; + for ( j = jstart; j <= jstop; j++ ) { + node = adjncy[j]; + link = -node; + if ( node < 0 ) goto n400; + if ( node == 0 ) break; + if ((marker[node]=0)) { + marker[node] = tag; + /*use storage from eliminated nodes if necessary.*/ + while ( rloc >= rlmt ) { + link = -adjncy[rlmt]; + rloc = xadj[link]; + rlmt = xadj[link+1] - 1; + }; + adjncy[rloc] = node; + rloc++; + }; + }; /* end of -- for ( j = jstart; -- */ + element = list[element]; + }; /* end of -- while ( element > 0 ) -- */ + if ( rloc <= rlmt ) adjncy[rloc] = 0; + /* for each node in the reachable set, do the following. */ + link = mdeg_node; + +n1100: + istart = xadj[link]; + istop = xadj[link+1] - 1; + for ( i = istart; i <= istop; i++ ) { + rnode = adjncy[i]; + link = -rnode; + if ( rnode < 0 ) goto n1100; + if ( rnode == 0 ) return; + + /* 'rnode' is in the degree list structure. */ + pvnode = backward[rnode]; + if (( pvnode != 0 ) && ( pvnode != (-maxint) )) { + /* then remove 'rnode' from the structure. */ + nxnode = forward[rnode]; + if ( nxnode > 0 ) backward[nxnode] = pvnode; + if ( pvnode > 0 ) forward[pvnode] = nxnode; + npv = -pvnode; + if ( pvnode < 0 ) head[npv] = nxnode; + }; + + /* purge inactive quotient nabors of 'rnode'. */ + jstart = xadj[rnode]; + jstop = xadj[rnode+1] - 1; + xqnbr = jstart; + for ( j = jstart; j <= jstop; j++ ) { + nabor = adjncy[j]; + if ( nabor == 0 ) break; + if ( marker[nabor] < tag ) { + adjncy[xqnbr] = nabor; + xqnbr++; + }; + }; + + /* no active nabor after the purging. */ + nqnbrs = xqnbr - jstart; + if ( nqnbrs <= 0 ) { + /* merge 'rnode' with 'mdeg_node'. */ + qsize[mdeg_node] += qsize[rnode]; + qsize[rnode] = 0; + marker[rnode] = maxint; + forward[rnode] = -mdeg_node; + backward[rnode] = -maxint; + } else { + /* flag 'rnode' for degree update, and */ + /* add 'mdeg_node' as a nabor of 'rnode'. */ + forward[rnode] = nqnbrs + 1; + backward[rnode] = 0; + adjncy[xqnbr] = mdeg_node; + xqnbr++; + if ( xqnbr <= jstop ) adjncy[xqnbr] = 0; + }; + }; /* end of -- for ( i = istart; -- */ + return; + } + +/*************************************************************************** +* mmdint ---- mult minimum degree initialization +* purpose -- this routine performs initialization for the +* multiple elimination version of the minimum degree algorithm. +* input parameters -- +* neqns -- number of equations. +* (xadj, adjncy) -- adjacency structure. +* output parameters -- +* (head, dfrow, backward) -- degree doubly linked structure. +* qsize -- size of supernode ( initialized to one). +* list -- linked list. +* marker -- marker vector. +****************************************************************************/ +int mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward, + idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker) +{ + int fnode, ndeg, node; + + for ( node = 1; node <= neqns; node++ ) { + head[node] = 0; + qsize[node] = 1; + marker[node] = 0; + list[node] = 0; + }; + + /* initialize the degree doubly linked lists. */ + for ( node = 1; node <= neqns; node++ ) { + ndeg = xadj[node+1] - xadj[node]/* + 1*/; /* george */ + if (ndeg == 0) + ndeg = 1; + fnode = head[ndeg]; + forward[node] = fnode; + head[ndeg] = node; + if ( fnode > 0 ) backward[fnode] = node; + backward[node] = -ndeg; + }; + return 0; +} + +/**************************************************************************** +* mmdnum --- multi minimum degree numbering +* purpose -- this routine performs the final step in producing +* the permutation and inverse permutation vectors in the +* multiple elimination version of the minimum degree +* ordering algorithm. +* input parameters -- +* neqns -- number of equations. +* qsize -- size of supernodes at elimination. +* updated parameters -- +* invp -- inverse permutation vector. on input, +* if qsize[node] = 0, then node has been merged +* into the node -invp[node]; otherwise, +* -invp[node] is its inverse labelling. +* output parameters -- +* perm -- the permutation vector. +****************************************************************************/ +void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize) +{ + int father, nextf, node, nqsize, num, root; + + for ( node = 1; node <= neqns; node++ ) { + nqsize = qsize[node]; + if ( nqsize <= 0 ) perm[node] = invp[node]; + if ( nqsize > 0 ) perm[node] = -invp[node]; + }; + + /* for each node which has been merged, do the following. */ + for ( node = 1; node <= neqns; node++ ) { + if ( perm[node] <= 0 ) { + + /* trace the merged tree until one which has not */ + /* been merged, call it root. */ + father = node; + while ( perm[father] <= 0 ) + father = - perm[father]; + + /* number node after root. */ + root = father; + num = perm[root] + 1; + invp[node] = -num; + perm[root] = num; + + /* shorten the merged tree. */ + father = node; + nextf = - perm[father]; + while ( nextf > 0 ) { + perm[father] = -root; + father = nextf; + nextf = -perm[father]; + }; + }; /* end of -- if ( perm[node] <= 0 ) -- */ + }; /* end of -- for ( node = 1; -- */ + + /* ready to compute perm. */ + for ( node = 1; node <= neqns; node++ ) { + num = -invp[node]; + invp[node] = num; + perm[num] = node; + }; + return; +} + +/**************************************************************************** +* mmdupd ---- multiple minimum degree update +* purpose -- this routine updates the degrees of nodes after a +* multiple elimination step. +* input parameters -- +* ehead -- the beginning of the list of eliminated nodes +* (i.e., newly formed elements). +* neqns -- number of equations. +* (xadj, adjncy) -- adjacency structure. +* delta -- tolerance value for multiple elimination. +* maxint -- maximum machine representable (short) integer. +* updated parameters -- +* mdeg -- new minimum degree after degree update. +* (head, forward, backward) -- degree doubly linked structure. +* qsize -- size of supernode. +* list -- marker vector for degree update. +* *tag -- tag value. +****************************************************************************/ +void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg, + idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list, + idxtype *marker, int maxint,int *tag) +{ + int deg, deg0, element, enode, fnode, i, iq2, istop, + istart, j, jstop, jstart, link, mdeg0, mtag, nabor, + node, q2head, qxhead; + + mdeg0 = *mdeg + delta; + element = ehead; + +n100: + if ( element <= 0 ) return; + + /* for each of the newly formed element, do the following. */ + /* reset tag value if necessary. */ + mtag = *tag + mdeg0; + if ( mtag >= maxint ) { + *tag = 1; + for ( i = 1; i <= neqns; i++ ) + if ( marker[i] < maxint ) marker[i] = 0; + mtag = *tag + mdeg0; + }; + + /* create two linked lists from nodes associated with 'element': */ + /* one with two nabors (q2head) in the adjacency structure, and the*/ + /* other with more than two nabors (qxhead). also compute 'deg0',*/ + /* number of nodes in this element. */ + q2head = 0; + qxhead = 0; + deg0 = 0; + link =element; + +n400: + istart = xadj[link]; + istop = xadj[link+1] - 1; + for ( i = istart; i <= istop; i++ ) { + enode = adjncy[i]; + link = -enode; + if ( enode < 0 ) goto n400; + if ( enode == 0 ) break; + if ( qsize[enode] != 0 ) { + deg0 += qsize[enode]; + marker[enode] = mtag; + + /*'enode' requires a degree update*/ + if ( backward[enode] == 0 ) { + /* place either in qxhead or q2head list. */ + if ( forward[enode] != 2 ) { + list[enode] = qxhead; + qxhead = enode; + } else { + list[enode] = q2head; + q2head = enode; + }; + }; + }; /* enf of -- if ( qsize[enode] != 0 ) -- */ + }; /* end of -- for ( i = istart; -- */ + + /* for each node in q2 list, do the following. */ + enode = q2head; + iq2 = 1; + +n900: + if ( enode <= 0 ) goto n1500; + if ( backward[enode] != 0 ) goto n2200; + (*tag)++; + deg = deg0; + + /* identify the other adjacent element nabor. */ + istart = xadj[enode]; + nabor = adjncy[istart]; + if ( nabor == element ) nabor = adjncy[istart+1]; + link = nabor; + if ( forward[nabor] >= 0 ) { + /* nabor is uneliminated, increase degree count. */ + deg += qsize[nabor]; + goto n2100; + }; + + /* the nabor is eliminated. for each node in the 2nd element */ + /* do the following. */ +n1000: + istart = xadj[link]; + istop = xadj[link+1] - 1; + for ( i = istart; i <= istop; i++ ) { + node = adjncy[i]; + link = -node; + if ( node != enode ) { + if ( node < 0 ) goto n1000; + if ( node == 0 ) goto n2100; + if ( qsize[node] != 0 ) { + if ( marker[node] < *tag ) { + /* 'node' is not yet considered. */ + marker[node] = *tag; + deg += qsize[node]; + } else { + if ( backward[node] == 0 ) { + if ( forward[node] == 2 ) { + /* 'node' is indistinguishable from 'enode'.*/ + /* merge them into a new supernode. */ + qsize[enode] += qsize[node]; + qsize[node] = 0; + marker[node] = maxint; + forward[node] = -enode; + backward[node] = -maxint; + } else { + /* 'node' is outmacthed by 'enode' */ + if (backward[node]==0) backward[node] = -maxint; + }; + }; /* end of -- if ( backward[node] == 0 ) -- */ + }; /* end of -- if ( marker[node] < *tag ) -- */ + }; /* end of -- if ( qsize[node] != 0 ) -- */ + }; /* end of -- if ( node != enode ) -- */ + }; /* end of -- for ( i = istart; -- */ + goto n2100; + +n1500: + /* for each 'enode' in the 'qx' list, do the following. */ + enode = qxhead; + iq2 = 0; + +n1600: if ( enode <= 0 ) goto n2300; + if ( backward[enode] != 0 ) goto n2200; + (*tag)++; + deg = deg0; + + /*for each unmarked nabor of 'enode', do the following.*/ + istart = xadj[enode]; + istop = xadj[enode+1] - 1; + for ( i = istart; i <= istop; i++ ) { + nabor = adjncy[i]; + if ( nabor == 0 ) break; + if ( marker[nabor] < *tag ) { + marker[nabor] = *tag; + link = nabor; + if ( forward[nabor] >= 0 ) + /*if uneliminated, include it in deg count.*/ + deg += qsize[nabor]; + else { +n1700: + /* if eliminated, include unmarked nodes in this*/ + /* element into the degree count. */ + jstart = xadj[link]; + jstop = xadj[link+1] - 1; + for ( j = jstart; j <= jstop; j++ ) { + node = adjncy[j]; + link = -node; + if ( node < 0 ) goto n1700; + if ( node == 0 ) break; + if ( marker[node] < *tag ) { + marker[node] = *tag; + deg += qsize[node]; + }; + }; /* end of -- for ( j = jstart; -- */ + }; /* end of -- if ( forward[nabor] >= 0 ) -- */ + }; /* end of -- if ( marker[nabor] < *tag ) -- */ + }; /* end of -- for ( i = istart; -- */ + +n2100: + /* update external degree of 'enode' in degree structure, */ + /* and '*mdeg' if necessary. */ + deg = deg - qsize[enode] + 1; + fnode = head[deg]; + forward[enode] = fnode; + backward[enode] = -deg; + if ( fnode > 0 ) backward[fnode] = enode; + head[deg] = enode; + if ( deg < *mdeg ) *mdeg = deg; + +n2200: + /* get next enode in current element. */ + enode = list[enode]; + if ( iq2 == 1 ) goto n900; + goto n1600; + +n2300: + /* get next element in the list. */ + *tag = mtag; + element = list[element]; + goto n100; + } diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mpmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mpmetis.c new file mode 100644 index 0000000..3b7aa9f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mpmetis.c @@ -0,0 +1,402 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mpmetis.c + * + * This file contains the top level routines for the multilevel recursive + * bisection algorithm PMETIS. + * + * Started 7/24/97 + * George + * + * $Id: mpmetis.c,v 1.1 2003/07/16 15:55:12 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = McPMETIS_CTYPE; + ctrl.IType = McPMETIS_ITYPE; + ctrl.RType = McPMETIS_RTYPE; + ctrl.dbglvl = McPMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCHPartGraphRecursive(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *ubvec, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *myubvec; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = PMETIS_CTYPE; + ctrl.IType = PMETIS_ITYPE; + ctrl.RType = PMETIS_RTYPE; + ctrl.dbglvl = PMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts"); + scopy(*ncon, ubvec, myubvec); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + GKfree(&myubvec, LTERM); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + float *nvwgt, idxtype *adjwgt, int *nparts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = PMETIS_CTYPE; + ctrl.IType = PMETIS_ITYPE; + ctrl.RType = PMETIS_RTYPE; + ctrl.dbglvl = PMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MCMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, 1.000, 0); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + +} + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCHPartGraphRecursiveInternal(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + float *nvwgt, idxtype *adjwgt, int *nparts, float *ubvec, int *options, int *edgecut, + idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *myubvec; + + SetUpGraph2(&graph, *nvtxs, *ncon, xadj, adjncy, nvwgt, adjwgt); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = PMETIS_CTYPE; + ctrl.IType = PMETIS_ITYPE; + ctrl.RType = PMETIS_RTYPE; + ctrl.dbglvl = PMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + myubvec = fmalloc(*ncon, "PWMETIS: mytpwgts"); + scopy(*ncon, ubvec, myubvec); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MCHMlevelRecursiveBisection(&ctrl, &graph, *nparts, part, myubvec, 0); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + GKfree(&myubvec, LTERM); + +} + + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, + float ubfactor, int fpart) +{ + int i, j, nvtxs, ncon, cut; + idxtype *label, *where; + GraphType lgraph, rgraph; + float tpwgts[2]; + + nvtxs = graph->nvtxs; + if (nvtxs == 0) { + printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); + return 0; + } + + /* Determine the weights of the partitions */ + tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts); + tpwgts[1] = 1.0 - tpwgts[0]; + + MCMlevelEdgeBisection(ctrl, graph, tpwgts, ubfactor); + cut = graph->mincut; + + label = graph->label; + where = graph->where; + for (i=0; i 2) + SplitGraphPart(ctrl, graph, &lgraph, &rgraph); + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->label, LTERM); + + + /* Do the recursive call */ + if (nparts > 3) { + cut += MCMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, ubfactor, fpart); + cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MCMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, ubfactor, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); + } + + return cut; + +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCHMlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, + float *ubvec, int fpart) +{ + int i, j, nvtxs, ncon, cut; + idxtype *label, *where; + GraphType lgraph, rgraph; + float tpwgts[2], *npwgts, *lubvec, *rubvec; + + lubvec = rubvec = NULL; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + if (nvtxs == 0) { + printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); + return 0; + } + + /* Determine the weights of the partitions */ + tpwgts[0] = 1.0*(nparts>>1)/(1.0*nparts); + tpwgts[1] = 1.0 - tpwgts[0]; + + /* For now, relax at the coarsest level only */ + if (nparts == 2) + MCHMlevelEdgeBisection(ctrl, graph, tpwgts, ubvec); + else + MCMlevelEdgeBisection(ctrl, graph, tpwgts, 1.000); + cut = graph->mincut; + + label = graph->label; + where = graph->where; + for (i=0; i 2) { + /* Adjust the ubvecs before the split */ + npwgts = graph->npwgts; + lubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection"); + rubvec = fmalloc(ncon, "MCHMlevelRecursiveBisection"); + + for (i=0; igdata, &graph->nvwgt, &graph->rdata, &graph->label, LTERM); + + + /* Do the recursive call */ + if (nparts > 3) { + cut += MCHMlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, lubvec, fpart); + cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MCHMlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, rubvec, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); + } + + GKfree(&lubvec, &rubvec, LTERM); + + return cut; + +} + + + + +/************************************************************************* +* This function performs multilevel bisection +**************************************************************************/ +void MCMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float ubfactor) +{ + GraphType *cgraph; + + cgraph = MCCoarsen2Way(ctrl, graph); + + MocInit2WayPartition(ctrl, cgraph, tpwgts, ubfactor); + + MocRefine2Way(ctrl, graph, cgraph, tpwgts, ubfactor); + +} + + + +/************************************************************************* +* This function performs multilevel bisection +**************************************************************************/ +void MCHMlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, float *tpwgts, float *ubvec) +{ + int i; + GraphType *cgraph; + +/* + for (i=0; incon; i++) + printf("%.4f ", ubvec[i]); + printf("\n"); +*/ + + cgraph = MCCoarsen2Way(ctrl, graph); + + MocInit2WayPartition2(ctrl, cgraph, tpwgts, ubvec); + + MocRefine2Way2(ctrl, graph, cgraph, tpwgts, ubvec); + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine.c new file mode 100644 index 0000000..3e28dc7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine.c @@ -0,0 +1,219 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * refine.c + * + * This file contains the driving routines for multilevel refinement + * + * Started 7/24/97 + * George + * + * $Id: mrefine.c,v 1.1 2003/07/24 18:39:10 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void MocRefine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, float ubfactor) +{ + int i; + float tubvec[MAXNCON]; + + for (i=0; incon; i++) + tubvec[i] = 1.0; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + MocCompute2WayPartitionParams(ctrl, graph); + + for (;;) { + ASSERT(CheckBnd(graph)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + switch (ctrl->RType) { + case RTYPE_FM: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + break; + case 2: + MocBalance2Way(ctrl, graph, tpwgts, 1.03); + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, tubvec, 8); + break; + default: + errexit("Unknown refinement type: %d\n", ctrl->RType); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + MocProject2WayPartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + MocBalance2Way(ctrl, graph, tpwgts, 1.01); + MocFM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for 2-way edge refinement +**************************************************************************/ +void MocAllocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) +{ + int nvtxs, ncon; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + graph->rdata = idxmalloc(5*nvtxs, "Allocate2WayPartitionMemory: rdata"); + graph->where = graph->rdata; + graph->id = graph->rdata + nvtxs; + graph->ed = graph->rdata + 2*nvtxs; + graph->bndptr = graph->rdata + 3*nvtxs; + graph->bndind = graph->rdata + 4*nvtxs; + + graph->npwgts = fmalloc(2*ncon, "npwgts"); +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void MocCompute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, l, nvtxs, ncon, nbnd, mincut; + idxtype *xadj, *adjncy, *adjwgt; + float *nvwgt, *npwgts; + idxtype *id, *ed, *where; + idxtype *bndptr, *bndind; + int me, other; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + npwgts = sset(2*ncon, 0.0, graph->npwgts); + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nbnd = mincut = 0; + for (i=0; i= 0 && where[i] <= 1); + me = where[i]; + saxpy(ncon, 1.0, nvwgt+i*ncon, 1, npwgts+me*ncon, 1); + + for (j=xadj[i]; j 0 || xadj[i] == xadj[i+1]) { + mincut += ed[i]; + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + + graph->mincut = mincut/2; + graph->nbnd = nbnd; + +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void MocProject2WayPartition(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, nvtxs, nbnd, me; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; + idxtype *cwhere, *cid, *ced, *cbndptr; + GraphType *cgraph; + + cgraph = graph->coarser; + cwhere = cgraph->where; + cid = cgraph->id; + ced = cgraph->ed; + cbndptr = cgraph->bndptr; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + MocAllocate2WayPartitionMemory(ctrl, graph); + + where = graph->where; + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; i 0 || xadj[i] == xadj[i+1]) { + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + } + } + + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + scopy(2*graph->ncon, cgraph->npwgts, graph->npwgts); + + FreeGraph(graph->coarser); + graph->coarser = NULL; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine2.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine2.c new file mode 100644 index 0000000..91ad0b5 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mrefine2.c @@ -0,0 +1,55 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mrefine2.c + * + * This file contains the driving routines for multilevel refinement + * + * Started 7/24/97 + * George + * + * $Id: mrefine2.c,v 1.1 2003/07/16 15:55:12 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void MocRefine2Way2(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float *tpwgts, + float *ubvec) +{ + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + MocCompute2WayPartitionParams(ctrl, graph); + + for (;;) { + ASSERT(CheckBnd(graph)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + switch (ctrl->RType) { + case RTYPE_FM: + MocBalance2Way2(ctrl, graph, tpwgts, ubvec); + MocFM_2WayEdgeRefine2(ctrl, graph, tpwgts, ubvec, 8); + break; + default: + errexit("Unknown refinement type: %d\n", ctrl->RType); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + MocProject2WayPartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mutil.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mutil.c new file mode 100644 index 0000000..68dc5c5 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/mutil.c @@ -0,0 +1,101 @@ +/* + * mutil.c + * + * This file contains various utility functions for the MOC portion of the + * code + * + * Started 2/15/98 + * George + * + * $Id: mutil.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function checks if the vertex weights of two vertices are below +* a given set of values +**************************************************************************/ +int AreAllVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit) +{ + int i; + + for (i=0; i limit) + return 0; + + return 1; +} + + +/************************************************************************* +* This function checks if the vertex weights of two vertices are below +* a given set of values +**************************************************************************/ +int AreAnyVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float limit) +{ + int i; + + for (i=0; i max) + max = npwgts[j*ncon+i]; + } + if (max*nparts > lb) + lb = max*nparts; + } + + return lb; +} + +/************************************************************************* +* This function checks if the vertex weights of two vertices are below +* a given set of values +**************************************************************************/ +int AreAllBelow(int ncon, float *v1, float *v2) +{ + int i; + + for (i=0; i v2[i]) + return 0; + + return 1; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/myqsort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/myqsort.c new file mode 100644 index 0000000..a6939ce --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/myqsort.c @@ -0,0 +1,547 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * myqsort.c + * + * This file contains a fast idxtype increasing qsort algorithm. + * Addopted from TeX + * + * Started 10/18/96 + * George + * + * $Id: myqsort.c,v 1.1 2003/07/16 15:55:13 karypis Exp $ + */ + +#include /* only for type declarations */ + +#define THRESH 1 /* threshold for insertion */ +#define MTHRESH 6 /* threshold for median */ + + + + +static void siqst(idxtype *, idxtype *); +static void iiqst(int *, int *); +static void keyiqst(KeyValueType *, KeyValueType *); +static void keyvaliqst(KeyValueType *, KeyValueType *); + + +/************************************************************************* +* Entry point of idxtype increasing sort +**************************************************************************/ +void iidxsort(int n, idxtype *base) +{ + register idxtype *i; + register idxtype *j; + register idxtype *lo; + register idxtype *hi; + register idxtype *min; + register idxtype c; + idxtype *max; + + if (n <= 1) + return; + + max = base + n; + + if (n >= THRESH) { + siqst(base, max); + hi = base + THRESH; + } + else + hi = max; + + for (j = lo = base; lo++ < hi;) { + if (*j > *lo) + j = lo; + } + if (j != base) { /* swap j into place */ + c = *base; + *base = *j; + *j = c; + } + + for (min = base; (hi = min += 1) < max;) { + while (*(--hi) > *min); + if ((hi += 1) != min) { + for (lo = min + 1; --lo >= min;) { + c = *lo; + for (i = j = lo; (j -= 1) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} + +static void siqst(idxtype *base, idxtype *max) +{ + register idxtype *i; + register idxtype *j; + register idxtype *jj; + register idxtype *mid; + register int ii; + register idxtype c; + idxtype *tmp; + int lo; + int hi; + + lo = max - base; /* number of elements as idxtype */ + do { + mid = base + ((unsigned) lo>>1); + if (lo >= MTHRESH) { + j = (*base > *mid ? base : mid); + tmp = max - 1; + if (*j > *tmp) { + j = (j == base ? mid : base); /* switch to first loser */ + if (*j < *tmp) + j = tmp; + } + + if (j != mid) { /* SWAP */ + c = *mid; + *mid = *j; + *j = c; + } + } + + /* Semi-standard quicksort partitioning/swapping */ + for (i = base, j = max - 1;;) { + while (i < mid && *i <= *mid) + i++; + while (j > mid) { + if (*mid <= *j) { + j--; + continue; + } + tmp = i + 1; /* value of i after swap */ + if (i == mid) /* j <-> mid, new mid is j */ + mid = jj = j; + else /* i <-> j */ + jj = j--; + goto swap; + } + + if (i == mid) + break; + else { /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j--; + } +swap: + c = *i; + *i = *jj; + *jj = c; + i = tmp; + } + + i = (j = mid) + 1; + if ((lo = j - base) <= (hi = max - i)) { + if (lo >= THRESH) + siqst(base, j); + base = i; + lo = hi; + } + else { + if (hi >= THRESH) + siqst(i, max); + max = j; + } + } while (lo >= THRESH); +} + + + + + +/************************************************************************* +* Entry point of int increasing sort +**************************************************************************/ +void iintsort(int n, int *base) +{ + register int *i; + register int *j; + register int *lo; + register int *hi; + register int *min; + register int c; + int *max; + + if (n <= 1) + return; + + max = base + n; + + if (n >= THRESH) { + iiqst(base, max); + hi = base + THRESH; + } + else + hi = max; + + for (j = lo = base; lo++ < hi;) { + if (*j > *lo) + j = lo; + } + if (j != base) { /* swap j into place */ + c = *base; + *base = *j; + *j = c; + } + + for (min = base; (hi = min += 1) < max;) { + while (*(--hi) > *min); + if ((hi += 1) != min) { + for (lo = min + 1; --lo >= min;) { + c = *lo; + for (i = j = lo; (j -= 1) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} + + +static void iiqst(int *base, int *max) +{ + register int *i; + register int *j; + register int *jj; + register int *mid; + register int ii; + register int c; + int *tmp; + int lo; + int hi; + + lo = max - base; /* number of elements as ints */ + do { + mid = base + ((unsigned) lo>>1); + if (lo >= MTHRESH) { + j = (*base > *mid ? base : mid); + tmp = max - 1; + if (*j > *tmp) { + j = (j == base ? mid : base); /* switch to first loser */ + if (*j < *tmp) + j = tmp; + } + + if (j != mid) { /* SWAP */ + c = *mid; + *mid = *j; + *j = c; + } + } + + /* Semi-standard quicksort partitioning/swapping */ + for (i = base, j = max - 1;;) { + while (i < mid && *i <= *mid) + i++; + while (j > mid) { + if (*mid <= *j) { + j--; + continue; + } + tmp = i + 1; /* value of i after swap */ + if (i == mid) /* j <-> mid, new mid is j */ + mid = jj = j; + else /* i <-> j */ + jj = j--; + goto swap; + } + + if (i == mid) + break; + else { /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j--; + } +swap: + c = *i; + *i = *jj; + *jj = c; + i = tmp; + } + + i = (j = mid) + 1; + if ((lo = j - base) <= (hi = max - i)) { + if (lo >= THRESH) + iiqst(base, j); + base = i; + lo = hi; + } + else { + if (hi >= THRESH) + iiqst(i, max); + max = j; + } + } while (lo >= THRESH); +} + + + + + +/************************************************************************* +* Entry point of KeyVal increasing sort, ONLY key part +**************************************************************************/ +void ikeysort(int n, KeyValueType *base) +{ + register KeyValueType *i; + register KeyValueType *j; + register KeyValueType *lo; + register KeyValueType *hi; + register KeyValueType *min; + register KeyValueType c; + KeyValueType *max; + + if (n <= 1) + return; + + max = base + n; + + if (n >= THRESH) { + keyiqst(base, max); + hi = base + THRESH; + } + else + hi = max; + + for (j = lo = base; lo++ < hi;) { + if (j->key > lo->key) + j = lo; + } + if (j != base) { /* swap j into place */ + c = *base; + *base = *j; + *j = c; + } + + for (min = base; (hi = min += 1) < max;) { + while ((--hi)->key > min->key); + if ((hi += 1) != min) { + for (lo = min + 1; --lo >= min;) { + c = *lo; + for (i = j = lo; (j -= 1) >= hi; i = j) + *i = *j; + *i = c; + } + } + } + + /* Sanity check */ + { + int i; + for (i=0; i base[i+1].key) + printf("Something went wrong!\n"); + } +} + + +static void keyiqst(KeyValueType *base, KeyValueType *max) +{ + register KeyValueType *i; + register KeyValueType *j; + register KeyValueType *jj; + register KeyValueType *mid; + register KeyValueType c; + KeyValueType *tmp; + int lo; + int hi; + + lo = (max - base)>>1; /* number of elements as KeyValueType */ + do { + mid = base + ((unsigned) lo>>1); + if (lo >= MTHRESH) { + j = (base->key > mid->key ? base : mid); + tmp = max - 1; + if (j->key > tmp->key) { + j = (j == base ? mid : base); /* switch to first loser */ + if (j->key < tmp->key) + j = tmp; + } + + if (j != mid) { /* SWAP */ + c = *mid; + *mid = *j; + *j = c; + } + } + + /* Semi-standard quicksort partitioning/swapping */ + for (i = base, j = max - 1;;) { + while (i < mid && i->key <= mid->key) + i++; + while (j > mid) { + if (mid->key <= j->key) { + j--; + continue; + } + tmp = i + 1; /* value of i after swap */ + if (i == mid) /* j <-> mid, new mid is j */ + mid = jj = j; + else /* i <-> j */ + jj = j--; + goto swap; + } + + if (i == mid) + break; + else { /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j--; + } +swap: + c = *i; + *i = *jj; + *jj = c; + i = tmp; + } + + i = (j = mid) + 1; + if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) { + if (lo >= THRESH) + keyiqst(base, j); + base = i; + lo = hi; + } + else { + if (hi >= THRESH) + keyiqst(i, max); + max = j; + } + } while (lo >= THRESH); +} + + + + +/************************************************************************* +* Entry point of KeyVal increasing sort, BOTH key and val part +**************************************************************************/ +void ikeyvalsort(int n, KeyValueType *base) +{ + register KeyValueType *i; + register KeyValueType *j; + register KeyValueType *lo; + register KeyValueType *hi; + register KeyValueType *min; + register KeyValueType c; + KeyValueType *max; + + if (n <= 1) + return; + + max = base + n; + + if (n >= THRESH) { + keyvaliqst(base, max); + hi = base + THRESH; + } + else + hi = max; + + for (j = lo = base; lo++ < hi;) { + if ((j->key > lo->key) || (j->key == lo->key && j->val > lo->val)) + j = lo; + } + if (j != base) { /* swap j into place */ + c = *base; + *base = *j; + *j = c; + } + + for (min = base; (hi = min += 1) < max;) { + while ((--hi)->key > min->key || (hi->key == min->key && hi->val > min->val)); + if ((hi += 1) != min) { + for (lo = min + 1; --lo >= min;) { + c = *lo; + for (i = j = lo; (j -= 1) >= hi; i = j) + *i = *j; + *i = c; + } + } + } +} + + +static void keyvaliqst(KeyValueType *base, KeyValueType *max) +{ + register KeyValueType *i; + register KeyValueType *j; + register KeyValueType *jj; + register KeyValueType *mid; + register KeyValueType c; + KeyValueType *tmp; + int lo; + int hi; + + lo = (max - base)>>1; /* number of elements as KeyValueType */ + do { + mid = base + ((unsigned) lo>>1); + if (lo >= MTHRESH) { + j = (base->key > mid->key || (base->key == mid->key && base->val > mid->val) ? base : mid); + tmp = max - 1; + if (j->key > tmp->key || (j->key == tmp->key && j->val > tmp->val)) { + j = (j == base ? mid : base); /* switch to first loser */ + if (j->key < tmp->key || (j->key == tmp->key && j->val < tmp->val)) + j = tmp; + } + + if (j != mid) { /* SWAP */ + c = *mid; + *mid = *j; + *j = c; + } + } + + /* Semi-standard quicksort partitioning/swapping */ + for (i = base, j = max - 1;;) { + while (i < mid && (i->key < mid->key || (i->key == mid->key && i->val <= mid->val))) + i++; + while (j > mid) { + if (mid->key < j->key || (mid->key == j->key && mid->val <= j->val)) { + j--; + continue; + } + tmp = i + 1; /* value of i after swap */ + if (i == mid) /* j <-> mid, new mid is j */ + mid = jj = j; + else /* i <-> j */ + jj = j--; + goto swap; + } + + if (i == mid) + break; + else { /* i <-> mid, new mid is i */ + jj = mid; + tmp = mid = i; /* value of i after swap */ + j--; + } +swap: + c = *i; + *i = *jj; + *jj = c; + i = tmp; + } + + i = (j = mid) + 1; + if ((lo = (j - base)>>1) <= (hi = (max - i)>>1)) { + if (lo >= THRESH) + keyvaliqst(base, j); + base = i; + lo = hi; + } + else { + if (hi >= THRESH) + keyvaliqst(i, max); + max = j; + } + } while (lo >= THRESH); +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/ometis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/ometis.c new file mode 100644 index 0000000..e972e88 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/ometis.c @@ -0,0 +1,764 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * ometis.c + * + * This file contains the top level routines for the multilevel recursive + * bisection algorithm PMETIS. + * + * Started 7/24/97 + * George + * + * $Id: ometis.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for OEMETIS +**************************************************************************/ +void METIS_EdgeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *perm, idxtype *iperm) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_OEMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = OEMETIS_CTYPE; + ctrl.IType = OEMETIS_ITYPE; + ctrl.RType = OEMETIS_RTYPE; + ctrl.dbglvl = OEMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.oflags = 0; + ctrl.pfactor = -1; + ctrl.nseps = 1; + + ctrl.optype = OP_OEMETIS; + ctrl.CoarsenTo = 20; + ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo); + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, 2); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, *nvtxs); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + for (i=0; i<*nvtxs; i++) + perm[iperm[i]] = i; + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumberingOrder(*nvtxs, xadj, adjncy, perm, iperm); +} + + +/************************************************************************* +* This function is the entry point for ONCMETIS +**************************************************************************/ +void METIS_NodeND(int *nvtxs, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *perm, idxtype *iperm) +{ + int i, ii, j, l, wflag, nflag; + GraphType graph; + CtrlType ctrl; + idxtype *cptr, *cind, *piperm; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = ONMETIS_CTYPE; + ctrl.IType = ONMETIS_ITYPE; + ctrl.RType = ONMETIS_RTYPE; + ctrl.dbglvl = ONMETIS_DBGLVL; + ctrl.oflags = ONMETIS_OFLAGS; + ctrl.pfactor = ONMETIS_PFACTOR; + ctrl.nseps = ONMETIS_NSEPS; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + ctrl.oflags = options[OPTION_OFLAGS]; + ctrl.pfactor = options[OPTION_PFACTOR]; + ctrl.nseps = options[OPTION_NSEPS]; + } + if (ctrl.nseps < 1) + ctrl.nseps = 1; + + ctrl.optype = OP_ONMETIS; + ctrl.CoarsenTo = 100; + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + InitRandom(-1); + + if (ctrl.pfactor > 0) { + /*============================================================ + * Prune the dense columns + ==============================================================*/ + piperm = idxmalloc(*nvtxs, "ONMETIS: piperm"); + + PruneGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, piperm, (float)(0.1*ctrl.pfactor)); + } + else if (ctrl.oflags&OFLAG_COMPRESS) { + /*============================================================ + * Compress the graph + ==============================================================*/ + cptr = idxmalloc(*nvtxs+1, "ONMETIS: cptr"); + cind = idxmalloc(*nvtxs, "ONMETIS: cind"); + + CompressGraph(&ctrl, &graph, *nvtxs, xadj, adjncy, cptr, cind); + + if (graph.nvtxs >= COMPRESSION_FRACTION*(*nvtxs)) { + ctrl.oflags--; /* We actually performed no compression */ + GKfree(&cptr, &cind, LTERM); + } + else if (2*graph.nvtxs < *nvtxs && ctrl.nseps == 1) + ctrl.nseps = 2; + } + else { + SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, NULL, NULL, 0); + } + + + /*============================================================= + * Do the nested dissection ordering + --=============================================================*/ + ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo); + AllocateWorkSpace(&ctrl, &graph, 2); + + if (ctrl.oflags&OFLAG_CCMP) + MlevelNestedDissectionCC(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs); + else + MlevelNestedDissection(&ctrl, &graph, iperm, ORDER_UNBALANCE_FRACTION, graph.nvtxs); + + FreeWorkSpace(&ctrl, &graph); + + if (ctrl.pfactor > 0) { /* Order any prunned vertices */ + if (graph.nvtxs < *nvtxs) { + idxcopy(graph.nvtxs, iperm, perm); /* Use perm as an auxiliary array */ + for (i=0; invtxs; + + /* Determine the weights of the partitions */ + tvwgt = idxsum(nvtxs, graph->vwgt); + tpwgts2[0] = tvwgt/2; + tpwgts2[1] = tvwgt-tpwgts2[0]; + + switch (ctrl->optype) { + case OP_OEMETIS: + MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); + ConstructMinCoverSeparator(ctrl, graph, ubfactor); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); + + break; + case OP_ONMETIS: + MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); + + IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); + + break; + } + + /* Order the nodes in the separator */ + nbnd = graph->nbnd; + bndind = graph->bndind; + label = graph->label; + for (i=0; igdata, &graph->rdata, &graph->label, LTERM); + + if (rgraph.nvtxs > MMDSWITCH) + MlevelNestedDissection(ctrl, &rgraph, order, ubfactor, lastvtx); + else { + MMDOrder(ctrl, &rgraph, order, lastvtx); + GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM); + } + if (lgraph.nvtxs > MMDSWITCH) + MlevelNestedDissection(ctrl, &lgraph, order, ubfactor, lastvtx-rgraph.nvtxs); + else { + MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); + GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM); + } +} + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +void MlevelNestedDissectionCC(CtrlType *ctrl, GraphType *graph, idxtype *order, float ubfactor, int lastvtx) +{ + int i, j, nvtxs, nbnd, tvwgt, tpwgts2[2], nsgraphs, ncmps, rnvtxs; + idxtype *label, *bndind; + idxtype *cptr, *cind; + GraphType *sgraphs; + + nvtxs = graph->nvtxs; + + /* Determine the weights of the partitions */ + tvwgt = idxsum(nvtxs, graph->vwgt); + tpwgts2[0] = tvwgt/2; + tpwgts2[1] = tvwgt-tpwgts2[0]; + + MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); + IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); + + /* Order the nodes in the separator */ + nbnd = graph->nbnd; + bndind = graph->bndind; + label = graph->label; + for (i=0; i 2) + printf("[%5d] has %3d components\n", nvtxs, ncmps); +*/ + + sgraphs = (GraphType *)GKmalloc(ncmps*sizeof(GraphType), "MlevelNestedDissectionCC: sgraphs"); + + nsgraphs = SplitGraphOrderCC(ctrl, graph, sgraphs, ncmps, cptr, cind); + + GKfree(&cptr, &cind, LTERM); + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); + + /* Go and process the subgraphs */ + for (rnvtxs=i=0; inseps == 1 || graph->nvtxs < (ctrl->oflags&OFLAG_COMPRESS ? 1000 : 2000)) { + MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); + return; + } + + nvtxs = graph->nvtxs; + + if (ctrl->oflags&OFLAG_COMPRESS) { /* Multiple separators at the original graph */ + bestwhere = idxmalloc(nvtxs, "MlevelNodeBisection2: bestwhere"); + mincut = nvtxs; + + for (i=ctrl->nseps; i>0; i--) { + MlevelNodeBisection(ctrl, graph, tpwgts, ubfactor); + + /* printf("%5d ", cgraph->mincut); */ + + if (graph->mincut < mincut) { + mincut = graph->mincut; + idxcopy(nvtxs, graph->where, bestwhere); + } + + GKfree(&graph->rdata, LTERM); + + if (mincut == 0) + break; + } + /* printf("[%5d]\n", mincut); */ + + Allocate2WayNodePartitionMemory(ctrl, graph); + idxcopy(nvtxs, bestwhere, graph->where); + free(bestwhere); + + Compute2WayNodePartitionParams(ctrl, graph); + } + else { /* Coarsen it a bit */ + ctrl->CoarsenTo = nvtxs-1; + + cgraph = Coarsen2Way(ctrl, graph); + + cnvtxs = cgraph->nvtxs; + + bestwhere = idxmalloc(cnvtxs, "MlevelNodeBisection2: bestwhere"); + mincut = nvtxs; + + for (i=ctrl->nseps; i>0; i--) { + ctrl->CType += 20; /* This is a hack. Look at coarsen.c */ + MlevelNodeBisection(ctrl, cgraph, tpwgts, ubfactor); + + /* printf("%5d ", cgraph->mincut); */ + + if (cgraph->mincut < mincut) { + mincut = cgraph->mincut; + idxcopy(cnvtxs, cgraph->where, bestwhere); + } + + GKfree(&cgraph->rdata, LTERM); + + if (mincut == 0) + break; + } + /* printf("[%5d]\n", mincut); */ + + Allocate2WayNodePartitionMemory(ctrl, cgraph); + idxcopy(cnvtxs, bestwhere, cgraph->where); + free(bestwhere); + + Compute2WayNodePartitionParams(ctrl, cgraph); + + Refine2WayNode(ctrl, graph, cgraph, ubfactor); + } + +} + +/************************************************************************* +* This function performs multilevel bisection +**************************************************************************/ +void MlevelNodeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + GraphType *cgraph; + + ctrl->CoarsenTo = graph->nvtxs/8; + if (ctrl->CoarsenTo > 100) + ctrl->CoarsenTo = 100; + else if (ctrl->CoarsenTo < 40) + ctrl->CoarsenTo = 40; + ctrl->maxvwgt = 1.5*((tpwgts[0]+tpwgts[1])/ctrl->CoarsenTo); + + cgraph = Coarsen2Way(ctrl, graph); + + switch (ctrl->IType) { + case IPART_GGPKL: + Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SepTmr)); + + Compute2WayPartitionParams(ctrl, cgraph); + ConstructSeparator(ctrl, cgraph, ubfactor); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SepTmr)); + break; + case IPART_GGPKLNODE: + InitSeparator(ctrl, cgraph, ubfactor); + break; + } + + Refine2WayNode(ctrl, graph, cgraph, ubfactor); + +} + + + + +/************************************************************************* +* This function takes a graph and a bisection and splits it into two graphs. +* This function relies on the fact that adjwgt is all equal to 1. +**************************************************************************/ +void SplitGraphOrder(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph) +{ + int i, ii, j, k, l, istart, iend, mypart, nvtxs, snvtxs[3], snedges[3]; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr, *bndind; + idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2]; + idxtype *rename; + idxtype *auxadjncy, *auxadjwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + label = graph->label; + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + ASSERT(bndptr != NULL); + + rename = idxwspacemalloc(ctrl, nvtxs); + + snvtxs[0] = snvtxs[1] = snvtxs[2] = snedges[0] = snedges[1] = snedges[2] = 0; + for (i=0; ixadj; + svwgt[0] = lgraph->vwgt; + sadjwgtsum[0] = lgraph->adjwgtsum; + sadjncy[0] = lgraph->adjncy; + sadjwgt[0] = lgraph->adjwgt; + slabel[0] = lgraph->label; + + SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]); + sxadj[1] = rgraph->xadj; + svwgt[1] = rgraph->vwgt; + sadjwgtsum[1] = rgraph->adjwgtsum; + sadjncy[1] = rgraph->adjncy; + sadjwgt[1] = rgraph->adjwgt; + slabel[1] = rgraph->label; + + /* Go and use bndptr to also mark the boundary nodes in the two partitions */ + for (ii=0; iinbnd; ii++) { + i = bndind[ii]; + for (j=xadj[i]; jnvtxs = snvtxs[0]; + lgraph->nedges = snedges[0]; + rgraph->nvtxs = snvtxs[1]; + rgraph->nedges = snedges[1]; + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); + + idxwspacefree(ctrl, nvtxs); + +} + +/************************************************************************* +* This function uses MMD to order the graph. The vertices are numbered +* from lastvtx downwards +**************************************************************************/ +void MMDOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, int lastvtx) +{ + int i, j, k, nvtxs, nofsub, firstvtx; + idxtype *xadj, *adjncy, *label; + idxtype *perm, *iperm, *head, *qsize, *list, *marker; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + /* Relabel the vertices so that it starts from 1 */ + k = xadj[nvtxs]; + for (i=0; ilabel; + firstvtx = lastvtx-nvtxs; + for (i=0; idbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + label = graph->label; + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + ASSERT(bndptr != NULL); + + /* Go and use bndptr to also mark the boundary nodes in the two partitions */ + for (ii=0; iinbnd; ii++) { + i = bndind[ii]; + for (j=xadj[i]; jdbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); + + idxwspacefree(ctrl, nvtxs); + + return ncmps; + +} + + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/parmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/parmetis.c new file mode 100644 index 0000000..d183082 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/parmetis.c @@ -0,0 +1,512 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * parmetis.c + * + * This file contains top level routines that are used by ParMETIS + * + * Started 10/14/97 + * George + * + * $Id: parmetis.c,v 1.2 2003/07/24 18:39:11 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for KMETIS with seed specification +* in options[7] +**************************************************************************/ +void METIS_PartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ + int i; + float *tpwgts; + + tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); + for (i=0; i<*nparts; i++) + tpwgts[i] = 1.0/(1.0*(*nparts)); + + METIS_WPartGraphKway2(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, + tpwgts, options, edgecut, part); + + free(tpwgts); +} + + +/************************************************************************* +* This function is the entry point for KWMETIS with seed specification +* in options[7] +**************************************************************************/ +void METIS_WPartGraphKway2(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_KMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = KMETIS_CTYPE; + ctrl.IType = KMETIS_ITYPE; + ctrl.RType = KMETIS_RTYPE; + ctrl.dbglvl = KMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_KMETIS; + ctrl.CoarsenTo = 20*(*nparts); + ctrl.maxvwgt = 1.5*((graph.vwgt ? idxsum(*nvtxs, graph.vwgt) : (*nvtxs))/ctrl.CoarsenTo); + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MlevelKWayPartitioning(&ctrl, &graph, *nparts, part, tpwgts, 1.000); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + +/************************************************************************* +* This function is the entry point for the node ND code for ParMETIS +**************************************************************************/ +void METIS_NodeNDP(int nvtxs, idxtype *xadj, idxtype *adjncy, int npes, + int *options, idxtype *perm, idxtype *iperm, idxtype *sizes) +{ + int i, ii, j, l, wflag, nflag; + GraphType graph; + CtrlType ctrl; + idxtype *cptr, *cind; + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = ONMETIS_CTYPE; + ctrl.IType = ONMETIS_ITYPE; + ctrl.RType = ONMETIS_RTYPE; + ctrl.dbglvl = ONMETIS_DBGLVL; + ctrl.oflags = ONMETIS_OFLAGS; + ctrl.pfactor = ONMETIS_PFACTOR; + ctrl.nseps = ONMETIS_NSEPS; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + ctrl.oflags = options[OPTION_OFLAGS]; + ctrl.pfactor = options[OPTION_PFACTOR]; + ctrl.nseps = options[OPTION_NSEPS]; + } + if (ctrl.nseps < 1) + ctrl.nseps = 1; + + ctrl.optype = OP_ONMETIS; + ctrl.CoarsenTo = 100; + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + InitRandom(-1); + + if (ctrl.oflags&OFLAG_COMPRESS) { + /*============================================================ + * Compress the graph + ==============================================================*/ + cptr = idxmalloc(nvtxs+1, "ONMETIS: cptr"); + cind = idxmalloc(nvtxs, "ONMETIS: cind"); + + CompressGraph(&ctrl, &graph, nvtxs, xadj, adjncy, cptr, cind); + + if (graph.nvtxs >= COMPRESSION_FRACTION*(nvtxs)) { + ctrl.oflags--; /* We actually performed no compression */ + GKfree(&cptr, &cind, LTERM); + } + else if (2*graph.nvtxs < nvtxs && ctrl.nseps == 1) + ctrl.nseps = 2; + } + else { + SetUpGraph(&graph, OP_ONMETIS, nvtxs, 1, xadj, adjncy, NULL, NULL, 0); + } + + + /*============================================================= + * Do the nested dissection ordering + --=============================================================*/ + ctrl.maxvwgt = 1.5*(idxsum(graph.nvtxs, graph.vwgt)/ctrl.CoarsenTo); + AllocateWorkSpace(&ctrl, &graph, 2); + + idxset(2*npes-1, 0, sizes); + MlevelNestedDissectionP(&ctrl, &graph, iperm, graph.nvtxs, npes, 0, sizes); + + FreeWorkSpace(&ctrl, &graph); + + if (ctrl.oflags&OFLAG_COMPRESS) { /* Uncompress the ordering */ + if (graph.nvtxs < COMPRESSION_FRACTION*(nvtxs)) { + /* construct perm from iperm */ + for (i=0; invtxs; + + if (nvtxs == 0) { + GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); + return; + } + + /* Determine the weights of the partitions */ + tvwgt = idxsum(nvtxs, graph->vwgt); + tpwgts2[0] = tvwgt/2; + tpwgts2[1] = tvwgt-tpwgts2[0]; + + if (cpos >= npes-1) + ubfactor = ORDER_UNBALANCE_FRACTION; + else + ubfactor = 1.05; + + + MlevelNodeBisectionMultiple(ctrl, graph, tpwgts2, ubfactor); + + IFSET(ctrl->dbglvl, DBG_SEPINFO, printf("Nvtxs: %6d, [%6d %6d %6d]\n", graph->nvtxs, graph->pwgts[0], graph->pwgts[1], graph->pwgts[2])); + + if (cpos < npes-1) { + sizes[2*npes-2-cpos] = graph->pwgts[2]; + sizes[2*npes-2-(2*cpos+1)] = graph->pwgts[1]; + sizes[2*npes-2-(2*cpos+2)] = graph->pwgts[0]; + } + + /* Order the nodes in the separator */ + nbnd = graph->nbnd; + bndind = graph->bndind; + label = graph->label; + for (i=0; igdata, &graph->rdata, &graph->label, LTERM); + + if (rgraph.nvtxs > MMDSWITCH || 2*cpos+1 < npes-1) + MlevelNestedDissectionP(ctrl, &rgraph, order, lastvtx, npes, 2*cpos+1, sizes); + else { + MMDOrder(ctrl, &rgraph, order, lastvtx); + GKfree(&rgraph.gdata, &rgraph.rdata, &rgraph.label, LTERM); + } + if (lgraph.nvtxs > MMDSWITCH || 2*cpos+2 < npes-1) + MlevelNestedDissectionP(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs, npes, 2*cpos+2, sizes); + else { + MMDOrder(ctrl, &lgraph, order, lastvtx-rgraph.nvtxs); + GKfree(&lgraph.gdata, &lgraph.rdata, &lgraph.label, LTERM); + } +} + + + + +/************************************************************************* +* This function is the entry point for ONWMETIS. It requires weights on the +* vertices. It is for the case that the matrix has been pre-compressed. +**************************************************************************/ +void METIS_NodeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *options, int *sepsize, idxtype *part) +{ + int i, j, tvwgt, tpwgts[2]; + GraphType graph; + CtrlType ctrl; + + SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3); + tvwgt = idxsum(*nvtxs, graph.vwgt); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = ONMETIS_CTYPE; + ctrl.IType = ONMETIS_ITYPE; + ctrl.RType = ONMETIS_RTYPE; + ctrl.dbglvl = ONMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + + ctrl.oflags = 0; + ctrl.pfactor = 0; + ctrl.nseps = 1; + ctrl.optype = OP_ONMETIS; + ctrl.CoarsenTo = amin(100, *nvtxs-1); + ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, 2); + + /*============================================================ + * Perform the bisection + *============================================================*/ + tpwgts[0] = tvwgt/2; + tpwgts[1] = tvwgt-tpwgts[0]; + + MlevelNodeBisectionMultiple(&ctrl, &graph, tpwgts, 1.05); + + *sepsize = graph.pwgts[2]; + idxcopy(*nvtxs, graph.where, part); + + GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM); + + + FreeWorkSpace(&ctrl, &graph); + +} + + + +/************************************************************************* +* This function is the entry point for ONWMETIS. It requires weights on the +* vertices. It is for the case that the matrix has been pre-compressed. +**************************************************************************/ +void METIS_EdgeComputeSeparator(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *options, int *sepsize, idxtype *part) +{ + int i, j, tvwgt, tpwgts[2]; + GraphType graph; + CtrlType ctrl; + + SetUpGraph(&graph, OP_ONMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, 3); + tvwgt = idxsum(*nvtxs, graph.vwgt); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = ONMETIS_CTYPE; + ctrl.IType = ONMETIS_ITYPE; + ctrl.RType = ONMETIS_RTYPE; + ctrl.dbglvl = ONMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + + ctrl.oflags = 0; + ctrl.pfactor = 0; + ctrl.nseps = 1; + ctrl.optype = OP_OEMETIS; + ctrl.CoarsenTo = amin(100, *nvtxs-1); + ctrl.maxvwgt = 1.5*tvwgt/ctrl.CoarsenTo; + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, 2); + + /*============================================================ + * Perform the bisection + *============================================================*/ + tpwgts[0] = tvwgt/2; + tpwgts[1] = tvwgt-tpwgts[0]; + + MlevelEdgeBisection(&ctrl, &graph, tpwgts, 1.05); + ConstructMinCoverSeparator(&ctrl, &graph, 1.05); + + *sepsize = graph.pwgts[2]; + idxcopy(*nvtxs, graph.where, part); + + GKfree(&graph.gdata, &graph.rdata, &graph.label, LTERM); + + + FreeWorkSpace(&ctrl, &graph); + +} + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_mCPartGraphRecursive2(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *mytpwgts; + float avgwgt; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, *ncon, xadj, adjncy, vwgt, adjwgt, *wgtflag); + graph.npwgts = NULL; + mytpwgts = fmalloc(*nparts, "mytpwgts"); + scopy(*nparts, tpwgts, mytpwgts); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = McPMETIS_CTYPE; + ctrl.IType = McPMETIS_ITYPE; + ctrl.RType = McPMETIS_RTYPE; + ctrl.dbglvl = McPMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 100; + + ctrl.nmaxvwgt = 1.5/(1.0*ctrl.CoarsenTo); + + InitRandom(options[7]); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + ASSERT(CheckGraph(&graph)); + *edgecut = MCMlevelRecursiveBisection2(&ctrl, &graph, *nparts, mytpwgts, part, 1.000, 0); + +/* +{ +idxtype wgt[2048], minwgt, maxwgt, sumwgt; + +printf("nvtxs: %d, nparts: %d, ncon: %d\n", graph.nvtxs, *nparts, *ncon); +for (i=0; i<(*nparts)*(*ncon); i++) + wgt[i] = 0; +for (i=0; i wgt[maxwgt*(*ncon)+j]) ? i : maxwgt; + sumwgt += wgt[i*(*ncon)+j]; + } + avgwgt = (float)sumwgt / (float)*nparts; + printf("min: %5d, max: %5d, avg: %5.2f, balance: %6.3f\n", wgt[minwgt*(*ncon)+j], wgt[maxwgt*(*ncon)+j], avgwgt, (float)wgt[maxwgt*(*ncon)+j] / avgwgt); +} +printf("\n"); +} +*/ + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + GKfree((void *)&mytpwgts, LTERM); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MCMlevelRecursiveBisection2(CtrlType *ctrl, GraphType *graph, int nparts, + float *tpwgts, idxtype *part, float ubfactor, int fpart) +{ + int i, nvtxs, cut; + float wsum, tpwgts2[2]; + idxtype *label, *where; + GraphType lgraph, rgraph; + + nvtxs = graph->nvtxs; + if (nvtxs == 0) + return 0; + + /* Determine the weights of the partitions */ + tpwgts2[0] = ssum(nparts/2, tpwgts); + tpwgts2[1] = 1.0-tpwgts2[0]; + + MCMlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); + cut = graph->mincut; + + label = graph->label; + where = graph->where; + for (i=0; i 2) + SplitGraphPart(ctrl, graph, &lgraph, &rgraph); + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->nvwgt, &graph->rdata, &graph->label, &graph->npwgts, LTERM); + + /* Scale the fractions in the tpwgts according to the true weight */ + wsum = ssum(nparts/2, tpwgts); + sscale(nparts/2, 1.0/wsum, tpwgts); + sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2); + + /* Do the recursive call */ + if (nparts > 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &lgraph, nparts/2, tpwgts, part, ubfactor, fpart); + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MCMlevelRecursiveBisection2(ctrl, &rgraph, nparts-nparts/2, tpwgts+nparts/2, part, ubfactor, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.nvwgt, &lgraph.label, LTERM); + } + + return cut; + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pmetis.c new file mode 100644 index 0000000..9212cd7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pmetis.c @@ -0,0 +1,341 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * pmetis.c + * + * This file contains the top level routines for the multilevel recursive + * bisection algorithm PMETIS. + * + * Started 7/24/97 + * George + * + * $Id: pmetis.c,v 1.1 2003/07/16 15:55:16 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function is the entry point for PMETIS +**************************************************************************/ +void METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ + int i; + float *tpwgts; + + tpwgts = fmalloc(*nparts, "KMETIS: tpwgts"); + for (i=0; i<*nparts; i++) + tpwgts[i] = 1.0/(1.0*(*nparts)); + + METIS_WPartGraphRecursive(nvtxs, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, + tpwgts, options, edgecut, part); + + free(tpwgts); +} + + + +/************************************************************************* +* This function is the entry point for PWMETIS that accepts exact weights +* for the target partitions +**************************************************************************/ +void METIS_WPartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + float *tpwgts, int *options, int *edgecut, idxtype *part) +{ + int i, j; + GraphType graph; + CtrlType ctrl; + float *mytpwgts; + + if (*numflag == 1) + Change2CNumbering(*nvtxs, xadj, adjncy); + + SetUpGraph(&graph, OP_PMETIS, *nvtxs, 1, xadj, adjncy, vwgt, adjwgt, *wgtflag); + + if (options[0] == 0) { /* Use the default parameters */ + ctrl.CType = PMETIS_CTYPE; + ctrl.IType = PMETIS_ITYPE; + ctrl.RType = PMETIS_RTYPE; + ctrl.dbglvl = PMETIS_DBGLVL; + } + else { + ctrl.CType = options[OPTION_CTYPE]; + ctrl.IType = options[OPTION_ITYPE]; + ctrl.RType = options[OPTION_RTYPE]; + ctrl.dbglvl = options[OPTION_DBGLVL]; + } + ctrl.optype = OP_PMETIS; + ctrl.CoarsenTo = 20; + ctrl.maxvwgt = 1.5*(idxsum(*nvtxs, graph.vwgt)/ctrl.CoarsenTo); + + mytpwgts = fmalloc(*nparts, "PWMETIS: mytpwgts"); + for (i=0; i<*nparts; i++) + mytpwgts[i] = tpwgts[i]; + + InitRandom(-1); + + AllocateWorkSpace(&ctrl, &graph, *nparts); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + *edgecut = MlevelRecursiveBisection(&ctrl, &graph, *nparts, part, mytpwgts, 1.000, 0); + + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimers(&ctrl)); + + FreeWorkSpace(&ctrl, &graph); + free(mytpwgts); + + if (*numflag == 1) + Change2FNumbering(*nvtxs, xadj, adjncy, part); +} + + + +/************************************************************************* +* This function takes a graph and produces a bisection of it +**************************************************************************/ +int MlevelRecursiveBisection(CtrlType *ctrl, GraphType *graph, int nparts, idxtype *part, float *tpwgts, float ubfactor, int fpart) +{ + int i, j, nvtxs, cut, tvwgt, tpwgts2[2]; + idxtype *label, *where; + GraphType lgraph, rgraph; + float wsum; + + nvtxs = graph->nvtxs; + if (nvtxs == 0) { + printf("\t***Cannot bisect a graph with 0 vertices!\n\t***You are trying to partition a graph into too many parts!\n"); + return 0; + } + + /* Determine the weights of the partitions */ + tvwgt = idxsum(nvtxs, graph->vwgt); + tpwgts2[0] = tvwgt*ssum(nparts/2, tpwgts); + tpwgts2[1] = tvwgt-tpwgts2[0]; + + MlevelEdgeBisection(ctrl, graph, tpwgts2, ubfactor); + cut = graph->mincut; + + /* printf("%5d %5d %5d [%5d %f]\n", tpwgts2[0], tpwgts2[1], cut, tvwgt, ssum(nparts/2, tpwgts));*/ + + label = graph->label; + where = graph->where; + for (i=0; i 2) { + SplitGraphPart(ctrl, graph, &lgraph, &rgraph); + /* printf("%d %d\n", lgraph.nvtxs, rgraph.nvtxs); */ + } + + + /* Free the memory of the top level graph */ + GKfree(&graph->gdata, &graph->rdata, &graph->label, LTERM); + + /* Scale the fractions in the tpwgts according to the true weight */ + wsum = ssum(nparts/2, tpwgts); + sscale(nparts/2, 1.0/wsum, tpwgts); + sscale(nparts-nparts/2, 1.0/(1.0-wsum), tpwgts+nparts/2); + /* + for (i=0; i 3) { + cut += MlevelRecursiveBisection(ctrl, &lgraph, nparts/2, part, tpwgts, ubfactor, fpart); + cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2); + } + else if (nparts == 3) { + cut += MlevelRecursiveBisection(ctrl, &rgraph, nparts-nparts/2, part, tpwgts+nparts/2, ubfactor, fpart+nparts/2); + GKfree(&lgraph.gdata, &lgraph.label, LTERM); + } + + return cut; + +} + + +/************************************************************************* +* This function performs multilevel bisection +**************************************************************************/ +void MlevelEdgeBisection(CtrlType *ctrl, GraphType *graph, int *tpwgts, float ubfactor) +{ + GraphType *cgraph; + + cgraph = Coarsen2Way(ctrl, graph); + + Init2WayPartition(ctrl, cgraph, tpwgts, ubfactor); + + Refine2Way(ctrl, graph, cgraph, tpwgts, ubfactor); + +/* + IsConnectedSubdomain(ctrl, graph, 0); + IsConnectedSubdomain(ctrl, graph, 1); +*/ +} + + + + +/************************************************************************* +* This function takes a graph and a bisection and splits it into two graphs. +**************************************************************************/ +void SplitGraphPart(CtrlType *ctrl, GraphType *graph, GraphType *lgraph, GraphType *rgraph) +{ + int i, j, k, kk, l, istart, iend, mypart, nvtxs, ncon, snvtxs[2], snedges[2], sum; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *adjwgtsum, *label, *where, *bndptr; + idxtype *sxadj[2], *svwgt[2], *sadjncy[2], *sadjwgt[2], *sadjwgtsum[2], *slabel[2]; + idxtype *rename; + idxtype *auxadjncy, *auxadjwgt; + float *nvwgt, *snvwgt[2], *npwgts; + + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SplitTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + vwgt = graph->vwgt; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + label = graph->label; + where = graph->where; + bndptr = graph->bndptr; + npwgts = graph->npwgts; + + ASSERT(bndptr != NULL); + + rename = idxwspacemalloc(ctrl, nvtxs); + + snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0; + for (i=0; ixadj; + svwgt[0] = lgraph->vwgt; + snvwgt[0] = lgraph->nvwgt; + sadjwgtsum[0] = lgraph->adjwgtsum; + sadjncy[0] = lgraph->adjncy; + sadjwgt[0] = lgraph->adjwgt; + slabel[0] = lgraph->label; + + SetUpSplitGraph(graph, rgraph, snvtxs[1], snedges[1]); + sxadj[1] = rgraph->xadj; + svwgt[1] = rgraph->vwgt; + snvwgt[1] = rgraph->nvwgt; + sadjwgtsum[1] = rgraph->adjwgtsum; + sadjncy[1] = rgraph->adjncy; + sadjwgt[1] = rgraph->adjwgt; + slabel[1] = rgraph->label; + + snvtxs[0] = snvtxs[1] = snedges[0] = snedges[1] = 0; + sxadj[0][0] = sxadj[1][0] = 0; + for (i=0; inedges = snedges[0]; + rgraph->nedges = snedges[1]; + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SplitTmr)); + + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* Setup the various arrays for the splitted graph +**************************************************************************/ +void SetUpSplitGraph(GraphType *graph, GraphType *sgraph, int snvtxs, int snedges) +{ + InitGraph(sgraph); + sgraph->nvtxs = snvtxs; + sgraph->nedges = snedges; + sgraph->ncon = graph->ncon; + + /* Allocate memory for the splitted graph */ + if (graph->ncon == 1) { + sgraph->gdata = idxmalloc(4*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata"); + + sgraph->xadj = sgraph->gdata; + sgraph->vwgt = sgraph->gdata + snvtxs+1; + sgraph->adjwgtsum = sgraph->gdata + 2*snvtxs+1; + sgraph->cmap = sgraph->gdata + 3*snvtxs+1; + sgraph->adjncy = sgraph->gdata + 4*snvtxs+1; + sgraph->adjwgt = sgraph->gdata + 4*snvtxs+1 + snedges; + } + else { + sgraph->gdata = idxmalloc(3*snvtxs+1 + 2*snedges, "SetUpSplitGraph: gdata"); + + sgraph->xadj = sgraph->gdata; + sgraph->adjwgtsum = sgraph->gdata + snvtxs+1; + sgraph->cmap = sgraph->gdata + 2*snvtxs+1; + sgraph->adjncy = sgraph->gdata + 3*snvtxs+1; + sgraph->adjwgt = sgraph->gdata + 3*snvtxs+1 + snedges; + + sgraph->nvwgt = fmalloc(graph->ncon*snvtxs, "SetUpSplitGraph: nvwgt"); + } + + sgraph->label = idxmalloc(snvtxs, "SetUpSplitGraph: sgraph->label"); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pqueue.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pqueue.c new file mode 100644 index 0000000..6a1986f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/pqueue.c @@ -0,0 +1,579 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * pqueue.c + * + * This file contains functions for manipulating the bucket list + * representation of the gains associated with each vertex in a graph. + * These functions are used by the refinement algorithms + * + * Started 9/2/94 + * George + * + * $Id: pqueue.c,v 1.1 2003/07/16 15:55:16 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function initializes the data structures of the priority queue +**************************************************************************/ +void PQueueInit(CtrlType *ctrl, PQueueType *queue, int maxnodes, int maxgain) +{ + int i, j, ncore; + + queue->nnodes = 0; + queue->maxnodes = maxnodes; + + queue->buckets = NULL; + queue->nodes = NULL; + queue->heap = NULL; + queue->locator = NULL; + + if (maxgain > PLUS_GAINSPAN || maxnodes < 500) + queue->type = 2; + else + queue->type = 1; + + if (queue->type == 1) { + queue->pgainspan = amin(PLUS_GAINSPAN, maxgain); + queue->ngainspan = amin(NEG_GAINSPAN, maxgain); + + j = queue->ngainspan+queue->pgainspan+1; + + ncore = 2 + (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes + (sizeof(ListNodeType *)/sizeof(idxtype))*j; + + if (WspaceAvail(ctrl) > ncore) { + queue->nodes = (ListNodeType *)idxwspacemalloc(ctrl, (sizeof(ListNodeType)/sizeof(idxtype))*maxnodes); + queue->buckets = (ListNodeType **)idxwspacemalloc(ctrl, (sizeof(ListNodeType *)/sizeof(idxtype))*j); + queue->mustfree = 0; + } + else { /* Not enough memory in the wspace, allocate it */ + queue->nodes = (ListNodeType *)idxmalloc((sizeof(ListNodeType)/sizeof(idxtype))*maxnodes, "PQueueInit: queue->nodes"); + queue->buckets = (ListNodeType **)idxmalloc((sizeof(ListNodeType *)/sizeof(idxtype))*j, "PQueueInit: queue->buckets"); + queue->mustfree = 1; + } + + for (i=0; inodes[i].id = i; + + for (i=0; ibuckets[i] = NULL; + + queue->buckets += queue->ngainspan; /* Advance buckets by the ngainspan proper indexing */ + queue->maxgain = -queue->ngainspan; + } + else { + queue->heap = (KeyValueType *)idxwspacemalloc(ctrl, (sizeof(KeyValueType)/sizeof(idxtype))*maxnodes); + queue->locator = idxwspacemalloc(ctrl, maxnodes); + idxset(maxnodes, -1, queue->locator); + } + +} + + +/************************************************************************* +* This function resets the buckets +**************************************************************************/ +void PQueueReset(PQueueType *queue) +{ + int i, j; + queue->nnodes = 0; + + if (queue->type == 1) { + queue->maxgain = -queue->ngainspan; + + j = queue->ngainspan+queue->pgainspan+1; + queue->buckets -= queue->ngainspan; + for (i=0; ibuckets[i] = NULL; + queue->buckets += queue->ngainspan; + } + else { + idxset(queue->maxnodes, -1, queue->locator); + } + +} + + +/************************************************************************* +* This function frees the buckets +**************************************************************************/ +void PQueueFree(CtrlType *ctrl, PQueueType *queue) +{ + + if (queue->type == 1) { + if (queue->mustfree) { + queue->buckets -= queue->ngainspan; + GKfree(&queue->nodes, &queue->buckets, LTERM); + } + else { + idxwspacefree(ctrl, sizeof(ListNodeType *)*(queue->ngainspan+queue->pgainspan+1)/sizeof(idxtype)); + idxwspacefree(ctrl, sizeof(ListNodeType)*queue->maxnodes/sizeof(idxtype)); + } + } + else { + idxwspacefree(ctrl, sizeof(KeyValueType)*queue->maxnodes/sizeof(idxtype)); + idxwspacefree(ctrl, queue->maxnodes); + } + + queue->maxnodes = 0; +} + + +/************************************************************************* +* This function returns the number of nodes in the queue +**************************************************************************/ +int PQueueGetSize(PQueueType *queue) +{ + return queue->nnodes; +} + + +/************************************************************************* +* This function adds a node of certain gain into a partition +**************************************************************************/ +int PQueueInsert(PQueueType *queue, int node, int gain) +{ + int i, j, k; + idxtype *locator; + ListNodeType *newnode; + KeyValueType *heap; + + if (queue->type == 1) { + ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); + + /* Allocate and add the node */ + queue->nnodes++; + newnode = queue->nodes + node; + + /* Attach this node in the doubly-linked list */ + newnode->next = queue->buckets[gain]; + newnode->prev = NULL; + if (newnode->next != NULL) + newnode->next->prev = newnode; + queue->buckets[gain] = newnode; + + if (queue->maxgain < gain) + queue->maxgain = gain; + } + else { + ASSERT(CheckHeap(queue)); + + heap = queue->heap; + locator = queue->locator; + + ASSERT(locator[node] == -1); + + i = queue->nnodes++; + while (i > 0) { + j = (i-1)/2; + if (heap[j].key < gain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + ASSERT(i >= 0); + heap[i].key = gain; + heap[i].val = node; + locator[node] = i; + + ASSERT(CheckHeap(queue)); + } + + return 0; +} + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +int PQueueDelete(PQueueType *queue, int node, int gain) +{ + int i, j, newgain, oldgain; + idxtype *locator; + ListNodeType *newnode, **buckets; + KeyValueType *heap; + + if (queue->type == 1) { + ASSERT(gain >= -queue->ngainspan && gain <= queue->pgainspan); + ASSERT(queue->nnodes > 0); + + buckets = queue->buckets; + queue->nnodes--; + newnode = queue->nodes+node; + + /* Remove newnode from the doubly-linked list */ + if (newnode->prev != NULL) + newnode->prev->next = newnode->next; + else + buckets[gain] = newnode->next; + if (newnode->next != NULL) + newnode->next->prev = newnode->prev; + + if (buckets[gain] == NULL && gain == queue->maxgain) { + if (queue->nnodes == 0) + queue->maxgain = -queue->ngainspan; + else + for (; buckets[queue->maxgain]==NULL; queue->maxgain--); + } + } + else { /* Heap Priority Queue */ + heap = queue->heap; + locator = queue->locator; + + ASSERT(locator[node] != -1); + ASSERT(heap[locator[node]].val == node); + + ASSERT(CheckHeap(queue)); + + i = locator[node]; + locator[node] = -1; + + if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) { + node = heap[queue->nnodes].val; + newgain = heap[queue->nnodes].key; + oldgain = heap[i].key; + + if (oldgain < newgain) { /* Filter-up */ + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + else { /* Filter down */ + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > newgain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + } + + ASSERT(CheckHeap(queue)); + } + + return 0; +} + + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +int PQueueUpdate(PQueueType *queue, int node, int oldgain, int newgain) +{ + int i, j; + idxtype *locator; + ListNodeType *newnode; + KeyValueType *heap; + + if (oldgain == newgain) + return 0; + + if (queue->type == 1) { + /* First delete the node and then insert it */ + PQueueDelete(queue, node, oldgain); + return PQueueInsert(queue, node, newgain); + } + else { /* Heap Priority Queue */ + heap = queue->heap; + locator = queue->locator; + + ASSERT(locator[node] != -1); + ASSERT(heap[locator[node]].val == node); + ASSERT(heap[locator[node]].key == oldgain); + ASSERT(CheckHeap(queue)); + + i = locator[node]; + + if (oldgain < newgain) { /* Filter-up */ + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + else { /* Filter down */ + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > newgain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + + ASSERT(CheckHeap(queue)); + } + + return 0; +} + + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +void PQueueUpdateUp(PQueueType *queue, int node, int oldgain, int newgain) +{ + int i, j; + idxtype *locator; + ListNodeType *newnode, **buckets; + KeyValueType *heap; + + if (oldgain == newgain) + return; + + if (queue->type == 1) { + ASSERT(oldgain >= -queue->ngainspan && oldgain <= queue->pgainspan); + ASSERT(newgain >= -queue->ngainspan && newgain <= queue->pgainspan); + ASSERT(queue->nnodes > 0); + + buckets = queue->buckets; + newnode = queue->nodes+node; + + /* First delete the node */ + if (newnode->prev != NULL) + newnode->prev->next = newnode->next; + else + buckets[oldgain] = newnode->next; + if (newnode->next != NULL) + newnode->next->prev = newnode->prev; + + /* Attach this node in the doubly-linked list */ + newnode->next = buckets[newgain]; + newnode->prev = NULL; + if (newnode->next != NULL) + newnode->next->prev = newnode; + buckets[newgain] = newnode; + + if (queue->maxgain < newgain) + queue->maxgain = newgain; + } + else { /* Heap Priority Queue */ + heap = queue->heap; + locator = queue->locator; + + ASSERT(locator[node] != -1); + ASSERT(heap[locator[node]].val == node); + ASSERT(heap[locator[node]].key == oldgain); + ASSERT(CheckHeap(queue)); + + + /* Here we are just filtering up since the newgain is greater than the oldgain */ + i = locator[node]; + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + + ASSERT(CheckHeap(queue)); + } + +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +* and removes the node from the bucket list +**************************************************************************/ +int PQueueGetMax(PQueueType *queue) +{ + int vtx, i, j, gain, node; + idxtype *locator; + ListNodeType *tptr; + KeyValueType *heap; + + if (queue->nnodes == 0) + return -1; + + queue->nnodes--; + + if (queue->type == 1) { + tptr = queue->buckets[queue->maxgain]; + queue->buckets[queue->maxgain] = tptr->next; + if (tptr->next != NULL) { + tptr->next->prev = NULL; + } + else { + if (queue->nnodes == 0) { + queue->maxgain = -queue->ngainspan; + } + else + for (; queue->buckets[queue->maxgain]==NULL; queue->maxgain--); + } + + return tptr->id; + } + else { + heap = queue->heap; + locator = queue->locator; + + vtx = heap[0].val; + locator[vtx] = -1; + + if ((i = queue->nnodes) > 0) { + gain = heap[i].key; + node = heap[i].val; + i = 0; + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > gain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > gain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + + heap[i].key = gain; + heap[i].val = node; + locator[node] = i; + } + + ASSERT(CheckHeap(queue)); + return vtx; + } +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +**************************************************************************/ +int PQueueSeeMax(PQueueType *queue) +{ + int vtx; + + if (queue->nnodes == 0) + return -1; + + if (queue->type == 1) + vtx = queue->buckets[queue->maxgain]->id; + else + vtx = queue->heap[0].val; + + return vtx; +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +**************************************************************************/ +int PQueueGetKey(PQueueType *queue) +{ + int key; + + if (queue->nnodes == 0) + return -1; + + if (queue->type == 1) + key = queue->maxgain; + else + key = queue->heap[0].key; + + return key; +} + + + + +/************************************************************************* +* This functions checks the consistency of the heap +**************************************************************************/ +int CheckHeap(PQueueType *queue) +{ + int i, j, nnodes; + idxtype *locator; + KeyValueType *heap; + + heap = queue->heap; + locator = queue->locator; + nnodes = queue->nnodes; + + if (nnodes == 0) + return 1; + + ASSERT(locator[heap[0].val] == 0); + for (i=1; imaxnodes; i++) { + if (locator[i] != -1) + j++; + } + ASSERTP(j == nnodes, ("%d %d\n", j, nnodes)); + + return 1; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/proto.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/proto.h new file mode 100644 index 0000000..3cfadab --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/proto.h @@ -0,0 +1,511 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * proto.h + * + * This file contains header files + * + * Started 10/19/95 + * George + * + * $Id: proto.h,v 1.3 2003/07/24 18:39:11 karypis Exp $ + * + */ + +/* balance.c */ +void Balance2Way(CtrlType *, GraphType *, int *, float); +void Bnd2WayBalance(CtrlType *, GraphType *, int *); +void General2WayBalance(CtrlType *, GraphType *, int *); + +/* bucketsort.c */ +void BucketSortKeysInc(int, int, idxtype *, idxtype *, idxtype *); + +/* ccgraph.c */ +void CreateCoarseGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *); +void CreateCoarseGraphNoMask(CtrlType *, GraphType *, int, idxtype *, idxtype *); +void CreateCoarseGraph_NVW(CtrlType *, GraphType *, int, idxtype *, idxtype *); +GraphType *SetUpCoarseGraph(GraphType *, int, int); +void ReAdjustMemory(GraphType *, GraphType *, int); + +/* checkgraph.c */ +int CheckGraph(GraphType *); + +/* coarsen.c */ +GraphType *Coarsen2Way(CtrlType *, GraphType *); + +/* compress.c */ +void CompressGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, idxtype *); +void PruneGraph(CtrlType *, GraphType *, int, idxtype *, idxtype *, idxtype *, float); + +/* debug.c */ +int ComputeCut(GraphType *, idxtype *); +int CheckBnd(GraphType *); +int CheckBnd2(GraphType *); +int CheckNodeBnd(GraphType *, int); +int CheckRInfo(RInfoType *); +int CheckNodePartitionParams(GraphType *); +int IsSeparable(GraphType *); + +/* estmem.c */ +void METIS_EstimateMemory(int *, idxtype *, idxtype *, int *, int *, int *); +void EstimateCFraction(int, idxtype *, idxtype *, float *, float *); +int ComputeCoarseGraphSize(int, idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *); + +/* fm.c */ +void FM_2WayEdgeRefine(CtrlType *, GraphType *, int *, int); + +/* fortran.c */ +void Change2CNumbering(int, idxtype *, idxtype *); +void Change2FNumbering(int, idxtype *, idxtype *, idxtype *); +void Change2FNumbering2(int, idxtype *, idxtype *); +void Change2FNumberingOrder(int, idxtype *, idxtype *, idxtype *, idxtype *); +void ChangeMesh2CNumbering(int, idxtype *); +void ChangeMesh2FNumbering(int, idxtype *, int, idxtype *, idxtype *); +void ChangeMesh2FNumbering2(int, idxtype *, int, int, idxtype *, idxtype *); + +/* frename.c */ +void METIS_PARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHRECURSIVE(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphrecursive__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_PARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_EDGEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_edgend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NODEND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend_(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodend__(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NODEWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd_(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_nodewnd__(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_PARTMESHNODAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshnodal__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_PARTMESHDUAL(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual_(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void metis_partmeshdual__(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_MESHTONODAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtonodal__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_MESHTODUAL(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual_(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void metis_meshtodual__(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_ESTIMATEMEMORY(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory_(int *, idxtype *, idxtype *, int *, int *, int *); +void metis_estimatememory__(int *, idxtype *, idxtype *, int *, int *, int *); +void METIS_MCPARTGRAPHRECURSIVE(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_mcpartgraphrecursive__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_MCPARTGRAPHKWAY(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway_(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_mcpartgraphkway__(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_PARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void metis_partgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPARTGRAPHVKWAY(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway_(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void metis_wpartgraphvkway__(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); + +/* graph.c */ +void SetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); +void SetUpGraphKway(GraphType *, int, idxtype *, idxtype *); +void SetUpGraph2(GraphType *, int, int, idxtype *, idxtype *, float *, idxtype *); +void VolSetUpGraph(GraphType *, int, int, int, idxtype *, idxtype *, idxtype *, idxtype *, int); +void RandomizeGraph(GraphType *); +int IsConnectedSubdomain(CtrlType *, GraphType *, int, int); +int IsConnected(CtrlType *, GraphType *, int); +int IsConnected2(GraphType *, int); +int FindComponents(CtrlType *, GraphType *, idxtype *, idxtype *); + +/* initpart.c */ +void Init2WayPartition(CtrlType *, GraphType *, int *, float); +void InitSeparator(CtrlType *, GraphType *, float); +void GrowBisection(CtrlType *, GraphType *, int *, float); +void GrowBisectionNode(CtrlType *, GraphType *, float); +void RandomBisection(CtrlType *, GraphType *, int *, float); + +/* kmetis.c */ +void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); + +/* kvmetis.c */ +void METIS_PartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphVKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelVolKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *, float); + +/* kwayfm.c */ +void Random_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayEdgeRefine(CtrlType *, GraphType *, int, float *, float, int); +void Greedy_KWayEdgeBalance(CtrlType *, GraphType *, int, float *, float, int); + +/* kwayrefine.c */ +void RefineKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); +void AllocateKWayPartitionMemory(CtrlType *, GraphType *, int); +void ComputeKWayPartitionParams(CtrlType *, GraphType *, int); +void ProjectKWayPartition(CtrlType *, GraphType *, int); +int IsBalanced(idxtype *, int, float *, float); +void ComputeKWayBoundary(CtrlType *, GraphType *, int); +void ComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* kwayvolfm.c */ +void Random_KWayVolRefine(CtrlType *, GraphType *, int, float *, float, int, int); +void Random_KWayVolRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayVolBalance(CtrlType *, GraphType *, int, float *, float, int); +void Greedy_KWayVolBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); +void KWayVolUpdate(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *, idxtype *); +void ComputeKWayVolume(GraphType *, int, idxtype *, idxtype *, idxtype *); +int ComputeVolume(GraphType *, idxtype *); +void CheckVolKWayPartitionParams(CtrlType *, GraphType *, int); +void ComputeVolSubDomainGraph(GraphType *, int, idxtype *, idxtype *); +void EliminateVolSubDomainEdges(CtrlType *, GraphType *, int, float *); +void EliminateVolComponents(CtrlType *, GraphType *, int, float *, float); + +/* kwayvolrefine.c */ +void RefineVolKWay(CtrlType *, GraphType *, GraphType *, int, float *, float); +void AllocateVolKWayPartitionMemory(CtrlType *, GraphType *, int); +void ComputeVolKWayPartitionParams(CtrlType *, GraphType *, int); +void ComputeKWayVolGains(CtrlType *, GraphType *, int); +void ProjectVolKWayPartition(CtrlType *, GraphType *, int); +void ComputeVolKWayBoundary(CtrlType *, GraphType *, int); +void ComputeVolKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* match.c */ +void Match_RM(CtrlType *, GraphType *); +void Match_RM_NVW(CtrlType *, GraphType *); +void Match_HEM(CtrlType *, GraphType *); +void Match_SHEM(CtrlType *, GraphType *); + +/* mbalance.c */ +void MocBalance2Way(CtrlType *, GraphType *, float *, float); +void MocGeneral2WayBalance(CtrlType *, GraphType *, float *, float); + +/* mbalance2.c */ +void MocBalance2Way2(CtrlType *, GraphType *, float *, float *); +void MocGeneral2WayBalance2(CtrlType *, GraphType *, float *, float *); +void SelectQueue3(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); + +/* mcoarsen.c */ +GraphType *MCCoarsen2Way(CtrlType *, GraphType *); + +/* memory.c */ +void AllocateWorkSpace(CtrlType *, GraphType *, int); +void FreeWorkSpace(CtrlType *, GraphType *); +int WspaceAvail(CtrlType *); +idxtype *idxwspacemalloc(CtrlType *, int); +void idxwspacefree(CtrlType *, int); +float *fwspacemalloc(CtrlType *, int); +void fwspacefree(CtrlType *, int); +GraphType *CreateGraph(void); +void InitGraph(GraphType *); +void FreeGraph(GraphType *); + +/* mesh.c */ +void METIS_MeshToDual(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_MeshToNodal(int *, int *, idxtype *, int *, int *, idxtype *, idxtype *); +void GENDUALMETIS(int, int, int, idxtype *, idxtype *, idxtype *adjncy); +void TRINODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void TETNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void HEXNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); +void QUADNODALMETIS(int, int, idxtype *, idxtype *, idxtype *adjncy); + +/* meshpart.c */ +void METIS_PartMeshNodal(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); +void METIS_PartMeshDual(int *, int *, idxtype *, int *, int *, int *, int *, idxtype *, idxtype *); + +/* mfm.c */ +void MocFM_2WayEdgeRefine(CtrlType *, GraphType *, float *, int); +void SelectQueue(int, float *, float *, int *, int *, PQueueType [MAXNCON][2]); +int BetterBalance(int, float *, float *, float *); +float Compute2WayHLoadImbalance(int, float *, float *); +void Compute2WayHLoadImbalanceVec(int, float *, float *, float *); + +/* mfm2.c */ +void MocFM_2WayEdgeRefine2(CtrlType *, GraphType *, float *, float *, int); +void SelectQueue2(int, float *, float *, int *, int *, PQueueType [MAXNCON][2], float *); +int IsBetter2wayBalance(int, float *, float *, float *); + +/* mincover.o */ +void MinCover(idxtype *, idxtype *, int, int, idxtype *, int *); +int MinCover_Augment(idxtype *, idxtype *, int, idxtype *, idxtype *, idxtype *, int); +void MinCover_Decompose(idxtype *, idxtype *, int, int, idxtype *, idxtype *, int *); +void MinCover_ColDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); +void MinCover_RowDFS(idxtype *, idxtype *, int, idxtype *, idxtype *, int); + +/* minitpart.c */ +void MocInit2WayPartition(CtrlType *, GraphType *, float *, float); +void MocGrowBisection(CtrlType *, GraphType *, float *, float); +void MocRandomBisection(CtrlType *, GraphType *, float *, float); +void MocInit2WayBalance(CtrlType *, GraphType *, float *); +int SelectQueueoneWay(int, float *, float *, int, PQueueType [MAXNCON][2]); + +/* minitpart2.c */ +void MocInit2WayPartition2(CtrlType *, GraphType *, float *, float *); +void MocGrowBisection2(CtrlType *, GraphType *, float *, float *); +void MocGrowBisectionNew2(CtrlType *, GraphType *, float *, float *); +void MocInit2WayBalance2(CtrlType *, GraphType *, float *, float *); +int SelectQueueOneWay2(int, float *, PQueueType [MAXNCON][2], float *); + +/* mkmetis.c */ +void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MCMlevelKWayPartitioning(CtrlType *, GraphType *, int, idxtype *, float *); + +/* mkwayfmh.c */ +void MCRandom_KWayEdgeRefineHorizontal(CtrlType *, GraphType *, int, float *, int); +void MCGreedy_KWayEdgeBalanceHorizontal(CtrlType *, GraphType *, int, float *, int); +int AreAllHVwgtsBelow(int, float, float *, float, float *, float *); +int AreAllHVwgtsAbove(int, float, float *, float, float *, float *); +void ComputeHKWayLoadImbalance(int, int, float *, float *); +int MocIsHBalanced(int, int, float *, float *); +int IsHBalanceBetterFT(int, int, float *, float *, float *, float *); +int IsHBalanceBetterTT(int, int, float *, float *, float *, float *); + +/* mkwayrefine.c */ +void MocRefineKWayHorizontal(CtrlType *, GraphType *, GraphType *, int, float *); +void MocAllocateKWayPartitionMemory(CtrlType *, GraphType *, int); +void MocComputeKWayPartitionParams(CtrlType *, GraphType *, int); +void MocProjectKWayPartition(CtrlType *, GraphType *, int); +void MocComputeKWayBalanceBoundary(CtrlType *, GraphType *, int); + +/* mmatch.c */ +void MCMatch_RM(CtrlType *, GraphType *); +void MCMatch_HEM(CtrlType *, GraphType *); +void MCMatch_SHEM(CtrlType *, GraphType *); +void MCMatch_SHEBM(CtrlType *, GraphType *, int); +void MCMatch_SBHEM(CtrlType *, GraphType *, int); +float BetterVBalance(int, int, float *, float *, float *); +int AreAllVwgtsBelowFast(int, float *, float *, float); + +/* mmd.c */ +void genmmd(int, idxtype *, idxtype *, idxtype *, idxtype *, int , idxtype *, idxtype *, idxtype *, idxtype *, int, int *); +void mmdelm(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int); +int mmdint(int, idxtype *xadj, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *); +void mmdnum(int, idxtype *, idxtype *, idxtype *); +void mmdupd(int, int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int *tag); + +/* mpmetis.c */ +void METIS_mCPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_mCHPartGraphRecursive(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_mCPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, int *, int *, idxtype *); +void METIS_mCHPartGraphRecursiveInternal(int *, int *, idxtype *, idxtype *, float *, idxtype *, int *, float *, int *, int *, idxtype *); +int MCMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float, int); +int MCHMlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, int); +void MCMlevelEdgeBisection(CtrlType *, GraphType *, float *, float); +void MCHMlevelEdgeBisection(CtrlType *, GraphType *, float *, float *); + +/* mrefine.c */ +void MocRefine2Way(CtrlType *, GraphType *, GraphType *, float *, float); +void MocAllocate2WayPartitionMemory(CtrlType *, GraphType *); +void MocCompute2WayPartitionParams(CtrlType *, GraphType *); +void MocProject2WayPartition(CtrlType *, GraphType *); + +/* mrefine2.c */ +void MocRefine2Way2(CtrlType *, GraphType *, GraphType *, float *, float *); + +/* mutil.c */ +int AreAllVwgtsBelow(int, float, float *, float, float *, float); +int AreAnyVwgtsBelow(int, float, float *, float, float *, float); +int AreAllVwgtsAbove(int, float, float *, float, float *, float); +float ComputeLoadImbalance(int, int, float *, float *); +int AreAllBelow(int, float *, float *); + +/* myqsort.c */ +void iidxsort(int, idxtype *); +void iintsort(int, int *); +void ikeysort(int, KeyValueType *); +void ikeyvalsort(int, KeyValueType *); + +/* ometis.c */ +void METIS_EdgeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeWND(int *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void MlevelNestedDissection(CtrlType *, GraphType *, idxtype *, float, int); +void MlevelNestedDissectionCC(CtrlType *, GraphType *, idxtype *, float, int); +void MlevelNodeBisectionMultiple(CtrlType *, GraphType *, int *, float); +void MlevelNodeBisection(CtrlType *, GraphType *, int *, float); +void SplitGraphOrder(CtrlType *, GraphType *, GraphType *, GraphType *); +void MMDOrder(CtrlType *, GraphType *, idxtype *, int); +int SplitGraphOrderCC(CtrlType *, GraphType *, GraphType *, int, idxtype *, idxtype *); + +/* parmetis.c */ +void METIS_PartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *); +void MlevelNestedDissectionP(CtrlType *, GraphType *, idxtype *, int, int, int, idxtype *); +void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_mCPartGraphRecursive2(int *nvtxs, int *ncon, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, float *tpwgts, int *options, int *edgecut, idxtype *part); +int MCMlevelRecursiveBisection2(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, idxtype *part, float ubfactor, int fpart); + + + +/* pmetis.c */ +void METIS_PartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_WPartGraphRecursive(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MlevelRecursiveBisection(CtrlType *, GraphType *, int, idxtype *, float *, float, int); +void MlevelEdgeBisection(CtrlType *, GraphType *, int *, float); +void SplitGraphPart(CtrlType *, GraphType *, GraphType *, GraphType *); +void SetUpSplitGraph(GraphType *, GraphType *, int, int); + +/* pqueue.c */ +void PQueueInit(CtrlType *ctrl, PQueueType *, int, int); +void PQueueReset(PQueueType *); +void PQueueFree(CtrlType *ctrl, PQueueType *); +int PQueueGetSize(PQueueType *); +int PQueueInsert(PQueueType *, int, int); +int PQueueDelete(PQueueType *, int, int); +int PQueueUpdate(PQueueType *, int, int, int); +void PQueueUpdateUp(PQueueType *, int, int, int); +int PQueueGetMax(PQueueType *); +int PQueueSeeMax(PQueueType *); +int PQueueGetKey(PQueueType *); +int CheckHeap(PQueueType *); + +/* refine.c */ +void Refine2Way(CtrlType *, GraphType *, GraphType *, int *, float ubfactor); +void Allocate2WayPartitionMemory(CtrlType *, GraphType *); +void Compute2WayPartitionParams(CtrlType *, GraphType *); +void Project2WayPartition(CtrlType *, GraphType *); + +/* separator.c */ +void ConstructSeparator(CtrlType *, GraphType *, float); +void ConstructMinCoverSeparator0(CtrlType *, GraphType *, float); +void ConstructMinCoverSeparator(CtrlType *, GraphType *, float); + +/* sfm.c */ +void FM_2WayNodeRefine(CtrlType *, GraphType *, float, int); +void FM_2WayNodeRefineEqWgt(CtrlType *, GraphType *, int); +void FM_2WayNodeRefine_OneSided(CtrlType *, GraphType *, float, int); +void FM_2WayNodeBalance(CtrlType *, GraphType *, float); +int ComputeMaxNodeGain(int, idxtype *, idxtype *, idxtype *); + +/* srefine.c */ +void Refine2WayNode(CtrlType *, GraphType *, GraphType *, float); +void Allocate2WayNodePartitionMemory(CtrlType *, GraphType *); +void Compute2WayNodePartitionParams(CtrlType *, GraphType *); +void Project2WayNodePartition(CtrlType *, GraphType *); + +/* stat.c */ +void ComputePartitionInfo(GraphType *, int, idxtype *); +void ComputePartitionInfoBipartite(GraphType *, int, idxtype *); +void ComputePartitionBalance(GraphType *, int, idxtype *, float *); +float ComputeElementBalance(int, int, idxtype *); +void Moc_ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec); + +/* subdomains.c */ +void Random_KWayEdgeRefineMConn(CtrlType *, GraphType *, int, float *, float, int, int); +void Greedy_KWayEdgeBalanceMConn(CtrlType *, GraphType *, int, float *, float, int); +void PrintSubDomainGraph(GraphType *, int, idxtype *); +void ComputeSubDomainGraph(GraphType *, int, idxtype *, idxtype *); +void EliminateSubDomainEdges(CtrlType *, GraphType *, int, float *); +void MoveGroupMConn(CtrlType *, GraphType *, idxtype *, idxtype *, int, int, int, idxtype *); +void EliminateComponents(CtrlType *, GraphType *, int, float *, float); +void MoveGroup(CtrlType *, GraphType *, int, int, int, idxtype *, idxtype *); + +/* timing.c */ +void InitTimers(CtrlType *); +void PrintTimers(CtrlType *); +double seconds(void); + +/* util.c */ +void errexit(char *,...); +#ifndef DMALLOC +int *imalloc(int, char *); +idxtype *idxmalloc(int, char *); +float *fmalloc(int, char *); +int *ismalloc(int, int, char *); +idxtype *idxsmalloc(int, idxtype, char *); +void *GKmalloc(int, char *); +#endif +/*void GKfree(void **,...); */ +int *iset(int n, int val, int *x); +idxtype *idxset(int n, idxtype val, idxtype *x); +float *sset(int n, float val, float *x); +int iamax(int, int *); +int idxamax(int, idxtype *); +int idxamax_strd(int, idxtype *, int); +int samax(int, float *); +int samax2(int, float *); +int idxamin(int, idxtype *); +int samin(int, float *); +int idxsum(int, idxtype *); +int idxsum_strd(int, idxtype *, int); +void idxadd(int, idxtype *, idxtype *); +int charsum(int, char *); +int isum(int, int *); +float ssum(int, float *); +float ssum_strd(int n, float *x, int); +void sscale(int n, float, float *x); +float snorm2(int, float *); +float sdot(int n, float *, float *); +void saxpy(int, float, float *, int, float *, int); +void RandomPermute(int, idxtype *, int); +int ispow2(int); +void InitRandom(int); +int log2Int(int); + + + + + + + + + + +/*************************************************************** +* Programs Directory +****************************************************************/ + +/* io.c */ +void ReadGraph(GraphType *, char *, int *); +void WritePartition(char *, idxtype *, int, int); +void WriteMeshPartition(char *, int, int, idxtype *, int, idxtype *); +void WritePermutation(char *, idxtype *, int); +int CheckGraph(GraphType *); +idxtype *ReadMesh(char *, int *, int *, int *); +void WriteGraph(char *, int, idxtype *, idxtype *); + +/* smbfactor.c */ +void ComputeFillIn(GraphType *, idxtype *); +idxtype ComputeFillIn2(GraphType *, idxtype *); +int smbfct(int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *, idxtype *, idxtype *, int *); + + +/*************************************************************** +* Test Directory +****************************************************************/ +void Test_PartGraph(int, idxtype *, idxtype *); +int VerifyPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); +int VerifyWPart(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_PartGraphV(int, idxtype *, idxtype *); +int VerifyPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, int, idxtype *); +int VerifyWPartV(int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_PartGraphmC(int, idxtype *, idxtype *); +int VerifyPartmC(int, int, idxtype *, idxtype *, idxtype *, idxtype *, int, float *, int, idxtype *); +void Test_ND(int, idxtype *, idxtype *); +int VerifyND(int, idxtype *, idxtype *); + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/refine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/refine.c new file mode 100644 index 0000000..f479298 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/refine.c @@ -0,0 +1,204 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * refine.c + * + * This file contains the driving routines for multilevel refinement + * + * Started 7/24/97 + * George + * + * $Id: refine.c,v 1.1 2003/07/16 15:55:17 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of refinement +**************************************************************************/ +void Refine2Way(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, int *tpwgts, float ubfactor) +{ + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + /* Compute the parameters of the coarsest graph */ + Compute2WayPartitionParams(ctrl, graph); + + for (;;) { + ASSERT(CheckBnd(graph)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + switch (ctrl->RType) { + case 1: + Balance2Way(ctrl, graph, tpwgts, ubfactor); + FM_2WayEdgeRefine(ctrl, graph, tpwgts, 8); + break; + default: + errexit("Unknown refinement type: %d\n", ctrl->RType); + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + Project2WayPartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for 2-way edge refinement +**************************************************************************/ +void Allocate2WayPartitionMemory(CtrlType *ctrl, GraphType *graph) +{ + int nvtxs; + + nvtxs = graph->nvtxs; + + graph->rdata = idxmalloc(5*nvtxs+2, "Allocate2WayPartitionMemory: rdata"); + graph->pwgts = graph->rdata; + graph->where = graph->rdata + 2; + graph->id = graph->rdata + nvtxs + 2; + graph->ed = graph->rdata + 2*nvtxs + 2; + graph->bndptr = graph->rdata + 3*nvtxs + 2; + graph->bndind = graph->rdata + 4*nvtxs + 2; +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Compute2WayPartitionParams(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, l, nvtxs, nbnd, mincut; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *pwgts; + idxtype *id, *ed, *where; + idxtype *bndptr, *bndind; + int me, other; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = idxset(2, 0, graph->pwgts); + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nbnd = mincut = 0; + for (i=0; i= 0 && where[i] <= 1); + me = where[i]; + pwgts[me] += vwgt[i]; + + for (j=xadj[i]; j 0 || xadj[i] == xadj[i+1]) { + mincut += ed[i]; + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + + graph->mincut = mincut/2; + graph->nbnd = nbnd; + + ASSERT(pwgts[0]+pwgts[1] == idxsum(nvtxs, vwgt)); +} + + + +/************************************************************************* +* This function projects a partition, and at the same time computes the +* parameters for refinement. +**************************************************************************/ +void Project2WayPartition(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, nvtxs, nbnd, me; + idxtype *xadj, *adjncy, *adjwgt, *adjwgtsum; + idxtype *cmap, *where, *id, *ed, *bndptr, *bndind; + idxtype *cwhere, *cid, *ced, *cbndptr; + GraphType *cgraph; + + cgraph = graph->coarser; + cwhere = cgraph->where; + cid = cgraph->id; + ced = cgraph->ed; + cbndptr = cgraph->bndptr; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + adjwgtsum = graph->adjwgtsum; + + Allocate2WayPartitionMemory(ctrl, graph); + + where = graph->where; + id = idxset(nvtxs, 0, graph->id); + ed = idxset(nvtxs, 0, graph->ed); + bndptr = idxset(nvtxs, -1, graph->bndptr); + bndind = graph->bndind; + + + /* Go through and project partition and compute id/ed for the nodes */ + for (i=0; i 0 || xadj[i] == xadj[i+1]) { + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + } + } + + graph->mincut = cgraph->mincut; + graph->nbnd = nbnd; + idxcopy(2, cgraph->pwgts, graph->pwgts); + + FreeGraph(graph->coarser); + graph->coarser = NULL; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/rename.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/rename.h new file mode 100644 index 0000000..ca07dfe --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/rename.h @@ -0,0 +1,424 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * rename.h + * + * This file contains header files + * + * Started 10/2/97 + * George + * + * $Id: rename.h,v 1.2 2003/07/24 18:39:12 karypis Exp $ + * + */ + +/* balance.c */ +#define Balance2Way __Balance2Way +#define Bnd2WayBalance __Bnd2WayBalance +#define General2WayBalance __General2WayBalance + + +/* bucketsort.c */ +#define BucketSortKeysInc __BucketSortKeysInc + + +/* ccgraph.c */ +#define CreateCoarseGraph __CreateCoarseGraph +#define CreateCoarseGraphNoMask __CreateCoarseGraphNoMask +#define CreateCoarseGraph_NVW __CreateCoarseGraph_NVW +#define SetUpCoarseGraph __SetUpCoarseGraph +#define ReAdjustMemory __ReAdjustMemory + + +/* checkgraph.c */ +#define CheckGraph __CheckGraph + + +/* coarsen.c */ +#define Coarsen2Way __Coarsen2Way + + +/* compress.c */ +#define CompressGraph __CompressGraph +#define PruneGraph __PruneGraph + + +/* debug.c */ +#define ComputeCut __ComputeCut +#define CheckBnd __CheckBnd +#define CheckBnd2 __CheckBnd2 +#define CheckNodeBnd __CheckNodeBnd +#define CheckRInfo __CheckRInfo +#define CheckNodePartitionParams __CheckNodePartitionParams +#define IsSeparable __IsSeparable + + +/* estmem.c */ +#define EstimateCFraction __EstimateCFraction +#define ComputeCoarseGraphSize __ComputeCoarseGraphSize + + +/* fm.c */ +#define FM_2WayEdgeRefine __FM_2WayEdgeRefine + + +/* fortran.c */ +#define Change2CNumbering __Change2CNumbering +#define Change2FNumbering __Change2FNumbering +#define Change2FNumbering2 __Change2FNumbering2 +#define Change2FNumberingOrder __Change2FNumberingOrder +#define ChangeMesh2CNumbering __ChangeMesh2CNumbering +#define ChangeMesh2FNumbering __ChangeMesh2FNumbering +#define ChangeMesh2FNumbering2 __ChangeMesh2FNumbering2 + + +/* graph.c */ +#define SetUpGraph __SetUpGraph +#define SetUpGraphKway __SetUpGraphKway +#define SetUpGraph2 __SetUpGraph2 +#define VolSetUpGraph __VolSetUpGraph +#define RandomizeGraph __RandomizeGraph +#define IsConnectedSubdomain __IsConnectedSubdomain +#define IsConnected __IsConnected +#define IsConnected2 __IsConnected2 +#define FindComponents __FindComponents + + +/* initpart.c */ +#define Init2WayPartition __Init2WayPartition +#define InitSeparator __InitSeparator +#define GrowBisection __GrowBisection +#define GrowBisectionNode __GrowBisectionNode +#define RandomBisection __RandomBisection + + +/* kmetis.c */ +#define MlevelKWayPartitioning __MlevelKWayPartitioning + + +/* kvmetis.c */ +#define MlevelVolKWayPartitioning __MlevelVolKWayPartitioning + + +/* kwayfm.c */ +#define Random_KWayEdgeRefine __Random_KWayEdgeRefine +#define Greedy_KWayEdgeRefine __Greedy_KWayEdgeRefine +#define Greedy_KWayEdgeBalance __Greedy_KWayEdgeBalance + + +/* kwayrefine.c */ +#define RefineKWay __RefineKWay +#define AllocateKWayPartitionMemory __AllocateKWayPartitionMemory +#define ComputeKWayPartitionParams __ComputeKWayPartitionParams +#define ProjectKWayPartition __ProjectKWayPartition +#define IsBalanced __IsBalanced +#define ComputeKWayBoundary __ComputeKWayBoundary +#define ComputeKWayBalanceBoundary __ComputeKWayBalanceBoundary + + +/* kwayvolfm.c */ +#define Random_KWayVolRefine __Random_KWayVolRefine +#define Random_KWayVolRefineMConn __Random_KWayVolRefineMConn +#define Greedy_KWayVolBalance __Greedy_KWayVolBalance +#define Greedy_KWayVolBalanceMConn __Greedy_KWayVolBalanceMConn +#define KWayVolUpdate __KWayVolUpdate +#define ComputeKWayVolume __ComputeKWayVolume +#define ComputeVolume __ComputeVolume +#define CheckVolKWayPartitionParams __CheckVolKWayPartitionParams +#define ComputeVolSubDomainGraph __ComputeVolSubDomainGraph +#define EliminateVolSubDomainEdges __EliminateVolSubDomainEdges + + +/* kwayvolrefine.c */ +#define RefineVolKWay __RefineVolKWay +#define AllocateVolKWayPartitionMemory __AllocateVolKWayPartitionMemory +#define ComputeVolKWayPartitionParams __ComputeVolKWayPartitionParams +#define ComputeKWayVolGains __ComputeKWayVolGains +#define ProjectVolKWayPartition __ProjectVolKWayPartition +#define ComputeVolKWayBoundary __ComputeVolKWayBoundary +#define ComputeVolKWayBalanceBoundary __ComputeVolKWayBalanceBoundary + + +/* match.c */ +#define Match_RM __Match_RM +#define Match_RM_NVW __Match_RM_NVW +#define Match_HEM __Match_HEM +#define Match_SHEM __Match_SHEM + + +/* mbalance.c */ +#define MocBalance2Way __MocBalance2Way +#define MocGeneral2WayBalance __MocGeneral2WayBalance + + +/* mbalance2.c */ +#define MocBalance2Way2 __MocBalance2Way2 +#define MocGeneral2WayBalance2 __MocGeneral2WayBalance2 +#define SelectQueue3 __SelectQueue3 + + +/* mcoarsen.c */ +#define MCCoarsen2Way __MCCoarsen2Way + + +/* memory.c */ +#define AllocateWorkSpace __AllocateWorkSpace +#define FreeWorkSpace __FreeWorkSpace +#define WspaceAvail __WspaceAvail +#define idxwspacemalloc __idxwspacemalloc +#define idxwspacefree __idxwspacefree +#define fwspacemalloc __fwspacemalloc +#define CreateGraph __CreateGraph +#define InitGraph __InitGraph +#define FreeGraph __FreeGraph + + +/* mesh.c */ +#define TRIDUALMETIS __TRIDUALMETIS +#define TETDUALMETIS __TETDUALMETIS +#define HEXDUALMETIS __HEXDUALMETIS +#define TRINODALMETIS __TRINODALMETIS +#define TETNODALMETIS __TETNODALMETIS +#define HEXNODALMETIS __HEXNODALMETIS + + +/* mfm.c */ +#define MocFM_2WayEdgeRefine __MocFM_2WayEdgeRefine +#define SelectQueue __SelectQueue +#define BetterBalance __BetterBalance +#define Compute2WayHLoadImbalance __Compute2WayHLoadImbalance +#define Compute2WayHLoadImbalanceVec __Compute2WayHLoadImbalanceVec + + +/* mfm2.c */ +#define MocFM_2WayEdgeRefine2 __MocFM_2WayEdgeRefine2 +#define SelectQueue2 __SelectQueue2 +#define IsBetter2wayBalance __IsBetter2wayBalance + + +/* mincover.c */ +#define MinCover __MinCover +#define MinCover_Augment __MinCover_Augment +#define MinCover_Decompose __MinCover_Decompose +#define MinCover_ColDFS __MinCover_ColDFS +#define MinCover_RowDFS __MinCover_RowDFS + + +/* minitpart.c */ +#define MocInit2WayPartition __MocInit2WayPartition +#define MocGrowBisection __MocGrowBisection +#define MocRandomBisection __MocRandomBisection +#define MocInit2WayBalance __MocInit2WayBalance +#define SelectQueueoneWay __SelectQueueoneWay + + +/* minitpart2.c */ +#define MocInit2WayPartition2 __MocInit2WayPartition2 +#define MocGrowBisection2 __MocGrowBisection2 +#define MocGrowBisectionNew2 __MocGrowBisectionNew2 +#define MocInit2WayBalance2 __MocInit2WayBalance2 +#define SelectQueueOneWay2 __SelectQueueOneWay2 + + +/* mkmetis.c */ +#define MCMlevelKWayPartitioning __MCMlevelKWayPartitioning + + +/* mkwayfmh.c */ +#define MCRandom_KWayEdgeRefineHorizontal __MCRandom_KWayEdgeRefineHorizontal +#define MCGreedy_KWayEdgeBalanceHorizontal __MCGreedy_KWayEdgeBalanceHorizontal +#define AreAllHVwgtsBelow __AreAllHVwgtsBelow +#define AreAllHVwgtsAbove __AreAllHVwgtsAbove +#define ComputeHKWayLoadImbalance __ComputeHKWayLoadImbalance +#define MocIsHBalanced __MocIsHBalanced +#define IsHBalanceBetterFT __IsHBalanceBetterFT +#define IsHBalanceBetterTT __IsHBalanceBetterTT + + +/* mkwayrefine.c */ +#define MocRefineKWayHorizontal __MocRefineKWayHorizontal +#define MocAllocateKWayPartitionMemory __MocAllocateKWayPartitionMemory +#define MocComputeKWayPartitionParams __MocComputeKWayPartitionParams +#define MocProjectKWayPartition __MocProjectKWayPartition +#define MocComputeKWayBalanceBoundary __MocComputeKWayBalanceBoundary + + +/* mmatch.c */ +#define MCMatch_RM __MCMatch_RM +#define MCMatch_HEM __MCMatch_HEM +#define MCMatch_SHEM __MCMatch_SHEM +#define MCMatch_SHEBM __MCMatch_SHEBM +#define MCMatch_SBHEM __MCMatch_SBHEM +#define BetterVBalance __BetterVBalance +#define AreAllVwgtsBelowFast __AreAllVwgtsBelowFast + + +/* mmd.c */ +#define genmmd __genmmd +#define mmdelm __mmdelm +#define mmdint __mmdint +#define mmdnum __mmdnum +#define mmdupd __mmdupd + + +/* mpmetis.c */ +#define MCMlevelRecursiveBisection __MCMlevelRecursiveBisection +#define MCHMlevelRecursiveBisection __MCHMlevelRecursiveBisection +#define MCMlevelEdgeBisection __MCMlevelEdgeBisection +#define MCHMlevelEdgeBisection __MCHMlevelEdgeBisection + + +/* mrefine.c */ +#define MocRefine2Way __MocRefine2Way +#define MocAllocate2WayPartitionMemory __MocAllocate2WayPartitionMemory +#define MocCompute2WayPartitionParams __MocCompute2WayPartitionParams +#define MocProject2WayPartition __MocProject2WayPartition + + +/* mrefine2.c */ +#define MocRefine2Way2 __MocRefine2Way2 + + +/* mutil.c */ +#define AreAllVwgtsBelow __AreAllVwgtsBelow +#define AreAnyVwgtsBelow __AreAnyVwgtsBelow +#define AreAllVwgtsAbove __AreAllVwgtsAbove +#define ComputeLoadImbalance __ComputeLoadImbalance +#define AreAllBelow __AreAllBelow + + +/* myqsort.c */ +#define iidxsort __iidxsort +#define iintsort __iintsort +#define ikeysort __ikeysort +#define ikeyvalsort __ikeyvalsort + + +/* ometis.c */ +#define MlevelNestedDissection __MlevelNestedDissection +#define MlevelNestedDissectionCC __MlevelNestedDissectionCC +#define MlevelNodeBisectionMultiple __MlevelNodeBisectionMultiple +#define MlevelNodeBisection __MlevelNodeBisection +#define SplitGraphOrder __SplitGraphOrder +#define MMDOrder __MMDOrder +#define SplitGraphOrderCC __SplitGraphOrderCC + + +/* parmetis.c */ +#define MlevelNestedDissectionP __MlevelNestedDissectionP +#define MCMlevelRecursiveBisection2 __MCMlevelRecursiveBisection2 + + +/* pmetis.c */ +#define MlevelRecursiveBisection __MlevelRecursiveBisection +#define MlevelEdgeBisection __MlevelEdgeBisection +#define SplitGraphPart __SplitGraphPart +#define SetUpSplitGraph __SetUpSplitGraph + + +/* pqueue.c */ +#define PQueueInit __PQueueInit +#define PQueueReset __PQueueReset +#define PQueueFree __PQueueFree +#define PQueueInsert __PQueueInsert +#define PQueueDelete __PQueueDelete +#define PQueueUpdate __PQueueUpdate +#define PQueueUpdateUp __PQueueUpdateUp +#define PQueueGetMax __PQueueGetMax +#define PQueueSeeMax __PQueueSeeMax +#define CheckHeap __CheckHeap + + +/* refine.c */ +#define Refine2Way __Refine2Way +#define Allocate2WayPartitionMemory __Allocate2WayPartitionMemory +#define Compute2WayPartitionParams __Compute2WayPartitionParams +#define Project2WayPartition __Project2WayPartition + + +/* separator.c */ +#define ConstructSeparator __ConstructSeparator +#define ConstructMinCoverSeparator0 __ConstructMinCoverSeparator0 +#define ConstructMinCoverSeparator __ConstructMinCoverSeparator + + +/* sfm.c */ +#define FM_2WayNodeRefine __FM_2WayNodeRefine +#define FM_2WayNodeRefineEqWgt __FM_2WayNodeRefineEqWgt +#define FM_2WayNodeRefine_OneSided __FM_2WayNodeRefine_OneSided +#define FM_2WayNodeBalance __FM_2WayNodeBalance +#define ComputeMaxNodeGain __ComputeMaxNodeGain + + +/* srefine.c */ +#define Refine2WayNode __Refine2WayNode +#define Allocate2WayNodePartitionMemory __Allocate2WayNodePartitionMemory +#define Compute2WayNodePartitionParams __Compute2WayNodePartitionParams +#define Project2WayNodePartition __Project2WayNodePartition + + +/* stat.c */ +#define ComputePartitionInfo __ComputePartitionInfo +#define ComputePartitionBalance __ComputePartitionBalance +#define ComputeElementBalance __ComputeElementBalance +#define Moc_ComputePartitionBalance __Moc_ComputePartitionBalance + + +/* subdomains.c */ +#define Random_KWayEdgeRefineMConn __Random_KWayEdgeRefineMConn +#define Greedy_KWayEdgeBalanceMConn __Greedy_KWayEdgeBalanceMConn +#define PrintSubDomainGraph __PrintSubDomainGraph +#define ComputeSubDomainGraph __ComputeSubDomainGraph +#define EliminateSubDomainEdges __EliminateSubDomainEdges +#define MoveGroupMConn __MoveGroupMConn +#define EliminateComponents __EliminateComponents +#define MoveGroup __MoveGroup + + +/* timing.c */ +#define InitTimers __InitTimers +#define PrintTimers __PrintTimers +#define seconds __seconds + + +/* util.c */ +#define errexit __errexit +#define GKfree __GKfree +#ifndef DMALLOC +#define imalloc __imalloc +#define idxmalloc __idxmalloc +#define fmalloc __fmalloc +#define ismalloc __ismalloc +#define idxsmalloc __idxsmalloc +#define GKmalloc __GKmalloc +#endif +#define iset __iset +#define idxset __idxset +#define sset __sset +#define iamax __iamax +#define idxamax __idxamax +#define idxamax_strd __idxamax_strd +#define samax __samax +#define samax2 __samax2 +#define idxamin __idxamin +#define samin __samin +#define idxsum __idxsum +#define idxsum_strd __idxsum_strd +#define idxadd __idxadd +#define charsum __charsum +#define isum __isum +#define ssum __ssum +#define ssum_strd __ssum_strd +#define sscale __sscale +#define snorm2 __snorm2 +#define sdot __sdot +#define saxpy __saxpy +#define RandomPermute __RandomPermute +#define ispow2 __ispow2 +#define InitRandom __InitRandom +#define log2Int __log2Int + + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/separator.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/separator.c new file mode 100644 index 0000000..380d4f4 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/separator.c @@ -0,0 +1,284 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * separator.c + * + * This file contains code for separator extraction + * + * Started 8/1/97 + * George + * + * $Id: separator.c,v 1.1 2003/07/16 15:55:17 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function takes a bisection and constructs a minimum weight vertex +* separator out of it. It uses the node-based separator refinement for it. +**************************************************************************/ +void ConstructSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int i, j, k, nvtxs, nbnd; + idxtype *xadj, *where, *bndind; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + nbnd = graph->nbnd; + bndind = graph->bndind; + + where = idxcopy(nvtxs, graph->where, idxwspacemalloc(ctrl, nvtxs)); + + /* Put the nodes in the boundary into the separator */ + for (i=0; i 0) /* Ignore islands */ + where[j] = 2; + } + + GKfree(&graph->rdata, LTERM); + Allocate2WayNodePartitionMemory(ctrl, graph); + idxcopy(nvtxs, where, graph->where); + idxwspacefree(ctrl, nvtxs); + + ASSERT(IsSeparable(graph)); + + Compute2WayNodePartitionParams(ctrl, graph); + + ASSERT(CheckNodePartitionParams(graph)); + + FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); + + ASSERT(IsSeparable(graph)); +} + + + +/************************************************************************* +* This function takes a bisection and constructs a minimum weight vertex +* separator out of it. It uses an unweighted minimum-cover algorithm +* followed by node-based separator refinement. +**************************************************************************/ +void ConstructMinCoverSeparator0(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize; + idxtype *xadj, *adjncy, *bxadj, *badjncy; + idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover; + + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + nbnd = graph->nbnd; + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + + vmap = idxwspacemalloc(ctrl, nvtxs); + ivmap = idxwspacemalloc(ctrl, nbnd); + cover = idxwspacemalloc(ctrl, nbnd); + + if (nbnd > 0) { + /* Go through the boundary and determine the sizes of the bipartite graph */ + bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0; + for (i=0; i 0) { + bnvtxs[k]++; + bnedges[k] += xadj[j+1]-xadj[j]; + } + } + + bnvtxs[2] = bnvtxs[0]+bnvtxs[1]; + bnvtxs[1] = bnvtxs[0]; + bnvtxs[0] = 0; + + bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj"); + badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy"); + + /* Construct the ivmap and vmap */ + ASSERT(idxset(nvtxs, -1, vmap) == vmap); + for (i=0; i 0) { + vmap[j] = bnvtxs[k]; + ivmap[bnvtxs[k]++] = j; + } + } + + /* OK, go through and put the vertices of each part starting from 0 */ + bnvtxs[1] = bnvtxs[0]; + bnvtxs[0] = 0; + bxadj[0] = l = 0; + for (k=0; k<2; k++) { + for (ii=0; iibndptr[jj])); + badjncy[l++] = vmap[jj]; + } + } + bxadj[++bnvtxs[k]] = l; + } + } + } + + ASSERT(l <= bnedges[0]+bnedges[1]); + + MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize); + + IFSET(ctrl->dbglvl, DBG_SEPINFO, + printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize)); + + for (i=0; idbglvl, DBG_SEPINFO, + printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0)); + } + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, graph->nbnd); + idxwspacefree(ctrl, graph->nbnd); + graph->nbnd = nbnd; + + + ASSERT(IsSeparable(graph)); +} + + + +/************************************************************************* +* This function takes a bisection and constructs a minimum weight vertex +* separator out of it. It uses an unweighted minimum-cover algorithm +* followed by node-based separator refinement. +**************************************************************************/ +void ConstructMinCoverSeparator(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int i, ii, j, jj, k, l, nvtxs, nbnd, bnvtxs[3], bnedges[2], csize; + idxtype *xadj, *adjncy, *bxadj, *badjncy; + idxtype *where, *bndind, *bndptr, *vmap, *ivmap, *cover; + + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + nbnd = graph->nbnd; + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + + vmap = idxwspacemalloc(ctrl, nvtxs); + ivmap = idxwspacemalloc(ctrl, nbnd); + cover = idxwspacemalloc(ctrl, nbnd); + + if (nbnd > 0) { + /* Go through the boundary and determine the sizes of the bipartite graph */ + bnvtxs[0] = bnvtxs[1] = bnedges[0] = bnedges[1] = 0; + for (i=0; i 0) { + bnvtxs[k]++; + bnedges[k] += xadj[j+1]-xadj[j]; + } + } + + bnvtxs[2] = bnvtxs[0]+bnvtxs[1]; + bnvtxs[1] = bnvtxs[0]; + bnvtxs[0] = 0; + + bxadj = idxmalloc(bnvtxs[2]+1, "ConstructMinCoverSeparator: bxadj"); + badjncy = idxmalloc(bnedges[0]+bnedges[1]+1, "ConstructMinCoverSeparator: badjncy"); + + /* Construct the ivmap and vmap */ + ASSERT(idxset(nvtxs, -1, vmap) == vmap); + for (i=0; i 0) { + vmap[j] = bnvtxs[k]; + ivmap[bnvtxs[k]++] = j; + } + } + + /* OK, go through and put the vertices of each part starting from 0 */ + bnvtxs[1] = bnvtxs[0]; + bnvtxs[0] = 0; + bxadj[0] = l = 0; + for (k=0; k<2; k++) { + for (ii=0; iibndptr[jj])); + badjncy[l++] = vmap[jj]; + } + } + bxadj[++bnvtxs[k]] = l; + } + } + } + + ASSERT(l <= bnedges[0]+bnedges[1]); + + MinCover(bxadj, badjncy, bnvtxs[0], bnvtxs[1], cover, &csize); + + IFSET(ctrl->dbglvl, DBG_SEPINFO, + printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, bnvtxs[0], bnvtxs[1]-bnvtxs[0], csize)); + + for (i=0; idbglvl, DBG_SEPINFO, + printf("Nvtxs: %6d, [%5d %5d], Cut: %6d, SS: [%6d %6d], Cover: %6d\n", nvtxs, graph->pwgts[0], graph->pwgts[1], graph->mincut, 0, 0, 0)); + } + + /* Prepare to refine the vertex separator */ + idxcopy(nvtxs, graph->where, vmap); + GKfree(&graph->rdata, LTERM); + + Allocate2WayNodePartitionMemory(ctrl, graph); + idxcopy(nvtxs, vmap, graph->where); + idxwspacefree(ctrl, nvtxs+2*graph->nbnd); + + Compute2WayNodePartitionParams(ctrl, graph); + + ASSERT(CheckNodePartitionParams(graph)); + + FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 6); + + ASSERT(IsSeparable(graph)); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/sfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/sfm.c new file mode 100644 index 0000000..eece33f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/sfm.c @@ -0,0 +1,1069 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * sfm.c + * + * This file contains code that implementes an FM-based separator refinement + * + * Started 8/1/97 + * George + * + * $Id: sfm.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function performs a node-based FM refinement +**************************************************************************/ +void FM_2WayNodeRefine(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) +{ + int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; + idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; + idxtype *mptr, *mind, *moved, *swaps, *perm; + PQueueType parts[2]; + NRInfoType *rinfo; + int higain, oldgain, mincut, initcut, mincutorder; + int pass, to, other, limit; + int badmaxpwgt, mindiff, newdiff; + int u[2], g[2]; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + pwgts = graph->pwgts; + rinfo = graph->nrinfo; + + + i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); + PQueueInit(ctrl, &parts[0], nvtxs, i); + PQueueInit(ctrl, &parts[1], nvtxs, i); + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + mptr = idxwspacemalloc(ctrl, nvtxs+1); + mind = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); + + for (pass=0; passmincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iioflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); + + /****************************************************** + * Get into the FM loop + *******************************************************/ + mptr[0] = nmind = 0; + mindiff = abs(pwgts[0]-pwgts[1]); + to = (pwgts[0] < pwgts[1] ? 0 : 1); + for (nswaps=0; nswaps g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); + /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */ + + if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) + to = (to+1)%2; + } + else if (u[0] == -1 && u[1] == -1) { + break; + } + else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) { + to = 0; + } + else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) { + to = 1; + } + else + break; + + other = (to+1)%2; + + higain = PQueueGetMax(&parts[to]); + if (moved[higain] == -1) /* Delete if it was in the separator originally */ + PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); + + ASSERT(bndptr[higain] != -1); + + pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); + + newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); + if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { + mincut = pwgts[2]; + mincutorder = nswaps; + mindiff = newdiff; + } + else { + if (nswaps - mincutorder > limit) { + pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); + break; /* No further improvement, break out */ + } + } + + BNDDelete(nbnd, bndind, bndptr, higain); + pwgts[to] += vwgt[higain]; + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + + /********************************************************** + * Update the degrees of the affected nodes + ***********************************************************/ + for (j=xadj[higain]; jdbglvl, DBG_MOVEINFO, + printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); + + } + + + /**************************************************************** + * Roll back computation + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + ASSERT(CheckNodePartitionParams(graph)); + + to = where[higain]; + other = (to+1)%2; + INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); + where[higain] = 2; + BNDInsert(nbnd, bndind, bndptr, higain); + + edegrees = rinfo[higain].edegrees; + edegrees[0] = edegrees[1] = 0; + for (j=xadj[higain]; jdbglvl, DBG_REFINE, + printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut >= initcut) + break; + } + + PQueueFree(ctrl, &parts[0]); + PQueueFree(ctrl, &parts[1]); + + idxwspacefree(ctrl, nvtxs+1); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function performs a node-based FM refinement +**************************************************************************/ +void FM_2WayNodeRefine2(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) +{ + int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; + idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; + idxtype *mptr, *mind, *moved, *swaps, *perm; + PQueueType parts[2]; + NRInfoType *rinfo; + int higain, oldgain, mincut, initcut, mincutorder; + int pass, to, other, limit; + int badmaxpwgt, mindiff, newdiff; + int u[2], g[2]; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + pwgts = graph->pwgts; + rinfo = graph->nrinfo; + + + i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); + PQueueInit(ctrl, &parts[0], nvtxs, i); + PQueueInit(ctrl, &parts[1], nvtxs, i); + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + mptr = idxwspacemalloc(ctrl, nvtxs+1); + mind = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); + + for (pass=0; passmincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iioflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); + + /****************************************************** + * Get into the FM loop + *******************************************************/ + mptr[0] = nmind = 0; + mindiff = abs(pwgts[0]-pwgts[1]); + to = (pwgts[0] < pwgts[1] ? 0 : 1); + for (nswaps=0; nswaps g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); + /* to = (g[0] > g[1] ? 0 : (g[0] < g[1] ? 1 : (pwgts[0] < pwgts[1] ? 0 : 1))); */ + + if (pwgts[to]+vwgt[u[to]] > badmaxpwgt) + to = (to+1)%2; + } + else if (u[0] == -1 && u[1] == -1) { + break; + } + else if (u[0] != -1 && pwgts[0]+vwgt[u[0]] <= badmaxpwgt) { + to = 0; + } + else if (u[1] != -1 && pwgts[1]+vwgt[u[1]] <= badmaxpwgt) { + to = 1; + } + else + break; + + other = (to+1)%2; + + higain = PQueueGetMax(&parts[to]); + if (moved[higain] == -1) /* Delete if it was in the separator originally */ + PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); + + ASSERT(bndptr[higain] != -1); + + pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); + + newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); + if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { + mincut = pwgts[2]; + mincutorder = nswaps; + mindiff = newdiff; + } + else { + if (nswaps - mincutorder > limit) { + pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); + break; /* No further improvement, break out */ + } + } + + BNDDelete(nbnd, bndind, bndptr, higain); + pwgts[to] += vwgt[higain]; + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + + /********************************************************** + * Update the degrees of the affected nodes + ***********************************************************/ + for (j=xadj[higain]; jdbglvl, DBG_MOVEINFO, + printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); + + } + + + /**************************************************************** + * Roll back computation + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + ASSERT(CheckNodePartitionParams(graph)); + + to = where[higain]; + other = (to+1)%2; + INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); + where[higain] = 2; + BNDInsert(nbnd, bndind, bndptr, higain); + + edegrees = rinfo[higain].edegrees; + edegrees[0] = edegrees[1] = 0; + for (j=xadj[higain]; jdbglvl, DBG_REFINE, + printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut >= initcut) + break; + } + + PQueueFree(ctrl, &parts[0]); + PQueueFree(ctrl, &parts[1]); + + idxwspacefree(ctrl, nvtxs+1); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function performs a node-based FM refinement +**************************************************************************/ +void FM_2WayNodeRefineEqWgt(CtrlType *ctrl, GraphType *graph, int npasses) +{ + int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; + idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; + idxtype *mptr, *mind, *moved, *swaps, *perm; + PQueueType parts[2]; + NRInfoType *rinfo; + int higain, oldgain, mincut, initcut, mincutorder; + int pass, to, other, limit; + int mindiff, newdiff; + int u[2], g[2]; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + pwgts = graph->pwgts; + rinfo = graph->nrinfo; + + + i = ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt); + PQueueInit(ctrl, &parts[0], nvtxs, i); + PQueueInit(ctrl, &parts[1], nvtxs, i); + + moved = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + mptr = idxwspacemalloc(ctrl, nvtxs+1); + mind = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + for (pass=0; passmincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iioflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); + + /****************************************************** + * Get into the FM loop + *******************************************************/ + mptr[0] = nmind = 0; + mindiff = abs(pwgts[0]-pwgts[1]); + to = (pwgts[0] < pwgts[1] ? 0 : 1); + for (nswaps=0; nswaps g[1] ? 0 : (g[0] < g[1] ? 1 : pass%2)); + } + } + other = (to+1)%2; + + if ((higain = PQueueGetMax(&parts[to])) == -1) + break; + + if (moved[higain] == -1) /* Delete if it was in the separator originally */ + PQueueDelete(&parts[other], higain, vwgt[higain]-rinfo[higain].edegrees[to]); + + ASSERT(bndptr[higain] != -1); + + pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); + + newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); + if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { + mincut = pwgts[2]; + mincutorder = nswaps; + mindiff = newdiff; + } + else { + if (nswaps - mincutorder > limit) { + pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); + break; /* No further improvement, break out */ + } + } + + BNDDelete(nbnd, bndind, bndptr, higain); + pwgts[to] += vwgt[higain]; + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + + /********************************************************** + * Update the degrees of the affected nodes + ***********************************************************/ + for (j=xadj[higain]; jdbglvl, DBG_MOVEINFO, + printf("Moved %6d to %3d, Gain: %5d [%5d] [%4d %4d] \t[%5d %5d %5d]\n", higain, to, g[to], g[other], vwgt[u[to]], vwgt[u[other]], pwgts[0], pwgts[1], pwgts[2])); + + } + + + /**************************************************************** + * Roll back computation + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + ASSERT(CheckNodePartitionParams(graph)); + + to = where[higain]; + other = (to+1)%2; + INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); + where[higain] = 2; + BNDInsert(nbnd, bndind, bndptr, higain); + + edegrees = rinfo[higain].edegrees; + edegrees[0] = edegrees[1] = 0; + for (j=xadj[higain]; jdbglvl, DBG_REFINE, + printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + if (mincutorder == -1 || mincut >= initcut) + break; + } + + PQueueFree(ctrl, &parts[0]); + PQueueFree(ctrl, &parts[1]); + + idxwspacefree(ctrl, nvtxs+1); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function performs a node-based FM refinement. This is the +* one-way version +**************************************************************************/ +void FM_2WayNodeRefine_OneSided(CtrlType *ctrl, GraphType *graph, float ubfactor, int npasses) +{ + int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps, nmind; + idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; + idxtype *mptr, *mind, *swaps, *perm; + PQueueType parts; + NRInfoType *rinfo; + int higain, oldgain, mincut, initcut, mincutorder; + int pass, to, other, limit; + int badmaxpwgt, mindiff, newdiff; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + pwgts = graph->pwgts; + rinfo = graph->nrinfo; + + PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt)); + + perm = idxwspacemalloc(ctrl, nvtxs); + swaps = idxwspacemalloc(ctrl, nvtxs); + mptr = idxwspacemalloc(ctrl, nvtxs+1); + mind = idxwspacemalloc(ctrl, nvtxs); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions-N1: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + badmaxpwgt = (int)(ubfactor*(pwgts[0]+pwgts[1]+pwgts[2])/2); + + to = (pwgts[0] < pwgts[1] ? 1 : 0); + for (pass=0; passmincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iioflags&OFLAG_COMPRESS ? amin(5*nbnd, 400) : amin(2*nbnd, 300)); + + /****************************************************** + * Get into the FM loop + *******************************************************/ + mptr[0] = nmind = 0; + mindiff = abs(pwgts[0]-pwgts[1]); + for (nswaps=0; nswaps badmaxpwgt) + break; /* No point going any further. Balance will be bad */ + + pwgts[2] -= (vwgt[higain]-rinfo[higain].edegrees[other]); + + newdiff = abs(pwgts[to]+vwgt[higain] - (pwgts[other]-rinfo[higain].edegrees[other])); + if (pwgts[2] < mincut || (pwgts[2] == mincut && newdiff < mindiff)) { + mincut = pwgts[2]; + mincutorder = nswaps; + mindiff = newdiff; + } + else { + if (nswaps - mincutorder > limit) { + pwgts[2] += (vwgt[higain]-rinfo[higain].edegrees[other]); + break; /* No further improvement, break out */ + } + } + + BNDDelete(nbnd, bndind, bndptr, higain); + pwgts[to] += vwgt[higain]; + where[higain] = to; + swaps[nswaps] = higain; + + + /********************************************************** + * Update the degrees of the affected nodes + ***********************************************************/ + for (j=xadj[higain]; jdbglvl, DBG_MOVEINFO, + printf("Moved %6d to %3d, Gain: %5d [%5d] \t[%5d %5d %5d] [%3d %2d]\n", + higain, to, (vwgt[higain]-rinfo[higain].edegrees[other]), vwgt[higain], pwgts[0], pwgts[1], pwgts[2], nswaps, limit)); + + } + + + /**************************************************************** + * Roll back computation + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + ASSERT(CheckNodePartitionParams(graph)); + ASSERT(where[higain] == to); + + INC_DEC(pwgts[2], pwgts[to], vwgt[higain]); + where[higain] = 2; + BNDInsert(nbnd, bndind, bndptr, higain); + + edegrees = rinfo[higain].edegrees; + edegrees[0] = edegrees[1] = 0; + for (j=xadj[higain]; jdbglvl, DBG_REFINE, + printf("\tMinimum sep: %6d at %5d, PWGTS: [%6d %6d], NBND: %6d\n", mincut, mincutorder, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = mincut; + graph->nbnd = nbnd; + + if (pass%2 == 1 && (mincutorder == -1 || mincut >= initcut)) + break; + } + + PQueueFree(ctrl, &parts); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs+1); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function performs a node-based FM refinement +**************************************************************************/ +void FM_2WayNodeBalance(CtrlType *ctrl, GraphType *graph, float ubfactor) +{ + int i, ii, j, k, jj, kk, nvtxs, nbnd, nswaps; + idxtype *xadj, *vwgt, *adjncy, *where, *pwgts, *edegrees, *bndind, *bndptr; + idxtype *perm, *moved; + PQueueType parts; + NRInfoType *rinfo; + int higain, oldgain; + int pass, to, other; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + where = graph->where; + pwgts = graph->pwgts; + rinfo = graph->nrinfo; + + if (abs(pwgts[0]-pwgts[1]) < (int)((ubfactor-1.0)*(pwgts[0]+pwgts[1]))) + return; + if (abs(pwgts[0]-pwgts[1]) < 3*idxsum(nvtxs, vwgt)/nvtxs) + return; + + to = (pwgts[0] < pwgts[1] ? 0 : 1); + other = (to+1)%2; + + PQueueInit(ctrl, &parts, nvtxs, ComputeMaxNodeGain(nvtxs, xadj, adjncy, vwgt)); + + perm = idxwspacemalloc(ctrl, nvtxs); + moved = idxset(nvtxs, -1, idxwspacemalloc(ctrl, nvtxs)); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d] Nv-Nb[%6d %6d]. ISep: %6d [B]\n", pwgts[0], pwgts[1], graph->nvtxs, graph->nbnd, graph->mincut)); + + nbnd = graph->nbnd; + RandomPermute(nbnd, perm, 1); + for (ii=0; iidbglvl, DBG_MOVEINFO, + printf("Moved %6d to %3d, Gain: %3d, \t[%5d %5d %5d]\n", higain, to, vwgt[higain]-rinfo[higain].edegrees[other], pwgts[0], pwgts[1], pwgts[2])); + + + /********************************************************** + * Update the degrees of the affected nodes + ***********************************************************/ + for (j=xadj[higain]; j pwgts[other]) + break; + } + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\tBalanced sep: %6d at %4d, PWGTS: [%6d %6d], NBND: %6d\n", pwgts[2], nswaps, pwgts[0], pwgts[1], nbnd)); + + graph->mincut = pwgts[2]; + graph->nbnd = nbnd; + + + PQueueFree(ctrl, &parts); + + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); +} + + +/************************************************************************* +* This function computes the maximum possible gain for a vertex +**************************************************************************/ +int ComputeMaxNodeGain(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt) +{ + int i, j, k, max; + + max = 0; + for (j=xadj[0]; j + + +/************************************************************************* +* This function is the entry point of the separator refinement +**************************************************************************/ +void Refine2WayNode(CtrlType *ctrl, GraphType *orggraph, GraphType *graph, float ubfactor) +{ + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->UncoarsenTmr)); + + for (;;) { + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->RefTmr)); + if (ctrl->RType != 15) + FM_2WayNodeBalance(ctrl, graph, ubfactor); + + switch (ctrl->RType) { + case 1: + FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); + break; + case 2: + FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); + break; + case 3: + FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); + FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); + break; + case 4: + FM_2WayNodeRefine_OneSided(ctrl, graph, ubfactor, 8); + FM_2WayNodeRefine(ctrl, graph, ubfactor, 8); + break; + case 5: + FM_2WayNodeRefineEqWgt(ctrl, graph, 8); + break; + } + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->RefTmr)); + + if (graph == orggraph) + break; + + graph = graph->finer; + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + Project2WayNodePartition(ctrl, graph); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->UncoarsenTmr)); +} + + +/************************************************************************* +* This function allocates memory for 2-way edge refinement +**************************************************************************/ +void Allocate2WayNodePartitionMemory(CtrlType *ctrl, GraphType *graph) +{ + int nvtxs, pad64; + + nvtxs = graph->nvtxs; + + pad64 = (3*nvtxs+3)%2; + + graph->rdata = idxmalloc(3*nvtxs+3+(sizeof(NRInfoType)/sizeof(idxtype))*nvtxs+pad64, "Allocate2WayPartitionMemory: rdata"); + graph->pwgts = graph->rdata; + graph->where = graph->rdata + 3; + graph->bndptr = graph->rdata + nvtxs + 3; + graph->bndind = graph->rdata + 2*nvtxs + 3; + graph->nrinfo = (NRInfoType *)(graph->rdata + 3*nvtxs + 3 + pad64); +} + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Compute2WayNodePartitionParams(CtrlType *ctrl, GraphType *graph) +{ + int i, j, k, l, nvtxs, nbnd; + idxtype *xadj, *adjncy, *adjwgt, *vwgt; + idxtype *where, *pwgts, *bndind, *bndptr, *edegrees; + NRInfoType *rinfo; + int me, other; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + rinfo = graph->nrinfo; + pwgts = idxset(3, 0, graph->pwgts); + bndind = graph->bndind; + bndptr = idxset(nvtxs, -1, graph->bndptr); + + + /*------------------------------------------------------------ + / Compute now the separator external degrees + /------------------------------------------------------------*/ + nbnd = 0; + for (i=0; i=0 && me <= 2); + + if (me == 2) { /* If it is on the separator do some computations */ + BNDInsert(nbnd, bndind, bndptr, i); + + edegrees = rinfo[i].edegrees; + edegrees[0] = edegrees[1] = 0; + + for (j=xadj[i]; jmincut = pwgts[2]; + graph->nbnd = nbnd; +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Project2WayNodePartition(CtrlType *ctrl, GraphType *graph) +{ + int i, j, nvtxs; + idxtype *cmap, *where, *cwhere; + GraphType *cgraph; + + cgraph = graph->coarser; + cwhere = cgraph->where; + + nvtxs = graph->nvtxs; + cmap = graph->cmap; + + Allocate2WayNodePartitionMemory(ctrl, graph); + where = graph->where; + + /* Project the partition */ + for (i=0; i= 0 && where[i] <= 2, ("%d %d %d %d\n", i, cmap[i], where[i], cwhere[cmap[i]])); + } + + FreeGraph(graph->coarser); + graph->coarser = NULL; + + Compute2WayNodePartitionParams(ctrl, graph); +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stat.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stat.c new file mode 100644 index 0000000..6156d6d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stat.c @@ -0,0 +1,316 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stat.c + * + * This file computes various statistics + * + * Started 7/25/97 + * George + * + * $Id: stat.c,v 1.2 2003/07/24 18:39:12 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function computes cuts and balance information +**************************************************************************/ +void ComputePartitionInfo(GraphType *graph, int nparts, idxtype *where) +{ + int i, j, k, nvtxs, ncon, mustfree=0; + idxtype *xadj, *adjncy, *vwgt, *adjwgt, *kpwgts, *tmpptr; + idxtype *padjncy, *padjwgt, *padjcut; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + adjwgt = graph->adjwgt; + + if (vwgt == NULL) { + vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt"); + mustfree = 1; + } + if (adjwgt == NULL) { + adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt"); + mustfree += 2; + } + + printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where)); + + /* Compute balance information */ + kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts"); + + for (i=0; iwhere; + graph->where = where; + for (i=0; iwhere = tmpptr; + + if (mustfree == 1 || mustfree == 3) { + free(vwgt); + graph->vwgt = NULL; + } + if (mustfree == 2 || mustfree == 3) { + free(adjwgt); + graph->adjwgt = NULL; + } + + GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM); +} + + +/************************************************************************* +* This function computes cuts and balance information +**************************************************************************/ +void ComputePartitionInfoBipartite(GraphType *graph, int nparts, idxtype *where) +{ + int i, j, k, nvtxs, ncon, mustfree=0; + idxtype *xadj, *adjncy, *vwgt, *vsize, *adjwgt, *kpwgts, *tmpptr; + idxtype *padjncy, *padjwgt, *padjcut; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + vsize = graph->vsize; + adjwgt = graph->adjwgt; + + if (vwgt == NULL) { + vwgt = graph->vwgt = idxsmalloc(nvtxs, 1, "vwgt"); + mustfree = 1; + } + if (adjwgt == NULL) { + adjwgt = graph->adjwgt = idxsmalloc(xadj[nvtxs], 1, "adjwgt"); + mustfree += 2; + } + + printf("%d-way Cut: %5d, Vol: %5d, ", nparts, ComputeCut(graph, where), ComputeVolume(graph, where)); + + /* Compute balance information */ + kpwgts = idxsmalloc(ncon*nparts, 0, "ComputePartitionInfo: kpwgts"); + + for (i=0; ivwgt = NULL; + } + if (mustfree == 2 || mustfree == 3) { + free(adjwgt); + graph->adjwgt = NULL; + } + + GKfree(&kpwgts, &padjncy, &padjwgt, &padjcut, LTERM); +} + + + +/************************************************************************* +* This function computes the balance of the partitioning +**************************************************************************/ +void ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) +{ + int i, j, nvtxs, ncon; + idxtype *kpwgts, *vwgt; + float balance; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + vwgt = graph->vwgt; + + kpwgts = idxsmalloc(nparts, 0, "ComputePartitionInfo: kpwgts"); + + if (vwgt == NULL && ncon == 1) { + for (i=0; invtxs; i++) + kpwgts[where[i]] += vwgt[i*ncon+j]; + + ubvec[j] = 1.0*nparts*kpwgts[idxamax(nparts, kpwgts)]/(1.0*idxsum(nparts, kpwgts)); + } + } + + free(kpwgts); + +} + + +/************************************************************************* +* This function computes the balance of the element partitioning +**************************************************************************/ +float ComputeElementBalance(int ne, int nparts, idxtype *where) +{ + int i; + idxtype *kpwgts; + float balance; + + kpwgts = idxsmalloc(nparts, 0, "ComputeElementBalance: kpwgts"); + + for (i=0; invtxs; + ncon = graph->ncon; + nvwgt = graph->nvwgt; + + kpwgts = fmalloc(nparts, "ComputePartitionInfo: kpwgts"); + + for (j=0; jnvtxs; i++) + kpwgts[where[i]] += nvwgt[i*ncon+j]; + + ubvec[j] = (float)nparts*kpwgts[samax(nparts, kpwgts)]/ssum(nparts, kpwgts); + } + + free(kpwgts); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stats.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stats.c new file mode 100644 index 0000000..4f6b548 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stats.c @@ -0,0 +1,44 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stat.c + * + * This file computes various statistics + * + * Started 7/25/97 + * George + * + * $Id: stats.c,v 1.1 2003/03/13 06:33:20 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function computes the balance of the partitioning +**************************************************************************/ +void Moc_ComputePartitionBalance(GraphType *graph, int nparts, idxtype *where, float *ubvec) +{ + int i, j, nvtxs, ncon; + float *kpwgts, *nvwgt; + float balance; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + nvwgt = graph->nvwgt; + + kpwgts = fmalloc(nparts, "ComputePartitionInfo: kpwgts"); + + for (j=0; jnvtxs; i++) + kpwgts[where[i]] += nvwgt[i*ncon+j]; + + ubvec[j] = (float)nparts*kpwgts[samax(nparts, kpwgts)]/ssum(nparts, kpwgts); + } + + free(kpwgts); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stdheaders.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stdheaders.h new file mode 100644 index 0000000..f82b0cb --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/stdheaders.h @@ -0,0 +1,26 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stdheaders.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: stdheaders.h,v 1.2 2003/07/25 14:31:45 karypis Exp $ + */ + + +#include +#ifdef __STDC__ +#include +#else +#include +#endif +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/struct.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/struct.h new file mode 100644 index 0000000..ff091c6 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/struct.h @@ -0,0 +1,253 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * struct.h + * + * This file contains data structures for ILU routines. + * + * Started 9/26/95 + * George + * + * $Id: struct.h,v 1.2 2003/07/25 13:52:01 karypis Exp $ + */ + +#ifndef __parmetis_h__ +/* Undefine the following #define in order to use short int as the idxtype */ +#define IDXTYPE_INT + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +typedef int idxtype; +#else +typedef short idxtype; +#endif +#endif + +#define MAXIDX (1<<8*sizeof(idxtype)-2) + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KeyValueType { + idxtype key; + idxtype val; +}; + +typedef struct KeyValueType KeyValueType; + + +/************************************************************************* +* The following data structure will hold a node of a doubly-linked list. +**************************************************************************/ +struct ListNodeType { + int id; /* The id value of the node */ + struct ListNodeType *prev, *next; /* It's a doubly-linked list */ +}; + +typedef struct ListNodeType ListNodeType; + + + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct PQueueType { + int type; /* The type of the representation used */ + int nnodes; + int maxnodes; + int mustfree; + + /* Linear array version of the data structures */ + int pgainspan, ngainspan; /* plus and negative gain span */ + int maxgain; + ListNodeType *nodes; + ListNodeType **buckets; + + /* Heap version of the data structure */ + KeyValueType *heap; + idxtype *locator; +}; + +typedef struct PQueueType PQueueType; + + +/************************************************************************* +* The following data structure stores an edge +**************************************************************************/ +struct edegreedef { + idxtype pid; + idxtype ed; +}; +typedef struct edegreedef EDegreeType; + + +/************************************************************************* +* The following data structure stores an edge for vol +**************************************************************************/ +struct vedegreedef { + idxtype pid; + idxtype ed, ned; + idxtype gv; +}; +typedef struct vedegreedef VEDegreeType; + + +/************************************************************************* +* This data structure holds various working space data +**************************************************************************/ +struct workspacedef { + idxtype *core; /* Where pairs, indices, and degrees are coming from */ + int maxcore, ccore; + + EDegreeType *edegrees; + VEDegreeType *vedegrees; + int cdegree; + + idxtype *auxcore; /* This points to the memory of the edegrees */ + + idxtype *pmat; /* An array of k^2 used for eliminating domain + connectivity in k-way refinement */ +}; + +typedef struct workspacedef WorkSpaceType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct rinfodef { + int id, ed; /* ID/ED of nodes */ + int ndegrees; /* The number of different ext-degrees */ + EDegreeType *edegrees; /* List of edges */ +}; + +typedef struct rinfodef RInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* vol-based partition +**************************************************************************/ +struct vrinfodef { + int id, ed, nid; /* ID/ED of nodes */ + int gv; /* IV/EV of nodes */ + int ndegrees; /* The number of different ext-degrees */ + VEDegreeType *edegrees; /* List of edges */ +}; + +typedef struct vrinfodef VRInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct nrinfodef { + idxtype edegrees[2]; +}; + +typedef struct nrinfodef NRInfoType; + + +/************************************************************************* +* This data structure holds the input graph +**************************************************************************/ +struct graphdef { + idxtype *gdata, *rdata; /* Memory pools for graph and refinement data. + This is where memory is allocated and used + the rest of the fields in this structure */ + + int nvtxs, nedges; /* The # of vertices and edges in the graph */ + idxtype *xadj; /* Pointers to the locally stored vertices */ + idxtype *vwgt; /* Vertex weights */ + idxtype *vsize; /* Vertex sizes for min-volume formulation */ + idxtype *adjncy; /* Array that stores the adjacency lists of nvtxs */ + idxtype *adjwgt; /* Array that stores the weights of the adjacency lists */ + + idxtype *adjwgtsum; /* The sum of the adjacency weight of each vertex */ + + idxtype *label; + + idxtype *cmap; + + /* Partition parameters */ + int mincut, minvol; + idxtype *where, *pwgts; + int nbnd; + idxtype *bndptr, *bndind; + + /* Bisection refinement parameters */ + idxtype *id, *ed; + + /* K-way refinement parameters */ + RInfoType *rinfo; + + /* K-way volume refinement parameters */ + VRInfoType *vrinfo; + + /* Node refinement information */ + NRInfoType *nrinfo; + + + /* Additional info needed by the MOC routines */ + int ncon; /* The # of constrains */ + float *nvwgt; /* Normalized vertex weights */ + float *npwgts; /* The normalized partition weights */ + + struct graphdef *coarser, *finer; +}; + +typedef struct graphdef GraphType; + + + +/************************************************************************* +* The following data type implements a timer +**************************************************************************/ +typedef double timer; + + +/************************************************************************* +* The following structure stores information used by Metis +**************************************************************************/ +struct controldef { + int CoarsenTo; /* The # of vertices in the coarsest graph */ + int dbglvl; /* Controls the debuging output of the program */ + int CType; /* The type of coarsening */ + int IType; /* The type of initial partitioning */ + int RType; /* The type of refinement */ + int maxvwgt; /* The maximum allowed weight for a vertex */ + float nmaxvwgt; /* The maximum allowed weight for a vertex for each constrain */ + int optype; /* Type of operation */ + int pfactor; /* .1*prunning factor */ + int nseps; /* The number of separators to be found during multiple bisections */ + int oflags; + + WorkSpaceType wspace; /* Work Space Informations */ + + /* Various Timers */ + timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, UncoarsenTmr, + SepTmr, RefTmr, ProjectTmr, SplitTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6; + +}; + +typedef struct controldef CtrlType; + + +/************************************************************************* +* The following data structure stores max-partition weight info for +* Vertical MOC k-way refinement +**************************************************************************/ +struct vpwgtdef { + float max[2][MAXNCON]; + int imax[2][MAXNCON]; +}; + +typedef struct vpwgtdef VPInfoType; + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/subdomains.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/subdomains.c new file mode 100644 index 0000000..6fc65e7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/subdomains.c @@ -0,0 +1,1295 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * subdomains.c + * + * This file contains functions that deal with prunning the number of + * adjacent subdomains in KMETIS + * + * Started 7/15/98 + * George + * + * $Id: subdomains.c,v 1.2 2003/07/31 06:14:01 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Random_KWayEdgeRefineMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses, int ffactor) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, nmoves, nbnd, tvwgt, myndegrees; + int from, me, to, oldcut, vwgt, gain; + int maxndoms, nadd; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *itpwgts; + idxtype *phtable, *pmat, *pmatptr, *ndoms; + EDegreeType *myedegrees; + RInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndptr = graph->bndptr; + bndind = graph->bndind; + + where = graph->where; + pwgts = graph->pwgts; + + pmat = ctrl->wspace.pmat; + phtable = idxwspacemalloc(ctrl, nparts); + ndoms = idxwspacemalloc(ctrl, nparts); + + ComputeSubDomainGraph(graph, nparts, pmat, ndoms); + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + for (i=0; idbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut)); + + for (pass=0; passmincut); + + maxndoms = ndoms[idxamax(nparts, ndoms)]; + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (nmoves=iii=0; iiinbnd; iii++) { + ii = perm[iii]; + if (ii >= nbnd) + continue; + i = bndind[ii]; + + myrinfo = graph->rinfo+i; + + if (myrinfo->ed >= myrinfo->id) { /* Total ED is too high */ + from = where[i]; + vwgt = graph->vwgt[i]; + + if (myrinfo->id > 0 && pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + /* Determine the valid domains */ + for (j=0; j maxndoms-1) { + phtable[to] = 0; + nadd = maxndoms; + break; + } + nadd++; + } + } + if (ndoms[to]+nadd > maxndoms) + phtable[to] = 0; + if (nadd == 0) + phtable[to] = 2; + } + + /* Find the first valid move */ + j = myrinfo->id; + for (k=0; kid. Allow good nodes to move */ + if (pwgts[to]+vwgt <= maxwgt[to]+ffactor*gain && gain >= 0) + break; + } + if (k == myndegrees) + continue; /* break out if you did not find a candidate */ + + for (j=k+1; j myedegrees[k].ed && pwgts[to]+vwgt <= maxwgt[to]) || + (myedegrees[j].ed == myedegrees[k].ed && + itpwgts[myedegrees[k].pid]*pwgts[to] < itpwgts[to]*pwgts[myedegrees[k].pid])) + k = j; + } + + to = myedegrees[k].pid; + + j = 0; + if (myedegrees[k].ed-myrinfo->id > 0) + j = 1; + else if (myedegrees[k].ed-myrinfo->id == 0) { + if (/*(iii&7) == 0 ||*/ phtable[myedegrees[k].pid] == 2 || pwgts[from] >= maxwgt[from] || itpwgts[from]*(pwgts[to]+vwgt) < itpwgts[to]*pwgts[from]) + j = 1; + } + if (j == 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update pmat to reflect the move of 'i' */ + pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); + pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); + if (pmat[from*nparts+to] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[to*nparts+from] == 0) { + ndoms[to]--; + if (ndoms[to]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + INC_DEC(pwgts[to], pwgts[from], vwgt); + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed-myrinfo->id < 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ + if (me != from && me != to) { + pmat[me*nparts+from] -= adjwgt[j]; + pmat[from*nparts+me] -= adjwgt[j]; + if (pmat[me*nparts+from] == 0) { + ndoms[me]--; + if (ndoms[me]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[from*nparts+me] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + if (pmat[me*nparts+to] == 0) { + ndoms[me]++; + if (ndoms[me] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms)); + maxndoms = ndoms[me]; + } + } + if (pmat[to*nparts+me] == 0) { + ndoms[to]++; + if (ndoms[to] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms)); + maxndoms = ndoms[to]; + } + } + pmat[me*nparts+to] += adjwgt[j]; + pmat[to*nparts+me] += adjwgt[j]; + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + + } + nmoves++; + } + } + + graph->nbnd = nbnd; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %5d, Vol: %5d, %d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, + graph->mincut, ComputeVolume(graph, where), idxsum(nparts, ndoms))); + + if (graph->mincut == oldcut) + break; + } + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); +} + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Greedy_KWayEdgeBalanceMConn(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor, int npasses) +{ + int i, ii, iii, j, jj, k, l, pass, nvtxs, nbnd, tvwgt, myndegrees, oldgain, gain, nmoves; + int from, me, to, oldcut, vwgt, maxndoms, nadd; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *pwgts, *perm, *bndptr, *bndind, *minwgt, *maxwgt, *moved, *itpwgts; + idxtype *phtable, *pmat, *pmatptr, *ndoms; + EDegreeType *myedegrees; + RInfoType *myrinfo; + PQueueType queue; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + bndind = graph->bndind; + bndptr = graph->bndptr; + + where = graph->where; + pwgts = graph->pwgts; + + pmat = ctrl->wspace.pmat; + phtable = idxwspacemalloc(ctrl, nparts); + ndoms = idxwspacemalloc(ctrl, nparts); + + ComputeSubDomainGraph(graph, nparts, pmat, ndoms); + + + /* Setup the weight intervals of the various subdomains */ + minwgt = idxwspacemalloc(ctrl, nparts); + maxwgt = idxwspacemalloc(ctrl, nparts); + itpwgts = idxwspacemalloc(ctrl, nparts); + tvwgt = idxsum(nparts, pwgts); + ASSERT(tvwgt == idxsum(nvtxs, graph->vwgt)); + + for (i=0; iadjwgtsum[idxamax(nvtxs, graph->adjwgtsum)]); + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("Partitions: [%6d %6d]-[%6d %6d], Balance: %5.3f, Nv-Nb[%6d %6d]. Cut: %6d [B]\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], minwgt[0], maxwgt[0], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nvtxs, graph->nbnd, + graph->mincut)); + + for (pass=0; passmincut); + + /* Check to see if things are out of balance, given the tolerance */ + for (i=0; i maxwgt[i]) + break; + } + if (i == nparts) /* Things are balanced. Return right away */ + break; + + PQueueReset(&queue); + idxset(nvtxs, -1, moved); + + oldcut = graph->mincut; + nbnd = graph->nbnd; + + RandomPermute(nbnd, perm, 1); + for (ii=0; iirinfo[i].ed - graph->rinfo[i].id); + moved[i] = 2; + } + + maxndoms = ndoms[idxamax(nparts, ndoms)]; + + for (nmoves=0;;) { + if ((i = PQueueGetMax(&queue)) == -1) + break; + moved[i] = 1; + + myrinfo = graph->rinfo+i; + from = where[i]; + vwgt = graph->vwgt[i]; + + if (pwgts[from]-vwgt < minwgt[from]) + continue; /* This cannot be moved! */ + + myedegrees = myrinfo->edegrees; + myndegrees = myrinfo->ndegrees; + + /* Determine the valid domains */ + for (j=0; j maxndoms-1) { + phtable[to] = 0; + nadd = maxndoms; + break; + } + nadd++; + } + } + if (ndoms[to]+nadd > maxndoms) + phtable[to] = 0; + } + + for (k=0; k minwgt[to] && myedegrees[k].ed-myrinfo->id < 0) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + IFSET(ctrl->dbglvl, DBG_MOVEINFO, printf("\t\tMoving %6d to %3d. Gain: %4d. Cut: %6d\n", i, to, myedegrees[k].ed-myrinfo->id, graph->mincut)); + + /* Update pmat to reflect the move of 'i' */ + pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); + pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); + if (pmat[from*nparts+to] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[to*nparts+from] == 0) { + ndoms[to]--; + if (ndoms[to]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + INC_DEC(pwgts[to], pwgts[from], vwgt); + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed == 0) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + oldgain = (myrinfo->ed-myrinfo->id); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed > 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed == 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ + if (me != from && me != to) { + pmat[me*nparts+from] -= adjwgt[j]; + pmat[from*nparts+me] -= adjwgt[j]; + if (pmat[me*nparts+from] == 0) { + ndoms[me]--; + if (ndoms[me]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + if (pmat[from*nparts+me] == 0) { + ndoms[from]--; + if (ndoms[from]+1 == maxndoms) + maxndoms = ndoms[idxamax(nparts, ndoms)]; + } + + if (pmat[me*nparts+to] == 0) { + ndoms[me]++; + if (ndoms[me] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[me], maxndoms)); + maxndoms = ndoms[me]; + } + } + if (pmat[to*nparts+me] == 0) { + ndoms[to]++; + if (ndoms[to] > maxndoms) { + IFSET(ctrl->dbglvl, DBG_REFINE, printf("You just increased the maxndoms: %d %d\n", ndoms[to], maxndoms)); + maxndoms = ndoms[to]; + } + } + pmat[me*nparts+to] += adjwgt[j]; + pmat[to*nparts+me] += adjwgt[j]; + } + + /* Update the queue */ + if (me == to || me == from) { + gain = myrinfo->ed-myrinfo->id; + if (moved[ii] == 2) { + if (myrinfo->ed > 0) + PQueueUpdate(&queue, ii, oldgain, gain); + else { + PQueueDelete(&queue, ii, oldgain); + moved[ii] = -1; + } + } + else if (moved[ii] == -1 && myrinfo->ed > 0) { + PQueueInsert(&queue, ii, gain); + moved[ii] = 2; + } + } + + ASSERT(myrinfo->ndegrees <= xadj[ii+1]-xadj[ii]); + ASSERT(CheckRInfo(myrinfo)); + } + nmoves++; + } + + graph->nbnd = nbnd; + + IFSET(ctrl->dbglvl, DBG_REFINE, + printf("\t[%6d %6d], Balance: %5.3f, Nb: %6d. Nmoves: %5d, Cut: %6d, %d\n", + pwgts[idxamin(nparts, pwgts)], pwgts[idxamax(nparts, pwgts)], + 1.0*nparts*pwgts[idxamax(nparts, pwgts)]/tvwgt, graph->nbnd, nmoves, graph->mincut,idxsum(nparts, ndoms))); + } + + PQueueFree(ctrl, &queue); + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + +} + + + + +/************************************************************************* +* This function computes the subdomain graph +**************************************************************************/ +void PrintSubDomainGraph(GraphType *graph, int nparts, idxtype *where) +{ + int i, j, k, me, nvtxs, total, max; + idxtype *xadj, *adjncy, *adjwgt, *pmat; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + pmat = idxsmalloc(nparts*nparts, 0, "ComputeSubDomainGraph: pmat"); + + for (i=0; i 0) + k++; + } + total += k; + + if (k > max) + max = k; +/* + printf("%2d -> %2d ", i, k); + for (j=0; j 0) + printf("[%2d %4d] ", j, pmat[i*nparts+j]); + } + printf("\n"); +*/ + } + printf("Total adjacent subdomains: %d, Max: %d\n", total, max); + + free(pmat); +} + + + +/************************************************************************* +* This function computes the subdomain graph +**************************************************************************/ +void ComputeSubDomainGraph(GraphType *graph, int nparts, idxtype *pmat, idxtype *ndoms) +{ + int i, j, k, me, nvtxs, ndegrees; + idxtype *xadj, *adjncy, *adjwgt, *where; + RInfoType *rinfo; + EDegreeType *edegrees; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->rinfo; + + idxset(nparts*nparts, 0, pmat); + + for (i=0; i 0) { + me = where[i]; + ndegrees = rinfo[i].ndegrees; + edegrees = rinfo[i].edegrees; + + k = me*nparts; + for (j=0; j 0) + ndoms[i]++; + } + } + +} + + + + + +/************************************************************************* +* This function computes the subdomain graph +**************************************************************************/ +void EliminateSubDomainEdges(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts) +{ + int i, ii, j, k, me, other, nvtxs, total, max, avg, totalout, nind, ncand, ncand2, target, target2, nadd; + int min, move, cpwgt, tvwgt; + idxtype *xadj, *adjncy, *vwgt, *adjwgt, *pwgts, *where, *maxpwgt, *pmat, *ndoms, *mypmat, *otherpmat, *ind; + KeyValueType *cand, *cand2; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = graph->pwgts; /* We assume that this is properly initialized */ + + maxpwgt = idxwspacemalloc(ctrl, nparts); + ndoms = idxwspacemalloc(ctrl, nparts); + otherpmat = idxwspacemalloc(ctrl, nparts); + ind = idxwspacemalloc(ctrl, nvtxs); + pmat = ctrl->wspace.pmat; + + cand = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); + cand2 = (KeyValueType *)GKmalloc(nparts*sizeof(KeyValueType), "EliminateSubDomainEdges: cand"); + + /* Compute the pmat matrix and ndoms */ + ComputeSubDomainGraph(graph, nparts, pmat, ndoms); + + + /* Compute the maximum allowed weight for each domain */ + tvwgt = idxsum(nparts, pwgts); + for (i=0; i 0) { + cand2[ncand2].key = mypmat[i]; + cand2[ncand2++].val = i; + } + } + ikeysort(ncand2, cand2); + + move = 0; + for (min=0; min totalout/(2*ndoms[me])) + break; + + other = cand2[min].val; + + /*printf("\tMinOut: %d to %d\n", mypmat[other], other);*/ + + idxset(nparts, 0, otherpmat); + + /* Go and find the vertices in 'other' that are connected in 'me' */ + for (nind=0, i=0; i 0) { + cand[ncand].key = -otherpmat[i]; + cand[ncand++].val = i; + } + } + ikeysort(ncand, cand); + + /* + * Go through and the select the first domain that is common with 'me', and + * does not increase the ndoms[target] higher than my ndoms, subject to the + * maxpwgt constraint. Traversal is done from the mostly connected to the least. + */ + target = target2 = -1; + for (i=0; i 0) { + if (pwgts[k] + cpwgt > maxpwgt[k]) /* Check if balance will go off */ + continue; + + for (j=0; j 0 && ndoms[j] >= ndoms[me]-1 && pmat[nparts*j+k] == 0) + break; + } + if (j == nparts) { /* No bad second level effects */ + for (nadd=0, j=0; j 0 && pmat[nparts*k+j] == 0) + nadd++; + } + + /*printf("\t\tto=%d, nadd=%d, %d\n", k, nadd, ndoms[k]);*/ + if (target2 == -1 && ndoms[k]+nadd < ndoms[me]) { + target2 = k; + } + if (nadd == 0) { + target = k; + break; + } + } + } + } + if (target == -1 && target2 != -1) + target = target2; + + if (target == -1) { + /* printf("\t\tCould not make the move\n");*/ + continue; + } + + /*printf("\t\tMoving to %d\n", target);*/ + + /* Update the partition weights */ + INC_DEC(pwgts[target], pwgts[other], cpwgt); + + MoveGroupMConn(ctrl, graph, ndoms, pmat, nparts, target, nind, ind); + + move = 1; + break; + } + + if (move == 0) + break; + } + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + + GKfree(&cand, &cand2, LTERM); +} + + +/************************************************************************* +* This function moves a collection of vertices and updates their rinfo +**************************************************************************/ +void MoveGroupMConn(CtrlType *ctrl, GraphType *graph, idxtype *ndoms, idxtype *pmat, + int nparts, int to, int nind, idxtype *ind) +{ + int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; + int from, me; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *bndptr, *bndind; + EDegreeType *myedegrees; + RInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + + nbnd = graph->nbnd; + + for (iii=0; iiirinfo+i; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; + myrinfo->ndegrees = 0; + } + myedegrees = myrinfo->edegrees; + + /* find the location of 'to' in myrinfo or create it if it is not there */ + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) + break; + } + if (k == myrinfo->ndegrees) { + myedegrees[k].pid = to; + myedegrees[k].ed = 0; + myrinfo->ndegrees++; + } + + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + /* Update pmat to reflect the move of 'i' */ + pmat[from*nparts+to] += (myrinfo->id-myedegrees[k].ed); + pmat[to*nparts+from] += (myrinfo->id-myedegrees[k].ed); + if (pmat[from*nparts+to] == 0) + ndoms[from]--; + if (pmat[to*nparts+from] == 0) + ndoms[to]--; + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + /* Update pmat to reflect the move of 'i' for domains other than 'from' and 'to' */ + if (me != from && me != to) { + pmat[me*nparts+from] -= adjwgt[j]; + pmat[from*nparts+me] -= adjwgt[j]; + if (pmat[me*nparts+from] == 0) + ndoms[me]--; + if (pmat[from*nparts+me] == 0) + ndoms[from]--; + + if (pmat[me*nparts+to] == 0) + ndoms[me]++; + if (pmat[to*nparts+me] == 0) + ndoms[to]++; + + pmat[me*nparts+to] += adjwgt[j]; + pmat[to*nparts+me] += adjwgt[j]; + } + + ASSERT(CheckRInfo(myrinfo)); + } + + ASSERT(CheckRInfo(graph->rinfo+i)); + } + + graph->nbnd = nbnd; + +} + + + + +/************************************************************************* +* This function finds all the connected components induced by the +* partitioning vector in wgraph->where and tries to push them around to +* remove some of them +**************************************************************************/ +void EliminateComponents(CtrlType *ctrl, GraphType *graph, int nparts, float *tpwgts, float ubfactor) +{ + int i, ii, j, jj, k, me, nvtxs, tvwgt, first, last, nleft, ncmps, cwgt, other, target, deltawgt; + idxtype *xadj, *adjncy, *vwgt, *adjwgt, *where, *pwgts, *maxpwgt; + idxtype *cpvec, *touched, *perm, *todo, *cind, *cptr, *npcmps; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vwgt = graph->vwgt; + adjwgt = graph->adjwgt; + + where = graph->where; + pwgts = graph->pwgts; + + touched = idxset(nvtxs, 0, idxwspacemalloc(ctrl, nvtxs)); + cptr = idxwspacemalloc(ctrl, nvtxs+1); + cind = idxwspacemalloc(ctrl, nvtxs); + perm = idxwspacemalloc(ctrl, nvtxs); + todo = idxwspacemalloc(ctrl, nvtxs); + maxpwgt = idxwspacemalloc(ctrl, nparts); + cpvec = idxwspacemalloc(ctrl, nparts); + npcmps = idxset(nparts, 0, idxwspacemalloc(ctrl, nparts)); + + for (i=0; i 0) { + if (first == last) { /* Find another starting vertex */ + cptr[++ncmps] = first; + ASSERT(touched[todo[0]] == 0); + i = todo[0]; + cind[last++] = i; + touched[i] = 1; + me = where[i]; + npcmps[me]++; + } + + i = cind[first++]; + k = perm[i]; + j = todo[k] = todo[--nleft]; + perm[j] = k; + + for (j=xadj[i]; j nparts) { /* There are more components than processors */ + /* First determine the max allowed load imbalance */ + tvwgt = idxsum(nparts, pwgts); + for (i=0; i .30*pwgts[me]) + continue; /* Skip the component if it is over 30% of the weight */ + + /* Determine the connectivity */ + idxset(nparts, 0, cpvec); + for (j=cptr[i]; j 0 && (cwgt < deltawgt || pwgts[j] + cwgt < maxpwgt[j])) { + if (target == -1 || cpvec[target] < cpvec[j]) + target = j; + } + } + + /* printf("\tMoving it to %d [%d]\n", target, cpvec[target]);*/ + + if (target != -1) { + /* Assign all the vertices of 'me' to 'target' and update data structures */ + INC_DEC(pwgts[target], pwgts[me], cwgt); + npcmps[me]--; + + MoveGroup(ctrl, graph, nparts, target, i, cptr, cind); + } + } + + } + + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nparts); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs); + idxwspacefree(ctrl, nvtxs+1); + +} + + +/************************************************************************* +* This function moves a collection of vertices and updates their rinfo +**************************************************************************/ +void MoveGroup(CtrlType *ctrl, GraphType *graph, int nparts, int to, int gid, idxtype *ptr, idxtype *ind) +{ + int i, ii, iii, j, jj, k, l, nvtxs, nbnd, myndegrees; + int from, me; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where, *bndptr, *bndind; + EDegreeType *myedegrees; + RInfoType *myrinfo; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + bndptr = graph->bndptr; + bndind = graph->bndind; + + nbnd = graph->nbnd; + + for (iii=ptr[gid]; iiirinfo+i; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[i+1]-xadj[i]; + myrinfo->ndegrees = 0; + } + myedegrees = myrinfo->edegrees; + + /* find the location of 'to' in myrinfo or create it if it is not there */ + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) + break; + } + if (k == myrinfo->ndegrees) { + myedegrees[k].pid = to; + myedegrees[k].ed = 0; + myrinfo->ndegrees++; + } + + graph->mincut -= myedegrees[k].ed-myrinfo->id; + + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = to; + myrinfo->ed += myrinfo->id-myedegrees[k].ed; + SWAP(myrinfo->id, myedegrees[k].ed, j); + if (myedegrees[k].ed == 0) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].pid = from; + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[i] != -1) + BNDDelete(nbnd, bndind, bndptr, i); + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jrinfo+ii; + if (myrinfo->edegrees == NULL) { + myrinfo->edegrees = ctrl->wspace.edegrees+ctrl->wspace.cdegree; + ctrl->wspace.cdegree += xadj[ii+1]-xadj[ii]; + } + myedegrees = myrinfo->edegrees; + + ASSERT(CheckRInfo(myrinfo)); + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id >= 0 && bndptr[ii] == -1) + BNDInsert(nbnd, bndind, bndptr, ii); + } + else if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + + if (myrinfo->ed-myrinfo->id < 0 && bndptr[ii] != -1) + BNDDelete(nbnd, bndind, bndptr, ii); + } + + /* Remove contribution from the .ed of 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == from) { + if (myedegrees[k].ed == adjwgt[j]) + myedegrees[k] = myedegrees[--myrinfo->ndegrees]; + else + myedegrees[k].ed -= adjwgt[j]; + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (myedegrees[k].pid == to) { + myedegrees[k].ed += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + myedegrees[myrinfo->ndegrees].pid = to; + myedegrees[myrinfo->ndegrees++].ed = adjwgt[j]; + } + } + + ASSERT(CheckRInfo(myrinfo)); + } + + ASSERT(CheckRInfo(graph->rinfo+i)); + } + + graph->nbnd = nbnd; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/timing.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/timing.c new file mode 100644 index 0000000..a9d0910 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/timing.c @@ -0,0 +1,74 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * timing.c + * + * This file contains routines that deal with timing Metis + * + * Started 7/24/97 + * George + * + * $Id: timing.c,v 1.1 2003/07/16 15:55:20 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function clears the timers +**************************************************************************/ +void InitTimers(CtrlType *ctrl) +{ + cleartimer(ctrl->TotalTmr); + cleartimer(ctrl->InitPartTmr); + cleartimer(ctrl->MatchTmr); + cleartimer(ctrl->ContractTmr); + cleartimer(ctrl->CoarsenTmr); + cleartimer(ctrl->UncoarsenTmr); + cleartimer(ctrl->RefTmr); + cleartimer(ctrl->ProjectTmr); + cleartimer(ctrl->SplitTmr); + cleartimer(ctrl->SepTmr); + cleartimer(ctrl->AuxTmr1); + cleartimer(ctrl->AuxTmr2); + cleartimer(ctrl->AuxTmr3); + cleartimer(ctrl->AuxTmr4); + cleartimer(ctrl->AuxTmr5); + cleartimer(ctrl->AuxTmr6); +} + + + +/************************************************************************* +* This function prints the various timers +**************************************************************************/ +void PrintTimers(CtrlType *ctrl) +{ + printf("\nTiming Information -------------------------------------------------"); + printf("\n Multilevel: \t\t %7.3f", gettimer(ctrl->TotalTmr)); + printf("\n Coarsening: \t\t %7.3f", gettimer(ctrl->CoarsenTmr)); + printf("\n Matching: \t\t\t %7.3f", gettimer(ctrl->MatchTmr)); + printf("\n Contract: \t\t\t %7.3f", gettimer(ctrl->ContractTmr)); + printf("\n Initial Partition: \t %7.3f", gettimer(ctrl->InitPartTmr)); + printf("\n Construct Separator: \t %7.3f", gettimer(ctrl->SepTmr)); + printf("\n Uncoarsening: \t\t %7.3f", gettimer(ctrl->UncoarsenTmr)); + printf("\n Refinement: \t\t\t %7.3f", gettimer(ctrl->RefTmr)); + printf("\n Projection: \t\t\t %7.3f", gettimer(ctrl->ProjectTmr)); + printf("\n Splitting: \t\t %7.3f", gettimer(ctrl->SplitTmr)); + printf("\n AUX1: \t\t %7.3f", gettimer(ctrl->AuxTmr1)); + printf("\n AUX2: \t\t %7.3f", gettimer(ctrl->AuxTmr2)); + printf("\n AUX3: \t\t %7.3f", gettimer(ctrl->AuxTmr3)); + printf("\n********************************************************************\n"); +} + + +/************************************************************************* +* This function returns the seconds +**************************************************************************/ +double seconds(void) +{ + return((double) clock()/CLOCKS_PER_SEC); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/util.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/util.c new file mode 100644 index 0000000..5d2e739 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/METISLib/util.c @@ -0,0 +1,511 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * util.c + * + * This function contains various utility routines + * + * Started 9/28/95 + * George + * + * $Id: util.c,v 1.2 2003/07/21 18:53:41 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function prints an error message and exits +**************************************************************************/ +void errexit(char *f_str,...) +{ + va_list argp; + char out1[256], out2[256]; + + va_start(argp, f_str); + vsprintf(out1, f_str, argp); + va_end(argp); + + sprintf(out2, "Error! %s", out1); + + fprintf(stdout, out2); + fflush(stdout); + + abort(); +} + + + +#ifndef DMALLOC +/************************************************************************* +* The following function allocates an array of integers +**************************************************************************/ +int *imalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (int *)GKmalloc(sizeof(int)*n, msg); +} + + +/************************************************************************* +* The following function allocates an array of integers +**************************************************************************/ +idxtype *idxmalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (idxtype *)GKmalloc(sizeof(idxtype)*n, msg); +} + + +/************************************************************************* +* The following function allocates an array of float +**************************************************************************/ +float *fmalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (float *)GKmalloc(sizeof(float)*n, msg); +} + + +/************************************************************************* +* The follwoing function allocates an array of integers +**************************************************************************/ +int *ismalloc(int n, int ival, char *msg) +{ + if (n == 0) + return NULL; + + return iset(n, ival, (int *)GKmalloc(sizeof(int)*n, msg)); +} + + + +/************************************************************************* +* The follwoing function allocates an array of integers +**************************************************************************/ +idxtype *idxsmalloc(int n, idxtype ival, char *msg) +{ + if (n == 0) + return NULL; + + return idxset(n, ival, (idxtype *)GKmalloc(sizeof(idxtype)*n, msg)); +} + + +/************************************************************************* +* This function is my wrapper around malloc +**************************************************************************/ +void *GKmalloc(int nbytes, char *msg) +{ + void *ptr; + + if (nbytes == 0) + return NULL; + + ptr = (void *)malloc(nbytes); + if (ptr == NULL) + errexit("***Memory allocation failed for %s. Requested size: %d bytes", msg, nbytes); + + return ptr; +} +#endif + +/************************************************************************* +* This function is my wrapper around free, allows multiple pointers +**************************************************************************/ +void GKfree(void **ptr1,...) +{ + va_list plist; + void **ptr; + + if (*ptr1 != NULL) + free(*ptr1); + *ptr1 = NULL; + + va_start(plist, ptr1); + + /* while ((int)(ptr = va_arg(plist, void **)) != -1) { */ + while ((ptr = va_arg(plist, void **)) != LTERM) { + if (*ptr != NULL) + free(*ptr); + *ptr = NULL; + } + + va_end(plist); +} + + +/************************************************************************* +* These functions set the values of a vector +**************************************************************************/ +int *iset(int n, int val, int *x) +{ + int i; + + for (i=0; i x[max] ? i : max); + + return max; +} + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int idxamax(int n, idxtype *x) +{ + int i, max=0; + + for (i=1; i x[max] ? i : max); + + return max; +} + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int idxamax_strd(int n, idxtype *x, int incx) +{ + int i, max=0; + + n *= incx; + for (i=incx; i x[max] ? i : max); + + return max/incx; +} + + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int samax(int n, float *x) +{ + int i, max=0; + + for (i=1; i x[max] ? i : max); + + return max; +} + +/************************************************************************* +* These functions return the index of the almost maximum element in a vector +**************************************************************************/ +int samax2(int n, float *x) +{ + int i, max1, max2; + + if (x[0] > x[1]) { + max1 = 0; + max2 = 1; + } + else { + max1 = 1; + max2 = 0; + } + + for (i=2; i x[max1]) { + max2 = max1; + max1 = i; + } + else if (x[i] > x[max2]) + max2 = i; + } + + return max2; +} + + +/************************************************************************* +* These functions return the index of the minimum element in a vector +**************************************************************************/ +int idxamin(int n, idxtype *x) +{ + int i, min=0; + + for (i=1; i=0; n--) + y[n] += x[n]; +} + + +/************************************************************************* +* This function sums the entries in an array +**************************************************************************/ +int charsum(int n, char *x) +{ + int i, sum = 0; + + for (i=0; i>1); + return (a > 1 ? 0 : 1); +} + + +/************************************************************************* +* This function initializes the random number generator +**************************************************************************/ +void InitRandom(int seed) +{ + if (seed == -1) + srand(4321); + else + srand(seed); +} + +/************************************************************************* +* This function returns the log2(x) +**************************************************************************/ +int log2Int(int a) +{ + int i; + + for (i=1; a > 1; i++, a = a>>1); + return i-1; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile new file mode 100644 index 0000000..2d53371 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile @@ -0,0 +1,13 @@ + + +default: + (cd METISLib ; make ) + (cd ParMETISLib ; make ) + (cd Programs ; make ) + +clean: + (cd METISLib ; make realclean ) + (cd ParMETISLib ; make realclean ) + (cd Programs ; make realclean ) + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.in b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.in new file mode 100644 index 0000000..af82bb1 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.in @@ -0,0 +1,32 @@ + +# Which compiler to use +CC = mpicc + + +# What optimization level to use +OPTFLAGS = -O3 + +# Include directories for the compiler +INCDIR = -I/opt/local/include -I/usr/include/malloc + +# What options to be used by the compiler +COPTIONS = + +# Which loader to use +LD = mpicc + +# In which directories to look for any additional libraries +LIBDIR = -L/usr/lib64 -L/usr/lib64/mpi/gcc/openmpi/lib64/ + +# What additional libraries to link the programs with (eg., -lmpi) +#XTRALIBS = -lefence +#XTRALIBS = -ldmalloc + +# What archiving to use +AR = ar rv + +# What to use for indexing the archive +#RANLIB = ranlib +RANLIB = ar -ts + +VERNUM = diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.osx b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.osx new file mode 100644 index 0000000..a8a3172 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.osx @@ -0,0 +1,32 @@ + +# Which compiler to use +CC = mpicc + + +# What optimization level to use +OPTFLAGS = -g + +# Include directories for the compiler +INCDIR = -I/opt/local/include -I/usr/include/malloc + +# What options to be used by the compiler +COPTIONS = + +# Which loader to use +LD = mpicc + +# In which directories to look for any additional libraries +LIBDIR = -L/opt/local/lib -L/usr/lib + +# What additional libraries to link the programs with (eg., -lmpi) +#XTRALIBS = -lefence +#XTRALIBS = -ldmalloc + +# What archiving to use +AR = ar rv + +# What to use for indexing the archive +#RANLIB = ranlib +RANLIB = ar -ts + +VERNUM = diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.rtc b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.rtc new file mode 100644 index 0000000..a5626c2 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Makefile.rtc @@ -0,0 +1,33 @@ + +# Which compiler to use +CC = mpicc + + +# What optimization level to use +OPTFLAGS = -g + +# Include directories for the compiler +INCDIR = +# -I/opt/local/include -I/usr/include/malloc + +# What options to be used by the compiler +COPTIONS = + +# Which loader to use +LD = mpicc + +# In which directories to look for any additional libraries +LIBDIR = -L/opt/local/lib -L/usr/lib + +# What additional libraries to link the programs with (eg., -lmpi) +#XTRALIBS = -lefence +#XTRALIBS = -ldmalloc + +# What archiving to use +AR = ar rv + +# What to use for indexing the archive +#RANLIB = ranlib +RANLIB = ar -ts + +VERNUM = diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.pdf b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.pdf new file mode 100644 index 0000000..737e641 Binary files /dev/null and b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.pdf differ diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.ps b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.ps new file mode 100644 index 0000000..bfe57d8 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Manual/manual.ps @@ -0,0 +1,6812 @@ +%!PS-Adobe-2.0 +%%Creator: dvips(k) 5.86 Copyright 1999 Radical Eye Software +%%Title: manual.dvi +%%Pages: 29 +%%PageOrder: Ascend +%%BoundingBox: 0 0 612 792 +%%DocumentFonts: Helvetica-Bold MTSYN AvantGarde-Demi Helvetica +%%+ Times-Roman Times-Bold RMTMI Times-Italic Helvetica-Narrow-Bold +%%+ Helvetica-Narrow Times-BoldItalic Courier MTEX +%%EndComments +%DVIPSWebPage: (www.radicaleye.com) +%DVIPSCommandLine: dvips -o manual.ps manual +%DVIPSParameters: dpi=1200, compressed +%DVIPSSource: TeX output 2003.08.15:1401 +%%BeginProcSet: texc.pro +%! +/TeXDict 300 dict def TeXDict begin/N{def}def/B{bind def}N/S{exch}N/X{S +N}B/A{dup}B/TR{translate}N/isls false N/vsize 11 72 mul N/hsize 8.5 72 +mul N/landplus90{false}def/@rigin{isls{[0 landplus90{1 -1}{-1 1}ifelse 0 +0 0]concat}if 72 Resolution div 72 VResolution div neg scale isls{ +landplus90{VResolution 72 div vsize mul 0 exch}{Resolution -72 div hsize +mul 0}ifelse TR}if Resolution VResolution vsize -72 div 1 add mul TR[ +matrix currentmatrix{A A round sub abs 0.00001 lt{round}if}forall round +exch round exch]setmatrix}N/@landscape{/isls true N}B/@manualfeed{ +statusdict/manualfeed true put}B/@copies{/#copies X}B/FMat[1 0 0 -1 0 0] +N/FBB[0 0 0 0]N/nn 0 N/IEn 0 N/ctr 0 N/df-tail{/nn 8 dict N nn begin +/FontType 3 N/FontMatrix fntrx N/FontBBox FBB N string/base X array +/BitMaps X/BuildChar{CharBuilder}N/Encoding IEn N end A{/foo setfont}2 +array copy cvx N load 0 nn put/ctr 0 N[}B/sf 0 N/df{/sf 1 N/fntrx FMat N +df-tail}B/dfs{div/sf X/fntrx[sf 0 0 sf neg 0 0]N df-tail}B/E{pop nn A +definefont setfont}B/Cw{Cd A length 5 sub get}B/Ch{Cd A length 4 sub get +}B/Cx{128 Cd A length 3 sub get sub}B/Cy{Cd A length 2 sub get 127 sub} +B/Cdx{Cd A length 1 sub get}B/Ci{Cd A type/stringtype ne{ctr get/ctr ctr +1 add N}if}B/id 0 N/rw 0 N/rc 0 N/gp 0 N/cp 0 N/G 0 N/CharBuilder{save 3 +1 roll S A/base get 2 index get S/BitMaps get S get/Cd X pop/ctr 0 N Cdx +0 Cx Cy Ch sub Cx Cw add Cy setcachedevice Cw Ch true[1 0 0 -1 -.1 Cx +sub Cy .1 sub]/id Ci N/rw Cw 7 add 8 idiv string N/rc 0 N/gp 0 N/cp 0 N{ +rc 0 ne{rc 1 sub/rc X rw}{G}ifelse}imagemask restore}B/G{{id gp get/gp +gp 1 add N A 18 mod S 18 idiv pl S get exec}loop}B/adv{cp add/cp X}B +/chg{rw cp id gp 4 index getinterval putinterval A gp add/gp X adv}B/nd{ +/cp 0 N rw exit}B/lsh{rw cp 2 copy get A 0 eq{pop 1}{A 255 eq{pop 254}{ +A A add 255 and S 1 and or}ifelse}ifelse put 1 adv}B/rsh{rw cp 2 copy +get A 0 eq{pop 128}{A 255 eq{pop 127}{A 2 idiv S 128 and or}ifelse} +ifelse put 1 adv}B/clr{rw cp 2 index string putinterval adv}B/set{rw cp +fillstr 0 4 index getinterval putinterval adv}B/fillstr 18 string 0 1 17 +{2 copy 255 put pop}for N/pl[{adv 1 chg}{adv 1 chg nd}{1 add chg}{1 add +chg nd}{adv lsh}{adv lsh nd}{adv rsh}{adv rsh nd}{1 add adv}{/rc X nd}{ +1 add set}{1 add clr}{adv 2 chg}{adv 2 chg nd}{pop nd}]A{bind pop} +forall N/D{/cc X A type/stringtype ne{]}if nn/base get cc ctr put nn +/BitMaps get S ctr S sf 1 ne{A A length 1 sub A 2 index S get sf div put +}if put/ctr ctr 1 add N}B/I{cc 1 add D}B/bop{userdict/bop-hook known{ +bop-hook}if/SI save N @rigin 0 0 moveto/V matrix currentmatrix A 1 get A +mul exch 0 get A mul add .99 lt{/QV}{/RV}ifelse load def pop pop}N/eop{ +SI restore userdict/eop-hook known{eop-hook}if showpage}N/@start{ +userdict/start-hook known{start-hook}if pop/VResolution X/Resolution X +1000 div/DVImag X/IEn 256 array N 2 string 0 1 255{IEn S A 360 add 36 4 +index cvrs cvn put}for pop 65781.76 div/vsize X 65781.76 div/hsize X}N +/p{show}N/RMat[1 0 0 -1 0 0]N/BDot 260 string N/Rx 0 N/Ry 0 N/V{}B/RV/v{ +/Ry X/Rx X V}B statusdict begin/product where{pop false[(Display)(NeXT) +(LaserWriter 16/600)]{A length product length le{A length product exch 0 +exch getinterval eq{pop true exit}if}{pop}ifelse}forall}{false}ifelse +end{{gsave TR -.1 .1 TR 1 1 scale Rx Ry false RMat{BDot}imagemask +grestore}}{{gsave TR -.1 .1 TR Rx Ry scale 1 1 false RMat{BDot} +imagemask grestore}}ifelse B/QV{gsave newpath transform round exch round +exch itransform moveto Rx 0 rlineto 0 Ry neg rlineto Rx neg 0 rlineto +fill grestore}B/a{moveto}B/delta 0 N/tail{A/delta X 0 rmoveto}B/M{S p +delta add tail}B/b{S p tail}B/c{-4 M}B/d{-3 M}B/e{-2 M}B/f{-1 M}B/g{0 M} +B/h{1 M}B/i{2 M}B/j{3 M}B/k{4 M}B/w{0 rmoveto}B/l{p -4 w}B/m{p -3 w}B/n{ +p -2 w}B/o{p -1 w}B/q{p 1 w}B/r{p 2 w}B/s{p 3 w}B/t{p 4 w}B/x{0 S +rmoveto}B/y{3 2 roll p a}B/bos{/SS save N}B/eos{SS restore}B end + +%%EndProcSet +%%BeginProcSet: psfrag.pro +%% +%% This is file `psfrag.pro', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% psfrag.dtx (with options: `filepro') +%% +%% Copyright (c) 1996 Craig Barratt, Michael C. Grant, and David Carlisle. +%% All rights reserved. +%% +%% This file is part of the PSfrag package. +%% +userdict begin +/PSfragLib 90 dict def +/PSfragDict 6 dict def +/PSfrag { PSfragLib begin load exec end } bind def +end +PSfragLib begin +/RO /readonly load def +/CP /currentpoint load def +/CM /currentmatrix load def +/B { bind RO def } bind def +/X { exch def } B +/MD { { X } forall } B +/OE { end exec PSfragLib begin } B +/S false def +/tstr 8 string def +/islev2 { languagelevel } stopped { false } { 2 ge } ifelse def +[ /sM /tM /srcM /dstM /dM /idM /srcFM /dstFM ] { matrix def } forall +sM currentmatrix RO pop +dM defaultmatrix RO idM invertmatrix RO pop +srcFM identmatrix pop +/Hide { gsave { CP } stopped not newpath clip { moveto } if } B +/Unhide { { CP } stopped not grestore { moveto } if } B +/setrepl islev2 {{ /glob currentglobal def true setglobal array astore + globaldict exch /PSfrags exch put glob setglobal }} + {{ array astore /PSfrags X }} ifelse B +/getrepl islev2 {{ globaldict /PSfrags get aload length }} + {{ PSfrags aload length }} ifelse B +/convert { + /src X src length string + /c 0 def src length { + dup c src c get dup 32 lt { pop 32 } if put /c c 1 add def + } repeat +} B +/Begin { + /saver save def + srcFM exch 3 exch put + 0 ne /debugMode X 0 setrepl + dup /S exch dict def { S 3 1 roll exch convert exch put } repeat + srcM CM dup invertmatrix pop + mark { currentdict { end } stopped { pop exit } if } loop + PSfragDict counttomark { begin } repeat pop +} B +/End { + mark { currentdict end dup PSfragDict eq { pop exit } if } loop + counttomark { begin } repeat pop + getrepl saver restore + 7 idiv dup /S exch dict def { + 6 array astore /mtrx X tstr cvs /K X + S K [ S K known { S K get aload pop } if mtrx ] put + } repeat +} B +/Place { + tstr cvs /K X + S K known { + bind /proc X tM CM pop + CP /cY X /cX X + 0 0 transform idtransform neg /aY X neg /aX X + S K get dup length /maxiter X + /iter 1 def { + iter maxiter ne { /saver save def } if + tM setmatrix aX aY translate + [ exch aload pop idtransform ] concat + cX neg cY neg translate cX cY moveto + /proc load OE + iter maxiter ne { saver restore /iter iter 1 add def } if + } forall + /noXY { CP /cY X /cX X } stopped def + tM setmatrix noXY { newpath } { cX cY moveto } ifelse + } { + Hide OE Unhide + } ifelse +} B +/normalize { + 2 index dup mul 2 index dup mul add sqrt div + dup 4 -1 roll exch mul 3 1 roll mul +} B +/replace { + aload pop MD + CP /bY X /lX X gsave sM setmatrix + str stringwidth abs exch abs add dup 0 eq + { pop } { 360 exch div dup scale } ifelse + lX neg bY neg translate newpath lX bY moveto + str { /ch X ( ) dup 0 ch put false charpath ch Kproc } forall + flattenpath pathbbox [ /uY /uX /lY /lX ] MD + CP grestore moveto + currentfont /FontMatrix get dstFM copy dup + 0 get 0 lt { uX lX /uX X /lX X } if + 3 get 0 lt { uY lY /uY X /lY X } if + /cX uX lX add 0.5 mul def + /cY uY lY add 0.5 mul def + debugMode { gsave 0 setgray 1 setlinewidth + lX lY moveto lX uY lineto uX uY lineto uX lY lineto closepath + lX bY moveto uX bY lineto lX cY moveto uX cY lineto + cX lY moveto cX uY lineto stroke + grestore } if + dstFM dup invertmatrix dstM CM srcM + 2 { dstM concatmatrix } repeat pop + getrepl /temp X + S str convert get { + aload pop [ /rot /scl /loc /K ] MD + /aX cX def /aY cY def + loc { + dup 66 eq { /aY bY def } { % B + dup 98 eq { /aY lY def } { % b + dup 108 eq { /aX lX def } { % l + dup 114 eq { /aX uX def } { % r + dup 116 eq { /aY uY def } % t + if } ifelse } ifelse } ifelse } ifelse pop + } forall + K srcFM rot tM rotate dstM + 2 { tM concatmatrix } repeat aload pop pop pop + 2 { scl normalize 4 2 roll } repeat + aX aY transform + /temp temp 7 add def + } forall + temp setrepl +} B +/Rif { + S 3 index convert known { pop replace } { exch pop OE } ifelse +} B +/XA { bind [ /Kproc /str } B /XC { ] 2 array astore def } B +/xs { pop } XA XC +/xks { /kern load OE } XA /kern XC +/xas { pop ax ay rmoveto } XA /ay /ax XC +/xws { c eq { cx cy rmoveto } if } XA /c /cy /cx XC +/xaws { ax ay rmoveto c eq { cx cy rmoveto } if } + XA /ay /ax /c /cy /cx XC +/raws { xaws { awidthshow } Rif } B +/rws { xws { widthshow } Rif } B +/rks { xks { kshow } Rif } B +/ras { xas { ashow } Rif } B +/rs { xs { show } Rif } B +/rrs { getrepl dup 2 add -1 roll //restore exec setrepl } B +PSfragDict begin +islev2 not { /restore { /rrs PSfrag } B } if +/show { /rs PSfrag } B +/kshow { /rks PSfrag } B +/ashow { /ras PSfrag } B +/widthshow { /rws PSfrag } B +/awidthshow { /raws PSfrag } B +end PSfragDict RO pop +end + +%%EndProcSet +%%BeginProcSet: 8r.enc +% @@psencodingfile@{ +% author = "S. Rahtz, P. MacKay, Alan Jeffrey, B. Horn, K. Berry", +% version = "0.6", +% date = "1 July 1998", +% filename = "8r.enc", +% email = "tex-fonts@@tug.org", +% docstring = "Encoding for TrueType or Type 1 fonts +% to be used with TeX." +% @} +% +% Idea is to have all the characters normally included in Type 1 fonts +% available for typesetting. This is effectively the characters in Adobe +% Standard Encoding + ISO Latin 1 + extra characters from Lucida. +% +% Character code assignments were made as follows: +% +% (1) the Windows ANSI characters are almost all in their Windows ANSI +% positions, because some Windows users cannot easily reencode the +% fonts, and it makes no difference on other systems. The only Windows +% ANSI characters not available are those that make no sense for +% typesetting -- rubout (127 decimal), nobreakspace (160), softhyphen +% (173). quotesingle and grave are moved just because it's such an +% irritation not having them in TeX positions. +% +% (2) Remaining characters are assigned arbitrarily to the lower part +% of the range, avoiding 0, 10 and 13 in case we meet dumb software. +% +% (3) Y&Y Lucida Bright includes some extra text characters; in the +% hopes that other PostScript fonts, perhaps created for public +% consumption, will include them, they are included starting at 0x12. +% +% (4) Remaining positions left undefined are for use in (hopefully) +% upward-compatible revisions, if someday more characters are generally +% available. +% +% (5) hyphen appears twice for compatibility with both +% ASCII and Windows. +% +/TeXBase1Encoding [ +% 0x00 (encoded characters from Adobe Standard not in Windows 3.1) + /.notdef /dotaccent /fi /fl + /fraction /hungarumlaut /Lslash /lslash + /ogonek /ring /.notdef + /breve /minus /.notdef +% These are the only two remaining unencoded characters, so may as +% well include them. + /Zcaron /zcaron +% 0x10 + /caron /dotlessi +% (unusual TeX characters available in, e.g., Lucida Bright) + /dotlessj /ff /ffi /ffl + /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef + % very contentious; it's so painful not having quoteleft and quoteright + % at 96 and 145 that we move the things normally found there to here. + /grave /quotesingle +% 0x20 (ASCII begins) + /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright + /parenleft /parenright /asterisk /plus /comma /hyphen /period /slash +% 0x30 + /zero /one /two /three /four /five /six /seven + /eight /nine /colon /semicolon /less /equal /greater /question +% 0x40 + /at /A /B /C /D /E /F /G /H /I /J /K /L /M /N /O +% 0x50 + /P /Q /R /S /T /U /V /W + /X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore +% 0x60 + /quoteleft /a /b /c /d /e /f /g /h /i /j /k /l /m /n /o +% 0x70 + /p /q /r /s /t /u /v /w + /x /y /z /braceleft /bar /braceright /asciitilde + /.notdef % rubout; ASCII ends +% 0x80 + /.notdef /.notdef /quotesinglbase /florin + /quotedblbase /ellipsis /dagger /daggerdbl + /circumflex /perthousand /Scaron /guilsinglleft + /OE /.notdef /.notdef /.notdef +% 0x90 + /.notdef /.notdef /.notdef /quotedblleft + /quotedblright /bullet /endash /emdash + /tilde /trademark /scaron /guilsinglright + /oe /.notdef /.notdef /Ydieresis +% 0xA0 + /.notdef % nobreakspace + /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot + /hyphen % Y&Y (also at 45); Windows' softhyphen + /registered + /macron +% 0xD0 + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% 0xC0 + /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis +% 0xD0 + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% 0xE0 + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis +% 0xF0 + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +] def + +%%EndProcSet +%%BeginProcSet: texps.pro +%! +TeXDict begin/rf{findfont dup length 1 add dict begin{1 index/FID ne 2 +index/UniqueID ne and{def}{pop pop}ifelse}forall[1 index 0 6 -1 roll +exec 0 exch 5 -1 roll VResolution Resolution div mul neg 0 0]/Metrics +exch def dict begin Encoding{exch dup type/integertype ne{pop pop 1 sub +dup 0 le{pop}{[}ifelse}{FontMatrix 0 get div Metrics 0 get div def} +ifelse}forall Metrics/Metrics currentdict end def[2 index currentdict +end definefont 3 -1 roll makefont/setfont cvx]cvx def}def/ObliqueSlant{ +dup sin S cos div neg}B/SlantFont{4 index mul add}def/ExtendFont{3 -1 +roll mul exch}def/ReEncodeFont{CharStrings rcheck{/Encoding false def +dup[exch{dup CharStrings exch known not{pop/.notdef/Encoding true def} +if}forall Encoding{]exch pop}{cleartomark}ifelse}if/Encoding exch def} +def end + +%%EndProcSet +%%BeginProcSet: special.pro +%! +TeXDict begin/SDict 200 dict N SDict begin/@SpecialDefaults{/hs 612 N +/vs 792 N/ho 0 N/vo 0 N/hsc 1 N/vsc 1 N/ang 0 N/CLIP 0 N/rwiSeen false N +/rhiSeen false N/letter{}N/note{}N/a4{}N/legal{}N}B/@scaleunit 100 N +/@hscale{@scaleunit div/hsc X}B/@vscale{@scaleunit div/vsc X}B/@hsize{ +/hs X/CLIP 1 N}B/@vsize{/vs X/CLIP 1 N}B/@clip{/CLIP 2 N}B/@hoffset{/ho +X}B/@voffset{/vo X}B/@angle{/ang X}B/@rwi{10 div/rwi X/rwiSeen true N}B +/@rhi{10 div/rhi X/rhiSeen true N}B/@llx{/llx X}B/@lly{/lly X}B/@urx{ +/urx X}B/@ury{/ury X}B/magscale true def end/@MacSetUp{userdict/md known +{userdict/md get type/dicttype eq{userdict begin md length 10 add md +maxlength ge{/md md dup length 20 add dict copy def}if end md begin +/letter{}N/note{}N/legal{}N/od{txpose 1 0 mtx defaultmatrix dtransform S +atan/pa X newpath clippath mark{transform{itransform moveto}}{transform{ +itransform lineto}}{6 -2 roll transform 6 -2 roll transform 6 -2 roll +transform{itransform 6 2 roll itransform 6 2 roll itransform 6 2 roll +curveto}}{{closepath}}pathforall newpath counttomark array astore/gc xdf +pop ct 39 0 put 10 fz 0 fs 2 F/|______Courier fnt invertflag{PaintBlack} +if}N/txpose{pxs pys scale ppr aload pop por{noflips{pop S neg S TR pop 1 +-1 scale}if xflip yflip and{pop S neg S TR 180 rotate 1 -1 scale ppr 3 +get ppr 1 get neg sub neg ppr 2 get ppr 0 get neg sub neg TR}if xflip +yflip not and{pop S neg S TR pop 180 rotate ppr 3 get ppr 1 get neg sub +neg 0 TR}if yflip xflip not and{ppr 1 get neg ppr 0 get neg TR}if}{ +noflips{TR pop pop 270 rotate 1 -1 scale}if xflip yflip and{TR pop pop +90 rotate 1 -1 scale ppr 3 get ppr 1 get neg sub neg ppr 2 get ppr 0 get +neg sub neg TR}if xflip yflip not and{TR pop pop 90 rotate ppr 3 get ppr +1 get neg sub neg 0 TR}if yflip xflip not and{TR pop pop 270 rotate ppr +2 get ppr 0 get neg sub neg 0 S TR}if}ifelse scaleby96{ppr aload pop 4 +-1 roll add 2 div 3 1 roll add 2 div 2 copy TR .96 dup scale neg S neg S +TR}if}N/cp{pop pop showpage pm restore}N end}if}if}N/normalscale{ +Resolution 72 div VResolution 72 div neg scale magscale{DVImag dup scale +}if 0 setgray}N/psfts{S 65781.76 div N}N/startTexFig{/psf$SavedState +save N userdict maxlength dict begin/magscale true def normalscale +currentpoint TR/psf$ury psfts/psf$urx psfts/psf$lly psfts/psf$llx psfts +/psf$y psfts/psf$x psfts currentpoint/psf$cy X/psf$cx X/psf$sx psf$x +psf$urx psf$llx sub div N/psf$sy psf$y psf$ury psf$lly sub div N psf$sx +psf$sy scale psf$cx psf$sx div psf$llx sub psf$cy psf$sy div psf$ury sub +TR/showpage{}N/erasepage{}N/copypage{}N/p 3 def @MacSetUp}N/doclip{ +psf$llx psf$lly psf$urx psf$ury currentpoint 6 2 roll newpath 4 copy 4 2 +roll moveto 6 -1 roll S lineto S lineto S lineto closepath clip newpath +moveto}N/endTexFig{end psf$SavedState restore}N/@beginspecial{SDict +begin/SpecialSave save N gsave normalscale currentpoint TR +@SpecialDefaults count/ocount X/dcount countdictstack N}N/@setspecial{ +CLIP 1 eq{newpath 0 0 moveto hs 0 rlineto 0 vs rlineto hs neg 0 rlineto +closepath clip}if ho vo TR hsc vsc scale ang rotate rwiSeen{rwi urx llx +sub div rhiSeen{rhi ury lly sub div}{dup}ifelse scale llx neg lly neg TR +}{rhiSeen{rhi ury lly sub div dup scale llx neg lly neg TR}if}ifelse +CLIP 2 eq{newpath llx lly moveto urx lly lineto urx ury lineto llx ury +lineto closepath clip}if/showpage{}N/erasepage{}N/copypage{}N newpath}N +/@endspecial{count ocount sub{pop}repeat countdictstack dcount sub{end} +repeat grestore SpecialSave restore end}N/@defspecial{SDict begin}N +/@fedspecial{end}B/li{lineto}B/rl{rlineto}B/rc{rcurveto}B/np{/SaveX +currentpoint/SaveY X N 1 setlinecap newpath}N/st{stroke SaveX SaveY +moveto}N/fil{fill SaveX SaveY moveto}N/ellipse{/endangle X/startangle X +/yrad X/xrad X/savematrix matrix currentmatrix N TR xrad yrad scale 0 0 +1 startangle endangle arc savematrix setmatrix}N end + +%%EndProcSet +TeXDict begin @defspecial + + TeXDict begin /box{newpath 2 copy moveto 3 copy pop exch lineto 4 +copy pop pop lineto 4 copy exch pop exch pop lineto closepath } bind +def /min{ 2 copy gt { exch } if pop } bind def/max{ 2 copy lt { exch +} if pop } bind def/roundedbox{/radius exch store 3 2 roll 2 copy min +radius sub /miny exch store max radius add /maxy exch store 2 copy +min radius sub /minx exch store max radius add /maxx exch store newpath +minx radius add miny moveto maxx miny maxx maxy radius arcto maxx maxy +minx maxy radius arcto minx maxy minx miny radius arcto minx miny maxx +miny radius arcto 16 {pop} repeat closepath }bind def /rectcartouche{box +gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def /cartouche{roundedbox +gsave .95 setgray fill grestore 1 setlinewidth stroke }bind def end + +@fedspecial end +%%BeginFont: RMTMI +%!PS-AdobeFont-1.1: RMTMI 1.1 +%%CreationDate: 1993 May 10 16:52:31 + +% Copyright (c) 1992, 1993 The TeXplorators Corporation +% Hinting Copyright (c) 1992, 1993 Y&Y, Inc. + +11 dict begin +/FontInfo 9 dict dup begin +/version (1.1) readonly def +/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def +/FullName (RMTMI) readonly def +/FamilyName (MathTime) readonly def +/Weight (Medium) readonly def +/ItalicAngle -14.036 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /RMTMI def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 46 /parenleft put +dup 47 /parenright put +dup 58 /period put +dup 59 /comma put +dup 61 /slash put +dup 118 /v put +readonly def +/FontBBox{0 -213 987 680}readonly def +/UniqueXX 5018946 def +currentdict end +currentfile eexec +80347982ab3942d930e069a70d0d48311d70c1e2528f01045f8caec9829f31d6 +48c8d0a29ea851af41c327a0d569abaafe5afe94dad818c312d3cee72f1acea0 +b701b6a5608521a2866790bdd5776d6cd0c7d971b9a48b96aa970dcbb8b76edc +b90da356dc2529b665eb4bb80ac4f5b0f4c0ed76861e399638ad3db1be4759c7 +8d4f2e81a2ff688d366b91d729d63ab5fc9556fe10a07b81904d879a7446da82 +dc107ff41b0e3b7c2245d57b2ee9bab31eccfe9b79e3ec32cb1f10c622f4bce1 +8df0e5c4b98ec714593d6f127c5cf6d719a79b83c627433d3aa39cb88ef85d27 +4184c4b4c46ca5b496f20460ed75ccfb3d66073b710cc1ad2f2bec4ac64065ed +5e03930ed9ec97810f36845dd5048d90d724a88fd3c814ce17c417c84ba45c43 +f5569a4d73739f71544ed91c657705e131f4d0c61752509fbe0212bde9c02a83 +3910dff28f7c53f64b032c8e3cd2ba95c22177c3e0532f8699d106f119b80549 +c45726d793b9aec38ff4c3120c259083fd13c644dea026e1e7c75dea2ec23419 +83aff4d712c27c024393022797db1500c6543d620f20c9ce973ef7d917e7fb3e +6cfee0999e06c9dfff2d01bac5b3be0c47b2d5abc02e1f0f383588f430fa64bf +d5250e56da323c91f033c8f0f4e0f9cbb36eb8d4d25b127fda1bb032a7088cf6 +fb34b617290de038198297f2af323602e5e96d475e4678e129d88aa15d5ad9cb +58e244028cd8d9a8210fb1aecfc3f29299986c1df1cb3ffa0fc203626e8e2f6f +3a6ab198963acb2b528d6bc06687d59efddb9c88535c1c69da5d81812b911c5e +f9985179796d2b2e4e92beec47a4075e306c8d26431d8e0732768dff70ef2270 +d1fddddd4cca0f209ad05c9af2f26da7ca0acccdac0ea4f479b548c741193594 +d515f614bda3f394c77bd7296981ac947ca0d6d6ccafd9a05547b28f0ce449ff +bde2744249af134a1d3629edfec122c615e4a74067a7f8358519bfac0f31d1a4 +6d260a3db271750d02cd6a12d019ab6c1c2f9955ca205f12d8a03de3203bb5eb +869ed8b66b53d1c29eaa26b4d20f9460891b018031bf81eba788b77ccccc5ff9 +9acb5b025a4dcbafafc1b34bb2adbd17cdd741da586af1b784cf74cf88603b20 +d68afab47d21c1a0c6bee297777db1a8231237a40ec89aa97ce1c848c9da6804 +d3b98c11590b239616e0e6d668fc5b987075d77769eaf4877f1a359217b40731 +293574eae905bd7a5c46719ec7f8a97fac1c46dcd76b0344e8378fd61d02c990 +5b194613df280648e2f86ef15a2dd8e6bec1cac0d90b8302b2846127b2d50d8f +fb7d210c7826fde88f2d165fa6afd755db04910140e070126a663f3d57ea417e +d6d2128bf21a7cc2911f8bf0f2668eadbe8e042a1cdcea38c5c9a71226f6f4ed +bc85ddf8c25d80933a42f5f303e5495c247e973df20e2195b07b60657205de14 +9d86dbd56bb2594fea81688f21573a8210f6fbf48c82425bf58215b3d91d3255 +012f7b2bc17357bfb35cd40b0c1d5536cde7bd0b29dea7674b32bc83cb453bbf +76807cf4a5aeece57fae3d291ae50098b85e357e9606694fcfe15cc48406012b +f12efcea89892d1811b5ef93abad0e929160090fad55766535e605ecb8381777 +df5a2ac4a3e332a7e1b7ab9713a37619293bc7c8a69652ec4be93c6f786fab81 +e636cd8ad1959c266cb622f998c5c8762159cb792e123cb46042a84709054f39 +d5251483de5735331ab02cc31ad384dec4176d48661db17d104c4956474dce80 +2519c973688aa6609a0fcb3128bb928cb1e676def0e4ec52eb0ee05d55e6afa7 +fd22c8f9537de1f8f5fe275f190890ed4ee638b479a8727024d414971b191636 +744ae3a5022bca7b6b8f475aff1e4bb03ee9dbfefdd88aa2cad0d10339a42f6a +342fafa530f9707e723f7a2c90667b94f9764bf334eb294b35e3eef1c8410a28 +7e9cadcd03f3488f317d700b53c348e012ef4d3431b125aea4c7f00f79a3bd4a +d0edd781418b51543364a9e8b40a32b4554ddc0a7f2e1a48a682be1b990d6224 +651dd3dbdeede0555bf6cb4685bcb3b54b22f1d2f27d577f29188d708889f5cb +c45cab82180f3d7ff3a1fda6cd9776d22155e43a43c708cbd680a8e3880d74c1 +bf8db0b07dc626d744fd8b37050ee64faedb57746913c896e0abf7eadaf2c118 +bc1ee6cb292b41b403c365f6658d64c60e3494ab2ba9060425a72d27ca1fea5d +0fb89027036e31dfa311549ccfa914b87ebfea444a601d29276f6752eef4766a +4cf3bc60ccc488e457eb6cc458cde216dc0901e7ea735d9e57a83981fe52da47 +c17d764379cf63998c9ee47a80a87c9179a0238ad6ccb7521ab06487c7985f15 +70f2594db6b852d1ae2960f8d527b1e2f8f1bf54e9014712ad114db6c7844412 +823a8c57fa38ddcd8c6e34db04ded337c9b962ee864e2610ba2ee6fe644d239b +8e94fbc188cd16db10e20a9e93250acbec7756826ac93ff1df9308efd8507f05 +33327021fb1ef1ad82d501080e4f16b75c9b0d7d15cf75e51feb9ecd4a475e56 +51aa688761ace098dfcf96d604030f3428080cfa1efb5fcc97c750ebbe4ceeaf +969b0795eaff4e620dfb144780245a9fa0651eaf137f463bbbdd94fe0dcb754b +7d608d2ad9a92f329fb371ec0804de94c5d92e785a060c719d327a49b6210182 +2dad060c64e48259de0bbb77c269de5715ce9d8d85c6b6c1992f9a008b9c6012 +5f001f20735fa9d9343bc20b03fafb2a08e28d989df8f657071a81c14ffeb49c +dad0b4ddc301c096327836fb58ee41c0ad61e8aad9e0a6658f7f813de254e929 +4d0db0e46c07f6e9fbe9db98d48fdcc6e9c1c32dc043d28239e5b6f2ccff9cde +ec04dadcba1836fbe06cf3a1ba39504ece115764f78d0b8f812b9c0d03e4a2ea +663a4fd20ccc1c4c5465a76889eb987932462cf8cbff87ecc1c3004774f89f9f +f71e895d01a73866b9ae3d0d05776a488bd12a01c5f4c7813fceb413d1ba5f63 +26dc2121cd2fac85ffc91507 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark + +%%EndFont +%%BeginFont: MTEX +%!PS-AdobeFont-1.1: MTEX 1.1 +%%CreationDate: 1993 Jun 26 10:30:36 + +% Copyright (c) 1992, 1993 The TeXplorators Corporation +% Hinting Copyright (c) 1992, 1993 Y&Y, Inc. + +11 dict begin +/FontInfo 9 dict dup begin +/version (1.1) readonly def +/Notice (Copyright (C) 1992, 1993 The TeXplorators Corporation) readonly def +/FullName (MTEX) readonly def +/FamilyName (MathTime) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /MTEX def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 80 /summationtext put +readonly def +/FontBBox{-23 -2958 1456 766}readonly def +/UniqueXX 5018948 def +currentdict end +currentfile eexec +80347982ab3942d930e069a70d0d48311d70c1e2528f01045f8caec9829f31d6 +48c8d0a29ea851af41c327a0d569abaafe5afe94dad818c312d3cee72f1acea0 +b701b6a5608521a2866790bdd5776d6cd0c7d971b9a48b96aa970dcbb8b76edc +b90da356dc2529b665eb4bb80ac4f5b0f4c0ed76861e399638ad3db1be4759c7 +8d4f2e81a2ff688d366b91d729d63ab5fc9556fe10a07b81904d879a7446da82 +dc107ff41b0e3b7c2245d57b2ee9bab31eccfe9b79e3ec32cb1f10c622f4bce1 +8df0e5c4b98ec714593d6f127c5cf6d719a79b83c627433d3aa39cb88ef85d27 +4184c4b4c46ca5b496f20460ed75ccfb3d66073b710cc1ad2f2bec4ac64065ed +5e03930ed9ec97810f36845dd5048d90d724a88fd3c814ce17c417c84ba45c43 +f5569a4d73739f71544ed91c657705e131f4d0c61752509fbe0212bde9c02a83 +3910dff28f7c53f64b032c8e3cd2ba95c22177c3e0532f8699d106f119b80549 +c45726d793b9aec38ff4c3120c259083fd13c644dea026e1e7c75dea2ec23419 +83aff4d712c27c024393022797db1500c6543d620f20c9ce973ef7d917e7fb3e +6cfee0999e06c9dfff2d01bac5b3be0c47b2d5abc02e1f0f383588f430fa64bf +d5250e56da323c91f033c8f0f4e0f9cbb36eb8d4d25b127fda1bb032a7088cf6 +fb34b617290de038198297f2af323602e5e96d475e4678e129d88aa15d5ad9cb +58e244028cd8d9a8210fb1aecfc3f29299986c1df1cb3ffa0fc203626e8e2f6f +3a6ab198963acb2b528d6bc06687d59efddb9c88535c1c69da5d81812b911c5e +f9985179796d2b2e4e92beec47a4075e306c8d26431d8e0732768dff70ef2270 +d1fddddd4cca0f209ad05c9af2f26da7ca0accc0349d554800072fe70fe3f12f +846085405a3e13764f457e887846db5eca49493fb685acac9e0d4c5ca63c7b16 +408cb7eb5decb4429557acbe97a89d9360f0d29566678e6c2e3569923451905d +8951f729d6e4e166c0150cfade571c25f92820fc6fb202f2d010bdb81e8baa62 +32cd15f94af4804b08cddbc782c1295ed9d18025f1c453a678f58a7e1b7bcfba +4400dda52bd25ccaef380af4b5003dcc06f75960ac763ec42a6ef95eaf46f77b +3aa68bbc3c182d192d602a713f8082af7e531b1282e701d3a39904e4802c94b6 +df379cc5faf66b0fbc4e279ebe2154c755887098745ea0303640d9ecd80ad923 +deda40cca8136f760a6e4eaa342751fef587651a7c6394ed4fe12a07e33fcdc6 +15954ab2599f9a75ccf54e560b978add203d169ad883c855f40ec67c410bf468 +e7ad9a8fe58c601bf464797f492cb9354c0a21deb7e6e0b951770086d598fbd0 +138393a017903ac875192d5da1d671e70f91c6cd9722d168eebb3cffb58e5637 +3712ae6823a0b39fe863ce84e8a867c5d1f5611aefdf25d31c9896dcf5e320b0 +875dd95c3a3f8ba7a6331558180e833af7c1625d0a0efd6266b95ba0a2dc769e +694d43ab27088f81e8a7f25a9207efd5ab98f0390b28d219ac289fa217fa1e67 +d801778da34b6ca048034a044e83294061d64a98e7b5989ea55d9e4b046545c8 +41452c7e8f23ed381387e1ea4e2912922c12ecf8c2822605c9934c37fde6571c +287ae7d66b15afcac9e8a6b39c7b78c44630a58a2c75b90dda031bd6c638f8f2 +b8dfeb6d907570f17c05639011861348bfa5be91bf88b7f55b076e7b13da36d6 +edf2380bc2f78c7d0448611c015f938c51f03e600baf9474b670cc6dd9efe445 +69f2a13ce298af63e248e04bcf843a499cf72865e8e459c55ce949ba387e3931 +17ea030b510ae3abe57838cfd9280d2d51beaf22b4de8bc15d9d8715a0cf9c23 +cbb480ed646f36ffa612a82ad4ea8df8907af82d8d2a8e807dca8291b4c896b6 +929f19e14ef43c78734d823bdc212f879780e62b11b95205c8f19de83b297873 +7d0d7144430ebf265c93c7120ff9a762c2eec171a7ee5e3e19e82d43f9285a2c +4e51e2ed1ec7acb28fa010b27024cbf80c010d1ddcd9942413e033be71494e72 +67f05602dc769a9027fad4b026bf3d92f9fcf25c63ed663d7143a0c371376523 +6a919f21397e9b2e8bf7521e43683a15a1d942fb4d36d07e733db38079cd156d +e644c93c6628a5cbcab46d0a645484bf21aaf042be5f5b8e7e8294597bc5ab29 +478f4b931f7211 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark + +%%EndFont +%%BeginFont: MTSYN +%!PS-AdobeFont-1.1: MTSYN 1.000 +%%CreationDate: 1996 Aug 26 20:27:17 + +% MathTime fonts were designed by Michael Spivak. +% Copyright (c) 1996 Publish or Perish, Inc. +% Hinting Copyright (c) 1996 Y&Y, Inc. +% MathTime is a registered trademark of Publish or Perish, Inc. + +11 dict begin +/FontInfo 9 dict dup begin +/version (1.000) readonly def +/Notice (Copyright (c) 1992-1996 Publish or Perish and Y&Y, Inc.) readonly def +/FullName (MTSYN) readonly def +/FamilyName (MathTime) readonly def +/Weight (Medium) readonly def +/ItalicAngle 0 def +/isFixedPitch false def +/UnderlinePosition -100 def +/UnderlineThickness 50 def +end readonly def +/FontName /MTSYN def +/PaintType 0 def +/FontType 1 def +/FontMatrix [0.001 0 0 0.001 0 0] readonly def +/Encoding 256 array +0 1 255 {1 index exch /.notdef put} for +dup 0 /minus put +dup 2 /multiply put +dup 3 /asteriskmath put +dup 15 /bullet put +dup 67 /plus put +dup 68 /equal put +dup 102 /braceleft put +dup 103 /braceright put +readonly def +/FontBBox{0 -954 1043 900}readonly def +/UniqueID 5087393 def +currentdict end +currentfile eexec +80347982ab3942d930e069a70d0d48311e252234d51741e18db3a68e8ad10242 +29e5817a10e796a78d2c7f7c1f50961b9a57aa604c9f821dbf5a9295197bc666 +31678d7d2c7e1f8f2151ce0c29efce46270570f4301c5dad1b38884732e53dad +05dfc36b020e726ca575f71f04abf2b49e1f1d6d2a08a477658ca9a48f1c8cce +14382f0a42201de56e2821ee2b0e91a818b1b753d810ec2428dae5153b66af66 +a6cbcba4db2bf926e909644db41326e327493b2750168d128a100fe56c76b17c +16f9ce939588d19c6e9cda7cb062196e66e38e537670953934ffc63663c7146a +12277d8f7c13b563981d696e0abe4478eabeba753024ebdf3ee17f2613df08c9 +228159906a48ddeed6212332ef96023e5c73ea55aac6a2b938138ec26b4732c1 +1e8fed889257e9d4f2002935585d9aa2265929948e37bab7adf12f1a22b3c68d +09a6b6c4e14b1470ecf0874d92d964cfbb8e2a0e4cbd1a114cc05bbdee4699a5 +76ab8c0bd8499b166e9e60b21f45561279f6474bb497e3d55dd09a26264ffa6e +8d9f228e894c456756d321bb5d5932c5bbcd39eb95f5b7d4dc2da25d6773ea6b +f8b758972bef890ed520777e90b017bb4f0f1a7076da33c972773e8ecfdf76b3 +47fe529109a1ea0d91b80161c32e4dfb08ef07f23680182631baf1bea4a5b9e5 +05311402d9263290e3cf4409b44edfe28038a0f2101424a9aa4ce83a902faaa4 +ee6da88833898cd9efb74a321458332cc9a62c93501cd1eb799c6da44f94c61a +da58024d0ced31cd07ba36a70d986aaad1d3b9c04d6acba7ecae982a8712ba24 +b26bc4bf9b042c6fcc9bf7d3404804e72d2b93fd4f56771495070aa0fd181c35 +cc11cf251be8dea12600643f2b79d09aa1bcf2636f70edf1f7e0e434df83b888 +598ece0100492a48645305b4bb8bf16cc994abdaf88ee7ca62fa459e42158053 +1f5bdfd3bd83467260f184afa17abff39208581863acd6632867c05ec9c11a91 +0e396f09359713c5b37ae855d3a2ff8657fb89cad579eb1baa0979eb227202e4 +4306b7c89d6b32c41795f994b293a6baf7df640c3f68cba7674e695121892c8d +f86d2c12158d6628ba8643af6c51d423799d274aa5cbefb8ead46fe7e2ae9971 +84e8e036793b47aae8a8bfe6fe656b789c232f3761e296dcda097e85b8a63a6e +bb0c07a4c86cd4bdebb8cd50299e1efa106ecfbf361f5787095aaf4bfec3b442 +d91941d799c1260629f7829354981d7c999bb9277533e8f949735eb63c17c620 +64c68743ffb4b7708b0e58fd575a2e0331624bc5867a495f88565ba4779c38ad +cb9e7d8b66d67ba91b48fea71a1ea1ab965a807bf793faddf073934a5a2886db +c9b8d3f807568cb2261038afb4a639b960ae3c2248eb17dace94c4c2460c70b2 +113fdeb93813a5e7ffc9c5808a3d5b381a890a7246f2dd5848357f12e9bee65f +6b7f68055190810b5dcabff800f13ba97650e9100a69f6a40c7b4385e627952d +82eebbbf053d5c0dd068212fc546d222bc888e7b2e6af864d71b3b6bd0d3b0f6 +ff7c72a08fe798e85f5c83f372b14fc206b7d0b67e50d1bd7257ce74872d7736 +79a0237c84f1520102efce483eceb4e8414ef2e50c30e76166166dfc0eec9dbf +f02764d84eaf448d955eabbbae38aa9569ce31e7660e663582d8f6a50afa2c83 +d6ba455efcb9a13945f0ee5ad9bb00381d666e201d9cbf7b90b006d94251a6a8 +2bf32f07415b2919aaa4b9b043842edee3f8322e5d7c3c3ec226398c53e10012 +ee7cdb28b2599a431e7e412630623b8cf22b1e2bb64bd233f675659d35011002 +5b9e1045711592076917e961fce901770dbe0913422334487b11b41e2a4f44a9 +8a80b0177903da131592075162e55d83f841562737e4aacb808c009d4cc20761 +6512621af048858cf8f18b307709712964702144eb218aae8cececc161507a0e +754694dd18367bcc2a3de7581683ab19b9c5a187b9101df51a51df5167a68a31 +f3924bf4ce4d6d2941c84b052a11f7bbb27e6a3c6d8ef978e97c27b085d31a43 +f25e3a768fdaeb8b9a247752dde160c41225db9d487a67b3ddc5d518bdea3052 +5a2f648107f1d3da192ebd26834b5920afe148b8f9fd944e4fd65e5d9ab42e51 +b381feebd3f2a56bc465f801656ae6aaa83df9c9f63bfa89bd7469cdd230fb76 +5090e7d39a462d87b970c7fd1ea098061e3ae156808dec95657b1a8adbeb1eb0 +ed6d2bcefecd4382c64c6a275e962aa83c47b9aab2b832716e713848dcb6ba57 +66cf434bacce548d8eeb33504ec27f1c12af40cd15c28aa0a3396079780e25c4 +9b3cbdaf7d26a03e98d57cf2709e723357ad48df971b28467f77d18d0485e080 +3484a2d94efc2d44aef79dc0b4f944a8d1fc46ee9a07b63c908c36032b3dba0f +07f43333a5584c7132c1c3b739a2b322bbc58b80d9d1297ec5bf8a49bc421b10 +08adf2333646679f1249ea53ece33640033ebe6ed8842d12af51970a6799eb85 +a9bca6b6ff7b31deedc76f03acbf32ca50cb4c29c7437f1d3be13fdb22d7488d +38c025fddc4d33c69b424c9ac2f6852b488371dd39077b8a87e48b51ccc6f03b +eaa95d98baf8e17c38b50a39a47bb07c34876f7c0e2b41afb5f72e3cbce5c87b +3a5bf1b6a5a1c39aca22a96083e7b4d3e8b6c4a39ed923d0c376af7f339d77a3 +e59d45abf26603b95a4fb28612e6a0e5402e08841c7c88ab0df226e5fd93a39d +907aaa96b050ff1e8956ba461c59ab98d95ca6c9ebe9936dfdc84b4d1473945d +8e3f89 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000 +cleartomark + +%%EndFont +TeXDict begin 40258431 52099146 1000 1200 1200 (manual.dvi) +@start /Fa 171[91 100 5[124 77[{TeXBase1Encoding ReEncodeFont}3 +149.44 /Helvetica rf /Fb 182[33 3[80 69[{TeXBase1Encoding ReEncodeFont} +2 119.552 /Helvetica rf /Fc 143[75 4[66 2[75 104[{}3 +149.44 /Times-Italic rf /Fe 134[66 1[100 66 75 42 58 +58 1[75 75 75 108 42 2[42 75 75 42 66 75 66 75 75 50 +11[83 75 91 1[91 1[100 124 2[66 50 108 2[91 108 100 91 +91 7[75 75 75 4[75 75 75 1[37 50 5[50 36[75 2[{ +TeXBase1Encoding ReEncodeFont}46 149.44 /Times-Italic +rf /Ff 105[75 28[75 75 108 75 75 42 58 50 75 75 75 75 +116 42 75 42 42 75 75 50 66 75 66 75 66 3[50 1[50 1[108 +1[141 108 108 91 83 100 1[83 108 108 133 91 108 58 50 +108 108 83 91 108 100 100 108 6[42 75 75 75 75 75 75 +75 75 75 75 1[37 50 37 2[50 50 37[83 2[{TeXBase1Encoding ReEncodeFont} +68 149.44 /Times-Roman rf /Fg 175[174 80[{}1 166.044 +/MTEX rf /Fh 150[35 105[{}1 126.194 /Times-Italic rf +/Fj 133[100 100 100 100 100 1[100 100 100 1[100 100 100 +100 100 1[100 100 100 100 100 100 100 100 100 100 3[100 +1[100 3[100 1[100 100 100 100 1[100 100 100 100 100 2[100 +1[100 1[100 100 100 1[100 13[100 100 100 2[100 100 1[100 +100 42[{TeXBase1Encoding ReEncodeFont}48 166.044 /Courier +rf /Fk 137[74 92 46 65 65 1[83 83 92 129 3[46 92 83 55 +74 83 74 1[83 12[101 1[111 8[65 2[111 70[{TeXBase1Encoding ReEncodeFont} +21 166.044 /Times-BoldItalic rf /Fl 150[31 105[{}1 112.91 +/Times-Italic rf /Fn 143[66 1[66 2[59 35[96 71[{}4 132.835 +/Times-Italic rf /Fo 194[62 61[{}1 132.835 /RMTMI rf +/Fp 138[66 37 52 52 1[66 66 66 4[37 66 66 2[66 1[66 66 +97[{TeXBase1Encoding ReEncodeFont}13 132.835 /Times-Italic +rf /Fq 203[56 56 56 56 56 48[{TeXBase1Encoding ReEncodeFont}5 +112.91 /Times-Roman rf /Fr 203[63 63 63 63 49[{ +TeXBase1Encoding ReEncodeFont}4 126.194 /Times-Roman +rf /Fs 134[74 74 111 74 83 46 65 65 1[83 83 83 120 46 +1[46 46 83 83 1[74 83 74 83 83 3[65 1[65 26[153 2[112 +11[83 83 1[42 55 41[83 3[{TeXBase1Encoding ReEncodeFont}31 +166.044 /Times-Italic rf /Ft 134[111 111 1[111 122 66 +111 78 1[122 122 122 177 55 2[55 122 122 66 111 122 111 +122 111 10[133 144 122 1[144 1[133 155 144 166 3[55 144 +155 122 1[144 144 1[144 9[111 111 111 111 111 111 111 +2[55 66 42[122 2[{TeXBase1Encoding ReEncodeFont}46 199.253 +/Helvetica-Bold rf /Fu 173[134 8[52 3[124 3[134 65[{ +TeXBase1Encoding ReEncodeFont}4 185.969 /Helvetica-Bold +rf /Fv 133[54 54 54 79 54 61 30 54 36 1[61 61 61 91 24 +54 24 24 61 61 30 61 61 54 61 61 12[67 1[79 8[30 2[67 +73 79 2[73 13[61 4[30 36 30 2[36 36 37[54 2[{ +TeXBase1Encoding ReEncodeFont}39 132.835 /Helvetica-Narrow +rf /Fw 134[68 68 98 68 76 38 68 45 1[76 76 76 113 30 +2[30 76 76 38 76 76 68 76 76 1[76 8[91 98 83 91 2[91 +1[98 113 76 2[38 3[91 98 98 1[91 13[76 4[38 45 38 41[68 +2[{TeXBase1Encoding ReEncodeFont}41 166.044 /Helvetica-Narrow +rf /Fx 138[83 2[53 5[38 2[38 1[83 1[76 2[83 76 12[83 +13[83 15[76 76 76 76 76 76 49[{TeXBase1Encoding ReEncodeFont}16 +166.044 /Helvetica-Narrow-Bold rf /Fy 138[83 4[83 1[83 +120 1[74 46 46 1[83 2[83 74 18[101 80[{}11 166.044 /Times-Italic +rf /Fz 137[81 56[78 1[55 46 10[62 62 46[{}6 166.044 /RMTMI +rf /FA 134[83 1[120 83 92 46 83 55 1[92 92 92 138 37 +2[37 92 1[46 92 92 2[92 10[111 1[101 111 120 1[111 1[120 +138 92 111 1[46 1[129 1[111 120 2[111 13[92 92 47[83 +2[{TeXBase1Encoding ReEncodeFont}35 166.044 /Helvetica +rf /FB 134[92 1[129 92 101 55 92 65 1[101 101 101 148 +46 2[46 101 101 55 92 101 92 101 92 10[111 1[101 111 +120 1[111 1[120 138 1[120 1[46 1[129 101 111 120 120 +1[120 13[92 92 47[101 2[{TeXBase1Encoding ReEncodeFont}39 +166.044 /Helvetica-Bold rf /FC 173[96 8[37 3[89 3[96 +65[{TeXBase1Encoding ReEncodeFont}4 132.835 /Helvetica-Bold +rf /FD 133[74 83 83 120 83 92 55 65 74 92 92 83 92 138 +46 1[55 46 92 83 55 74 92 74 92 83 9[166 120 120 111 +92 120 2[129 120 4[65 129 1[101 2[120 1[120 7[83 2[83 +83 83 83 83 83 4[42 5[138 34[92 3[{TeXBase1Encoding ReEncodeFont}48 +166.044 /Times-Bold rf /FE 134[129 1[181 1[142 77 129 +90 142 142 142 142 207 65 2[65 142 142 77 129 142 129 +142 129 9[219 155 168 142 155 168 1[155 181 168 194 3[65 +168 1[142 2[168 1[168 10[129 129 129 129 129 129 4[65 +5[168 38[{TeXBase1Encoding ReEncodeFont}44 232.462 /Helvetica-Bold +rf /FF 134[66 66 96 66 66 37 52 44 66 66 66 66 103 37 +66 37 37 66 66 44 59 66 59 66 59 3[44 1[44 5[96 81 4[96 +96 118 3[44 96 1[74 4[96 10[66 2[66 1[66 2[33 44 33 2[44 +44 37[74 2[{TeXBase1Encoding ReEncodeFont}45 132.835 +/Times-Roman rf /FG 134[66 1[96 2[37 1[44 2[74 1[111 +7[74 3[74 10[89 1[81 89 96 1[89 2[111 1[89 1[37 1[103 +1[89 3[89 13[74 51[{TeXBase1Encoding ReEncodeFont}20 +132.835 /Helvetica rf /FH 173[77 8[30 3[71 3[71 65[{ +TeXBase1Encoding ReEncodeFont}4 106.268 /Helvetica rf +/FI 188[88 63[59 3[{}2 112.91 /MTSYN rf /FJ 134[100 2[100 +100 55 78 66 1[100 100 100 155 55 2[55 100 100 66 88 +100 88 1[88 11[144 1[111 133 1[111 1[144 177 4[144 2[122 +144 133 1[144 11[100 100 100 100 100 100 3[50 44[{ +TeXBase1Encoding ReEncodeFont}37 199.253 /Times-Roman +rf /FK 133[74 83 83 120 83 83 46 65 55 83 83 83 83 129 +46 83 46 46 83 83 55 74 83 74 83 74 3[55 1[55 101 2[157 +120 120 101 92 111 1[92 120 120 148 101 120 1[55 120 +120 92 101 120 111 111 120 153 74 4[46 83 83 83 83 83 +83 83 83 83 83 46 42 55 42 1[83 55 55 55 1[138 3[55 29[92 +92 2[{TeXBase1Encoding ReEncodeFont}75 166.044 /Times-Roman +rf /FL 152[61 61 33[130 130 51[83 11[87 130 1[130{}8 +166.044 /MTSYN rf /FM 134[120 3[133 1[120 80 1[133 133 +133 199 53 120 1[53 133 133 1[133 133 120 1[133 10[159 +2[159 7[159 3[186 26[66 44[{TeXBase1Encoding ReEncodeFont}22 +239.103 /Helvetica rf /FN 140[105 77 2[153 143 4[57 3[153 +14[167 34[134 1[134 2[67 46[{TeXBase1Encoding ReEncodeFont}10 +239.103 /AvantGarde-Demi rf /FO 134[166 161 3[86 126 +92 1[189 184 172 1[69 2[69 172 189 1[184 189 1[189 189 +13[149 2[161 241 1[258 126 4[241 71[{TeXBase1Encoding ReEncodeFont}22 +286.924 /AvantGarde-Demi rf /FP 252[112 3[{}1 214.527 +/MTSYN rf /FQ 171[252 276 2[276 2[344 77[{TeXBase1Encoding ReEncodeFont} +4 413.118 /Helvetica-Bold rf /FR 173[239 8[92 3[220 3[239 +65[{TeXBase1Encoding ReEncodeFont}4 330.494 /Helvetica-Bold +rf end +%%EndProlog +%%BeginSetup +%%Feature: *Resolution 1200dpi +TeXDict begin + +%%EndSetup +%%Page: 1 1 +1 0 bop 3012 1064 a FQ(P)-17 b FR(A)20 b(R)g FQ(M)-21 +b FR(E)-83 b FQ(T)g FR(I)o FQ(S)4795 962 y FP(\003)147 +1411 y FO(P)-6 b(arallel)80 b(Gra)6 b(ph)81 b(P)-6 b(ar)6 +b(titioning)80 b(and)i(Spar)6 b(se)80 b(Ma)q(tr)6 b(ix)81 +b(Or)n(der)6 b(ing)3432 1758 y(Librar)11 b(y)3281 2105 +y FN(V)-24 b(er)5 b(sion)67 b(3.1)1322 2794 y FM(George)f(Kar)7 +b(ypis)l(,)67 b(Kir)t(k)e(Schloegel)i(and)f(Vipin)h(K)-7 +b(umar)2711 3129 y FL(f)p FK(karypis,)41 b(kirk,)g(kumar)p +FL(g)p FK(@cs.umn.edu)863 3457 y FJ(Uni)-5 b(v)m(ersity)50 +b(of)g(Minnesota,)g(Department)h(of)f(Computer)g(Science)h(and)f +(Engineering)2768 3712 y(Army)g(HPC)f(Research)i(Center)2918 +3968 y(Minneapolis,)e(MN)h(55455)3239 4363 y(August)e(15,)h(2003)p +0 10646 3120 7 v 172 10751 a FI(\003)242 10799 y FG(P)-8 +b FH(A)6 b(R)g FG(M)-7 b FH(E)-27 b FG(T)g FH(I)o FG(S)39 +b FF(is)32 b(cop)o(yrighted)k(by)e(the)f(re)n(gents)h(of)g(the)g(Uni)m +(v)n(ersity)f(of)h(Minnesota.)3858 11298 y FK(1)p eop +%%Page: 2 2 +2 1 bop 0 170 a FE(Contents)0 555 y FD(1)166 b(Intr)m(oduction)6568 +b(3)0 940 y(2)166 b(What)42 b(is)g(New)f(in)h(This)f(V)-17 +b(ersion)5450 b(4)0 1325 y(3)166 b(Algorithms)42 b(Used)f(in)46 +b FB(P)-7 b FC(A)8 b(R)g FB(M)-9 b FC(E)-34 b FB(T)g +FC(I)p FB(S)5337 b FD(5)249 1544 y FK(3.1)174 b(Unstructured)41 +b(Graph)h(P)n(artitioning)129 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)286 b(5)249 1764 +y(3.2)174 b(P)n(artitioning)42 b(Meshes)e(Directly)110 +b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)286 b(7)249 1983 y(3.3)174 b(P)n(artitioning)42 +b(Adapti)l(v)n(ely)f(Re\002ned)g(Meshes)110 b(.)82 b(.)h(.)f(.)h(.)g(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)286 b(7)249 2202 +y(3.4)174 b(P)n(artition)42 b(Re\002nement)151 b(.)82 +b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)286 b(8)249 2421 y(3.5)174 +b(P)n(artitioning)42 b(for)g(Multi-phase)f(and)h(Multi-ph)o(ysics)f +(Computations)64 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)286 b(9)249 2640 +y(3.6)174 b(P)n(artitioning)42 b(for)g(Heterogeneous)f(Computing)h +(Architectures)114 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(10)249 +2860 y(3.7)174 b(Computing)42 b(Fill-Reducing)g(Orderings)107 +b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)203 b(10)0 3245 y FD(4)166 b(Input)42 b(and)h(Output)g(F)l(ormats)f +(used)f(by)46 b FB(P)-7 b FC(A)8 b(R)g FB(M)-9 b FC(E)-34 +b FB(T)g FC(I)p FB(S)4146 b FD(12)249 3464 y FK(4.1)174 +b(F)n(ormat)42 b(of)g(the)f(Input)h(Graph)151 b(.)83 +b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)203 b(12)249 3683 y(4.2)174 b(F)n(ormat)42 +b(of)g(V)-18 b(erte)n(x)40 b(Coordinates)52 b(.)82 b(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 +b(14)249 3902 y(4.3)174 b(F)n(ormat)42 b(of)g(the)f(Input)h(Mesh)72 +b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(14)249 4121 y(4.4)174 +b(F)n(ormat)42 b(of)g(the)f(Computed)g(P)n(artitionings)h(and)f +(Orderings)136 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 +b(14)249 4341 y(4.5)174 b(Numbering)42 b(and)f(Memory)g(Allocation)131 +b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)203 b(15)0 4726 y FD(5)166 b(Calling)42 b(Sequence)g(of)g(the)g +(Routines)f(in)46 b FB(P)-7 b FC(A)8 b(R)g FB(M)-9 b +FC(E)-34 b FB(T)g FC(I)p FB(S)4115 b FD(16)249 4945 y +FK(5.1)174 b(Graph)41 b(P)n(artitioning)166 b(.)83 b(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)203 b(17)1009 5164 y(P)n(arMETIS)p 1735 5164 +50 7 v 61 w(V3)p 1999 5164 V 59 w(P)n(artKw)n(ay)73 b(.)83 +b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)203 b(17)1009 5383 y(P)n(arMETIS)p 1735 5383 +V 61 w(V3)p 1999 5383 V 59 w(P)n(artGeomKw)n(ay)165 b(.)83 +b(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 +b(19)1009 5603 y(P)n(arMETIS)p 1735 5603 V 61 w(V3)p +1999 5603 V 59 w(P)n(artGeom)62 b(.)83 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.) +h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(21)1009 +5822 y(P)n(arMETIS)p 1735 5822 V 61 w(V3)p 1999 5822 +V 59 w(P)n(artMeshKw)n(ay)77 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(22)249 6041 y(5.2)174 +b(Graph)41 b(Repartitioning)113 b(.)82 b(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 +b(24)1009 6260 y(P)n(arMETIS)p 1735 6260 V 61 w(V3)p +1999 6260 V 59 w(Adapti)l(v)n(eRepart)61 b(.)82 b(.)h(.)f(.)h(.)f(.)h +(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(24)249 +6479 y(5.3)174 b(P)n(artitioning)42 b(Re\002nement)63 +b(.)83 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f +(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(26)1009 6698 y(P)n(arMETIS)p +1735 6698 V 61 w(V3)p 1999 6698 V 59 w(Re\002neKw)n(ay)153 +b(.)83 b(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f +(.)h(.)203 b(26)249 6918 y(5.4)174 b(Fill-reducing)43 +b(Orderings)79 b(.)k(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.) +g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(27)1009 +7137 y(P)n(arMETIS)p 1735 7137 V 61 w(V3)p 1999 7137 +V 59 w(NodeND)133 b(.)83 b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.) +f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 b(27)249 7356 y(5.5)174 +b(Mesh)40 b(to)i(Graph)g(T)-6 b(ranslation)113 b(.)83 +b(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.) +f(.)h(.)f(.)h(.)203 b(28)1009 7575 y(P)n(arMETIS)p 1735 +7575 V 61 w(V3)p 1999 7575 V 59 w(Mesh2Dual)82 b(.)g(.)h(.)f(.)h(.)f(.) +h(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h +(.)f(.)h(.)g(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)f(.)h(.)203 +b(28)0 7960 y FD(6)166 b(Hard)n(war)m(e)41 b(&)h(Softwar)m(e)f(Requir)m +(ements,)g(and)i(Contact)f(Inf)l(ormation)2914 b(29)3858 +11298 y FK(2)p eop +%%Page: 3 3 +3 2 bop 0 170 a FE(1)233 b(Intr)-5 b(oduction)4 522 y +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)49 b FK(is)42 b(an)g(MPI-based)g(parallel)h(library)g(that)f +(implements)h(a)f(v)l(ariety)g(of)h(algorithms)g(for)g(partitioning)g +(and)f(repartitioning)0 741 y(unstructured)g(graphs)g(and)g(for)g +(computing)h(\002ll-reducing)g(orderings)f(of)g(sparse)f(matrices.)57 +b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)48 b FK(is)42 b(particularly)h(suited)e(for)0 +960 y(parallel)k(numerical)h(simulations)f(in)-7 b(v)m(olving)46 +b(lar)m(ge)f(unstructured)g(meshes.)62 b(In)45 b(this)h(type)f(of)h +(computation,)k FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)51 b FK(dramati-)0 1179 y(cally)40 +b(reduces)f(the)i(time)f(spent)g(in)g(communication)h(by)f(computing)h +(mesh)e(decompositions)h(such)g(that)g(the)g(numbers)g(of)h(interf)n +(ace)0 1398 y(elements)g(are)g(minimized.)199 1617 y(The)g(algorithms)h +(in)j FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)47 b FK(are)41 b(based)f(on)h(the)g(multile)l(v)n(el)g +(partitioning)h(and)e(\002ll-reducing)i(ordering)g(algorithms)f(that)g +(are)0 1837 y(implemented)g(in)h(the)f(widely-used)f(serial)h(package)j +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)48 b FK([5].)k(Ho)l(we)l(v)n +(er)-7 b(,)43 b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)48 b FK(e)n(xtends)40 b(the)h(functionality)h(pro) +n(vided)f(by)4 2056 y FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)45 b FK(and)38 b(includes)g(routines)g(that)g(are)g(especially)g +(suited)g(for)g(parallel)h(computations)f(and)g(lar)m(ge-scale)f +(numerical)i(simulations.)0 2275 y(In)j(particular)-7 +b(,)45 b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b +FA(T)g FG(I)p FA(S)48 b FK(pro)n(vides)41 b(the)h(follo)l(wing)g +(functionality:)249 2627 y FL(\017)83 b FK(P)n(artition)42 +b(unstructured)g(graphs)f(and)g(meshes.)249 2979 y FL(\017)83 +b FK(Repartition)42 b(graphs)f(that)h(correspond)f(to)g(adapti)l(v)n +(ely)g(re\002ned)h(meshes.)249 3331 y FL(\017)83 b FK(P)n(artition)42 +b(graphs)f(for)h(multi-phase)g(and)f(multi-ph)o(ysics)h(simulations.) +249 3683 y FL(\017)83 b FK(Impro)n(v)n(e)41 b(the)h(quality)f(of)h(e)n +(xisting)f(partitionings.)249 4035 y FL(\017)83 b FK(Compute)41 +b(\002ll-reducing)i(orderings)f(for)g(sparse)e(direct)i(f)n +(actorization.)249 4387 y FL(\017)83 b FK(Construct)41 +b(the)h(dual)f(graphs)g(of)h(meshes)199 4739 y(The)d(rest)g(of)g(this)g +(manual)g(is)g(or)m(g)o(anized)f(as)h(follo)l(ws.)50 +b(Section)39 b(2)g(brie\003y)g(describes)f(the)h(dif)l(ferences)f +(between)g(this)h(v)n(ersion)f(and)0 4958 y(the)46 b(pre)l(vious)g +(major)h(release.)64 b(Section)47 b(3)f(describes)f(the)h(v)l(arious)g +(algorithms)h(that)f(are)g(implemented)h(in)j FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t +FK(.)49 b(Section)d(4)0 5177 y(describes)53 b(the)g(format)i(of)f(the)f +(basic)g(parameters)h(that)f(need)h(to)g(be)f(supplied)h(to)g(the)f +(routines.)88 b(Section)54 b(5)g(pro)n(vides)f(a)g(detailed)0 +5397 y(description)i(of)g(the)g(calling)g(sequences)f(for)h(the)g +(major)h(routines)f(in)k FA(P)-10 b FG(A)8 b(R)g FA(M)-9 +b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)57 b(Finally)-11 +b(,)59 b(Section)c(6)g(describes)f(softw)n(are)h(and)0 +5616 y(hardw)n(are)42 b(requirements)f(and)g(pro)n(vides)g(contact)g +(information.)3858 11298 y(3)p eop +%%Page: 4 4 +4 3 bop 0 170 a FE(2)233 b(What)65 b(is)g(Ne)m(w)f(in)g(This)h(V)-12 +b(er)m(sion)4 522 y FA(P)i FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)t FK(,)48 b(V)-18 b(ersion)45 b(3.x)g(contains)h +(a)f(number)i(of)f(changes)e(o)n(v)n(er)h(the)h(pre)l(vious)g(major)g +(release)f(\(V)-18 b(ersion)45 b(2.x\).)64 b(Theses)45 +b(changes)0 741 y(include)c(the)h(follo)l(wing:)249 1126 +y FL(\017)83 b FK(The)51 b(names)f(and)h(calling)g(sequence)e(of)i(all) +g(the)g(routines)f(ha)m(v)n(e)g(changed)g(due)g(to)h(e)n(xpanded)f +(functionality)h(that)g(has)g(been)415 1345 y(pro)n(vided)37 +b(in)f(this)h(release.)48 b(T)-13 b(able)37 b(1)f(sho)l(ws)g(ho)l(w)g +(the)h(names)f(of)g(the)h(v)l(arious)f(routines)h(map)f(from)i(v)n +(ersion)e(to)h(v)n(ersion.)48 b(Note)415 1564 y(that)55 +b(V)-18 b(ersion)55 b(3.0)f(is)h(fully)h(backw)n(ards)e(compatible)h +(with)h(all)f(pre)l(vious)f(v)n(ersions)h(of)k FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t +FK(.)57 b(That)e(is,)j(the)d(old)h(API)415 1784 y(calls)45 +b(ha)m(v)n(e)e(been)i(mapped)g(to)g(the)g(ne)l(w)g(routines.)62 +b(Ho)l(we)l(v)n(er)-7 b(,)44 b(the)h(e)n(xpanded)f(functionality)i(pro) +n(vided)f(with)g(this)g(release)f(is)415 2003 y(only)e(a)m(v)l(ailable) +e(by)i(using)f(the)h(ne)l(w)f(calling)g(sequences.)249 +2355 y FL(\017)83 b FK(The)73 b(four)g(adapti)l(v)n(e)f(repartitioning) +h(routines:)114 b FA(P)-7 b(arMETIS)p 4163 2355 50 7 +v 61 w(Repar)7 b(tLDiffusion)p FK(,)82 b FA(P)-7 b(arMETIS)p +6347 2355 V 61 w(Repar)7 b(tGDiffusion)p FK(,)415 2574 +y FA(P)-7 b(arMETIS)p 1183 2574 V 61 w(Repar)7 b(tRemap)p +FK(,)45 b(and)d FA(P)-7 b(arMETIS)p 3409 2574 V 61 w(Repar)7 +b(tMLRemap)46 b FK(ha)m(v)n(e)41 b(been)h(replaced)g(by)h(a)g +(\(single\))g(implementa-)415 2793 y(tion)36 b(of)h(a)e(uni\002ed)i +(repartitioning)g(algorithm)f([15)q(],)g FA(P)-7 b(arMETIS)p +4235 2793 V 61 w(V3)p 4499 2793 V 60 w(Adaptiv)l(eRepar)7 +b(t)p FK(,)39 b(that)d(combines)f(the)h(best)f(features)415 +3012 y(of)42 b(the)f(pre)l(vious)h(routines.)249 3364 +y FL(\017)83 b FK(Multiple)39 b(v)n(erte)n(x)g(weights/balance)f +(constraints)g(are)h(supported)g(for)h(most)f(of)h(the)f(routines.)50 +b(This)40 b(allo)l(ws)i FA(P)-10 b FG(A)8 b(R)g FA(M)-9 +b FG(E)-34 b FA(T)g FG(I)p FA(S)46 b FK(to)39 b(be)415 +3583 y(used)i(to)h(partition)g(graphs)f(for)h(multi-phase)g(and)f +(multi-ph)o(ysics)h(simulations.)249 3935 y FL(\017)83 +b FK(In)66 b(order)g(to)h(optimize)f(partitionings)g(for)g(speci\002c)f +(heterogeneous)g(computing)i(architectures,)j(it)c(is)g(no)l(w)g +(possible)f(to)415 4155 y(specify)36 b(the)h(tar)m(get)g(sub-domain)f +(weights)h(for)g(each)f(of)h(the)g(sub-domains)f(and)g(for)i(each)e +(balance)f(constraint.)50 b(This)37 b(feature,)415 4374 +y(for)47 b(e)n(xample,)f(allo)l(ws)g(the)h(user)f(to)g(compute)h(a)f +(partitioning)h(in)g(which)f(one)h(of)f(the)h(sub-domains)f(is)g(twice) +g(the)h(size)e(of)i(all)415 4593 y(of)42 b(the)f(others.)249 +4945 y FL(\017)83 b FK(The)63 b(number)g(of)g(sub-domains)g(has)f(been) +g(de-coupled)h(from)g(the)g(number)g(of)g(processors)f(in)h(both)g(the) +f(static)h(and)f(the)415 5164 y(adapti)l(v)n(e)j(partitioning)h +(schemes.)123 b(Hence,)70 b(it)c(is)g(no)l(w)f(possible)g(to)h(use)f +(the)h(parallel)g(partitioning)h(and)e(repartitioning)415 +5383 y(algorithms)51 b(to)g(compute)g(a)g Fy(k)10 b FK(-w)n(ay)50 +b(partitioning)i(independent)f(of)g(the)f(number)i(of)f(processors)e +(that)i(are)g(used.)78 b(Note)51 b(that)415 5603 y(V)-18 +b(ersion)41 b(2.0)g(pro)n(vided)g(this)h(functionality)g(for)g(the)f +(static)g(partitioning)i(schemes)d(only)-11 b(.)249 5955 +y FL(\017)83 b FK(Routines)48 b(are)g(pro)n(vided)h(for)g(both)g +(directly)g(partitioning)g(a)f(\002nite)h(element)g(mesh,)g(and)f(for)h +(constructing)g(the)f(dual)h(graph)415 6174 y(of)42 b(a)f(mesh)g(in)h +(parallel.)51 b(In)42 b(v)n(ersion)f(3.1)g(these)f(routines)i(ha)m(v)n +(e)e(been)h(e)n(xtended)f(to)i(support)g(mix)n(ed)f(element)g(meshes.)p +1040 6714 5721 7 v 1037 6914 7 200 v 1140 6854 a(V)-18 +b(ersion)40 b(1.0)p 2281 6914 V 488 w(V)-18 b(ersion)41 +b(2.0)p 4452 6914 V 1414 w(V)-18 b(ersion)41 b(3.0)p +6757 6914 V 1040 6920 5721 7 v 1040 6927 V 1037 7126 +7 200 v 1140 7066 a(P)-15 b(ARKMETIS)p 2281 7126 V 319 +w(P)n(arMETIS)p 3110 7066 50 7 v 61 w(P)n(artKw)n(ay)p +4452 7126 7 200 v 734 w(P)n(arMETIS)p 5281 7066 50 7 +v 61 w(V3)p 5545 7066 V 60 w(P)n(artKw)n(ay)p 6757 7126 +7 200 v 1040 7133 5721 7 v 1037 7332 7 200 v 1140 7272 +a(P)g(ARGKMETIS)p 2281 7332 V 199 w(P)n(arMETIS)p 3110 +7272 50 7 v 61 w(P)n(artGeomKw)n(ay)p 4452 7332 7 200 +v 328 w(P)n(arMETIS)p 5281 7272 50 7 v 61 w(V3)p 5545 +7272 V 60 w(P)n(artGeomKw)n(ay)p 6757 7332 7 200 v 1040 +7339 5721 7 v 1037 7538 7 200 v 1140 7478 a(P)g(ARGMETIS)p +2281 7538 V 319 w(P)n(arMETIS)p 3110 7478 50 7 v 61 w(P)n(artGeom)p +4452 7538 7 200 v 723 w(P)n(arMETIS)p 5281 7478 50 7 +v 61 w(V3)p 5545 7478 V 60 w(P)n(artGeom)p 6757 7538 +7 200 v 1040 7545 5721 7 v 1037 7744 7 200 v 1140 7684 +a(P)g(ARGRMETIS)p 2281 7744 V 208 w(Not)42 b(a)m(v)l(ailable)p +4452 7744 V 1287 w(Not)g(a)m(v)l(ailable)p 6757 7744 +V 1040 7751 5721 7 v 1037 7950 7 200 v 1140 7890 a(P)-15 +b(ARRMETIS)p 2281 7950 V 328 w(P)n(arMETIS)p 3110 7890 +50 7 v 61 w(Re\002neKw)n(ay)p 4452 7950 7 200 v 565 w(P)n(arMETIS)p +5281 7890 50 7 v 61 w(V3)p 5545 7890 V 60 w(Re\002neKw)n(ay)p +6757 7950 7 200 v 1040 7956 5721 7 v 1037 8156 7 200 +v 1140 8096 a(P)g(AR)-7 b(U)g(AMETIS)p 2281 8156 V 213 +w(P)n(arMETIS)p 3110 8096 50 7 v 61 w(RepartLDif)l(fusion)p +4452 8156 7 200 v 4452 8156 V 6757 8156 V 1037 8355 V +1140 8295 a(P)-15 b(ARD)-7 b(AMETIS)p 2281 8355 V 206 +w(P)n(arMETIS)p 3110 8295 50 7 v 61 w(RepartGDif)l(fusion)p +4452 8355 7 200 v 4452 8355 V 6757 8355 V 1037 8554 V +1140 8494 a(Not)41 b(a)m(v)l(ailable)p 2281 8554 V 361 +w(P)n(arMETIS)p 3110 8494 50 7 v 61 w(RepartRemap)p 4452 +8554 7 200 v 4452 8554 V 4555 8382 a(P)n(arMETIS)p 5281 +8382 50 7 v 61 w(V3)p 5545 8382 V 60 w(Adapti)l(v)n(eRepart)p +6757 8554 7 200 v 1037 8753 V 1140 8694 a(Not)g(a)m(v)l(ailable)p +2281 8753 V 361 w(P)n(arMETIS)p 3110 8694 50 7 v 61 w(RepartMLRemap)p +4452 8753 7 200 v 4452 8753 V 6757 8753 V 1040 8760 5721 +7 v 1037 8959 7 200 v 1140 8900 a(P)-15 b(AR)-7 b(OMETIS)p +2281 8959 V 326 w(P)n(arMETIS)p 3110 8900 50 7 v 61 w(NodeND)p +4452 8959 7 200 v 794 w(P)n(arMETIS)p 5281 8900 50 7 +v 61 w(V3)p 5545 8900 V 60 w(NodeND)p 6757 8959 7 200 +v 1040 8966 5721 7 v 1037 9165 7 200 v 1140 9106 a(Not)41 +b(a)m(v)l(ailable)p 2281 9165 V 361 w(Not)h(a)m(v)l(ailable)p +4452 9165 V 1287 w(P)n(arMETIS)p 5281 9106 50 7 v 61 +w(V3)p 5545 9106 V 60 w(P)n(artMeshKw)n(ay)p 6757 9165 +7 200 v 1040 9172 5721 7 v 1037 9371 7 200 v 1140 9311 +a(Not)f(a)m(v)l(ailable)p 2281 9371 V 361 w(Not)h(a)m(v)l(ailable)p +4452 9371 V 1287 w(P)n(arMETIS)p 5281 9311 50 7 v 61 +w(V3)p 5545 9311 V 60 w(Mesh2Dual)p 6757 9371 7 200 v +1040 9378 5721 7 v 920 9683 a Fx(T)-11 b(ab)o(le)38 b(1)p +FK(:)51 b Fw(The)38 b(relationships)f(betw)o(een)f(the)i(names)f(of)g +(the)h(routines)f(in)h(the)f(diff)l(erent)g(v)m(ersions)g(of)k(P)-6 +b Fv(A)8 b(R)g Fw(M)-9 b Fv(E)-34 b Fw(T)g Fv(I)p Fw(S)t(.)3858 +11298 y FK(4)p eop +%%Page: 5 5 +5 4 bop 0 170 a FE(3)233 b(Algorithms)64 b(Used)h(in)71 +b(P)-9 b Fu(A)12 b(R)g FE(M)-11 b Fu(E)-46 b FE(T)g Fu(I)p +FE(S)4 522 y FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)40 b FK(pro)n(vides)33 b(a)g(v)l(ariety)g(of)h +(routines)g(that)f(can)g(be)h(used)e(to)i(compute)f(dif)l(ferent)h +(types)f(of)h(partitionings)g(and)f(repartitionings)0 +741 y(as)46 b(well)h(as)f(\002ll-reducing)i(orderings.)67 +b(Figure)47 b(1)g(pro)n(vides)f(an)h(o)n(v)n(ervie)l(w)f(of)h(the)g +(functionality)g(pro)n(vided)g(by)k FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)53 b FK(as)46 +b(well)0 960 y(as)41 b(a)g(guide)h(to)f(its)h(use.)300 +5341 y @beginspecial 0 @llx 0 @lly 1182 @urx 686 @ury +4320 @rwi @setspecial +%%BeginDocument: ./figures/usagemap.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: usagemap.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3b +%%CreationDate: Mon Jan 14 18:01:01 2002 +%%For: kirk@lnx08 (Kirk Schloegel) +%%BoundingBox: 0 0 1182 686 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 686 moveto 0 0 lineto 1182 0 lineto 1182 686 lineto closepath clip newpath +-39.0 775.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def +/reencdict 12 dict def /ReEncode { reencdict begin +/newcodesandnames exch def /newfontname exch def /basefontname exch def +/basefontdict basefontname findfont def /newfont basefontdict maxlength dict def +basefontdict { exch dup /FID ne { dup /Encoding eq +{ exch dup length array copy newfont 3 1 roll put } +{ exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall +newfont /FontName newfontname put newcodesandnames aload pop +128 1 255 { newfont /Encoding get exch /.notdef put } for +newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat +newfontname newfont definefont pop end } def +/isovec [ +8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde +8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis +8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron +8#220 /dotlessi 8#230 /oe 8#231 /OE +8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling +8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis +8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot +8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus +8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph +8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine +8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf +8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute +8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring +8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute +8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute +8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve +8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply +8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex +8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave +8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring +8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute +8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute +8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve +8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide +8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex +8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def +/Helvetica /Helvetica-iso isovec ReEncode +/Helvetica-Bold /Helvetica-Bold-iso isovec ReEncode +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 6705 8400 m 6600 8400 6600 9195 105 arcto 4 {pop} repeat + 6600 9300 10695 9300 105 arcto 4 {pop} repeat + 10800 9300 10800 8505 105 arcto 4 {pop} repeat + 10800 8400 6705 8400 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 2505 8400 m 2400 8400 2400 9195 105 arcto 4 {pop} repeat + 2400 9300 5595 9300 105 arcto 4 {pop} repeat + 5700 9300 5700 8505 105 arcto 4 {pop} repeat + 5700 8400 2505 8400 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 6705 10200 m 6600 10200 6600 10995 105 arcto 4 {pop} repeat + 6600 11100 10695 11100 105 arcto 4 {pop} repeat + 10800 11100 10800 10305 105 arcto 4 {pop} repeat + 10800 10200 6705 10200 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 6705 12000 m 6600 12000 6600 12795 105 arcto 4 {pop} repeat + 6600 12900 10695 12900 105 arcto 4 {pop} repeat + 10800 12900 10800 12105 105 arcto 4 {pop} repeat + 10800 12000 6705 12000 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 2505 12000 m 2400 12000 2400 12795 105 arcto 4 {pop} repeat + 2400 12900 5595 12900 105 arcto 4 {pop} repeat + 5700 12900 5700 12105 105 arcto 4 {pop} repeat + 5700 12000 2505 12000 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 2505 10200 m 2400 10200 2400 10995 105 arcto 4 {pop} repeat + 2400 11100 5595 11100 105 arcto 4 {pop} repeat + 5700 11100 5700 10305 105 arcto 4 {pop} repeat + 5700 10200 2505 10200 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 6705 6600 m 6600 6600 6600 7395 105 arcto 4 {pop} repeat + 6600 7500 10695 7500 105 arcto 4 {pop} repeat + 10800 7500 10800 6705 105 arcto 4 {pop} repeat + 10800 6600 6705 6600 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 2505 6600 m 2400 6600 2400 7395 105 arcto 4 {pop} repeat + 2400 7500 5595 7500 105 arcto 4 {pop} repeat + 5700 7500 5700 6705 105 arcto 4 {pop} repeat + 5700 6600 2505 6600 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +gs clippath +2374 12506 m 2449 12412 l 2238 12244 l 2342 12404 l 2163 12338 l cp +eoclip +n 1275 11550 m + 2400 12450 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2163 12338 m 2342 12404 l 2238 12244 l 2163 12338 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +2415 10710 m 2415 10590 l 2146 10590 l 2326 10650 l 2146 10710 l cp +eoclip +n 1275 10650 m + 2400 10650 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2146 10710 m 2326 10650 l 2146 10590 l 2146 10710 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +2415 8910 m 2415 8790 l 2146 8790 l 2326 8850 l 2146 8910 l cp +eoclip +n 1275 8850 m + 2400 8850 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2146 8910 m 2326 8850 l 2146 8790 l 2146 8910 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +2415 7110 m 2415 6990 l 2146 6990 l 2326 7050 l 2146 7110 l cp +eoclip +n 1275 7050 m + 2400 7050 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2146 7110 m 2326 7050 l 2146 6990 l 2146 7110 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +n 6705 4800 m 6600 4800 6600 5595 105 arcto 4 {pop} repeat + 6600 5700 10695 5700 105 arcto 4 {pop} repeat + 10800 5700 10800 4905 105 arcto 4 {pop} repeat + 10800 4800 6705 4800 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +gs clippath +2415 5310 m 2415 5190 l 2146 5190 l 2326 5250 l 2146 5310 l cp +eoclip +n 1275 5250 m + 2400 5250 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2146 5310 m 2326 5250 l 2146 5190 l 2146 5310 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +2455 3176 m 2363 3100 l 2190 3306 l 2352 3207 l 2282 3383 l cp +eoclip +n 1275 4500 m + 2400 3150 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 2282 3383 m 2352 3207 l 2190 3306 l 2282 3383 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 3210 m 6615 3090 l 6346 3090 l 6526 3150 l 6346 3210 l cp +eoclip +n 5700 3150 m + 6600 3150 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 3210 m 6526 3150 l 6346 3090 l 6346 3210 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 5310 m 6615 5190 l 6346 5190 l 6526 5250 l 6346 5310 l cp +eoclip +n 5700 5250 m + 6600 5250 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 5310 m 6526 5250 l 6346 5190 l 6346 5310 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 7110 m 6615 6990 l 6346 6990 l 6526 7050 l 6346 7110 l cp +eoclip +n 5700 7050 m + 6600 7050 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 7110 m 6526 7050 l 6346 6990 l 6346 7110 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 8910 m 6615 8790 l 6346 8790 l 6526 8850 l 6346 8910 l cp +eoclip +n 5700 8850 m + 6600 8850 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 8910 m 6526 8850 l 6346 8790 l 6346 8910 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 10710 m 6615 10590 l 6346 10590 l 6526 10650 l 6346 10710 l cp +eoclip +n 5700 10650 m + 6600 10650 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 10710 m 6526 10650 l 6346 10590 l 6346 10710 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +6615 12510 m 6615 12390 l 6346 12390 l 6526 12450 l 6346 12510 l cp +eoclip +n 5700 12450 m + 6600 12450 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 6346 12510 m 6526 12450 l 6346 12390 l 6346 12510 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +11092 3811 m 11135 3699 l 10882 3604 l 11030 3724 l 10840 3716 l cp +eoclip +n 9900 3300 m + 11100 3750 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 10840 3716 m 11030 3724 l 10882 3604 l 10840 3716 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +n 16605 2700 m 16500 2700 16500 3495 105 arcto 4 {pop} repeat + 16500 3600 19995 3600 105 arcto 4 {pop} repeat + 20100 3600 20100 2805 105 arcto 4 {pop} repeat + 20100 2700 16605 2700 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 16305 1500 m 16200 1500 16200 2295 105 arcto 4 {pop} repeat + 16200 2400 20220 2400 105 arcto 4 {pop} repeat + 20325 2400 20325 1605 105 arcto 4 {pop} repeat + 20325 1500 16305 1500 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +gs clippath +16224 2006 m 16204 1888 l 15939 1932 l 16127 1962 l 15959 2050 l cp +eoclip +n 14400 2250 m + 16200 1950 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 15959 2050 m 16127 1962 l 15939 1932 l 15959 2050 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +16506 3211 m 16523 3092 l 16256 3054 l 16426 3139 l 16239 3172 l cp +eoclip +n 14400 2850 m + 16500 3150 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 16239 3172 m 16426 3139 l 16256 3054 l 16239 3172 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +gs clippath +11137 2523 m 11089 2414 l 10843 2522 l 11032 2505 l 10891 2632 l cp +eoclip +n 9900 3000 m + 11100 2475 l gs col7 1.00 shd ef gr gs col-1 s gr gr + +% arrowhead +45.000 slw +n 10891 2632 m 11032 2505 l 10843 2522 l 10891 2632 l cp gs 0.00 setgray ef gr col-1 s +% Polyline +7.500 slw +n 2505 2700 m 2400 2700 2400 3495 105 arcto 4 {pop} repeat + 2400 3600 5595 3600 105 arcto 4 {pop} repeat + 5700 3600 5700 2805 105 arcto 4 {pop} repeat + 5700 2700 2505 2700 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 2505 4800 m 2400 4800 2400 5595 105 arcto 4 {pop} repeat + 2400 5700 5595 5700 105 arcto 4 {pop} repeat + 5700 5700 5700 4905 105 arcto 4 {pop} repeat + 5700 4800 2505 4800 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 6705 2700 m 6600 2700 6600 3495 105 arcto 4 {pop} repeat + 6600 3600 9795 3600 105 arcto 4 {pop} repeat + 9900 3600 9900 2805 105 arcto 4 {pop} repeat + 9900 2700 6705 2700 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +% Polyline +n 11205 3300 m 11100 3300 11100 4095 105 arcto 4 {pop} repeat + 11100 4200 14295 4200 105 arcto 4 {pop} repeat + 14400 4200 14400 3405 105 arcto 4 {pop} repeat + 14400 3300 11205 3300 105 arcto 4 {pop} repeat + cp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 11205 2100 m 11100 2100 11100 2895 105 arcto 4 {pop} repeat + 11100 3000 14295 3000 105 arcto 4 {pop} repeat + 14400 3000 14400 2205 105 arcto 4 {pop} repeat + 14400 2100 11205 2100 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +/Helvetica-iso ff 240.00 scf sf +10425 2625 m +gs 1 -1 sc 20.0 rot (YES) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 210.00 scf sf +10500 3900 m +gs 1 -1 sc 340.0 rot (YES or NO) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +15225 1950 m +gs 1 -1 sc 8.0 rot (High quality) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +15375 2850 m +gs 1 -1 sc 352.0 rot (Low quality) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +8700 12525 m +gs 1 -1 sc (ParMETIS_V3_NodeND) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +8700 10800 m +gs 1 -1 sc (ParMETIS_V3_RefineKway) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +8700 9000 m +gs 1 -1 sc (ParMETIS_V3_AdaptiveRepart) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +8700 7200 m +gs 1 -1 sc (ParMETIS_V3_Mesh2Dual) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +8700 5400 m +gs 1 -1 sc (ParMETIS_V3_PartMeshKway) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +12750 3900 m +gs 1 -1 sc (ParMETIS_V3_PartKway) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +18262 2100 m +gs 1 -1 sc (ParMETIS_V3_PartGeomKway) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold-iso ff 240.00 scf sf +18300 3225 m +gs 1 -1 sc (ParMETIS_V3_PartGeom) dup sw pop 2 div neg 0 rm col-1 sh gr +% Polyline +n 780 4425 m 675 4425 675 11520 105 arcto 4 {pop} repeat + 675 11625 1170 11625 105 arcto 4 {pop} repeat + 1275 11625 1275 4530 105 arcto 4 {pop} repeat + 1275 4425 780 4425 105 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col-1 s gr +/Helvetica-iso ff 360.00 scf sf +1125 8025 m +gs 1 -1 sc 90.0 rot (ParMetis Can Do The Following) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 3225 m +gs 1 -1 sc (Partition a graph) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 5325 m +gs 1 -1 sc (Partition a mesh) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 10575 m +gs 1 -1 sc (Refine the quality) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 10875 m +gs 1 -1 sc (of a partitioning) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 12375 m +gs 1 -1 sc (Compute a fill-reducing ) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +4050 12675 m +gs 1 -1 sc (ordering) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +8250 3405 m +gs 1 -1 sc (for the vertices?) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +8250 3075 m +gs 1 -1 sc (Do you have coordinates) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +12750 2475 m +gs 1 -1 sc (What are your ) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 240.00 scf sf +12750 2805 m +gs 1 -1 sc (time/quality tradeoffs?) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 210.00 scf sf +4050 8775 m +gs 1 -1 sc (Repartition a graph corresponding) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 210.00 scf sf +4050 9075 m +gs 1 -1 sc (to an adaptively refined mesh) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-iso ff 210.00 scf sf +4050 7125 m +gs 1 -1 sc (Construct a graph from a mesh) dup sw pop 2 div neg 0 rm col-1 sh gr +$F2psEnd +rs + +%%EndDocument + @endspecial 0 5706 a Fx(Figure)56 b(1)p FK(:)91 b Fw(A)56 +b(br)r(ief)g(o)n(v)m(er)t(vie)n(w)g(of)f(the)g(functionality)g(pro)n +(vided)h(b)n(y)j(P)-6 b Fv(A)8 b(R)g Fw(M)-9 b Fv(E)-34 +b Fw(T)g Fv(I)p Fw(S)t(.)58 b(The)e(shaded)e(bo)l(x)l(es)i(correspond)f +(to)g(the)g(actual)h(routines)f(in)4 5905 y(P)-6 b Fv(A)8 +b(R)g Fw(M)-9 b Fv(E)-34 b Fw(T)g Fv(I)p Fw(S)44 b(that)37 +b(implement)h(each)f(par)5 b(ticular)38 b(oper)o(ation.)0 +6526 y Ft(3.1)199 b(Unstructured)53 b(Graph)i(P)-6 b(ar)t(titioning)0 +6844 y FA(P)f(arMETIS)p 768 6844 50 7 v 61 w(V3)p 1032 +6844 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)40 b FK(is)g(the)g(routine)h(in)j +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)47 b FK(that)41 b(is)f(used)f(to)i(partition)g(unstructured)f +(graphs.)50 b(This)41 b(routine)f(tak)n(es)0 7064 y(a)i(graph)g(and)f +(computes)h(a)f Fy(k)10 b FK(-w)n(ay)42 b(partitioning)h(\(where)f +Fy(k)51 b FK(is)42 b(equal)f(to)h(the)g(number)g(of)h(sub-domains)e +(desired\))h(while)g(attempting)0 7283 y(to)e(minimize)f(the)g(number)h +(of)g(edges)e(that)i(are)f(cut)g(by)g(the)h(partitioning)g(\()p +Fs(i.e)p FK(.,)e(the)i Fs(edg)n(e-cut)p FK(\).)50 b FA(P)-7 +b(arMETIS)p 6321 7283 V 61 w(V3)p 6585 7283 V 60 w(P)g(ar)7 +b(tKw)n(a)-5 b(y)39 b FK(mak)n(es)0 7502 y(no)j(assumptions)e(on)i(ho)l +(w)f(the)h(graph)f(is)g(initially)i(distrib)m(uted)e(among)h(the)f +(processors.)50 b(It)42 b(can)f(ef)l(fecti)l(v)n(ely)g(partition)h(a)f +(graph)h(that)0 7721 y(is)i(randomly)h(distrib)m(uted)f(as)f(well)h(as) +g(a)g(graph)g(that)g(is)g(well)g(distrib)m(uted)4307 +7661 y Fr(1)4379 7721 y FK(.)59 b(If)44 b(the)h(graph)f(is)g(initially) +h(well)f(distrib)m(uted)g(among)g(the)0 7940 y(processors,)i +FA(P)-7 b(arMETIS)p 1558 7940 V 61 w(V3)p 1822 7940 V +60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)46 b FK(will)h(tak)n(e)f(less)f(time)i +(to)g(run.)65 b(Ho)l(we)l(v)n(er)-7 b(,)47 b(the)f(quality)g(of)h(the)f +(computed)g(partitionings)0 8160 y(does)41 b(not)h(depend)f(on)g(the)h +(initial)g(distrib)m(ution.)199 8379 y(The)58 b(parallel)f(graph)h +(partitioning)g(algorithm)g(used)f(in)h FA(P)-7 b(arMETIS)p +4358 8379 V 61 w(V3)p 4622 8379 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)57 b FK(is)g(based)g(on)g(the)h(serial)f(multile)l(v)n(el)g +Fy(k)10 b FK(-)0 8598 y(w)n(ay)49 b(partitioning)g(algorithm)h +(described)e(in)h([6,)f(7])i(and)e(parallelized)g(in)h([4)q(,)f(14].)73 +b(This)49 b(algorithm)g(has)g(been)f(sho)l(wn)g(to)h(quickly)0 +8817 y(produce)g(partitionings)g(that)g(are)g(of)g(v)n(ery)f(high)i +(quality)-11 b(.)73 b(It)50 b(consists)d(of)j(three)e(phases:)66 +b(graph)49 b(coarsening,)g(initial)h(partitioning,)0 +9036 y(and)c(uncoarsening/re\002nement.)66 b(In)46 b(the)h(graph)f +(coarsening)g(phase,)g(a)g(series)g(of)g(graphs)g(is)h(constructed)e +(by)i(collapsing)f(together)p 0 9325 3120 7 v 174 9445 +a Fq(1)239 9494 y FF(The)36 b(reader)g(should)h(note)f(the)f(dif)m +(ference)i(between)e(the)h(terms)f Fp(gr)n(aph)i(distrib)m(ution)g +FF(and)f Fp(gr)n(aph)g(partition)p FF(.)49 b(A)35 b(partitioning)i(is)e +(a)h(mapping)h(of)f(the)f(v)n(ertices)h(to)0 9651 y(the)g(processors)f +(that)h(results)f(in)h(a)f(distrib)m(ution.)49 b(In)36 +b(other)g(w)o(ords,)h(a)e(partitioning)i(speci\002es)e(a)g(distrib)m +(ution.)49 b(In)36 b(order)h(to)e(partition)i(a)e(graph)h(in)g +(parallel,)g(an)g(initial)0 9809 y(distrib)m(ution)i(of)e(the)g(nodes)h +(and)g(edges)f(of)g(the)g(graph)i(among)f(the)f(processors)g(is)g +(required.)50 b(F)n(or)37 b(e)n(xample,)g(consider)g(a)f(graph)h(that)f +(corresponds)i(to)e(the)g(dual)h(of)f(a)0 9967 y(\002nite-element)30 +b(mesh.)40 b(This)30 b(graph)g(could)h(initially)e(be)h(partitioned)g +(simply)g(by)g(mapping)h(groups)g(of)e Fn(n)6 b Fo(=)15 +b Fn(p)35 b FF(consecuti)m(v)n(ely)30 b(numbered)i(elements)d(to)h +(each)f(processor)0 10125 y(where)g Fn(n)35 b FF(is)28 +b(the)h(number)i(of)e(elements)g(and)44 b Fn(p)34 b FF(is)28 +b(the)h(number)h(of)g(processors.)40 b(Of)29 b(course,)h(this)f(nai)m +(v)n(e)g(approach)h(is)f(not)g(lik)o(ely)g(to)g(result)g(in)f(a)h(v)n +(ery)h(good)g(distrib)m(ution)0 10282 y(because)j(elements)h(that)f +(belong)h(to)g(a)f(number)i(of)e(dif)m(ferent)h(re)n(gions)g(of)g(the)f +(mesh)h(may)f(get)h(mapped)g(to)g(the)f(same)g(processor)-7 +b(.)42 b(\(That)34 b(is,)f(each)g(processor)h(may)g(get)0 +10440 y(a)d(number)j(of)e(small)f(sub-domains)j(as)d(opposed)i(to)f(a)f +(single)h(contiguous)i(sub-domain\).)43 b(Hence,)32 b(you)h(w)o(ould)f +(w)o(ant)f(to)h(compute)h(a)f(ne)m(w)f(high-quality)j(partitioning)0 +10598 y(for)h(the)f(graph)i(and)e(then)h(redistrib)m(ute)g(the)g(mesh)f +(accordingly)-9 b(.)46 b(Note)34 b(that)h(it)f(may)g(also)g(be)h(the)f +(case)f(that)i(the)f(initial)g(graph)h(is)f(well)g(distrib)m(uted,)i +(as)d(when)i(meshes)0 10755 y(are)e(adapti)m(v)n(ely)i(re\002ned)f(and) +g(repartitioned.)3858 11298 y FK(5)p eop +%%Page: 6 6 +6 5 bop 1800 3598 a @beginspecial 0 @llx 0 @lly 544 @urx +466 @ury 2520 @rwi @setspecial +%%BeginDocument: figures/mlp.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: kmlevel.fig +%%Creator: fig2dev Version 3.1 Patchlevel 2 +%%CreationDate: Mon Feb 3 14:33:40 1997 +%%For: kirk@peca (Kirk Schloegel) +%Magnification: 1.00 +%%Orientation: Portrait +%%BoundingBox: 0 0 544 466 +%%Pages: 0 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +-52.0 485.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawSplineSection { + /y3 exch def + /x3 exch def + /y2 exch def + /x2 exch def + /y1 exch def + /x1 exch def + /xa x1 x2 x1 sub 0.666667 mul add def + /ya y1 y2 y1 sub 0.666667 mul add def + /xb x3 x2 x3 sub 0.666667 mul add def + /yb y3 y2 y3 sub 0.666667 mul add def + x1 y1 lineto + xa ya xb yb x3 y3 curveto + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit +n 0 792 m 0 0 l 612 0 l 612 792 l cp clip + 0.06000 0.06000 sc +% Closed spline +gs 7.500 slw +n 2489.0 3150.0 m + 2489.0 3150.0 2399.0 3180.0 2309.0 3210.0 DrawSplineSection + 2309.0 3210.0 2219.0 3240.0 2069.5 3359.5 DrawSplineSection + 2069.5 3359.5 1920.0 3479.0 1860.0 3539.0 DrawSplineSection + 1860.0 3539.0 1800.0 3599.0 1800.0 3689.0 DrawSplineSection + 1800.0 3689.0 1800.0 3779.0 1800.0 3839.0 DrawSplineSection + 1800.0 3839.0 1800.0 3899.0 1860.0 3959.5 DrawSplineSection + 1860.0 3959.5 1920.0 4020.0 1980.0 4079.5 DrawSplineSection + 1980.0 4079.5 2040.0 4139.0 2070.0 4139.0 DrawSplineSection + 2070.0 4139.0 2100.0 4139.0 2219.5 4169.0 DrawSplineSection + 2219.5 4169.0 2339.0 4199.0 2489.5 4229.0 DrawSplineSection + 2489.5 4229.0 2640.0 4259.0 2790.0 4259.0 DrawSplineSection + 2790.0 4259.0 2940.0 4259.0 3089.5 4259.0 DrawSplineSection + 3089.5 4259.0 3239.0 4259.0 3329.0 4349.0 DrawSplineSection + 3329.0 4349.0 3419.0 4439.0 3479.0 4439.0 DrawSplineSection + 3479.0 4439.0 3539.0 4439.0 3599.0 4439.0 DrawSplineSection + 3599.0 4439.0 3659.0 4439.0 3779.0 4379.0 DrawSplineSection + 3779.0 4379.0 3899.0 4319.0 3869.0 4199.0 DrawSplineSection + 3869.0 4199.0 3839.0 4079.0 3869.0 3989.0 DrawSplineSection + 3869.0 3989.0 3899.0 3899.0 4019.0 3809.0 DrawSplineSection + 4019.0 3809.0 4139.0 3719.0 4169.0 3689.0 DrawSplineSection + 4169.0 3689.0 4199.0 3659.0 4199.0 3509.5 DrawSplineSection + 4199.0 3509.5 4199.0 3360.0 4019.0 3240.0 DrawSplineSection + 4019.0 3240.0 3839.0 3120.0 3779.0 3090.0 DrawSplineSection + 3779.0 3090.0 3719.0 3060.0 3539.0 3030.0 DrawSplineSection + 3539.0 3030.0 3359.0 3000.0 3209.0 3000.0 DrawSplineSection + 3209.0 3000.0 3059.0 3000.0 2969.5 3000.0 DrawSplineSection + 2969.5 3000.0 2880.0 3000.0 2820.0 3060.0 DrawSplineSection + 2820.0 3060.0 2760.0 3120.0 2700.0 3120.0 DrawSplineSection + 2700.0 3120.0 2640.0 3120.0 2609.5 3120.0 DrawSplineSection + 2609.5 3120.0 2579.0 3120.0 2489.0 3150.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 6349.5 6331.0 m + 6349.5 6331.0 6304.0 6347.0 6259.0 6361.5 DrawSplineSection + 6259.0 6361.5 6214.0 6376.0 6138.0 6436.5 DrawSplineSection + 6138.0 6436.5 6062.0 6497.0 6033.0 6527.0 DrawSplineSection + 6033.0 6527.0 6004.0 6557.0 6004.0 6602.5 DrawSplineSection + 6004.0 6602.5 6004.0 6648.0 6004.0 6678.0 DrawSplineSection + 6004.0 6678.0 6004.0 6708.0 6033.0 6738.0 DrawSplineSection + 6033.0 6738.0 6062.0 6768.0 6092.5 6798.0 DrawSplineSection + 6092.5 6798.0 6123.0 6828.0 6138.5 6828.0 DrawSplineSection + 6138.5 6828.0 6154.0 6828.0 6214.5 6844.0 DrawSplineSection + 6214.5 6844.0 6275.0 6860.0 6350.0 6874.5 DrawSplineSection + 6350.0 6874.5 6425.0 6889.0 6500.5 6889.0 DrawSplineSection + 6500.5 6889.0 6576.0 6889.0 6651.5 6889.0 DrawSplineSection + 6651.5 6889.0 6727.0 6889.0 6772.0 6934.0 DrawSplineSection + 6772.0 6934.0 6817.0 6979.0 6847.0 6979.0 DrawSplineSection + 6847.0 6979.0 6877.0 6979.0 6907.0 6979.0 DrawSplineSection + 6907.0 6979.0 6937.0 6979.0 6997.5 6949.0 DrawSplineSection + 6997.5 6949.0 7058.0 6919.0 7043.0 6858.5 DrawSplineSection + 7043.0 6858.5 7028.0 6798.0 7043.0 6753.0 DrawSplineSection + 7043.0 6753.0 7058.0 6708.0 7118.5 6663.0 DrawSplineSection + 7118.5 6663.0 7179.0 6618.0 7194.0 6602.0 DrawSplineSection + 7194.0 6602.0 7209.0 6586.0 7209.0 6511.5 DrawSplineSection + 7209.0 6511.5 7209.0 6437.0 7118.5 6376.0 DrawSplineSection + 7118.5 6376.0 7028.0 6315.0 6998.0 6301.0 DrawSplineSection + 6998.0 6301.0 6968.0 6287.0 6877.5 6272.0 DrawSplineSection + 6877.5 6272.0 6787.0 6257.0 6711.5 6257.0 DrawSplineSection + 6711.5 6257.0 6636.0 6257.0 6590.0 6257.0 DrawSplineSection + 6590.0 6257.0 6544.0 6257.0 6514.0 6286.0 DrawSplineSection + 6514.0 6286.0 6484.0 6315.0 6454.5 6315.0 DrawSplineSection + 6454.5 6315.0 6425.0 6315.0 6410.0 6315.0 DrawSplineSection + 6410.0 6315.0 6395.0 6315.0 6349.5 6331.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 6860.0 4878.0 m + 6860.0 4878.0 6795.0 4901.0 6730.0 4922.0 DrawSplineSection + 6730.0 4922.0 6665.0 4943.0 6556.0 5029.5 DrawSplineSection + 6556.0 5029.5 6447.0 5116.0 6405.5 5159.0 DrawSplineSection + 6405.5 5159.0 6364.0 5202.0 6364.0 5267.5 DrawSplineSection + 6364.0 5267.5 6364.0 5333.0 6364.0 5376.0 DrawSplineSection + 6364.0 5376.0 6364.0 5419.0 6405.5 5462.0 DrawSplineSection + 6405.5 5462.0 6447.0 5505.0 6491.0 5548.0 DrawSplineSection + 6491.0 5548.0 6535.0 5591.0 6557.0 5591.0 DrawSplineSection + 6557.0 5591.0 6579.0 5591.0 6666.0 5614.0 DrawSplineSection + 6666.0 5614.0 6753.0 5637.0 6860.5 5658.0 DrawSplineSection + 6860.5 5658.0 6968.0 5679.0 7076.5 5679.0 DrawSplineSection + 7076.5 5679.0 7185.0 5679.0 7293.5 5679.0 DrawSplineSection + 7293.5 5679.0 7402.0 5679.0 7466.5 5743.5 DrawSplineSection + 7466.5 5743.5 7531.0 5808.0 7574.0 5808.0 DrawSplineSection + 7574.0 5808.0 7617.0 5808.0 7660.0 5808.0 DrawSplineSection + 7660.0 5808.0 7703.0 5808.0 7790.0 5765.0 DrawSplineSection + 7790.0 5765.0 7877.0 5722.0 7855.5 5635.0 DrawSplineSection + 7855.5 5635.0 7834.0 5548.0 7855.5 5483.5 DrawSplineSection + 7855.5 5483.5 7877.0 5419.0 7964.0 5354.5 DrawSplineSection + 7964.0 5354.5 8051.0 5290.0 8072.5 5267.0 DrawSplineSection + 8072.5 5267.0 8094.0 5244.0 8094.0 5137.0 DrawSplineSection + 8094.0 5137.0 8094.0 5030.0 7964.0 4942.5 DrawSplineSection + 7964.0 4942.5 7834.0 4855.0 7791.0 4835.0 DrawSplineSection + 7791.0 4835.0 7748.0 4815.0 7618.0 4793.5 DrawSplineSection + 7618.0 4793.5 7488.0 4772.0 7379.5 4772.0 DrawSplineSection + 7379.5 4772.0 7271.0 4772.0 7205.0 4772.0 DrawSplineSection + 7205.0 4772.0 7139.0 4772.0 7096.0 4813.5 DrawSplineSection + 7096.0 4813.5 7053.0 4855.0 7010.5 4855.0 DrawSplineSection + 7010.5 4855.0 6968.0 4855.0 6946.5 4855.0 DrawSplineSection + 6946.5 4855.0 6925.0 4855.0 6860.0 4878.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 3944.0 6299.0 m + 3944.0 6299.0 3899.0 6314.0 3854.0 6329.5 DrawSplineSection + 3854.0 6329.5 3809.0 6345.0 3734.0 6404.5 DrawSplineSection + 3734.0 6404.5 3659.0 6464.0 3629.5 6494.0 DrawSplineSection + 3629.5 6494.0 3600.0 6524.0 3600.0 6569.0 DrawSplineSection + 3600.0 6569.0 3600.0 6614.0 3600.0 6644.0 DrawSplineSection + 3600.0 6644.0 3600.0 6674.0 3629.5 6703.5 DrawSplineSection + 3629.5 6703.5 3659.0 6733.0 3689.5 6763.0 DrawSplineSection + 3689.5 6763.0 3720.0 6793.0 3735.0 6793.0 DrawSplineSection + 3735.0 6793.0 3750.0 6793.0 3810.0 6808.0 DrawSplineSection + 3810.0 6808.0 3870.0 6823.0 3945.0 6838.0 DrawSplineSection + 3945.0 6838.0 4020.0 6853.0 4095.0 6853.0 DrawSplineSection + 4095.0 6853.0 4170.0 6853.0 4245.0 6853.0 DrawSplineSection + 4245.0 6853.0 4320.0 6853.0 4364.5 6898.0 DrawSplineSection + 4364.5 6898.0 4409.0 6943.0 4439.0 6943.0 DrawSplineSection + 4439.0 6943.0 4469.0 6943.0 4499.0 6943.0 DrawSplineSection + 4499.0 6943.0 4529.0 6943.0 4589.0 6913.0 DrawSplineSection + 4589.0 6913.0 4649.0 6883.0 4634.0 6823.0 DrawSplineSection + 4634.0 6823.0 4619.0 6763.0 4634.0 6718.5 DrawSplineSection + 4634.0 6718.5 4649.0 6674.0 4709.0 6629.0 DrawSplineSection + 4709.0 6629.0 4769.0 6584.0 4784.0 6568.5 DrawSplineSection + 4784.0 6568.5 4799.0 6553.0 4799.0 6478.5 DrawSplineSection + 4799.0 6478.5 4799.0 6404.0 4709.0 6344.0 DrawSplineSection + 4709.0 6344.0 4619.0 6284.0 4589.0 6269.0 DrawSplineSection + 4589.0 6269.0 4559.0 6254.0 4469.0 6239.5 DrawSplineSection + 4469.0 6239.5 4379.0 6225.0 4304.0 6225.0 DrawSplineSection + 4304.0 6225.0 4229.0 6225.0 4184.0 6225.0 DrawSplineSection + 4184.0 6225.0 4139.0 6225.0 4109.0 6254.5 DrawSplineSection + 4109.0 6254.5 4079.0 6284.0 4049.5 6284.0 DrawSplineSection + 4049.5 6284.0 4020.0 6284.0 4004.5 6284.0 DrawSplineSection + 4004.5 6284.0 3989.0 6284.0 3944.0 6299.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 1762.5 1087.5 m + 1762.5 1087.5 1650.0 1125.0 1537.5 1162.5 DrawSplineSection + 1537.5 1162.5 1425.0 1200.0 1237.5 1350.0 DrawSplineSection + 1237.5 1350.0 1050.0 1500.0 975.0 1575.0 DrawSplineSection + 975.0 1575.0 900.0 1650.0 900.0 1762.5 DrawSplineSection + 900.0 1762.5 900.0 1875.0 900.0 1950.0 DrawSplineSection + 900.0 1950.0 900.0 2025.0 975.0 2100.0 DrawSplineSection + 975.0 2100.0 1050.0 2175.0 1125.0 2250.0 DrawSplineSection + 1125.0 2250.0 1200.0 2325.0 1237.5 2325.0 DrawSplineSection + 1237.5 2325.0 1275.0 2325.0 1425.0 2362.5 DrawSplineSection + 1425.0 2362.5 1575.0 2400.0 1762.5 2437.5 DrawSplineSection + 1762.5 2437.5 1950.0 2475.0 2137.5 2475.0 DrawSplineSection + 2137.5 2475.0 2325.0 2475.0 2512.5 2475.0 DrawSplineSection + 2512.5 2475.0 2700.0 2475.0 2812.5 2587.5 DrawSplineSection + 2812.5 2587.5 2925.0 2700.0 3000.0 2700.0 DrawSplineSection + 3000.0 2700.0 3075.0 2700.0 3150.0 2700.0 DrawSplineSection + 3150.0 2700.0 3225.0 2700.0 3375.0 2625.0 DrawSplineSection + 3375.0 2625.0 3525.0 2550.0 3487.5 2400.0 DrawSplineSection + 3487.5 2400.0 3450.0 2250.0 3487.5 2137.5 DrawSplineSection + 3487.5 2137.5 3525.0 2025.0 3675.0 1912.5 DrawSplineSection + 3675.0 1912.5 3825.0 1800.0 3862.5 1762.5 DrawSplineSection + 3862.5 1762.5 3900.0 1725.0 3900.0 1537.5 DrawSplineSection + 3900.0 1537.5 3900.0 1350.0 3675.0 1200.0 DrawSplineSection + 3675.0 1200.0 3450.0 1050.0 3375.0 1012.5 DrawSplineSection + 3375.0 1012.5 3300.0 975.0 3075.0 937.5 DrawSplineSection + 3075.0 937.5 2850.0 900.0 2662.5 900.0 DrawSplineSection + 2662.5 900.0 2475.0 900.0 2362.5 900.0 DrawSplineSection + 2362.5 900.0 2250.0 900.0 2175.0 975.0 DrawSplineSection + 2175.0 975.0 2100.0 1050.0 2025.0 1050.0 DrawSplineSection + 2025.0 1050.0 1950.0 1050.0 1912.5 1050.0 DrawSplineSection + 1912.5 1050.0 1875.0 1050.0 1762.5 1087.5 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 3270.0 4907.5 m + 3270.0 4907.5 3205.0 4929.0 3140.5 4950.5 DrawSplineSection + 3140.5 4950.5 3076.0 4972.0 2968.5 5058.0 DrawSplineSection + 2968.5 5058.0 2861.0 5144.0 2818.0 5187.0 DrawSplineSection + 2818.0 5187.0 2775.0 5230.0 2775.0 5294.5 DrawSplineSection + 2775.0 5294.5 2775.0 5359.0 2775.0 5402.5 DrawSplineSection + 2775.0 5402.5 2775.0 5446.0 2818.0 5489.0 DrawSplineSection + 2818.0 5489.0 2861.0 5532.0 2904.0 5575.0 DrawSplineSection + 2904.0 5575.0 2947.0 5618.0 2969.0 5618.0 DrawSplineSection + 2969.0 5618.0 2991.0 5618.0 3077.0 5639.5 DrawSplineSection + 3077.0 5639.5 3163.0 5661.0 3270.5 5682.5 DrawSplineSection + 3270.5 5682.5 3378.0 5704.0 3486.0 5704.0 DrawSplineSection + 3486.0 5704.0 3594.0 5704.0 3701.5 5704.0 DrawSplineSection + 3701.5 5704.0 3809.0 5704.0 3874.0 5768.5 DrawSplineSection + 3874.0 5768.5 3939.0 5833.0 3982.0 5833.0 DrawSplineSection + 3982.0 5833.0 4025.0 5833.0 4068.0 5833.0 DrawSplineSection + 4068.0 5833.0 4111.0 5833.0 4197.5 5790.0 DrawSplineSection + 4197.5 5790.0 4284.0 5747.0 4262.5 5661.0 DrawSplineSection + 4262.5 5661.0 4241.0 5575.0 4262.5 5510.5 DrawSplineSection + 4262.5 5510.5 4284.0 5446.0 4370.0 5381.5 DrawSplineSection + 4370.0 5381.5 4456.0 5317.0 4477.5 5295.0 DrawSplineSection + 4477.5 5295.0 4499.0 5273.0 4499.0 5165.5 DrawSplineSection + 4499.0 5165.5 4499.0 5058.0 4370.0 4972.0 DrawSplineSection + 4370.0 4972.0 4241.0 4886.0 4197.5 4864.5 DrawSplineSection + 4197.5 4864.5 4154.0 4843.0 4025.0 4821.5 DrawSplineSection + 4025.0 4821.5 3896.0 4800.0 3788.0 4800.0 DrawSplineSection + 3788.0 4800.0 3680.0 4800.0 3615.5 4800.0 DrawSplineSection + 3615.5 4800.0 3551.0 4800.0 3508.0 4843.0 DrawSplineSection + 3508.0 4843.0 3465.0 4886.0 3421.5 4886.0 DrawSplineSection + 3421.5 4886.0 3378.0 4886.0 3356.5 4886.0 DrawSplineSection + 3356.5 4886.0 3335.0 4886.0 3270.0 4907.5 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 7248.5 3162.0 m + 7248.5 3162.0 7161.0 3193.0 7073.0 3221.5 DrawSplineSection + 7073.0 3221.5 6985.0 3250.0 6838.0 3366.5 DrawSplineSection + 6838.0 3366.5 6691.0 3483.0 6635.0 3541.0 DrawSplineSection + 6635.0 3541.0 6579.0 3599.0 6579.0 3687.5 DrawSplineSection + 6579.0 3687.5 6579.0 3776.0 6579.0 3834.0 DrawSplineSection + 6579.0 3834.0 6579.0 3892.0 6635.0 3950.0 DrawSplineSection + 6635.0 3950.0 6691.0 4008.0 6750.5 4066.0 DrawSplineSection + 6750.5 4066.0 6810.0 4124.0 6839.5 4124.0 DrawSplineSection + 6839.5 4124.0 6869.0 4124.0 6986.5 4155.0 DrawSplineSection + 6986.5 4155.0 7104.0 4186.0 7249.0 4214.5 DrawSplineSection + 7249.0 4214.5 7394.0 4243.0 7540.5 4243.0 DrawSplineSection + 7540.5 4243.0 7687.0 4243.0 7833.5 4243.0 DrawSplineSection + 7833.5 4243.0 7980.0 4243.0 8067.0 4330.0 DrawSplineSection + 8067.0 4330.0 8154.0 4417.0 8212.0 4417.0 DrawSplineSection + 8212.0 4417.0 8270.0 4417.0 8328.0 4417.0 DrawSplineSection + 8328.0 4417.0 8386.0 4417.0 8503.5 4359.0 DrawSplineSection + 8503.5 4359.0 8621.0 4301.0 8592.0 4183.5 DrawSplineSection + 8592.0 4183.5 8563.0 4066.0 8592.0 3979.0 DrawSplineSection + 8592.0 3979.0 8621.0 3892.0 8738.5 3805.0 DrawSplineSection + 8738.5 3805.0 8856.0 3718.0 8885.0 3687.0 DrawSplineSection + 8885.0 3687.0 8914.0 3656.0 8914.0 3511.5 DrawSplineSection + 8914.0 3511.5 8914.0 3367.0 8738.5 3249.0 DrawSplineSection + 8738.5 3249.0 8563.0 3131.0 8505.0 3104.0 DrawSplineSection + 8505.0 3104.0 8447.0 3077.0 8271.5 3048.0 DrawSplineSection + 8271.5 3048.0 8096.0 3019.0 7949.5 3019.0 DrawSplineSection + 7949.5 3019.0 7803.0 3019.0 7714.0 3019.0 DrawSplineSection + 7714.0 3019.0 7625.0 3019.0 7567.0 3075.0 DrawSplineSection + 7567.0 3075.0 7509.0 3131.0 7451.5 3131.0 DrawSplineSection + 7451.5 3131.0 7394.0 3131.0 7365.0 3131.0 DrawSplineSection + 7365.0 3131.0 7336.0 3131.0 7248.5 3162.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 5181.5 7273.5 m + 5181.5 7273.5 5151.0 7284.0 5121.0 7294.0 DrawSplineSection + 5121.0 7294.0 5091.0 7304.0 5040.5 7344.0 DrawSplineSection + 5040.5 7344.0 4990.0 7384.0 4970.5 7404.0 DrawSplineSection + 4970.5 7404.0 4951.0 7424.0 4951.0 7454.5 DrawSplineSection + 4951.0 7454.5 4951.0 7485.0 4951.0 7505.0 DrawSplineSection + 4951.0 7505.0 4951.0 7525.0 4970.5 7545.0 DrawSplineSection + 4970.5 7545.0 4990.0 7565.0 5010.5 7585.0 DrawSplineSection + 5010.5 7585.0 5031.0 7605.0 5041.0 7605.0 DrawSplineSection + 5041.0 7605.0 5051.0 7605.0 5091.5 7615.5 DrawSplineSection + 5091.5 7615.5 5132.0 7626.0 5182.0 7636.0 DrawSplineSection + 5182.0 7636.0 5232.0 7646.0 5282.5 7646.0 DrawSplineSection + 5282.5 7646.0 5333.0 7646.0 5383.5 7646.0 DrawSplineSection + 5383.5 7646.0 5434.0 7646.0 5464.0 7676.0 DrawSplineSection + 5464.0 7676.0 5494.0 7706.0 5514.0 7706.0 DrawSplineSection + 5514.0 7706.0 5534.0 7706.0 5554.0 7706.0 DrawSplineSection + 5554.0 7706.0 5574.0 7706.0 5614.5 7686.0 DrawSplineSection + 5614.5 7686.0 5655.0 7666.0 5645.0 7625.5 DrawSplineSection + 5645.0 7625.5 5635.0 7585.0 5645.0 7555.0 DrawSplineSection + 5645.0 7555.0 5655.0 7525.0 5695.5 7495.0 DrawSplineSection + 5695.5 7495.0 5736.0 7465.0 5746.0 7454.5 DrawSplineSection + 5746.0 7454.5 5756.0 7444.0 5756.0 7394.0 DrawSplineSection + 5756.0 7394.0 5756.0 7344.0 5695.5 7303.5 DrawSplineSection + 5695.5 7303.5 5635.0 7263.0 5615.0 7253.5 DrawSplineSection + 5615.0 7253.5 5595.0 7244.0 5534.5 7234.0 DrawSplineSection + 5534.5 7234.0 5474.0 7224.0 5423.5 7224.0 DrawSplineSection + 5423.5 7224.0 5373.0 7224.0 5342.5 7224.0 DrawSplineSection + 5342.5 7224.0 5312.0 7224.0 5292.0 7243.5 DrawSplineSection + 5292.0 7243.5 5272.0 7263.0 5252.0 7263.0 DrawSplineSection + 5252.0 7263.0 5232.0 7263.0 5222.0 7263.0 DrawSplineSection + 5222.0 7263.0 5212.0 7263.0 5181.5 7273.5 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +% Closed spline +gs n 7727.0 1143.0 m + 7727.0 1143.0 7618.0 1182.0 7508.5 1217.5 DrawSplineSection + 7508.5 1217.5 7399.0 1253.0 7216.0 1398.0 DrawSplineSection + 7216.0 1398.0 7033.0 1543.0 6963.5 1615.0 DrawSplineSection + 6963.5 1615.0 6894.0 1687.0 6894.0 1797.0 DrawSplineSection + 6894.0 1797.0 6894.0 1907.0 6894.0 1979.5 DrawSplineSection + 6894.0 1979.5 6894.0 2052.0 6963.5 2124.0 DrawSplineSection + 6963.5 2124.0 7033.0 2196.0 7107.0 2268.0 DrawSplineSection + 7107.0 2268.0 7181.0 2340.0 7218.0 2340.0 DrawSplineSection + 7218.0 2340.0 7255.0 2340.0 7401.0 2378.5 DrawSplineSection + 7401.0 2378.5 7547.0 2417.0 7727.5 2452.5 DrawSplineSection + 7727.5 2452.5 7908.0 2488.0 8090.5 2488.0 DrawSplineSection + 8090.5 2488.0 8273.0 2488.0 8455.5 2488.0 DrawSplineSection + 8455.5 2488.0 8638.0 2488.0 8746.0 2596.5 DrawSplineSection + 8746.0 2596.5 8854.0 2705.0 8926.5 2705.0 DrawSplineSection + 8926.5 2705.0 8999.0 2705.0 9071.0 2705.0 DrawSplineSection + 9071.0 2705.0 9143.0 2705.0 9289.0 2633.0 DrawSplineSection + 9289.0 2633.0 9435.0 2561.0 9399.0 2414.5 DrawSplineSection + 9399.0 2414.5 9363.0 2268.0 9399.0 2160.0 DrawSplineSection + 9399.0 2160.0 9435.0 2052.0 9581.5 1943.5 DrawSplineSection + 9581.5 1943.5 9728.0 1835.0 9764.0 1796.5 DrawSplineSection + 9764.0 1796.5 9800.0 1758.0 9800.0 1578.0 DrawSplineSection + 9800.0 1578.0 9800.0 1398.0 9581.5 1251.0 DrawSplineSection + 9581.5 1251.0 9363.0 1104.0 9291.0 1070.5 DrawSplineSection + 9291.0 1070.5 9219.0 1037.0 9000.5 1001.0 DrawSplineSection + 9000.5 1001.0 8782.0 965.0 8599.5 965.0 DrawSplineSection + 8599.5 965.0 8417.0 965.0 8306.5 965.0 DrawSplineSection + 8306.5 965.0 8196.0 965.0 8123.5 1034.5 DrawSplineSection + 8123.5 1034.5 8051.0 1104.0 7979.5 1104.0 DrawSplineSection + 7979.5 1104.0 7908.0 1104.0 7872.0 1104.0 DrawSplineSection + 7872.0 1104.0 7836.0 1104.0 7727.0 1143.0 DrawSplineSection closepath gs col7 1.00 shd ef gr gs col-1 s gr + gr + +/Times-Italic ff 240.00 scf sf +2085 1605 m +gs 1 -1 sc (G) col-1 sh gr +/Times-Italic ff 240.00 scf sf +7060 1933 m +gs 1 -1 sc (G) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4245 6615 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2265 1650 m +gs 1 -1 sc (O) col-1 sh gr +/Times-Italic ff 240.00 scf sf +4650 7545 m +gs 1 -1 sc (G) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4830 7590 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Italic ff 240.00 scf sf +4065 6570 m +gs 1 -1 sc (G) col-1 sh gr +15.000 slw +% Interp Spline +gs n 5164 7462 m + 5236.3 7457.9 5267.6 7454.1 5289 7447 curveto + 5313.9 7438.7 5365.7 7414.4 5384 7392 curveto + 5405.1 7366.2 5419.2 7301.3 5424 7272 curveto + 5425.3 7264.2 5425.3 7252.9 5424 7227 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 5364 7417 m + 5396.1 7469.8 5408.6 7493.6 5414 7512 curveto + 5421.5 7537.2 5422.9 7596.8 5424 7622 curveto + 5424.2 7627.1 5424.2 7634.6 5424 7652 curveto + gs col2 s gr + gr + +/Times-Roman ff 150.00 scf sf +3690 5355 m +gs 1 -1 sc (2) col-1 sh gr +% Interp Spline +gs n 5419 7512 m + 5497.0 7511.7 5530.8 7513.0 5554 7517 curveto + 5571.1 7520.0 5594.9 7527.5 5649 7547 curveto + gs col2 s gr + gr + +/Times-Roman ff 150.00 scf sf +2925 3735 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Italic ff 240.00 scf sf +3510 5310 m +gs 1 -1 sc (G) col-1 sh gr +% Interp Spline +gs n 6323 6613 m + 6431.2 6607.1 6477.9 6601.6 6510 6591 curveto + 6547.2 6578.6 6625.9 6547.1 6652 6509 curveto + 6679.7 6468.6 6686.4 6381.0 6679 6337 curveto + 6676.3 6320.9 6666.3 6302.1 6639 6262 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 5069 7327 m + 5126.5 7400.3 5149.0 7434.0 5159 7462 curveto + 5167.3 7485.1 5178.5 7535.4 5169 7562 curveto + 5163.0 7578.8 5148.0 7593.8 5109 7622 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6697 6441 m + 6822.7 6491.2 6878.2 6510.2 6919 6517 curveto + 6960.8 6523.9 7057.0 6524.9 7099 6517 curveto + 7115.9 6513.8 7138.4 6505.1 7189 6482 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6704 6688 m + 6821.3 6688.0 6871.9 6689.9 6906 6696 curveto + 6932.3 6700.3 6967.8 6711.6 7049 6741 curveto + gs col2 s gr + gr + +/Times-Roman ff 150.00 scf sf +6204 6752 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Italic ff 240.00 scf sf +6024 6707 m +gs 1 -1 sc (G) col-1 sh gr +/Times-Italic ff 240.00 scf sf +2745 3690 m +gs 1 -1 sc (G) col-1 sh gr +% Interp Spline +gs n 5414 7347 m + 5498.1 7392.1 5535.6 7409.6 5564 7417 curveto + 5595.0 7425.1 5667.3 7429.7 5699 7427 curveto + 5709.9 7426.1 5724.9 7422.3 5759 7412 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6784 5287 m + 6961.1 5277.3 7037.6 5268.3 7090 5251 curveto + 7143.4 5233.4 7256.4 5188.6 7294 5134 curveto + 7334.0 5076.0 7343.5 4950.1 7333 4887 curveto + 7329.2 4863.9 7314.9 4836.9 7276 4779 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7251 5187 m + 7301.1 5309.2 7320.6 5362.9 7329 5402 curveto + 7338.6 5446.5 7346.2 5551.6 7344 5597 curveto + 7343.3 5612.0 7339.5 5633.3 7329 5682 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7324 5067 m + 7527.1 5118.7 7615.6 5138.2 7678 5145 curveto + 7737.3 5151.4 7875.9 5156.2 7936 5145 curveto + 7960.2 5140.5 7992.4 5128.0 8065 5095 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7334 5437 m + 7519.4 5405.0 7600.6 5396.3 7659 5402 curveto + 7697.4 5405.8 7748.6 5421.8 7864 5466 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6181 6411 m + 6271.0 6516.2 6304.8 6566.7 6316 6613 curveto + 6325.2 6651.1 6311.1 6727.8 6299 6762 curveto + 6292.5 6780.4 6278.0 6803.2 6241 6853 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6922 3317 m + 7073.0 3532.6 7130.7 3631.8 7153 3714 curveto + 7170.7 3781.6 7171.5 3929.4 7151 3997 curveto + 7140.1 4034.8 7111.8 4078.7 7038 4173 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7146 3714 m + 7384.9 3700.9 7488.1 3688.7 7559 3665 curveto + 7630.9 3641.6 7783.5 3581.1 7834 3507 curveto + 7888.2 3429.2 7901.0 3259.4 7887 3174 curveto + 7881.7 3143.0 7862.5 3106.6 7810 3028 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7776 3579 m + 7843.8 3743.9 7870.1 3816.4 7881 3869 curveto + 7894.4 3929.2 7904.7 4071.1 7902 4132 curveto + 7900.7 4152.5 7895.7 4181.2 7881 4247 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7875 3417 m + 8146.4 3493.1 8266.0 3519.3 8353 3522 curveto + 8437.3 3524.6 8624.4 3497.7 8704 3467 curveto + 8736.2 3454.6 8776.2 3428.3 8864 3362 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7888 3916 m + 8138.4 3873.2 8248.1 3861.4 8327 3869 curveto + 8378.7 3874.2 8447.8 3895.8 8604 3955 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6622 6546 m + 6670.2 6625.2 6688.9 6660.8 6697 6688 curveto + 6708.2 6726.2 6710.3 6815.4 6712 6853 curveto + 6712.4 6860.9 6712.4 6872.1 6712 6898 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7321 1336 m + 7508.8 1604.2 7580.6 1727.7 7608 1830 curveto + 7630.4 1914.2 7631.4 2098.2 7606 2182 curveto + 7592.3 2229.4 7557.1 2283.9 7465 2401 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 7600 1830 m + 7896.9 1813.7 8025.4 1798.6 8114 1769 curveto + 8203.1 1739.9 8393.0 1664.6 8456 1572 curveto + 8523.3 1475.5 8539.3 1264.2 8522 1158 curveto + 8515.2 1119.3 8491.3 1074.0 8426 976 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 8384 1662 m + 8468.1 1867.2 8500.8 1957.5 8514 2023 curveto + 8531.1 2097.9 8543.9 2274.4 8541 2350 curveto + 8538.9 2375.8 8532.6 2411.5 8514 2493 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 8507 1460 m + 8844.8 1555.1 8993.5 1587.8 9102 1591 curveto + 9206.7 1594.2 9439.5 1560.8 9539 1523 curveto + 9578.7 1507.2 9628.5 1474.5 9738 1392 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 8523 2081 m + 8834.7 2028.2 8971.2 2013.5 9069 2023 curveto + 9133.7 2029.4 9219.8 2056.3 9414 2130 curveto + gs col2 s gr + gr + +% Interp Spline +gs n 6618 4993 m + 6730.0 5152.6 6772.7 5226.1 6789 5287 curveto + 6802.4 5337.1 6803.0 5446.7 6788 5497 curveto + 6779.7 5524.8 6758.7 5557.3 6704 5627 curveto + gs col2 s gr + gr + +/Times-Roman ff 150.00 scf sf +7240 1978 m +gs 1 -1 sc (O) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6864 3882 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Italic ff 240.00 scf sf +6684 3837 m +gs 1 -1 sc (G) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6609 5442 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Italic ff 240.00 scf sf +6429 5397 m +gs 1 -1 sc (G) col-1 sh gr +7.500 slw +% Arc +gs clippath +3523 7341 m 3649 7416 l 3504 7398 l 3679 7458 l 3699 7402 l cp clip +n 4758.3 4091.7 3505.0 -155.3 108.0 arcn +gs col-1 s gr + gr + +% arrowhead +n 3523 7341 m 3649 7416 l 3504 7398 l 3536 7377 l 3523 7341 l cp gs 0.00 setgray ef gr col-1 s +% Arc +gs clippath +9389 3098 m 9381 2951 l 9447 3083 l 9400 2903 l 9342 2918 l cp clip +n 5725.6 3971.0 3796.4 68.4 -16.0 arcn +gs col-1 s gr + gr + +% arrowhead +n 9389 3098 m 9381 2951 l 9447 3083 l 9412 3067 l 9389 3098 l cp gs 0.00 setgray ef gr col-1 s +/Helvetica-Bold ff 210.00 scf sf +1050 4200 m +gs 1 -1 sc 90.0 rot (Coarsening Phase) dup sw pop 2 div neg 0 rm col4 sh gr +/Helvetica-Bold ff 210.00 scf sf +9750 4200 m +gs 1 -1 sc 270.0 rot (Uncoarsening Phase) dup sw pop 2 div neg 0 rm col4 sh gr +/Helvetica-Bold ff 210.00 scf sf +5400 8025 m +gs 1 -1 sc (Initial Partitioning Phase) dup sw pop 2 div neg 0 rm col4 sh gr +/Helvetica-Bold ff 240.00 scf sf +5400 525 m +gs 1 -1 sc (Multilevel K-way Partitioning) dup sw pop 2 div neg 0 rm col1 sh gr +$F2psEnd +rs + +%%EndDocument + @endspecial 0 3963 a Fx(Figure)43 b(2)p FK(:)108 b Fv(The)34 +b(three)f(phases)h(of)g(m)o(ultile)m(v)m(el)h Fn(k)8 +b Fv(-w)o(a)m(y)33 b(g)o(r)o(aph)g(par)t(titioning.)50 +b(Dur)r(ing)32 b(the)i(coarsening)f(phase)o(,)h(the)g(siz)o(e)h(of)f +(the)g(g)o(r)o(aph)f(is)i(successiv)m(ely)i(decreased.)49 +b(Dur)r(ing)33 b(the)0 4162 y(initial)e(par)t(titioning)e(phase)o(,)g +(a)h Fn(k)8 b Fv(-w)o(a)m(y)30 b(par)t(titioning)g(is)h(computed,)e +(Dur)r(ing)g(the)h(m)o(ultile)m(v)m(el)g(re\002nement)f(\(or)i +(uncoarsening\))e(phase)o(,)g(the)h(par)t(titioning)f(is)i(successiv)m +(ely)i(re\002ned)d(as)g(it)h(is)0 4362 y(projected)e(to)h(the)g(larger) +g(g)o(r)o(aphs)o(.)39 b Fn(G)1594 4390 y Fq(0)1689 4362 +y Fv(is)31 b(the)f(input)g(g)o(r)o(aph,)f(which)g(is)i(the)f(\002nest)h +(g)o(r)o(aph.)39 b Fn(G)3924 4390 y Fl(i)12 b FI(C)p +Fq(1)4150 4362 y Fv(is)31 b(the)f(ne)m(xt)g(le)m(v)m(el)g(coarser)g(g)o +(r)o(aph)f(of)34 b Fn(G)5850 4389 y Fl(i)5900 4362 y +Fv(.)41 b Fn(G)6075 4390 y Fq(4)6170 4362 y Fv(is)31 +b(the)f(coarsest)h(g)o(r)o(aph.)0 4731 y FK(adjacent)50 +b(v)n(ertices)g(of)h(the)g(input)g(graph)g(in)g(order)h(to)f(form)h(a)e +(related)h(coarser)f(graph.)79 b(Computation)52 b(of)f(the)g(initial)g +(partitioning)0 4950 y(is)46 b(performed)g(on)g(the)g(coarsest)f(\(and) +h(hence)f(smallest\))g(of)h(these)g(graphs,)g(and)f(so)h(is)g(v)n(ery)f +(f)n(ast.)64 b(Finally)-11 b(,)48 b(partition)e(re\002nement)g(is)0 +5170 y(performed)54 b(on)f(each)f(le)l(v)n(el)g(graph,)k(from)e(the)f +(coarsest)f(to)h(the)g(\002nest)g(\()p Fs(i.e)o FK(.,)i(original)f +(graph\))f(using)g(a)g(KL/FM-type)h(re\002nement)0 5389 +y(algorithm)42 b([2)q(,)f(9].)51 b(Figure)42 b(2)f(illustrates)h(the)f +(multile)l(v)n(el)g(graph)h(partitioning)g(paradigm.)199 +5608 y(Comparisons)58 b(performed)g(in)h([7])f(ha)m(v)n(e)f(sho)l(wn)g +(that)h(serial)g(multile)l(v)n(el)g Fy(k)10 b FK(-w)n(ay)58 +b(partitioning)h(is)f(o)n(v)n(er)f(50)h(times)g(f)n(aster)g(than)0 +5827 y(multile)l(v)n(el)39 b(spectral)g(bisection)g([12])h(while)g +(producing)f(partitionings)h(that)g(cut)f(10\045)h(to)f(50\045)h(fe)l +(wer)f(edges.)50 b(Our)39 b(e)n(xperiments)g(on)0 6046 +y(a)j(1024-processor)g(Cray)g(T3E)h(ha)m(v)n(e)e(sho)l(wn)h(that)h +FA(P)-7 b(arMETIS)p 3757 6046 50 7 v 61 w(V3)p 4021 6046 +V 59 w(P)g(ar)7 b(tKw)n(a)-5 b(y)43 b FK(can)f(partition)h(a)f +(500-million)h(element)f(3D)g(mesh)0 6265 y(in)g(well)f(under)h(a)f +(minute!)199 6485 y(Recall)d(that)g(we)f(mentioned)i(that)f(if)g(the)g +(graph)g(is)g(well)g(distrib)m(uted)g(among)g(the)g(processors)f +FA(P)-7 b(arMETIS)p 6459 6485 V 61 w(V3)p 6723 6485 V +60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)38 b FK(runs)0 6704 y(f)n(aster)-9 +b(.)79 b(In)51 b(f)n(act,)i(our)e(e)n(xperiments)f(ha)m(v)n(e)f(sho)l +(wn)h(that)h(when)g(we)f(use)g FA(P)-7 b(arMETIS)p 4975 +6704 V 61 w(V3)p 5239 6704 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)51 b FK(to)g(partition)g(a)g(graph)f(that)h(is)0 +6923 y(distrib)m(uted)57 b(according)f(to)h(the)g(partitioning)h +(produced)f(by)g(an)f(earlier)h(call)g(to)g FA(P)-7 b(arMETIS)p +5596 6923 V 61 w(V3)p 5860 6923 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)p FK(,)6715 6863 y Fr(2)6847 6923 y FK(the)57 b(amount)g(of)0 +7142 y(time)40 b(required)f(for)h(this)g(second)e(partitioning)j(is)e +(often)g(reduced)g(by)h(a)f(f)n(actor)h(of)g(tw)n(o)g(to)f(four)-9 +b(.)51 b(The)40 b(reason)f(for)h(this)f(has)g(to)g(do)h(with)0 +7361 y(the)f(inter)m(-processor)g(communication)h(pattern)f(of)h +FA(P)-7 b(arMETIS)p 3793 7361 V 61 w(V3)p 4057 7361 V +59 w(P)g(ar)7 b(tKw)n(a)-5 b(y)p FK(.)51 b(If)40 b(the)f(graph)g(is)g +(initially)h(distrib)m(uted)g(randomly)0 7581 y(\()p +Fs(i.e)p FK(.,)51 b(there)f(are)g(man)n(y)g(interf)n(ace)g(v)n +(ertices\),)h(each)e(processor)h(spends)f(a)h(lot)g(of)h(time)f +(communicating)g(information)i(about)e(these)0 7800 y(interf)n(ace)g(v) +n(ertices)f(to)i(man)n(y)e(other)i(processors.)75 b(On)50 +b(the)g(other)h(hand,)g(if)g(the)f(graph)g(is)g(well)g(distrib)m(uted,) +i(the)e(number)g(of)h(inter)m(-)0 8019 y(f)n(ace)c(v)n(ertices)g(is)g +(much)g(smaller)h(\(as)f(is)g(the)h(number)f(of)h(other)g(processors)e +(with)i(whom)g(each)e(processor)h(has)g(to)h(communicate\),)0 +8238 y(reducing)f(the)f(o)n(v)n(erall)g(runtime)h(of)g(the)g +(partitioner)-9 b(.)67 b(Of)47 b(course,)f(this)h(is)f(the)h(chick)n +(en)f(and)h(e)n(gg)f(problem.)67 b(Ho)l(w)46 b(can)g(we)g(initially)0 +8457 y(distrib)m(ute)53 b(the)g(graph)f(nicely)h(without)g(ha)m(ving)g +(\002rst)g(partitioned)g(it?)86 b(W)-13 b(e)52 b(ha)m(v)n(e)f(de)l(v)n +(eloped)h(one)h(such)f(method)h(for)g(partitioning)0 +8676 y(graphs)h(that)g(correspond)f(to)i(\002nite)f(element)g(meshes.) +87 b(This)54 b(is)g(to)g(quickly)g(compute)g(a)g(f)n(airly)h(good)f +(initial)g(partitioning)h(using)0 8896 y(the)d(coordinate)f(v)l(alues)g +(of)h(the)g(mesh.)82 b(W)-13 b(e)51 b(can)g(then)h(redistrib)m(ute)f +(the)h(graph)g(according)g(to)g(this)f(initial)i(partitioning)f(and)g +(then)0 9115 y(call)46 b FA(P)-7 b(arMETIS)p 1054 9115 +V 60 w(V3)p 1317 9115 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)46 +b FK(on)g(the)g(redistrib)m(uted)f(graph.)68 b FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)52 +b FK(pro)n(vides)45 b(the)h FA(P)-7 b(arMETIS)p 6331 +9115 V 61 w(V3)p 6595 9115 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)0 9334 y FK(routine)59 b(for)g(doing)f(just)h(this.)101 +b(Gi)l(v)n(en)57 b(a)h(graph)h(that)f(is)g(distrib)m(uted)h(among)f +(the)g(processors)f(and)i(the)f(coordinates)g(of)g(the)g(v)n(er)m(-)0 +9553 y(tices,)347 9493 y Fr(3)467 9553 y FA(P)-7 b(arMETIS)p +1235 9553 V 61 w(V3)p 1499 9553 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)49 b FK(quickly)g(computes)e(an)h(initial)h(partitioning)g(using)f +(a)g(space-\002lling)g(curv)n(e)f(method,)0 9772 y(redistrib)m(utes)53 +b(the)g(graph)g(according)g(to)g(this)g(partitioning,)k(and)c(then)g +(calls)f FA(P)-7 b(arMETIS)p 5371 9772 V 61 w(V3)p 5635 +9772 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)53 b FK(to)h(compute)f(the)g +(\002nal)0 9992 y(high-quality)38 b(partitioning.)50 +b(Our)37 b(e)n(xperiments)f(ha)m(v)n(e)f(sho)l(wn)i(that)g +FA(P)-7 b(arMETIS)p 4721 9992 V 61 w(V3)p 4985 9992 V +59 w(P)g(ar)7 b(tGeomKw)n(a)-5 b(y)38 b FK(is)f(often)g(tw)n(o)g(times) +g(f)n(aster)p 0 10280 3120 7 v 174 10401 a Fq(2)239 10449 +y FF(That)d(is,)g(we)f(\002rst)g(call)h FG(P)-5 b(arMETIS)p +1943 10449 40 7 v 46 w(V3)p 2152 10449 V 47 w(P)g(ar)5 +b(tKw)n(a)l(y)33 b FF(to)h(\002nd)g(a)g(good)h(partitioning)g(of)g(a)e +(graph.)44 b(Ne)n(xt)34 b(we)f(mo)n(v)n(e)i(the)f(v)n(ertices)f(of)i +(the)e(graph)i(according)h(to)e(the)0 10607 y(computed)h(partitioning,) +g(and)f(then)g(call)f FG(P)-5 b(arMETIS)p 2572 10607 +V 47 w(V3)p 2782 10607 V 47 w(P)g(ar)5 b(tKw)n(a)l(y)32 +b FF(to)i(partition)g(this)g(same,)f(b)m(ut)h(ne)m(wly)g(distrib)m +(uted,)h(graph.)174 10731 y Fq(3)239 10779 y FG(P)-5 +b(arMETIS)p 856 10779 V 46 w(V3)p 1065 10779 V 48 w(P)g(ar)5 +b(tGeomKw)n(a)l(y)32 b FF(requires)i(the)f(coordinates)i(of)f(the)f +(centers)h(of)g(each)f(element.)3858 11298 y FK(6)p eop +%%Page: 7 7 +7 6 bop 0 166 a FK(than)41 b FA(P)-7 b(arMETIS)p 1095 +166 50 7 v 61 w(V3)p 1359 166 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)p FK(,)41 b(and)h(achie)l(v)n(es)d(identical)i(partition)i(quality) +-11 b(.)203 385 y FA(P)h FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)39 b FK(also)32 b(pro)n(vides)f(the)h +FA(P)-7 b(arMETIS)p 2847 385 V 61 w(P)g(ar)7 b(tGeom)34 +b FK(function)f(for)f(partitioning)i(unstructured)e(graphs)g(when)g +(coordinates)0 604 y(for)53 b(the)f(v)n(ertices)f(are)h(a)m(v)l +(ailable.)82 b FA(P)-7 b(arMETIS)p 2807 604 V 61 w(P)g(ar)7 +b(tGeom)54 b FK(computes)e(a)g(partitioning)h(based)f(only)g(on)g(the)h +(space-\002lling)f(curv)n(e)0 824 y(method.)f(Therefore,)41 +b(it)g(is)g(e)n(xtremely)f(f)n(ast)h(\(often)h(5)f(to)g(10)g(times)g(f) +n(aster)g(than)g FA(P)-7 b(arMETIS)p 5437 824 V 60 w(P)g(ar)7 +b(tGeomKw)n(a)-5 b(y)p FK(\),)42 b(b)m(ut)f(it)h(computes)0 +1043 y(poor)k(quality)g(partitionings)g(\(it)g(may)g(cut)f(2)h(to)g(10) +f(times)h(more)g(edges)e(than)i FA(P)-7 b(arMETIS)p 5346 +1043 V 61 w(P)g(ar)7 b(tGeomKw)n(a)-5 b(y)p FK(\).)65 +b(This)46 b(routine)g(can)0 1262 y(be)53 b(useful)h(for)g(certain)f +(computations)h(in)g(which)f(the)g(use)g(of)h(space-\002lling)g(curv)n +(es)e(is)i(the)f(appropriate)h(partitioning)g(technique)0 +1481 y(\()p Fs(e)n(.g)o FK(.,)41 b Fy(n)7 b FK(-body)42 +b(computations\).)0 1936 y Ft(3.2)199 b(P)-6 b(ar)t(titioning)56 +b(Meshes)e(Directl)m(y)4 2255 y FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(,)69 b(V)-18 +b(ersion)67 b(3.0)g(also)g(pro)n(vides)f(ne)l(w)h(routines)h(that)f +(support)h(the)f(computation)g(of)h(partitionings)g(and)f(repartition-) +0 2474 y(ings)57 b(gi)l(v)n(en)g Fs(meshes)g FK(\(and)g(not)h(graphs\)) +g(as)f(inputs.)99 b(In)58 b(particular)-7 b(,)62 b FA(P)-7 +b(arMETIS)p 4910 2474 V 61 w(V3)p 5174 2474 V 60 w(P)g(ar)7 +b(tMeshKw)n(a)-5 b(y)58 b FK(tak)n(e)g(a)f(mesh)h(as)f(input)0 +2693 y(and)71 b(computes)g(a)g(partitioning)i(of)e(the)h(mesh)f +(elements.)140 b(Internally)-11 b(,)79 b FA(P)-7 b(arMETIS)p +5213 2693 V 61 w(V3)p 5477 2693 V 60 w(P)g(ar)7 b(tMeshKw)n(a)-5 +b(y)72 b FK(uses)f(a)g(mesh-to-)0 2912 y(graph)56 b(routine)h(and)e +(then)h(calls)g(the)g(same)f(core)h(partitioning)g(routine)h(that)f(is) +g(used)f(by)h(both)g FA(P)-7 b(arMETIS)p 6487 2912 V +61 w(V3)p 6751 2912 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)56 +b FK(and)0 3132 y FA(P)-7 b(arMETIS)p 768 3132 V 61 w(V3)p +1032 3132 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 b(y)p FK(.)203 +3351 y FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)65 b FK(pro)n(vides)57 b(no)h(such)f(routines)h(for)h +(computing)f(adapti)l(v)n(e)f(repartitionings)i(directly)f(from)h +(meshes.)99 b(Ho)l(we)l(v)n(er)-7 b(,)61 b(it)0 3570 +y(does)h(pro)n(vide)h(the)g(routine)g FA(P)-7 b(arMETIS)p +2502 3570 V 61 w(V3)p 2766 3570 V 60 w(Mesh2Dual)64 b +FK(for)g(constructing)f(a)f(dual)h(graph)g(gi)l(v)n(en)f(a)h(mesh,)k +(quickly)c(and)g(in)0 3789 y(parallel.)133 b(Since)68 +b(the)h(construction)f(of)h(the)g(dual)g(graph)g(is)f(in)h(parallel,)75 +b(it)69 b(can)f(be)h(used)f(to)g(construct)h(the)g(input)g(graph)f(for) +0 4008 y FA(P)-7 b(arMETIS)p 768 4008 V 61 w(V3)p 1032 +4008 V 60 w(Adaptiv)l(eRepar)7 b(t)p FK(.)199 4228 y(Essentially)-11 +b(,)50 b(both)e FA(P)-7 b(arMETIS)p 2120 4228 V 61 w(V3)p +2384 4228 V 60 w(P)g(ar)7 b(tMeshKw)n(a)-5 b(y)49 b FK(and)f +FA(P)-7 b(arMETIS)p 4647 4228 V 61 w(V3)p 4911 4228 V +60 w(Mesh2Dual)50 b FK(tak)n(e)e(the)g(b)m(urden)g(of)g(writing)h(an)0 +4447 y(ef)l(\002cient)j(mesh-to-graph)g(routine)g(from)g(the)g(user)-9 +b(.)81 b(Our)52 b(e)n(xperiments)f(ha)m(v)n(e)f(sho)l(wn)h(that)h(this) +g(routine)g(typically)g(runs)f(in)h(about)0 4666 y(half)42 +b(the)f(time)h(that)f(it)h(tak)n(es)f(for)46 b FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)48 +b FK(to)42 b(compute)f(a)h(partitioning.)0 5121 y Ft(3.3)199 +b(P)-6 b(ar)t(titioning)56 b(Adaptivel)m(y)f(Re\002ned)f(Meshes)0 +5440 y FK(F)n(or)35 b(lar)m(ge-scale)e(scienti\002c)h(simulations,)i +(the)e(computational)h(requirements)f(of)h(techniques)e(relying)i(on)g +(globally)g(re\002ned)f(meshes)0 5659 y(become)42 b(v)n(ery)g(high,)g +(especially)f(as)h(the)g(comple)n(xity)g(and)g(size)g(of)g(the)g +(problems)h(increase.)52 b(By)42 b(locally)g(re\002ning)h(and)f +(de-re\002ning)0 5878 y(the)55 b(mesh)h(either)f(to)h(capture)f(\003o)l +(w-\002eld)h(phenomena)g(of)f(interest)h([1])g(or)g(to)g(account)f(for) +h(v)l(ariations)f(in)h(errors)g([11],)j(adapti)l(v)n(e)0 +6097 y(methods)38 b(mak)n(e)g(standard)g(computational)g(methods)g +(more)g(cost)g(ef)l(fecti)l(v)n(e.)49 b(The)38 b(ef)l(\002cient)h(e)n +(x)n(ecution)d(of)j(such)e(adapti)l(v)n(e)g(scienti\002c)0 +6316 y(simulations)59 b(on)h(parallel)g(computers)f(requires)h(a)f +(periodic)h(repartitioning)h(of)f(the)f(underlying)i(computational)e +(mesh.)105 b(These)0 6536 y(repartitionings)39 b(should)f(minimize)g +(both)h(the)f(inter)m(-processor)g(communications)g(incurred)g(in)h +(the)f(iterati)l(v)n(e)g(mesh-based)f(compu-)0 6755 y(tation)j(and)f +(the)g(data)g(redistrib)m(ution)h(costs)e(required)i(to)f(balance)g +(the)g(load.)50 b(Hence,)38 b(adapti)l(v)n(e)h(repartitioning)h(is)f(a) +g(multi-objecti)l(v)n(e)0 6974 y(optimization)i(problem.)55 +b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)46 b FK(pro)n(vides)40 b(the)g(routine)g +FA(P)-7 b(arMETIS)p 4408 6974 V 61 w(V3)p 4672 6974 V +60 w(Adaptiv)l(eRepar)7 b(t)42 b FK(for)f(repartitioning)g(such)e +(adap-)0 7193 y(ti)l(v)n(ely)50 b(re\002ned)g(meshes.)76 +b(This)50 b(routine)h(assumes)d(that)j(the)f(mesh)f(is)h(well)g +(distrib)m(uted)g(among)h(the)f(processors,)g(b)m(ut)g(that)h(\(due)f +(to)0 7412 y(mesh)41 b(re\002nement)h(and)f(de-re\002nement\))h(this)f +(distrib)m(ution)h(is)g(poorly)g(load)f(balanced.)199 +7631 y(Repartitioning)53 b(algorithms)f(f)n(all)h(into)g(tw)n(o)f +(general)g(cate)n(gories.)81 b(The)53 b(\002rst)f(cate)n(gory)f +(balances)g(the)h(computation)h(by)f(incre-)0 7851 y(mentally)i(dif)l +(fusing)g(load)g(from)g(those)g(sub-domains)f(that)h(ha)m(v)n(e)e(more) +i(w)n(ork)h(to)e(adjacent)g(sub-domains)h(that)g(ha)m(v)n(e)e(less)h(w) +n(ork.)0 8070 y(These)43 b(schemes)g(are)g(referred)h(to)g(as)g +Fk(dif)m(fusiv)n(e)f(sc)n(hemes)p FK(.)57 b(The)44 b(second)f(cate)n +(gory)g(balances)g(the)g(load)h(by)g(computing)g(an)g(entirely)0 +8289 y(ne)l(w)k(partitioning,)i(and)e(then)h(intelligently)g(mapping)f +(the)g(sub-domains)g(of)h(the)f(ne)l(w)g(partitioning)h(to)g(the)f +(processors)f(such)h(that)0 8508 y(the)57 b(redistrib)m(ution)h(cost)f +(is)g(minimized.)99 b(These)57 b(schemes)f(are)i(generally)f(referred)h +(to)f(as)g Fk(remapping)g(sc)n(hemes)p FK(.)98 b(Remapping)0 +8727 y(schemes)47 b(typically)h(lead)f(to)h(repartitionings)h(that)f +(ha)m(v)n(e)f(smaller)g(edge-cuts,)i(while)f(dif)l(fusi)l(v)n(e)f +(schemes)g(lead)g(to)h(repartitionings)0 8946 y(that)55 +b(incur)f(smaller)h(redistrib)m(ution)g(costs.)89 b(Ho)l(we)l(v)n(er)-7 +b(,)56 b(since)e(these)f(results)h(can)g(v)l(ary)h(signi\002cantly)f +(among)h(dif)l(ferent)g(types)f(of)0 9166 y(applications,)41 +b(it)g(can)g(be)h(dif)l(\002cult)g(to)f(select)g(the)g(best)g +(repartitioning)i(scheme)d(for)i(the)g(job)-7 b(.)199 +9385 y(Recently)c(,)43 b(we)f(de)l(v)n(eloped)g(a)g(Uni\002ed)h +(Repartitioning)h(Algorithm)g([15])f(for)h(adapti)l(v)n(e)d +(repartitioning)j(that)f(combines)g(the)g(best)0 9604 +y(characteristics)60 b(of)i(remapping)g(and)f(dif)l(fusion-based)g +(repartitioning)i(schemes.)109 b(A)62 b(k)n(e)n(y)f(parameter)g(used)g +(by)h(this)f(algorithm)0 9823 y(is)54 b(the)g Fk(ITR)f(F)-16 +b(actor)p FK(.)88 b(This)54 b(parameter)g(describes)f(the)g(ratio)i +(between)e(the)h(time)g(required)g(for)h(performing)g(the)e(inter)m +(-processor)0 10042 y(communications)36 b(incurred)h(during)f(parallel) +h(processing)e(compared)h(to)g(the)h(time)f(to)h(perform)g(the)f(data)g +(redistrib)m(ution)h(associated)0 10262 y(with)e(balancing)g(the)g +(load.)48 b(As)35 b(such,)g(it)g(allo)l(ws)g(us)f(to)i(compute)f(a)f +(single)h(metric)g(that)g(describes)f(the)h(quality)g(of)h(the)f +(repartitioning,)0 10481 y(e)l(v)n(en)40 b(though)i(adapti)l(v)n(e)f +(repartitioning)h(is)f(a)g(multi-objecti)l(v)n(e)h(optimization)g +(problem.)199 10700 y FA(P)-7 b(arMETIS)p 967 10700 V +61 w(V3)p 1231 10700 V 60 w(Adaptiv)l(eRepar)7 b(t)52 +b FK(is)f(a)f(parallel)h(implementation)g(of)g(the)f(Uni\002ed)h +(Repartitioning)g(Algorithm.)79 b(This)51 b(is)f(a)3858 +11298 y(7)p eop +%%Page: 8 8 +8 7 bop 0 166 a FK(multile)l(v)n(el)31 b(partitioning)i(algorithm,)h +(and)d(so,)i(is)e(in)h(nature)f(similar)h(to)g(the)f(the)h(algorithm)g +(implemented)f(in)h FA(P)-7 b(arMETIS)p 7096 166 50 7 +v 61 w(V3)p 7360 166 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)p +FK(.)0 385 y(Ho)l(we)l(v)n(er)e(,)40 b(this)h(routine)h(uses)e(a)g +(technique)h(kno)l(wn)g(as)g Fs(local)g(coar)n(sening)p +FK(.)50 b(Here,)40 b(only)i(v)n(ertices)e(that)h(ha)m(v)n(e)f(been)h +(distrib)m(uted)g(onto)0 604 y(the)f(same)g(processor)g(are)g +(coarsened)g(together)-9 b(.)50 b(On)41 b(the)f(coarsest)f(graph,)i(an) +f(initial)h(partitioning)g(need)f(not)h(be)f(computed,)g(as)g(one)0 +824 y(can)45 b(either)g(be)g(deri)l(v)n(ed)f(from)i(the)g(initial)f +(graph)h(distrib)m(ution)f(\(in)h(the)f(case)f(when)h(sub-domains)g +(are)g(coupled)g(to)g(processors\),)g(or)0 1043 y(else)k(one)h(needs)f +(to)i(be)f(supplied)g(as)f(an)h(input)g(to)h(the)f(routine)g(\(in)h +(the)f(case)f(when)h(sub-domains)g(are)g(de-coupled)f(from)i(proces-)0 +1262 y(sors\).)74 b(Ho)l(we)l(v)n(er)-7 b(,)49 b(this)g(partitioning)h +(does)f(need)f(to)i(be)e(balanced.)73 b(The)50 b(balancing)e(phase)g +(is)h(performed)h(on)f(the)g(coarsest)f(graph)0 1481 +y(twice)42 b(by)g(alternati)l(v)n(e)g(methods.)53 b(That)43 +b(is,)f(optimized)g(v)l(ariants)g(of)h(remapping)f(and)g(dif)l(fusion)h +(algorithms)g([16])g(are)f(both)g(used)g(to)0 1700 y(compute)48 +b(ne)l(w)f(partitionings.)71 b(A)48 b(quality)g(metric)g(for)h(each)e +(of)h(these)g(partitionings)g(is)g(then)g(computed)g(\(using)g(the)g +(ITR)g(F)n(actor\))0 1919 y(and)d(the)f(partitioning)i(with)f(the)g +(highest)f(quality)h(is)g(selected.)60 b(This)45 b(technique)f(tends)g +(to)h(gi)l(v)n(e)g(v)n(ery)f(good)h(points)g(from)g(which)g(to)0 +2139 y(start)i(multile)l(v)n(el)g(re\002nement,)h(re)n(g)o(ardless)e +(of)i(the)f(type)g(of)g(repartitioning)h(problem)g(or)g(the)f(v)l(alue) +f(of)i(the)f(ITR)g(F)n(actor)-9 b(.)68 b(Note)47 b(that)0 +2358 y(the)h(f)n(act)g(that)g(the)g(algorithm)h(computes)e(tw)n(o)h +(initial)h(partitionings)f(does)g(not)g(impact)g(its)g(scalability)f +(as)g(long)i(as)e(the)h(size)f(of)h(the)0 2577 y(coarsest)35 +b(graph)i(is)f(suitably)g(small)g([8].)50 b(Finally)-11 +b(,)38 b(multile)l(v)n(el)e(re\002nement)g(is)g(performed)h(on)g(the)f +(balanced)f(partitioning)j(in)e(order)h(to)0 2796 y(further)i(impro)n +(v)n(e)e(its)h(quality)-11 b(.)51 b(Since)38 b FA(P)-7 +b(arMETIS)p 2989 2796 V 61 w(V3)p 3253 2796 V 59 w(Adaptiv)l(eRepar)7 +b(t)40 b FK(starts)e(from)h(a)f(graph)g(that)g(is)g(already)f(well)h +(distrib)m(uted,)0 3015 y(it)i(is)f(e)n(xtremely)g(f)n(ast.)50 +b(Experiments)40 b(on)g(a)f(1024-processor)g(Cray)h(T3E)g(sho)l(w)f +(that)g FA(P)-7 b(arMETIS)p 5704 3015 V 61 w(V3)p 5968 +3015 V 60 w(Adaptiv)l(eRepar)7 b(t)41 b FK(is)f(able)f(to)0 +3235 y(compute)i(partitionings)h(for)g(a)g(billion-element)g(mesh)f(in) +h(under)f(a)g(minute.)199 3454 y(Appropriate)i(v)l(alues)e(to)i(pass)e +(for)i(the)f(ITR)h(F)n(actor)f(parameter)g(can)f(easily)h(be)g +(determined)g(depending)g(on)h(the)f(times)g(required)0 +3673 y(to)59 b(perform)g(\(i\))h(all)e(inter)m(-processor)h +(communications)f(that)h(ha)m(v)n(e)e(occurred)i(since)f(the)g(last)g +(repartitioning,)64 b(and)58 b(\(ii\))i(the)e(data)0 +3892 y(redistrib)m(ution)45 b(associated)d(with)j(the)f(last)f +(repartitioning/load)j(balancing)d(phase.)58 b(Simply)45 +b(di)l(vide)f(the)g(\002rst)h(time)f(by)g(the)g(second.)0 +4111 y(The)53 b(result)f(is)g(the)h(correct)f(ITR)h(F)n(actor)-9 +b(.)84 b(In)53 b(case)e(these)h(times)g(cannot)g(be)h(ascertained)e(\() +p Fs(e)n(.g)o FK(.,)k(for)e(the)f(\002rst)h(repartitioning/load)0 +4330 y(balancing)39 b(phase\),)f(our)h(e)n(xperiments)f(ha)m(v)n(e)g +(sho)l(wn)g(that)i(v)l(alues)e(between)g(100)h(and)g(1000)g(w)n(ork)g +(well)g(for)h(a)f(v)l(ariety)g(of)g(situations.)199 4550 +y FA(P)-7 b(arMETIS)p 967 4550 V 61 w(V3)p 1231 4550 +V 60 w(Adaptiv)l(eRepar)7 b(t)50 b FK(can)d(be)g(used)g(to)h(load)g +(balance)f(the)g(mesh)h(either)f(before)h(or)g(after)g(mesh)f +(adaptation.)70 b(In)0 4769 y(the)41 b(latter)f(case,)g(each)f +(processor)h(\002rst)h(locally)g(adapts)f(its)h(mesh,)e(leading)i(to)g +(dif)l(ferent)g(processors)f(ha)m(ving)g(dif)l(ferent)h(numbers)g(of)0 +4988 y(elements.)58 b FA(P)-7 b(arMETIS)p 1459 4988 V +61 w(V3)p 1723 4988 V 60 w(Adaptiv)l(eRepar)7 b(t)46 +b FK(can)d(then)h(compute)g(a)g(partitioning)h(in)g(which)f(the)g(load) +g(is)f(balanced.)58 b(Ho)l(we)l(v)n(er)-7 b(,)0 5207 +y(load)55 b(balancing)g(can)g(also)g(be)g(done)g(before)h(adaptation)f +(if)h(the)f(de)n(gree)f(of)i(re\002nement)g(for)g(each)e(element)h(can) +g(be)g(estimated)g Fs(a)0 5426 y(priori)p FK(.)70 b(That)49 +b(is,)g(if)f(we)g(kno)l(w)g(ahead)f(of)h(time)g(into)h(ho)l(w)f(man)n +(y)f(ne)l(w)h(elements)f(each)g(old)i(element)e(will)i(subdi)l(vide,)f +(we)g(can)g(use)0 5646 y(these)j(estimations)f(as)h(the)g(weights)g(of) +h(the)f(v)n(ertices)f(for)i(the)f(graph)g(that)h(corresponds)e(to)i +(the)f(dual)g(of)h(the)f(mesh.)80 b(In)52 b(this)f(case,)0 +5865 y(the)45 b(mesh)g(can)f(be)h(redistrib)m(uted)g(before)g(adaption) +g(tak)n(es)g(place.)61 b(This)45 b(technique)g(can)f(signi\002cantly)h +(reduce)g(data)g(redistrib)m(ution)0 6084 y(times)c([10)q(].)0 +6539 y Ft(3.4)199 b(P)-6 b(ar)t(tition)56 b(Re\002nement)0 +6858 y FA(P)-7 b(arMETIS)p 768 6858 V 61 w(V3)p 1032 +6858 V 60 w(Re\002neKw)n(a)i(y)44 b FK(is)g(the)f(routine)i(pro)n +(vided)e(by)48 b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)50 b FK(to)44 b(impro)n(v)n(e)g(the)g(quality)g +(of)g(an)f(e)n(xisting)h(partitioning.)0 7077 y(Once)51 +b(a)g(graph)h(is)f(partitioned)i(and)e(it)h(has)f(been)g(redistrib)m +(uted)h(accordingly)-11 b(,)53 b FA(P)-7 b(arMETIS)p +5488 7077 V 61 w(V3)p 5752 7077 V 60 w(Re\002neKw)n(a)i(y)52 +b FK(can)f(be)h(called)f(to)0 7296 y(compute)37 b(a)g(ne)l(w)f +(partitioning)i(that)f(further)h(impro)n(v)n(es)e(the)h(quality)-11 +b(.)50 b(Thus,)38 b(lik)n(e)f FA(P)-7 b(arMETIS)p 5512 +7296 V 61 w(V3)p 5776 7296 V 60 w(Adaptiv)l(eRepar)7 +b(t)p FK(,)40 b(this)d(routine)0 7515 y(assumes)j(that)h(the)h(graph)g +(is)f(already)g(well)g(distrib)m(uted)h(among)f(the)h(processors.)199 +7734 y FA(P)-7 b(arMETIS)p 967 7734 V 61 w(V3)p 1231 +7734 V 60 w(Re\002neKw)n(a)i(y)53 b FK(can)f(be)g(used)g(to)h(impro)n +(v)n(e)f(the)g(quality)h(of)g(partitionings)g(that)g(are)f(produced)h +(by)f(other)h(par)m(-)0 7954 y(titioning)71 b(algorithms)f(\(such)g(as) +f(the)h(technique)g(discussed)e(in)j(Section)f(3.1)f(that)h(is)g(used)g +(in)g FA(P)-7 b(arMETIS)p 6633 7954 V 61 w(V3)p 6897 +7954 V 60 w(P)g(ar)7 b(tGeom)p FK(\).)0 8173 y FA(P)-7 +b(arMETIS)p 768 8173 V 61 w(V3)p 1032 8173 V 60 w(Re\002neKw)n(a)i(y)44 +b FK(can)f(also)h(be)f(used)g(repeatedly)h(to)g(further)h(impro)n(v)n +(e)e(the)h(quality)g(of)g(a)g(partitioning.)58 b(That)45 +b(is,)e(we)0 8392 y(can)135 b(call)h FA(P)-7 b(arMETIS)p +1510 8392 V 61 w(V3)p 1774 8392 V 60 w(Re\002neKw)n(a)i(y)p +FK(,)159 b(mo)n(v)n(e)135 b(the)h(graph)g(according)g(to)g(the)g +(partitioning,)160 b(and)135 b(then)h(call)0 8611 y FA(P)-7 +b(arMETIS)p 768 8611 V 61 w(V3)p 1032 8611 V 60 w(Re\002neKw)n(a)i(y)46 +b FK(ag)o(ain.)65 b(Ho)l(we)l(v)n(er)-7 b(,)46 b(each)g(successi)l(v)n +(e)d(call)j(to)h FA(P)-7 b(arMETIS)p 5473 8611 V 61 w(V3)p +5737 8611 V 60 w(Re\002neKw)n(a)i(y)46 b FK(will)h(tend)f(to)g(pro-)0 +8830 y(duce)41 b(smaller)g(impro)n(v)n(ements)g(in)h(quality)-11 +b(.)199 9049 y(Lik)n(e)54 b FA(P)-7 b(arMETIS)p 1323 +9049 V 61 w(V3)p 1587 9049 V 60 w(Adaptiv)l(eRepar)7 +b(t)p FK(,)58 b FA(P)-7 b(arMETIS)p 3650 9049 V 61 w(V3)p +3914 9049 V 60 w(Re\002neKw)n(a)i(y)53 b FK(performs)h(local)g +(coarsening.)86 b(These)53 b(tw)n(o)g(rou-)0 9269 y(tines)g(also)f(use) +h(the)g(same)f(re\002nement)h(algorithm.)86 b(The)54 +b(dif)l(ference)f(is)f(that)h FA(P)-7 b(arMETIS)p 5415 +9269 V 61 w(V3)p 5679 9269 V 60 w(Re\002neKw)n(a)i(y)54 +b FK(does)e(not)h(initially)0 9488 y(balance)d(the)g(partitioning)h(on) +g(the)f(coarsest)f(graph,)j(as)e FA(P)-7 b(arMETIS)p +4120 9488 V 61 w(V3)p 4384 9488 V 60 w(Adaptiv)l(eRepar)7 +b(t)52 b FK(does.)77 b(Instead,)52 b(the)e(assumption)g(is)0 +9707 y(that)57 b(the)g(graph)g(is)g(well)g(distrib)m(uted)g(and)g(the)g +(initial)g(partitioning)h(is)f(balanced.)96 b(Since)57 +b FA(P)-7 b(arMETIS)p 6200 9707 V 61 w(V3)p 6464 9707 +V 60 w(Re\002neKw)n(a)i(y)57 b FK(starts)0 9926 y(from)42 +b(a)g(graph)f(that)h(is)f(well)g(distrib)m(uted,)g(it)h(is)g(v)n(ery)f +(f)n(ast.)3858 11298 y(8)p eop +%%Page: 9 9 +9 8 bop 1500 2836 a @beginspecial 0 @llx 0 @lly 704 @urx +416 @ury 2880 @rwi @setspecial +%%BeginDocument: figures/multiphase.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: multiphase.eps +%%Creator: fig2dev Version 3.2 Patchlevel 1 +%%CreationDate: Thu Feb 15 08:49:41 2001 +%%For: kirk@lnx08.cs.umn.edu (Kirk Schloegel) +%%Orientation: Portrait +%%BoundingBox: 0 0 704 416 +%%Pages: 0 +%%BeginSetup +%%EndSetup +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +-53.0 469.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit +n -1000 8812 m -1000 -1000 l 13612 -1000 l 13612 8812 l cp clip + 0.06000 0.06000 sc +% Polyline +7.500 slw +n 1650 3150 m 2100 2400 l gs col0 s gr +% Polyline +n 2100 2400 m 3300 2100 l gs col0 s gr +% Polyline +n 3300 2100 m 4500 2100 l gs col0 s gr +% Polyline +n 4500 2100 m 5400 3000 l gs col0 s gr +% Polyline +n 5400 3000 m 5700 4200 l gs col0 s gr +% Polyline +n 5700 4200 m 5100 5400 l gs col0 s gr +% Polyline +n 5100 5400 m 3900 5700 l gs col0 s gr +% Polyline +n 3900 5700 m 2700 5700 l gs col0 s gr +% Polyline +n 2700 5700 m 1800 5100 l gs col0 s gr +% Polyline +n 1800 5100 m 2400 3900 l gs col0 s gr +% Polyline +n 2400 3900 m 3525 3300 l gs col0 s gr +% Polyline +n 3525 3300 m 4200 4200 l gs col0 s gr +% Polyline +n 4200 4200 m 3300 4800 l gs col0 s gr +% Polyline +n 3300 4800 m 3300 3900 l gs col0 s gr +% Polyline +n 3300 3900 m 4200 4200 l gs col0 s gr +% Polyline +n 3300 3900 m 3525 3300 l gs col0 s gr +% Polyline +n 3300 4800 m 2700 5700 l gs col0 s gr +% Polyline +n 3300 4800 m 3900 5700 l gs col0 s gr +% Polyline +n 5100 5400 m 4200 4200 l gs col0 s gr +% Polyline +n 4200 4200 m 5700 4200 l gs col0 s gr +% Polyline +n 3900 5700 m 4200 4200 l gs col0 s gr +% Polyline +n 4200 4200 m 5400 3000 l gs col0 s gr +% Polyline +n 3525 3300 m 4500 2100 l gs col0 s gr +% Polyline +n 3525 3300 m 3300 2100 l gs col0 s gr +% Polyline +n 2400 3900 m 1650 3150 l gs col0 s gr +% Polyline +n 2400 3900 m 2100 2400 l gs col0 s gr +% Polyline +n 2100 2400 m 3525 3300 l gs col0 s gr +% Polyline +n 3525 3300 m 5400 3000 l gs col0 s gr +% Polyline +n 3300 3900 m 2400 3900 l gs col0 s gr +% Polyline +n 2400 3900 m 3300 4800 l gs col0 s gr +% Polyline +n 3300 4800 m 1800 5100 l gs col0 s gr +% Polyline +n 1200 4200 m 2400 3900 l gs col0 s gr +% Polyline +n 1800 5100 m 1200 4200 l gs col0 s gr +% Polyline +n 1200 4200 m 1350 3450 l gs col0 s gr +% Polyline +n 1350 3450 m 2400 3900 l gs col0 s gr +% Polyline +n 1350 3450 m 1650 3150 l gs col0 s gr +% Polyline +n 9900 3150 m 9900 2550 l cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9600 2250 m 9300 2250 l cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 3150 m 9900 2550 l 9600 2250 l 9300 2250 l 9600 1950 l 10200 2550 l + 10200 2850 l cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 6750 m 8100 3450 l 7050 2400 l 6300 3150 l 6300 2850 l 6900 2250 l + 6300 1650 l 6300 1350 l 7500 2550 l 8100 1950 l 7500 1350 l + 7800 1350 l 8400 1950 l 9000 1350 l 9300 1350 l 8100 2550 l + 8550 3000 l 8700 2850 l 8700 2250 l 9000 2250 l 9000 2850 l + 9600 2850 l 9600 3150 l 9000 3150 l 8850 3300 l 9300 3750 l + 10500 2550 l 9900 1950 l 9900 1350 l 10200 1350 l 10200 1950 l + 10800 1350 l 11100 1350 l 10500 1950 l 11100 2550 l 11850 1800 l + 11550 1500 l 11700 1350 l 12000 1650 l 12300 1350 l 12300 1650 l + 11700 2250 l 12300 2850 l 12300 3150 l 11700 2550 l 10500 3750 l + 10500 6750 l cp gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 4650 m 10500 4950 l 10200 4950 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 4950 m 10500 5250 l 10200 5250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 5250 m 10500 5550 l 10200 5550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 5550 m 10500 5850 l 10200 5850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 5850 m 10500 6150 l 10200 6150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 6150 m 10500 6450 l 10200 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 4350 m 10500 4650 l 10200 4650 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 4050 m 10500 4350 l 10200 4350 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 3750 m 10500 4050 l 10200 4050 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 3750 m 8400 4050 l 8400 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4050 m 8400 4350 l 8400 4050 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4350 m 8400 4650 l 8400 4350 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4650 m 8400 4950 l 8400 4650 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4950 m 8400 5250 l 8400 4950 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 5250 m 8400 5550 l 8400 5250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 5550 m 8400 5850 l 8400 5550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 5850 m 8400 6150 l 8400 5850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 6150 m 8400 6450 l 8400 6150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 6450 m 8400 6750 l 8400 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 6450 m 8700 6750 l 8700 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8700 6450 m 9000 6750 l 9000 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9000 6450 m 9300 6750 l 9300 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9300 6450 m 9600 6750 l 9600 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9600 6450 m 9900 6750 l 9900 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 6450 m 10200 6750 l 10200 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 3750 m 10200 3750 l 10200 6450 l 8400 6450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8700 3450 m 9000 3750 l 9000 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 3450 m 8700 3750 l 8700 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9600 3450 m 9900 3750 l 9900 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 3150 m 10200 3450 l 10200 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 2850 m 10500 3150 l 10500 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2550 m 10800 2850 l 10800 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2250 m 10800 2550 l 10800 2250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 1950 m 10500 2250 l 10500 1950 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10800 2550 m 11100 2850 l 11100 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10800 2850 m 11100 3150 l 11100 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 3150 m 10800 3450 l 10800 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 3450 m 10500 3750 l 10500 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 3450 m 10200 3750 l 9900 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 3150 m 10500 3450 l 10200 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2850 m 10800 3150 l 10500 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10800 2550 m 11100 2850 l 10800 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2250 m 10800 2550 l 10500 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 1950 m 10500 2250 l 10200 2250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 11400 2250 m 11700 2550 l 11400 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 11100 2550 m 11400 2850 l 11100 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 3150 m 8700 3450 l 8400 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 2850 m 8400 3150 l 8100 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 2850 m 8400 3150 l 8400 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 3150 m 10500 3450 l 10500 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2850 m 10800 3150 l 10800 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 11400 2250 m 11700 2550 l 11700 2250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10800 2850 m 11100 3150 l 10800 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 3150 m 10800 3450 l 10500 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 2850 m 10500 3150 l 10200 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 2550 m 10800 2850 l 10500 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 3150 m 10200 3450 l 9900 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 3450 m 10500 3750 l 10200 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 3450 m 10200 3750 l 10200 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 9600 3450 m 9900 3750 l 9600 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10200 2850 m 9900 3150 l 10200 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 3450 m 8400 3150 l 8400 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 3450 m 8700 3750 l 8400 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8700 3450 m 9000 3750 l 8700 3750 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 3450 m 8400 3750 l 8400 3450 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 3150 m 8100 3450 l 8100 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 3150 m 7500 2850 l 7500 2550 l 8100 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8700 3450 m 8850 3300 l 8550 3000 l 8400 3150 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8700 2850 m 9000 3150 l 9000 2850 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 12000 1650 m 12000 1950 l 11850 1800 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 2550 m 8100 1950 l 8400 1950 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 7050 2400 m 6900 2250 l 7200 2250 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 11400 2850 m 11100 2550 l 11400 2550 l cp gs col2 1.00 shd ef gr gs col0 s gr +% Polyline +n 10500 6750 m 10500 3750 l gs col0 s gr +% Polyline +n 7050 2400 m 8100 3450 l gs col0 s gr +% Polyline +n 10500 3750 m 11700 2550 l gs col0 s gr +% Polyline +n 9300 3750 m 10500 2550 l gs col0 s gr +% Polyline +n 10500 2550 m 9900 1950 l gs col0 s gr +% Polyline +n 7500 2550 m 8100 1950 l gs col0 s gr +% Polyline +n 7500 2550 m 6900 1950 l gs col0 s gr +% Polyline +n 11100 2550 m 10500 1950 l gs col0 s gr +% Polyline +n 7050 2400 m 6300 3150 l 6300 2850 l 6900 2250 l 6300 1650 l 6300 1350 l + 6975 2025 l gs col0 s gr +% Polyline +n 8100 1950 m 7500 1350 l 7800 1350 l 8400 1950 l 9000 1350 l 9300 1350 l + 8700 1950 l gs col0 s gr +% Polyline +n 9900 1950 m 9900 1425 l 9900 1350 l 10200 1350 l 10200 1950 l 10800 1350 l + 11100 1350 l 10500 1950 l gs col0 s gr +% Polyline +n 11700 2550 m 12300 3150 l 12300 2850 l 11700 2250 l 12300 1650 l 12300 1350 l + 12000 1650 l 11700 1350 l 11550 1500 l 11850 1800 l gs col0 s gr +% Polyline +n 8700 1950 m 8100 2550 l gs col0 s gr +% Polyline +n 9300 3750 m 8850 3300 l 9000 3150 l 9600 3150 l 9600 2850 l 9000 2850 l + 9000 2250 l 8700 2250 l 8700 2850 l 8550 3000 l 8100 2550 l gs col0 s gr +% Polyline +n 11100 2550 m 11850 1800 l gs col0 s gr +% Polyline +n 6300 1650 m 6600 1650 l 6600 1950 l 6900 1950 l 6900 2550 l 6600 2550 l + 6600 2850 l 6300 2850 l gs col0 s gr +% Polyline +n 6900 2250 m 7200 2250 l 7050 2400 l 6900 2250 l cp gs col0 s gr +% Polyline +n 7200 2250 m 7200 2550 l 8100 2550 l 8100 1950 l gs col0 s gr +% Polyline +n 7800 1350 m 7800 1650 l 8100 1650 l 8100 1950 l 8700 1950 l 8700 1650 l + 9000 1650 l 9000 1350 l gs col0 s gr +% Polyline +n 7500 2550 m 7500 2850 l 8100 2550 l gs col0 s gr +% Polyline +n 9000 2250 m 8700 2550 l 9000 2550 l 8700 2850 l 9000 2850 l 9000 3150 l + 9300 2850 l 9300 3150 l 9600 2850 l gs col0 s gr +% Polyline +n 9000 3150 m 8700 2850 l 8850 3300 l 8550 3000 l 8100 3450 l 8100 2550 l gs col0 s gr +% Polyline +n 8100 6150 m 8100 3450 l gs col0 s gr +% Polyline +n 8100 3750 m 8100 3450 l 8400 3750 l 8100 3750 l cp gs col0 s gr +% Polyline +n 8100 4050 m 8100 3750 l 8400 4050 l 8100 4050 l cp gs col0 s gr +% Polyline +n 8100 4350 m 8100 4050 l 8400 4350 l 8100 4350 l cp gs col0 s gr +% Polyline +n 8100 4650 m 8100 4350 l 8400 4650 l 8100 4650 l cp gs col0 s gr +% Polyline +n 8100 4950 m 8100 4650 l 8400 4950 l 8100 4950 l cp gs col0 s gr +% Polyline +n 8100 5550 m 8100 5250 l 8400 5550 l 8100 5550 l cp gs col0 s gr +% Polyline +n 8400 3750 m 8400 3450 l 8700 3750 l 8400 3750 l cp gs col0 s gr +% Polyline +n 8400 4050 m 8400 3750 l 8700 4050 l 8400 4050 l cp gs col0 s gr +% Polyline +n 8400 4350 m 8400 4050 l 8700 4350 l 8400 4350 l cp gs col0 s gr +% Polyline +n 8400 4650 m 8400 4350 l 8700 4650 l 8400 4650 l cp gs col0 s gr +% Polyline +n 8400 4950 m 8400 4650 l 8700 4950 l 8400 4950 l cp gs col0 s gr +% Polyline +n 8400 5250 m 8400 4950 l 8700 5250 l 8400 5250 l cp gs col0 s gr +% Polyline +n 8400 5550 m 8400 5250 l 8700 5550 l 8400 5550 l cp gs col0 s gr +% Polyline +n 8700 3750 m 8700 3450 l 9000 3750 l 8700 3750 l cp gs col0 s gr +% Polyline +n 8700 4050 m 8700 3750 l 9000 4050 l 8700 4050 l cp gs col0 s gr +% Polyline +n 8700 4350 m 8700 4050 l 9000 4350 l 8700 4350 l cp gs col0 s gr +% Polyline +n 8700 4650 m 8700 4350 l 9000 4650 l 8700 4650 l cp gs col0 s gr +% Polyline +n 8700 4950 m 8700 4650 l 9000 4950 l 8700 4950 l cp gs col0 s gr +% Polyline +n 8700 5250 m 8700 4950 l 9000 5250 l 8700 5250 l cp gs col0 s gr +% Polyline +n 8700 5550 m 8700 5250 l 9000 5550 l 8700 5550 l cp gs col0 s gr +% Polyline +n 9000 3750 m 9000 3450 l 9300 3750 l 9000 3750 l cp gs col0 s gr +% Polyline +n 9000 4050 m 9000 3750 l 9300 4050 l 9000 4050 l cp gs col0 s gr +% Polyline +n 9000 4350 m 9000 4050 l 9300 4350 l 9000 4350 l cp gs col0 s gr +% Polyline +n 9000 4650 m 9000 4350 l 9300 4650 l 9000 4650 l cp gs col0 s gr +% Polyline +n 9000 4950 m 9000 4650 l 9300 4950 l 9000 4950 l cp gs col0 s gr +% Polyline +n 9000 5250 m 9000 4950 l 9300 5250 l 9000 5250 l cp gs col0 s gr +% Polyline +n 9000 5550 m 9000 5250 l 9300 5550 l 9000 5550 l cp gs col0 s gr +% Polyline +n 9300 4050 m 9300 3750 l 9600 4050 l 9300 4050 l cp gs col0 s gr +% Polyline +n 9300 4350 m 9300 4050 l 9600 4350 l 9300 4350 l cp gs col0 s gr +% Polyline +n 9300 4650 m 9300 4350 l 9600 4650 l 9300 4650 l cp gs col0 s gr +% Polyline +n 9300 4950 m 9300 4650 l 9600 4950 l 9300 4950 l cp gs col0 s gr +% Polyline +n 9300 5250 m 9300 4950 l 9600 5250 l 9300 5250 l cp gs col0 s gr +% Polyline +n 9300 5550 m 9300 5250 l 9600 5550 l 9300 5550 l cp gs col0 s gr +% Polyline +n 9600 3750 m 9600 3450 l 9900 3750 l 9600 3750 l cp gs col0 s gr +% Polyline +n 9600 4050 m 9600 3750 l 9900 4050 l 9600 4050 l cp gs col0 s gr +% Polyline +n 9600 4350 m 9600 4050 l 9900 4350 l 9600 4350 l cp gs col0 s gr +% Polyline +n 9600 4650 m 9600 4350 l 9900 4650 l 9600 4650 l cp gs col0 s gr +% Polyline +n 9600 4950 m 9600 4650 l 9900 4950 l 9600 4950 l cp gs col0 s gr +% Polyline +n 9600 5250 m 9600 4950 l 9900 5250 l 9600 5250 l cp gs col0 s gr +% Polyline +n 9600 5550 m 9600 5250 l 9900 5550 l 9600 5550 l cp gs col0 s gr +% Polyline +n 9900 3750 m 9900 3450 l 10200 3750 l 9900 3750 l cp gs col0 s gr +% Polyline +n 9900 4050 m 9900 3750 l 10200 4050 l 9900 4050 l cp gs col0 s gr +% Polyline +n 9900 4350 m 9900 4050 l 10200 4350 l 9900 4350 l cp gs col0 s gr +% Polyline +n 9900 4650 m 9900 4350 l 10200 4650 l 9900 4650 l cp gs col0 s gr +% Polyline +n 9900 4950 m 9900 4650 l 10200 4950 l 9900 4950 l cp gs col0 s gr +% Polyline +n 9900 5250 m 9900 4950 l 10200 5250 l 9900 5250 l cp gs col0 s gr +% Polyline +n 9900 5550 m 9900 5250 l 10200 5550 l 9900 5550 l cp gs col0 s gr +% Polyline +n 10200 3750 m 10200 3450 l 10500 3750 l 10200 3750 l cp gs col0 s gr +% Polyline +n 10200 4050 m 10200 3750 l 10500 4050 l 10200 4050 l cp gs col0 s gr +% Polyline +n 10200 4350 m 10200 4050 l 10500 4350 l 10200 4350 l cp gs col0 s gr +% Polyline +n 10200 4650 m 10200 4350 l 10500 4650 l 10200 4650 l cp gs col0 s gr +% Polyline +n 10200 4950 m 10200 4650 l 10500 4950 l 10200 4950 l cp gs col0 s gr +% Polyline +n 10200 5250 m 10200 4950 l 10500 5250 l 10200 5250 l cp gs col0 s gr +% Polyline +n 10200 5550 m 10200 5250 l 10500 5550 l 10200 5550 l cp gs col0 s gr +% Polyline +n 9900 3450 m 9900 3150 l 10200 3450 l 9900 3450 l cp gs col0 s gr +% Polyline +n 10200 3450 m 10200 3150 l 10500 3450 l 10200 3450 l cp gs col0 s gr +% Polyline +n 10500 3450 m 10500 3150 l 10800 3450 l 10500 3450 l cp gs col0 s gr +% Polyline +n 10200 3150 m 10200 2850 l 10500 3150 l 10200 3150 l cp gs col0 s gr +% Polyline +n 10500 3150 m 10500 2850 l 10800 3150 l 10500 3150 l cp gs col0 s gr +% Polyline +n 10800 3150 m 10800 2850 l 11100 3150 l 10800 3150 l cp gs col0 s gr +% Polyline +n 10500 2850 m 10500 2550 l 10800 2850 l 10500 2850 l cp gs col0 s gr +% Polyline +n 11100 2850 m 11100 2550 l 11400 2850 l 11100 2850 l cp gs col0 s gr +% Polyline +n 10800 2850 m 10800 2550 l 11100 2850 l 10800 2850 l cp gs col0 s gr +% Polyline +n 10500 2550 m 10500 2250 l 10800 2550 l 10500 2550 l cp gs col0 s gr +% Polyline +n 10200 2250 m 10200 1950 l 10500 2250 l 10200 2250 l cp gs col0 s gr +% Polyline +n 9900 1950 m 9900 1650 l 10200 1950 l 9900 1950 l cp gs col0 s gr +% Polyline +n 9900 1650 m 9900 1350 l 10200 1650 l 9900 1650 l cp gs col0 s gr +% Polyline +n 8400 3450 m 8400 3150 l 8700 3450 l 8400 3450 l cp gs col0 s gr +% Polyline +n 8100 3450 m 8400 3450 l gs col0 s gr +% Polyline +n 8400 3150 m 8100 3150 l gs col0 s gr +% Polyline +n 8400 3150 m 8400 2850 l 8100 2850 l 8400 3150 l cp gs col0 s gr +% Polyline +n 8100 3150 m 7500 2850 l gs col0 s gr +% Polyline +n 8100 2850 m 7500 2850 l gs col0 s gr +% Polyline +n 8850 3300 m 8700 3450 l gs col0 s gr +% Polyline +n 9000 3450 m 8700 3450 l gs col0 s gr +% Polyline +n 8400 3150 m 8850 3300 l gs col0 s gr +% Polyline +n 9300 3750 m 9600 3750 l gs col0 s gr +% Polyline +n 9600 3450 m 9900 3450 l gs col0 s gr +% Polyline +n 9900 3150 m 10200 3150 l gs col0 s gr +% Polyline +n 10200 2850 m 10500 2850 l gs col0 s gr +% Polyline +n 10500 3750 m 10500 3450 l gs col0 s gr +% Polyline +n 10800 3450 m 10800 3150 l gs col0 s gr +% Polyline +n 11100 3150 m 11100 2850 l gs col0 s gr +% Polyline +n 11100 2550 m 10800 2550 l 10800 2250 l 10500 2250 l 10500 1950 l 10200 1950 l gs col0 s gr +% Polyline +n 10500 1950 m 10500 1650 l 10800 1650 l 10800 1350 l gs col0 s gr +% Polyline +n 12300 1650 m 11700 1650 l 11700 1350 l gs col0 s gr +% Polyline +n 12000 1950 m 11850 1800 l gs col0 s gr +% Polyline +n 11700 1950 m 12000 1950 l gs col0 s gr +% Polyline +n 11700 1950 m 11700 2550 l 12000 2550 l 12000 2850 l 12300 2850 l gs col0 s gr +% Polyline +n 11700 2250 m 11400 2250 l 11400 2850 l gs col0 s gr +% Polyline +n 11100 2550 m 11700 2550 l gs col0 s gr +% Polyline +n 11700 2550 m 11400 2250 l gs col0 s gr +% Polyline +n 8400 1950 m 8100 2550 l gs col0 s gr +% Polyline +n 12000 1650 m 11850 1800 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 12000 1950 m 12000 1650 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 5250 m 8100 4950 l 8400 5250 l 8100 5250 l cp gs col0 s gr +% Polyline +n 9900 3150 m 9900 2550 l 9600 2250 l 9300 2250 l 9600 1950 l 10200 2550 l + 10200 2850 l gs col0 s gr +% Polyline +n 10200 2850 m 9900 2850 l 10200 2550 l 9900 2550 l 9900 2250 l 9600 2250 l + 9600 1950 l gs col0 s gr +% Polyline +n 8100 6750 m 10500 6750 l gs col0 s gr +% Polyline +n 8100 6450 m 8100 6150 l 8400 6450 l 8100 6450 l cp gs col0 s gr +% Polyline +n 8100 6750 m 8100 6450 l 8400 6750 l 8100 6750 l cp gs col0 s gr +% Polyline +n 8400 6450 m 8400 6150 l 8700 6450 l 8400 6450 l cp gs col0 s gr +% Polyline +n 8400 6750 m 8400 6450 l 8700 6750 l 8400 6750 l cp gs col0 s gr +% Polyline +n 8700 6450 m 8700 6150 l 9000 6450 l 8700 6450 l cp gs col0 s gr +% Polyline +n 8700 6750 m 8700 6450 l 9000 6750 l 8700 6750 l cp gs col0 s gr +% Polyline +n 9000 6450 m 9000 6150 l 9300 6450 l 9000 6450 l cp gs col0 s gr +% Polyline +n 9000 6750 m 9000 6450 l 9300 6750 l 9000 6750 l cp gs col0 s gr +% Polyline +n 9300 6450 m 9300 6150 l 9600 6450 l 9300 6450 l cp gs col0 s gr +% Polyline +n 9300 6750 m 9300 6450 l 9600 6750 l 9300 6750 l cp gs col0 s gr +% Polyline +n 9600 6450 m 9600 6150 l 9900 6450 l 9600 6450 l cp gs col0 s gr +% Polyline +n 9600 6750 m 9600 6450 l 9900 6750 l 9600 6750 l cp gs col0 s gr +% Polyline +n 9900 6450 m 9900 6150 l 10200 6450 l 9900 6450 l cp gs col0 s gr +% Polyline +n 9900 6750 m 9900 6450 l 10200 6750 l 9900 6750 l cp gs col0 s gr +% Polyline +n 10200 6450 m 10200 6150 l 10500 6450 l 10200 6450 l cp gs col0 s gr +% Polyline +n 10200 6750 m 10200 6450 l 10500 6750 l 10200 6750 l cp gs col0 s gr +% Polyline +n 8100 6150 m 10500 6150 l gs col0 s gr +% Polyline +n 8100 5850 m 8100 5550 l 8400 5850 l 8100 5850 l cp gs col0 s gr +% Polyline +n 8100 6150 m 8100 5850 l 8400 6150 l 8100 6150 l cp gs col0 s gr +% Polyline +n 8400 5850 m 8400 5550 l 8700 5850 l 8400 5850 l cp gs col0 s gr +% Polyline +n 8400 6150 m 8400 5850 l 8700 6150 l 8400 6150 l cp gs col0 s gr +% Polyline +n 8700 5850 m 8700 5550 l 9000 5850 l 8700 5850 l cp gs col0 s gr +% Polyline +n 8700 6150 m 8700 5850 l 9000 6150 l 8700 6150 l cp gs col0 s gr +% Polyline +n 9000 5850 m 9000 5550 l 9300 5850 l 9000 5850 l cp gs col0 s gr +% Polyline +n 9000 6150 m 9000 5850 l 9300 6150 l 9000 6150 l cp gs col0 s gr +% Polyline +n 9300 5850 m 9300 5550 l 9600 5850 l 9300 5850 l cp gs col0 s gr +% Polyline +n 9300 6150 m 9300 5850 l 9600 6150 l 9300 6150 l cp gs col0 s gr +% Polyline +n 9600 5850 m 9600 5550 l 9900 5850 l 9600 5850 l cp gs col0 s gr +% Polyline +n 9600 6150 m 9600 5850 l 9900 6150 l 9600 6150 l cp gs col0 s gr +% Polyline +n 9900 5850 m 9900 5550 l 10200 5850 l 9900 5850 l cp gs col0 s gr +% Polyline +n 9900 6150 m 9900 5850 l 10200 6150 l 9900 6150 l cp gs col0 s gr +% Polyline +n 10200 5850 m 10200 5550 l 10500 5850 l 10200 5850 l cp gs col0 s gr +% Polyline +n 10200 6150 m 10200 5850 l 10500 6150 l 10200 6150 l cp gs col0 s gr +% Polyline +n 8100 2550 m 7800 2250 l gs col0 s gr +% Polyline +n 900 900 m 6000 900 l 6000 7800 l 900 7800 l cp gs col0 s gr +% Polyline +n 6000 900 m 12600 900 l 12600 7800 l 6000 7800 l cp gs col0 s gr +/Times-Roman ff 390.00 scf sf +3300 7500 m +gs 1 -1 sc (\(a\)) col0 sh gr +/Times-Roman ff 390.00 scf sf +9150 7500 m +gs 1 -1 sc (\(b\)) col0 sh gr +% Polyline +60.000 slw +n 5100 5400 m 4200 4200 l 3300 4800 l 3300 3900 l 2400 3900 l 2100 2400 l gs col0 s gr +% Polyline +45.000 slw + [112] 0 sd +n 7200 4050 m 11400 4050 l gs col0 s gr [] 0 sd +% Polyline +n 9600 1200 m 9600 1650 l 9150 2100 l 9150 2400 l 9750 2700 l 9750 3150 l + 9300 3600 l 9300 4050 l 9600 4350 l 9600 5250 l 9300 5250 l + 9300 6750 l 9300 7050 l gs col0 s gr +7.500 slw +% Ellipse +n 4500 5400 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4500 5100 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4200 5100 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3750 4950 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4800 4500 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 5100 3600 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4200 3600 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4500 2400 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3300 5400 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 2700 3300 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 2400 4800 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3600 4200 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 5100 4800 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4350 4650 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3900 4575 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4800 4725 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +$F2psEnd +rs + +%%EndDocument + @endspecial 0 3202 a Fx(Figure)42 b(3)p FK(:)103 b Fv(A)33 +b(computational)e(mesh)i(f)m(or)g(a)g(par)t(ticle-in-cells)i(sim)o +(ulation)d(\(a\))i(and)e(a)h(computational)e(mesh)i(f)m(or)g(a)g +(contact-impact)g(sim)o(ulation)g(\(b\).)47 b(The)32 +b(par)t(ticle-in-cells)j(mesh)0 3401 y(is)i(par)t(titioned)e(so)h(that) +g(both)g(the)f(n)o(umber)g(of)h(mesh)f(elements)h(and)e(the)i(n)o +(umber)f(of)h(par)t(ticles)h(are)f(balanced)e(across)j(the)f +(sub-domains)o(.)53 b(T)-13 b(w)o(o)35 b(par)t(titionings)h(are)g(sho)o +(wn)e(f)m(or)j(the)0 3600 y(contact-impact)28 b(mesh.)36 +b(The)27 b(dashed)f(par)t(titioning)h(balances)g(only)h(the)f(n)o +(umber)g(of)h(mesh)f(elements)o(.)35 b(The)27 b(solid)h(par)t +(titioning)f(balances)g(both)g(the)g(n)o(umber)f(of)i(mesh)f(elements)g +(and)0 3799 y(the)j(n)o(umber)e(of)i(surf)m(ace)h(\(lightly)g(shaded\)) +e(elements)g(across)i(the)f(sub-domains)o(.)0 4160 y +Ft(3.5)199 b(P)-6 b(ar)t(titioning)56 b(f)l(or)f(Multi-phase)g(and)g +(Multi-ph)l(ysics)g(Computations)0 4479 y FK(The)h(traditional)g(graph) +g(partitioning)h(problem)f(formulation)h(is)f(limited)g(in)g(the)g +(types)f(of)h(applications)g(that)f(it)i(can)e(ef)l(fecti)l(v)n(ely)0 +4698 y(model)33 b(because)f(it)h(speci\002es)g(that)g(only)g(a)g +(single)g(quantity)g(be)g(load)g(balanced.)48 b(Man)n(y)32 +b(important)i(types)e(of)i(multi-phase)f(and)g(multi-)0 +4917 y(ph)o(ysics)e(computations)g(require)h(that)g(multiple)g +(quantities)g(be)f(load)h(balanced)e(simultaneously)-11 +b(.)48 b(This)32 b(is)f(because)f(synchronization)0 5136 +y(steps)46 b(e)n(xist)h(between)f(the)h(dif)l(ferent)h(phases)e(of)i +(the)f(computations,)h(and)f(so,)h(each)e(phase)g(must)h(be)g(indi)l +(vidually)h(load)f(balanced.)0 5355 y(That)i(is,)g(it)g(is)f(not)g(suf) +l(\002cient)h(to)f(simply)h(sum)f(up)g(the)h(relati)l(v)n(e)e(times)h +(required)h(for)g(each)f(phase)f(and)h(to)h(compute)f(a)g(partitioning) +0 5575 y(based)38 b(on)i(this)f(sum.)50 b(Doing)40 b(so)f(may)g(lead)g +(to)h(some)f(processors)f(ha)m(ving)h(too)h(much)f(w)n(ork)h(during)g +(one)f(phase)g(of)g(the)h(computation)0 5794 y(\(and)j(so,)f(these)g +(may)h(still)f(be)h(w)n(orking)g(after)g(other)g(processors)f(are)g +(idle\),)h(and)g(not)g(enough)f(w)n(ork)h(during)h(another)-9 +b(.)54 b(Instead,)42 b(it)h(is)0 6013 y(critical)f(that)f(e)l(v)n(ery)g +(processor)g(ha)m(v)n(e)f(an)h(equal)g(amount)h(of)g(w)n(ork)g(from)g +(each)f(phase)f(of)i(the)g(computation.)199 6232 y(T)-13 +b(w)n(o)47 b(e)n(xamples)e(are)h(particle-in-cells)h([17])g(and)f +(contact-impact)g(simulations)g([3)q(].)65 b(Figure)47 +b(3)g(illustrates)f(the)g(characteristics)0 6451 y(of)h(partitionings)h +(that)f(are)g(needed)g(for)h(these)e(simulations.)68 +b(Figure)47 b(3\(a\))h(sho)l(ws)e(a)h(mesh)g(for)h(a)e +(particles-in-cells)h(computation.)0 6670 y(Assuming)d(that)g(a)f +(synchronization)h(separates)f(the)h(mesh-based)f(computation)h(from)h +(the)f(particle)g(computation,)g(a)g(partitioning)0 6890 +y(is)f(required)h(that)f(balances)f(both)i(the)f(number)h(of)g(mesh)f +(elements)f(and)i(the)f(number)h(of)f(particles)g(across)g(the)g +(sub-domains.)56 b(Fig-)0 7109 y(ure)41 b(3\(b\))h(sho)l(ws)d(a)i(mesh) +g(for)g(a)g(contact-impact)g(simulation.)51 b(During)41 +b(the)g(contact)f(detection)h(phase,)f(computation)h(is)f(performed)0 +7328 y(only)k(on)h(the)f(surf)n(ace)f(\(i.e.,)h(lightly)h(shaded\))e +(elements,)h(while)g(during)h(the)f(impact)g(phase,)f(computation)i(is) +f(performed)g(on)g(all)h(of)0 7547 y(the)50 b(elements.)78 +b(Therefore,)53 b(in)e(order)g(to)f(ensure)g(that)h(both)g(phases)e +(are)h(load)h(balanced,)g(a)g(partitioning)g(must)g(balance)e(both)i +(the)0 7766 y(total)45 b(number)f(of)h(mesh)f(elements)f(and)h(the)g +(number)h(of)g(surf)n(ace)f(elements)f(across)h(the)g(sub-domains.)59 +b(The)44 b(solid)h(partitioning)g(in)0 7986 y(Figure)k(3\(b\))f(does)g +(this.)70 b(The)49 b(dashed)e(partitioning)i(is)f(similar)g(to)g(what)g +(a)g(traditional)h(graph)f(partitioner)h(might)f(compute.)71 +b(This)0 8205 y(partitioning)42 b(balances)f(only)g(the)h(total)g +(number)f(of)h(mesh)f(elements.)50 b(The)42 b(surf)n(ace)f(elements)g +(are)g(imbalanced)g(by)h(o)n(v)n(er)e(50\045.)199 8424 +y(A)65 b(ne)l(w)f(formulation)i(of)f(the)g(graph)g(partitioning)h +(problem)f(is)f(presented)g(in)h([6)q(])g(that)g(is)f(able)h(to)g +(model)g(the)f(problem)i(of)0 8643 y(balancing)43 b(multiple)h +(computational)g(phases)e(simultaneously)-11 b(,)43 b(while)g(also)g +(minimizing)h(the)g(inter)m(-processor)f(communications.)0 +8862 y(In)57 b(this)g(formulation,)k(a)c(weight)g(v)n(ector)f(of)h +(size)f Fy(m)67 b FK(is)56 b(assigned)g(to)h(each)f(v)n(erte)n(x)g(of)h +(the)g(graph.)97 b(The)57 b Fs(multi-constr)n(aint)g(gr)n(aph)0 +9081 y(partitioning)73 b(pr)-7 b(oblem)71 b FK(then)h(is)g(to)h +(compute)f(a)g(partitioning)h(such)e(that)i(the)f(edge-cut)g(is)g +(minimized)g(and)g(that)h(e)l(v)n(ery)e(sub-)0 9301 y(domain)49 +b(has)f(approximately)h(the)g(same)f(amount)h(of)g(each)f(of)h(the)g(v) +n(erte)n(x)e(weights.)73 b(The)49 b(routines)g FA(P)-7 +b(arMETIS)p 6742 9301 50 7 v 61 w(V3)p 7006 9301 V 59 +w(P)g(ar)7 b(tKw)n(a)-5 b(y)p FK(,)0 9520 y FA(P)e(arMETIS)p +768 9520 V 61 w(V3)p 1032 9520 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)p FK(,)40 b FA(P)-7 b(arMETIS)p 3086 9520 V 61 w(V3)p +3350 9520 V 60 w(Re\002neKw)n(a)i(y)p FK(,)40 b(and)f +FA(P)-7 b(arMETIS)p 5407 9520 V 61 w(V3)p 5671 9520 V +60 w(Adaptiv)l(eRepar)7 b(t)41 b FK(are)e(all)h(able)f(to)0 +9739 y(compute)i(partitionings)h(that)g(satisfy)f(multiple)h(balance)f +(constraints.)199 9958 y(Figure)k(4)f(gi)l(v)n(es)e(the)i(dual)g(graph) +g(for)g(the)g(particles-in-cells)g(mesh)f(sho)l(wn)g(in)i(Figure)f(3.) +58 b(Each)44 b(v)n(erte)n(x)f(has)g(tw)n(o)h(weights)g(here.)0 +10177 y(The)33 b(\002rst)g(represents)f(the)g(w)n(ork)i(associated)d +(with)i(the)f(mesh-based)g(computation)h(for)g(the)g(corresponding)f +(element.)48 b(\(These)33 b(are)f(all)0 10396 y(ones)i(because)g(we)g +(assume)g(in)h(this)f(case)g(that)h(all)g(of)g(the)g(elements)f(ha)m(v) +n(e)f(the)i(same)f(amount)h(of)g(mesh-based)f(w)n(ork)i(associated)d +(with)0 10616 y(them.\))50 b(The)39 b(second)f(weight)g(represents)g +(the)h(w)n(ork)g(associated)e(with)i(the)f(particle-based)g +(computation.)50 b(This)39 b(v)l(alue)f(is)h(estimated)3858 +11298 y(9)p eop +%%Page: 10 10 +10 9 bop 900 2536 a @beginspecial 0 @llx 0 @lly 646 @urx +273 @ury 3600 @rwi @setspecial +%%BeginDocument: figures/particle.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: particle.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3b +%%CreationDate: Wed Jan 23 20:29:48 2002 +%%For: kirk@lnx08 (Kirk Schloegel) +%%BoundingBox: 0 0 646 273 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 273 moveto 0 0 lineto 646 0 lineto 646 273 lineto closepath clip newpath +-62.0 369.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +% Polyline +7.500 slw +n 1500 3300 m + 1950 2550 l gs col0 s gr +% Polyline +n 1950 2550 m + 3150 2250 l gs col0 s gr +% Polyline +n 3150 2250 m + 4350 2250 l gs col0 s gr +% Polyline +n 4350 2250 m + 5250 3150 l gs col0 s gr +% Polyline +n 5250 3150 m + 5550 4350 l gs col0 s gr +% Polyline +n 5550 4350 m + 4950 5550 l gs col0 s gr +% Polyline +n 4950 5550 m + 3750 5850 l gs col0 s gr +% Polyline +n 3750 5850 m + 2550 5850 l gs col0 s gr +% Polyline +n 2550 5850 m + 1650 5250 l gs col0 s gr +% Polyline +n 1650 5250 m + 2250 4050 l gs col0 s gr +% Polyline +n 2250 4050 m + 3375 3450 l gs col0 s gr +% Polyline +n 3375 3450 m + 4050 4350 l gs col0 s gr +% Polyline +n 4050 4350 m + 3150 4950 l gs col0 s gr +% Polyline +n 3150 4950 m + 3150 4050 l gs col0 s gr +% Polyline +n 3150 4050 m + 4050 4350 l gs col0 s gr +% Polyline +n 3150 4050 m + 3375 3450 l gs col0 s gr +% Polyline +n 3150 4950 m + 2550 5850 l gs col0 s gr +% Polyline +n 3150 4950 m + 3750 5850 l gs col0 s gr +% Polyline +n 4950 5550 m + 4050 4350 l gs col0 s gr +% Polyline +n 4050 4350 m + 5550 4350 l gs col0 s gr +% Polyline +n 3750 5850 m + 4050 4350 l gs col0 s gr +% Polyline +n 4050 4350 m + 5250 3150 l gs col0 s gr +% Polyline +n 3375 3450 m + 4350 2250 l gs col0 s gr +% Polyline +n 3375 3450 m + 3150 2250 l gs col0 s gr +% Polyline +n 2250 4050 m + 1500 3300 l gs col0 s gr +% Polyline +n 2250 4050 m + 1950 2550 l gs col0 s gr +% Polyline +n 1950 2550 m + 3375 3450 l gs col0 s gr +% Polyline +n 3375 3450 m + 5250 3150 l gs col0 s gr +% Polyline +n 3150 4050 m + 2250 4050 l gs col0 s gr +% Polyline +n 2250 4050 m + 3150 4950 l gs col0 s gr +% Polyline +n 3150 4950 m + 1650 5250 l gs col0 s gr +% Polyline +n 1050 4350 m + 2250 4050 l gs col0 s gr +% Polyline +n 1650 5250 m + 1050 4350 l gs col0 s gr +% Polyline +n 1050 4350 m + 1200 3600 l gs col0 s gr +% Polyline +n 1200 3600 m + 2250 4050 l gs col0 s gr +% Polyline +n 1200 3600 m + 1500 3300 l gs col0 s gr +% Polyline +60.000 slw +n 4950 5550 m 4050 4350 l 3150 4950 l 3150 4050 l 2250 4050 l + 1950 2550 l gs col0 s gr +7.500 slw +% Ellipse +n 4350 5550 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4350 5250 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4050 5250 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3600 5100 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4650 4650 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4950 3750 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4050 3750 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4350 2550 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3150 5550 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 2550 3450 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 2250 4950 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3450 4350 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4950 4950 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4200 4800 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 3750 4725 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 4650 4875 75 75 0 360 DrawEllipse gs col4 1.00 shd ef gr gs col0 s gr + +% Polyline +n 7950 3975 m + 7875 3225 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 7950 3975 m + 8100 4725 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4725 m + 8400 5325 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8400 5325 m + 8925 5625 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8925 5625 m + 9525 5925 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 7875 3225 m + 8175 2775 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9300 3375 m + 9525 2325 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9975 3600 m + 11475 3900 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 4350 m + 9525 5925 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8175 2775 m + 8775 2325 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8775 2325 m + 9525 2325 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9525 2325 m + 10050 2325 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 10050 2325 m + 10950 2700 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 10950 2700 m + 11325 3300 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 11325 3300 m + 11475 3900 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 11475 3900 m + 11400 4725 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 11400 4725 m + 11025 5475 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 11025 5475 m + 10350 5850 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 10350 5850 m + 9525 5925 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9000 4125 m + 9300 3375 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9000 4125 m + 9900 4350 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9900 4350 m + 9975 3600 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 9975 3600 m + 9300 3375 l gs col6 1.00 shd ef gr gs col0 s gr +% Polyline +n 8100 4725 m + 9000 4125 l gs col6 1.00 shd ef gr gs col0 s gr +/Times-Roman ff 180.00 scf sf +10275 2325 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8175 4050 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10050 3975 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8250 3075 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8625 2625 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10425 2850 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +9300 3750 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8625 5250 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8025 3450 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +9525 2625 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10725 3375 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10950 4125 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10800 4875 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10500 5400 m +gs 1 -1 sc (\(1, 3\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +10050 5625 m +gs 1 -1 sc (\(1, 4\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +9975 4650 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +9075 5475 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8325 4800 m +gs 1 -1 sc (\(1, 1\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +9675 6150 m +gs 1 -1 sc (\(1, 2\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +8925 4500 m +gs 1 -1 sc (\(1, 0\)) col0 sh gr +/Times-Roman ff 180.00 scf sf +1425 4050 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 180.00 scf sf +3600 5475 m +gs 1 -1 sc (12) col0 sh gr +/Times-Roman ff 180.00 scf sf +3300 4650 m +gs 1 -1 sc (20) col0 sh gr +/Times-Roman ff 180.00 scf sf +1500 3600 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 180.00 scf sf +1800 3300 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 180.00 scf sf +2250 3075 m +gs 1 -1 sc (4) col0 sh gr +/Times-Roman ff 180.00 scf sf +2850 2700 m +gs 1 -1 sc (5) col0 sh gr +/Times-Roman ff 180.00 scf sf +3600 2550 m +gs 1 -1 sc (6) col0 sh gr +/Times-Roman ff 180.00 scf sf +4500 2850 m +gs 1 -1 sc (7) col0 sh gr +/Times-Roman ff 180.00 scf sf +4500 3525 m +gs 1 -1 sc (8) col0 sh gr +/Times-Roman ff 180.00 scf sf +5100 3600 m +gs 1 -1 sc (9) col0 sh gr +/Times-Roman ff 180.00 scf sf +5025 4650 m +gs 1 -1 sc (10) col0 sh gr +/Times-Roman ff 180.00 scf sf +3975 5625 m +gs 1 -1 sc (11) col0 sh gr +/Times-Roman ff 180.00 scf sf +3075 5400 m +gs 1 -1 sc (13) col0 sh gr +/Times-Roman ff 180.00 scf sf +2625 5325 m +gs 1 -1 sc (14) col0 sh gr +/Times-Roman ff 180.00 scf sf +2850 4350 m +gs 1 -1 sc (17) col0 sh gr +/Times-Roman ff 180.00 scf sf +2925 3900 m +gs 1 -1 sc (18) col0 sh gr +/Times-Roman ff 180.00 scf sf +3375 3900 m +gs 1 -1 sc (19) col0 sh gr +/Times-Roman ff 180.00 scf sf +2250 4500 m +gs 1 -1 sc (15) col0 sh gr +/Times-Roman ff 180.00 scf sf +1725 4425 m +gs 1 -1 sc (16) col0 sh gr +% Ellipse +n 8775 2325 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9525 2325 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 10050 2325 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 10950 2700 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 11475 3900 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 8100 4725 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 7950 3975 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 7875 3225 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 8175 2775 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9000 4125 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9300 3375 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9975 3600 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9900 4350 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 11400 4725 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 11025 5475 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 10350 5850 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 9525 5925 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 8925 5625 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 8400 5325 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +% Ellipse +n 11305 3347 106 106 0 360 DrawEllipse gs col6 1.00 shd ef gr gs col0 s gr + +/Times-Roman ff 180.00 scf sf +10500 6150 m +gs 1 -1 sc (11) col0 sh gr +/Times-Roman ff 180.00 scf sf +8700 6000 m +gs 1 -1 sc (13) col0 sh gr +/Times-Roman ff 180.00 scf sf +7575 4050 m +gs 1 -1 sc (16) col0 sh gr +/Times-Roman ff 180.00 scf sf +7650 3225 m +gs 1 -1 sc (1) col0 sh gr +/Times-Roman ff 180.00 scf sf +8025 2625 m +gs 1 -1 sc (2) col0 sh gr +/Times-Roman ff 180.00 scf sf +8550 2175 m +gs 1 -1 sc (3) col0 sh gr +/Times-Roman ff 180.00 scf sf +9450 2100 m +gs 1 -1 sc (4) col0 sh gr +/Times-Roman ff 180.00 scf sf +10050 2100 m +gs 1 -1 sc (5) col0 sh gr +/Times-Roman ff 180.00 scf sf +10950 2475 m +gs 1 -1 sc (6) col0 sh gr +/Times-Roman ff 180.00 scf sf +11550 3225 m +gs 1 -1 sc (7) col0 sh gr +/Times-Roman ff 180.00 scf sf +11700 3825 m +gs 1 -1 sc (8) col0 sh gr +/Times-Roman ff 180.00 scf sf +11625 4725 m +gs 1 -1 sc (9) col0 sh gr +/Times-Roman ff 180.00 scf sf +11250 5550 m +gs 1 -1 sc (10) col0 sh gr +/Times-Roman ff 180.00 scf sf +9675 4200 m +gs 1 -1 sc (20) col0 sh gr +/Times-Roman ff 180.00 scf sf +9975 3375 m +gs 1 -1 sc (19) col0 sh gr +/Times-Roman ff 180.00 scf sf +9000 3225 m +gs 1 -1 sc (18) col0 sh gr +/Times-Roman ff 180.00 scf sf +8175 5625 m +gs 1 -1 sc (14) col0 sh gr +/Times-Roman ff 180.00 scf sf +7725 4950 m +gs 1 -1 sc (15) col0 sh gr +/Times-Roman ff 180.00 scf sf +9225 6150 m +gs 1 -1 sc (12) col0 sh gr +/Times-Roman ff 180.00 scf sf +8775 3975 m +gs 1 -1 sc (17) col0 sh gr +% Polyline +2 slj +45.000 slw +n 9000 1650 m 9001 1653 l 9002 1658 l 9005 1669 l 9009 1685 l 9014 1708 l + 9021 1737 l 9029 1772 l 9039 1813 l 9050 1858 l 9061 1907 l + 9073 1959 l 9084 2012 l 9096 2064 l 9107 2117 l 9117 2167 l + 9127 2216 l 9136 2262 l 9144 2306 l 9150 2347 l 9156 2385 l + 9161 2421 l 9164 2454 l 9167 2486 l 9169 2515 l 9169 2542 l + 9169 2568 l 9168 2592 l 9166 2615 l 9163 2638 l 9157 2666 l + 9150 2694 l 9142 2721 l 9132 2747 l 9121 2772 l 9108 2797 l + 9094 2821 l 9080 2844 l 9064 2866 l 9048 2888 l 9031 2909 l + 9013 2930 l 8996 2950 l 8979 2968 l 8962 2987 l 8945 3004 l + 8929 3021 l 8914 3037 l 8900 3053 l 8886 3069 l 8874 3084 l + 8863 3100 l 8853 3114 l 8844 3129 l 8836 3144 l 8829 3160 l + 8822 3176 l 8817 3193 l 8812 3210 l 8808 3228 l 8806 3247 l + 8804 3265 l 8804 3284 l 8804 3303 l 8806 3323 l 8809 3342 l + 8814 3362 l 8819 3381 l 8825 3400 l 8833 3419 l 8842 3437 l + 8851 3455 l 8862 3473 l 8874 3490 l 8886 3508 l 8900 3525 l + 8914 3541 l 8928 3557 l 8944 3573 l 8961 3590 l 8979 3606 l + 8998 3624 l 9017 3641 l 9038 3659 l 9059 3678 l 9081 3697 l + 9103 3716 l 9126 3735 l 9148 3755 l 9171 3775 l 9193 3795 l + 9215 3815 l 9237 3835 l 9257 3855 l 9277 3875 l 9296 3895 l + 9314 3915 l 9331 3934 l 9347 3954 l 9361 3973 l 9375 3993 l + 9388 4013 l 9400 4034 l 9411 4056 l 9421 4079 l 9431 4103 l + 9439 4127 l 9447 4152 l 9455 4178 l 9462 4204 l 9469 4232 l + 9475 4259 l 9481 4288 l 9488 4316 l 9494 4345 l 9500 4373 l + 9506 4402 l 9513 4430 l 9520 4457 l 9528 4485 l 9536 4511 l + 9544 4538 l 9554 4563 l 9564 4588 l 9575 4613 l 9588 4638 l + 9598 4657 l 9610 4676 l 9622 4696 l 9636 4716 l 9650 4736 l + 9666 4756 l 9682 4777 l 9700 4798 l 9718 4819 l 9738 4841 l + 9759 4862 l 9780 4884 l 9802 4907 l 9825 4929 l 9849 4952 l + 9874 4974 l 9899 4997 l 9924 5019 l 9950 5042 l 9976 5064 l + 10002 5086 l 10028 5108 l 10054 5129 l 10081 5151 l 10107 5172 l + 10133 5193 l 10159 5213 l 10185 5234 l 10211 5254 l 10238 5275 l + 10261 5293 l 10284 5312 l 10308 5330 l 10333 5350 l 10358 5369 l + 10384 5389 l 10411 5410 l 10439 5432 l 10468 5455 l 10499 5478 l + 10531 5503 l 10565 5529 l 10600 5557 l 10637 5585 l 10676 5615 l + 10716 5646 l 10757 5677 l 10798 5710 l 10841 5742 l 10883 5775 l + 10924 5807 l 10964 5838 l 11002 5867 l 11037 5894 l 11069 5918 l + 11097 5940 l 11120 5958 l 11139 5972 l 11153 5983 l 11163 5991 l + 11170 5996 l 11173 5999 l + 11175 6000 l gs col0 s gr +% Polyline +0 slj +7.500 slw +n 5850 4275 m 6750 4275 l 6750 4575 l 7350 4125 l 6750 3675 l 6750 3975 l + 5850 3975 l + cp gs col24 1.00 shd ef gr gs col0 s gr +$F2psEnd +rs + +%%EndDocument + @endspecial 0 2901 a Fx(Figure)44 b(4)p FK(:)114 b Fv(A)35 +b(dual)f(g)o(r)o(aph)g(with)h(v)m(er)t(te)m(x)i(w)o(eight)d(v)m(ectors) +j(of)f(siz)o(e)f(tw)o(o)g(is)h(constr)r(ucted)f(from)h(the)f(par)t +(ticle-in-cells)i(mesh)d(from)i(Figure)e(3.)53 b(A)35 +b(m)o(ulti-constr)o(aint)h(par)t(titioning)e(has)0 3100 +y(been)29 b(computed)f(f)m(or)i(this)h(g)o(r)o(aph,)e(and)g(this)i(par) +t(titioning)f(has)g(been)e(projected)h(bac)n(k)i(to)f(the)g(mesh.)0 +3461 y FK(by)39 b(the)f(number)h(of)g(particles)g(that)f(f)n(all)i +(within)f(each)f(element.)49 b(A)39 b(multi-constraint)g(partitioning)h +(is)f(sho)l(wn)f(that)g(balances)g(both)h(of)0 3680 y(these)i(weights.) +199 3899 y(A)46 b(related)g(graph)g(partitioning)h(problem)g +(formulation)g(that)f(is)g(discussed)f(in)h([13],)h(allo)l(ws)f(edges)f +(to)h(ha)m(v)n(e)f(multiple)i(weights.)0 4118 y(W)-13 +b(e)55 b(refer)h(to)f(this)h(as)f(the)g Fs(multi-objective)h(gr)n(aph)e +(partitioning)i(pr)-7 b(oblem)p FK(.)92 b(Multi-objecti)l(v)n(e)55 +b(graph)h(partitioning)g(is)g(applicable)0 4337 y(for)g +(tightly-coupled)g(multi-ph)o(ysics)g(computations)f(in)-7 +b(v)m(olving)56 b(multiple,)j(spatially-o)n(v)n(erlapping)c(meshes.)92 +b(Later)55 b(v)n(ersions)g(of)4 4557 y FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)48 b FK(will)42 +b(support)g(multiple)g(edge)f(weights.)0 5011 y Ft(3.6)199 +b(P)-6 b(ar)t(titioning)56 b(f)l(or)f(Heter)l(og)r(eneous)d(Computing)j +(Ar)l(c)n(hitectures)0 5330 y FK(Comple)n(x,)78 b(heterogeneous)71 +b(computing)h(platforms,)79 b(such)71 b(as)g(groups)h(of)g +(tightly-coupled)h(shared-memory)e(nodes)g(that)h(are)0 +5549 y(loosely)48 b(connected)f(via)h(high)h(bandwidth)f(and)g(high)g +(latenc)n(y)f(interconnection)h(netw)n(orks,)i(and/or)e(processing)g +(nodes)f(that)h(ha)m(v)n(e)0 5769 y(comple)n(x)53 b(memory)h +(hierarchies,)i(are)d(becoming)h(more)g(common,)i(as)d(the)n(y)g +(display)h(competiti)l(v)n(e)f(cost-to-performance)h(ratios.)0 +5988 y(The)49 b(same)g(is)f(true)i(of)f(platforms)g(that)h(are)e +(geographically)h(distrib)m(uted.)74 b(Most)48 b(e)n(xisting)h +(parallel)g(simulation)g(codes)f(can)h(easily)0 6207 +y(be)58 b(ported)g(to)g(a)f(wide)h(range)g(of)g(parallel)g +(architectures)f(as)g(the)n(y)g(emplo)n(y)h(a)g(standard)f(messaging)g +(layer)h(such)f(as)g(MPI.)h(Ho)l(w-)0 6426 y(e)l(v)n(er)-7 +b(,)47 b(comple)n(x)f(and)h(heterogeneous)f(architectures)g(present)h +(ne)l(w)f(challenges)g(to)h(the)f(scalable)g(e)n(x)n(ecution)g(of)h +(such)f(codes,)h(since)0 6645 y(man)n(y)h(of)h(the)g(basic)e(parallel)i +(algorithm)g(design)g(assumptions)e(are)i(no)f(longer)h(v)l(alid.)72 +b(One)49 b(w)n(ay)f(of)h(alle)l(viating)g(this)f(problem)h(is)0 +6865 y(to)56 b(de)l(v)n(elop)e(a)i(ne)l(w)f(class)f(of)i +(architecture-a)n(w)n(are)f(graph)g(partitioning)i(algorithms)f(that)f +(optimally)i(decompose)d(computations)0 7084 y(gi)l(v)n(en)43 +b(the)h(architecture)f(of)h(the)g(parallel)f(platform.)58 +b(Ideally)-11 b(,)45 b(this)e(approach)g(will)h(alle)l(viate)f(the)h +(need)f(for)h(major)h(restructuring)f(of)0 7303 y(scienti\002c)d +(codes.)199 7522 y(W)-13 b(e)49 b(ha)m(v)n(e)f(tak)n(en)i(the)f +(\002rst)h(steps)f(to)l(w)n(ard)h(de)l(v)n(eloping)f(architecture-a)n +(w)n(are)g(graph-partitioning)h(algorithms.)76 b(These)49 +b(are)g(able)0 7741 y(to)71 b(compute)h(partitionings)f(that)h(allo)l +(w)f(computations)g(to)g(achie)l(v)n(e)f(the)h(highest)g(le)l(v)n(els)f +(of)i(performance)f(re)n(g)o(ardless)f(of)i(the)0 7960 +y(computing)67 b(platform.)127 b(Speci\002cally)-11 b(,)73 +b(we)66 b(ha)m(v)n(e)f(enabled)h FA(P)-7 b(arMETIS)p +4390 7960 50 7 v 61 w(V3)p 4654 7960 V 60 w(P)g(ar)7 +b(tKw)n(a)-5 b(y)p FK(,)73 b FA(P)-7 b(arMETIS)p 6290 +7960 V 60 w(V3)p 6553 7960 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)p FK(,)0 8180 y FA(P)e(arMETIS)p 768 8180 V 61 w(V3)p +1032 8180 V 60 w(P)g(ar)7 b(tMeshKw)n(a)-5 b(y)p FK(,)37 +b FA(P)-7 b(arMETIS)p 3037 8180 V 60 w(V3)p 3300 8180 +V 60 w(Re\002neKw)n(a)i(y)p FK(,)36 b(and)f FA(P)-7 b(arMETIS)p +5349 8180 V 61 w(V3)p 5613 8180 V 60 w(Adaptiv)l(eRepar)7 +b(t)37 b FK(to)e(compute)g(ef-)0 8399 y(\002cient)55 +b(partitionings)h(for)g(netw)n(orks)f(of)h(heterogeneous)e(processors.) +92 b(T)-13 b(o)55 b(do)g(so,)j(these)d(routines)g(require)g(an)g +(additional)h(array)0 8618 y(\()p Fj(tpwgts)p FK(\))47 +b(to)h(be)g(passed)g(as)f(a)h(parameter)-9 b(.)72 b(This)48 +b(array)h(describes)e(the)h(fraction)h(of)g(the)f(total)h(v)n(erte)n(x) +e(weight)h(each)g(sub-domain)0 8837 y(should)60 b(contain.)105 +b(F)n(or)60 b(e)n(xample,)j(if)d(you)g(ha)m(v)n(e)e(a)i(netw)n(ork)g +(of)g(four)h(processors,)h(the)e(\002rst)g(three)g(of)g(which)f(are)h +(of)g(equal)f(pro-)0 9056 y(cessing)g(speed,)64 b(and)d(the)f(fourth)i +(of)f(which)f(is)h(twice)f(as)g(f)n(ast)h(as)f(the)g(others,)65 +b(the)60 b(user)h(w)n(ould)g(pass)e(an)i(array)f(containing)h(the)0 +9276 y(v)l(alues)50 b Fz(.)p FK(0)p Fz(:)p FK(2)p Fz(;)28 +b FK(0)p Fz(:)p FK(2)p Fz(;)g FK(0)p Fz(:)p FK(2)p Fz(;)g +FK(0)p Fz(:)p FK(4)p Fz(/)p FK(.)75 b(Note)50 b(that)h(by)f(allo)l +(wing)g(users)g(to)h(specify)f(tar)m(get)g(sub-domain)h(weights)f(as)f +(such,)j(heterogeneous)0 9495 y(processing)47 b(po)l(wer)h(can)g(be)g +(tak)n(en)g(into)h(account)f(when)f(computing)i(a)f(partitioning.)72 +b(Ho)l(we)l(v)n(er)-7 b(,)49 b(this)f(does)f(not)i(allo)l(w)f(us)g(to)g +(tak)n(e)0 9714 y(heterogeneous)e(netw)n(ork)i(bandwidths)f(and)g +(latencies)f(into)h(account.)68 b(Optimizing)47 b(partitionings)h(for)g +(heterogeneous)e(netw)n(orks)0 9933 y(is)41 b(still)h(the)f(focus)h(of) +f(ongoing)h(research.)0 10388 y Ft(3.7)199 b(Computing)55 +b(Fill-Reducing)g(Or)l(derings)0 10707 y FA(P)-7 b(arMETIS)p +768 10707 V 61 w(V3)p 1032 10707 V 60 w(NodeND)70 b FK(is)g(the)g +(routine)h(pro)n(vided)f(by)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)76 b FK(for)71 +b(computing)g(\002ll-reducing)g(orderings,)77 b(suited)69 +b(for)3817 11298 y(10)p eop +%%Page: 11 11 +11 10 bop 0 166 a FK(Cholesk)n(y-based)51 b(direct)j(f)n(actorization)f +(algorithms.)86 b FA(P)-7 b(arMETIS)p 4039 166 50 7 v +61 w(V3)p 4303 166 V 60 w(NodeND)54 b FK(mak)n(es)e(no)i(assumptions)e +(on)h(ho)l(w)g(the)g(graph)0 385 y(is)59 b(initially)g(distrib)m(uted)g +(among)g(the)g(processors.)102 b(It)60 b(can)e(ef)l(fecti)l(v)n(ely)g +(compute)h(\002ll-reducing)h(orderings)f(for)h(graphs)e(that)h(are)0 +604 y(randomly)42 b(distrib)m(uted)f(as)g(well)h(as)f(graphs)g(that)g +(are)h(well)f(distrib)m(uted.)199 824 y(The)36 b(algorithm)h +(implemented)f(by)f FA(P)-7 b(arMETIS)p 3047 824 V 61 +w(V3)p 3311 824 V 60 w(NodeND)37 b FK(is)e(based)g(on)h(a)f(multile)l +(v)n(el)h(nested)f(dissection)g(algorithm.)50 b(This)0 +1043 y(algorithm)h(has)f(been)g(sho)l(wn)g(to)g(produce)g(lo)l(w)h +(\002ll)g(orderings)f(for)h(a)f(wide)h(v)l(ariety)f(of)h(matrices.)77 +b(Furthermore,)53 b(it)e(leads)e(to)i(bal-)0 1262 y(anced)46 +b(elimination)h(trees)f(that)h(are)f(essential)f(for)j(parallel)e +(direct)h(f)n(actorization.)66 b FA(P)-7 b(arMETIS)p +5683 1262 V 61 w(V3)p 5947 1262 V 60 w(NodeND)47 b FK(uses)f(a)g +(multile)l(v)n(el)0 1481 y(node-based)f(re\002nement)i(algorithm)g +(that)f(is)g(particularly)h(suited)f(for)h(directly)f(re\002ning)h(the) +f(size)g(of)g(the)h(separators.)64 b(T)-13 b(o)47 b(achie)l(v)n(e)0 +1700 y(high)63 b(performance,)k FA(P)-7 b(arMETIS)p 2074 +1700 V 61 w(V3)p 2338 1700 V 60 w(NodeND)63 b FK(\002rst)g(uses)e +FA(P)-7 b(arMETIS)p 4524 1700 V 61 w(V3)p 4788 1700 V +60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)63 b FK(to)f(compute)h(a)f(high-quality) +h(parti-)0 1919 y(tioning)52 b(and)e(redistrib)m(utes)h(the)g(graph)g +(accordingly)-11 b(.)79 b(Ne)n(xt)50 b(it)i(proceeds)e(to)h(compute)g +(the)g(log)c Fy(p)56 b FK(le)l(v)n(els)49 b(of)j(the)f(elimination)g +(tree)0 2139 y(concurrently)-11 b(.)92 b(When)54 b(the)h(graph)g(has)g +(been)f(separated)g(into)75 b Fy(p)60 b FK(parts)55 b(\(where)74 +b Fy(p)60 b FK(is)55 b(the)g(number)g(of)g(processors\),)i(the)e(graph) +g(is)0 2358 y(redistrib)m(uted)45 b(among)g(the)h(processor)e(so)h +(that)g(each)g(processor)f(recei)l(v)n(es)g(a)h(single)g(subgraph,)g +(and)g(a)g(multiple)h(minimum)g(de)n(gree)0 2577 y(algorithm)c(is)g +(used)e(to)i(order)g(these)f(smaller)g(subgraphs.)3817 +11298 y(11)p eop +%%Page: 12 12 +12 11 bop 0 170 a FE(4)233 b(Input)64 b(and)h(Output)h(Formats)f(used)h +(b)-5 b(y)71 b(P)-9 b Fu(A)12 b(R)g FE(M)-11 b Fu(E)-46 +b FE(T)g Fu(I)p FE(S)0 558 y Ft(4.1)199 b(Format)55 b(of)g(the)h(Input) +f(Graph)0 877 y FK(All)48 b(of)g(the)g(graph)g(routines)f(in)52 +b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)55 b FK(tak)n(e)48 b(as)f(input)h(the)g(adjacenc)n(y)e +(structure)h(of)i(the)e(graph,)i(the)f(weights)f(of)h(the)g(v)n +(ertices)0 1096 y(and)h(edges)g(\(if)h(an)n(y\),)h(and)e(an)h(array)f +(describing)h(ho)l(w)f(the)h(graph)f(is)h(distrib)m(uted)f(among)h(the) +f(processors.)74 b(Note)50 b(that)f(depending)0 1315 +y(on)54 b(the)h(application)f(this)g(graph)h(can)f(represent)g(dif)l +(ferent)h(things.)89 b(F)n(or)55 b(e)n(xample,)h(when)i +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)61 b FK(is)54 b(used)g(to)h(compute)f(\002ll-)0 +1534 y(reducing)44 b(orderings,)h(the)g(graph)f(corresponds)g(to)h(the) +f(non-zero)h(structure)f(of)h(the)g(matrix)g(\(e)n(xcluding)f(the)g +(diagonal)h(entries\).)60 b(In)0 1754 y(the)46 b(case)f(of)i(\002nite)g +(element)e(computations,)i(the)f(v)n(ertices)g(of)g(the)g(graph)h(can)f +(correspond)g(to)g(nodes)g(\(points\))h(in)f(the)g(mesh)g(while)0 +1973 y(edges)c(represent)h(the)f(connections)h(between)f(these)g +(nodes.)55 b(Alternati)l(v)n(ely)-11 b(,)42 b(the)h(graph)g(can)g +(correspond)g(to)g(the)g(dual)f(of)i(the)f(\002nite)0 +2192 y(element)48 b(mesh.)71 b(In)49 b(this)g(case,)f(each)g(v)n(erte)n +(x)f(corresponds)h(to)g(an)h(element)f(and)g(tw)n(o)h(v)n(ertices)e +(are)h(connected)g(via)g(an)g(edge)g(if)h(the)0 2411 +y(corresponding)38 b(elements)f(share)g(an)h(edge)g(\(in)g(2D\))g(or)g +(a)g(f)n(ace)g(\(in)g(3D\).)g(Also,)g(the)g(graph)g(can)f(be)h(similar) +g(to)g(the)g(dual,)g(b)m(ut)g(be)g(more)0 2630 y(or)52 +b(less)e(connected.)79 b(That)52 b(is,)h(instead)d(of)i(limiting)g +(edges)f(to)g(those)g(elements)f(that)i(share)e(a)h(f)n(ace,)i(edges)e +(can)f(connect)h(an)n(y)g(tw)n(o)0 2850 y(elements)43 +b(that)h(share)f(e)l(v)n(en)g(a)g(single)h(node.)58 b(Ho)l(we)l(v)n(er) +42 b(the)i(graph)g(is)g(constructed,)f(it)h(is)g(usually)f(undirected.) +6526 2789 y Fr(4)6656 2850 y FK(That)h(is,)f(for)i(e)l(v)n(ery)0 +3069 y(pair)d(of)g(connected)e(v)n(ertices)h Fz(v)48 +b FK(and)41 b Fy(u)9 b FK(,)41 b(it)h(contains)e(both)i(edges)f +Fz(.v)7 b(;)28 b Fy(u)9 b Fz(/)40 b FK(and)h Fz(.)p Fy(u)9 +b Fz(;)28 b(v)7 b(/)p FK(.)199 3288 y(In)51 b FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t +FK(,)49 b(the)e(structure)g(of)g(the)g(graph)f(is)h(represented)f(by)h +(the)g(compressed)e(storage)i(format)g(\(CSR\),)g(e)n(xtended)f(for)h +(the)0 3507 y(conte)n(xt)j(of)h(parallel)g(distrib)m(uted-memory)h +(computing.)79 b(W)-13 b(e)50 b(will)h(\002rst)g(describe)f(the)h(CSR)g +(format)g(for)h(serial)e(graphs)g(and)h(then)0 3726 y(describe)41 +b(ho)l(w)g(it)h(has)f(been)g(e)n(xtended)f(for)i(storing)g(graphs)f +(that)h(are)f(distrib)m(uted)h(among)f(processors.)0 +4145 y FB(Serial)66 b(CSR)e(Format)200 b FK(The)59 b(CSR)g(format)h(is) +e(a)h(widely-used)f(scheme)g(for)h(storing)g(sparse)f(graphs.)103 +b(Here,)62 b(the)d(adjacenc)n(y)0 4364 y(structure)45 +b(of)h(a)f(graph)g(is)g(represented)f(by)h(tw)n(o)h(arrays,)f +Fj(xadj)f FK(and)h Fj(adjncy)p FK(.)60 b(W)-13 b(eights)44 +b(on)h(the)g(v)n(ertices)f(and)h(edges)g(\(if)h(an)n(y\))e(are)0 +4583 y(represented)d(by)h(using)f(tw)n(o)h(additional)g(arrays,)f +Fj(vwgt)f FK(and)h Fj(adjwgt)p FK(.)49 b(F)n(or)42 b(e)n(xample,)e +(consider)h(a)h(graph)f(with)h Fy(n)49 b FK(v)n(ertices)41 +b(and)g Fy(m)0 4802 y FK(edges.)50 b(In)42 b(the)f(CSR)h(format,)f +(this)h(graph)f(can)g(be)h(described)e(using)i(arrays)f(of)h(the)f +(follo)l(wing)h(sizes:)1794 5154 y Fj(xadj[)p Fy(n)g +FL(C)37 b FK(1)p Fj(])p FK(,)j Fj(vwgt[)p Fy(n)7 b Fj(])p +FK(,)40 b Fj(adjncy[)p FK(2)p Fy(m)10 b Fj(])p FK(,)37 +b(and)42 b Fj(adjwgt[)p FK(2)p Fy(m)10 b Fj(])0 5506 +y FK(Note)51 b(that)h(the)f(reason)g(both)h Fj(adjncy)d +FK(and)i Fj(adjwgt)e FK(are)j(of)f(size)g(2)p Fy(m)61 +b FK(is)52 b(because)e(e)l(v)n(ery)g(edge)h(is)g(listed)h(twice)f(\()p +Fs(i.e)o FK(.,)i(as)e Fz(.v)7 b(;)28 b Fy(u)9 b Fz(/)0 +5725 y FK(and)45 b Fz(.)p Fy(u)9 b Fz(;)28 b(v)7 b(/)p +FK(\).)63 b(Also)45 b(note)g(that)h(in)g(the)f(case)f(in)i(which)g(the) +f(graph)h(is)f(unweighted)g(\()p Fs(i.e)p FK(.,)h(all)f(v)n(ertices)g +(and/or)g(edges)g(ha)m(v)n(e)f(the)i(same)0 5945 y(weight\),)52 +b(then)e(either)g(or)g(both)g(of)g(the)g(arrays)g Fj(vwgt)e +FK(and)i Fj(adjwgt)e FK(can)h(be)h(set)f(to)h Fj(NULL)p +FK(.)e FA(P)-7 b(arMETIS)p 6339 5945 50 7 v 61 w(V3)p +6603 5945 V 60 w(Adaptiv)l(eRepar)7 b(t)0 6164 y FK(additionally)56 +b(requires)f(a)f Fj(vsize)g FK(array)-11 b(.)92 b(This)56 +b(array)f(is)g(similar)g(to)h(the)f Fj(vwgt)e FK(array)-11 +b(,)59 b(e)n(xcept)54 b(that)h(instead)g(of)g(describing)g(the)0 +6383 y(amount)d(of)g(w)n(ork)g(that)g(is)g(associated)e(with)i(each)f +(v)n(erte)n(x,)i(it)f(describes)e(the)i(amount)g(of)g(memory)g(that)g +(is)g(associated)e(with)i(each)0 6602 y(v)n(erte)n(x.)199 +6821 y(The)44 b(adjacenc)n(y)f(structure)h(of)g(the)g(graph)g(is)f +(stored)h(as)f(follo)l(ws.)59 b(Assuming)43 b(that)h(v)n(erte)n(x)f +(numbering)h(starts)g(from)h(0)f(\(C)g(style\),)0 7041 +y(the)i(adjacenc)n(y)f(list)h(of)h(v)n(erte)n(x)d Fy(i)62 +b FK(is)46 b(stored)g(in)h(array)f Fj(adjncy)e FK(starting)i(at)g(inde) +n(x)g Fj(xadj[)o Fy(i)16 b Fj(])44 b FK(and)i(ending)g(at)h(\(b)m(ut)f +(not)g(including\))0 7260 y(inde)n(x)f Fj(xadj[)o Fy(i)55 +b FL(C)39 b FK(1)p Fj(])46 b FK(\(in)g(other)g(w)n(ords,)h +Fj(adjncy[xadj[)o Fy(i)16 b Fj(]])41 b FK(up)46 b(through)g(and)g +(including)g Fj(adjncy[xadj[)o Fy(i)52 b FL(C)40 b FK(1)p +Fj(]-1])p FK(\).)0 7479 y(Hence,)58 b(the)f(adjacenc)n(y)d(lists)i(for) +h(each)e(v)n(erte)n(x)g(are)h(stored)g(consecuti)l(v)n(ely)f(in)h(the)g +(array)h Fj(adjncy)p FK(.)92 b(The)57 b(array)f Fj(xadj)f +FK(is)h(used)0 7698 y(to)k(point)g(to)h(where)e(the)h(list)g(for)g +(each)g(speci\002c)f(v)n(erte)n(x)g(be)n(gins)g(and)g(ends.)106 +b(Figure)60 b(5\(b\))h(illustrates)e(the)h(CSR)g(format)h(for)f(the)0 +7917 y(15-v)n(erte)n(x)52 b(graph)g(sho)l(wn)g(in)h(Figure)g(5\(a\).)85 +b(If)53 b(the)f(graph)h(w)n(as)f(weights)g(on)h(the)f(v)n(ertices,)i +(then)e Fj(vwgt[)o Fy(i)16 b Fj(])51 b FK(is)h(used)g(to)h(store)f(the) +0 8136 y(weight)43 b(of)g(v)n(erte)n(x)e Fy(i)16 b FK(.)55 +b(Similarly)-11 b(,)44 b(if)g(the)f(graph)f(has)h(weights)f(on)h(the)g +(edges,)f(then)h(the)f(weight)h(of)g(edge)g Fj(adjncy[)27 +b Fy(j)16 b Fj(])40 b FK(is)j(stored)g(in)0 8356 y Fj(adjwgt[)27 +b Fy(j)16 b Fj(])p FK(.)49 b(This)41 b(is)h(the)f(same)g(format)h(that) +g(is)f(used)g(by)g(the)h(\(serial\))j FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)48 b FK(library)43 b(routines.)0 +8774 y FB(Distrib)m(uted)58 b(CSR)d(Format)204 b FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)57 +b FK(uses)49 b(an)h(e)n(xtension)f(of)h(the)g(CSR)g(format)h(that)g +(allo)l(ws)e(the)h(v)n(ertices)f(of)i(the)f(graph)0 8993 +y(and)41 b(their)h(adjacenc)n(y)e(lists)h(to)g(be)h(distrib)m(uted)f +(among)g(the)h(processors.)50 b(In)41 b(particular)-7 +b(,)46 b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b +FA(T)g FG(I)p FA(S)48 b FK(assumes)40 b(that)h(each)g(processor)15 +9212 y Fy(P)104 9237 y Fh(i)198 9212 y FK(stores)d Fy(n)713 +9237 y Fh(i)808 9212 y FK(consecuti)l(v)n(e)e(v)n(ertices)i(of)g(the)h +(graph)f(and)h(the)f(corresponding)g Fy(m)4647 9237 y +Fh(i)4741 9212 y FK(edges,)g(so)g(that)h Fy(n)53 b FL(D)5986 +9088 y Fg(P)6158 9260 y Fh(i)6242 9212 y Fy(n)6331 9237 +y Fh(i)6387 9212 y FK(,)39 b(and)f(2)26 b FL(\003)g Fy(m)55 +b FL(D)7318 9088 y Fg(P)7491 9260 y Fh(i)7574 9212 y +Fy(m)7703 9237 y Fh(i)7758 9212 y FK(.)0 9432 y(Here,)34 +b(each)f(processor)g(stores)g(its)g(local)h(part)f(of)h(the)g(graph)g +(in)f(the)h(four)g(arrays)f Fj(xadj[)p Fy(n)5224 9457 +y Fh(i)5286 9432 y FL(C)8 b FK(1)p Fj(])p FK(,)33 b Fj(vwgt[)p +Fy(n)6271 9457 y Fh(i)6326 9432 y Fj(])p FK(,)h Fj(adjncy[)p +Fy(m)7331 9457 y Fh(i)7384 9432 y Fj(])p FK(,)g(and)0 +9651 y Fj(adjwgt[)p Fy(m)829 9676 y Fh(i)882 9651 y Fj(])p +FK(,)43 b(using)g(the)g(CSR)g(storage)g(scheme.)55 b(Ag)o(ain,)43 +b(if)h(the)f(graph)h(is)f(unweighted,)g(the)g(arrays)g +Fj(vwgt)e FK(and)i Fj(adjwgt)f FK(can)0 9870 y(be)48 +b(set)f(to)i Fj(NULL)p FK(.)d(The)i(straightforw)n(ard)h(w)n(ay)f(to)h +(distrib)m(ute)f(the)g(graph)g(for)53 b FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)54 b FK(is)48 +b(to)g(tak)n(e)g Fy(n)7 b Fz(=)19 b Fy(p)54 b FK(consecuti)l(v)n(e)47 +b(adjacenc)n(y)0 10089 y(lists)39 b(from)h Fj(adjncy)d +FK(and)i(store)g(them)h(on)f(consecuti)l(v)n(e)f(processors)g(\(where) +58 b Fy(p)45 b FK(is)39 b(the)g(number)h(of)f(processors\).)50 +b(In)39 b(addition,)h(each)p 0 10378 3120 7 v 174 10498 +a Fq(4)239 10546 y FF(Multi-constraint)35 b(and)g(multi-objecti)m(v)n +(e)h(graph)f(partitioning)h(formulations)g([6,)e(13)q(])g(can)h(get)f +(around)i(this)e(requirement)h(for)g(some)f(applications.)45 +b(These)34 b(also)0 10704 y(allo)m(w)f(the)h(computation)h(of)f +(partitionings)h(for)f(bipartite)g(graphs,)g(as)f(well)g(as)g(for)h +(graphs)g(corresponding)i(to)e(non-square)h(and)f(non-symmetric)i +(matrices.)3817 11298 y FK(12)p eop +%%Page: 13 13 +13 12 bop 900 5478 a @beginspecial 0 @llx 0 @lly 506 +@urx 462 @ury 3600 @rwi @setspecial +%%BeginDocument: ./figures/dcsr.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: dcsr.eps +%%Creator: fig2dev Version 3.2 Patchlevel 3b +%%CreationDate: Mon Jan 14 18:13:16 2002 +%%For: kirk@lnx08 (Kirk Schloegel) +%%BoundingBox: 0 0 506 462 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 462 moveto 0 0 lineto 506 0 lineto 506 462 lineto closepath clip newpath +-8.0 477.0 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +%%Page: 1 1 +10 setmiterlimit + 0.06000 0.06000 sc +% +% Fig objects follow +% +7.500 slw +% Ellipse +n 3300 300 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3600 300 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3900 300 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4200 300 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4500 300 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3300 600 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3600 600 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3900 600 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4200 600 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4500 600 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4500 900 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 4200 900 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3900 900 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3600 900 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 3300 900 38 38 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +/Times-Roman ff 150.00 scf sf +3600 4350 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 4350 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 4350 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 4350 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4200 4350 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4425 4350 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 4950 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 4950 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 4950 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 4950 m +gs 1 -1 sc (15) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 4950 m +gs 1 -1 sc (vtxdist) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 4650 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 4650 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 4650 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4200 4650 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4350 4650 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4500 4650 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4650 4650 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 4650 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4800 4650 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4950 4650 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5400 4650 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5250 4650 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5100 4650 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 5550 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 5550 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 5550 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 5550 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4275 5550 m +gs 1 -1 sc (15) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4500 5550 m +gs 1 -1 sc (18) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 5850 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4275 5850 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4425 5850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4575 5850 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4800 5850 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4950 5850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5100 5850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5250 5850 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5475 5850 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5625 5850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5775 5850 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5925 5850 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6150 5850 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6300 5850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6450 5850 m +gs 1 -1 sc (14) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 5850 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 5850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 5850 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 6150 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 6150 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 6150 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 6150 m +gs 1 -1 sc (15) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 6150 m +gs 1 -1 sc (vtxdist) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 7050 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 7050 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3975 7050 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 7050 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4350 7050 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4575 7050 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4725 7050 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4950 7050 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5175 7050 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5325 7050 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5550 7050 m +gs 1 -1 sc (14) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5775 7050 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5925 7050 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 6750 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 6750 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 6750 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 6750 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4200 6750 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4425 6750 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3600 7350 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 7350 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3900 7350 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 7350 m +gs 1 -1 sc (15) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 7350 m +gs 1 -1 sc (vtxdist) dup sw pop neg 0 rm col-1 sh gr +% Polyline +n 1350 4125 m 7200 4125 l 7200 7500 l 1350 7500 l + cp gs col-1 s gr +/Times-Roman ff 180.00 scf sf +1350 4050 m +gs 1 -1 sc (Description of the graph on a parallel computer with 3 processors \(ParMeTiS\)) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 4350 m +gs 1 -1 sc (xadj) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 4650 m +gs 1 -1 sc (adjncy) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +1500 4350 m +gs 1 -1 sc (Processor 0:) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1500 5550 m +gs 1 -1 sc (Processor 1:) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 5550 m +gs 1 -1 sc (xadj) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 5850 m +gs 1 -1 sc (adjncy) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 7050 m +gs 1 -1 sc (adjncy) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 6750 m +gs 1 -1 sc (xadj) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +1500 6750 m +gs 1 -1 sc (Processor 2:) col-1 sh gr +/Times-Roman ff 150.00 scf sf +900 2550 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1050 2550 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1200 2550 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1350 2550 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1500 2550 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1725 2550 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1950 2550 m +gs 1 -1 sc (16) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2175 2550 m +gs 1 -1 sc (20) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2400 2550 m +gs 1 -1 sc (24) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2625 2550 m +gs 1 -1 sc (28) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2850 2550 m +gs 1 -1 sc (31) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3075 2550 m +gs 1 -1 sc (33) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3300 2550 m +gs 1 -1 sc (36) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3525 2550 m +gs 1 -1 sc (39) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 2550 m +gs 1 -1 sc (42) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3975 2550 m +gs 1 -1 sc (44) col-1 sh gr +/Times-Roman ff 150.00 scf sf +900 2850 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1200 2850 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1350 2850 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1500 2850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1650 2850 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1800 2850 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1950 2850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +1050 2850 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2100 2850 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2250 2850 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2700 2850 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2550 2850 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2400 2850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3375 2850 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3525 2850 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3675 2850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3825 2850 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 2850 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4200 2850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4350 2850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4500 2850 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4725 2850 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4875 2850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5025 2850 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5175 2850 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5400 2850 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5550 2850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5700 2850 m +gs 1 -1 sc (14) col-1 sh gr +/Times-Roman ff 150.00 scf sf +2850 2850 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3000 2850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3150 2850 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +5925 2850 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6075 2850 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6300 2850 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6450 2850 m +gs 1 -1 sc (10) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6675 2850 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +6900 2850 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +7050 2850 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +7275 2850 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +7500 2850 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +7650 2850 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +7875 2850 m +gs 1 -1 sc (14) col-1 sh gr +/Times-Roman ff 150.00 scf sf +8100 2850 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +8250 2850 m +gs 1 -1 sc (13) col-1 sh gr +% Polyline +n 150 2250 m 8550 2250 l 8550 3000 l 150 3000 l + cp gs col-1 s gr +/Times-Roman ff 150.00 scf sf +600 2550 m +gs 1 -1 sc (xadj) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 150.00 scf sf +600 2850 m +gs 1 -1 sc (adjncy) dup sw pop neg 0 rm col-1 sh gr +/Times-Roman ff 180.00 scf sf +150 2175 m +gs 1 -1 sc (Description of the graph on a serial computer \(serial MeTiS\)) col-1 sh gr +% Polyline +n 3300 600 m + 4500 600 l gs col-1 s gr +% Polyline +n 3600 300 m + 3600 900 l gs col-1 s gr +% Polyline +n 3300 300 m 4500 300 l 4500 900 l 3300 900 l + 3300 300 l cp gs col-1 s gr +% Polyline +n 3900 300 m + 3900 900 l gs col-1 s gr +% Polyline +n 4200 300 m + 4200 900 l gs col-1 s gr +/Times-Roman ff 150.00 scf sf +3150 450 m +gs 1 -1 sc (0) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3450 450 m +gs 1 -1 sc (1) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 450 m +gs 1 -1 sc (2) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 450 m +gs 1 -1 sc (3) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4350 450 m +gs 1 -1 sc (4) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3150 750 m +gs 1 -1 sc (5) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3450 750 m +gs 1 -1 sc (6) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3750 750 m +gs 1 -1 sc (7) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4050 750 m +gs 1 -1 sc (8) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4350 750 m +gs 1 -1 sc (9) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4425 1125 m +gs 1 -1 sc (14) col-1 sh gr +/Times-Roman ff 150.00 scf sf +4125 1125 m +gs 1 -1 sc (13) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3825 1125 m +gs 1 -1 sc (12) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3525 1125 m +gs 1 -1 sc (11) col-1 sh gr +/Times-Roman ff 150.00 scf sf +3225 1125 m +gs 1 -1 sc (10) col-1 sh gr +/Helvetica-Bold ff 210.00 scf sf +3900 1500 m +gs 1 -1 sc (\(a\) A sample graph) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold ff 210.00 scf sf +3900 3375 m +gs 1 -1 sc (\(b\) Serial CSR format) dup sw pop 2 div neg 0 rm col-1 sh gr +/Helvetica-Bold ff 210.00 scf sf +3900 7950 m +gs 1 -1 sc (\(c\) Distributed CSR format) dup sw pop 2 div neg 0 rm col-1 sh gr +$F2psEnd +rs + +%%EndDocument + @endspecial 0 5844 a Fx(Figure)49 b(5)p FK(:)74 b Fw(An)48 +b(e)l(xample)g(of)g(the)g(par)o(ameters)g(passed)f(to)52 +b(P)-6 b Fv(A)8 b(R)g Fw(M)-9 b Fv(E)-34 b Fw(T)g Fv(I)p +Fw(S)55 b(in)48 b(a)g(three)g(processor)g(case)n(.)78 +b(The)48 b(arr)o(a)l(ys)h Fj(vwgt)e Fw(and)g Fj(adjwgt)f +Fw(are)0 6043 y(assumed)37 b(to)h(be)f(NULL.)0 6377 y +FK(processor)f(needs)f(its)h(local)h Fj(xadj)d FK(array)j(to)f(point)h +(to)g(where)f(each)f(of)i(its)f(local)g(v)n(ertices')g(adjacenc)n(y)f +(lists)h(be)n(gin)f(and)i(end.)49 b(Thus,)37 b(if)0 6597 +y(we)i(tak)n(e)h(all)f(the)h(local)f Fj(adjncy)e FK(arrays)j(and)f +(concatenate)f(them,)i(we)f(will)h(get)f(e)n(xactly)g(the)g(same)g +Fj(adjncy)e FK(array)j(that)g(is)f(used)g(in)0 6816 y(the)k(serial)g +(CSR.)g(Ho)l(we)l(v)n(er)-7 b(,)42 b(concatenating)g(the)i(local)f +Fj(xadj)e FK(arrays)i(will)h(not)f(gi)l(v)n(e)g(us)g(the)g(serial)g +Fj(xadj)f FK(array)-11 b(.)56 b(This)43 b(is)g(because)0 +7035 y(the)50 b(entries)f(in)h(each)f(local)h Fj(xadj)e +FK(must)i(point)g(to)g(their)h(local)e Fj(adjncy)f FK(array)-11 +b(,)52 b(and)d(so,)i Fj(xadj[)p FK(0)p Fj(])d FK(is)i(zero)f(for)i(all) +f(processors.)0 7254 y(In)d(addition)f(to)h(these)f(four)h(arrays,)f +(each)g(processor)g(also)f(requires)i(the)f(array)g Fj(vtxdist[)19 +b Fy(p)43 b FL(C)d FK(1)p Fj(])46 b FK(that)h(indicates)e(the)i(range)f +(of)0 7473 y(v)n(ertices)f(that)i(are)f(local)h(to)g(each)e(processor) +-9 b(.)66 b(In)47 b(particular)-7 b(,)48 b(processor)61 +b Fy(P)4428 7498 y Fh(i)4530 7473 y FK(stores)46 b(the)g(v)n(ertices)g +(from)h Fj(vtxdist[)o Fy(i)16 b Fj(])43 b FK(up)k(to)g(\(b)m(ut)0 +7693 y(not)42 b(including\))g(v)n(erte)n(x)e Fj(vtxdist[)o +Fy(i)50 b FL(C)37 b FK(1)p Fj(])p FK(.)199 7912 y(Figure)42 +b(5\(c\))g(illustrates)f(the)g(distrib)m(uted)g(CSR)h(format)g(by)f(an) +g(e)n(xample)f(on)i(a)f(three-processor)g(system.)50 +b(The)41 b(15-v)n(erte)n(x)g(graph)0 8131 y(in)65 b(Figure)g(5\(a\))g +(is)g(distrib)m(uted)g(among)f(the)h(processors)f(so)g(that)h(each)f +(processor)g(gets)g(5)h(v)n(ertices)e(and)i(their)g(corresponding)0 +8350 y(adjacenc)n(y)e(lists.)121 b(That)65 b(is,)70 b(Processor)64 +b(Zero)i(gets)e(v)n(ertices)g(0)g(through)i(4,)k(Processor)64 +b(One)h(gets)f(v)n(ertices)g(5)h(through)g(9,)70 b(and)0 +8569 y(Processor)54 b(T)-13 b(w)n(o)56 b(gets)e(v)n(ertices)g(10)h +(through)h(14.)91 b(This)55 b(\002gure)g(sho)l(ws)f(the)h +Fj(xadj)p FK(,)h Fj(adjncy)p FK(,)g(and)e Fj(vtxdist)f +FK(arrays)h(for)i(each)0 8788 y(processor)-9 b(.)50 b(Note)41 +b(that)h(the)f Fj(vtxdist)e FK(array)j(will)g(al)n(w)n(ays)f(be)g +(identical)h(for)g(e)l(v)n(ery)e(processor)-9 b(.)199 +9008 y(All)33 b(\002)l(v)n(e)f(arrays)h(that)f(describe)g(the)h +(distrib)m(uted)g(CSR)f(format)i(are)e(de\002ned)h(in)j +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)40 b FK(to)33 b(be)f(of)h(type)g Fj(idxtype)p FK(.)45 +b(By)33 b(def)n(ault)0 9227 y Fj(idxtype)50 b FK(is)i(set)f(to)i(be)f +(equi)l(v)l(alent)f(to)i(type)f Fj(int)f FK(\()p Fs(i.e)p +FK(.,)j(inte)n(gers\).)82 b(Ho)l(we)l(v)n(er)-7 b(,)54 +b Fj(idxtype)49 b FK(can)j(be)g(made)g(to)g(be)g(equi)l(v)l(alent)g(to) +0 9446 y(a)d Fj(short)98 b(int)47 b FK(for)j(certain)f(architectures)f +(that)h(use)g(64-bit)h(inte)n(gers)e(by)h(def)n(ault.)74 +b(\(Note)49 b(that)g(doing)h(so)e(will)i(cut)f(the)g(memory)0 +9665 y(usage)h(and)h(communication)g(time)g(required)h(approximately)f +(in)g(half.\))80 b(The)52 b(con)-7 b(v)n(ersion)50 b(of)h +Fj(idxtype)e FK(from)j Fj(int)e FK(to)h Fj(short)0 9884 +y FK(can)46 b(be)g(done)h(by)f(modifying)i(the)e(\002le)h +Fj(parmetis.h)p FK(.)62 b(\(Instructions)47 b(are)f(included)h +(there.\))66 b(The)47 b(same)e Fj(idxtype)f FK(is)j(used)e(for)0 +10104 y(the)c(arrays)h(that)f(store)g(the)h(computed)f(partitioning)i +(and)e(permutation)h(v)n(ectors.)199 10323 y(When)51 +b(multiple)i(v)n(erte)n(x)d(weights)i(are)f(used)g(for)h +(multi-constraint)h(partitioning,)h(the)e Fy(c)j FK(v)n(erte)n(x)50 +b(weights)i(for)g(each)f(v)n(erte)n(x)f(are)0 10542 y(stored)f +(contiguously)g(in)g(the)g Fj(vwgt)e FK(array)-11 b(.)74 +b(In)49 b(this)g(case,)h(the)e Fj(vwgt)g FK(array)h(is)g(of)g(size)f +Fy(n)7 b(c)s FK(,)51 b(where)e Fy(n)56 b FK(is)49 b(the)g(number)g(of)h +(locally-)0 10761 y(stored)41 b(v)n(ertices)g(and)g Fy(c)k +FK(is)c(the)g(number)h(of)g(v)n(erte)n(x)e(weights)h(\(and)h(also)f +(the)g(number)h(of)g(balance)f(constraints\).)3817 11298 +y(13)p eop +%%Page: 14 14 +14 13 bop 0 166 a Ft(4.2)199 b(Format)55 b(of)g(V)-10 +b(er)t(te)m(x)55 b(Coor)l(dinates)0 485 y FK(As)37 b(discussed)g(in)h +(Section)g(3.1,)k FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)44 b FK(pro)n(vides)38 b(routines)g(that)g(use)f +(the)h(coordinate)g(information)h(of)f(the)g(v)n(ertices)f(to)h +(quickly)0 704 y(pre-distrib)m(ute)65 b(the)f(graph,)70 +b(and)64 b(so,)70 b(speedup)63 b(the)i(e)n(x)n(ecution)e(of)i(the)f +(parallel)h Fy(k)10 b FK(-w)n(ay)64 b(partitioning.)121 +b(These)64 b(coordinates)g(are)0 923 y(speci\002ed)f(in)g(an)g(array)h +(called)f Fj(xyz)f FK(of)i(single)f(precision)g(\003oating)g(point)h +(numbers)f(\()p Fs(i.e)p FK(.,)68 b Fj(float)p FK(\).)115 +b(If)64 b Fy(d)76 b FK(is)63 b(the)g(number)h(of)0 1142 +y(dimensions)48 b(of)i(the)e(mesh)h(\()p Fs(i.e)o FK(.,)h +Fy(d)72 b FL(D)60 b FK(2)49 b(for)g(2D)g(meshes)e(or)j +Fy(d)72 b FL(D)59 b FK(3)49 b(for)h(3D)e(meshes\),)i(then)e(each)g +(processor)h(requires)f(an)h(array)0 1362 y(of)i(size)g +Fy(d)56 b FL(\003)44 b Fy(n)858 1387 y Fh(i)914 1362 +y FK(,)53 b(where)e Fy(n)1555 1387 y Fh(i)1662 1362 y +FK(is)g(the)g(number)g(of)h(locally-stored)f(v)n(ertices.)79 +b(\(Note)51 b(that)g(the)g(number)g(of)h(dimensions)f(of)g(the)g(mesh,) +0 1581 y Fy(d)12 b FK(,)55 b(is)d(required)g(as)g(a)g(parameter)g(to)h +(the)f(routine.\))84 b(In)52 b(this)h(array)-11 b(,)54 +b(the)e(coordinates)g(of)h(v)n(erte)n(x)d Fy(i)68 b FK(are)52 +b(stored)g(starting)h(at)f(location)0 1800 y Fj(xyz[)o +Fy(i)42 b FL(\003)28 b Fy(d)12 b Fj(])39 b FK(up)g(to)g(\(b)m(ut)g(not) +h(including\))f(location)g Fj(xyz[)o Fy(i)k FL(\003)27 +b Fy(d)40 b FL(C)27 b Fy(d)12 b Fj(])p FK(.)51 b(F)n(or)39 +b(e)n(xample,)f(if)h Fy(d)59 b FL(D)46 b FK(3,)39 b(then)g(the)g(x,)g +(y)-11 b(,)39 b(and)g(z)g(coordinates)0 2019 y(of)j(v)n(erte)n(x)d +Fy(i)58 b FK(are)41 b(stored)g(at)h Fj(xyz[3*i])p FK(,)c +Fj(xyz[3*i+1])p FK(,)f(and)k Fj(xyz[3*i+2])p FK(,)d(respecti)l(v)n(ely) +-11 b(.)0 2474 y Ft(4.3)199 b(Format)55 b(of)g(the)h(Input)f(Mesh)0 +2793 y FK(The)98 b(routine)h FA(P)-7 b(arMETIS)p 1693 +2793 50 7 v 61 w(V3)p 1957 2793 V 60 w(P)g(ar)7 b(tMeshKw)n(a)-5 +b(y)99 b FK(tak)n(es)e(a)h(distrib)m(uted)g(mesh)g(and)g(computes)f +(its)h(partitioning,)113 b(while)0 3012 y FA(P)-7 b(arMETIS)p +768 3012 V 61 w(V3)p 1032 3012 V 60 w(Mesh2Dual)58 b +FK(2dual)f(tak)n(es)g(a)f(distrib)m(uted)h(mesh)f(and)h(constructs)f(a) +h(distrib)m(uted)g(dual)g(graph.)97 b(Both)57 b(of)g(these)0 +3231 y(routines)41 b(require)h(an)f Fj(elmdist)e FK(array)i(that)h +(speci\002es)e(the)h(distrib)m(ution)h(of)g(the)f(mesh)g(elements,)f(b) +m(ut)i(that)f(is)g(otherwise)g(identical)0 3450 y(to)53 +b(the)f Fj(vtxdist)e FK(array)-11 b(.)84 b(The)n(y)52 +b(also)g(require)h(a)f(pair)h(of)f(arrays)g(called)g +Fj(eptr)f FK(and)i Fj(eind)p FK(,)g(as)f(well)g(as)g(the)g(inte)n(ger)g +(parameter)0 3670 y Fj(ncommonnodes)p FK(.)199 3889 y(The)e +Fj(eptr)e FK(and)h Fj(eind)f FK(arrays)h(are)h(similar)g(in)f(nature)h +(to)f(the)h Fj(xadj)e FK(and)h Fj(adjncy)e FK(arrays)j(used)e(to)i +(specify)f(the)h(adjacenc)n(y)0 4108 y(list)44 b(of)f(a)g(graph)h(b)m +(ut)f(no)l(w)g(for)i(each)d(element)h(the)n(y)g(specify)g(the)g(set)g +(of)h(nodes)f(that)g(mak)n(e)h(up)f(each)g(element.)56 +b(Speci\002cally)-11 b(,)44 b(the)g(set)0 4327 y(of)d(nodes)f(that)h +(belong)g(to)g(element)f Fy(i)57 b FK(is)40 b(stored)h(in)g(array)g +Fj(eind)e FK(starting)i(at)g(inde)n(x)f Fj(eptr[)o Fy(i)16 +b Fj(])39 b FK(and)i(ending)g(at)f(\(b)m(ut)h(not)g(including\))0 +4546 y(inde)n(x)e Fj(eptr[)o Fy(i)j FL(C)27 b FK(1)p +Fj(])39 b FK(\(in)g(other)h(w)n(ords,)f Fj(eind[eptr[)o +Fy(i)16 b Fj(]])35 b FK(up)k(through)g(and)g(including)h +Fj(eind[eptr[)o Fy(i)g FL(C)27 b FK(1)p Fj(]-1])p FK(\).)49 +b(Hence,)0 4765 y(the)54 b(node)g(lists)f(for)i(each)e(element)h(are)g +(stored)f(consecuti)l(v)n(ely)g(in)h(the)g(array)g Fj(eind)p +FK(.)87 b(This)54 b(format)h(allo)l(ws)e(the)h(speci\002cation)g(of)0 +4985 y(meshes)40 b(that)i(contain)f(elements)g(of)h(mix)n(ed)f(type.) +199 5204 y(The)58 b Fj(ncommonnodes)53 b FK(parameter)k(speci\002es)g +(the)g(de)n(gree)g(of)g(connecti)l(vity)h(that)f(is)h(desired)f +(between)f(the)i(v)n(ertices)e(of)i(the)0 5423 y(dual)50 +b(graph.)77 b(Speci\002cally)-11 b(,)52 b(an)d(edge)h(is)g(placed)f +(between)g(tw)n(o)i(v)n(ertices)e(if)h(their)h(corresponding)e(mesh)h +(elements)f(share)h(at)g(least)4 5642 y Fy(g)55 b FK(nodes,)50 +b(where)j Fy(g)i FK(is)49 b(the)g Fj(ncommonnodes)c FK(parameter)-9 +b(.)74 b(Hence,)49 b(this)g(parameter)g(can)g(be)g(set)g(to)g(result)g +(in)g(a)g(traditional)h(dual)0 5861 y(graph)57 b(\()p +Fs(e)n(.g)o FK(.,)i(a)d(v)l(alue)g(of)h(tw)n(o)f(for)h(a)g(triangle)f +(mesh)g(or)h(a)f(v)l(alue)g(of)h(four)g(for)g(a)f(he)n(xahedral)f +(mesh\).)96 b(Ho)l(we)l(v)n(er)-7 b(,)59 b(it)d(can)g(also)g(be)0 +6081 y(set)43 b(higher)i(or)f(lo)l(wer)g(for)g(increased)f(or)i +(decreased)d(connecti)l(vity)-11 b(.)58 b FA(P)-7 b(arMETIS)p +4760 6081 V 61 w(V3)p 5024 6081 V 60 w(P)g(ar)7 b(tMeshKw)n(a)-5 +b(y)45 b FK(additionally)f(requires)g(an)0 6300 y Fj(elmwgt)39 +b FK(array)j(that)f(is)h(analogous)e(to)i(the)g Fj(vwgt)e +FK(array)-11 b(.)0 6755 y Ft(4.4)199 b(Format)55 b(of)g(the)h(Computed) +e(P)-6 b(ar)t(titionings)55 b(and)g(Or)l(derings)0 7074 +y FB(Format)45 b(of)h(the)f(P)-5 b(ar)s(titioning)48 +b(Arra)m(y)198 b FK(The)40 b(partitioning)h(and)f(repartitioning)h +(routines)f(require)h(that)f(arrays)f(\(called)h Fj(part)p +FK(\))0 7293 y(of)54 b(sizes)e Fy(n)657 7318 y Fh(i)767 +7293 y FK(\(where)i Fy(n)1371 7318 y Fh(i)1480 7293 y +FK(is)g(the)f(number)h(of)g(local)f(v)n(ertices\))g(be)g(passed)g(as)f +(parameters)h(to)h(each)f(processor)-9 b(.)86 b(Upon)54 +b(completion)0 7512 y(of)h(the)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)62 b FK(routine,)c(for)e(each)e +(v)n(erte)n(x)81 b Fy(j)16 b FK(,)58 b(the)d(sub-domain)g(number)h(\()p +Fs(i.e)o FK(.,)i(the)d(processor)f(label\))h(to)g(which)g(this)g(v)n +(erte)n(x)0 7731 y(belongs)37 b(will)g(ha)m(v)n(e)f(been)h(written)g +(to)h Fj(part[)27 b Fy(j)16 b Fj(])p FK(.)48 b(Note)37 +b(that)k FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b +FA(T)g FG(I)p FA(S)44 b FK(does)36 b(not)i(redistrib)m(ute)f(the)g +(graph)g(according)g(to)g(the)h(ne)l(w)0 7950 y(partitioning,)k(it)g +(simply)f(computes)g(the)h(partitioning)g(and)f(writes)h(it)g(to)f(the) +h Fj(part)e FK(array)-11 b(.)199 8169 y(Additionally)g(,)45 +b(whene)l(v)n(er)d(the)i(number)g(of)f(sub-domains)h(does)f(not)h +(equal)f(the)g(number)h(of)g(processors)f(that)h(are)f(used)g(to)h +(com-)0 8389 y(pute)50 b(a)g(repartitioning,)j FA(P)-7 +b(arMETIS)p 2226 8389 V 61 w(V3)p 2490 8389 V 59 w(Adaptiv)l(eRepar)7 +b(t)52 b FK(requires)e(that)g(the)g(pre)l(viously)g(computed)g +(partitioning)h(be)f(passed)0 8608 y(as)i(a)h(parameter)g(via)g(the)g +Fj(part)e FK(array)-11 b(.)86 b(\(This)53 b(is)g(also)f(required)i +(whene)l(v)n(er)d(the)i(user)g(chooses)f(to)h(de-couple)f(the)h +(sub-domains)0 8827 y(from)44 b(the)g(processors.)56 +b(See)43 b(discussion)g(in)h(Section)f(5.2.\))57 b(This)44 +b(is)g(because)e(the)h(initial)h(partitioning)h(needs)e(to)g(be)h +(obtained)f(from)0 9046 y(the)h(v)l(alues)g(supplied)g(in)g(the)h +Fj(part)d FK(array)-11 b(.)60 b(If)45 b(the)f(numbers)h(of)f +(sub-domains)g(and)g(processors)g(are)g(equal,)g(then)g(the)g(initial)h +(parti-)0 9265 y(tioning)e(can)f(be)g(obtained)g(from)h(the)f(initial)h +(graph)g(distrib)m(ution,)f(and)g(so)g(this)g(information)i(need)e(not) +g(be)g(supplied.)54 b(\(In)42 b(this)h(case,)0 9484 y(for)f(each)f +(processor)f Fy(i)16 b FK(,)41 b(e)l(v)n(ery)f(element)i(of)f +Fj(part)f FK(w)n(ould)i(be)g(set)f(to)f Fy(i)16 b FK(.\))0 +9903 y FB(Format)37 b(of)h(the)g(P)-5 b(erm)m(utation)38 +b(Arra)m(y)198 b FK(Lik)n(e)l(wise,)35 b(each)d(processor)g(running)h +FA(P)-7 b(arMETIS)p 5708 9903 V 61 w(V3)p 5972 9903 V +60 w(NodeND)34 b FK(writes)e(its)h(portion)0 10122 y(of)54 +b(the)g(computed)f(\002ll-reducing)i(ordering)f(to)g(an)f(array)h +(called)f Fj(order)p FK(.)86 b(Similar)55 b(to)f(the)f +Fj(part)f FK(array)-11 b(,)57 b(the)d(size)e(of)i Fj(order)e +FK(is)0 10341 y(equal)47 b(to)g(the)h(number)f(of)h(v)n(ertices)e +(stored)h(at)g(each)g(processor)-9 b(.)68 b(Upon)47 b(completion,)h +(for)g(each)f(v)n(erte)n(x)73 b Fy(j)16 b FK(,)49 b Fj(order[)27 +b Fy(j)16 b Fj(])45 b FK(stores)i(the)0 10560 y(ne)l(w)41 +b(global)h(number)f(of)h(this)g(v)n(erte)n(x)e(in)i(the)f +(\002ll-reducing)i(permutation.)199 10780 y(Besides)63 +b(the)h(ordering)g(v)n(ector)-7 b(,)69 b FA(P)-7 b(arMETIS)p +2958 10780 V 61 w(V3)p 3222 10780 V 60 w(NodeND)64 b +FK(also)g(returns)g(information)h(about)f(the)g(sizes)e(of)j(the)e(dif) +l(ferent)3817 11298 y(14)p eop +%%Page: 15 15 +15 14 bop 1500 2086 a @beginspecial 0 @llx 0 @lly 412 +@urx 179 @ury 2880 @rwi @setspecial +%%BeginDocument: ./figures/stree.eps +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: stree.fig +%%Creator: fig2dev Version 3.1 Patchlevel 1 +%%CreationDate: Thu Jul 17 14:01:58 1997 +%%For: karypis@in19 (George Karypis) +%%Orientation: Portrait +%%BoundingBox: 0 0 412 179 +%%Pages: 0 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {} def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +-89.0 218.0 translate +1 -1 scale + +/clp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/l {lineto} bind def +/m {moveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit + 0.06000 0.06000 sc +/Times-Roman findfont 180.00 scalefont setfont +5175 3600 m +gs 1 -1 sc (13) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5625 3600 m +gs 1 -1 sc (11) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5850 3600 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6075 3600 m +gs 1 -1 sc (3) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +7.500 slw +% Polyline +n 6780 675 m 6675 675 6675 2220 105 arcto 4 {pop} repeat 6675 2325 7020 2325 105 arcto 4 {pop} repeat 7125 2325 7125 780 105 arcto 4 {pop} repeat 7125 675 6780 675 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +6825 3600 m +gs 1 -1 sc (9) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6600 3600 m +gs 1 -1 sc (8) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6300 3600 m +gs 1 -1 sc (12) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4950 3600 m +gs 1 -1 sc (5) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +3600 3600 m +gs 1 -1 sc (1) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 2880 675 m 2775 675 2775 2220 105 arcto 4 {pop} repeat 2775 2325 3120 2325 105 arcto 4 {pop} repeat 3225 2325 3225 780 105 arcto 4 {pop} repeat 3225 675 2880 675 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 1605 1275 m 1500 1275 1500 1620 105 arcto 4 {pop} repeat 1500 1725 2520 1725 105 arcto 4 {pop} repeat 2625 1725 2625 1380 105 arcto 4 {pop} repeat 2625 1275 1605 1275 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 3480 1275 m 3375 1275 3375 1620 105 arcto 4 {pop} repeat 3375 1725 4320 1725 105 arcto 4 {pop} repeat 4425 1725 4425 1380 105 arcto 4 {pop} repeat 4425 1275 3480 1275 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +3825 3600 m +gs 1 -1 sc (0) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4725 3600 m +gs 1 -1 sc (4) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4500 3600 m +gs 1 -1 sc (7) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4275 3600 m +gs 1 -1 sc (6) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4050 3600 m +gs 1 -1 sc (14) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5400 3600 m +gs 1 -1 sc (10) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Courier-Bold findfont 180.00 scalefont setfont +3225 3600 m +gs 1 -1 sc (order) dup stringwidth pop neg 0 rmoveto col-1 show gr +/Courier-Bold findfont 180.00 scalefont setfont +3225 3225 m +gs 1 -1 sc (sizes) dup stringwidth pop neg 0 rmoveto col-1 show gr +% Polyline +n 7380 1275 m 7275 1275 7275 1620 105 arcto 4 {pop} repeat 7275 1725 8220 1725 105 arcto 4 {pop} repeat 8325 1725 8325 1380 105 arcto 4 {pop} repeat 8325 1275 7380 1275 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +% Polyline +n 5505 1275 m 5400 1275 5400 1620 105 arcto 4 {pop} repeat 5400 1725 6420 1725 105 arcto 4 {pop} repeat 6525 1725 6525 1380 105 arcto 4 {pop} repeat 6525 1275 5505 1275 105 arcto 4 {pop} repeat clp gs col7 0.90 shd ef gr gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +3825 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4050 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4500 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4275 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5550 825 m +gs 1 -1 sc (1) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 8100 900 m 8100 2100 l gs col-1 s gr +% Polyline +n 5700 1500 m 8100 1500 l gs col-1 s gr +% Polyline +n 5700 2100 m 8175 2100 l gs col-1 s gr +% Polyline +n 5700 900 m 5700 2100 l gs col-1 s gr +% Polyline +n 6300 900 m 6300 2100 l gs col-1 s gr +% Polyline +n 6900 900 m 6900 2100 l gs col-1 s gr +% Polyline +n 7500 900 m 7500 2100 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +3600 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4950 3225 m +gs 1 -1 sc (3) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7350 1425 m +gs 1 -1 sc (10) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7950 1425 m +gs 1 -1 sc (11) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5550 2025 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6150 2025 m +gs 1 -1 sc (3) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6750 2025 m +gs 1 -1 sc (12) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7350 2025 m +gs 1 -1 sc (8) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7950 2025 m +gs 1 -1 sc (9) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6750 1425 m +gs 1 -1 sc (13) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4725 3225 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6150 825 m +gs 1 -1 sc (0) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6750 825 m +gs 1 -1 sc (14) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7350 825 m +gs 1 -1 sc (6) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +7950 825 m +gs 1 -1 sc (7) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +5550 1425 m +gs 1 -1 sc (4) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6150 1425 m +gs 1 -1 sc (5) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 5700 900 m 8175 900 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +2250 2025 m +gs 1 -1 sc (11) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +1650 2025 m +gs 1 -1 sc (10) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4050 1425 m +gs 1 -1 sc (9) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +3450 1425 m +gs 1 -1 sc (8) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +3450 825 m +gs 1 -1 sc (3) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +1650 1425 m +gs 1 -1 sc (5) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2250 1425 m +gs 1 -1 sc (6) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2850 1425 m +gs 1 -1 sc (7) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2850 2025 m +gs 1 -1 sc (12) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 1800 900 m 1800 2100 l gs col-1 s gr +% Polyline +n 1800 2100 m 4275 2100 l gs col-1 s gr +% Polyline +n 1800 900 m 4275 900 l gs col-1 s gr +% Polyline +n 1800 1500 m 4200 1500 l gs col-1 s gr +% Polyline +n 2400 900 m 2400 2100 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +3450 2025 m +gs 1 -1 sc (13) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +4050 2025 m +gs 1 -1 sc (14) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 3600 900 m 3600 2100 l gs col-1 s gr +% Polyline +n 3000 900 m 3000 2100 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +4050 825 m +gs 1 -1 sc (4) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Polyline +n 4200 900 m 4200 2100 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +1650 825 m +gs 1 -1 sc (0) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2850 825 m +gs 1 -1 sc (2) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2250 825 m +gs 1 -1 sc (1) dup stringwidth pop 2 div neg 0 rmoveto col-1 show gr +% Ellipse +n 4200 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 4200 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3600 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3600 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3000 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3000 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3000 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 1800 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 1800 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 1800 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 2400 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 2400 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 2400 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 4200 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 3600 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 5700 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 7500 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 7500 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 8100 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 8100 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 8100 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 5700 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 5700 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6300 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6300 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6300 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 7500 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6900 1500 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6900 900 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Ellipse +n 6900 2100 106 106 0 360 DrawEllipse gs col7 1.00 shd ef gr gs col-1 s gr + +% Polyline +n 3825 3075 m 5550 2250 l gs col7 0.90 shd ef gr gs col-1 s gr +n 5428.80 2274.71 m 5550.00 2250.00 l 5454.69 2328.84 l gs col-1 s gr +% Polyline +n 4275 3075 m 7350 2250 l gs col7 0.90 shd ef gr gs col-1 s gr +n 7226.33 2252.12 m 7350.00 2250.00 l 7241.87 2310.07 l gs col-1 s gr +% Polyline +n 4050 3075 m 7350 1050 l gs col7 0.90 shd ef gr gs col-1 s gr +n 7232.03 1087.19 m 7350.00 1050.00 l 7263.41 1138.33 l gs col-1 s gr +% Polyline +n 4500 3000 m 5400 1800 l gs col7 0.90 shd ef gr gs col-1 s gr +n 5304.00 1878.00 m 5400.00 1800.00 l 5352.00 1914.00 l gs col-1 s gr +% Polyline +n 3600 3000 m 5550 1050 l gs col7 0.90 shd ef gr gs col-1 s gr +n 5443.93 1113.64 m 5550.00 1050.00 l 5486.36 1156.07 l gs col-1 s gr +% Polyline +n 4725 3000 m 7275 1725 l gs col7 0.90 shd ef gr gs col-1 s gr +n 7154.25 1751.83 m 7275.00 1725.00 l 7181.09 1805.50 l gs col-1 s gr +% Polyline +n 4950 3075 m 6600 2325 l gs col7 0.90 shd ef gr gs col-1 s gr +n 6478.34 2347.35 m 6600.00 2325.00 l 6503.17 2401.97 l gs col-1 s gr +$F2psEnd +restore + +%%EndDocument + @endspecial 0 2451 a Fx(Figure)51 b(6)p FK(:)80 b Fw(An)50 +b(e)l(xample)h(of)f(the)g(order)r(ing)h(produced)e(b)n(y)h(P)-5 +b(arMETIS_V3_NodeND.)50 b(Consider)g(the)g(simple)i FK(3)47 +b FL(\002)h FK(5)j Fw(g)o(r)r(id)f(and)g(assume)h(that)0 +2650 y(w)o(e)45 b(ha)n(v)m(e)e(f)l(our)h(processors)n(.)67 +b(P)-5 b(arMETIS_V3_NodeND)44 b(\002nds)g(the)g(three)g(separ)o(ators)g +(that)g(are)g(shaded.)66 b(It)44 b(\002rst)h(\002nds)g(the)f(big)g +(separ)o(ator)g(and)0 2849 y(then)39 b(f)l(or)h(each)f(of)g(the)h(tw)o +(o)f(sub-domains)h(it)g(\002nds)f(the)g(smaller)-7 b(.)54 +b(At)40 b(the)f(end)g(of)h(the)f(order)r(ing,)h(the)f +Fj(order)f Fw(v)m(ector)h(concatenated)f(o)n(v)m(er)i(all)g(the)0 +3049 y(processors)d(will)i(be)e(the)g(one)g(sho)n(wn.)46 +b(Similar)r(ly)-13 b(,)38 b(the)f Fj(sizes)f Fw(arr)o(a)l(ys)i(will)g +(all)g(be)f(identical)g(to)g(the)g(one)g(sho)n(wn,)g(corresponding)f +(to)i(the)f(regions)0 3248 y(pointed)g(to)g(b)n(y)g(the)g(arro)n(ws)n +(.)0 3615 y FK(sub-domains)53 b(as)f(well)h(as)f(the)h(separators)f(at) +h(dif)l(ferent)g(le)l(v)n(els.)84 b(This)54 b(array)f(is)f(called)h +Fj(sizes)e FK(and)i(is)f(of)i(size)e(2)19 b Fy(p)58 b +FK(\(where)72 b Fy(p)58 b FK(is)0 3835 y(the)c(number)h(of)f +(processors\).)89 b(Ev)n(ery)54 b(processor)f(must)i(supply)f(this)g +(array)g(and)g(upon)g(return,)k(each)53 b(of)i(the)f +Fj(sizes)e FK(arrays)i(are)0 4054 y(identical.)199 4273 +y(The)49 b(format)g(of)f(this)g(array)h(is)f(as)f(follo)l(ws.)71 +b(The)49 b(\002rst)68 b Fy(p)53 b FK(entries)48 b(of)h +Fj(sizes)d FK(starting)i(from)h(0)g(to)67 b Fy(p)47 b +FL(\000)42 b FK(1)48 b(store)g(the)g(number)h(of)0 4492 +y(nodes)h(in)g(each)f(one)h(of)h(the)69 b Fy(p)55 b FK(sub-domains.)77 +b(The)50 b(remaining)69 b Fy(p)49 b FL(\000)43 b FK(1)50 +b(entries)g(of)g(this)g(array)h(starting)f(from)h Fj(sizes[)19 +b Fy(p)5 b Fj(])48 b FK(up)i(to)0 4711 y Fj(sizes[)p +FK(2)19 b Fy(p)c FL(\000)c FK(2)p Fj(])32 b FK(store)i(the)g(sizes)f +(of)i(the)f(separators)g(at)g(the)g(log)47 b Fy(p)40 +b FK(le)l(v)n(els)33 b(of)i(nested)e(dissection.)48 b(In)35 +b(particular)-7 b(,)36 b Fj(sizes[)p FK(2)19 b Fy(p)c +FL(\000)c FK(2)p Fj(])0 4930 y FK(stores)37 b(the)h(size)e(of)i(the)g +(top)g(le)l(v)n(el)e(separator)-7 b(,)38 b Fj(sizes[)p +FK(2)19 b Fy(p)28 b FL(\000)23 b FK(4)p Fj(])34 b FK(and)k +Fj(sizes[)p FK(2)19 b Fy(p)28 b FL(\000)23 b FK(3)p Fj(])33 +b FK(store)38 b(the)f(sizes)g(of)h(the)f(tw)n(o)h(separators)f(at)0 +5150 y(the)43 b(second)f(le)l(v)n(el)f(\(from)j(left)f(to)g(right\).)56 +b(Similarly)-11 b(,)44 b Fj(sizes[)p FK(2)19 b Fy(p)41 +b FL(\000)c FK(8)p Fj(])43 b FK(through)g Fj(sizes[)p +FK(2)19 b Fy(p)41 b FL(\000)c FK(5)p Fj(])43 b FK(store)f(the)h(sizes)f +(of)h(the)f(four)0 5369 y(separators)35 b(of)h(the)f(third)h(le)l(v)n +(el)f(\(from)i(left)f(to)f(right\),)j(and)d(so)g(on.)49 +b(This)36 b(array)g(can)f(be)g(used)g(to)h(quickly)f(construct)h(the)f +(separator)g(tree)0 5588 y(\(a)44 b(form)g(of)g(an)g(elimination)g +(tree\))g(for)g(direct)g(f)n(actorization.)58 b(Gi)l(v)n(en)43 +b(this)h(separator)f(tree)g(and)h(the)g(sizes)e(of)i(the)g +(sub-domains,)f(the)0 5807 y(nodes)e(in)g(the)g(ordering)h(produced)f +(by)g FA(P)-7 b(arMETIS)p 3081 5807 50 7 v 61 w(V3)p +3345 5807 V 60 w(NodeND)42 b FK(are)f(numbered)g(in)g(a)g(postorder)g +(f)n(ashion.)51 b(Figure)42 b(6)f(illustrates)0 6026 +y(the)g Fj(sizes)f FK(array)i(and)f(the)g(postorder)h(ordering.)0 +6481 y Ft(4.5)199 b(Numbering)54 b(and)h(Memor)r(y)f(Allocation)4 +6800 y FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)55 b FK(allo)l(ws)48 b(the)g(user)g(to)h(specify)f(a)g +(graph)g(whose)g(numbering)h(starts)f(either)g(at)g(0)h(\(C)f(style\))h +(or)f(at)h(1)f(\(F)n(ortran)h(style\).)72 b(Of)0 7019 +y(course,)62 b FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)62 b FK(requires)56 b(that)g(same)f(numbering)h +(scheme)f(be)g(used)g(consistently)g(for)i(all)f(the)f(arrays)h(passed) +e(to)i(it,)j(and)d(it)0 7238 y(writes)41 b(to)h(the)f +Fj(part)f FK(and)i Fj(order)d FK(arrays)j(similarly)-11 +b(.)203 7458 y FA(P)h FG(A)8 b(R)g FA(M)-9 b FG(E)-34 +b FA(T)g FG(I)p FA(S)46 b FK(allocates)38 b(all)h(the)g(memory)h(that)f +(it)h(requires)f(dynamically)-11 b(.)50 b(This)39 b(has)g(the)g(adv)l +(antage)f(that)h(the)h(user)e(does)h(not)g(ha)m(v)n(e)0 +7677 y(to)k(pro)n(vide)g(w)n(orkspace.)56 b(Ho)l(we)l(v)n(er)-7 +b(,)42 b(if)i(there)f(is)g(not)g(enough)g(memory)h(on)f(the)g(machine,) +g(the)g(routines)h(in)j FA(P)-10 b FG(A)8 b(R)g FA(M)-9 +b FG(E)-34 b FA(T)g FG(I)p FA(S)50 b FK(will)43 b(abort.)0 +7896 y(Note)52 b(that)g(the)g(routines)g(in)57 b FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)58 +b FK(do)52 b(not)h(modify)g(the)f(arrays)f(that)i(store)f(the)g(graph)g +(\()p Fs(e)n(.g)o FK(.,)i Fj(xadj)c FK(and)i Fj(adjncy)p +FK(\).)81 b(The)n(y)0 8115 y(only)42 b(modify)g(the)f +Fj(part)f FK(and)i Fj(order)d FK(arrays.)3817 11298 y(15)p +eop +%%Page: 16 16 +16 15 bop 0 170 a FE(5)233 b(Calling)63 b(Sequence)j(of)f(the)g +(Routines)h(in)k(P)-9 b Fu(A)12 b(R)g FE(M)-11 b Fu(E)-46 +b FE(T)g Fu(I)p FE(S)0 522 y FK(The)42 b(calling)f(sequences)f(of)i +(the)j FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)48 b FK(routines)42 b(are)f(described)g(in)g(this)h +(section.)3817 11298 y(16)p eop +%%Page: 17 17 +17 16 bop 0 166 a Ft(5.1)199 b(Graph)54 b(P)-6 b(ar)t(titioning)0 +476 y FB(P)h(arMETIS)p 780 476 50 7 v 60 w(V3)p 1043 +476 V 60 w(P)g(ar)s(tKwa)m(y)42 b FK(\(idxtype)g(*vtxdist,)f(idxtype)h +(*xadj,)f(idxtype)g(*adjnc)n(y)-11 b(,)41 b(idxtype)g(*vwgt,)g(idxtype) +h(*adjwgt,)1886 695 y(int)g(*wgt\003ag,)f(int)h(*num\003ag,)f(int)h +(*ncon,)f(int)h(*nparts,)e(\003oat)i(*tpwgts,)f(\003oat)h(*ub)n(v)n +(ec,)1886 914 y(int)g(*options,)f(int)h(*edgecut,)e(idxtype)i(*part,)f +(MPI)p 4926 914 V 60 w(Comm)h(*comm\))0 1351 y FB(Description)415 +1570 y FK(This)58 b(routine)f(is)h(used)e(to)i(compute)f(a)g +Fy(k)10 b FK(-w)n(ay)58 b(partitioning)g(of)g(a)f(graph)g(on)77 +b Fy(p)62 b FK(processors)56 b(using)i(the)f(multile)l(v)n(el)g +Fy(k)10 b FK(-w)n(ay)415 1789 y(multi-constraint)42 b(partitioning)h +(algorithm.)0 2123 y FB(P)-5 b(arameter)n(s)415 2344 +y FD(vtxdist)268 b FK(This)39 b(array)g(describes)f(ho)l(w)g(the)h(v)n +(ertices)f(of)h(the)f(graph)h(are)g(distrib)m(uted)f(among)h(the)g +(processors.)49 b(\(See)39 b(discus-)1162 2563 y(sion)j(in)f(Section)h +(4.1\).)51 b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f +(processor)-9 b(.)415 2778 y FD(xadj,)42 b(adjncy)1162 +2998 y FK(These)52 b(store)g(the)h(\(local\))f(adjacenc)n(y)f +(structure)h(of)h(the)f(graph)g(at)h(each)e(processor)-9 +b(.)83 b(\(See)52 b(discussion)f(in)i(Sec-)1162 3217 +y(tion)42 b(4.1\).)415 3426 y FD(vwgt,)f(adjwgt)1162 +3645 y FK(These)g(store)h(the)f(weights)g(of)h(the)f(v)n(ertices)g(and) +g(edges.)50 b(\(See)42 b(discussion)e(in)i(Section)f(4.1\).)415 +3912 y FD(wgt\003ag)231 b FK(This)42 b(is)f(used)g(to)h(indicate)f(if)h +(the)f(graph)h(is)f(weighted.)51 b Fs(wgt\003a)n(g)42 +b FK(can)f(tak)n(e)g(one)h(of)f(four)i(v)l(alues:)1162 +4180 y(0)166 b(No)42 b(weights)f(\(vwgt)h(and)f(adjwgt)h(are)f(both)g +(NULL\).)1162 4423 y(1)166 b(W)-13 b(eights)41 b(on)h(the)f(edges)g +(only)g(\(vwgt)h(is)f(NULL\).)1162 4666 y(2)166 b(W)-13 +b(eights)41 b(on)h(the)f(v)n(ertices)f(only)i(\(adjwgt)g(is)f(NULL\).) +1162 4910 y(3)166 b(W)-13 b(eights)41 b(on)h(both)f(the)h(v)n(ertices)e +(and)h(edges.)415 5177 y FD(num\003ag)167 b FK(This)58 +b(is)f(used)g(to)h(indicate)f(the)g(numbering)h(scheme)e(that)i(is)f +(used)g(for)h(the)f Fs(vtxdist)p FK(,)k Fs(xadj)p FK(,)f +Fs(adjncy)p FK(,)h(and)c Fs(part)1162 5397 y FK(arrays.)51 +b Fs(num\003a)n(g)42 b FK(can)f(tak)n(e)g(one)h(of)f(tw)n(o)h(v)l +(alues:)1162 5664 y(0)166 b(C-style)42 b(numbering)g(that)f(starts)g +(from)h(0.)1162 5907 y(1)166 b(F)n(ortran-style)42 b(numbering)g(that)g +(starts)f(from)h(1.)415 6175 y FD(ncon)406 b FK(This)47 +b(is)e(used)h(to)g(specify)f(the)h(number)g(of)h(weights)e(that)h(each) +f(v)n(erte)n(x)g(has.)64 b(It)46 b(is)g(also)g(the)f(number)i(of)f +(balance)1162 6394 y(constraints)41 b(that)h(must)f(be)h(satis\002ed.) +415 6662 y FD(nparts)286 b FK(This)54 b(is)f(used)g(to)h(specify)f(the) +g(number)h(of)f(sub-domains)g(that)h(are)f(desired.)87 +b(Note)53 b(that)g(the)h(number)f(of)h(sub-)1162 6881 +y(domains)42 b(is)f(independent)g(of)h(the)f(number)h(of)g(processors)e +(that)i(call)f(this)g(routine.)415 7148 y FD(tpwgts)277 +b FK(An)52 b(array)g(of)g(size)f Fj(ncon)g FK(x)h Fj(nparts)d +FK(that)j(is)g(used)f(to)h(specify)f(the)h(fraction)g(of)h(v)n(erte)n +(x)d(weight)i(that)g(should)1162 7367 y(be)44 b(distrib)m(uted)g(to)g +(each)f(sub-domain)h(for)h(each)e(balance)g(constraint.)58 +b(If)45 b(all)f(of)g(the)g(sub-domains)f(are)h(to)g(be)g(of)1162 +7587 y(the)e(same)e(size)h(for)h(e)l(v)n(ery)f(v)n(erte)n(x)f(weight,)h +(then)h(each)e(of)i(the)g Fj(ncon)e FK(x)h Fj(nparts)e +FK(elements)i(should)g(be)h(set)f(to)g(a)1162 7806 y(v)l(alue)c(of)g +(1/)p Fj(nparts)p FK(.)47 b(If)38 b Fj(ncon)d FK(is)i(greater)f(than)h +(one,)g(the)g(tar)m(get)g(sub-domain)g(weights)f(for)i(each)e +(sub-domain)1162 8025 y(are)50 b(stored)g(contiguously)f(\(similar)i +(to)f(the)g Fj(vwgt)e FK(array\).)76 b(Note)50 b(that)g(the)g(sum)f(of) +h(all)g(of)g(the)g Fj(tpwgts)e FK(for)i(a)1162 8244 y(gi)l(v)n(e)41 +b(v)n(erte)n(x)g(weight)g(should)g(be)h(one.)415 8512 +y FD(ub)n(v)n(ec)336 b FK(An)42 b(array)g(of)g(size)f +Fj(ncon)f FK(that)i(is)g(used)f(to)h(specify)f(the)h(imbalance)f +(tolerance)g(for)i(each)e(v)n(erte)n(x)g(weight,)g(with)h(1)1162 +8731 y(being)47 b(perfect)g(balance)e(and)i Fj(nparts)d +FK(being)j(perfect)g(imbalance.)66 b(A)46 b(v)l(alue)g(of)h(1.05)g(for) +g(each)f(of)h(the)f Fj(ncon)1162 8950 y FK(weights)41 +b(is)h(recommended.)415 9217 y FD(options)231 b FK(This)38 +b(is)e(an)h(array)h(of)f(inte)n(gers)f(that)h(is)g(used)g(to)g(pass)f +(additional)h(parameters)g(for)h(the)f(routine.)49 b(If)38 +b Fs(options[0]=0)p FK(,)1162 9437 y(then)54 b(the)f(def)n(ault)i(v)l +(alues)d(are)i(used.)87 b(If)54 b Fs(options[0]=1)p FK(,)h(then)f(the)g +(remaining)g(tw)n(o)g(elements)f(of)h Fs(options)f FK(are)1162 +9656 y(interpreted)42 b(as)f(follo)l(ws:)1162 9923 y(options[1])222 +b(This)45 b(speci\002es)f(the)h(le)l(v)n(el)f(of)h(information)g(to)g +(be)g(returned)g(during)g(the)g(e)n(x)n(ecution)e(of)i(the)g(algo-)2066 +10142 y(rithm.)61 b(T)-6 b(iming)46 b(information)f(can)f(be)h +(obtained)f(by)h(setting)f(this)g(to)h(1.)60 b(Additional)45 +b(options)f(for)2066 10362 y(this)i(parameter)f(can)f(be)h(obtained)g +(by)h(looking)f(at)g(the)g(the)g(\002le)h Fj(defs.h)d +FK(in)i(the)g Fj(ParMETIS-)2066 10581 y(Lib)39 b FK(directory)-11 +b(.)51 b(The)40 b(numerical)g(v)l(alues)f(there)h(should)f(be)h(added)f +(to)h(obtain)g(the)g(correct)g(v)l(alue.)2066 10800 y(The)i(def)n(ault) +g(v)l(alue)f(is)g(0.)3817 11298 y(17)p eop +%%Page: 18 18 +18 17 bop 1162 166 a FK(options[2])222 b(This)42 b(is)f(the)h(random)g +(number)f(seed)g(for)h(the)f(routine.)52 b(The)42 b(def)n(ault)f(v)l +(alue)h(is)f(15.)415 452 y FD(edgecut)203 b FK(Upon)51 +b(successful)f(completion,)k(the)d(number)g(of)h(edges)e(that)h(are)g +(cut)g(by)h(the)f(partitioning)h(is)f(written)h(to)f(this)1162 +671 y(parameter)-9 b(.)415 956 y FD(part)443 b FK(This)33 +b(is)f(an)f(array)i(of)f(size)f(equal)h(to)g(the)g(number)h(of)f +(locally-stored)g(v)n(ertices.)47 b(Upon)32 b(successful)f(completion)h +(the)1162 1176 y(partition)43 b(v)n(ector)d(of)i(the)g(locally-stored)f +(v)n(ertices)g(is)g(written)h(to)g(this)f(array)-11 b(.)51 +b(\(See)42 b(discussion)e(in)i(Section)g(4.4\).)415 1461 +y FD(comm)314 b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g +(communicator)h(of)f(the)g(processes)e(that)i(call)k +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)t FK(.)46 b(F)n(or)e(most)g(programs)1162 1680 y(this)e(will)g +(point)g(to)f Fj(MPI)p 2607 1680 50 7 v 59 w(COMM)p 3066 +1680 V 58 w(WORLD)p FK(.)3817 11298 y(18)p eop +%%Page: 19 19 +19 18 bop 0 166 a FB(P)-5 b(arMETIS)p 780 166 50 7 v +60 w(V3)p 1043 166 V 60 w(P)g(ar)s(tGeomKwa)m(y)42 b +FK(\(idxtype)g(*vtxdist,)g(idxtype)f(*xadj,)g(idxtype)h(*adjnc)n(y)-11 +b(,)40 b(idxtype)i(*vwgt,)f(idxtype)h(*adjwgt,)2356 385 +y(int)g(*wgt\003ag,)f(int)h(*num\003ag,)g(int)g(*ndims,)f(\003oat)g +(*xyz,)g(int)h(*ncon,)f(int)h(*nparts,)2356 604 y(\003oat)g(*tpwgts,)f +(\003oat)h(*ub)n(v)n(ec,)d(int)j(*options,)f(int)h(*edgecut,)f(idxtype) +g(*part,)2356 824 y(MPI)p 2661 824 V 60 w(Comm)h(*comm\))0 +1342 y FB(Description)415 1561 y FK(This)47 b(routine)g(is)g(used)f(to) +h(compute)f(a)h Fy(k)10 b FK(-w)n(ay)46 b(partitioning)i(of)f(a)f +(graph)h(on)66 b Fy(p)52 b FK(processors)45 b(by)i(combining)g(the)g +(coordinate-)415 1780 y(based)41 b(and)g(multi-constraint)h +Fy(k)10 b FK(-w)n(ay)42 b(partitioning)g(schemes.)0 2132 +y FB(P)-5 b(arameter)n(s)415 2371 y FD(vtxdist)268 b +FK(This)39 b(array)g(describes)f(ho)l(w)g(the)h(v)n(ertices)f(of)h(the) +f(graph)h(are)g(distrib)m(uted)f(among)h(the)g(processors.)49 +b(\(See)39 b(discus-)1162 2590 y(sion)j(in)f(Section)h(4.1\).)51 +b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f(processor) +-9 b(.)415 2824 y FD(xadj,)42 b(adjncy)1162 3043 y FK(These)52 +b(store)g(the)h(\(local\))f(adjacenc)n(y)f(structure)h(of)h(the)f +(graph)g(at)h(each)e(processor)-9 b(.)83 b(\(See)52 b(discussion)f(in)i +(Sec-)1162 3262 y(tion)42 b(4.1\).)415 3489 y FD(vwgt,)f(adjwgt)1162 +3708 y FK(These)g(store)h(the)f(weights)g(of)h(the)f(v)n(ertices)g(and) +g(edges.)50 b(\(See)42 b(discussion)e(in)i(Section)f(4.1\).)415 +3994 y FD(wgt\003ag)231 b FK(This)42 b(is)f(used)g(to)h(indicate)f(if)h +(the)f(graph)h(is)f(weighted.)51 b Fs(wgt\003a)n(g)42 +b FK(can)f(tak)n(e)g(one)h(of)f(four)i(v)l(alues:)1162 +4279 y(0)166 b(No)42 b(weights)f(\(vwgt)h(and)f(adjwgt)h(are)f(both)g +(NULL\).)1162 4532 y(1)166 b(W)-13 b(eights)41 b(on)h(the)f(edges)g +(only)g(\(vwgt)h(is)f(NULL\).)1162 4784 y(2)166 b(W)-13 +b(eights)41 b(on)h(the)f(v)n(ertices)f(only)i(\(adjwgt)g(is)f(NULL\).) +1162 5036 y(3)166 b(W)-13 b(eights)41 b(on)h(both)f(the)h(v)n(ertices)e +(and)h(edges.)415 5322 y FD(num\003ag)167 b FK(This)58 +b(is)f(used)g(to)h(indicate)f(the)g(numbering)h(scheme)e(that)i(is)f +(used)g(for)h(the)f Fs(vtxdist)p FK(,)k Fs(xadj)p FK(,)f +Fs(adjncy)p FK(,)h(and)c Fs(part)1162 5541 y FK(arrays.)51 +b Fs(num\003a)n(g)42 b FK(can)f(tak)n(e)g(one)h(of)f(tw)n(o)h(v)l +(alues:)1162 5827 y(0)166 b(C-style)42 b(numbering)g(that)f(starts)g +(from)h(0.)1162 6079 y(1)166 b(F)n(ortran-style)42 b(numbering)g(that)g +(starts)f(from)h(1.)415 6365 y FD(ndims)314 b FK(The)42 +b(number)g(of)g(dimensions)f(of)g(the)h(space)e(in)i(which)f(the)h +(graph)f(is)g(embedded.)415 6650 y FD(xyz)507 b FK(The)42 +b(array)g(storing)f(the)h(coordinates)f(of)h(the)f(v)n(ertices)f +(\(described)h(in)h(Section)g(4.2\).)415 6936 y FD(ncon)406 +b FK(This)47 b(is)e(used)h(to)g(specify)f(the)h(number)g(of)h(weights)e +(that)h(each)f(v)n(erte)n(x)g(has.)64 b(It)46 b(is)g(also)g(the)f +(number)i(of)f(balance)1162 7155 y(constraints)41 b(that)h(must)f(be)h +(satis\002ed.)415 7441 y FD(nparts)286 b FK(This)54 b(is)f(used)g(to)h +(specify)f(the)g(number)h(of)f(sub-domains)g(that)h(are)f(desired.)87 +b(Note)53 b(that)g(the)h(number)f(of)h(sub-)1162 7660 +y(domains)42 b(is)f(independent)g(of)h(the)f(number)h(of)g(processors)e +(that)i(call)f(this)g(routine.)415 7946 y FD(tpwgts)277 +b FK(An)52 b(array)g(of)g(size)f Fj(ncon)g FK(x)h Fj(nparts)d +FK(that)j(is)g(used)f(to)h(specify)f(the)h(fraction)g(of)h(v)n(erte)n +(x)d(weight)i(that)g(should)1162 8165 y(be)44 b(distrib)m(uted)g(to)g +(each)f(sub-domain)h(for)h(each)e(balance)g(constraint.)58 +b(If)45 b(all)f(of)g(the)g(sub-domains)f(are)h(to)g(be)g(of)1162 +8384 y(the)e(same)e(size)h(for)h(e)l(v)n(ery)f(v)n(erte)n(x)f(weight,)h +(then)h(each)e(of)i(the)g Fj(ncon)e FK(x)h Fj(nparts)e +FK(elements)i(should)g(be)h(set)f(to)g(a)1162 8603 y(v)l(alue)c(of)g +(1/)p Fj(nparts)p FK(.)47 b(If)38 b Fj(ncon)d FK(is)i(greater)f(than)h +(one,)g(the)g(tar)m(get)g(sub-domain)g(weights)f(for)i(each)e +(sub-domain)1162 8822 y(are)50 b(stored)g(contiguously)f(\(similar)i +(to)f(the)g Fj(vwgt)e FK(array\).)76 b(Note)50 b(that)g(the)g(sum)f(of) +h(all)g(of)g(the)g Fj(tpwgts)e FK(for)i(a)1162 9041 y(gi)l(v)n(e)41 +b(v)n(erte)n(x)g(weight)g(should)g(be)h(one.)415 9327 +y FD(ub)n(v)n(ec)336 b FK(An)42 b(array)g(of)g(size)f +Fj(ncon)f FK(that)i(is)g(used)f(to)h(specify)f(the)h(imbalance)f +(tolerance)g(for)i(each)e(v)n(erte)n(x)g(weight,)g(with)h(1)1162 +9546 y(being)47 b(perfect)g(balance)e(and)i Fj(nparts)d +FK(being)j(perfect)g(imbalance.)66 b(A)46 b(v)l(alue)g(of)h(1.05)g(for) +g(each)f(of)h(the)f Fj(ncon)1162 9765 y FK(weights)41 +b(is)h(recommended.)415 10051 y FD(options)231 b FK(This)36 +b(is)f(an)g(array)g(of)h(inte)n(gers)f(that)g(is)g(used)g(to)g(pass)g +(parameters)f(to)i(the)f(routine.)49 b(Their)36 b(meanings)f(are)g +(identical)1162 10270 y(to)42 b(those)f(of)h FA(P)-7 +b(arMETIS)p 2673 10270 V 61 w(V3)p 2937 10270 V 60 w(P)g(ar)7 +b(tKw)n(a)-5 b(y)p FK(.)415 10556 y FD(edgecut)203 b +FK(Upon)51 b(successful)f(completion,)k(the)d(number)g(of)h(edges)e +(that)h(are)g(cut)g(by)h(the)f(partitioning)h(is)f(written)h(to)f(this) +1162 10775 y(parameter)-9 b(.)3817 11298 y(19)p eop +%%Page: 20 20 +20 19 bop 415 166 a FD(part)443 b FK(This)33 b(is)f(an)f(array)i(of)f +(size)f(equal)h(to)g(the)g(number)h(of)f(locally-stored)g(v)n(ertices.) +47 b(Upon)32 b(successful)f(completion)h(the)1162 385 +y(partition)43 b(v)n(ector)d(of)i(the)g(locally-stored)f(v)n(ertices)g +(is)g(written)h(to)g(this)f(array)-11 b(.)51 b(\(See)42 +b(discussion)e(in)i(Section)g(4.4\).)415 671 y FD(comm)314 +b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g(communicator)h(of)f +(the)g(processes)e(that)i(call)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)46 b(F)n(or)e(most)g +(programs)1162 890 y(this)e(will)g(point)g(to)f Fj(MPI)p +2607 890 50 7 v 59 w(COMM)p 3066 890 V 58 w(WORLD)p FK(.)0 +1242 y FB(Note)415 1461 y FK(The)58 b(quality)g(of)g(the)g +(partitionings)g(computed)g(by)g FA(P)-7 b(arMETIS)p +4309 1461 V 61 w(V3)p 4573 1461 V 59 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)59 b FK(are)f(comparable)f(to)h(those)f(pro-)415 +1680 y(duced)41 b(by)h FA(P)-7 b(arMETIS)p 1829 1680 +V 61 w(V3)p 2093 1680 V 59 w(P)g(ar)7 b(tKw)n(a)-5 b(y)p +FK(.)51 b(Ho)l(we)l(v)n(er)-7 b(,)41 b(the)g(run)h(time)g(of)f(the)h +(routine)g(may)f(be)g(up)h(to)g(twice)f(as)g(f)n(ast.)3817 +11298 y(20)p eop +%%Page: 21 21 +21 20 bop 0 166 a FB(P)-5 b(arMETIS)p 780 166 50 7 v +60 w(V3)p 1043 166 V 60 w(P)g(ar)s(tGeom)42 b FK(\(idxtype)g(*vtxdist,) +f(int)h(*ndims,)f(\003oat)h(*xyz,)f(idxtype)g(*part,)g(MPI)p +5939 166 V 60 w(Comm)h(*comm\))0 684 y FB(Description)415 +903 y FK(This)64 b(routine)g(is)g(used)f(to)h(compute)g(a)82 +b Fy(p)5 b FK(-w)n(ay)65 b(partitioning)f(of)h(a)e(graph)h(on)83 +b Fy(p)69 b FK(processors)63 b(using)g(a)h(coordinate-based)415 +1122 y(space-\002lling)42 b(curv)n(es)e(method.)0 1474 +y FB(P)-5 b(arameter)n(s)415 1714 y FD(vtxdist)268 b +FK(This)39 b(array)g(describes)f(ho)l(w)g(the)h(v)n(ertices)f(of)h(the) +f(graph)h(are)g(distrib)m(uted)f(among)h(the)g(processors.)49 +b(\(See)39 b(discus-)1162 1933 y(sion)j(in)f(Section)h(4.1\).)51 +b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f(processor) +-9 b(.)415 2218 y FD(ndims)314 b FK(The)42 b(number)g(of)g(dimensions)f +(of)g(the)h(space)e(in)i(which)f(the)h(graph)f(is)g(embedded.)415 +2504 y FD(xyz)507 b FK(The)42 b(array)g(storing)f(the)h(coordinates)f +(of)h(the)f(v)n(ertices)f(\(described)h(in)h(Section)g(4.2\).)415 +2790 y FD(part)443 b FK(This)48 b(is)g(an)g(array)g(of)g(size)f(equal)g +(to)h(the)g(number)g(of)g(locally)g(stored)g(v)n(ertices.)69 +b(Upon)48 b(successful)e(completion)1162 3009 y(stores)41 +b(the)h(partition)g(v)n(ector)f(of)h(the)f(locally)h(stored)f(graph)g +(\(described)g(in)h(Section)g(4.4\).)415 3294 y FD(comm)314 +b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g(communicator)h(of)f +(the)g(processes)e(that)i(call)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)46 b(F)n(or)e(most)g +(programs)1162 3514 y(this)e(will)g(point)g(to)f Fj(MPI)p +2607 3514 V 59 w(COMM)p 3066 3514 V 58 w(WORLD)p FK(.)0 +3866 y FB(Note)415 4085 y FK(The)64 b(quality)h(of)f(the)h +(partitionings)f(computed)g(by)h FA(P)-7 b(arMETIS)p +4354 4085 V 60 w(V3)p 4617 4085 V 60 w(P)g(ar)7 b(tGeom)66 +b FK(are)e(signi\002cantly)g(w)n(orse)g(than)g(those)415 +4304 y(produced)41 b(by)h FA(P)-7 b(arMETIS)p 2050 4304 +V 61 w(V3)p 2314 4304 V 60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)41 +b FK(and)h FA(P)-7 b(arMETIS)p 4158 4304 V 61 w(V3)p +4422 4304 V 59 w(P)g(ar)7 b(tGeomKw)n(a)-5 b(y)p FK(.)3817 +11298 y(21)p eop +%%Page: 22 22 +22 21 bop 0 166 a FB(P)-5 b(arMETIS)p 780 166 50 7 v +60 w(V3)p 1043 166 V 60 w(P)g(ar)s(tMeshKwa)m(y)43 b +FK(\(idxtype)f(*elmdist,)f(idxtype)h(*eptr)-7 b(,)42 +b(idxtype)f(*eind,)g(idxtype)h(*elmwgt,)2310 385 y(int)g(*wgt\003ag,)f +(int)h(*num\003ag,)g(int)f(*ncon,)g(int)h(*ncommonnodes,)f(int)g +(*nparts,)2310 604 y(\003oat)h(*tpwgts,)f(\003oat)h(*ub)n(v)n(ec,)d +(int)j(*options,)f(int)h(*edgecut,)e(idxtype)i(*part,)2310 +824 y(MPI)p 2615 824 V 60 w(Comm)g(*comm\))0 1342 y FB(Description)415 +1561 y FK(This)d(routine)h(is)f(used)f(to)h(compute)g(a)g +Fy(k)10 b FK(-w)n(ay)39 b(partitioning)h(of)f(a)g Fs(mesh)f +FK(on)58 b Fy(p)45 b FK(processors.)k(The)39 b(mesh)f(can)h(contain)g +(elements)415 1780 y(of)j(dif)l(ferent)g(types.)0 2132 +y FB(P)-5 b(arameter)n(s)415 2371 y FD(elmdist)231 b +FK(This)47 b(array)g(describes)e(ho)l(w)i(the)f(elements)g(of)h(the)f +(mesh)h(are)f(distrib)m(uted)g(among)h(the)g(processors.)65 +b(It)47 b(is)f(anal-)1162 2590 y(ogous)64 b(to)g(the)g +Fj(vtxdist)d FK(array)-11 b(.)119 b(Its)64 b(contents)f(are)h +(identical)g(for)g(e)l(v)n(ery)f(processor)-9 b(.)118 +b(\(See)64 b(discussion)f(in)1162 2809 y(Section)42 b(4.3\).)415 +3036 y FD(eptr)-15 b(,)41 b(eind)1162 3256 y FK(These)64 +b(arrays)g(speci\002es)f(the)g(elements)h(that)g(are)g(stored)g +(locally)g(at)g(each)f(processor)-9 b(.)118 b(\(See)64 +b(discussion)f(in)1162 3475 y(Section)42 b(4.3\).)415 +3760 y FD(elmwgt)231 b FK(This)42 b(array)g(stores)e(the)i(weights)f +(of)h(the)f(elements.)50 b(\(See)42 b(discussion)e(in)i(Section)g +(4.3\).)415 4046 y FD(wgt\003ag)231 b FK(This)42 b(is)f(used)g(to)h +(indicate)f(if)h(the)f(graph)h(is)f(weighted.)51 b Fs(wgt\003a)n(g)42 +b FK(can)f(tak)n(e)g(one)h(of)f(four)i(v)l(alues:)1162 +4332 y(0)166 b(No)42 b(weights)f(\(vwgt)h(and)f(adjwgt)h(are)f(both)g +(NULL\).)1162 4584 y(1)166 b(W)-13 b(eights)41 b(on)h(the)f(edges)g +(only)g(\(vwgt)h(is)f(NULL\).)1162 4836 y(2)166 b(W)-13 +b(eights)41 b(on)h(the)f(v)n(ertices)f(only)i(\(adjwgt)g(is)f(NULL\).) +1162 5089 y(3)166 b(W)-13 b(eights)41 b(on)h(both)f(the)h(v)n(ertices)e +(and)h(edges.)415 5374 y FD(num\003ag)167 b FK(This)41 +b(is)f(used)f(to)i(indicate)f(the)g(numbering)g(scheme)g(that)g(is)g +(used)f(for)i(the)f Fs(elmdist)p FK(,)g Fs(elements)p +FK(,)f(and)h Fs(part)g FK(arrays.)1162 5593 y Fs(num\003a)n(g)i +FK(can)f(tak)n(e)h(one)f(of)h(tw)n(o)g(v)l(alues:)1162 +5879 y(0)166 b(C-style)42 b(numbering)g(that)f(starts)g(from)h(0.)1162 +6131 y(1)166 b(F)n(ortran-style)42 b(numbering)g(that)g(starts)f(from)h +(1.)415 6417 y FD(ncon)406 b FK(This)47 b(is)e(used)h(to)g(specify)f +(the)h(number)g(of)h(weights)e(that)h(each)f(v)n(erte)n(x)g(has.)64 +b(It)46 b(is)g(also)g(the)f(number)i(of)f(balance)1162 +6636 y(constraints)41 b(that)h(must)f(be)h(satis\002ed.)415 +6833 y FD(ncommonnodes)1162 7052 y FK(This)i(parameter)g(determines)g +(the)f(de)n(gree)g(of)i(connecti)l(vity)e(among)h(the)g(v)n(ertices)f +(in)h(the)f(dual)h(graph.)58 b(Speci\002-)1162 7271 y(cally)-11 +b(,)43 b(an)f(edge)g(is)h(placed)f(between)g(an)n(y)f(tw)n(o)j +(elements)d(if)j(and)e(only)h(if)g(the)n(y)f(share)g(at)g(least)g(this) +h(man)n(y)f(nodes.)1162 7490 y(This)53 b(v)l(alue)e(should)h(be)g +(greater)g(than)g(zero,)i(and)e(for)h(most)f(meshes)f(a)h(v)l(alue)f +(of)i(tw)n(o)f(will)h(create)e(reasonable)1162 7710 y(dual)45 +b(graphs.)61 b(Ho)l(we)l(v)n(er)-7 b(,)44 b(depending)g(on)h(the)g +(type)g(of)g(elements)f(in)h(the)g(mesh,)f(v)l(alues)g(greater)h(than)g +(tw)n(o)g(may)1162 7929 y(also)50 b(be)g(v)l(alid)g(choices.)77 +b(F)n(or)50 b(e)n(xample,)h(for)g(meshes)f(containing)g(only)h +(triangular)-7 b(,)53 b(tetrahedral,)f(he)n(xahedral,)1162 +8148 y(or)42 b(rectangular)g(elements,)e(this)h(parameter)h(can)f(be)g +(set)g(to)g(tw)n(o,)h(three,)f(four)-7 b(,)42 b(or)g(tw)n(o,)f +(respecti)l(v)n(ely)-11 b(.)1162 8400 y(Note)51 b(that)f(setting)h +(this)f(parameter)g(to)h(a)f(small)h(v)l(alue)f(will)h(increase)e(the)h +(number)h(of)g(edges)f(in)g(the)h(resulting)1162 8620 +y(dual)42 b(graph)f(and)h(the)f(corresponding)g(partitioning)i(time.) +415 8905 y FD(nparts)286 b FK(This)54 b(is)f(used)g(to)h(specify)f(the) +g(number)h(of)f(sub-domains)g(that)h(are)f(desired.)87 +b(Note)53 b(that)g(the)h(number)f(of)h(sub-)1162 9124 +y(domains)42 b(is)f(independent)g(of)h(the)f(number)h(of)g(processors)e +(that)i(call)f(this)g(routine.)415 9410 y FD(tpwgts)277 +b FK(An)52 b(array)g(of)g(size)f Fj(ncon)g FK(x)h Fj(nparts)d +FK(that)j(is)g(used)f(to)h(specify)f(the)h(fraction)g(of)h(v)n(erte)n +(x)d(weight)i(that)g(should)1162 9629 y(be)44 b(distrib)m(uted)g(to)g +(each)f(sub-domain)h(for)h(each)e(balance)g(constraint.)58 +b(If)45 b(all)f(of)g(the)g(sub-domains)f(are)h(to)g(be)g(of)1162 +9848 y(the)e(same)e(size)h(for)h(e)l(v)n(ery)f(v)n(erte)n(x)f(weight,)h +(then)h(each)e(of)i(the)g Fj(ncon)e FK(x)h Fj(nparts)e +FK(elements)i(should)g(be)h(set)f(to)g(a)1162 10067 y(v)l(alue)c(of)g +(1/)p Fj(nparts)p FK(.)47 b(If)38 b Fj(ncon)d FK(is)i(greater)f(than)h +(one,)g(the)g(tar)m(get)g(sub-domain)g(weights)f(for)i(each)e +(sub-domain)1162 10287 y(are)50 b(stored)g(contiguously)f(\(similar)i +(to)f(the)g Fj(vwgt)e FK(array\).)76 b(Note)50 b(that)g(the)g(sum)f(of) +h(all)g(of)g(the)g Fj(tpwgts)e FK(for)i(a)1162 10506 +y(gi)l(v)n(e)41 b(v)n(erte)n(x)g(weight)g(should)g(be)h(one.)3817 +11298 y(22)p eop +%%Page: 23 23 +23 22 bop 415 166 a FD(ub)n(v)n(ec)336 b FK(An)42 b(array)g(of)g(size)f +Fj(ncon)f FK(that)i(is)g(used)f(to)h(specify)f(the)h(imbalance)f +(tolerance)g(for)i(each)e(v)n(erte)n(x)g(weight,)g(with)h(1)1162 +385 y(being)47 b(perfect)g(balance)e(and)i Fj(nparts)d +FK(being)j(perfect)g(imbalance.)66 b(A)46 b(v)l(alue)g(of)h(1.05)g(for) +g(each)f(of)h(the)f Fj(ncon)1162 604 y FK(weights)41 +b(is)h(recommended.)415 890 y FD(options)231 b FK(This)36 +b(is)f(an)g(array)g(of)h(inte)n(gers)f(that)g(is)g(used)g(to)g(pass)g +(parameters)f(to)i(the)f(routine.)49 b(Their)36 b(meanings)f(are)g +(identical)1162 1109 y(to)42 b(those)f(of)h FA(P)-7 b(arMETIS)p +2673 1109 50 7 v 61 w(V3)p 2937 1109 V 60 w(P)g(ar)7 +b(tKw)n(a)-5 b(y)p FK(.)415 1395 y FD(edgecut)203 b FK(Upon)51 +b(successful)f(completion,)k(the)d(number)g(of)h(edges)e(that)h(are)g +(cut)g(by)h(the)f(partitioning)h(is)f(written)h(to)f(this)1162 +1614 y(parameter)-9 b(.)415 1900 y FD(part)443 b FK(This)33 +b(is)f(an)f(array)i(of)f(size)f(equal)h(to)g(the)g(number)h(of)f +(locally-stored)g(v)n(ertices.)47 b(Upon)32 b(successful)f(completion)h +(the)1162 2119 y(partition)43 b(v)n(ector)d(of)i(the)g(locally-stored)f +(v)n(ertices)g(is)g(written)h(to)g(this)f(array)-11 b(.)51 +b(\(See)42 b(discussion)e(in)i(Section)g(4.4\).)415 2404 +y FD(comm)314 b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g +(communicator)h(of)f(the)g(processes)e(that)i(call)k +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)t FK(.)46 b(F)n(or)e(most)g(programs)1162 2624 y(this)e(will)g +(point)g(to)f Fj(MPI)p 2607 2624 V 59 w(COMM)p 3066 2624 +V 58 w(WORLD)p FK(.)3817 11298 y(23)p eop +%%Page: 24 24 +24 23 bop 0 166 a Ft(5.2)199 b(Graph)54 b(Repar)t(titioning)0 +476 y FB(P)-5 b(arMETIS)p 780 476 50 7 v 60 w(V3)p 1043 +476 V 60 w(AdaptiveRepar)s(t)45 b FK(\(idxtype)d(*vtxdist,)f(idxtype)g +(*xadj,)g(idxtype)h(*adjnc)n(y)-11 b(,)40 b(idxtype)i(*vwgt,)f(idxtype) +h(*vsize,)2365 695 y(idxtype)f(*adjwgt,)g(int)h(*wgt\003ag,)f(int)h +(*num\003ag,)f(int)h(*ncon,)f(int)h(*nparts,)f(\003oat)h(*tpwgts,)2365 +914 y(\003oat)f(*ub)n(v)n(ec,)f(\003oat)i(*itr)-7 b(,)42 +b(int)g(*options,)f(int)g(*edgecut,)g(idxtype)g(*part,)2365 +1133 y(MPI)p 2670 1133 V 60 w(Comm)g(*comm\))0 1570 y +FB(Description)415 1789 y FK(This)h(routine)g(is)f(used)g(to)h(balance) +e(the)i(w)n(ork)g(load)f(of)h(a)f(graph)h(that)f(corresponds)g(to)h(an) +f(adapti)l(v)n(ely)g(re\002ned)g(mesh.)0 2123 y FB(P)-5 +b(arameter)n(s)415 2344 y FD(vtxdist)268 b FK(This)39 +b(array)g(describes)f(ho)l(w)g(the)h(v)n(ertices)f(of)h(the)f(graph)h +(are)g(distrib)m(uted)f(among)h(the)g(processors.)49 +b(\(See)39 b(discus-)1162 2563 y(sion)j(in)f(Section)h(4.1\).)51 +b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f(processor) +-9 b(.)415 2778 y FD(xadj,)42 b(adjncy)1162 2998 y FK(These)52 +b(store)g(the)h(\(local\))f(adjacenc)n(y)f(structure)h(of)h(the)f +(graph)g(at)h(each)e(processor)-9 b(.)83 b(\(See)52 b(discussion)f(in)i +(Sec-)1162 3217 y(tion)42 b(4.1\).)415 3426 y FD(vwgt,)f(adjwgt)1162 +3645 y FK(These)g(store)h(the)f(weights)g(of)h(the)f(v)n(ertices)g(and) +g(edges.)50 b(\(See)42 b(discussion)e(in)i(Section)f(4.1\).)415 +3912 y FD(vsize)405 b FK(This)46 b(array)f(stores)g(the)g(size)f(of)i +(the)f(v)n(ertices)f(with)i(respect)e(to)i(redistrib)m(ution)g(costs.) +61 b(Hence,)45 b(v)n(ertices)f(associ-)1162 4131 y(ated)j(with)g(mesh)g +(elements)f(that)h(require)h(a)e(lot)i(of)f(memory)h(will)f(ha)m(v)n(e) +f(lar)m(ger)h(corresponding)g(entries)g(in)g(this)1162 +4351 y(array)-11 b(.)52 b(Otherwise,)40 b(this)h(array)h(is)f(similar)h +(to)g(the)f Fj(vwgt)f FK(array)-11 b(.)51 b(\(See)42 +b(discussion)e(in)i(Section)g(4.1\).)415 4618 y FD(wgt\003ag)231 +b FK(This)42 b(is)f(used)g(to)h(indicate)f(if)h(the)f(graph)h(is)f +(weighted.)51 b Fs(wgt\003a)n(g)42 b FK(can)f(tak)n(e)g(one)h(of)f +(four)i(v)l(alues:)1162 4886 y(0)166 b(No)42 b(weights)f(\(vwgt)h(and)f +(adjwgt)h(are)f(both)g(NULL\).)1162 5129 y(1)166 b(W)-13 +b(eights)41 b(on)h(the)f(edges)g(only)g(\(vwgt)h(is)f(NULL\).)1162 +5372 y(2)166 b(W)-13 b(eights)41 b(on)h(the)f(v)n(ertices)f(only)i +(\(adjwgt)g(is)f(NULL\).)1162 5616 y(3)166 b(W)-13 b(eights)41 +b(on)h(both)f(the)h(v)n(ertices)e(and)h(edges.)415 5883 +y FD(num\003ag)167 b FK(This)58 b(is)f(used)g(to)h(indicate)f(the)g +(numbering)h(scheme)e(that)i(is)f(used)g(for)h(the)f +Fs(vtxdist)p FK(,)k Fs(xadj)p FK(,)f Fs(adjncy)p FK(,)h(and)c +Fs(part)1162 6102 y FK(arrays.)51 b Fs(num\003a)n(g)42 +b FK(can)f(tak)n(e)g(the)h(follo)l(wing)g(tw)n(o)g(v)l(alues:)1162 +6370 y(0)166 b(C-style)42 b(numbering)g(is)f(assumed)f(that)i(starts)f +(from)h(0)1162 6613 y(1)166 b(F)n(ortran-style)42 b(numbering)g(is)f +(assumed)g(that)g(starts)g(from)i(1)415 6881 y FD(ncon)406 +b FK(This)47 b(is)e(used)h(to)g(specify)f(the)h(number)g(of)h(weights)e +(that)h(each)f(v)n(erte)n(x)g(has.)64 b(It)46 b(is)g(also)g(the)f +(number)i(of)f(balance)1162 7100 y(constraints)41 b(that)h(must)f(be)h +(satis\002ed.)415 7367 y FD(nparts)286 b FK(This)54 b(is)f(used)g(to)h +(specify)f(the)g(number)h(of)f(sub-domains)g(that)h(are)f(desired.)87 +b(Note)53 b(that)g(the)h(number)f(of)h(sub-)1162 7587 +y(domains)42 b(is)f(independent)g(of)h(the)f(number)h(of)g(processors)e +(that)i(call)f(this)g(routine.)415 7854 y FD(tpwgts)277 +b FK(An)52 b(array)g(of)g(size)f Fj(ncon)g FK(x)h Fj(nparts)d +FK(that)j(is)g(used)f(to)h(specify)f(the)h(fraction)g(of)h(v)n(erte)n +(x)d(weight)i(that)g(should)1162 8073 y(be)44 b(distrib)m(uted)g(to)g +(each)f(sub-domain)h(for)h(each)e(balance)g(constraint.)58 +b(If)45 b(all)f(of)g(the)g(sub-domains)f(are)h(to)g(be)g(of)1162 +8292 y(the)e(same)e(size)h(for)h(e)l(v)n(ery)f(v)n(erte)n(x)f(weight,)h +(then)h(each)e(of)i(the)g Fj(ncon)e FK(x)h Fj(nparts)e +FK(elements)i(should)g(be)h(set)f(to)g(a)1162 8512 y(v)l(alue)c(of)g +(1/)p Fj(nparts)p FK(.)47 b(If)38 b Fj(ncon)d FK(is)i(greater)f(than)h +(one,)g(the)g(tar)m(get)g(sub-domain)g(weights)f(for)i(each)e +(sub-domain)1162 8731 y(are)50 b(stored)g(contiguously)f(\(similar)i +(to)f(the)g Fj(vwgt)e FK(array\).)76 b(Note)50 b(that)g(the)g(sum)f(of) +h(all)g(of)g(the)g Fj(tpwgts)e FK(for)i(a)1162 8950 y(gi)l(v)n(e)41 +b(v)n(erte)n(x)g(weight)g(should)g(be)h(one.)415 9217 +y FD(ub)n(v)n(ec)336 b FK(An)42 b(array)g(of)g(size)f +Fj(ncon)f FK(that)i(is)g(used)f(to)h(specify)f(the)h(imbalance)f +(tolerance)g(for)i(each)e(v)n(erte)n(x)g(weight,)g(with)h(1)1162 +9437 y(being)47 b(perfect)g(balance)e(and)i Fj(nparts)d +FK(being)j(perfect)g(imbalance.)66 b(A)46 b(v)l(alue)g(of)h(1.05)g(for) +g(each)f(of)h(the)f Fj(ncon)1162 9656 y FK(weights)41 +b(is)h(recommended.)415 9923 y FD(itr)572 b FK(This)43 +b(parameter)f(describes)f(the)h(ratio)h(of)g(inter)m(-processor)f +(communication)g(time)h(compared)f(to)g(data)g(redistri-)1162 +10142 y(b)m(ution)50 b(time.)75 b(It)50 b(should)f(be)g(set)g(between)f +(0.000001)h(and)h(1000000.0.)74 b(If)50 b(ITR)g(is)f(set)g(high,)i(a)e +(repartitioning)1162 10362 y(with)39 b(a)e(lo)l(w)h(edge-cut)g(will)h +(be)e(computed.)50 b(If)39 b(it)f(is)g(set)g(lo)l(w)-11 +b(,)38 b(a)g(repartitioning)h(that)f(requires)g(little)h(data)e +(redistri-)1162 10581 y(b)m(ution)i(will)g(be)f(computed.)50 +b(Good)38 b(v)l(alues)g(for)h(this)g(parameter)f(can)g(be)g(obtained)h +(by)f(di)l(viding)h(inter)m(-processor)1162 10800 y(communication)j +(time)g(by)f(data)g(redistrib)m(ution)h(time.)52 b(Otherwise,)40 +b(a)h(v)l(alue)g(of)h(1000.0)f(is)g(recommended.)3817 +11298 y(24)p eop +%%Page: 25 25 +25 24 bop 415 166 a FD(options)231 b FK(This)38 b(is)e(an)h(array)h(of) +f(inte)n(gers)f(that)h(is)g(used)g(to)g(pass)f(additional)h(parameters) +g(for)h(the)f(routine.)49 b(If)38 b Fs(options[0]=0)p +FK(,)1162 385 y(then)49 b(the)g(def)n(ault)g(v)l(alues)f(are)g(used.)72 +b(If)50 b Fs(options[0]=1)p FK(,)f(then)g(the)g(remaining)g(three)f +(elements)g(of)h Fs(options)g FK(are)1162 604 y(interpreted)42 +b(as)f(follo)l(ws:)1162 890 y(options[1])222 b(This)45 +b(speci\002es)f(the)h(le)l(v)n(el)f(of)h(information)g(to)g(be)g +(returned)g(during)g(the)g(e)n(x)n(ecution)e(of)i(the)g(algo-)2066 +1109 y(rithm.)61 b(T)-6 b(iming)46 b(information)f(can)f(be)h(obtained) +f(by)h(setting)f(this)g(to)h(1.)60 b(Additional)45 b(options)f(for)2066 +1328 y(this)i(parameter)f(can)f(be)h(obtained)g(by)h(looking)f(at)g +(the)g(the)g(\002le)h Fj(defs.h)d FK(in)i(the)g Fj(ParMETIS-)2066 +1548 y(Lib)39 b FK(directory)-11 b(.)51 b(The)40 b(numerical)g(v)l +(alues)f(there)h(should)f(be)h(added)f(to)h(obtain)g(the)g(correct)g(v) +l(alue.)2066 1767 y(The)i(def)n(ault)g(v)l(alue)f(is)g(0.)1162 +2019 y(options[2])222 b(This)42 b(is)f(the)h(random)g(number)f(seed)g +(for)h(the)f(routine.)52 b(The)42 b(def)n(ault)f(v)l(alue)h(is)f(15.) +1162 2271 y(options[3])222 b(This)51 b(speci\002es)e(whether)i(the)f +(sub-domains)g(and)g(processors)g(are)g(coupled)g(or)h(de-coupled.)77 +b(If)2066 2491 y(the)47 b(number)h(of)f(sub-domains)g(desired)f(\()p +Fs(i.e)p FK(.,)h Fj(nparts)p FK(\))f(and)g(the)h(number)h(of)f +(processors)f(that)2066 2710 y(are)k(being)g(used)f(is)h(not)g(the)g +(same,)h(then)f(these)f(must)h(be)g(de-coupled.)76 b(Ho)l(we)l(v)n(er) +-7 b(,)51 b(if)f Fj(nparts)2066 2929 y FK(equals)56 b(the)g(number)g +(of)h(processors,)h(these)d(can)h(either)g(be)g(coupled)f(or)i +(de-coupled.)94 b(If)57 b(sub-)2066 3148 y(domains)49 +b(and)g(processors)f(are)h(coupled,)h(then)f(the)g(initial)h +(partitioning)g(will)g(be)e(obtained)h(im-)2066 3367 +y(plicitly)66 b(from)f(the)g(graph)g(distrib)m(ution.)121 +b(Ho)l(we)l(v)n(er)-7 b(,)69 b(if)c(sub-domains)f(are)h(de-coupled)f +(from)2066 3587 y(processors,)44 b(then)g(the)g(initial)h(partitioning) +g(needs)f(to)g(be)h(obtained)f(from)h(the)f(initial)h(v)l(alues)e(as-) +2066 3806 y(signed)j(to)h(the)f Fj(part)f FK(array)-11 +b(.)66 b(A)46 b(v)l(alue)g(of)h(1)g(indicates)e(that)i(sub-domains)f +(and)g(processors)f(are)2066 4025 y(coupled)50 b(and)f(2)g(indicates)g +(that)g(these)g(are)g(de-coupled.)75 b(The)49 b(def)n(ault)h(v)l(alue)f +(is)g(1)h(\(coupled\))g(if)2066 4244 y Fj(nparts)40 b +FK(equals)g(the)i(number)g(of)f(processors)g(and)g(2)h(\(de-coupled\))f +(otherwise.)415 4530 y FD(edgecut)203 b FK(Upon)51 b(successful)f +(completion,)k(the)d(number)g(of)h(edges)e(that)h(are)g(cut)g(by)h(the) +f(partitioning)h(is)f(written)h(to)f(this)1162 4749 y(parameter)-9 +b(.)415 5034 y FD(part)443 b FK(This)33 b(is)f(an)f(array)i(of)f(size)f +(equal)h(to)g(the)g(number)h(of)f(locally-stored)g(v)n(ertices.)47 +b(Upon)32 b(successful)f(completion)h(the)1162 5254 y(partition)44 +b(v)n(ector)e(of)h(the)g(locally-stored)g(v)n(ertices)e(is)i(written)g +(to)g(this)f(array)-11 b(.)55 b(\(See)43 b(discussion)f(in)h(Section)g +(4.4\).)1162 5473 y(If)i(the)f(number)g(of)h(processors)d(does)i(not)g +(equal)g(the)g(number)g(of)g(sub-domains)g(and/or)g(options[3])h(is)f +(set)f(to)h(2,)1162 5692 y(then)38 b(the)g(pre)l(viously)g(computed)g +(partitioning)g(must)g(be)g(passed)f(to)h(the)g(routine)g(as)f(a)h +(parameter)g(via)f(this)h(array)-11 b(.)415 5978 y FD(comm)314 +b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g(communicator)h(of)f +(the)g(processes)e(that)i(call)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)46 b(F)n(or)e(most)g +(programs)1162 6197 y(this)e(will)g(point)g(to)f Fj(MPI)p +2607 6197 50 7 v 59 w(COMM)p 3066 6197 V 58 w(WORLD)p +FK(.)3817 11298 y(25)p eop +%%Page: 26 26 +26 25 bop 0 166 a Ft(5.3)199 b(P)-6 b(ar)t(titioning)56 +b(Re\002nement)0 471 y FB(P)-5 b(arMETIS)p 780 471 50 +7 v 60 w(V3)p 1043 471 V 60 w(Re\002neKwa)m(y)43 b FK(\(idxtype)f +(*vtxdist,)f(idxtype)h(*xadj,)f(idxtype)g(*adjnc)n(y)-11 +b(,)41 b(idxtype)g(*vwgt,)h(idxtype)f(*adjwgt,)2072 690 +y(int)h(*wgt\003ag,)f(int)h(*num\003ag,)f(int)h(*ncon,)f(int)h +(*nparts,)f(\003oat)g(*tpwgts,)g(\003oat)h(*ub)n(v)n(ec,)2072 +909 y(int)g(*options,)f(int)h(*edgecut,)e(idxtype)i(*part,)f(MPI)p +5112 909 V 60 w(Comm)h(*comm\))0 1299 y FB(Description)415 +1518 y FK(This)i(routine)h(is)f(used)f(to)i(impro)n(v)n(e)e(the)h +(quality)h(of)f(an)g(e)n(xisting)g(a)f Fy(k)10 b FK(-w)n(ay)44 +b(partitioning)h(on)64 b Fy(p)49 b FK(processors)43 b(using)h(the)g +(multi-)415 1738 y(le)l(v)n(el)d Fy(k)10 b FK(-w)n(ay)41 +b(re\002nement)h(algorithm.)0 2061 y FB(P)-5 b(arameter)n(s)415 +2272 y FD(vtxdist)268 b FK(This)39 b(array)g(describes)f(ho)l(w)g(the)h +(v)n(ertices)f(of)h(the)f(graph)h(are)g(distrib)m(uted)f(among)h(the)g +(processors.)49 b(\(See)39 b(discus-)1162 2491 y(sion)j(in)f(Section)h +(4.1\).)51 b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f +(processor)-9 b(.)415 2696 y FD(xadj,)42 b(adjncy)1162 +2915 y FK(These)52 b(store)g(the)h(\(local\))f(adjacenc)n(y)f +(structure)h(of)h(the)f(graph)g(at)h(each)e(processor)-9 +b(.)83 b(\(See)52 b(discussion)f(in)i(Sec-)1162 3134 +y(tion)42 b(4.1\).)415 3333 y FD(vwgt,)f(adjwgt)1162 +3552 y FK(These)g(store)h(the)f(weights)g(of)h(the)f(v)n(ertices)g(and) +g(edges.)50 b(\(See)42 b(discussion)e(in)i(Section)f(4.1\).)415 +3809 y FD(ncon)406 b FK(This)47 b(is)e(used)h(to)g(specify)f(the)h +(number)g(of)h(weights)e(that)h(each)f(v)n(erte)n(x)g(has.)64 +b(It)46 b(is)g(also)g(the)f(number)i(of)f(balance)1162 +4028 y(constraints)41 b(that)h(must)f(be)h(satis\002ed.)415 +4286 y FD(nparts)286 b FK(This)54 b(is)f(used)g(to)h(specify)f(the)g +(number)h(of)f(sub-domains)g(that)h(are)f(desired.)87 +b(Note)53 b(that)g(the)h(number)f(of)h(sub-)1162 4505 +y(domains)42 b(is)f(independent)g(of)h(the)f(number)h(of)g(processors)e +(that)i(call)f(this)g(routine.)415 4762 y FD(wgt\003ag)231 +b FK(This)42 b(is)f(used)g(to)h(indicate)f(if)h(the)f(graph)h(is)f +(weighted.)51 b Fs(wgt\003a)n(g)42 b FK(can)f(tak)n(e)g(one)h(of)f +(four)i(v)l(alues:)1162 5019 y(0)166 b(No)42 b(weights)f(\(vwgt)h(and)f +(adjwgt)h(are)f(both)g(NULL\).)1162 5257 y(1)166 b(W)-13 +b(eights)41 b(on)h(the)f(edges)g(only)g(\(vwgt)h(is)f(NULL\).)1162 +5496 y(2)166 b(W)-13 b(eights)41 b(on)h(the)f(v)n(ertices)f(only)i +(\(adjwgt)g(is)f(NULL\).)1162 5734 y(3)166 b(W)-13 b(eights)41 +b(on)h(both)f(the)h(v)n(ertices)e(and)h(edges.)415 5991 +y FD(num\003ag)167 b FK(This)58 b(is)f(used)g(to)h(indicate)f(the)g +(numbering)h(scheme)e(that)i(is)f(used)g(for)h(the)f +Fs(vtxdist)p FK(,)k Fs(xadj)p FK(,)f Fs(adjncy)p FK(,)h(and)c +Fs(part)1162 6210 y FK(arrays.)51 b Fs(num\003a)n(g)42 +b FK(can)f(tak)n(e)g(the)h(follo)l(wing)g(tw)n(o)g(v)l(alues:)1162 +6467 y(0)166 b(C-style)42 b(numbering)g(is)f(assumed)f(that)i(starts)f +(from)h(0)1162 6706 y(1)166 b(F)n(ortran-style)42 b(numbering)g(is)f +(assumed)g(that)g(starts)g(from)i(1)415 6963 y FD(tpwgts)277 +b FK(An)52 b(array)g(of)g(size)f Fj(ncon)g FK(x)h Fj(nparts)d +FK(that)j(is)g(used)f(to)h(specify)f(the)h(fraction)g(of)h(v)n(erte)n +(x)d(weight)i(that)g(should)1162 7182 y(be)44 b(distrib)m(uted)g(to)g +(each)f(sub-domain)h(for)h(each)e(balance)g(constraint.)58 +b(If)45 b(all)f(of)g(the)g(sub-domains)f(are)h(to)g(be)g(of)1162 +7401 y(the)e(same)e(size)h(for)h(e)l(v)n(ery)f(v)n(erte)n(x)f(weight,)h +(then)h(each)e(of)i(the)g Fj(ncon)e FK(x)h Fj(nparts)e +FK(elements)i(should)g(be)h(set)f(to)g(a)1162 7620 y(v)l(alue)c(of)g +(1/)p Fj(nparts)p FK(.)47 b(If)38 b Fj(ncon)d FK(is)i(greater)f(than)h +(one,)g(the)g(tar)m(get)g(sub-domain)g(weights)f(for)i(each)e +(sub-domain)1162 7839 y(are)50 b(stored)g(contiguously)f(\(similar)i +(to)f(the)g Fj(vwgt)e FK(array\).)76 b(Note)50 b(that)g(the)g(sum)f(of) +h(all)g(of)g(the)g Fj(tpwgts)e FK(for)i(a)1162 8059 y(gi)l(v)n(e)41 +b(v)n(erte)n(x)g(weight)g(should)g(be)h(one.)415 8316 +y FD(ub)n(v)n(ec)336 b FK(An)42 b(array)g(of)g(size)f +Fj(ncon)f FK(that)i(is)g(used)f(to)h(specify)f(the)h(imbalance)f +(tolerance)g(for)i(each)e(v)n(erte)n(x)g(weight,)g(with)h(1)1162 +8535 y(being)47 b(perfect)g(balance)e(and)i Fj(nparts)d +FK(being)j(perfect)g(imbalance.)66 b(A)46 b(v)l(alue)g(of)h(1.05)g(for) +g(each)f(of)h(the)f Fj(ncon)1162 8754 y FK(weights)41 +b(is)h(recommended.)415 9011 y FD(options)231 b FK(This)36 +b(is)f(an)g(array)g(of)h(inte)n(gers)f(that)g(is)g(used)g(to)g(pass)g +(parameters)f(to)i(the)f(routine.)49 b(Their)36 b(meanings)f(are)g +(identical)1162 9231 y(to)42 b(those)f(of)h FA(P)-7 b(arMETIS)p +2673 9231 V 61 w(V3)p 2937 9231 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)p FK(.)415 9488 y FD(edgecut)203 b FK(Upon)51 b(successful)f +(completion,)k(the)d(number)g(of)h(edges)e(that)h(are)g(cut)g(by)h(the) +f(partitioning)h(is)f(written)h(to)f(this)1162 9707 y(parameter)-9 +b(.)415 9964 y FD(part)443 b FK(This)33 b(is)f(an)f(array)i(of)f(size)f +(equal)h(to)g(the)g(number)h(of)f(locally-stored)g(v)n(ertices.)47 +b(Upon)32 b(successful)f(completion)h(the)1162 10183 +y(partition)43 b(v)n(ector)d(of)i(the)g(locally-stored)f(v)n(ertices)g +(is)g(written)h(to)g(this)f(array)-11 b(.)51 b(\(See)42 +b(discussion)e(in)i(Section)g(4.4\).)415 10440 y FD(comm)314 +b FK(This)45 b(is)e(a)h(pointer)g(to)g(the)g(MPI)g(communicator)h(of)f +(the)g(processes)e(that)i(call)k FA(P)-10 b FG(A)8 b(R)g +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)46 b(F)n(or)e(most)g +(programs)1162 10660 y(this)e(will)g(point)g(to)f Fj(MPI)p +2607 10660 V 59 w(COMM)p 3066 10660 V 58 w(WORLD)p FK(.)3817 +11298 y(26)p eop +%%Page: 27 27 +27 26 bop 0 166 a Ft(5.4)199 b(Fill-reducing)55 b(Or)l(derings)0 +485 y FB(P)-5 b(arMETIS)p 780 485 50 7 v 60 w(V3)p 1043 +485 V 60 w(NodeND)42 b FK(\(idxtype)g(*vtxdist,)f(idxtype)h(*xadj,)f +(idxtype)g(*adjnc)n(y)-11 b(,)41 b(int)h(*num\003ag,)f(int)h(*options,) +1789 704 y(idxtype)g(*order)-7 b(,)42 b(idxtype)f(*sizes,)f(MPI)p +4172 704 V 60 w(Comm)i(*comm\))0 1222 y FB(Description)415 +1441 y FK(This)g(routine)g(is)f(used)g(to)h(compute)f(a)g +(\002ll-reducing)i(ordering)f(of)f(a)h(sparse)e(matrix)i(using)g +(multile)l(v)n(el)f(nested)g(dissection.)0 1793 y FB(P)-5 +b(arameter)n(s)415 2032 y FD(vtxdist)268 b FK(This)39 +b(array)g(describes)f(ho)l(w)g(the)h(v)n(ertices)f(of)h(the)f(graph)h +(are)g(distrib)m(uted)f(among)h(the)g(processors.)49 +b(\(See)39 b(discus-)1162 2252 y(sion)j(in)f(Section)h(4.1\).)51 +b(Its)41 b(contents)g(are)g(identical)h(for)g(e)l(v)n(ery)f(processor) +-9 b(.)415 2485 y FD(xadj,)42 b(adjncy)1162 2704 y FK(These)56 +b(store)h(the)f(\(local\))h(adjacenc)n(y)e(structure)i(of)g(the)f +(graph)h(at)f(each)g(processor)g(\(See)h(discussion)e(in)i(Sec-)1162 +2923 y(tion)42 b(4.1\).)415 3209 y FD(num\003ag)167 b +FK(This)53 b(is)f(used)g(to)h(indicate)f(the)h(numbering)g(scheme)f +(that)g(is)g(used)g(for)i(the)e Fs(vtxdist)p FK(,)j Fs(xadj)p +FK(,)f Fs(adjncy)p FK(,)h(and)d Fs(or)-6 b(der)1162 3428 +y FK(arrays.)51 b Fs(num\003a)n(g)42 b FK(can)f(tak)n(e)g(the)h(follo)l +(wing)g(tw)n(o)g(v)l(alues:)1162 3714 y(0)166 b(C-style)42 +b(numbering)g(is)f(assumed)f(that)i(starts)f(from)h(0)1162 +3966 y(1)166 b(F)n(ortran-style)42 b(numbering)g(is)f(assumed)g(that)g +(starts)g(from)i(1)415 4252 y FD(options)231 b FK(This)36 +b(is)f(an)g(array)g(of)h(inte)n(gers)f(that)g(is)g(used)g(to)g(pass)g +(parameters)f(to)i(the)f(routine.)49 b(Their)36 b(meanings)f(are)g +(identical)1162 4471 y(to)42 b(those)f(of)h FA(P)-7 b(arMETIS)p +2673 4471 V 61 w(V3)p 2937 4471 V 60 w(P)g(ar)7 b(tKw)n(a)-5 +b(y)p FK(.)415 4756 y FD(order)350 b FK(This)42 b(array)g(returns)f +(the)h(result)f(of)h(the)f(ordering)h(\(described)f(in)h(Section)g +(4.4\).)415 5042 y FD(sizes)423 b FK(This)51 b(array)f(returns)h(the)f +(number)g(of)h(nodes)f(for)g(each)g(sub-domain)g(and)g(each)g +(separator)g(\(described)f(in)i(Sec-)1162 5261 y(tion)42 +b(4.4\).)415 5547 y FD(comm)314 b FK(This)45 b(is)e(a)h(pointer)g(to)g +(the)g(MPI)g(communicator)h(of)f(the)g(processes)e(that)i(call)k +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)t FK(.)46 b(F)n(or)e(most)g(programs)1162 5766 y(this)e(will)g +(point)g(to)f Fj(MPI)p 2607 5766 V 59 w(COMM)p 3066 5766 +V 58 w(WORLD)p FK(.)0 6118 y FB(Note)415 6337 y FA(P)-7 +b(arMETIS)p 1183 6337 V 61 w(V3)p 1447 6337 V 60 w(NodeND)42 +b FK(requires)f(that)h(the)f(number)h(of)g(processors)e(be)i(a)f(po)l +(wer)g(of)h(2.)3817 11298 y(27)p eop +%%Page: 28 28 +28 27 bop 0 166 a Ft(5.5)199 b(Mesh)55 b(to)g(Graph)g(T)-16 +b(ranslation)0 485 y FB(P)-5 b(arMETIS)p 780 485 50 7 +v 60 w(V3)p 1043 485 V 60 w(Mesh2Dual)44 b FK(\(idxtype)e(*elmdist,)f +(idxtype)g(*eptr)-7 b(,)42 b(idxtype)g(*eind,)f(int)g(*num\003ag,)2011 +704 y(int)h(*ncommonnodes,)e(idxtype)i(**xadj,)f(idxtype)g(**adjnc)n(y) +-11 b(,)41 b(MPI)p 6043 704 V 60 w(Comm)h(*comm\))0 1222 +y FB(Description)415 1441 y FK(This)e(routine)h(is)e(used)h(to)g +(construct)g(a)f(distrib)m(uted)h(graph)h(gi)l(v)n(en)e(a)h(distrib)m +(uted)g(mesh.)50 b(It)40 b(can)f(be)h(used)g(in)g(conjunction)g(with) +415 1660 y(other)i(routines)f(in)h(the)j FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)48 b FK(library)-11 +b(.)52 b(The)42 b(mesh)f(can)g(contain)g(elements)g(of)h(dif)l(ferent)g +(types.)0 2012 y FB(P)-5 b(arameter)n(s)415 2252 y FD(elmdist)231 +b FK(This)47 b(array)g(describes)e(ho)l(w)i(the)f(elements)g(of)h(the)f +(mesh)h(are)f(distrib)m(uted)g(among)h(the)g(processors.)65 +b(It)47 b(is)f(anal-)1162 2471 y(ogous)64 b(to)g(the)g +Fj(vtxdist)d FK(array)-11 b(.)119 b(Its)64 b(contents)f(are)h +(identical)g(for)g(e)l(v)n(ery)f(processor)-9 b(.)118 +b(\(See)64 b(discussion)f(in)1162 2690 y(Section)42 b(4.3\).)415 +2917 y FD(eptr)-15 b(,)41 b(eind)1162 3136 y FK(These)64 +b(arrays)g(speci\002es)f(the)g(elements)h(that)g(are)g(stored)g +(locally)g(at)g(each)f(processor)-9 b(.)118 b(\(See)64 +b(discussion)f(in)1162 3355 y(Section)42 b(4.3\).)415 +3641 y FD(num\003ag)167 b FK(This)52 b(is)g(used)f(to)h(indicate)f(the) +h(numbering)g(scheme)f(that)h(is)f(used)h(for)g(the)g +Fs(elmdist)p FK(,)h Fs(elements)p FK(,)g Fs(xadj)p FK(,)h +Fs(adjncy)p FK(,)1162 3860 y(and)42 b Fs(part)f FK(arrays.)51 +b Fs(num\003a)n(g)41 b FK(can)g(tak)n(e)h(one)f(of)h(tw)n(o)g(v)l +(alues:)1162 4146 y(0)166 b(C-style)42 b(numbering)g(that)f(starts)g +(from)h(0.)1162 4398 y(1)166 b(F)n(ortran-style)42 b(numbering)g(that)g +(starts)f(from)h(1.)415 4629 y FD(ncommonnodes)1162 4848 +y FK(This)i(parameter)g(determines)g(the)f(de)n(gree)g(of)i(connecti)l +(vity)e(among)h(the)g(v)n(ertices)f(in)h(the)f(dual)h(graph.)58 +b(Speci\002-)1162 5067 y(cally)-11 b(,)43 b(an)f(edge)g(is)h(placed)f +(between)g(an)n(y)f(tw)n(o)j(elements)d(if)j(and)e(only)h(if)g(the)n(y) +f(share)g(at)g(least)g(this)h(man)n(y)f(nodes.)1162 5286 +y(This)53 b(v)l(alue)e(should)h(be)g(greater)g(than)g(zero,)i(and)e +(for)h(most)f(meshes)f(a)h(v)l(alue)f(of)i(tw)n(o)f(will)h(create)e +(reasonable)1162 5505 y(dual)45 b(graphs.)61 b(Ho)l(we)l(v)n(er)-7 +b(,)44 b(depending)g(on)h(the)g(type)g(of)g(elements)f(in)h(the)g +(mesh,)f(v)l(alues)g(greater)h(than)g(tw)n(o)g(may)1162 +5724 y(also)50 b(be)g(v)l(alid)g(choices.)77 b(F)n(or)50 +b(e)n(xample,)h(for)g(meshes)f(containing)g(only)h(triangular)-7 +b(,)53 b(tetrahedral,)f(he)n(xahedral,)1162 5944 y(or)42 +b(rectangular)g(elements,)e(this)h(parameter)h(can)f(be)g(set)g(to)g +(tw)n(o,)h(three,)f(four)-7 b(,)42 b(or)g(tw)n(o,)f(respecti)l(v)n(ely) +-11 b(.)1162 6196 y(Note)51 b(that)f(setting)h(this)f(parameter)g(to)h +(a)f(small)h(v)l(alue)f(will)h(increase)e(the)h(number)h(of)g(edges)f +(in)g(the)h(resulting)1162 6415 y(dual)42 b(graph)f(and)h(the)f +(corresponding)g(partitioning)i(time.)415 6649 y FD(xadj,)f(adjncy)1162 +6868 y FK(Upon)37 b(the)f(successful)e(completion)j(of)f(the)h +(routine,)g(pointers)f(to)h(the)f(constructed)g Fj(xadj)e +FK(and)i Fj(adjncy)e FK(arrays)1162 7087 y(will)42 b(be)f(written)h(to) +g(these)f(parameters.)50 b(\(See)42 b(discussion)e(in)i(Section)f +(4.1\).)415 7373 y FD(comm)314 b FK(This)45 b(is)e(a)h(pointer)g(to)g +(the)g(MPI)g(communicator)h(of)f(the)g(processes)e(that)i(call)k +FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p +FA(S)t FK(.)46 b(F)n(or)e(most)g(programs)1162 7592 y(this)e(will)g +(point)g(to)f Fj(MPI)p 2607 7592 V 59 w(COMM)p 3066 7592 +V 58 w(WORLD)p FK(.)0 7944 y FB(Note)415 8163 y FK(This)48 +b(routine)f(can)g(be)g(used)g(in)g(conjunction)h(with)f +FA(P)-7 b(arMETIS)p 4227 8163 V 61 w(V3)p 4491 8163 V +60 w(P)g(ar)7 b(tKw)n(a)-5 b(y)p FK(,)48 b FA(P)-7 b(arMETIS)p +6102 8163 V 61 w(V3)p 6366 8163 V 60 w(P)g(ar)7 b(tGeomKw)n(a)-5 +b(y)p FK(,)50 b(or)415 8382 y FA(P)-7 b(arMETIS)p 1183 +8382 V 61 w(V3)p 1447 8382 V 60 w(Adaptiv)l(eRepar)7 +b(t)p FK(.)53 b(It)42 b(typically)f(runs)h(in)f(half)h(the)g(time)f +(required)h(by)g FA(P)-7 b(arMETIS)p 6452 8382 V 61 w(V3)p +6716 8382 V 59 w(P)g(ar)7 b(tKw)n(a)-5 b(y)p FK(.)3817 +11298 y(28)p eop +%%Page: 29 29 +29 28 bop 0 170 a FE(6)233 b(Har)-5 b(d)m(ware)66 b(&)e(Software)i +(Requirements,)g(and)e(Contact)i(Inf)-5 b(ormation)4 +522 y FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)72 b FK(is)64 b(written)i(in)f(ANSI)h(C)f(and)g(uses)f(MPI) +h(for)h(inter)m(-processor)e(communication.)122 b(Instructions)66 +b(on)f(ho)l(w)g(to)g(b)m(uild)4 741 y FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)60 b FK(are)53 +b(a)m(v)l(ailable)f(in)h(the)h Fj(INSTALL)c FK(\002le.)87 +b(In)53 b(the)h(directory)f(called)g Fj(Graphs)p FK(,)h(you)f(will)h +(\002nd)f(programs)h(that)f(tests)g(if)4 960 y FA(P)-10 +b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)57 +b FK(w)n(as)50 b(b)m(uilt)g(correctly)-11 b(.)78 b(Also,)52 +b(a)e(header)g(\002le)g(called)g Fj(parmetis.h)c FK(is)51 +b(pro)n(vided)f(that)g(contains)g(prototypes)g(for)h(the)0 +1179 y(functions)42 b(in)j FA(P)-10 b FG(A)8 b(R)g FA(M)-9 +b FG(E)-34 b FA(T)g FG(I)p FA(S)t FK(.)199 1398 y(In)54 +b(order)g(to)g(use)j FA(P)-10 b FG(A)8 b(R)g FA(M)-9 +b FG(E)-34 b FA(T)g FG(I)p FA(S)61 b FK(in)54 b(your)g(application)f +(you)h(need)f(to)h(ha)m(v)n(e)f(a)g(cop)n(y)h(of)g(the)g(serial)j +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)61 b FK(library)54 +b(and)g(link)g(your)0 1617 y(program)49 b(with)g(both)g(libraries)f(\() +p Fs(i.e)p FK(.,)h Fj(libparmetis.a)44 b FK(and)k Fj(libmetis.a)p +FK(\).)69 b(Note)48 b(that)g(the)53 b FA(P)-10 b FG(A)8 +b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)55 b FK(package)47 +b(already)0 1837 y(contains)41 b(the)g(source)g(code)g(for)h(the)k +FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)48 b FK(library)-11 +b(.)52 b(The)41 b(included)h(Mak)n(e\002les)e(automatically)i +(construct)f(both)h(libraries.)203 2056 y FA(P)-10 b +FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g FG(I)p FA(S)76 +b FK(ha)m(v)n(e)69 b(been)g(e)n(xtensi)l(v)n(ely)f(tested)h(on)h(a)f +(number)h(of)g(dif)l(ferent)g(parallel)g(computers.)135 +b(Ho)l(we)l(v)n(er)-7 b(,)75 b(e)l(v)n(en)69 b(though)4 +2275 y FA(P)-10 b FG(A)8 b(R)g FA(M)-9 b FG(E)-34 b FA(T)g +FG(I)p FA(S)47 b FK(contains)41 b(no)f(kno)l(wn)h(b)m(ugs,)f(this)h +(does)f(not)h(mean)f(that)h(all)g(of)g(its)g(b)m(ugs)f(ha)m(v)n(e)f +(been)i(found)g(and)g(\002x)n(ed.)50 b(If)41 b(you)g(ha)m(v)n(e)f(an)n +(y)0 2494 y(problems,)h(please)f(send)h(email)h(to)f +Fs(metis@cs.umn.edu)e FK(with)j(a)f(brief)h(description)g(of)f(the)h +(problem.)0 2986 y FE(Ref)n(erences)75 3319 y Ff([1])82 +b(R.)33 b(Bisw)o(as)f(and)h(R.)g(Stra)n(wn.)45 b(A)33 +b(ne)l(w)g(procedure)f(for)h(dynamic)g(adaption)e(of)i +(three-dimensional)e(unstructured)g(grids.)44 b Fe(Applied)32 +b(Numerical)332 3520 y(Mathematics)p Ff(,)37 b(13:437\226452,)d(1994.) +75 3754 y([2])82 b(C.)53 b(Fiduccia)f(and)h(R.)g(Matthe)n(yses.)103 +b(A)52 b(linear)h(time)f(heuristic)g(for)g(impro)n(ving)e(netw)o(ork)h +(partitions.)101 b(In)52 b Fe(In)h(Pr)-7 b(oc.)54 b(19th)d(IEEE)j +(Design)332 3955 y(A)m(utomation)35 b(Confer)-6 b(ence)p +Ff(,)38 b(pages)g(175\226181,)d(1982.)75 4190 y([3])82 +b(J.)40 b(Fingber)m(g,)f(A.)h(Basermann,)h(G.)f(Lonsdale,)g(J.)g +(Clinck)o(emaillie,)e(J.)i(Gratien,)g(and)f(R.)h(Ducloux.)60 +b(Dynamic)39 b(load-balancing)f(for)h(parallel)332 4390 +y(structural)d(mechanics)i(simulations)d(with)i(DRAMA.)53 +b Fe(ECT2000)p Ff(,)37 b(2000.)75 4625 y([4])82 b(G.)43 +b(Karypis)f(and)h(V)-19 b(.)43 b(K)n(umar)-8 b(.)72 b(A)42 +b(coarse-grain)h(parallel)f(multile)l(v)n(el)f Fc(k)9 +b Ff(-w)o(ay)43 b(partitioning)c(algorithm.)70 b(In)43 +b Fe(Pr)-7 b(oceedings)43 b(of)f(the)h(8th)f(SIAM)332 +4825 y(confer)-6 b(ence)38 b(on)f(P)-12 b(ar)n(allel)36 +b(Pr)-7 b(ocessing)38 b(for)f(Scienti\002c)f(Computing)p +Ff(,)f(1997.)75 5060 y([5])82 b(G.)37 b(Karypis)f(and)g(V)-19 +b(.)37 b(K)n(umar)-8 b(.)56 b Fa(M)-7 b Fb(E)-29 b Fa(T)g +Fb(I)q Fa(S)t Ff(:)33 b(A)j(softw)o(are)g(package)h(for)f(partitioning) +d(unstructured)i(graphs,)h(partitioning)d(meshes,)38 +b(and)f(comput-)332 5261 y(ing)h(\002ll-reducing)f(orderings)g(of)h +(sparse)i(matrices,)g(v)n(ersion)d(4.0.)59 b(T)-10 b(echnical)39 +b(report,)f(Uni)l(v)-10 b(.)39 b(of)f(MN,)h(Dept.)g(of)f(Computer)g +(Sci.)h(and)g(Engr)-8 b(.,)332 5461 y(1998.)75 5696 y([6])82 +b(G.)38 b(Karypis)e(and)h(V)-19 b(.)38 b(K)n(umar)-8 +b(.)53 b(Multile)l(v)n(el)35 b(algorithms)h(for)h(multi-constraint)d +(graph)i(partitioning.)51 b(In)37 b Fe(Pr)-7 b(oc.)38 +b(Super)-6 b(computing)36 b('98)p Ff(,)h(1998.)75 5930 +y([7])82 b(G.)49 b(Karypis)e(and)h(V)-19 b(.)48 b(K)n(umar)-8 +b(.)89 b(Multile)l(v)n(el)46 b Fc(k)9 b Ff(-w)o(ay)48 +b(partitioning)d(scheme)k(for)f(irre)n(gular)e(graphs.)89 +b Fe(J)l(ournal)47 b(of)h(P)-12 b(ar)n(allel)47 b(and)g(Distrib)m(uted) +332 6131 y(Computing)p Ff(,)35 b(48\(1\),)h(1998.)75 +6365 y([8])82 b(G.)42 b(Karypis)f(and)h(V)-19 b(.)42 +b(K)n(umar)-8 b(.)68 b(P)n(arallel)41 b(multile)l(v)n(el)f +Fc(k)9 b Ff(-w)o(ay)41 b(partitioning)e(scheme)k(for)e(irre)n(gular)f +(graphs.)68 b Fe(Siam)41 b(Re)n(vie)n(w)p Ff(,)i(41\(2\):278\226300,) +332 6566 y(1999.)75 6800 y([9])82 b(B.)60 b(K)l(ernighan)e(and)h(S.)h +(Lin.)125 b(An)59 b(ef)l(\002cient)h(heuristic)e(procedure)h(for)g +(partitioning)d(graphs.)124 b Fe(The)60 b(Bell)f(System)h(T)-14 +b(ec)n(hnical)58 b(J)l(ournal)p Ff(,)332 7001 y(49\(2\):291\226307,)34 +b(1970.)0 7235 y([10])82 b(L.)31 b(Olik)o(er)e(and)h(R.)h(Bisw)o(as.)38 +b(PLUM:)30 b(P)n(arallel)g(load)g(balancing)g(for)f(adapti)l(v)n(e)h +(unstructured)f(meshes.)40 b Fe(J)l(ournal)30 b(of)f(P)-12 +b(ar)n(allel)29 b(and)h(Distrib)m(uted)332 7436 y(Computing)p +Ff(,)35 b(52\(2\):150\226177,)f(1998.)0 7670 y([11])82 +b(A.)47 b(P)n(atra)h(and)f(D.)g(Kim.)85 b(Ef)l(\002cient)47 +b(mesh)h(partitioning)c(for)i(adapti)l(v)n(e)i Fc(h)11 +b(p)51 b Ff(\002nite)c(element)g(meshes.)87 b(T)-10 b(echnical)47 +b(report,)i(Dept.)e(of)f(Mech.)332 7871 y(Engr)-8 b(.,)37 +b(SUNY)g(at)h(Buf)l(f)o(alo,)e(1999.)0 8105 y([12])82 +b(A.)43 b(Pothen,)h(H.)f(Simon,)h(L.)g(W)-12 b(ang,)44 +b(and)f(S.)h(Bernard.)71 b(T)-12 b(o)l(w)o(ards)43 b(a)g(f)o(ast)f +(implementation)f(of)i(spectral)f(nested)h(dissection.)71 +b(In)42 b Fe(Super)-6 b(com-)332 8306 y(puting)35 b('92)i(Pr)-7 +b(oceedings)p Ff(,)38 b(pages)g(42\22651,)e(1992.)0 8540 +y([13])82 b(K.)34 b(Schloe)n(gel,)h(G.)f(Karypis,)g(and)g(V)-19 +b(.)34 b(K)n(umar)-8 b(.)47 b(A)34 b(ne)l(w)g(algorithm)e(for)i +(multi-objecti)l(v)n(e)d(graph)j(partitioning.)43 b(In)34 +b Fe(Pr)-7 b(oc.)35 b(Eur)-7 b(oP)-12 b(ar)34 b('99)p +Ff(,)h(pages)332 8741 y(322\226331,)h(1999.)0 8975 y([14])82 +b(K.)54 b(Schloe)n(gel,)j(G.)d(Karypis,)j(and)c(V)-19 +b(.)54 b(K)n(umar)-8 b(.)105 b(P)n(arallel)53 b(multile)l(v)n(el)f +(algorithms)g(for)g(multi-constraint)f(graph)h(partitioning.)103 +b(In)53 b Fe(Pr)-7 b(oc.)332 9176 y(Eur)g(oP)-12 b(ar)m(-2000)p +Ff(,)37 b(2000.)53 b(Accepted)37 b(as)h(a)g(Distinguished)d(P)n(aper)-8 +b(.)0 9410 y([15])82 b(K.)50 b(Schloe)n(gel,)h(G.)f(Karypis,)i(and)d(V) +-19 b(.)49 b(K)n(umar)-8 b(.)92 b(A)49 b(uni\002ed)g(algorithm)e(for)i +(load-balancing)e(adapti)l(v)n(e)i(scienti\002c)g(simulations.)90 +b(In)49 b Fe(Pr)-7 b(oc.)332 9611 y(Super)h(computing)35 +b(2000)p Ff(,)i(2000.)0 9845 y([16])82 b(K.)38 b(Schloe)n(gel,)g(G.)h +(Karypis,)e(and)h(V)-19 b(.)38 b(K)n(umar)-8 b(.)57 b(W)-12 +b(a)m(v)n(efront)37 b(dif)l(fusion)f(and)i(LMSR:)f(Algorithms)f(for)i +(dynamic)f(repartitioning)e(of)j(adapti)l(v)n(e)332 10046 +y(meshes.)55 b Fe(IEEE)38 b(T)-8 b(r)n(ansactions)36 +b(on)g(P)-12 b(ar)n(allel)36 b(and)h(Distrib)m(uted)e(Systems)p +Ff(,)j(12\(5\):451\226466,)c(2001.)0 10280 y([17])82 +b(J.)47 b(W)-12 b(atts,)49 b(M.)e(Rief)l(fel,)i(and)e(S.)g(T)-12 +b(aylor)k(.)83 b(A)47 b(load)f(balancing)g(technique)f(for)h +(multi-phase)g(computations.)82 b Fe(Pr)-7 b(oc.)48 b(of)e(High)g(P)-12 +b(erformance)332 10481 y(Computing)35 b(`97)p Ff(,)i(pages)g(15\22620,) +f(1997.)3817 11298 y FK(29)p eop +%%Trailer +end +userdict /end-hook known{end-hook}if +%%EOF diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/Makefile b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/Makefile new file mode 100644 index 0000000..3281a07 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/Makefile @@ -0,0 +1,48 @@ +include ../Makefile.in + + +CFLAGS = $(COPTIONS) $(OPTFLAGS) -I. $(INCDIR) + + +OBJS = comm.o util.o debug.o setup.o grsetup.o timer.o \ + node_refine.o initmsection.o order.o \ + xyzpart.o pspases.o frename.o \ + iintsort.o iidxsort.o ikeysort.o ikeyvalsort.o \ + kmetis.o gkmetis.o ometis.o \ + initpart.o match.o coarsen.o \ + kwayfm.o kwayrefine.o kwaybalance.o \ + remap.o stat.o fpqueue.o \ + ametis.o rmetis.o lmatch.o initbalance.o \ + mdiffusion.o diffutil.o wave.o \ + csrmatch.o redomylink.o balancemylink.o \ + selectq.o akwayfm.o serial.o move.o \ + mmetis.o mesh.o memory.o weird.o backcompat.o + +.c.o: + $(CC) $(CFLAGS) -c $*.c + + +../libparmetis.a: $(OBJS) + $(AR) $@ $(OBJS) + $(RANLIB) $@ + +clean: + rm -f *.o + +realclean: + rm -f *.o ; rm -f ../libparmetis.a + + +checkin: + @for file in *.[c,h]; \ + do \ + ci -u -m'Maintance' $$file;\ + done + +checkin2: + @for file in *.[c,h]; \ + do \ + ci $$file;\ + rcs -U $$file;\ + co $$file;\ + done diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/adrivers.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/adrivers.c new file mode 100644 index 0000000..e9c5fe0 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/adrivers.c @@ -0,0 +1,117 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * adrivers.c + * + * This file contains the driving routines for the various parallel + * multilevel partitioning and repartitioning algorithms + * + * Started 11/19/96 + * George + * + * $Id: adrivers.c,v 1.5 2003/07/30 18:37:58 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function is the driver for the adaptive refinement mode of ParMETIS +**************************************************************************/ +void Adaptive_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i; + int tewgt, tvsize; + float gtewgt, gtvsize; + float ubavg, lbavg, lbvec[MAXNCON]; + + /************************************/ + /* Set up important data structures */ + /************************************/ + SetUp(ctrl, graph, wspace); + + ubavg = savg(graph->ncon, ctrl->ubvec); + tewgt = idxsum(graph->nedges, graph->adjwgt); + tvsize = idxsum(graph->nvtxs, graph->vsize); + gtewgt = (float) GlobalSESum(ctrl, tewgt) + 1.0; /* The +1 were added to remove any FPE */ + gtvsize = (float) GlobalSESum(ctrl, tvsize) + 1.0; + ctrl->redist_factor = ctrl->redist_base * ((gtewgt/gtvsize)/ ctrl->edge_size_ratio); + + IFSET(ctrl->dbglvl, DBG_PROGRESS, rprintf(ctrl, "[%6d %8d %5d %5d][%d]\n", + graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo)); + + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || + (graph->finer != NULL && graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + + /***********************************************/ + /* Balance the partition on the coarsest graph */ + /***********************************************/ + graph->where = idxsmalloc(graph->nvtxs+graph->nrecv, -1, "graph->where"); + idxcopy(graph->nvtxs, graph->home, graph->where); + + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) + Balance_Partition(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + /* check if no coarsening took place */ + if (graph->finer == NULL) { + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + } + } + else { + /*******************************/ + /* Coarsen it and partition it */ + /*******************************/ + switch (ctrl->ps_relation) { + case COUPLED: + Mc_LocalMatch_HEM(ctrl, graph, wspace); + break; + case DISCOUPLED: + default: + Moc_GlobalMatch_Balance(ctrl, graph, wspace); + break; + } + + Adaptive_Partition(ctrl, graph->coarser, wspace); + + /********************************/ + /* project partition and refine */ + /********************************/ + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); + + if (graph->ncon > 1 && graph->level < 4) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.025) { + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + } + } + + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + } +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/akwayfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/akwayfm.c new file mode 100644 index 0000000..7579d8b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/akwayfm.c @@ -0,0 +1,629 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * makwayfm.c + * + * This file contains code that performs the k-way refinement + * + * Started 3/1/96 + * George + * + * $Id: akwayfm.c,v 1.3 2003/07/22 22:58:18 karypis Exp $ + */ + +#include + +#define ProperSide(c, from, other) \ + (((c) == 0 && (from)-(other) < 0) || ((c) == 1 && (from)-(other) > 0)) + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Moc_KWayAdaptiveRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +{ + int h, i, ii, iii, j, k, c; + int pass, nvtxs, nedges, ncon; + int nmoves, nmoved; + int me, firstvtx, lastvtx, yourlastvtx; + int from, to = -1, oldto, oldcut, mydomain, yourdomain, imbalanced, overweight; + int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; + int nlupd, nsupd, nnbrs, nchanged; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; + idxtype *where, *tmp_where, *moved; + float *lnpwgts, *gnpwgts, *ognpwgts, *pgnpwgts, *movewgts, *overfill; + idxtype *update, *supdate, *rupdate, *pe_updates; + idxtype *changed, *perm, *pperm, *htable; + idxtype *peind, *recvptr, *sendptr; + KeyValueType *swchanges, *rwchanges; + RInfoType *rinfo, *myrinfo, *tmp_myrinfo, *tmp_rinfo; + EdgeType *tmp_edegrees, *my_edegrees, *your_edegrees; + float lbvec[MAXNCON], *nvwgt, *badmaxpwgt, *ubvec, *tpwgts, lbavg, ubavg; + float oldgain, gain; + float ipc_factor, redist_factor, vsize; + int *nupds_pe, ndirty, nclean, dptr; + int better, worse; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); + + /*************************/ + /* set up common aliases */ + /*************************/ + nvtxs = graph->nvtxs; + nedges = graph->nedges; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + where = graph->where; + rinfo = graph->rinfo; + lnpwgts = graph->lnpwgts; + gnpwgts = graph->gnpwgts; + ubvec = ctrl->ubvec; + tpwgts = ctrl->tpwgts; + ipc_factor = ctrl->ipc_factor; + redist_factor = ctrl->redist_factor; + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvptr = graph->recvptr; + sendptr = graph->sendptr; + + changed = idxmalloc(nvtxs, "AKWR: changed"); + rwchanges = wspace->pairs; + swchanges = rwchanges + recvptr[nnbrs]; + + /************************************/ + /* set up important data structures */ + /************************************/ + perm = idxmalloc(nvtxs, "AKWR: perm"); + pperm = idxmalloc(nparts, "AKWR: pperm"); + + update = idxmalloc(nvtxs, "AKWR: update"); + supdate = wspace->indices; + rupdate = supdate + recvptr[nnbrs]; + nupds_pe = imalloc(npes, "AKWR: nupds_pe"); + htable = idxsmalloc(nvtxs+graph->nrecv, 0, "AKWR: lhtable"); + badmaxpwgt = fmalloc(nparts*ncon, "badmaxpwgt"); + + for (i=0; inrecv, "AKWR: tmp_where"); + tmp_rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "AKWR: tmp_rinfo"); + tmp_edegrees = (EdgeType *)GKmalloc(sizeof(EdgeType)*nedges, "AKWR: tmp_edegrees"); + + idxcopy(nvtxs+graph->nrecv, where, tmp_where); + for (i=0; imincut; + if (mype == 0) + RandomPermute(nparts, pperm, 1); + MPI_Bcast((void *)pperm, nparts, IDX_DATATYPE, 0, ctrl->comm); +/* FastRandomPermute(nvtxs, perm, 1); */ + + /*****************************/ + /* move dirty vertices first */ + /*****************************/ + ndirty = 0; + for (i=0; iwhere, lbvec); + ubavg = savg(ncon, ubvec); + lbavg = savg(ncon, lbvec); + imbalanced = (lbavg > ubavg) ? 1 : 0; + + for (c=0; c<2; c++) { + scopy(ncon*nparts, gnpwgts, ognpwgts); + sset(ncon*nparts, 0.0, movewgts); + nmoved = 0; + + /**********************************************/ + /* PASS ONE -- record stats for desired moves */ + /**********************************************/ + for (iii=0; iiinvwgt+i*ncon; + vsize = (float)(graph->vsize[i]); + + for (h=0; h badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) + break; + } + if (h == ncon) + break; + } + } + oldto = to; + + /* check if a subdomain was found that fits */ + if (k < tmp_rinfo[i].ndegrees) { + /**************************/ + /**************************/ + switch (ctrl->ps_relation) { + case COUPLED: + better = (oldto == mype) ? 1 : 0; + worse = (from == mype) ? 1 : 0; + break; + case DISCOUPLED: + default: + better = (oldto == graph->home[i]) ? 1 : 0; + worse = (from == graph->home[i]) ? 1 : 0; + break; + } + /**************************/ + /**************************/ + + oldgain = ipc_factor * (float)(my_edegrees[k].ewgt-tmp_rinfo[i].id); + if (better) oldgain += redist_factor * vsize; + if (worse) oldgain -= redist_factor * vsize; + + for (j=k+1; jps_relation) { + case COUPLED: + better = (to == mype) ? 1 : 0; + break; + case DISCOUPLED: + default: + better = (to == graph->home[i]) ? 1 : 0; + break; + } + /**************************/ + /**************************/ + + gain = ipc_factor * (float)(my_edegrees[j].ewgt-tmp_rinfo[i].id); + if (better) gain += redist_factor * vsize; + if (worse) gain -= redist_factor * vsize; + + for (h=0; h badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) + break; + + if (h == ncon) { + if (gain > oldgain || + (fabs(gain-oldgain) < SMALLFLOAT && + IsHBalanceBetterTT(ncon,gnpwgts+oldto*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ + oldgain = gain; + oldto = to; + k = j; + } + } + } + } + to = oldto; + gain = oldgain; + + if (gain > 0.0 || + (gain > -1.0*SMALLFLOAT && + (imbalanced || graph->level > 3 || iii % 8 == 0) && + IsHBalanceBetterFT(ncon,gnpwgts+from*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ + + /****************************************/ + /* Update tmp arrays of the moved vertex */ + /****************************************/ + tmp_where[i] = to; + moved[nmoved++] = i; + for (h=0; h= nvtxs) + continue; + + me = ladjncy[j]; + mydomain = tmp_where[me]; + + myrinfo = tmp_rinfo+me; + your_edegrees = myrinfo->degrees; + + if (mydomain == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (mydomain == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution from the .ed of 'from' */ + if (mydomain != from) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == from) { + if (your_edegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; + your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; + } + else { + your_edegrees[k].ewgt -= adjwgt[j]; + } + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (mydomain != to) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == to) { + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + your_edegrees[myrinfo->ndegrees].edge = to; + your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + } + + /******************************************/ + /* Let processors know the subdomain wgts */ + /* if all proposed moves commit. */ + /******************************************/ + MPI_Allreduce((void *)lnpwgts, (void *)pgnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); + + /**************************/ + /* compute overfill array */ + /**************************/ + overweight = 0; + for (j=0; j ognpwgts[j*ncon+h]) + overfill[j*ncon+h] = (pgnpwgts[j*ncon+h]-badmaxpwgt[j*ncon+h]) / (pgnpwgts[j*ncon+h]-ognpwgts[j*ncon+h]); + else + overfill[j*ncon+h] = 0.0; + + overfill[j*ncon+h] = amax(overfill[j*ncon+h], 0.0); + overfill[j*ncon+h] *= movewgts[j*ncon+h]; + + if (overfill[j*ncon+h] > 0.0) + overweight = 1; + + ASSERTP(ctrl, ognpwgts[j*ncon+h] <= badmaxpwgt[j*ncon+h] || pgnpwgts[j*ncon+h] <= ognpwgts[j*ncon+h], + (ctrl, "%.4f %.4f %.4f\n", ognpwgts[j*ncon+h], badmaxpwgt[j*ncon+h], pgnpwgts[j*ncon+h])); + } + } + + /****************************************************/ + /* select moves to undo according to overfill array */ + /****************************************************/ + if (overweight == 1) { + for (iii=0; iiinvwgt+i*ncon; + my_edegrees = tmp_rinfo[i].degrees; + + for (k=0; k 0.0 && overfill[oldto*ncon+h] > nvwgt[h]/4.0) + break; + + /**********************************/ + /* nullify this move if necessary */ + /**********************************/ + if (k != tmp_rinfo[i].ndegrees && h != ncon) { + moved[iii] = -1; + from = oldto; + to = where[i]; + + for (h=0; h= nvtxs) + continue; + + me = ladjncy[j]; + mydomain = tmp_where[me]; + + myrinfo = tmp_rinfo+me; + your_edegrees = myrinfo->degrees; + + if (mydomain == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (mydomain == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution from the .ed of 'from' */ + if (mydomain != from) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == from) { + if (your_edegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; + your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; + } + else { + your_edegrees[k].ewgt -= adjwgt[j]; + } + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (mydomain != to) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == to) { + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + your_edegrees[myrinfo->ndegrees].edge = to; + your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + } + + /*************************************************/ + /* PASS TWO -- commit the remainder of the moves */ + /*************************************************/ + nlupd = nsupd = nmoves = nchanged = 0; + for (iii=0; iiipexadj[i+1]-graph->pexadj[i] > 0) + changed[nchanged++] = i; + } + + /* Tell interested pe's the new where[] info for the interface vertices */ + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); + + + IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", + pass, c, badmaxpwgt[0], GlobalSESum(ctrl, nmoves), GlobalSESum(ctrl, nsupd), GlobalSESum(ctrl, nlupd))); + + /*------------------------------------------------------------- + / Time to communicate with processors to send the vertices + / whose degrees need to be update. + /-------------------------------------------------------------*/ + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + + /* Issue the sends next. This needs some preporcessing */ + for (i=0; iimap[supdate[i]]; + } + iidxsort(nsupd, supdate); + + for (j=i=0; icomm, ctrl->sreq+i); + j = k; + } + + /* OK, now get into the loop waiting for the send/recv operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nupds_pe+i); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*------------------------------------------------------------- + / Place the recieved to-be updated vertices into update[] + /-------------------------------------------------------------*/ + for (i=0; idegrees; + your_edegrees = tmp_myrinfo->degrees; + + graph->lmincut -= myrinfo->ed; + myrinfo->ndegrees = 0; + myrinfo->id = 0; + myrinfo->ed = 0; + + for (j=xadj[i]; jed += adjwgt[j]; + + for (k=0; kndegrees; k++) { + if (my_edegrees[k].edge == yourdomain) { + my_edegrees[k].ewgt += adjwgt[j]; + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + my_edegrees[k].edge = yourdomain; + my_edegrees[k].ewgt = adjwgt[j]; + your_edegrees[k].edge = yourdomain; + your_edegrees[k].ewgt = adjwgt[j]; + myrinfo->ndegrees++; + } + ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + ASSERT(ctrl, tmp_myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + + } + else { + myrinfo->id += adjwgt[j]; + } + } + graph->lmincut += myrinfo->ed; + + tmp_myrinfo->id = myrinfo->id; + tmp_myrinfo->ed = myrinfo->ed; + tmp_myrinfo->ndegrees = myrinfo->ndegrees; + } + + /* finally, sum-up the partition weights */ + MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); + } + graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; + + if (graph->mincut == oldcut) + break; + } + + GKfree((void **)&badmaxpwgt, (void **)&update, (void **)&nupds_pe, (void **)&htable, LTERM); + GKfree((void **)&changed, (void **)&pperm, (void **)&perm, (void **)&moved, LTERM); + GKfree((void **)&pgnpwgts, (void **)&ognpwgts, (void **)&overfill, (void **)&movewgts, LTERM); + GKfree((void **)&tmp_where, (void **)&tmp_rinfo, (void **)&tmp_edegrees, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ametis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ametis.c new file mode 100644 index 0000000..6fac271 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ametis.c @@ -0,0 +1,272 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * ametis.c + * + * This is the entry point of parallel difussive repartitioning routines + * + * Started 10/19/96 + * George + * + * $Id: ametis.c,v 1.6 2003/07/25 04:01:03 karypis Exp $ + * + */ + +#include + + + +/*********************************************************************************** +* This function is the entry point of the parallel multilevel local diffusion +* algorithm. It uses parallel undirected diffusion followed by adaptive k-way +* refinement. This function utilizes local coarsening. +************************************************************************************/ +void ParMETIS_V3_AdaptiveRepart(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *vsize, idxtype *adjwgt, int *wgtflag, int *numflag, + int *ncon, int *nparts, float *tpwgts, float *ubvec, float *ipc2redist, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm) +{ + int h, i; + int npes, mype; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph; + int tewgt, tvsize, nmoved, maxin, maxout, vtx_factor; + float gtewgt, gtvsize, avg, maximb; + int ps_relation, seed, dbglvl = 0; + int iwgtflag, inumflag, incon, inparts, ioptions[10]; + float iipc2redist, *itpwgts, iubvec[MAXNCON]; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + /********************************/ + /* Try and take care bad inputs */ + /********************************/ + if (options != NULL && options[0] == 1) + dbglvl = options[PMV3_OPTION_DBGLVL]; + CheckInputs(ADAPTIVE_PARTITION, npes, dbglvl, wgtflag, &iwgtflag, numflag, &inumflag, + ncon, &incon, nparts, &inparts, tpwgts, &itpwgts, ubvec, iubvec, + ipc2redist, &iipc2redist, options, ioptions, part, comm); + + /* ADD: take care of disconnected graph */ + /* ADD: take care of highly unbalanced vtxdist */ + /*********************************/ + /* Take care the nparts = 1 case */ + /*********************************/ + if (inparts == 1) { + idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); + *edgecut = 0; + return; + } + + /**************************/ + /* Set up data structures */ + /**************************/ + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 1); + + /*****************************/ + /* Set up control structures */ + /*****************************/ + if (ioptions[0] == 1) { + dbglvl = ioptions[PMV3_OPTION_DBGLVL]; + seed = ioptions[PMV3_OPTION_SEED]; + ps_relation = (npes == inparts ? ioptions[PMV3_OPTION_PSR] : DISCOUPLED); + } + else { + dbglvl = GLOBAL_DBGLVL; + seed = GLOBAL_SEED; + ps_relation = (npes == inparts ? COUPLED : DISCOUPLED); + } + + SetUpCtrl(&ctrl, inparts, dbglvl, *comm); + vtx_factor = (amax(npes, inparts) > 256) ? 20 : 50; + ctrl.CoarsenTo = amin(vtxdist[npes]+1, vtx_factor*incon*amax(npes, inparts)); + ctrl.ipc_factor = iipc2redist; + ctrl.redist_factor = 1.0; + ctrl.redist_base = 1.0; + ctrl.seed = (seed == 0 ? mype : seed*mype); + ctrl.sync = GlobalSEMax(&ctrl, seed); + ctrl.partType = ADAPTIVE_PARTITION; + ctrl.ps_relation = ps_relation; + ctrl.tpwgts = itpwgts; + + graph = Moc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); + graph->vsize = (vsize == NULL ? idxsmalloc(graph->nvtxs, 1, "vsize") : vsize); + + graph->home = idxmalloc(graph->nvtxs, "home"); + if (ctrl.ps_relation == COUPLED) + idxset(graph->nvtxs, mype, graph->home); + else { + /* Downgrade the partition numbers if part[] has more partitions that nparts */ + for (i=0; invtxs; i++) + part[i] = (part[i] >= ctrl.nparts ? 0 : part[i]); + + idxcopy(graph->nvtxs, part, graph->home); + } + + tewgt = idxsum(graph->nedges, graph->adjwgt); + tvsize = idxsum(graph->nvtxs, graph->vsize); + gtewgt = (float) GlobalSESum(&ctrl, tewgt) + 1.0/graph->gnvtxs; /* The +1/graph->gnvtxs were added to remove any FPE */ + gtvsize = (float) GlobalSESum(&ctrl, tvsize) + 1.0/graph->gnvtxs; + ctrl.edge_size_ratio = gtewgt/gtvsize; + scopy(incon, iubvec, ctrl.ubvec); + + PreAllocateMemory(&ctrl, graph, &wspace); + + /***********************/ + /* Partition and Remap */ + /***********************/ + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + Adaptive_Partition(&ctrl, graph, &wspace); + ParallelReMapGraph(&ctrl, graph, &wspace); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + + idxcopy(graph->nvtxs, graph->where, part); + if (edgecut != NULL) + *edgecut = graph->mincut; + + /***********************/ + /* Take care of output */ + /***********************/ + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + + if (ctrl.dbglvl&DBG_INFO) { + Mc_ComputeMoveStatistics(&ctrl, graph, &nmoved, &maxin, &maxout); + rprintf(&ctrl, "Final %3d-way Cut: %6d \tBalance: ", inparts, graph->mincut); + avg = 0.0; + for (h=0; hgnpwgts[i*incon+h]/itpwgts[i*incon+h]); + avg += maximb; + rprintf(&ctrl, "%.3f ", maximb); + } + rprintf(&ctrl, "\nNMoved: %d %d %d %d\n", nmoved, maxin, maxout, maxin+maxout); + } + + /*************************************/ + /* Free memory, renumber, and return */ + /*************************************/ + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, (void **)(&graph->home), LTERM); + if (vsize == NULL) + GKfree((void **)(&graph->vsize), LTERM); + GKfree((void **)&itpwgts, LTERM); + FreeInitialGraphAndRemap(graph, iwgtflag); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 0); + + return; +} + + + + +/************************************************************************* +* This function is the driver for the adaptive refinement mode of ParMETIS +**************************************************************************/ +void Adaptive_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i; + int tewgt, tvsize; + float gtewgt, gtvsize; + float ubavg, lbavg, lbvec[MAXNCON]; + + /************************************/ + /* Set up important data structures */ + /************************************/ + SetUp(ctrl, graph, wspace); + + ubavg = savg(graph->ncon, ctrl->ubvec); + tewgt = idxsum(graph->nedges, graph->adjwgt); + tvsize = idxsum(graph->nvtxs, graph->vsize); + gtewgt = (float) GlobalSESum(ctrl, tewgt) + 1.0/graph->gnvtxs; /* The +1/graph->gnvtxs were added to remove any FPE */ + gtvsize = (float) GlobalSESum(ctrl, tvsize) + 1.0/graph->gnvtxs; + ctrl->redist_factor = ctrl->redist_base * ((gtewgt/gtvsize)/ ctrl->edge_size_ratio); + + IFSET(ctrl->dbglvl, DBG_PROGRESS, rprintf(ctrl, "[%6d %8d %5d %5d][%d]\n", + graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo)); + + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || + (graph->finer != NULL && graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + + /***********************************************/ + /* Balance the partition on the coarsest graph */ + /***********************************************/ + graph->where = idxsmalloc(graph->nvtxs+graph->nrecv, -1, "graph->where"); + idxcopy(graph->nvtxs, graph->home, graph->where); + + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) + Balance_Partition(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + /* check if no coarsening took place */ + if (graph->finer == NULL) { + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + } + } + else { + /*******************************/ + /* Coarsen it and partition it */ + /*******************************/ + switch (ctrl->ps_relation) { + case COUPLED: + Mc_LocalMatch_HEM(ctrl, graph, wspace); + break; + case DISCOUPLED: + default: + Moc_GlobalMatch_Balance(ctrl, graph, wspace); + break; + } + + Adaptive_Partition(ctrl, graph->coarser, wspace); + + /********************************/ + /* project partition and refine */ + /********************************/ + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); + + if (graph->ncon > 1 && graph->level < 4) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.025) { + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + } + } + + Moc_KWayAdaptiveRefine(ctrl, graph, wspace, NGR_PASSES); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + } +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/backcompat.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/backcompat.c new file mode 100644 index 0000000..b62d4bb --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/backcompat.c @@ -0,0 +1,517 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * backcompat.c + * + * This file ensures backwards compatability with previous ParMETIS releases + * + * Started 10/19/96 + * George + * + * $Id: backcompat.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + * + */ + +#include + +/***************************************************************************** +* This function computes a partitioning. +*****************************************************************************/ +void ParMETIS_PartKway(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm) +{ + int i; + int ncon = 1; + float *tpwgts, ubvec[MAXNCON]; + int myoptions[10]; + + tpwgts = fmalloc(*nparts*ncon, "tpwgts"); + for (i=0; i<*nparts*ncon; i++) + tpwgts[i] = 1.0/(float)(*nparts); + for (i=0; i +#define PE 0 + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +int BalanceMyLink(CtrlType *ctrl, GraphType *graph, idxtype *home, int me, + int you, float *flows, float maxdiff, float *diff_cost, float *diff_lbavg, + float avgvwgt) +{ + int h, i, ii, j, k; + int nvtxs, ncon; + int nqueues, minval, maxval, higain, vtx, edge, totalv; + int from, to, qnum, index, nchanges, cut, tmp; + int pass, nswaps, nmoves, multiplier; + idxtype *xadj, *vsize, *adjncy, *adjwgt, *where, *ed, *id; + idxtype *hval, *nvpq, *inq, *map, *rmap, *ptr, *myqueue, *changes; + float *nvwgt, lbvec[MAXNCON], pwgts[MAXNCON*2], tpwgts[MAXNCON*2], my_wgt[MAXNCON]; + float newgain, oldgain = 0.0; + float lbavg, bestflow, mycost; + float ipc_factor, redist_factor, ftmp; + FPQueueType *queues; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + ipc_factor = ctrl->ipc_factor; + redist_factor = ctrl->redist_factor; + + hval = idxmalloc(nvtxs*7, "hval"); + id = hval + nvtxs; + ed = hval + nvtxs*2; + map = hval + nvtxs*3; + rmap = hval + nvtxs*4; + myqueue = hval + nvtxs*5; + changes = hval + nvtxs*6; + + sset(ncon*2, 0.0, pwgts); + for (h=0; h0; i--) + ptr[i] = ptr[i-1]; + ptr[0] = 0; + + /* initialize queues */ + for (i=0; i 0) { + FPQueueInit(queues+i, nvpq[i]); + FPQueueInit(queues+i+nqueues, nvpq[i]); + } + + /* compute internal/external degrees */ + idxset(nvtxs, 0, id); + idxset(nvtxs, 0, ed); + for (j=0; j fabs(flows[j])) j = h; + bestflow = fabs(flows[j]); + + nchanges = nmoves = 0; + for (ii=0; ii avgvwgt) + break; + } + else { + for (j=0; j fabs(flows[j])) j = h; + ftmp = fabs(flows[j]); + + if (ftmp < bestflow) { + bestflow = ftmp; + nchanges = 0; + } + else { + changes[nchanges++] = vtx; + } + + SWAP(id[vtx], ed[vtx], tmp); + + for (j=xadj[vtx]; j 0) { + FPQueueReset(queues+i); + FPQueueReset(queues+i+nqueues); + } + } + + if (nmoves == 0) + break; + } + + /***************************/ + /* compute 2-way imbalance */ + /***************************/ + sset(ncon, 0.0, my_wgt); + for (i=0; i 0) { + FPQueueFree(queues+i); + FPQueueFree(queues+i+nqueues); + } + + GKfree((void **)&hval, (void **)&nvpq, (void **)&ptr, (void **)&inq, (void **)&queues, LTERM); + return nswaps; +} + 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); + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/comm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/comm.c new file mode 100644 index 0000000..fb18789 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/comm.c @@ -0,0 +1,213 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * comm.c + * + * This function provides various high level communication functions + * + * $Id: comm.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + */ + +#include + + + +/************************************************************************* +* This function performs the gather/scatter for the boundary vertices +**************************************************************************/ +void CommInterfaceData(CtrlType *ctrl, GraphType *graph, idxtype *data, + idxtype *sendvector, idxtype *recvvector) +{ + int i, k, nnbrs, firstvtx; + idxtype *peind, *sendptr, *sendind, *recvptr, *recvind; + + firstvtx = graph->vtxdist[ctrl->mype]; + nnbrs = graph->nnbrs; + peind = graph->peind; + sendptr = graph->sendptr; + sendind = graph->sendind; + recvptr = graph->recvptr; + recvind = graph->recvind; + + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next */ + k = sendptr[nnbrs]; + for (i=0; icomm, ctrl->sreq+i); + } + + /* OK, now get into the loop waiting for the operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + +} + + + +/************************************************************************* +* This function performs the gather/scatter for the boundary vertices +**************************************************************************/ +void CommChangedInterfaceData(CtrlType *ctrl, GraphType *graph, + int nchanged, idxtype *changed, idxtype *data, + KeyValueType *sendpairs, KeyValueType *recvpairs, idxtype *psendptr) +{ + int i, j, k, n, penum, nnbrs, firstvtx, nrecv; + idxtype *peind, *sendptr, *recvptr, *recvind, *pexadj, *peadjncy, *peadjloc; + KeyValueType *pairs; + + firstvtx = graph->vtxdist[ctrl->mype]; + nnbrs = graph->nnbrs; + nrecv = graph->nrecv; + peind = graph->peind; + sendptr = graph->sendptr; + recvptr = graph->recvptr; + recvind = graph->recvind; + pexadj = graph->pexadj; + peadjncy = graph->peadjncy; + peadjloc = graph->peadjloc; + + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + } + + if (nchanged != 0) { + idxcopy(ctrl->npes, sendptr, psendptr); + + /* Copy the changed values into the sendvector */ + for (i=0; icomm, ctrl->sreq+i); + } + } + else { + for (i=0; icomm, ctrl->sreq+i); + } + + /* OK, now get into the loop waiting for the operations to finish */ + for (i=0; irreq+i, &(ctrl->status)); + MPI_Get_count(&ctrl->status, IDX_DATATYPE, &n); + if (n != 0) { + n = n/2; + pairs = recvpairs+graph->recvptr[i]; + for (k=0; ksreq, ctrl->statuses); +} + + + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +int GlobalSEMax(CtrlType *ctrl, int value) +{ + int max; + + MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_INT, MPI_MAX, ctrl->comm); + + return max; +} + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +double GlobalSEMaxDouble(CtrlType *ctrl, double value) +{ + double max; + + MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_DOUBLE, MPI_MAX, ctrl->comm); + + return max; +} + + + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +int GlobalSEMin(CtrlType *ctrl, int value) +{ + int min; + + MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_INT, MPI_MIN, ctrl->comm); + + return min; +} + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +int GlobalSESum(CtrlType *ctrl, int value) +{ + int sum; + + MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_INT, MPI_SUM, ctrl->comm); + + return sum; +} + + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +float GlobalSEMaxFloat(CtrlType *ctrl, float value) +{ + float max; + + MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_FLOAT, MPI_MAX, ctrl->comm); + + return max; +} + + + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +float GlobalSEMinFloat(CtrlType *ctrl, float value) +{ + float min; + + MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_FLOAT, MPI_MIN, ctrl->comm); + + return min; +} + +/************************************************************************* +* This function computes the max of a single element +**************************************************************************/ +float GlobalSESumFloat(CtrlType *ctrl, float value) +{ + float sum; + + MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_FLOAT, MPI_SUM, ctrl->comm); + + return sum; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/csrmatch.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/csrmatch.c new file mode 100644 index 0000000..ace7998 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/csrmatch.c @@ -0,0 +1,88 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * csrmatch.c + * + * This file contains the code that computes matchings + * + * Started 7/23/97 + * George + * + * $Id: csrmatch.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + * + */ + +#include + + + + +/************************************************************************* +* This function finds a matching using the HEM heuristic +**************************************************************************/ +void CSR_Match_SHEM(MatrixType *matrix, idxtype *match, idxtype *mlist, + idxtype *skip, int ncon) +{ + int h, i, ii, j; + int nrows, edge, maxidx, count; + float maxwgt; + idxtype *rowptr, *colind; + float *transfer; + KVType *links; + + nrows = matrix->nrows; + rowptr = matrix->rowptr; + colind = matrix->colind; + transfer = matrix->transfer; + + idxset(nrows, UNMATCHED, match); + + links = (KVType *)GKmalloc(sizeof(KVType)*nrows, "links"); + for (i=0; i + + +/************************************************************************* +* This function prints a vector stored in each processor +**************************************************************************/ +void PrintVector(CtrlType *ctrl, int n, int first, idxtype *vec, char *title) +{ + int i, penum; + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + if (ctrl->mype == 0) + printf("%s\n", title); + printf("\t%3d. ", ctrl->mype); + for (i=0; icomm); + } +} + + +/************************************************************************* +* This function prints a vector stored in each processor +**************************************************************************/ +void PrintVector2(CtrlType *ctrl, int n, int first, idxtype *vec, char *title) +{ + int i, penum; + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + if (ctrl->mype == 0) + printf("%s\n", title); + printf("\t%3d. ", ctrl->mype); + for (i=0; i=KEEP_BIT ? 1 : 0), (vec[i]>=KEEP_BIT ? vec[i]-KEEP_BIT : vec[i])); + printf("\n"); + fflush(stdout); + } + MPI_Barrier(ctrl->comm); + } +} + + +/************************************************************************* +* This function prints a vector stored in each processor +**************************************************************************/ +void PrintPairs(CtrlType *ctrl, int n, KeyValueType *pairs, char *title) +{ + int i, penum; + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + if (ctrl->mype == 0) + printf("%s\n", title); + printf("\t%3d. ", ctrl->mype); + for (i=0; icomm); + } +} + + + +/************************************************************************* +* This function prints the local portion of the graph stored at each +* processor +**************************************************************************/ +void PrintGraph(CtrlType *ctrl, GraphType *graph) +{ + int i, j, penum; + int firstvtx; + + MPI_Barrier(ctrl->comm); + + firstvtx = graph->vtxdist[ctrl->mype]; + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + printf("\t%d", penum); + for (i=0; invtxs; i++) { + if (i==0) + printf("\t%2d %2d\t", firstvtx+i, graph->vwgt[i]); + else + printf("\t\t%2d %2d\t", firstvtx+i, graph->vwgt[i]); + for (j=graph->xadj[i]; jxadj[i+1]; j++) + printf("[%d %d] ", graph->adjncy[j], graph->adjwgt[j]); + printf("\n"); + } + fflush(stdout); + } + MPI_Barrier(ctrl->comm); + } +} + + +/************************************************************************* +* This function prints the local portion of the graph stored at each +* processor along with degree information during refinement +**************************************************************************/ +void PrintGraph2(CtrlType *ctrl, GraphType *graph) +{ + int i, j, penum; + int firstvtx; + + MPI_Barrier(ctrl->comm); + + firstvtx = graph->vtxdist[ctrl->mype]; + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + printf("\t%d", penum); + for (i=0; invtxs; i++) { + if (i==0) + printf("\t%2d %2d [%d %d %d]\t", firstvtx+i, graph->vwgt[i], graph->where[i], graph->rinfo[i].id, graph->rinfo[i].ed); + else + printf("\t\t%2d %2d [%d %d %d]\t", firstvtx+i, graph->vwgt[i], graph->where[i], graph->rinfo[i].id, graph->rinfo[i].ed); + for (j=graph->xadj[i]; jxadj[i+1]; j++) + printf("[%d %d] ", graph->adjncy[j], graph->adjwgt[j]); + printf("\n"); + } + fflush(stdout); + } + MPI_Barrier(ctrl->comm); + } +} + + +/************************************************************************* +* This function prints the information computed during setup +**************************************************************************/ +void PrintSetUpInfo(CtrlType *ctrl, GraphType *graph) +{ + int i, j, penum; + + MPI_Barrier(ctrl->comm); + + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + printf("PE: %d, nnbrs: %d\n", ctrl->mype, graph->nnbrs); + printf("\tSending...\n"); + for (i=0; innbrs; i++) { + printf("\t\tTo: %d: ", graph->peind[i]); + for (j=graph->sendptr[i]; jsendptr[i+1]; j++) + printf("%d ", graph->sendind[j]); + printf("\n"); + } + printf("\tReceiving...\n"); + for (i=0; innbrs; i++) { + printf("\t\tFrom: %d: ", graph->peind[i]); + for (j=graph->recvptr[i]; jrecvptr[i+1]; j++) + printf("%d ", graph->recvind[j]); + printf("\n"); + } + printf("\n"); + } + MPI_Barrier(ctrl->comm); + } + +} + + +/************************************************************************* +* This function prints information about the graphs that were sent/received +**************************************************************************/ +void PrintTransferedGraphs(CtrlType *ctrl, int nnbrs, idxtype *peind, idxtype *slens, + idxtype *rlens, idxtype *sgraph, idxtype *rgraph) +{ + int i, ii, jj, ll, penum; + + MPI_Barrier(ctrl->comm); + for (penum=0; penumnpes; penum++) { + if (ctrl->mype == penum) { + printf("PE: %d, nnbrs: %d", ctrl->mype, nnbrs); + for (ll=i=0; i 0) { + printf("\n\tTo %d\t", peind[i]); + for (ii=slens[i]; ii 0) { + printf("\n\tFrom %d\t", peind[i]); + for (ii=rlens[i]; iicomm); + } + +} + + +/************************************************************************* +* This function writes a graph in the format used by serial METIS +**************************************************************************/ +void WriteMetisGraph(int nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt) +{ + int i, j; + FILE *fp; + + fp = fopen("test.graph", "w"); + + fprintf(fp, "%d %d 11", nvtxs, xadj[nvtxs]/2); + for (i=0; i + + +/************************************************************************* +* This function computes the load for each subdomain +**************************************************************************/ +void SetUpConnectGraph(GraphType *graph, MatrixType *matrix, idxtype *workspace) +{ + int i, ii, j, jj, k, l; + int nvtxs, nrows; + idxtype *xadj, *adjncy, *where; + idxtype *rowptr, *colind; + idxtype *pcounts, *perm, *marker; + float *values; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + where = graph->where; + + nrows = matrix->nrows; + rowptr = matrix->rowptr; + colind = matrix->colind; + values = matrix->values; + + perm = workspace; + marker = idxset(nrows, -1, workspace+nvtxs); + pcounts = idxset(nrows+1, 0, workspace+nvtxs+nrows); + + for (i=0; i0; i--) + pcounts[i] = pcounts[i-1]; + pcounts[0] = 0; + + /************************/ + /* Construct the matrix */ + /************************/ + rowptr[0] = k = 0; + for (ii=0; iinnzs = rowptr[nrows]; + + return; +} + + +/************************************************************************* +* This function computes movement statistics for adaptive refinement +* schemes +**************************************************************************/ +void Mc_ComputeMoveStatistics(CtrlType *ctrl, GraphType *graph, int *nmoved, int *maxin, int *maxout) +{ + int i, nvtxs, nparts, myhome; + idxtype *vwgt, *where; + idxtype *lend, *gend, *lleft, *gleft, *lstart, *gstart; + + nvtxs = graph->nvtxs; + vwgt = graph->vwgt; + where = graph->where; + nparts = ctrl->nparts; + + lstart = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lstart"); + gstart = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gstart"); + lleft = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lleft"); + gleft = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gleft"); + lend = idxsmalloc(nparts, 0, "ComputeMoveStatistics: lend"); + gend = idxsmalloc(nparts, 0, "ComputeMoveStatistics: gend"); + + for (i=0; ips_relation == COUPLED) ? ctrl->mype : graph->home[i]; + lstart[myhome] += (graph->vsize == NULL) ? 1 : graph->vsize[i]; + lend[where[i]] += (graph->vsize == NULL) ? 1 : graph->vsize[i]; + if (where[i] != myhome) + lleft[myhome] += (graph->vsize == NULL) ? 1 : graph->vsize[i]; + } + + /* PrintVector(ctrl, ctrl->npes, 0, lend, "Lend: "); */ + + MPI_Allreduce((void *)lstart, (void *)gstart, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + MPI_Allreduce((void *)lleft, (void *)gleft, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + MPI_Allreduce((void *)lend, (void *)gend, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + + *nmoved = idxsum(nparts, gleft); + *maxout = gleft[idxamax(nparts, gleft)]; + for (i=0; invtxs; i++) { + if (graph->where[i] != home[i]) + totalv += (graph->vsize == NULL) ? graph->vwgt[i*graph->ncon] : graph->vsize[i]; + } + + return totalv; +} + + + +/************************************************************************* +* This function computes the load for each subdomain +**************************************************************************/ +void ComputeLoad(GraphType *graph, int nparts, float *load, float *tpwgts, int index) +{ + int i; + int nvtxs, ncon; + idxtype *where; + float *nvwgt; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + where = graph->where; + nvwgt = graph->nvwgt; + + sset(nparts, 0.0, load); + + for (i=0; inrows; + rowptr = A->rowptr; + colind = A->colind; + values = A->values; + + /* Initial Setup */ + p = workspace; + r = workspace + n; + q = workspace + 2*n; + z = workspace + 3*n; + M = workspace + 4*n; + + for (i=0; i 0.0) { + error = snorm2(n, r) / bnrm2; + + if (error > tol) { + /* Begin Iterations */ + for (k=0; knrows; i++) + w[i] = 0.0; + + for (i = 0; i < A->nrows; i++) + for (j = A->rowptr[i]; j < A->rowptr[i+1]; j++) + w[i] += A->values[j] * v[A->colind[j]]; + + return; + } + + +/************************************************************************* +* This function sets up the transfer vectors +**************************************************************************/ +void ComputeTransferVector(int ncon, MatrixType *matrix, float *solution, + float *transfer, int index) +{ + int j, k; + int nrows; + idxtype *rowptr, *colind; + + nrows = matrix->nrows; + rowptr = matrix->rowptr; + colind = matrix->colind; + + for (j=0; j solution[colind[k]]) { + transfer[k*ncon+index] = solution[j] - solution[colind[k]]; + } + else { + transfer[k*ncon+index] = 0.0; + } + } + } +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/fpqueue.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/fpqueue.c new file mode 100644 index 0000000..11c617f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/fpqueue.c @@ -0,0 +1,440 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * fpqueue.c + * + * This file contains functions for manipulating the bucket list + * representation of the gains associated with each vertex in a graph. + * These functions are used by the refinement algorithms + * + * Started 9/2/94 + * George + * + * $Id: fpqueue.c,v 1.2 2003/07/21 17:18:48 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function initializes the data structures of the priority queue +**************************************************************************/ +void FPQueueInit(FPQueueType *queue, int maxnodes) +{ + queue->nnodes = 0; + queue->maxnodes = maxnodes; + queue->heap = NULL; + queue->locator = NULL; + + queue->heap = (FKeyValueType *) malloc(sizeof(FKeyValueType)*maxnodes); + queue->locator = (idxtype *) malloc(sizeof(idxtype)*maxnodes); + + idxset(maxnodes, -1, queue->locator); + +} + + +/************************************************************************* +* This function resets the buckets +**************************************************************************/ +void FPQueueReset(FPQueueType *queue) +{ + queue->nnodes = 0; + + idxset(queue->maxnodes, -1, queue->locator); + +} + + +/************************************************************************* +* This function frees the buckets +**************************************************************************/ +void FPQueueFree(FPQueueType *queue) +{ + + free(queue->heap); + free(queue->locator); + + queue->maxnodes = 0; +} + + +/************************************************************************* +* This function returns the number of nodes in the queue +**************************************************************************/ +int FPQueueGetSize(FPQueueType *queue) +{ + return queue->nnodes; +} + + +/************************************************************************* +* This function adds a node of certain gain into a partition +**************************************************************************/ +int FPQueueInsert(FPQueueType *queue, int node, float gain) +{ + int i, j; + idxtype *locator; + FKeyValueType *heap; + + ASSERTS(CheckHeapFloat(queue)); + + heap = queue->heap; + locator = queue->locator; + + ASSERTS(locator[node] == -1); + + i = queue->nnodes++; + while (i > 0) { + j = (i-1)/2; + if (heap[j].key < gain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + ASSERTS(i >= 0); + heap[i].key = gain; + heap[i].val = node; + locator[node] = i; + + ASSERTS(CheckHeapFloat(queue)); + + return 0; +} + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +int FPQueueDelete(FPQueueType *queue, int node) +{ + int i, j; + float newgain, oldgain; + idxtype *locator; + FKeyValueType *heap; + + heap = queue->heap; + locator = queue->locator; + + ASSERTS(locator[node] != -1); + ASSERTS(heap[locator[node]].val == node); + + ASSERTS(CheckHeapFloat(queue)); + + i = locator[node]; + locator[node] = -1; + + if (--queue->nnodes > 0 && heap[queue->nnodes].val != node) { + node = heap[queue->nnodes].val; + newgain = heap[queue->nnodes].key; + oldgain = heap[i].key; + + if (oldgain < newgain) { + /* Filter-up */ + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + else { + /* Filter down */ + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > newgain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + } + + ASSERTS(CheckHeapFloat(queue)); + + return 0; +} + + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +int FPQueueUpdate(FPQueueType *queue, int node, float oldgain, float newgain) +{ + int i, j; + idxtype *locator; + FKeyValueType *heap; + + if (oldgain == newgain) + return 0; + + heap = queue->heap; + locator = queue->locator; + + ASSERTS(locator[node] != -1); + ASSERTS(heap[locator[node]].val == node); + ASSERTS(fabs(heap[locator[node]].key - oldgain) < SMALLFLOAT); + ASSERTS(CheckHeapFloat(queue)); + + i = locator[node]; + + if (oldgain < newgain) { + /* Filter-up */ + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + else { + /* Filter down */ + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > newgain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > newgain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + + ASSERTS(CheckHeapFloat(queue)); + + return 0; +} + + + +/************************************************************************* +* This function deletes a node from a partition and reinserts it with +* an updated gain +**************************************************************************/ +void FPQueueUpdateUp(FPQueueType *queue, int node, float oldgain, float newgain) +{ + int i, j; + idxtype *locator; + FKeyValueType *heap; + + if (oldgain == newgain) + return; + + heap = queue->heap; + locator = queue->locator; + + ASSERTS(locator[node] != -1); + ASSERTS(heap[locator[node]].val == node); + ASSERTS(heap[locator[node]].key == oldgain); + ASSERTS(CheckHeapFloat(queue)); + + + /* Here we are just filtering up since the newgain is greater than the oldgain */ + i = locator[node]; + while (i > 0) { + j = (i-1)>>1; + if (heap[j].key < newgain) { + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + + heap[i].key = newgain; + heap[i].val = node; + locator[node] = i; + + ASSERTS(CheckHeapFloat(queue)); + +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +* and removes the node from the bucket list +**************************************************************************/ +int FPQueueGetMax(FPQueueType *queue) +{ + int vtx, i, j, node; + float gain; + idxtype *locator; + FKeyValueType *heap; + + if (queue->nnodes == 0) + return -1; + + queue->nnodes--; + + heap = queue->heap; + locator = queue->locator; + + vtx = heap[0].val; + locator[vtx] = -1; + + if ((i = queue->nnodes) > 0) { + gain = heap[i].key; + node = heap[i].val; + i = 0; + while ((j=2*i+1) < queue->nnodes) { + if (heap[j].key > gain) { + if (j+1 < queue->nnodes && heap[j+1].key > heap[j].key) + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else if (j+1 < queue->nnodes && heap[j+1].key > gain) { + j = j+1; + heap[i] = heap[j]; + locator[heap[i].val] = i; + i = j; + } + else + break; + } + + heap[i].key = gain; + heap[i].val = node; + locator[node] = i; + } + + ASSERTS(CheckHeapFloat(queue)); + return vtx; +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +**************************************************************************/ +int FPQueueSeeMaxVtx(FPQueueType *queue) +{ + int vtx; + + if (queue->nnodes == 0) + return -1; + + vtx = queue->heap[0].val; + + return vtx; +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +**************************************************************************/ +float FPQueueSeeMaxGain(FPQueueType *queue) +{ + float gain; + + if (queue->nnodes == 0) + return 0.0; + + gain = queue->heap[0].key; + + return gain; +} + + +/************************************************************************* +* This function returns the vertex with the largest gain from a partition +**************************************************************************/ +float FPQueueGetKey(FPQueueType *queue) +{ + int key; + + if (queue->nnodes == 0) + return -1; + + key = queue->heap[0].key; + + return key; +} + +/************************************************************************* +* This function returns the number of nodes in the queue +**************************************************************************/ +int FPQueueGetQSize(FPQueueType *queue) +{ + return queue->nnodes; +} + + + + + + +/************************************************************************* +* This functions checks the consistency of the heap +**************************************************************************/ +int CheckHeapFloat(FPQueueType *queue) +{ + int i, j, nnodes; + idxtype *locator; + FKeyValueType *heap; + + heap = queue->heap; + locator = queue->locator; + nnodes = queue->nnodes; + + if (nnodes == 0) + return 1; + + ASSERTS(locator[heap[0].val] == 0); + for (i=1; imaxnodes; i++) { + if (locator[i] != -1) + j++; + } + ASSERTS(j == nnodes); + + return 1; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/frename.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/frename.c new file mode 100644 index 0000000..551dd59 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/frename.c @@ -0,0 +1,322 @@ +/* + * frename.c + * + * This file contains some renaming routines to deal with different + * Fortran compilers. + * + * Started 6/1/98 + * George + * + * $Id: frename.c,v 1.4 2003/07/30 18:37:58 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* Renaming macro (at least to save some typing :)) +**************************************************************************/ +#define FRENAME(name0, name1, name2, name3, name4, dargs, cargs) \ + void name1 dargs { name0 cargs; } \ + void name2 dargs { name0 cargs; } \ + void name3 dargs { name0 cargs; } \ + void name4 dargs { name0 cargs; } + + + + + + + + +/************************************************************************* +* Renames for Release 3.0 API +**************************************************************************/ +FRENAME(ParMETIS_V3_AdaptiveRepart, + PARMETIS_V3_ADAPTIVEREPART, + parmetis_v3_adaptiverepart, + parmetis_v3_adaptiverepart_, + parmetis_v3_adaptiverepart__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *vsize, idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, + int *nparts, float *tpwgts, float *ubvec, float *ipc2redist, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, vsize, adjwgt, wgtflag, numflag, ncon, + nparts, tpwgts, ubvec, ipc2redist, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_V3_PartGeomKway, + PARMETIS_V3_PARTGEOMKWAY, + parmetis_v3_partgeomkway, + parmetis_v3_partgeomkway_, + parmetis_v3_partgeomkway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, float *xyz, + int *ncon, int *nparts, float *tpwgts, float *ubvec, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ndims, xyz, + ncon, nparts, tpwgts, ubvec, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_V3_PartGeom, + PARMETIS_V3_PARTGEOM, + parmetis_v3_partgeom, + parmetis_v3_partgeom_, + parmetis_v3_partgeom__, + (idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm), + (vtxdist, ndims, xyz, part, comm) +) + +FRENAME(ParMETIS_V3_PartKway, + PARMETIS_V3_PARTKWAY, + parmetis_v3_partkway, + parmetis_v3_partkway_, + parmetis_v3_partkway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ncon, int *nparts, float *tpwgts, float *ubvec, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ncon, nparts, tpwgts, + ubvec, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_V3_Mesh2Dual, + PARMETIS_V3_MESH2DUAL, + parmetis_v3_mesh2dual, + parmetis_v3_mesh2dual_, + parmetis_v3_mesh2dual__, + (idxtype *elmdist, idxtype *eptr, idxtype *eind, int *numflag, int *ncommonnodes, + idxtype **xadj, idxtype **adjncy, MPI_Comm *comm), + (elmdist, eptr, eind, numflag, ncommonnodes, xadj, adjncy, comm) +) + +FRENAME(ParMETIS_V3_PartMeshKway, + PARMETIS_V3_PARTMESHKWAY, + parmetis_v3_partmeshkway, + parmetis_v3_partmeshkway_, + parmetis_v3_partmeshkway__, + (idxtype *elmdist, idxtype *eptr, idxtype *eind, idxtype *elmwgt, int *wgtflag, + int *numflag, int *ncon, int *ncommonnodes, int *nparts, float *tpwgts, + float *ubvec, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (elmdist, eptr, eind, elmwgt, wgtflag, numflag, ncon, ncommonnodes, nparts, tpwgts, + ubvec, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_V3_NodeND, + PARMETIS_V3_NODEND, + parmetis_v3_nodend, + parmetis_v3_nodend_, + parmetis_v3_nodend__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm), + (vtxdist, xadj, adjncy, numflag, options, order, sizes, comm) +) + +FRENAME(ParMETIS_V3_RefineKway, + PARMETIS_V3_REFINEKWAY, + parmetis_v3_refinekway, + parmetis_v3_refinekway_, + parmetis_v3_refinekway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ncon, int *nparts, float *tpwgts, float *ubvec, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ncon, nparts, tpwgts, + ubvec, options, edgecut, part, comm) +) + + +/************************************************************************* +* Renames for Release 2.0 API +**************************************************************************/ +FRENAME(ParMETIS_PartKway, + PARMETIS_PARTKWAY, + parmetis_partkway, + parmetis_partkway_, + parmetis_partkway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *nparts, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, nparts, options, edgecut, + part, comm) +) + +FRENAME(ParMETIS_PartGeomKway, + PARMETIS_PARTGEOMKWAY, + parmetis_partgeomkway, + parmetis_partgeomkway_, + parmetis_partgeomkway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ndims, float *xyz, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ndims, xyz, nparts, options, + edgecut, part, comm) +) + +FRENAME(ParMETIS_PartGeom, + PARMETIS_PARTGEOM, + parmetis_partgeom, + parmetis_partgeom_, + parmetis_partgeom__, + (idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm), + (vtxdist, ndims, xyz, part, comm) +) + +FRENAME(ParMETIS_PartGeomRefine, + PARMETIS_PARTGEOMREFINE, + parmetis_partgeomrefine, + parmetis_partgeomrefine_, + parmetis_partgeomrefine__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ndims, float *xyz, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, ndims, xyz, options, + edgecut, part, comm) +) + +FRENAME(ParMETIS_RefineKway, + PARMETIS_REFINEKWAY, + parmetis_refinekway, + parmetis_refinekway_, + parmetis_refinekway__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_RepartLDiffusion, + PARMETIS_REPARTLDIFUSSION, + parmetis_repartldiffusion, + parmetis_repartldiffusion_, + parmetis_repartldiffusion__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_RepartGDiffusion, + PARMETIS_REPARTGDIFFUSION, + parmetis_repartgdiffusion, + parmetis_repartgdiffusion_, + parmetis_repartgdiffusion__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_RepartRemap, + PARMETIS_REPARTREMAP, + parmetis_repartremap, + parmetis_repartremap_, + parmetis_repartremap__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_RepartMLRemap, + PARMETIS_REPARTMLREMAP, + parmetis_repartmlremap, + parmetis_repartmlremap_, + parmetis_repartmlremap__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, MPI_Comm *comm), + (vtxdist, xadj, adjncy, vwgt, adjwgt, wgtflag, numflag, options, edgecut, part, comm) +) + +FRENAME(ParMETIS_NodeND, + PARMETIS_NODEND, + parmetis_nodend, + parmetis_nodend_, + parmetis_nodend__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm), + (vtxdist, xadj, adjncy, numflag, options, order, sizes, comm) +) + +FRENAME(ParMETIS_SerialNodeND, + PARMETIS_SERIALNODEND, + parmetis_serialnodend, + parmetis_serialnodend_, + parmetis_serialnodend__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm), + (vtxdist, xadj, adjncy, numflag, options, order, sizes, comm) +) + + + + +/************************************************************************* +* Renames for Release 1.0 API +**************************************************************************/ +FRENAME(PARKMETIS, + PARKMETIS_, + parkmetis, + parkmetis_, + parkmetis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, part, options, comm) +) + +FRENAME(PARGKMETIS, + PARGKMETIS_, + pargkmetis, + pargkmetis_, + pargkmetis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, ndims, xyz, part, options, comm) +) + +FRENAME(PARGRMETIS, + PARGRMETIS_, + pargrmetis, + pargrmetis_, + pargrmetis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, ndims, xyz, part, options, comm) +) + +FRENAME(PARGMETIS, + PARGMETIS_, + pargmetis, + pargmetis_, + pargmetis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int ndims, float *xyz, + idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, adjncy, ndims, xyz, part, options, comm) +) + +FRENAME(PARRMETIS, + PARRMETIS_, + parrmetis, + parrmetis_, + parrmetis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, part, options, comm) +) + +FRENAME(PARUAMETIS, + PARUAMETIS_, + paruametis, + paruametis_, + paruametis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, part, options, comm) +) + +FRENAME(PARDAMETIS, + PARDAMETIS_, + pardametis, + pardametis_, + pardametis__, + (idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm), + (vtxdist, xadj, vwgt, adjncy, adjwgt, part, options, comm) +) + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/gkmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/gkmetis.c new file mode 100644 index 0000000..8eb2382 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/gkmetis.c @@ -0,0 +1,331 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * gkmetis.c + * + * This is the entry point of parallel geometry based partitioning + * routines + * + * Started 10/19/96 + * George + * + * $Id: gkmetis.c,v 1.8 2003/07/31 16:23:30 karypis Exp $ + * + */ + +#include + + + + +/*********************************************************************************** +* This function is the entry point of the parallel kmetis algorithm that uses +* coordinates to compute an initial graph distribution. +************************************************************************************/ +void ParMETIS_V3_PartGeomKway(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, + float *xyz, int *ncon, int *nparts, float *tpwgts, float *ubvec, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm) +{ + int h, i, j; + int nvtxs = -1, npes, mype; + int uwgtflag, cut, gcut, maxnvtxs; + int ltvwgts[MAXNCON]; + int moptions[10]; + CtrlType ctrl; + idxtype *uvwgt; + WorkSpaceType wspace; + GraphType *graph, *mgraph; + float avg, maximb, balance, *mytpwgts; + int seed, dbglvl = 0; + int iwgtflag, inumflag, incon, inparts, ioptions[10]; + float *itpwgts, iubvec[MAXNCON]; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + /********************************/ + /* Try and take care bad inputs */ + /********************************/ + if (options != NULL && options[0] == 1) + dbglvl = options[PMV3_OPTION_DBGLVL]; + + CheckInputs(STATIC_PARTITION, npes, dbglvl, wgtflag, &iwgtflag, numflag, &inumflag, + ncon, &incon, nparts, &inparts, tpwgts, &itpwgts, ubvec, iubvec, + NULL, NULL, options, ioptions, part, comm); + + + /*********************************/ + /* Take care the nparts = 1 case */ + /*********************************/ + if (inparts <= 1) { + idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); + *edgecut = 0; + return; + } + + /******************************/ + /* Take care of npes = 1 case */ + /******************************/ + if (npes == 1 && inparts > 1) { + moptions[0] = 0; + nvtxs = vtxdist[1]; + + if (incon == 1) { + METIS_WPartGraphKway(&nvtxs, xadj, adjncy, vwgt, adjwgt, &iwgtflag, &inumflag, + &inparts, itpwgts, moptions, edgecut, part); + } + else { + /* ADD: this is because METIS does not support tpwgts for all constraints */ + mytpwgts = fmalloc(inparts, "mytpwgts"); + for (i=0; invwgt); graph->nvwgt = NULL; + + PreAllocateMemory(&ctrl, graph, &wspace); + + /*================================================================= + * Compute the initial npes-way partitioning geometric partitioning + =================================================================*/ + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + Coordinate_Partition(&ctrl, graph, *ndims, xyz, 1, &wspace); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + + /*================================================================= + * Move the graph according to the partitioning + =================================================================*/ + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.MoveTmr)); + + free(uvwgt); + graph->vwgt = ((iwgtflag&2) != 0) ? vwgt : idxsmalloc(graph->nvtxs*incon, 1, "vwgt"); + graph->ncon = incon; + j = ctrl.nparts; + ctrl.nparts = ctrl.npes; + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); + ctrl.nparts = j; + + /**********************************************************/ + /* Do the same functionality as Moc_SetUpGraph for mgraph */ + /**********************************************************/ + /* compute tvwgts */ + for (j=0; jnvtxs; i++) + for (j=0; jvwgt[i*incon+j]; + + for (j=0; jnvwgt = fmalloc(mgraph->nvtxs*incon, "mgraph->nvwgt"); + for (i=0; invtxs; i++) + for (j=0; jnvwgt[i*incon+j] = (float)(mgraph->vwgt[i*incon+j]) / (float)(ctrl.tvwgts[j]); + + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.MoveTmr)); + + if (ctrl.dbglvl&DBG_INFO) { + cut = 0; + for (i=0; invtxs; i++) + for (j=graph->xadj[i]; jxadj[i+1]; j++) + if (graph->where[i] != graph->where[graph->adjncy[j]]) + cut += graph->adjwgt[j]; + gcut = GlobalSESum(&ctrl, cut)/2; + maxnvtxs = GlobalSEMax(&ctrl, mgraph->nvtxs); + balance = (float)(maxnvtxs)/((float)(graph->gnvtxs)/(float)(npes)); + rprintf(&ctrl, "XYZ Cut: %6d \tBalance: %6.3f [%d %d %d]\n", + gcut, balance, maxnvtxs, graph->gnvtxs, npes); + + } + + /*================================================================= + * Set up the newly moved graph + =================================================================*/ + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + ctrl.nparts = inparts; + FreeWSpace(&wspace); + PreAllocateMemory(&ctrl, mgraph, &wspace); + + /*======================================================= + * Now compute the partition of the moved graph + =======================================================*/ + if (vtxdist[npes] < SMALLGRAPH || vtxdist[npes] < npes*20 || GlobalSESum(&ctrl, mgraph->nedges) == 0) { + IFSET(ctrl.dbglvl, DBG_INFO, rprintf(&ctrl, "Partitioning a graph of size %d serially\n", vtxdist[npes])); + PartitionSmallGraph(&ctrl, mgraph, &wspace); + } + else { + Moc_Global_Partition(&ctrl, mgraph, &wspace); + } + ParallelReMapGraph(&ctrl, mgraph, &wspace); + + /* Invert the ordering back to the original graph */ + ctrl.nparts = npes; + ProjectInfoBack(&ctrl, graph, part, mgraph->where, &wspace); + + *edgecut = mgraph->mincut; + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + + /*******************/ + /* Print out stats */ + /*******************/ + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + + if (ctrl.dbglvl&DBG_INFO) { + rprintf(&ctrl, "Final %d-way CUT: %6d \tBalance: ", inparts, mgraph->mincut); + avg = 0.0; + for (h=0; hgnpwgts[i*incon+h]/itpwgts[i*incon+h]); + avg += maximb; + rprintf(&ctrl, "%.3f ", maximb); + } + rprintf(&ctrl, " avg: %.3f\n", avg/(float)incon); + } + + GKfree((void **)&itpwgts, LTERM); + FreeGraph(mgraph); + FreeInitialGraphAndRemap(graph, iwgtflag); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 0); + +} + + + +/*********************************************************************************** +* This function is the entry point of the parallel ordering algorithm. +* This function assumes that the graph is already nice partitioned among the +* processors and then proceeds to perform recursive bisection. +************************************************************************************/ +void ParMETIS_V3_PartGeom(idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm) +{ + int i, npes, mype, nvtxs, firstvtx, dbglvl; + idxtype *xadj, *adjncy; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph; + int zeroflg = 0; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + if (npes == 1) { + idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); + return; + } + + /* Setup a fake graph to allow the rest of the code to work unchanged */ + dbglvl = 0; + + nvtxs = vtxdist[mype+1]-vtxdist[mype]; + firstvtx = vtxdist[mype]; + xadj = idxmalloc(nvtxs+1, "ParMETIS_PartGeom: xadj"); + adjncy = idxmalloc(nvtxs, "ParMETIS_PartGeom: adjncy"); + for (i=0; invtxs, graph->where, part); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + + FreeInitialGraphAndRemap(graph, 0); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + GKfree((void **)&xadj, (void **)&adjncy, LTERM); +} + + + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/grsetup.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/grsetup.c new file mode 100644 index 0000000..7f10a8f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/grsetup.c @@ -0,0 +1,274 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mgrsetup.c + * + * This file contain various graph setting up routines + * + * Started 10/19/96 + * George + * + * $Id: grsetup.c,v 1.7 2003/07/23 00:54:55 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function setsup the CtrlType structure +**************************************************************************/ +GraphType *Moc_SetUpGraph(CtrlType *ctrl, int ncon, idxtype *vtxdist, idxtype *xadj, + idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, int *wgtflag) +{ + int i, j; + GraphType *graph; + int ltvwgts[MAXNCON]; + + graph = CreateGraph(); + graph->level = 0; + graph->gnvtxs = vtxdist[ctrl->npes]; + graph->nvtxs = vtxdist[ctrl->mype+1]-vtxdist[ctrl->mype]; + graph->ncon = ncon; + graph->nedges = xadj[graph->nvtxs]; + graph->xadj = xadj; + graph->vwgt = vwgt; + graph->adjncy = adjncy; + graph->adjwgt = adjwgt; + graph->vtxdist = vtxdist; + + + if (((*wgtflag)&2) == 0) + graph->vwgt = idxsmalloc(graph->nvtxs*ncon, 1, "Par_KMetis: vwgt"); + + if (((*wgtflag)&1) == 0) + graph->adjwgt = idxsmalloc(graph->nedges, 1, "Par_KMetis: adjwgt"); + + /* compute tvwgts */ + for (j=0; jnvtxs; i++) + for (j=0; jvwgt[i*ncon+j]; + + for (j=0; jtvwgts[j] = GlobalSESum(ctrl, ltvwgts[j]); + + /* check for zero wgt constraints */ + for (i=0; itvwgts[i] == 0) { + rprintf(ctrl, "ERROR: sum weight for constraint %d is zero\n", i); + MPI_Finalize(); + exit(-1); + } + } + + /* compute nvwgts */ + graph->nvwgt = fmalloc(graph->nvtxs*ncon, "graph->nvwgt"); + for (i=0; invtxs; i++) { + for (j=0; jnvwgt[i*ncon+j] = (float)(graph->vwgt[i*ncon+j]) / (float)(ctrl->tvwgts[j]); + } + + srand(ctrl->seed); + + return graph; +} + + +/************************************************************************* +* This function setsup the CtrlType structure +**************************************************************************/ +void SetUpCtrl(CtrlType *ctrl, int nparts, int dbglvl, MPI_Comm comm) +{ + + MPI_Comm_dup(comm, &(ctrl->gcomm)); + MPI_Comm_rank(ctrl->gcomm, &ctrl->mype); + MPI_Comm_size(ctrl->gcomm, &ctrl->npes); + + ctrl->dbglvl = dbglvl; + ctrl->nparts = nparts; /* Set the # of partitions is de-coupled from the # of domains */ + ctrl->comm = ctrl->gcomm; + ctrl->xyztype = XYZ_SPFILL; + + srand(ctrl->mype); +} + + +/************************************************************************* +* This function changes the numbering from 1 to 0 or 0 to 1 +**************************************************************************/ +void ChangeNumbering(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *part, int npes, int mype, int from) +{ + int i, nvtxs, nedges; + + if (from == 1) { /* Change it from 1 to 0 */ + for (i=0; invtxs; i++) { + for (j=graph->xadj[i]; jxadj[i+1]; j++) { + k = graph->xadj[i] + RandomInRange(graph->xadj[i+1]-graph->xadj[i]); + SWAP(graph->adjncy[j], graph->adjncy[k], tmp); + SWAP(graph->adjwgt[j], graph->adjwgt[k], tmp); + } + } +} + + +/************************************************************************* +* This function computes movement statistics for adaptive refinement +* schemes +**************************************************************************/ +void ComputeMoveStatistics(CtrlType *ctrl, GraphType *graph, int *nmoved, int *maxin, int *maxout) +{ + int i, j, nvtxs; + idxtype *vwgt, *where; + idxtype *lpvtxs, *gpvtxs; + + nvtxs = graph->nvtxs; + vwgt = graph->vwgt; + where = graph->where; + + lpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: lpvtxs"); + gpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: gpvtxs"); + + for (j=i=0; imype) + j++; + } + + /* PrintVector(ctrl, ctrl->npes, 0, lpvtxs, "Lpvtxs: "); */ + + MPI_Allreduce((void *)lpvtxs, (void *)gpvtxs, ctrl->nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + + *nmoved = GlobalSESum(ctrl, j); + *maxout = GlobalSEMax(ctrl, j); + *maxin = GlobalSEMax(ctrl, gpvtxs[ctrl->mype]-(nvtxs-j)); + + GKfree((void **)&lpvtxs, (void **)&gpvtxs, LTERM); +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iidxsort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iidxsort.c new file mode 100644 index 0000000..869748c --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iidxsort.c @@ -0,0 +1,152 @@ +#include + + +/* Byte-wise swap two items of size SIZE. */ +#define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 20 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct { + idxtype *lo; + idxtype *hi; +} stack_node; + + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +void iidxsort(int total_elems, idxtype *pbase) +{ + idxtype pivot, stmp; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) { + idxtype *lo = pbase; + idxtype *hi = &lo[total_elems - 1]; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) { + idxtype *left_ptr; + idxtype *right_ptr; + idxtype *mid = lo + ((hi - lo) >> 1); + + + if (*mid < *lo) + QSSWAP(*mid, *lo, stmp); + if (*hi < *mid) + QSSWAP(*mid, *hi, stmp); + else + goto jump_over; + if (*mid < *lo) + QSSWAP(*mid, *lo, stmp); + +jump_over:; + pivot = *mid; + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do { + while (*left_ptr < pivot) + left_ptr++; + + while (pivot < *right_ptr) + right_ptr--; + + if (left_ptr < right_ptr) { + QSSWAP (*left_ptr, *right_ptr, stmp); + left_ptr++; + right_ptr--; + } + else if (left_ptr == right_ptr) { + left_ptr++; + right_ptr--; + break; + } + } while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= MAX_THRESH) { + if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + { + idxtype *end_ptr = &pbase[total_elems - 1]; + idxtype *tmp_ptr = pbase; + idxtype *thresh = (end_ptr < pbase + MAX_THRESH ? end_ptr : pbase + MAX_THRESH); + register idxtype *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++) + if (*run_ptr < *tmp_ptr) + tmp_ptr = run_ptr; + + if (tmp_ptr != pbase) + QSSWAP(*tmp_ptr, *pbase, stmp); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + run_ptr = pbase + 1; + while (++run_ptr <= end_ptr) { + tmp_ptr = run_ptr - 1; + while (*run_ptr < *tmp_ptr) + tmp_ptr--; + + tmp_ptr++; + if (tmp_ptr != run_ptr) { + idxtype elmnt = *run_ptr; + idxtype *mptr; + + for (mptr=run_ptr; mptr>tmp_ptr; mptr--) + *mptr = *(mptr-1); + *mptr = elmnt; + } + } + } +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iintsort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iintsort.c new file mode 100644 index 0000000..fb0e840 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/iintsort.c @@ -0,0 +1,157 @@ +#include + + +/* Byte-wise swap two items of size SIZE. */ +#define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 20 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct { + int *lo; + int *hi; +} stack_node; + + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +void iintsort(int total_elems, int *pbase) +{ + int pivot, stmp; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) { + int *lo = pbase; + int *hi = &lo[total_elems - 1]; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) { + int *left_ptr; + int *right_ptr; + + /* Select median value from among LO, MID, and HI. Rearrange + LO and HI so the three values are sorted. This lowers the + probability of picking a pathological pivot value and + skips a comparison for both the LEFT_PTR and RIGHT_PTR. */ + + int *mid = lo + ((hi - lo) >> 1); + + if (*mid < *lo) + QSSWAP(*mid, *lo, stmp); + if (*hi < *mid) + QSSWAP(*mid, *hi, stmp); + else + goto jump_over; + if (*mid < *lo) + QSSWAP(*mid, *lo, stmp); + +jump_over:; + pivot = *mid; + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do { + while (*left_ptr < pivot) + left_ptr++; + + while (pivot < *right_ptr) + right_ptr--; + + if (left_ptr < right_ptr) { + QSSWAP (*left_ptr, *right_ptr, stmp); + left_ptr++; + right_ptr--; + } + else if (left_ptr == right_ptr) { + left_ptr++; + right_ptr--; + break; + } + } while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= MAX_THRESH) { + if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + { + int *end_ptr = &pbase[total_elems - 1]; + int *tmp_ptr = pbase; + int *thresh = (end_ptr < pbase + MAX_THRESH ? end_ptr : pbase + MAX_THRESH); + register int *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++) + if (*run_ptr < *tmp_ptr) + tmp_ptr = run_ptr; + + if (tmp_ptr != pbase) + QSSWAP(*tmp_ptr, *pbase, stmp); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + run_ptr = pbase + 1; + while (++run_ptr <= end_ptr) { + tmp_ptr = run_ptr - 1; + while (*run_ptr < *tmp_ptr) + tmp_ptr--; + + tmp_ptr++; + if (tmp_ptr != run_ptr) { + int elmnt = *run_ptr; + int *mptr; + + for (mptr=run_ptr; mptr>tmp_ptr; mptr--) + *mptr = *(mptr-1); + *mptr = elmnt; + } + } + } +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeysort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeysort.c new file mode 100644 index 0000000..14b4241 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeysort.c @@ -0,0 +1,151 @@ +#include + + +/* Byte-wise swap two items of size SIZE. */ +#define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 20 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct { + KeyValueType *lo; + KeyValueType *hi; +} stack_node; + + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +void ikeysort(int total_elems, KeyValueType *pbase) +{ + KeyValueType pivot, stmp; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) { + KeyValueType *lo = pbase; + KeyValueType *hi = &lo[total_elems - 1]; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) { + KeyValueType *left_ptr; + KeyValueType *right_ptr; + KeyValueType *mid = lo + ((hi - lo) >> 1); + + if (mid->key < lo->key) + QSSWAP(*mid, *lo, stmp); + if (hi->key < mid->key) + QSSWAP(*mid, *hi, stmp); + else + goto jump_over; + if (mid->key < lo->key) + QSSWAP(*mid, *lo, stmp); + +jump_over:; + pivot = *mid; + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do { + while (left_ptr->key < pivot.key) + left_ptr++; + + while (pivot.key < right_ptr->key) + right_ptr--; + + if (left_ptr < right_ptr) { + QSSWAP (*left_ptr, *right_ptr, stmp); + left_ptr++; + right_ptr--; + } + else if (left_ptr == right_ptr) { + left_ptr++; + right_ptr--; + break; + } + } while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= MAX_THRESH) { + if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + { + KeyValueType *end_ptr = &pbase[total_elems - 1]; + KeyValueType *tmp_ptr = pbase; + KeyValueType *thresh = (end_ptr < pbase + MAX_THRESH ? end_ptr : pbase + MAX_THRESH); + register KeyValueType *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++) + if (run_ptr->key < tmp_ptr->key) + tmp_ptr = run_ptr; + + if (tmp_ptr != pbase) + QSSWAP(*tmp_ptr, *pbase, stmp); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + run_ptr = pbase + 1; + while (++run_ptr <= end_ptr) { + tmp_ptr = run_ptr - 1; + while (run_ptr->key < tmp_ptr->key) + tmp_ptr--; + + tmp_ptr++; + if (tmp_ptr != run_ptr) { + KeyValueType elmnt = *run_ptr; + KeyValueType *mptr; + + for (mptr=run_ptr; mptr>tmp_ptr; mptr--) + *mptr = *(mptr-1); + *mptr = elmnt; + } + } + } +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeyvalsort.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeyvalsort.c new file mode 100644 index 0000000..59dce52 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ikeyvalsort.c @@ -0,0 +1,151 @@ +#include + + +/* Byte-wise swap two items of size SIZE. */ +#define QSSWAP(a, b, stmp) do { stmp = (a); (a) = (b); (b) = stmp; } while (0) + +/* Discontinue quicksort algorithm when partition gets below this size. + This particular magic number was chosen to work best on a Sun 4/260. */ +#define MAX_THRESH 20 + +/* Stack node declarations used to store unfulfilled partition obligations. */ +typedef struct { + KeyValueType *lo; + KeyValueType *hi; +} stack_node; + + +/* The next 4 #defines implement a very fast in-line stack abstraction. */ +#define STACK_SIZE (8 * sizeof(unsigned long int)) +#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) +#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) +#define STACK_NOT_EMPTY (stack < top) + + +void ikeyvalsort(int total_elems, KeyValueType *pbase) +{ + KeyValueType pivot, stmp; + + if (total_elems == 0) + /* Avoid lossage with unsigned arithmetic below. */ + return; + + if (total_elems > MAX_THRESH) { + KeyValueType *lo = pbase; + KeyValueType *hi = &lo[total_elems - 1]; + stack_node stack[STACK_SIZE]; /* Largest size needed for 32-bit int!!! */ + stack_node *top = stack + 1; + + while (STACK_NOT_EMPTY) { + KeyValueType *left_ptr; + KeyValueType *right_ptr; + KeyValueType *mid = lo + ((hi - lo) >> 1); + + if (mid->key < lo->key || (mid->key == lo->key && mid->val < lo->val)) + QSSWAP(*mid, *lo, stmp); + if (hi->key < mid->key || (hi->key == mid->key && hi->val < mid->val)) + QSSWAP(*mid, *hi, stmp); + else + goto jump_over; + if (mid->key < lo->key || (mid->key == lo->key && mid->val < lo->val)) + QSSWAP(*mid, *lo, stmp); + +jump_over:; + pivot = *mid; + left_ptr = lo + 1; + right_ptr = hi - 1; + + /* Here's the famous ``collapse the walls'' section of quicksort. + Gotta like those tight inner loops! They are the main reason + that this algorithm runs much faster than others. */ + do { + while (left_ptr->key < pivot.key || (left_ptr->key == pivot.key && left_ptr->val < pivot.val)) + left_ptr++; + + while (pivot.key < right_ptr->key || (pivot.key == right_ptr->key && pivot.val < right_ptr->val)) + right_ptr--; + + if (left_ptr < right_ptr) { + QSSWAP (*left_ptr, *right_ptr, stmp); + left_ptr++; + right_ptr--; + } + else if (left_ptr == right_ptr) { + left_ptr++; + right_ptr--; + break; + } + } while (left_ptr <= right_ptr); + + /* Set up pointers for next iteration. First determine whether + left and right partitions are below the threshold size. If so, + ignore one or both. Otherwise, push the larger partition's + bounds on the stack and continue sorting the smaller one. */ + + if ((size_t) (right_ptr - lo) <= MAX_THRESH) { + if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore both small partitions. */ + POP (lo, hi); + else + /* Ignore small left partition. */ + lo = left_ptr; + } + else if ((size_t) (hi - left_ptr) <= MAX_THRESH) + /* Ignore small right partition. */ + hi = right_ptr; + else if ((right_ptr - lo) > (hi - left_ptr)) { + /* Push larger left partition indices. */ + PUSH (lo, right_ptr); + lo = left_ptr; + } + else { + /* Push larger right partition indices. */ + PUSH (left_ptr, hi); + hi = right_ptr; + } + } + } + + /* Once the BASE_PTR array is partially sorted by quicksort the rest + is completely sorted using insertion sort, since this is efficient + for partitions below MAX_THRESH size. BASE_PTR points to the beginning + of the array to sort, and END_PTR points at the very last element in + the array (*not* one beyond it!). */ + + { + KeyValueType *end_ptr = &pbase[total_elems - 1]; + KeyValueType *tmp_ptr = pbase; + KeyValueType *thresh = (end_ptr < pbase + MAX_THRESH ? end_ptr : pbase + MAX_THRESH); + register KeyValueType *run_ptr; + + /* Find smallest element in first threshold and place it at the + array's beginning. This is the smallest array element, + and the operation speeds up insertion sort's inner loop. */ + + for (run_ptr = tmp_ptr + 1; run_ptr <= thresh; run_ptr++) + if (run_ptr->key < tmp_ptr->key || (run_ptr->key == tmp_ptr->key && run_ptr->val < tmp_ptr->val)) + tmp_ptr = run_ptr; + + if (tmp_ptr != pbase) + QSSWAP(*tmp_ptr, *pbase, stmp); + + /* Insertion sort, running from left-hand-side up to right-hand-side. */ + run_ptr = pbase + 1; + while (++run_ptr <= end_ptr) { + tmp_ptr = run_ptr - 1; + while (run_ptr->key < tmp_ptr->key || (run_ptr->key == tmp_ptr->key && run_ptr->val < tmp_ptr->val)) + tmp_ptr--; + + tmp_ptr++; + if (tmp_ptr != run_ptr) { + KeyValueType elmnt = *run_ptr; + KeyValueType *mptr; + + for (mptr=run_ptr; mptr>tmp_ptr; mptr--) + *mptr = *(mptr-1); + *mptr = elmnt; + } + } + } +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initbalance.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initbalance.c new file mode 100644 index 0000000..9ec7a31 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initbalance.c @@ -0,0 +1,498 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * initbalance.c + * + * This file contains code that computes an initial partitioning + * + * Started 3/4/96 + * George + * + * $Id: initbalance.c,v 1.4 2003/07/30 21:18:52 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function is the entry point of the initial balancing algorithm. +* This algorithm assembles the graph to all the processors and preceeds +* with the balancing step. +**************************************************************************/ +void Balance_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j, mype, npes, nvtxs, nedges, ncon; + idxtype *vtxdist, *xadj, *adjncy, *adjwgt, *vwgt, *vsize; + idxtype *part, *lwhere, *home; + GraphType *agraph, cgraph; + CtrlType myctrl; + int lnparts, fpart, fpe, lnpes, ngroups, srnpes, srmype; + int twoparts=2, numflag = 0, wgtflag = 3, moptions[10], edgecut, max_cut; + int sr_pe, gd_pe, sr, gd, who_wins, *rcounts, *rdispls; + float my_cut, my_totalv, my_cost = -1.0, my_balance = -1.0, wsum; + float rating, max_rating, your_cost = -1.0, your_balance = -1.0; + float lbvec[MAXNCON], lbsum, min_lbsum, *mytpwgts, mytpwgts2[2], buffer[2]; + MPI_Status status; + MPI_Comm ipcomm, srcomm; + struct { + float cost; + int rank; + } lpecost, gpecost; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + vtxdist = graph->vtxdist; + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); + nvtxs = cgraph.nvtxs = agraph->nvtxs; + nedges = cgraph.nedges = agraph->nedges; + ncon = cgraph.ncon = agraph->ncon; + + xadj = cgraph.xadj = idxmalloc(nvtxs*(5+ncon)+1+nedges*2, "U_IP: xadj"); + vwgt = cgraph.vwgt = xadj + nvtxs+1; + vsize = cgraph.vsize = xadj + nvtxs*(1+ncon)+1; + cgraph.where = agraph->where = part = xadj + nvtxs*(2+ncon)+1; + lwhere = xadj + nvtxs*(3+ncon)+1; + home = xadj + nvtxs*(4+ncon)+1; + adjncy = cgraph.adjncy = xadj + nvtxs*(5+ncon)+1; + adjwgt = cgraph.adjwgt = xadj + nvtxs*(5+ncon)+1 + nedges; + + /* ADD: this assumes that tpwgts for all constraints is the same */ + /* ADD: this is necessary because serial metis does not support the general case */ + mytpwgts = fsmalloc(ctrl->nparts, 0.0, "mytpwgts"); + for (i=0; inparts; i++) + for (j=0; jtpwgts[i*ncon+j]; + for (i=0; inparts; i++) + mytpwgts[i] /= (float)ncon; + + idxcopy(nvtxs+1, agraph->xadj, xadj); + idxcopy(nvtxs*ncon, agraph->vwgt, vwgt); + idxcopy(nvtxs, agraph->vsize, vsize); + idxcopy(nedges, agraph->adjncy, adjncy); + idxcopy(nedges, agraph->adjwgt, adjwgt); + + /****************************************/ + /****************************************/ + if (ctrl->ps_relation == DISCOUPLED) { + rcounts = imalloc(ctrl->npes, "rcounts"); + rdispls = imalloc(ctrl->npes+1, "rdispls"); + + for (i=0; inpes; i++) { + rdispls[i] = rcounts[i] = vtxdist[i+1]-vtxdist[i]; + } + MAKECSR(i, ctrl->npes, rdispls); + + MPI_Allgatherv((void *)graph->home, graph->nvtxs, IDX_DATATYPE, + (void *)part, rcounts, rdispls, IDX_DATATYPE, ctrl->comm); + + for (i=0; invtxs; i++) + home[i] = part[i]; + + GKfree((void **)&rcounts, (void **)&rdispls, LTERM); + } + else { + for (i=0; inpes; i++) + for (j=vtxdist[i]; jnvtxs; i++) { + if (part[i] >= ctrl->nparts) + part[i] = home[i] = part[i] % ctrl->nparts; + if (part[i] < 0) + part[i] = home[i] = (-1*part[i]) % ctrl->nparts; + } + /****************************************/ + /****************************************/ + + IFSET(ctrl->dbglvl, DBG_REFINEINFO, Moc_ComputeSerialBalance(ctrl, agraph, agraph->where, lbvec)); + IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "input cut: %d, balance: ", ComputeSerialEdgeCut(agraph))); + for (i=0; incon; i++) + IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "%.3f ", lbvec[i])); + IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "\n")); + + /****************************************/ + /* Split the processors into two groups */ + /****************************************/ + sr = (ctrl->mype % 2 == 0) ? 1 : 0; + gd = (ctrl->mype % 2 == 1) ? 1 : 0; + + if (graph->ncon > MAX_NCON_FOR_DIFFUSION || ctrl->npes == 1) { + sr = 1; + gd = 0; + } + + sr_pe = 0; + gd_pe = 1; + + MPI_Comm_split(ctrl->gcomm, sr, 0, &ipcomm); + MPI_Comm_rank(ipcomm, &mype); + MPI_Comm_size(ipcomm, &npes); + + myctrl.dbglvl = 0; + myctrl.mype = mype; + myctrl.npes = npes; + myctrl.comm = ipcomm; + myctrl.sync = ctrl->sync; + myctrl.seed = ctrl->seed; + myctrl.nparts = ctrl->nparts; + myctrl.ipc_factor = ctrl->ipc_factor; + myctrl.redist_factor = ctrl->redist_base; + myctrl.partType = ADAPTIVE_PARTITION; + myctrl.ps_relation = DISCOUPLED; + myctrl.tpwgts = ctrl->tpwgts; + icopy(ncon, ctrl->tvwgts, myctrl.tvwgts); + icopy(ncon, ctrl->ubvec, myctrl.ubvec); + + if (sr == 1) { + /*******************************************/ + /* Half of the processors do scratch-remap */ + /*******************************************/ + ngroups = amax(amin(RIP_SPLIT_FACTOR, npes), 1); + MPI_Comm_split(ipcomm, mype % ngroups, 0, &srcomm); + MPI_Comm_rank(srcomm, &srmype); + MPI_Comm_size(srcomm, &srnpes); + + moptions[0] = 0; + moptions[7] = ctrl->sync + (mype % ngroups) + 1; + + idxset(nvtxs, 0, lwhere); + lnparts = ctrl->nparts; + fpart = fpe = 0; + lnpes = srnpes; + while (lnpes > 1 && lnparts > 1) { + ASSERT(ctrl, agraph->nvtxs > 1); + /* Determine the weights of the partitions */ + mytpwgts2[0] = ssum(lnparts/2, mytpwgts+fpart); + mytpwgts2[1] = 1.0-mytpwgts2[0]; + + + if (agraph->ncon == 1) { + METIS_WPartGraphKway2(&agraph->nvtxs, agraph->xadj, agraph->adjncy, agraph->vwgt, + agraph->adjwgt, &wgtflag, &numflag, &twoparts, mytpwgts2, moptions, &edgecut, + part); + } + else { + METIS_mCPartGraphRecursive2(&agraph->nvtxs, &ncon, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, &twoparts, mytpwgts2, + moptions, &edgecut, part); + } + + wsum = ssum(lnparts/2, mytpwgts+fpart); + sscale(lnparts/2, 1.0/wsum, mytpwgts+fpart); + sscale(lnparts-lnparts/2, 1.0/(1.0-wsum), mytpwgts+fpart+lnparts/2); + + /* I'm picking the left branch */ + if (srmype < fpe+lnpes/2) { + Moc_KeepPart(agraph, wspace, part, 0); + lnpes = lnpes/2; + lnparts = lnparts/2; + } + else { + Moc_KeepPart(agraph, wspace, part, 1); + fpart = fpart + lnparts/2; + fpe = fpe + lnpes/2; + lnpes = lnpes - lnpes/2; + lnparts = lnparts - lnparts/2; + } + } + + /* In case srnpes is greater than or equal to nparts */ + if (lnparts == 1) { + /* Only the first process will assign labels (for the reduction to work) */ + if (srmype == fpe) { + for (i=0; invtxs; i++) + lwhere[agraph->label[i]] = fpart; + } + } + /* In case srnpes is smaller than nparts */ + else { + if (ncon == 1) + METIS_WPartGraphKway2(&agraph->nvtxs, agraph->xadj, agraph->adjncy, agraph->vwgt, + agraph->adjwgt, &wgtflag, &numflag, &lnparts, mytpwgts+fpart, moptions, + &edgecut, part); + else + METIS_mCPartGraphRecursive2(&agraph->nvtxs, &ncon, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, &lnparts, mytpwgts+fpart, + moptions, &edgecut, part); + + for (i=0; invtxs; i++) + lwhere[agraph->label[i]] = fpart + part[i]; + } + + MPI_Allreduce((void *)lwhere, (void *)part, nvtxs, IDX_DATATYPE, MPI_SUM, srcomm); + + edgecut = ComputeSerialEdgeCut(&cgraph); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + lbsum = ssum(ncon, lbvec); + MPI_Allreduce((void *)&edgecut, (void *)&max_cut, 1, MPI_INT, MPI_MAX, ipcomm); + MPI_Allreduce((void *)&lbsum, (void *)&min_lbsum, 1, MPI_FLOAT, MPI_MIN, ipcomm); + lpecost.rank = ctrl->mype; + lpecost.cost = lbsum; + if (min_lbsum < UNBALANCE_FRACTION * (float)(ncon)) { + if (lbsum < UNBALANCE_FRACTION * (float)(ncon)) + lpecost.cost = (float)edgecut; + else + lpecost.cost = (float)max_cut + lbsum; + } + MPI_Allreduce((void *)&lpecost, (void *)&gpecost, 1, MPI_FLOAT_INT, MPI_MINLOC, ipcomm); + + if (ctrl->mype == gpecost.rank && ctrl->mype != sr_pe) { + MPI_Send((void *)part, nvtxs, IDX_DATATYPE, sr_pe, 1, ctrl->comm); + } + + if (ctrl->mype != gpecost.rank && ctrl->mype == sr_pe) { + MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); + } + + if (ctrl->mype == sr_pe) { + idxcopy(nvtxs, part, lwhere); + SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); + } + + MPI_Comm_free(&srcomm); + } + /**************************************/ + /* The other half do global diffusion */ + /**************************************/ + else { + /******************************************************************/ + /* The next stmt is required to balance out the sr MPI_Comm_split */ + /******************************************************************/ + MPI_Comm_split(ipcomm, MPI_UNDEFINED, 0, &srcomm); + + if (ncon == 1) { + rating = WavefrontDiffusion(&myctrl, agraph, home); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + lbsum = ssum(ncon, lbvec); + + /* Determine which PE computed the best partitioning */ + MPI_Allreduce((void *)&rating, (void *)&max_rating, 1, MPI_FLOAT, MPI_MAX, ipcomm); + MPI_Allreduce((void *)&lbsum, (void *)&min_lbsum, 1, MPI_FLOAT, MPI_MIN, ipcomm); + + lpecost.rank = ctrl->mype; + lpecost.cost = lbsum; + if (min_lbsum < UNBALANCE_FRACTION * (float)(ncon)) { + if (lbsum < UNBALANCE_FRACTION * (float)(ncon)) + lpecost.cost = rating; + else + lpecost.cost = max_rating + lbsum; + } + + MPI_Allreduce((void *)&lpecost, (void *)&gpecost, 1, MPI_FLOAT_INT, MPI_MINLOC, ipcomm); + + /* Now send this to the coordinating processor */ + if (ctrl->mype == gpecost.rank && ctrl->mype != gd_pe) + MPI_Send((void *)part, nvtxs, IDX_DATATYPE, gd_pe, 1, ctrl->comm); + + if (ctrl->mype != gpecost.rank && ctrl->mype == gd_pe) + MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); + + if (ctrl->mype == gd_pe) { + idxcopy(nvtxs, part, lwhere); + SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); + } + } + else { + Moc_Diffusion(&myctrl, agraph, graph->vtxdist, agraph->where, home, wspace, N_MOC_GD_PASSES); + } + } + + if (graph->ncon <= MAX_NCON_FOR_DIFFUSION) { + if (ctrl->mype == sr_pe || ctrl->mype == gd_pe) { + /********************************************************************/ + /* The coordinators from each group decide on the best partitioning */ + /********************************************************************/ + my_cut = (float) ComputeSerialEdgeCut(&cgraph); + my_totalv = (float) Mc_ComputeSerialTotalV(&cgraph, home); + Moc_ComputeSerialBalance(ctrl, &cgraph, part, lbvec); + my_balance = ssum(cgraph.ncon, lbvec); + my_balance /= (float) cgraph.ncon; + my_cost = ctrl->ipc_factor * my_cut + REDIST_WGT * ctrl->redist_base * my_totalv; + + IFSET(ctrl->dbglvl, DBG_REFINEINFO, printf("%s initial cut: %.1f, totalv: %.1f, balance: %.3f\n", + (ctrl->mype == sr_pe ? "scratch-remap" : "diffusion"), my_cut, my_totalv, my_balance)); + + if (ctrl->mype == gd_pe) { + buffer[0] = my_cost; + buffer[1] = my_balance; + MPI_Send((void *)buffer, 2, MPI_FLOAT, sr_pe, 1, ctrl->comm); + } + else { + MPI_Recv((void *)buffer, 2, MPI_FLOAT, gd_pe, 1, ctrl->comm, &status); + your_cost = buffer[0]; + your_balance = buffer[1]; + } + } + + if (ctrl->mype == sr_pe) { + who_wins = gd_pe; + if ((my_balance < 1.1 && your_balance > 1.1) || + (my_balance < 1.1 && your_balance < 1.1 && my_cost < your_cost) || + (my_balance > 1.1 && your_balance > 1.1 && my_balance < your_balance)) { + who_wins = sr_pe; + } + } + + MPI_Bcast((void *)&who_wins, 1, MPI_INT, sr_pe, ctrl->comm); + } + else { + who_wins = sr_pe; + } + + MPI_Bcast((void *)part, nvtxs, IDX_DATATYPE, who_wins, ctrl->comm); + idxcopy(graph->nvtxs, part+vtxdist[ctrl->mype], graph->where); + + MPI_Comm_free(&ipcomm); + GKfree((void **)&xadj, (void **)&mytpwgts, LTERM); + +/* For whatever reason, FreeGraph crashes here...so explicitly free the memory. + FreeGraph(agraph); +*/ + GKfree((void **)&agraph->xadj, (void **)&agraph->adjncy, (void **)&agraph->vwgt, (void **)&agraph->nvwgt, LTERM); + GKfree((void **)&agraph->vsize, (void **)&agraph->adjwgt, (void **)&agraph->label, LTERM); + GKfree((void **)&agraph, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + +} + + +/* NOTE: this subroutine should work for static, adaptive, single-, and multi-contraint */ +/************************************************************************* +* This function assembles the graph into a single processor +**************************************************************************/ +GraphType *Moc_AssembleAdaptiveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j, k, l, gnvtxs, nvtxs, ncon, gnedges, nedges, gsize; + idxtype *xadj, *vwgt, *vsize, *adjncy, *adjwgt, *vtxdist, *imap; + idxtype *axadj, *aadjncy, *aadjwgt, *avwgt, *avsize = NULL, *alabel; + idxtype *mygraph, *ggraph; + int *rcounts, *rdispls, mysize; + float *anvwgt; + GraphType *agraph; + + gnvtxs = graph->gnvtxs; + nvtxs = graph->nvtxs; + ncon = graph->ncon; + nedges = graph->xadj[nvtxs]; + xadj = graph->xadj; + vwgt = graph->vwgt; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vtxdist = graph->vtxdist; + imap = graph->imap; + + /*************************************************************/ + /* Determine the # of idxtype to receive from each processor */ + /*************************************************************/ + rcounts = imalloc(ctrl->npes, "AssembleGraph: rcounts"); + switch (ctrl->partType) { + case STATIC_PARTITION: + mysize = (1+ncon)*nvtxs + 2*nedges; + break; + case ADAPTIVE_PARTITION: + case REFINE_PARTITION: + mysize = (2+ncon)*nvtxs + 2*nedges; + break; + default: + printf("WARNING: bad value for ctrl->partType %d\n", ctrl->partType); + break; + } + MPI_Allgather((void *)(&mysize), 1, MPI_INT, (void *)rcounts, 1, MPI_INT, ctrl->comm); + + rdispls = imalloc(ctrl->npes+1, "AssembleGraph: rdispls"); + rdispls[0] = 0; + for (i=1; inpes+1; i++) + rdispls[i] = rdispls[i-1] + rcounts[i-1]; + + /* Construct the one-array storage format of the assembled graph */ + mygraph = (mysize <= wspace->maxcore ? wspace->core : idxmalloc(mysize, "AssembleGraph: mygraph")); + for (k=i=0; ipartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + mygraph[k++] = vsize[i]; + for (j=xadj[i]; jnpes]; + ggraph = (gsize <= wspace->maxcore-mysize ? wspace->core+mysize : idxmalloc(gsize, "AssembleGraph: ggraph")); + MPI_Allgatherv((void *)mygraph, mysize, IDX_DATATYPE, (void *)ggraph, rcounts, rdispls, IDX_DATATYPE, ctrl->comm); + + GKfree((void **)&rcounts, (void **)&rdispls, LTERM); + if (mysize > wspace->maxcore) + free(mygraph); + + agraph = CreateGraph(); + agraph->nvtxs = gnvtxs; + switch (ctrl->partType) { + case STATIC_PARTITION: + agraph->nedges = gnedges = (gsize-(1+ncon)*gnvtxs)/2; + break; + case ADAPTIVE_PARTITION: + case REFINE_PARTITION: + agraph->nedges = gnedges = (gsize-(2+ncon)*gnvtxs)/2; + break; + default: + printf("WARNING: bad value for ctrl->partType %d\n", ctrl->partType); + agraph->nedges = gnedges = -1; + break; + } + + agraph->ncon = ncon; + + /*******************************************/ + /* Allocate memory for the assembled graph */ + /*******************************************/ + axadj = agraph->xadj = idxmalloc(gnvtxs+1, "AssembleGraph: axadj"); + avwgt = agraph->vwgt = idxmalloc(gnvtxs*ncon, "AssembleGraph: avwgt"); + anvwgt = agraph->nvwgt = fmalloc(gnvtxs*ncon, "AssembleGraph: anvwgt"); + aadjncy = agraph->adjncy = idxmalloc(gnedges, "AssembleGraph: adjncy"); + aadjwgt = agraph->adjwgt = idxmalloc(gnedges, "AssembleGraph: adjwgt"); + alabel = agraph->label = idxmalloc(gnvtxs, "AssembleGraph: alabel"); + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + avsize = agraph->vsize = idxmalloc(gnvtxs, "AssembleGraph: avsize"); + + for (k=j=i=0; ipartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + avsize[i] = ggraph[k++]; + for (l=0; lvwgt[i*ncon+j]) / (float)(ctrl->tvwgts[j]); + + for (i=0; i wspace->maxcore-mysize) + free(ggraph); + + return agraph; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initmsection.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initmsection.c new file mode 100644 index 0000000..63c7c35 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initmsection.c @@ -0,0 +1,242 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * initmsection.c + * + * This file contains code that performs the k-way multisection + * + * Started 6/3/97 + * George + * + * $Id: initmsection.c,v 1.2 2003/07/21 17:18:49 karypis Exp $ + */ + +#include + + +#define DEBUG_IPART_ + + + +/************************************************************************* +* This function is the entry point of the initial partitioning algorithm. +* This algorithm assembles the graph to all the processors and preceed +* serially. +**************************************************************************/ +void InitMultisection(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, lpecut[2], gpecut[2], mypart, moptions[10]; + idxtype *vtxdist, *gwhere = NULL, *part, *label; + GraphType *agraph; + int *sendcounts, *displs; + MPI_Comm newcomm, labelcomm; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + /* Assemble the graph and do the necessary pre-processing */ + agraph = AssembleMultisectedGraph(ctrl, graph, wspace); + part = agraph->where; + agraph->where = NULL; + + /* Split the processors into groups so that each one can do a bisection */ + mypart = ctrl->mype%(ctrl->nparts/2); + MPI_Comm_split(ctrl->comm, mypart, 0, &newcomm); + + /* Each processor keeps the graphs that it only needs and bisects it */ + agraph->ncon = 1; /* needed for Moc_KeepPart */ + Moc_KeepPart(agraph, wspace, part, mypart); + label = agraph->label; /* Save this because ipart may need it */ + agraph->label = NULL; + + /* Bisect the graph and construct the separator */ + switch (ctrl->ipart) { + case ISEP_EDGE: + moptions[0] = 1; + moptions[1] = 3; + moptions[2] = 1; + moptions[3] = 1; + moptions[4] = 0; + moptions[7] = ctrl->mype; + + agraph->where = idxmalloc(agraph->nvtxs, "InitMultisection: agraph->where"); + + METIS_EdgeComputeSeparator(&agraph->nvtxs, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, moptions, &agraph->mincut, agraph->where); + break; + case ISEP_NODE: + moptions[0] = 1; + moptions[1] = 3; + moptions[2] = 1; + moptions[3] = 2; + moptions[4] = 0; + moptions[7] = ctrl->mype; + + agraph->where = idxmalloc(agraph->nvtxs, "InitMultisection: agraph->where"); + + METIS_NodeComputeSeparator(&agraph->nvtxs, agraph->xadj, agraph->adjncy, agraph->vwgt, + agraph->adjwgt, moptions, &agraph->mincut, agraph->where); + break; + default: + errexit("Unknown ISEP type!\n"); + } + + for (i=0; invtxs; i++) { + ASSERT(ctrl, agraph->where[i]>=0 && agraph->where[i]<=2); + if (agraph->where[i] == 2) + agraph->where[i] = ctrl->nparts+2*mypart; + else + agraph->where[i] += 2*mypart; + } + + /* Determine which PE got the minimum cut */ + lpecut[0] = agraph->mincut; + MPI_Comm_rank(newcomm, lpecut+1); + MPI_Allreduce(lpecut, gpecut, 1, MPI_2INT, MPI_MINLOC, newcomm); + + /* myprintf(ctrl, "Nvtxs: %d, Mincut: %d, GMincut: %d, %d\n", agraph->nvtxs, agraph->mincut, gpecut[0], gpecut[1]); */ + + /* Send the best where to the root processor of this partition */ + if (lpecut[1] == gpecut[1] && gpecut[1] != 0) + MPI_Send((void *)agraph->where, agraph->nvtxs, IDX_DATATYPE, 0, 1, newcomm); + if (lpecut[1] == 0 && gpecut[1] != 0) + MPI_Recv((void *)agraph->where, agraph->nvtxs, IDX_DATATYPE, gpecut[1], 1, newcomm, &ctrl->status); + + /* Create a communicator that stores all the i-th processors of the newcomm */ + MPI_Comm_split(ctrl->comm, lpecut[1], 0, &labelcomm); + + /* Map the separator back to agraph. This is inefficient! */ + if (lpecut[1] == 0) { + gwhere = idxsmalloc(graph->gnvtxs, 0, "InitMultisection: gwhere"); + for (i=0; invtxs; i++) + gwhere[label[i]] = agraph->where[i]; + } + + free(agraph->where); + agraph->where = part; + + if (lpecut[1] == 0) { + MPI_Reduce((void *)gwhere, (void *)agraph->where, graph->gnvtxs, IDX_DATATYPE, MPI_SUM, 0, labelcomm); + free(gwhere); + } + + /* The minimum PE performs the Scatter */ + vtxdist = graph->vtxdist; + ASSERT(ctrl, graph->where != NULL); + free(graph->where); /* Remove the propagated down where info */ + graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "InitPartition: where"); + + sendcounts = imalloc(ctrl->npes, "InitPartitionNew: sendcounts"); + displs = imalloc(ctrl->npes, "InitPartitionNew: displs"); + + for (i=0; inpes; i++) { + sendcounts[i] = vtxdist[i+1]-vtxdist[i]; + displs[i] = vtxdist[i]; + } + + MPI_Scatterv((void *)agraph->where, sendcounts, displs, IDX_DATATYPE, + (void *)graph->where, graph->nvtxs, IDX_DATATYPE, 0, ctrl->comm); + + GKfree((void **)&sendcounts, (void **)&displs, (void **)&label, LTERM); + + FreeGraph(agraph); + + MPI_Comm_free(&newcomm); + MPI_Comm_free(&labelcomm); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + +} + + + + +/************************************************************************* +* This function assembles the graph into a single processor +**************************************************************************/ +GraphType *AssembleMultisectedGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j, k, l, gnvtxs, nvtxs, gnedges, nedges, gsize; + idxtype *xadj, *vwgt, *where, *adjncy, *adjwgt, *vtxdist, *imap; + idxtype *axadj, *aadjncy, *aadjwgt, *avwgt, *awhere, *alabel; + idxtype *mygraph, *ggraph; + int *recvcounts, *displs, mysize; + GraphType *agraph; + + gnvtxs = graph->gnvtxs; + nvtxs = graph->nvtxs; + nedges = graph->xadj[nvtxs]; + xadj = graph->xadj; + vwgt = graph->vwgt; + where = graph->where; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vtxdist = graph->vtxdist; + imap = graph->imap; + + /* Determine the # of idxtype to receive from each processor */ + recvcounts = imalloc(ctrl->npes, "AssembleGraph: recvcounts"); + mysize = 3*nvtxs + 2*nedges; + MPI_Allgather((void *)(&mysize), 1, MPI_INT, (void *)recvcounts, 1, MPI_INT, ctrl->comm); + + displs = imalloc(ctrl->npes+1, "AssembleGraph: displs"); + displs[0] = 0; + for (i=1; inpes+1; i++) + displs[i] = displs[i-1] + recvcounts[i-1]; + + /* Construct the one-array storage format of the assembled graph */ + mygraph = (mysize <= wspace->maxcore ? wspace->core : idxmalloc(mysize, "AssembleGraph: mygraph")); + for (k=i=0; inpes]; + ggraph = (gsize <= wspace->maxcore-mysize ? wspace->core+mysize : idxmalloc(gsize, "AssembleGraph: ggraph")); + MPI_Allgatherv((void *)mygraph, mysize, IDX_DATATYPE, (void *)ggraph, recvcounts, displs, IDX_DATATYPE, ctrl->comm); + + GKfree((void **)&recvcounts, (void **)&displs, LTERM); + if (mysize > wspace->maxcore) + free(mygraph); + + agraph = CreateGraph(); + agraph->nvtxs = gnvtxs; + agraph->nedges = gnedges = (gsize-3*gnvtxs)/2; + + /* Allocate memory for the assembled graph */ + axadj = agraph->xadj = idxmalloc(gnvtxs+1, "AssembleGraph: axadj"); + avwgt = agraph->vwgt = idxmalloc(gnvtxs, "AssembleGraph: avwgt"); + awhere = agraph->where = idxmalloc(gnvtxs, "AssembleGraph: awhere"); + aadjncy = agraph->adjncy = idxmalloc(gnedges, "AssembleGraph: adjncy"); + aadjwgt = agraph->adjwgt = idxmalloc(gnedges, "AssembleGraph: adjwgt"); + alabel = agraph->label = idxmalloc(gnvtxs, "AssembleGraph: alabel"); + + for (k=j=i=0; i wspace->maxcore-mysize) + free(ggraph); + + return agraph; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initpart.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initpart.c new file mode 100644 index 0000000..40b8d95 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/initpart.c @@ -0,0 +1,252 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * initpart.c + * + * This file contains code that performs log(p) parallel multilevel + * recursive bissection + * + * Started 3/4/96 + * George + * + * $Id: initpart.c,v 1.2 2003/07/21 17:18:49 karypis Exp $ + */ + +#include + + +#define DEBUG_IPART_ + + + +/************************************************************************* +* This function is the entry point of the initial partition algorithm +* that does recursive bissection. +* This algorithm assembles the graph to all the processors and preceeds +* by parallelizing the recursive bisection step. +**************************************************************************/ +void Moc_InitPartition_RB(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j; + int ncon, mype, npes, gnvtxs, ngroups; + idxtype *xadj, *adjncy, *adjwgt, *vwgt; + idxtype *part, *gwhere0, *gwhere1; + idxtype *tmpwhere, *tmpvwgt, *tmpxadj, *tmpadjncy, *tmpadjwgt; + GraphType *agraph; + int lnparts, fpart, fpe, lnpes; + int twoparts=2, numflag = 0, wgtflag = 3, moptions[10], edgecut, max_cut; + float *mytpwgts, mytpwgts2[2], lbvec[MAXNCON], lbsum, min_lbsum, wsum; + MPI_Comm ipcomm; + struct { + float sum; + int rank; + } lpesum, gpesum; + + ncon = graph->ncon; + ngroups = amax(amin(RIP_SPLIT_FACTOR, ctrl->npes), 1); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); + + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); + part = idxmalloc(agraph->nvtxs, "Moc_IP_RB: part"); + xadj = idxmalloc(agraph->nvtxs+1, "Moc_IP_RB: xadj"); + adjncy = idxmalloc(agraph->nedges, "Moc_IP_RB: adjncy"); + adjwgt = idxmalloc(agraph->nedges, "Moc_IP_RB: adjwgt"); + vwgt = idxmalloc(agraph->nvtxs*ncon, "Moc_IP_RB: vwgt"); + + idxcopy(agraph->nvtxs*ncon, agraph->vwgt, vwgt); + idxcopy(agraph->nvtxs+1, agraph->xadj, xadj); + idxcopy(agraph->nedges, agraph->adjncy, adjncy); + idxcopy(agraph->nedges, agraph->adjwgt, adjwgt); + + MPI_Comm_split(ctrl->gcomm, ctrl->mype % ngroups, 0, &ipcomm); + MPI_Comm_rank(ipcomm, &mype); + MPI_Comm_size(ipcomm, &npes); + + gnvtxs = agraph->nvtxs; + + gwhere0 = idxsmalloc(gnvtxs, 0, "Moc_IP_RB: gwhere0"); + gwhere1 = idxmalloc(gnvtxs, "Moc_IP_RB: gwhere1"); + + /* ADD: this assumes that tpwgts for all constraints is the same */ + /* ADD: this is necessary because serial metis does not support the general case */ + mytpwgts = fsmalloc(ctrl->nparts, 0.0, "mytpwgts"); + for (i=0; inparts; i++) + for (j=0; jtpwgts[i*ncon+j]; + for (i=0; inparts; i++) + mytpwgts[i] /= (float)ncon; + + /* Go into the recursive bisection */ + /* ADD: consider changing this to breadth-first type bisection */ + moptions[0] = 0; + moptions[7] = ctrl->sync + (ctrl->mype % ngroups) + 1; + + lnparts = ctrl->nparts; + fpart = fpe = 0; + lnpes = npes; + while (lnpes > 1 && lnparts > 1) { + /* Determine the weights of the partitions */ + mytpwgts2[0] = ssum(lnparts/2, mytpwgts+fpart); + mytpwgts2[1] = 1.0-mytpwgts2[0]; + + if (ncon == 1) + METIS_WPartGraphKway2(&agraph->nvtxs, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, &twoparts, mytpwgts2, + moptions, &edgecut, part); + else { + METIS_mCPartGraphRecursive2(&agraph->nvtxs, &ncon, agraph->xadj, + agraph->adjncy, agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, + &twoparts, mytpwgts2, moptions, &edgecut, part); + } + + wsum = ssum(lnparts/2, mytpwgts+fpart); + sscale(lnparts/2, 1.0/wsum, mytpwgts+fpart); + sscale(lnparts-lnparts/2, 1.0/(1.0-wsum), mytpwgts+fpart+lnparts/2); + + /* I'm picking the left branch */ + if (mype < fpe+lnpes/2) { + Moc_KeepPart(agraph, wspace, part, 0); + lnpes = lnpes/2; + lnparts = lnparts/2; + } + else { + Moc_KeepPart(agraph, wspace, part, 1); + fpart = fpart + lnparts/2; + fpe = fpe + lnpes/2; + lnpes = lnpes - lnpes/2; + lnparts = lnparts - lnparts/2; + } + } + + /* In case npes is greater than or equal to nparts */ + if (lnparts == 1) { + /* Only the first process will assign labels (for the reduction to work) */ + if (mype == fpe) { + for (i=0; invtxs; i++) + gwhere0[agraph->label[i]] = fpart; + } + } + /* In case npes is smaller than nparts */ + else { + if (ncon == 1) + METIS_WPartGraphKway2(&agraph->nvtxs, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, &lnparts, mytpwgts+fpart, + moptions, &edgecut, part); + else + METIS_mCPartGraphRecursive2(&agraph->nvtxs, &ncon, agraph->xadj, + agraph->adjncy, agraph->vwgt, agraph->adjwgt, &wgtflag, &numflag, + &lnparts, mytpwgts+fpart, moptions, &edgecut, part); + + for (i=0; invtxs; i++) + gwhere0[agraph->label[i]] = fpart + part[i]; + } + + MPI_Allreduce((void *)gwhere0, (void *)gwhere1, gnvtxs, IDX_DATATYPE, MPI_SUM, ipcomm); + + if (ngroups > 1) { + tmpxadj = agraph->xadj; + tmpadjncy = agraph->adjncy; + tmpadjwgt = agraph->adjwgt; + tmpvwgt = agraph->vwgt; + tmpwhere = agraph->where; + agraph->xadj = xadj; + agraph->adjncy = adjncy; + agraph->adjwgt = adjwgt; + agraph->vwgt = vwgt; + agraph->where = gwhere1; + agraph->vwgt = vwgt; + agraph->nvtxs = gnvtxs; + Moc_ComputeSerialBalance(ctrl, agraph, gwhere1, lbvec); + lbsum = ssum(ncon, lbvec); + + edgecut = ComputeSerialEdgeCut(agraph); + MPI_Allreduce((void *)&edgecut, (void *)&max_cut, 1, MPI_INT, MPI_MAX, ctrl->gcomm); + MPI_Allreduce((void *)&lbsum, (void *)&min_lbsum, 1, MPI_FLOAT, MPI_MIN, ctrl->gcomm); + + lpesum.sum = lbsum; + if (min_lbsum < UNBALANCE_FRACTION * (float)(ncon)) { + if (lbsum < UNBALANCE_FRACTION * (float)(ncon)) + lpesum.sum = (float) (edgecut); + else + lpesum.sum = (float) (max_cut); + } + + MPI_Comm_rank(ctrl->gcomm, &(lpesum.rank)); + MPI_Allreduce((void *)&lpesum, (void *)&gpesum, 1, MPI_FLOAT_INT, MPI_MINLOC, ctrl->gcomm); + MPI_Bcast((void *)gwhere1, gnvtxs, IDX_DATATYPE, gpesum.rank, ctrl->gcomm); + + agraph->xadj = tmpxadj; + agraph->adjncy = tmpadjncy; + agraph->adjwgt = tmpadjwgt; + agraph->vwgt = tmpvwgt; + agraph->where = tmpwhere; + } + + idxcopy(graph->nvtxs, gwhere1+graph->vtxdist[ctrl->mype], graph->where); + + FreeGraph(agraph); + MPI_Comm_free(&ipcomm); + GKfree((void **)&gwhere0, (void **)&gwhere1, (void **)&mytpwgts, (void **)&part, (void **)&xadj, (void **)&adjncy, (void **)&adjwgt, (void **)&vwgt, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->InitPartTmr)); + +} + + +/************************************************************************* +* This function keeps one parts +**************************************************************************/ +void Moc_KeepPart(GraphType *graph, WorkSpaceType *wspace, idxtype *part, int mypart) +{ + int h, i, j, k; + int nvtxs, ncon, mynvtxs, mynedges; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *label; + idxtype *rename; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + label = graph->label; + + rename = idxmalloc(nvtxs, "Moc_KeepPart: rename"); + + for (mynvtxs=0, i=0; invtxs = mynvtxs; + graph->nedges = mynedges; + + free(rename); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kmetis.c new file mode 100644 index 0000000..2ad20e3 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kmetis.c @@ -0,0 +1,274 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * kmetis.c + * + * This is the entry point of Moc_PARMETIS_PartGraphKway + * + * Started 10/19/96 + * George + * + * $Id: kmetis.c,v 1.9 2003/07/31 16:27:27 karypis Exp $ + * + */ + +#include + + +/*********************************************************************************** +* This function is the entry point of the parallel k-way multilevel partitionioner. +* This function assumes nothing about the graph distribution. +* It is the general case. +************************************************************************************/ +void ParMETIS_V3_PartKway(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm) +{ + int h, i; + int nvtxs = -1, npes, mype; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph; + float avg, maximb, *mytpwgts; + int moptions[10]; + int seed, dbglvl = 0; + int iwgtflag, inumflag, incon, inparts, ioptions[10]; + float *itpwgts, iubvec[MAXNCON]; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + + /********************************/ + /* Try and take care bad inputs */ + /********************************/ + if (options != NULL && options[0] == 1) + dbglvl = options[PMV3_OPTION_DBGLVL]; + + CheckInputs(STATIC_PARTITION, npes, dbglvl, wgtflag, &iwgtflag, numflag, &inumflag, ncon, + &incon, nparts, &inparts, tpwgts, &itpwgts, ubvec, iubvec, NULL, NULL, + options, ioptions, part, comm); + + + /*********************************/ + /* Take care the nparts = 1 case */ + /*********************************/ + if (inparts <= 1) { + idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); + *edgecut = 0; + return; + } + + /******************************/ + /* Take care of npes = 1 case */ + /******************************/ + if (npes == 1 && inparts > 1) { + moptions[0] = 0; + nvtxs = vtxdist[1]; + + if (incon == 1) { + METIS_WPartGraphKway(&nvtxs, xadj, adjncy, vwgt, adjwgt, &iwgtflag, &inumflag, + &inparts, itpwgts, moptions, edgecut, part); + } + else { + /* ADD: this is because METIS does not support tpwgts for all constraints */ + mytpwgts = fmalloc(inparts, "mytpwgts"); + for (i=0; inedges) == 0) { + IFSET(ctrl.dbglvl, DBG_INFO, rprintf(&ctrl, "Partitioning a graph of size %d serially\n", vtxdist[npes])); + PartitionSmallGraph(&ctrl, graph, &wspace); + } + else { + /***********************/ + /* Partition the graph */ + /***********************/ + Moc_Global_Partition(&ctrl, graph, &wspace); + ParallelReMapGraph(&ctrl, graph, &wspace); + } + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + + idxcopy(graph->nvtxs, graph->where, part); + *edgecut = graph->mincut; + + /*******************/ + /* Print out stats */ + /*******************/ + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + + if (ctrl.dbglvl&DBG_INFO) { + rprintf(&ctrl, "Final %d-way CUT: %6d \tBalance: ", inparts, graph->mincut); + avg = 0.0; + for (h=0; hgnpwgts[i*incon+h]/itpwgts[i*incon+h]); + avg += maximb; + rprintf(&ctrl, "%.3f ", maximb); + } + rprintf(&ctrl, " avg: %.3f\n", avg/(float)incon); + } + + GKfree((void **)&itpwgts, (void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, LTERM); + FreeInitialGraphAndRemap(graph, iwgtflag); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 0); + +} + + + +/************************************************************************* +* This function is the driver to the multi-constraint partitioning algorithm. +**************************************************************************/ +void Moc_Global_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, ncon, nparts; + float ftmp, ubavg, lbavg, lbvec[MAXNCON]; + + ncon = graph->ncon; + nparts = ctrl->nparts; + ubavg = savg(graph->ncon, ctrl->ubvec); + + SetUp(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + rprintf(ctrl, "[%6d %8d %5d %5d] [%d] [", graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), + GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo); + for (i=0; invwgt[samin_strd(graph->nvtxs, graph->nvwgt+i, ncon)*ncon+i])); + rprintf(ctrl, "] ["); + for (i=0; invwgt[samax_strd(graph->nvtxs, graph->nvwgt+i, ncon)*ncon+i])); + rprintf(ctrl, "]\n"); + } + + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || + (graph->finer != NULL && + graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + + /* Done with coarsening. Find a partition */ + graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "graph->where"); + Moc_InitPartition_RB(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + /* In case no coarsening took place */ + if (graph->finer == NULL) { + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + } + } + else { + Moc_GlobalMatch_Balance(ctrl, graph, wspace); + + Moc_Global_Partition(ctrl, graph->coarser, wspace); + + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); + + if (graph->ncon > 1 && graph->level < 3) { + for (i=0; ignpwgts+i, ncon); + if (ftmp != 0.0) + lbvec[i] = (float)(nparts) * + graph->gnpwgts[samax_strd(nparts, graph->gnpwgts+i, ncon)*ncon+i]/ftmp; + else + lbvec[i] = 1.0; + } + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.035) { + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + } + } + + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + if (graph->level != 0) + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, LTERM); + } + + return; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwaybalance.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwaybalance.c new file mode 100644 index 0000000..003ec7c --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwaybalance.c @@ -0,0 +1,456 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mkwaybalance.c + * + * This file contains code that performs the k-way refinement + * + * Started 3/1/96 + * George + * + * $Id: kwaybalance.c,v 1.2 2003/07/21 17:18:49 karypis Exp $ + */ + +#include + +#define ProperSide(c, from, other) \ + (((c) == 0 && (from)-(other) < 0) || ((c) == 1 && (from)-(other) > 0)) + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Moc_KWayBalance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +{ + int h, i, ii, iii, j, k, c; + int pass, nvtxs, nedges, ncon; + int nmoves, nmoved, nswaps; +/* int gnswaps; */ + int me, firstvtx, lastvtx, yourlastvtx; + int from, to = -1, oldto, oldcut, mydomain, yourdomain, imbalanced; + int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; + int nlupd, nsupd, nnbrs, nchanged; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; + idxtype *where, *tmp_where, *moved; + float *lnpwgts, *gnpwgts; + idxtype *update, *supdate, *rupdate, *pe_updates; + idxtype *changed, *perm, *pperm, *htable; + idxtype *peind, *recvptr, *sendptr; + KeyValueType *swchanges, *rwchanges; + RInfoType *rinfo, *myrinfo, *tmp_myrinfo, *tmp_rinfo; + EdgeType *tmp_edegrees, *my_edegrees, *your_edegrees; + float lbvec[MAXNCON], *nvwgt, *badmaxpwgt, *ubvec, *tpwgts, lbavg, ubavg; + int *nupds_pe; +/* int ndirty, nclean, dptr; */ + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); + + /*************************/ + /* set up common aliases */ + /*************************/ + nvtxs = graph->nvtxs; + nedges = graph->nedges; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + where = graph->where; + rinfo = graph->rinfo; + lnpwgts = graph->lnpwgts; + gnpwgts = graph->gnpwgts; + ubvec = ctrl->ubvec; + tpwgts = ctrl->tpwgts; + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvptr = graph->recvptr; + sendptr = graph->sendptr; + + changed = idxmalloc(nvtxs, "KWR: changed"); + rwchanges = wspace->pairs; + swchanges = rwchanges + recvptr[nnbrs]; + + /************************************/ + /* set up important data structures */ + /************************************/ + perm = idxmalloc(nvtxs, "KWR: perm"); + pperm = idxmalloc(nparts, "KWR: pperm"); + + update = idxmalloc(nvtxs, "KWR: update"); + supdate = wspace->indices; + rupdate = supdate + recvptr[nnbrs]; + nupds_pe = imalloc(npes, "KWR: nupds_pe"); + htable = idxsmalloc(nvtxs+graph->nrecv, 0, "KWR: lhtable"); + badmaxpwgt = fmalloc(nparts*ncon, "badmaxpwgt"); + + for (i=0; inrecv, "KWR: tmp_where"); + tmp_rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "KWR: tmp_rinfo"); + tmp_edegrees = (EdgeType *)GKmalloc(sizeof(EdgeType)*nedges, "KWR: tmp_edegrees"); + + idxcopy(nvtxs+graph->nrecv, where, tmp_where); + for (i=0; imincut; + if (mype == 0) + RandomPermute(nparts, pperm, 1); + MPI_Bcast((void *)pperm, nparts, IDX_DATATYPE, 0, ctrl->comm); + FastRandomPermute(nvtxs, perm, 1); + + /*****************************/ + /* move dirty vertices first */ + /*****************************/ +/* + ndirty = 0; + for (i=0; iwhere, lbvec); + ubavg = savg(ncon, ubvec); + lbavg = savg(ncon, lbvec); + imbalanced = (lbavg > ubavg) ? 1 : 0; + + for (c=0; c<2; c++) { + nmoved = 0; + + /**********************************************/ + /* PASS ONE -- record stats for desired moves */ + /**********************************************/ + for (iii=0; iiinvwgt+i*ncon; + + for (h=0; h= tmp_rinfo[i].id) { + my_edegrees = tmp_rinfo[i].degrees; + + for (k=0; k= nvtxs) + continue; + + me = ladjncy[j]; + mydomain = tmp_where[me]; + + myrinfo = tmp_rinfo+me; + your_edegrees = myrinfo->degrees; + + if (mydomain == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (mydomain == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution from the .ed of 'from' */ + if (mydomain != from) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == from) { + if (your_edegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; + your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; + } + else { + your_edegrees[k].ewgt -= adjwgt[j]; + } + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (mydomain != to) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == to) { + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + your_edegrees[myrinfo->ndegrees].edge = to; + your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + } + } + + /*************************************************/ + /* PASS TWO -- commit the remainder of the moves */ + /*************************************************/ + nlupd = nsupd = nmoves = nchanged = 0; + for (iii=0; iiipexadj[i+1]-graph->pexadj[i] > 0) + changed[nchanged++] = i; + } + + /* Tell interested pe's the new where[] info for the interface vertices */ + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, + swchanges, rwchanges, wspace->pv4); + + + IFSET(ctrl->dbglvl, DBG_RMOVEINFO, + rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", + pass, c, badmaxpwgt[0], + GlobalSESum(ctrl, nmoves), + GlobalSESum(ctrl, nsupd), + GlobalSESum(ctrl, nlupd))); + + /*------------------------------------------------------------- + / Time to communicate with processors to send the vertices + / whose degrees need to be update. + /-------------------------------------------------------------*/ + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next. This needs some preporcessing */ + for (i=0; iimap[supdate[i]]; + } + iidxsort(nsupd, supdate); + + for (j=i=0; icomm, ctrl->sreq+i); + j = k; + } + + /* OK, now get into the loop waiting for the send/recv operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nupds_pe+i); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*------------------------------------------------------------- + / Place the recieved to-be updated vertices into update[] + /-------------------------------------------------------------*/ + for (i=0; idegrees; + your_edegrees = tmp_myrinfo->degrees; + + graph->lmincut -= myrinfo->ed; + myrinfo->ndegrees = 0; + myrinfo->id = 0; + myrinfo->ed = 0; + + for (j=xadj[i]; jed += adjwgt[j]; + + for (k=0; kndegrees; k++) { + if (my_edegrees[k].edge == yourdomain) { + my_edegrees[k].ewgt += adjwgt[j]; + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + my_edegrees[k].edge = yourdomain; + my_edegrees[k].ewgt = adjwgt[j]; + your_edegrees[k].edge = yourdomain; + your_edegrees[k].ewgt = adjwgt[j]; + myrinfo->ndegrees++; + } + ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + ASSERT(ctrl, tmp_myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + + } + else { + myrinfo->id += adjwgt[j]; + } + } + graph->lmincut += myrinfo->ed; + + tmp_myrinfo->id = myrinfo->id; + tmp_myrinfo->ed = myrinfo->ed; + tmp_myrinfo->ndegrees = myrinfo->ndegrees; + } + + /* finally, sum-up the partition weights */ + MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, + MPI_FLOAT, MPI_SUM, ctrl->comm); + } + graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; + + if (graph->mincut == oldcut) + break; + } + +/* + gnswaps = GlobalSESum(ctrl, nswaps); + if (mype == 0) + printf("niters: %d, nswaps: %d\n", pass+1, gnswaps); +*/ + + GKfree((void **)&badmaxpwgt, (void **)&update, (void **)&nupds_pe, (void **)&htable, LTERM); + GKfree((void **)&changed, (void **)&pperm, (void **)&perm, (void **)&moved, LTERM); + GKfree((void **)&tmp_where, (void **)&tmp_rinfo, (void **)&tmp_edegrees, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayfm.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayfm.c new file mode 100644 index 0000000..4d0849b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayfm.c @@ -0,0 +1,599 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mkwayfm.c + * + * This file contains code that performs the k-way refinement + * + * Started 3/1/96 + * George + * + * $Id: kwayfm.c,v 1.3 2003/07/22 20:29:05 karypis Exp $ + */ + +#include + +#define ProperSide(c, from, other) \ + (((c) == 0 && (from)-(other) < 0) || ((c) == 1 && (from)-(other) > 0)) + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Moc_KWayFM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses) +{ + int h, i, ii, iii, j, k, c; + int pass, nvtxs, nedges, ncon; + int nmoves, nmoved, nswaps, nzgswaps; +/* int gnswaps, gnzgswaps; */ + int me, firstvtx, lastvtx, yourlastvtx; + int from, to = -1, oldto, oldcut, mydomain, yourdomain, imbalanced, overweight; + int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; + int nlupd, nsupd, nnbrs, nchanged; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; + idxtype *where, *tmp_where, *moved; + float *lnpwgts, *gnpwgts, *ognpwgts, *pgnpwgts, *movewgts, *overfill; + idxtype *update, *supdate, *rupdate, *pe_updates; + idxtype *changed, *perm, *pperm, *htable; + idxtype *peind, *recvptr, *sendptr; + KeyValueType *swchanges, *rwchanges; + RInfoType *rinfo, *myrinfo, *tmp_myrinfo, *tmp_rinfo; + EdgeType *tmp_edegrees, *my_edegrees, *your_edegrees; + float lbvec[MAXNCON], *nvwgt, *badmaxpwgt, *ubvec, *tpwgts, lbavg, ubavg; + int *nupds_pe; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); + + /*************************/ + /* set up common aliases */ + /*************************/ + nvtxs = graph->nvtxs; + nedges = graph->nedges; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + where = graph->where; + rinfo = graph->rinfo; + lnpwgts = graph->lnpwgts; + gnpwgts = graph->gnpwgts; + ubvec = ctrl->ubvec; + tpwgts = ctrl->tpwgts; + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvptr = graph->recvptr; + sendptr = graph->sendptr; + + changed = idxmalloc(nvtxs, "KWR: changed"); + rwchanges = wspace->pairs; + swchanges = rwchanges + recvptr[nnbrs]; + + /************************************/ + /* set up important data structures */ + /************************************/ + perm = idxmalloc(nvtxs, "KWR: perm"); + pperm = idxmalloc(nparts, "KWR: pperm"); + + update = idxmalloc(nvtxs, "KWR: update"); + supdate = wspace->indices; + rupdate = supdate + recvptr[nnbrs]; + nupds_pe = imalloc(npes, "KWR: nupds_pe"); + htable = idxsmalloc(nvtxs+graph->nrecv, 0, "KWR: lhtable"); + badmaxpwgt = fmalloc(nparts*ncon, "badmaxpwgt"); + + for (i=0; inrecv, "KWR: tmp_where"); + tmp_rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "KWR: tmp_rinfo"); + tmp_edegrees = (EdgeType *)GKmalloc(sizeof(EdgeType)*nedges, "KWR: tmp_edegrees"); + + idxcopy(nvtxs+graph->nrecv, where, tmp_where); + for (i=0; icomm); + FastRandomPermute(nvtxs, perm, 1); + oldcut = graph->mincut; + + /* check to see if the partitioning is imbalanced */ + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + ubavg = savg(ncon, ubvec); + lbavg = savg(ncon, lbvec); + imbalanced = (lbavg > ubavg) ? 1 : 0; + + for (c=0; c<2; c++) { + scopy(ncon*nparts, gnpwgts, ognpwgts); + sset(ncon*nparts, 0.0, movewgts); + nmoved = 0; + + /**********************************************/ + /* PASS ONE -- record stats for desired moves */ + /**********************************************/ + for (iii=0; iiinvwgt+i*ncon; + + for (h=0; h= tmp_rinfo[i].id) { + my_edegrees = tmp_rinfo[i].degrees; + + for (k=0; k badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) + break; + + if (h == ncon) + break; + } + } + oldto = to; + + /* check if a subdomain was found that fits */ + if (k < tmp_rinfo[i].ndegrees) { + for (j=k+1; j badmaxpwgt[to*ncon+h] && nvwgt[h] > 0.0) + break; + + if (h == ncon) { + if (my_edegrees[j].ewgt > my_edegrees[k].ewgt || + (my_edegrees[j].ewgt == my_edegrees[k].ewgt && + IsHBalanceBetterTT(ncon,gnpwgts+oldto*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ + k = j; + oldto = my_edegrees[k].edge; + } + } + } + } + to = oldto; + + if (my_edegrees[k].ewgt > tmp_rinfo[i].id || + (my_edegrees[k].ewgt == tmp_rinfo[i].id && + (imbalanced || graph->level > 3 || iii % 8 == 0) && + IsHBalanceBetterFT(ncon,gnpwgts+from*ncon,gnpwgts+to*ncon,nvwgt,ubvec))){ + + /****************************************/ + /* Update tmp arrays of the moved vertex */ + /****************************************/ + tmp_where[i] = to; + moved[nmoved++] = i; + for (h=0; h= nvtxs) + continue; + + me = ladjncy[j]; + mydomain = tmp_where[me]; + + myrinfo = tmp_rinfo+me; + your_edegrees = myrinfo->degrees; + + if (mydomain == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (mydomain == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution from the .ed of 'from' */ + if (mydomain != from) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == from) { + if (your_edegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; + your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; + } + else { + your_edegrees[k].ewgt -= adjwgt[j]; + } + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (mydomain != to) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == to) { + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + your_edegrees[myrinfo->ndegrees].edge = to; + your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + } + } + + /******************************************/ + /* Let processors know the subdomain wgts */ + /* if all proposed moves commit. */ + /******************************************/ + MPI_Allreduce((void *)lnpwgts, (void *)pgnpwgts, nparts*ncon, + MPI_FLOAT, MPI_SUM, ctrl->comm); + + /**************************/ + /* compute overfill array */ + /**************************/ + overweight = 0; + for (j=0; j ognpwgts[j*ncon+h]) { + overfill[j*ncon+h] = + (pgnpwgts[j*ncon+h]-badmaxpwgt[j*ncon+h]) / + (pgnpwgts[j*ncon+h]-ognpwgts[j*ncon+h]); + } + else { + overfill[j*ncon+h] = 0.0; + } + + overfill[j*ncon+h] = amax(overfill[j*ncon+h], 0.0); + overfill[j*ncon+h] *= movewgts[j*ncon+h]; + + if (overfill[j*ncon+h] > 0.0) + overweight = 1; + + ASSERTP(ctrl, ognpwgts[j*ncon+h] <= badmaxpwgt[j*ncon+h] || + pgnpwgts[j*ncon+h] <= ognpwgts[j*ncon+h], + (ctrl, "%.4f %.4f %.4f\n", ognpwgts[j*ncon+h], + badmaxpwgt[j*ncon+h], pgnpwgts[j*ncon+h])); + } + } + + /****************************************************/ + /* select moves to undo according to overfill array */ + /****************************************************/ + if (overweight == 1) { + for (iii=0; iiinvwgt+i*ncon; + my_edegrees = tmp_rinfo[i].degrees; + + for (k=0; k 0.0 && overfill[oldto*ncon+h] > nvwgt[h]/4.0) + break; + + /**********************************/ + /* nullify this move if necessary */ + /**********************************/ + if (k != tmp_rinfo[i].ndegrees && h != ncon) { + moved[iii] = -1; + from = oldto; + to = where[i]; + + for (h=0; h= nvtxs) + continue; + + me = ladjncy[j]; + mydomain = tmp_where[me]; + + myrinfo = tmp_rinfo+me; + your_edegrees = myrinfo->degrees; + + if (mydomain == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (mydomain == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution from the .ed of 'from' */ + if (mydomain != from) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == from) { + if (your_edegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + your_edegrees[k].edge = your_edegrees[myrinfo->ndegrees].edge; + your_edegrees[k].ewgt = your_edegrees[myrinfo->ndegrees].ewgt; + } + else { + your_edegrees[k].ewgt -= adjwgt[j]; + } + break; + } + } + } + + /* Add contribution to the .ed of 'to' */ + if (mydomain != to) { + for (k=0; kndegrees; k++) { + if (your_edegrees[k].edge == to) { + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + your_edegrees[myrinfo->ndegrees].edge = to; + your_edegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + } + + /*************************************************/ + /* PASS TWO -- commit the remainder of the moves */ + /*************************************************/ + nlupd = nsupd = nmoves = nchanged = 0; + for (iii=0; iiipexadj[i+1]-graph->pexadj[i] > 0) + changed[nchanged++] = i; + } + + /* Tell interested pe's the new where[] info for the interface vertices */ + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, + swchanges, rwchanges, wspace->pv4); + + + IFSET(ctrl->dbglvl, DBG_RMOVEINFO, + rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", + pass, c, badmaxpwgt[0], + GlobalSESum(ctrl, nmoves), + GlobalSESum(ctrl, nsupd), + GlobalSESum(ctrl, nlupd))); + + /*------------------------------------------------------------- + / Time to communicate with processors to send the vertices + / whose degrees need to be update. + /-------------------------------------------------------------*/ + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next. This needs some preporcessing */ + for (i=0; iimap[supdate[i]]; + } + iidxsort(nsupd, supdate); + + for (j=i=0; icomm, ctrl->sreq+i); + j = k; + } + + /* OK, now get into the loop waiting for the send/recv operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nupds_pe+i); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*------------------------------------------------------------- + / Place the recieved to-be updated vertices into update[] + /-------------------------------------------------------------*/ + for (i=0; idegrees; + your_edegrees = tmp_myrinfo->degrees; + + graph->lmincut -= myrinfo->ed; + myrinfo->ndegrees = 0; + myrinfo->id = 0; + myrinfo->ed = 0; + + for (j=xadj[i]; jed += adjwgt[j]; + + for (k=0; kndegrees; k++) { + if (my_edegrees[k].edge == yourdomain) { + my_edegrees[k].ewgt += adjwgt[j]; + your_edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + my_edegrees[k].edge = yourdomain; + my_edegrees[k].ewgt = adjwgt[j]; + your_edegrees[k].edge = yourdomain; + your_edegrees[k].ewgt = adjwgt[j]; + myrinfo->ndegrees++; + } + ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + ASSERT(ctrl, tmp_myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + + } + else { + myrinfo->id += adjwgt[j]; + } + } + graph->lmincut += myrinfo->ed; + + tmp_myrinfo->id = myrinfo->id; + tmp_myrinfo->ed = myrinfo->ed; + tmp_myrinfo->ndegrees = myrinfo->ndegrees; + } + + /* finally, sum-up the partition weights */ + MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, + MPI_FLOAT, MPI_SUM, ctrl->comm); + } + graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; + + if (graph->mincut == oldcut) + break; + } + +/* + gnswaps = GlobalSESum(ctrl, nswaps); + gnzgswaps = GlobalSESum(ctrl, nzgswaps); + if (mype == 0) + printf("niters: %d, nswaps: %d, nzgswaps: %d\n", pass+1, gnswaps, gnzgswaps); +*/ + + GKfree((void **)&badmaxpwgt, (void **)&update, (void **)&nupds_pe, (void **)&htable, LTERM); + GKfree((void **)&changed, (void **)&pperm, (void **)&perm, (void **)&moved, LTERM); + GKfree((void **)&pgnpwgts, (void **)&ognpwgts, (void **)&overfill, (void **)&movewgts, LTERM); + GKfree((void **)&tmp_where, (void **)&tmp_rinfo, (void **)&tmp_edegrees, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayrefine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayrefine.c new file mode 100644 index 0000000..e4b776e --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/kwayrefine.c @@ -0,0 +1,239 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * medge_refine.c + * + * This file contains code that performs the k-way refinement + * + * Started 3/1/96 + * George + * + * $Id: kwayrefine.c,v 1.2 2003/07/21 17:18:49 karypis Exp $ + */ + +#include + +#define ProperSide(c, from, other) \ + (((c) == 0 && (from)-(other) < 0) || ((c) == 1 && (from)-(other) > 0)) + +/************************************************************************* +* This function projects a partition. +**************************************************************************/ +void Moc_ProjectPartition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, nvtxs, nnbrs = -1, firstvtx, cfirstvtx; + idxtype *match, *cmap, *where, *cwhere; + idxtype *peind, *slens = NULL, *rlens = NULL; + KeyValueType *rcand, *scand = NULL; + GraphType *cgraph; + + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ProjectTmr)); + + cgraph = graph->coarser; + cwhere = cgraph->where; + cfirstvtx = cgraph->vtxdist[ctrl->mype]; + + nvtxs = graph->nvtxs; + match = graph->match; + cmap = graph->cmap; + where = graph->where = idxmalloc(nvtxs+graph->nrecv, "ProjectPartition: graph->where"); + firstvtx = graph->vtxdist[ctrl->mype]; + + + if (graph->match_type == MATCH_GLOBAL) { /* Only if global matching is on */ + /*------------------------------------------------------------ + / Start the transmission of the remote where information + /------------------------------------------------------------*/ + scand = wspace->pairs; + nnbrs = graph->nnbrs; + peind = graph->peind; + slens = graph->slens; + rlens = graph->rlens; + rcand = graph->rcand; + + /* Issue the receives first */ + for (i=0; i 0) /* Issue a receive only if you are getting something */ + MPI_Irecv((void *)(scand+slens[i]), 2*(slens[i+1]-slens[i]), IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); + } + +#ifdef DEBUG_PROJECT + PrintPairs(ctrl, rlens[nnbrs], rcand, "rcand"); +#endif + + /* Put the where[rcand[].key] into the val field */ + for (i=0; i= 0 && rcand[i].val < cgraph->nvtxs); + rcand[i].val = cwhere[rcand[i].val]; + } + +#ifdef DEBUG_PROJECT + PrintPairs(ctrl, rlens[nnbrs], rcand, "rcand"); + PrintVector(ctrl, nvtxs, firstvtx, cmap, "cmap"); +#endif + + /* Issue the sends next */ + for (i=0; i 0) /* Issue a send only if you are sending something */ + MPI_Isend((void *)(rcand+rlens[i]), 2*(rlens[i+1]-rlens[i]), IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); + } + } + + /*------------------------------------------------------------ + / Project local vertices first + /------------------------------------------------------------*/ + for (i=0; i= KEEP_BIT) { + ASSERT(ctrl, cmap[i]-cfirstvtx>=0 && cmap[i]-cfirstvtxnvtxs); + where[i] = cwhere[cmap[i]-cfirstvtx]; + } + } + + if (graph->match_type == MATCH_GLOBAL) { /* Only if global matching is on */ + /*------------------------------------------------------------ + / Wait for the nonblocking operations to finish + /------------------------------------------------------------*/ + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + +#ifdef DEBUG_PROJECT + PrintPairs(ctrl, slens[nnbrs], scand, "scand"); +#endif + + /*------------------------------------------------------------ + / Project received vertices now + /------------------------------------------------------------*/ + for (i=0; i=0 && scand[i].key-firstvtxnvtxs, (ctrl, "%d %d %d\n", scand[i].key, firstvtx, graph->nvtxs)); + where[scand[i].key-firstvtx] = scand[i].val; + } + } + + + FreeGraph(graph->coarser); + graph->coarser = NULL; + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ProjectTmr)); +} + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Moc_ComputePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int h, i, j, k; + int nvtxs, ncon; + int firstvtx, lastvtx; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist; + float *lnpwgts, *gnpwgts; + idxtype *where, *swhere, *rwhere; + RInfoType *rinfo, *myrinfo; + EdgeType *edegrees; + int me, other; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); + + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + + where = graph->where; + rinfo = graph->rinfo = (RInfoType *)GKmalloc(sizeof(RInfoType)*nvtxs, "CPP: rinfo"); + lnpwgts = graph->lnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: lnpwgts"); + gnpwgts = graph->gnpwgts = fmalloc(ctrl->nparts*ncon, "CPP: gnpwgts"); + + sset(ctrl->nparts*ncon, 0, lnpwgts); + + firstvtx = vtxdist[ctrl->mype]; + lastvtx = vtxdist[ctrl->mype+1]; + + /*------------------------------------------------------------ + / Send/Receive the where information of interface vertices + /------------------------------------------------------------*/ + swhere = wspace->indices; + rwhere = where + nvtxs; + + CommInterfaceData(ctrl, graph, where, swhere, rwhere); + +#ifdef DEBUG_COMPUTEPPARAM + PrintVector(ctrl, nvtxs, firstvtx, where, "where"); +#endif + + ASSERT(ctrl, wspace->nlarge >= xadj[nvtxs]); + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + graph->lmincut = 0; + for (i=0; invwgt[i*ncon+h]; + + myrinfo->degrees = wspace->degrees + xadj[i]; + myrinfo->ndegrees = myrinfo->id = myrinfo->ed = 0; + + for (j=xadj[i]; jid += adjwgt[j]; + else + myrinfo->ed += adjwgt[j]; + } + + + if (myrinfo->ed > 0) { /* Time to do some serious work */ + graph->lmincut += myrinfo->ed; + edegrees = myrinfo->degrees; + + for (j=xadj[i]; jndegrees; k++) { + if (edegrees[k].edge == other) { + edegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + edegrees[k].edge = other; + edegrees[k].ewgt = adjwgt[j]; + myrinfo->ndegrees++; + } + ASSERT(ctrl, myrinfo->ndegrees <= xadj[i+1]-xadj[i]); + } + } + } + } + +#ifdef DEBUG_COMPUTEPPARAM + PrintVector(ctrl, ctrl->nparts*ncon, 0, lnpwgts, "lnpwgts"); +#endif + + /* Finally, sum-up the partition weights */ + MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, ctrl->nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); + + graph->mincut = GlobalSESum(ctrl, graph->lmincut)/2; + +#ifdef DEBUG_COMPUTEPPARAM + PrintVector(ctrl, ctrl->nparts*ncon, 0, gnpwgts, "gnpwgts"); +#endif + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayInitTmr)); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/lmatch.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/lmatch.c new file mode 100644 index 0000000..d8601ef --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/lmatch.c @@ -0,0 +1,364 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * coarsen.c + * + * This file contains code that finds a matching and performs the coarsening + * + * Started 2/22/96 + * George + * + * $Id: lmatch.c,v 1.2 2003/07/21 17:18:50 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function finds a HEM matching between local vertices only +**************************************************************************/ +void Mc_LocalMatch_HEM(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int h, i, ii, j, k; + int nvtxs, ncon, cnvtxs, firstvtx, maxi, maxidx, edge; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *home, *myhome, *shome, *rhome; + idxtype *perm, *match; + float maxnvwgt, *nvwgt; + + graph->match_type = MATCH_LOCAL; + maxnvwgt = 1.0/((float)(ctrl->nparts)*MAXVWGT_FACTOR); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + home = graph->home; + + vtxdist = graph->vtxdist; + firstvtx = vtxdist[ctrl->mype]; + + match = graph->match = idxmalloc(nvtxs+graph->nrecv, "HEM_Match: match"); + myhome = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: myhome"); + + idxset(nvtxs, UNMATCHED, match); + idxset(graph->nrecv, 0, match+nvtxs); /* Easy way to handle remote vertices */ + + /*------------------------------------------------------------ + / Send/Receive the home information of interface vertices + /------------------------------------------------------------*/ + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + idxcopy(nvtxs, home, myhome); + shome = wspace->indices; + rhome = myhome + nvtxs; + CommInterfaceData(ctrl, graph, myhome, shome, rhome); + } + + /************************************************************* + * Go now and find a local matching + *************************************************************/ + perm = wspace->indices; + FastRandomPermute(nvtxs, perm, 1); + cnvtxs = 0; + for (ii=0; ii maxnvwgt) + break; + + if (h == ncon) { + for (j=xadj[i]; j= nvtxs) + continue; + + for (h=0; h maxnvwgt) + break; + + if (h == ncon) { + if (match[edge] == UNMATCHED && + (maxi == -1 || + adjwgt[maxi] < adjwgt[j] || + (adjwgt[maxi] == adjwgt[j] && + BetterVBalance(ncon,nvwgt+i*ncon,nvwgt+maxidx*ncon,nvwgt+edge*ncon) >= 0))) { + maxi = j; + maxidx = edge; + } + } + } + } + + if (maxi != -1) { + k = ladjncy[maxi]; + if (i <= k) { + match[i] = firstvtx+k + KEEP_BIT; + match[k] = firstvtx+i; + } + else { + match[i] = firstvtx+k; + match[k] = firstvtx+i + KEEP_BIT; + } + } + else { + match[i] = (firstvtx+i) + KEEP_BIT; + } + cnvtxs++; + } + } + + CommInterfaceData(ctrl, graph, match, wspace->indices, match+nvtxs); + GKfree((void **)(&myhome), LTERM); + +#ifdef DEBUG_MATCH + PrintVector2(ctrl, nvtxs, firstvtx, match, "Match1"); +#endif + + + if (ctrl->dbglvl&DBG_MATCHINFO) { + PrintVector2(ctrl, nvtxs, firstvtx, match, "Match"); + myprintf(ctrl, "Cnvtxs: %d\n", cnvtxs); + rprintf(ctrl, "Done with matching...\n"); + } + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); + Mc_Local_CreateCoarseGraph(ctrl, graph, wspace, cnvtxs); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); + +} + + + + + +/************************************************************************* +* This function creates the coarser graph +**************************************************************************/ +void Mc_Local_CreateCoarseGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int cnvtxs) +{ + int h, i, j, k, l; + int nvtxs, ncon, nedges, firstvtx, cfirstvtx; + int npes=ctrl->npes, mype=ctrl->mype; + int cnedges, v, u; + idxtype *xadj, *vwgt, *vsize, *ladjncy, *adjwgt, *vtxdist, *where, *home; + idxtype *match, *cmap; + idxtype *cxadj, *cvwgt, *cvsize = NULL, *cadjncy, *cadjwgt, *cvtxdist, *chome = NULL, *cwhere = NULL; + float *cnvwgt; + GraphType *cgraph; + int mask=(1<<13)-1, htable[8192], htableidx[8192]; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + vwgt = graph->vwgt; + home = graph->home; + vsize = graph->vsize; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + match = graph->match; + + firstvtx = vtxdist[mype]; + + cmap = graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CreateCoarseGraph: cmap"); + + /* Initialize the coarser graph */ + cgraph = CreateGraph(); + cgraph->nvtxs = cnvtxs; + cgraph->level = graph->level+1; + cgraph->ncon = ncon; + + 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]; + + /* Create the cmap of what you know so far locally */ + cnvtxs = 0; + for (i=0; i= KEEP_BIT) { + k = match[i] - KEEP_BIT; + if (kindices, cmap+nvtxs); + + +#ifdef DEBUG_CONTRACT + PrintVector(ctrl, nvtxs, firstvtx, cmap, "Cmap"); +#endif + + + + /************************************************************* + * 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"); + cnvwgt = cgraph->nvwgt = fmalloc(cnvtxs*ncon, "CreateCoarserGraph: cnvwgt"); + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + chome = cgraph->home = idxmalloc(cnvtxs, "CreateCoarserGraph: chome"); + if (vsize != NULL) + cvsize = cgraph->vsize = idxmalloc(cnvtxs, "CreateCoarserGraph: cvsize"); + if (where != NULL) + cwhere = cgraph->where = idxmalloc(cnvtxs, "CreateCoarserGraph: cwhere"); + cadjncy = idxmalloc(2*graph->nedges, "CreateCoarserGraph: cadjncy"); + cadjwgt = cadjncy+graph->nedges; + + iset(8192, -1, htable); + + cxadj[0] = cnvtxs = cnedges = 0; + for (i=0; i u) + continue; /* I have already collapsed it as (u,v) */ + + /* Collapse the v vertex first, which you know that is local */ + for (h=0; hpartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + chome[cnvtxs] = home[i]; + if (vsize != NULL) + cvsize[cnvtxs] = vsize[i]; + if (where != NULL) + cwhere[cnvtxs] = where[i]; + nedges = 0; + + for (j=xadj[i]; jnedges = cnedges; + + 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); + GKfree((void **)&cadjncy, (void **)&graph->where, LTERM); /* Note that graph->where works fine even if it is NULL */ + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/macros.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/macros.h new file mode 100644 index 0000000..31861f7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/macros.h @@ -0,0 +1,163 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * macros.h + * + * This file contains macros used in multilevel + * + * Started 9/25/94 + * George + * + * $Id: macros.h,v 1.8 2003/07/21 19:11:46 karypis Exp $ + * + */ + + +/************************************************************************* +* The following macro returns a random number in the specified range +**************************************************************************/ +#define RandomInRange(u) ((int)(1.0*(u)*rand()/(RAND_MAX+1.0))) + +#define amax(a, b) ((a) >= (b) ? (a) : (b)) +#define amin(a, b) ((a) >= (b) ? (b) : (a)) + +#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) +#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) +#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) + +#define SWAP(a, b, tmp) \ + do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) + +#define INC_DEC(a, b, val) \ + do {(a) += (val); (b) -= (val);} while(0) + + +#define icopy(n, a, b) memcpy((b), (a), sizeof(int)*(n)) +#define scopy(n, a, b) memcpy((b), (a), sizeof(float)*(n)) +#define idxcopy(n, a, b) memcpy((b), (a), sizeof(idxtype)*(n)) + +#define HASHFCT(key, size) ((key)%(size)) + + +/************************************************************************* +* Timer macros +**************************************************************************/ +#define cleartimer(tmr) (tmr = 0.0) +#define starttimer(tmr) (tmr -= MPI_Wtime()) +#define stoptimer(tmr) (tmr += MPI_Wtime()) +#define gettimer(tmr) (tmr) + + +/************************************************************************* +* This macro is used to handle dbglvl +**************************************************************************/ +#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd); + +/************************************************************************* +* These macros are used for debuging memory leaks +**************************************************************************/ +#ifdef DMALLOC +#define imalloc(n, msg) (malloc(sizeof(int)*(n))) +#define fmalloc(n, msg) (malloc(sizeof(float)*(n))) +#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n))) +#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n)))) +#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n)))) +#define GKmalloc(a, b) (malloc(a)) +#endif + +#ifdef DMALLOC +# define MALLOC_CHECK(ptr); +/* +# define MALLOC_CHECK(ptr) \ + if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) { \ + printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +*/ +#else +# define MALLOC_CHECK(ptr) ; +#endif + +/************************************************************************* +* This macro converts a length array in a CSR one +**************************************************************************/ +#define MAKECSR(i, n, a) \ + do { \ + for (i=1; i0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + +#define SHIFTCSR(i, n, a) \ + do { \ + for (i=n; i>0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + + +#ifdef DEBUG +# define ASSERT(ctrl, expr) \ + if (!(expr)) { \ + myprintf(ctrl, "***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERT(ctrl, expr) ; +#endif + +#ifdef DEBUG +# define ASSERTP(ctrl, expr, msg) \ + if (!(expr)) { \ + myprintf(ctrl, "***ASSERTION failed on line %d of file %s:" #expr "\n", \ + __LINE__, __FILE__); \ + myprintf msg ; \ + abort(); \ + } +#else +# define ASSERTP(ctrl, expr,msg) ; +#endif + +#ifdef DEBUGS +# define ASSERTS(expr) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERTS(expr) ; +#endif + +#ifdef DEBUGS +# define ASSERTSP(expr, msg) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + printf msg ; \ + abort(); \ + } +#else +# define ASSERTSP(expr, msg) ; +#endif + +/************************************************************************* + * * These macros insert and remove nodes from the boundary list + * **************************************************************************/ +#define BNDInsert(nbnd, bndind, bndptr, vtx) \ + do { \ + bndind[nbnd] = vtx; \ + bndptr[vtx] = nbnd++;\ + } while(0) + +#define BNDDelete(nbnd, bndind, bndptr, vtx) \ + do { \ + bndind[bndptr[vtx]] = bndind[--nbnd]; \ + bndptr[bndind[nbnd]] = bndptr[vtx]; \ + bndptr[vtx] = -1; \ + } while(0) + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/match.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/match.c new file mode 100644 index 0000000..89bfa62 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/match.c @@ -0,0 +1,320 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mmatch.c + * + * This file contains code that finds a matching + * + * Started 2/22/96 + * George + * + * $Id: match.c,v 1.2 2003/07/21 17:18:50 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function finds a matching +**************************************************************************/ +void Moc_GlobalMatch_Balance(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int h, i, ii, j, k; + int nnbrs, nvtxs, ncon, cnvtxs, firstvtx, lastvtx, maxi, maxidx, nkept; + int otherlastvtx, nrequests, nchanged, pass, nmatched, wside; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *home, *myhome, *shome, *rhome; + idxtype *match, *rmatch, *smatch; + idxtype *peind, *sendptr, *recvptr; + idxtype *perm, *iperm, *nperm, *changed; + float *nvwgt, maxnvwgt; + int *nreqs_pe; + KeyValueType *match_requests, *match_granted, *pe_requests; + + maxnvwgt = 1.0/((float)(ctrl->nparts)*MAXNVWGT_FACTOR); + + graph->match_type = MATCH_GLOBAL; + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MatchTmr)); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + home = graph->home; + nvwgt = graph->nvwgt; + + vtxdist = graph->vtxdist; + firstvtx = vtxdist[ctrl->mype]; + lastvtx = vtxdist[ctrl->mype+1]; + + match = graph->match = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: match"); + myhome = idxsmalloc(nvtxs+graph->nrecv, UNMATCHED, "HEM_Match: myhome"); + + /*------------------------------------------------------------ + / Send/Receive the home information of interface vertices + /------------------------------------------------------------*/ + if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { + idxcopy(nvtxs, home, myhome); + shome = wspace->indices; + rhome = myhome + nvtxs; + CommInterfaceData(ctrl, graph, myhome, shome, rhome); + } + + nnbrs = graph->nnbrs; + peind = graph->peind; + sendptr = graph->sendptr; + recvptr = graph->recvptr; + + /* Use wspace->indices as the tmp space for matching info of the boundary + * vertices that are sent and received */ + rmatch = match + nvtxs; + smatch = wspace->indices; + changed = smatch+graph->nsend; + + /* Use wspace->indices as the tmp space for match requests of the boundary + * vertices that are sent and received */ + match_requests = wspace->pairs; + match_granted = match_requests + graph->nsend; + + nreqs_pe = ismalloc(nnbrs, 0, "Match_HEM: nreqs_pe"); + + nkept = graph->gnvtxs/ctrl->npes - nvtxs; + + perm = (idxtype *)wspace->degrees; + iperm = perm + nvtxs; + FastRandomPermute(nvtxs, perm, 1); + for (i=0; i maxnvwgt) { + break; + } + + if (h != ncon) { + match[i] = TOO_HEAVY; + nchanged++; + } + } + if (GlobalSESum(ctrl, nchanged) > 0) { + IFSET(ctrl->dbglvl, DBG_PROGRESS, + rprintf(ctrl, "We found %d heavy vertices!\n", GlobalSESum(ctrl, nchanged))); + CommInterfaceData(ctrl, graph, match, smatch, rmatch); + } + + + for (nmatched=pass=0; passlevel+pass)%2; + nchanged = nrequests = 0; + for (ii=nmatched; ii= 0))) { + maxi = j; + maxidx = k; + } + } + + if (maxi != -1) { + k = ladjncy[maxi]; + if (k < nvtxs) { /* Take care the local vertices first */ + /* Here we give preference the local matching by granting it right away */ + if (i <= k) { + match[i] = firstvtx+k + KEEP_BIT; + match[k] = firstvtx+i; + } + else { + match[i] = firstvtx+k; + match[k] = firstvtx+i + KEEP_BIT; + } + changed[nchanged++] = i; + changed[nchanged++] = k; + } + else { /* Take care any remote boundary vertices */ + match[k] = MAYBE_MATCHED; + /* Alternate among which vertices will issue the requests */ + if ((wside ==0 && firstvtx+i < graph->imap[k]) || (wside == 1 && firstvtx+i > graph->imap[k])) { + match[i] = MAYBE_MATCHED; + match_requests[nrequests].key = graph->imap[k]; + match_requests[nrequests].val = firstvtx+i; + nrequests++; + } + } + } + } + } + + +#ifdef DEBUG_MATCH + PrintVector2(ctrl, nvtxs, firstvtx, match, "Match1"); + myprintf(ctrl, "[c: %2d] Nlocal: %d, Nrequests: %d\n", c, nlocal, nrequests); +#endif + + + /*********************************************************** + * Exchange the match_requests, requests for me are stored in + * match_granted + ************************************************************/ + /* Issue the receives first. Note that from each PE can receive a maximum + of the interface node that it needs to send it in the case of a mat-vec */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next. This needs some work */ + ikeysort(nrequests, match_requests); + for (j=i=0; icomm, ctrl->sreq+i); + j = k; + } + + /* OK, now get into the loop waiting for the operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nreqs_pe+i); + nreqs_pe[i] = nreqs_pe[i]/2; /* Adjust for pairs of IDX_DATATYPE */ + } + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*********************************************************** + * Now, go and service the requests that you received in + * match_granted + ************************************************************/ + RandomPermute(nnbrs, nperm, 0); + for (ii=0; ii= firstvtx && k < lastvtx, (ctrl, "%d %d %d %d %d\n", firstvtx, lastvtx, k, j, peind[i])); + /* myprintf(ctrl, "Requesting a match %d %d\n", pe_requests[j].key, pe_requests[j].val); */ + if (match[k-firstvtx] == UNMATCHED) { /* Bingo, lets grant this request */ + changed[nchanged++] = k-firstvtx; + if (nkept >= 0) { /* Flip a coin for who gets it */ + match[k-firstvtx] = pe_requests[j].val + KEEP_BIT; + nkept--; + } + else { + match[k-firstvtx] = pe_requests[j].val; + pe_requests[j].key += KEEP_BIT; + nkept++; + } + /* myprintf(ctrl, "Request from pe:%d (%d %d) granted!\n", peind[i], pe_requests[j].val, pe_requests[j].key); */ + } + else { /* We are not granting the request */ + /* myprintf(ctrl, "Request from pe:%d (%d %d) not granted!\n", peind[i], pe_requests[j].val, pe_requests[j].key); */ + pe_requests[j].key = UNMATCHED; + } + } + } + + + /*********************************************************** + * Exchange the match_granted information. It is stored in + * match_requests + ************************************************************/ + /* Issue the receives first. Note that from each PE can receive a maximum + of the interface node that it needs to send during the case of a mat-vec */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next. */ + for (i=0; icomm, ctrl->sreq+i); + } + + /* OK, now get into the loop waiting for the operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nreqs_pe+i); + nreqs_pe[i] = nreqs_pe[i]/2; /* Adjust for pairs of IDX_DATATYPE */ + } + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*********************************************************** + * Now, go and through the match_requests and update local + * match information for the matchings that were granted. + ************************************************************/ + for (i=0; ipv4); + } + + /* Traverse the vertices and those that were unmatched, match them with themselves */ + cnvtxs = 0; + for (i=0; i= KEEP_BIT) { /* A matched vertex which I get to keep */ + cnvtxs++; + } + } + + if (ctrl->dbglvl&DBG_MATCHINFO) { + PrintVector2(ctrl, nvtxs, firstvtx, match, "Match"); + myprintf(ctrl, "Cnvtxs: %d\n", cnvtxs); + rprintf(ctrl, "Done with matching...\n"); + } + + GKfree((void **)(&myhome), (void **)(&nreqs_pe), LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MatchTmr)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->ContractTmr)); + + Moc_Global_CreateCoarseGraph(ctrl, graph, wspace, cnvtxs); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->ContractTmr)); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdiffusion.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdiffusion.c new file mode 100644 index 0000000..6c02138 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdiffusion.c @@ -0,0 +1,455 @@ +/* * Copyright 1997, Regents of the University of Minnesota + * + * mdiffusion.c + * + * This file contains code that performs mc-diffusion + * + * Started 9/16/99 + * George + * + * $Id: mdiffusion.c,v 1.2 2003/07/21 17:18:50 karypis Exp $ + */ + +#include + +#define PE -1 + +/************************************************************************* +* This function is the entry point of the initial partitioning algorithm. +* This algorithm assembles the graph to all the processors and preceed +* serially. +**************************************************************************/ +int Moc_Diffusion(CtrlType *ctrl, GraphType *graph, idxtype *vtxdist, + idxtype *where, idxtype *home, WorkSpaceType *wspace, int npasses) +{ + int h, i, j; + int nvtxs, nedges, ncon, pass, iter, domain, processor; + int nparts, mype, npes, nlinks, me, you, wsize; + int nvisited, nswaps = -1, tnswaps, done, alldone = -1; + idxtype *rowptr, *colind, *diff_where, *sr_where, *ehome, *map, *rmap; + idxtype *pack, *unpack, *match, *proc2sub, *sub2proc; + idxtype *visited, *gvisited; + float *transfer, *npwgts, maxdiff, minflow, maxflow; + float lbavg, oldlbavg, ubavg, lbvec[MAXNCON]; + float diff_flows[MAXNCON], sr_flows[MAXNCON]; + float diff_lbavg, sr_lbavg, diff_cost, sr_cost; + idxtype *rbuffer, *sbuffer; + int *rcount, *rdispl; + float *solution, *load, *workspace; + EdgeType *degrees; + MatrixType matrix; + GraphType *egraph; + RInfoType *rinfo; + + if (graph->ncon > 3) + return 0; + + nvtxs = graph->nvtxs; + nedges = graph->nedges; + ncon = graph->ncon; + + nparts = ctrl->nparts; + mype = ctrl->mype; + npes = ctrl->npes; + ubavg = savg(ncon, ctrl->ubvec); + + /********************************************/ + /* initialize variables and allocate memory */ + /********************************************/ + load = fmalloc(nparts*(2+ncon)+nedges*(1+ncon), "load"); + solution = load + nparts; + npwgts = graph->gnpwgts = load + 2*nparts; + matrix.values = load + (2+ncon)*nparts; + transfer = matrix.transfer = load + (2+ncon)*nparts + nedges; + + proc2sub = idxmalloc(amax(nparts, npes*2), "Mc_Diffusion: proc2sub"); + sub2proc = idxmalloc(nparts*3+nedges+1, "Mc_Diffusion: match"); + match = sub2proc + nparts; + rowptr = matrix.rowptr = sub2proc + 2*nparts; + colind = matrix.colind = sub2proc + 3*nparts + 1; + + rcount = imalloc(2*npes+1, "Mc_Diffusion: rcount"); + rdispl = rcount + npes; + + pack = idxmalloc(nvtxs*8, "Mc_Diffusion: pack"); + unpack = pack + nvtxs; + rbuffer = pack + 2*nvtxs; + sbuffer = pack + 3*nvtxs; + map = pack + 4*nvtxs; + rmap = pack + 5*nvtxs; + diff_where = pack + 6*nvtxs; + ehome = pack + 7*nvtxs; + + wsize = amax(sizeof(float)*nparts*6, sizeof(idxtype)*(nvtxs+nparts*2+1)); + workspace = (float *)GKmalloc(wsize, "Moc_Diffusion: workspace"); + degrees = GKmalloc(nedges*sizeof(EdgeType), "Mc_Diffusion: degrees"); + rinfo = graph->rinfo = GKmalloc(nvtxs*sizeof(RInfoType), "Mc_Diffusion: rinfo"); + + /******************************************/ + /* construct subdomain connectivity graph */ + /******************************************/ + matrix.nrows = nparts; + SetUpConnectGraph(graph, &matrix, (idxtype *)workspace); + nlinks = (matrix.nnzs-nparts) / 2; + + visited = idxmalloc(matrix.nnzs*2, "visited"); + gvisited = visited + matrix.nnzs; + + for (pass=0; passtpwgts, h); + + lbvec[h] = (load[samax(nparts, load)]+1.0/(float)nparts) * (float)nparts; + + ConjGrad2(&matrix, load, solution, 0.001, workspace); + ComputeTransferVector(ncon, &matrix, solution, transfer, h); + } + + oldlbavg = savg(ncon, lbvec); + tnswaps = 0; + maxdiff = 0.0; + for (i=0; i maxdiff) ? maxflow - minflow : maxdiff; + } + } + + while (nvisited < nlinks) { + + /******************************************/ + /* compute independent sets of subdomains */ + /******************************************/ + idxset(amax(nparts, npes*2), UNMATCHED, proc2sub); + CSR_Match_SHEM(&matrix, match, proc2sub, gvisited, ncon); + + /*****************************/ + /* Set up the packing arrays */ + /*****************************/ + idxset(nparts, UNMATCHED, sub2proc); + for (i=0; i0; i--) + rdispl[i] = rdispl[i-1]; + rdispl[0] = 0; + + idxset(nvtxs, UNMATCHED, pack); + for (i=0; i 0.0) + diff_flows[h] = -1.0 * transfer[j*ncon+h]; + break; + } + } + + nswaps = 1; + scopy(ncon, diff_flows, sr_flows); + + idxset(nvtxs, 0, sbuffer); + for (i=0; invtxs, egraph->where, diff_where); + for (j=0; jnvtxs; j++) + ehome[j] = home[map[j]]; + + RedoMyLink(ctrl, egraph, ehome, me, you, sr_flows, &sr_cost, &sr_lbavg); + + if (ncon <= 4) { + sr_where = egraph->where; + egraph->where = diff_where; + + nswaps = BalanceMyLink(ctrl, egraph, ehome, me, you, diff_flows, maxdiff, &diff_cost, &diff_lbavg, 1.0/(float)nvtxs); + + if ((sr_lbavg < diff_lbavg && + (diff_lbavg >= ubavg-1.0 || sr_cost == diff_cost)) || + (sr_lbavg < ubavg-1.0 && sr_cost < diff_cost)) { + for (i=0; invtxs; i++) + where[map[i]] = sr_where[i]; + } + else { + for (i=0; invtxs; i++) + where[map[i]] = diff_where[i]; + } + } + else { + for (i=0; invtxs; i++) + where[map[i]] = egraph->where[i]; + } + + GKfree((void **)&egraph->xadj, (void **)&egraph->nvwgt, (void **)&egraph->adjncy, LTERM); + GKfree((void **)&egraph, LTERM); + } + + /**********************/ + /* Pack the flow data */ + /**********************/ + idxset(nvtxs, UNMATCHED, sbuffer); + for (i=0; icomm); + + + /************************/ + /* Unpack the flow data */ + /************************/ + for (i=0; icomm); + nvisited = idxsum(matrix.nnzs, gvisited)/2; + tnswaps += GlobalSESum(ctrl, nswaps); + + if (iter++ == NGD_PASSES) + break; + } + + /*****************************/ + /* perform serial refinement */ + /*****************************/ + Moc_ComputeSerialPartitionParams(graph, nparts, degrees); + Moc_SerialKWayAdaptRefine(graph, nparts, home, ctrl->ubvec, 10); + + + /****************************/ + /* check for early breakout */ + /****************************/ + for (h=0; h= oldlbavg || + lbavg <= ubavg + 0.035 + ) + done = 1; + + alldone = GlobalSEMax(ctrl, done); + if (alldone == 1) + break; + } + + /*******************************************************/ + /* ensure that all subdomains have at least one vertex */ + /*******************************************************/ +/* + idxset(nparts, 0, match); + for (i=0; imype == PE) printf("WARNING: empty subdomain %d in Moc_Diffusion\n", me); + you = idxamax(nparts, match); + for (i=0; ignpwgts = NULL; + graph->rinfo = NULL; + + return 0; +} + + +/************************************************************************* +* This function extracts a subgraph from a graph given an indicator array. +**************************************************************************/ +GraphType *ExtractGraph(CtrlType *ctrl, GraphType *graph, idxtype *indicator, + idxtype *map, idxtype *rmap) +{ + int h, i, j; + int nvtxs, envtxs, enedges, ncon; + int vtx, count; + idxtype *xadj, *vsize, *adjncy, *adjwgt, *where; + idxtype *exadj, *evsize, *eadjncy, *eadjwgt, *ewhere; + float *nvwgt, *envwgt; + GraphType *egraph; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + + count = 0; + for (i=0; invtxs = count; + egraph->ncon = graph->ncon; + + exadj = egraph->xadj = idxmalloc(envtxs*3+1, "exadj"); + ewhere = egraph->where = exadj + envtxs + 1; + evsize = egraph->vsize = exadj + 2*envtxs + 1; + + envwgt = egraph->nvwgt = fmalloc(envtxs*ncon, "envwgt"); + + /************************************************/ + /* compute xadj, where, nvwgt, and vsize arrays */ + /************************************************/ + idxset(envtxs+1, 0, exadj); + for (i=0; ipartType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) + evsize[i] = vsize[vtx]; + + for (j=xadj[vtx]; jnedges = exadj[envtxs]; + eadjncy = egraph->adjncy = idxmalloc(enedges*2, "eadjncy"); + eadjwgt = egraph->adjwgt = eadjncy + enedges; + + for (i=0; i0; i--) + exadj[i] = exadj[i-1]; + exadj[0] = 0; + + return egraph; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdrivers.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdrivers.c new file mode 100644 index 0000000..467df79 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mdrivers.c @@ -0,0 +1,116 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mdrivers.c + * + * This file contains the driving routines for the various parallel + * multilevel partitioning and repartitioning algorithms + * + * Started 11/19/96 + * George + * + * $Id: mdrivers.c,v 1.3 2003/07/22 20:29:06 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function is the driver to the multi-constraint partitioning algorithm. +**************************************************************************/ +void Moc_Global_Partition(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, ncon, nparts; + float ftmp, ubavg, lbavg, lbvec[MAXNCON]; + + ncon = graph->ncon; + nparts = ctrl->nparts; + ubavg = savg(graph->ncon, ctrl->ubvec); + + SetUp(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + rprintf(ctrl, "[%6d %8d %5d %5d] [%d] [", graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), + GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo); + for (i=0; invwgt[samin_strd(graph->nvtxs, graph->nvwgt+i, ncon)*ncon+i])); + rprintf(ctrl, "] ["); + for (i=0; invwgt[samax_strd(graph->nvtxs, graph->nvwgt+i, ncon)*ncon+i])); + rprintf(ctrl, "]\n"); + } + + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || + (graph->finer != NULL && + graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + + /* Done with coarsening. Find a partition */ + graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "graph->where"); + Moc_InitPartition_RB(ctrl, graph, wspace); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, balance: ", graph->gnvtxs); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + /* In case no coarsening took place */ + if (graph->finer == NULL) { + Moc_ComputePartitionParams(ctrl, graph, wspace); + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + } + } + else { + Moc_GlobalMatch_Balance(ctrl, graph, wspace); + + Moc_Global_Partition(ctrl, graph->coarser, wspace); + + Moc_ProjectPartition(ctrl, graph, wspace); + Moc_ComputePartitionParams(ctrl, graph, wspace); + + if (graph->ncon > 1 && graph->level < 3) { + for (i=0; ignpwgts+i, ncon); + if (ftmp != 0.0) + lbvec[i] = (float)(nparts) * + graph->gnpwgts[samax_strd(nparts, graph->gnpwgts+i, ncon)*ncon+i]/ftmp; + else + lbvec[i] = 1.0; + } + lbavg = savg(graph->ncon, lbvec); + + if (lbavg > ubavg + 0.035) { + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + Moc_KWayBalance(ctrl, graph, wspace, graph->ncon); + } + } + + Moc_KWayFM(ctrl, graph, wspace, NGR_PASSES); + + if (ctrl->dbglvl&DBG_PROGRESS) { + Moc_ComputeParallelBalance(ctrl, graph, graph->where, lbvec); + rprintf(ctrl, "nvtxs: %10d, cut: %8d, balance: ", graph->gnvtxs, graph->mincut); + for (i=0; incon; i++) + rprintf(ctrl, "%.3f ", lbvec[i]); + rprintf(ctrl, "\n"); + } + + if (graph->level != 0) + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, LTERM); + } + + return; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/memory.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/memory.c new file mode 100644 index 0000000..a8eeaff --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/memory.c @@ -0,0 +1,216 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * memory.c + * + * This file contains routines that deal with memory allocation + * + * Started 2/24/96 + * George + * + * $Id: memory.c,v 1.3 2003/07/30 18:37:59 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function allocate various pools of memory +**************************************************************************/ +void PreAllocateMemory(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + wspace->nlarge = 2*graph->nedges; + + wspace->maxcore = 8*graph->nedges+1; + wspace->core = idxmalloc(wspace->maxcore, "PreAllocateMemory: wspace->core"); + + wspace->pairs = (KeyValueType *)wspace->core; + wspace->indices = (idxtype *)(wspace->pairs + wspace->nlarge); + wspace->degrees = (EdgeType *)(wspace->indices + wspace->nlarge); + + + wspace->pv1 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv2 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv3 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + wspace->pv4 = idxmalloc(ctrl->nparts+ctrl->npes+1, "PreAllocateMemory: wspace->pv?"); + + wspace->pepairs1 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "PreAllocateMemory: wspace->pepairs?"); + wspace->pepairs2 = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(ctrl->nparts+ctrl->npes+1), "PreAllocateMemory: wspace->pepairs?"); + +} + + +/************************************************************************* +* This function de-allocate various pools of memory +**************************************************************************/ +void FreeWSpace(WorkSpaceType *wspace) +{ + + GKfree((void **)&wspace->core, + (void **)&wspace->pv1, + (void **)&wspace->pv2, + (void **)&wspace->pv3, + (void **)&wspace->pv4, + (void **)&wspace->pepairs1, + (void **)&wspace->pepairs2, + LTERM); +} + + +/************************************************************************* +* This function de-allocates memory allocated for the control structures +**************************************************************************/ +void FreeCtrl(CtrlType *ctrl) +{ + MPI_Comm_free(&(ctrl->gcomm)); +} + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +GraphType *CreateGraph(void) +{ + GraphType *graph; + + graph = (GraphType *)GKmalloc(sizeof(GraphType), "CreateCoarseGraph: graph"); + + InitGraph(graph); + + return graph; +} + + +/************************************************************************* +* This function creates a CoarseGraphType data structure and initializes +* the various fields +**************************************************************************/ +void InitGraph(GraphType *graph) +{ + graph->gnvtxs = graph->nvtxs = graph->nedges = graph->nsep = -1; + graph->nnbrs = graph->nrecv = graph->nsend = graph->nlocal = -1; + graph->xadj = graph->vwgt = graph->vsize = graph->adjncy = graph->adjwgt = NULL; + graph->nvwgt = NULL; + graph->vtxdist = NULL; + graph->match = graph->cmap = NULL; + graph->label = NULL; + + graph->peind = NULL; + graph->sendptr = graph->sendind = graph->recvptr = graph->recvind = NULL; + graph->imap = NULL; + graph->pexadj = graph->peadjncy = graph->peadjloc = NULL; + graph->lperm = NULL; + + graph->slens = graph->rlens = NULL; + graph->rcand = NULL; + + graph->where = graph->home = graph->lpwgts = graph->gpwgts = NULL; + graph->lnpwgts = graph->gnpwgts = NULL; + graph->rinfo = NULL; + + graph->nrinfo = NULL; + graph->sepind = NULL; + + graph->coarser = graph->finer = NULL; + +} + +/************************************************************************* +* This function deallocates any memory stored in a graph +**************************************************************************/ +void FreeGraph(GraphType *graph) +{ + + GKfree((void **)&graph->xadj, + (void **)&graph->vwgt, + (void **)&graph->nvwgt, + (void **)&graph->vsize, + (void **)&graph->adjncy, + (void **)&graph->adjwgt, + (void **)&graph->vtxdist, + (void **)&graph->match, + (void **)&graph->cmap, + (void **)&graph->lperm, + (void **)&graph->label, + (void **)&graph->where, + (void **)&graph->home, + (void **)&graph->rinfo, + (void **)&graph->nrinfo, + (void **)&graph->sepind, + (void **)&graph->lpwgts, + (void **)&graph->gpwgts, + (void **)&graph->lnpwgts, + (void **)&graph->gnpwgts, + (void **)&graph->peind, + (void **)&graph->sendptr, + (void **)&graph->sendind, + (void **)&graph->recvptr, + (void **)&graph->recvind, + (void **)&graph->imap, + (void **)&graph->rlens, + (void **)&graph->slens, + (void **)&graph->rcand, + (void **)&graph->pexadj, + (void **)&graph->peadjncy, + (void **)&graph->peadjloc, + LTERM); + + free(graph); +} + + + +/************************************************************************* +* This function deallocates any memory stored in a graph +**************************************************************************/ +void FreeInitialGraphAndRemap(GraphType *graph, int wgtflag) +{ + int i, nedges; + idxtype *adjncy, *imap; + + nedges = graph->nedges; + adjncy = graph->adjncy; + imap = graph->imap; + + if (imap != NULL) { + for (i=0; imatch, + (void **)&graph->cmap, + (void **)&graph->lperm, + (void **)&graph->where, + (void **)&graph->label, + (void **)&graph->rinfo, + (void **)&graph->nrinfo, + (void **)&graph->nvwgt, + (void **)&graph->lpwgts, + (void **)&graph->gpwgts, + (void **)&graph->lnpwgts, + (void **)&graph->gnpwgts, + (void **)&graph->sepind, + (void **)&graph->peind, + (void **)&graph->sendptr, + (void **)&graph->sendind, + (void **)&graph->recvptr, + (void **)&graph->recvind, + (void **)&graph->imap, + (void **)&graph->rlens, + (void **)&graph->slens, + (void **)&graph->rcand, + (void **)&graph->pexadj, + (void **)&graph->peadjncy, + (void **)&graph->peadjloc, + LTERM); + + if ((wgtflag&2) == 0) + GKfree((void **)&graph->vwgt, (void **)&graph->vsize, LTERM); + if ((wgtflag&1) == 0) + GKfree((void **)&graph->adjwgt, LTERM); + + free(graph); +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mesh.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mesh.c new file mode 100644 index 0000000..57a80c0 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/mesh.c @@ -0,0 +1,335 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mesh.c + * + * This file contains routines for constructing the dual graph of a mesh. + * Assumes that each processor has at least one mesh element. + * + * Started 10/19/94 + * George + * + * $Id: mesh.c,v 1.11 2003/07/25 04:01:04 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function converts a mesh into a dual graph +**************************************************************************/ +void ParMETIS_V3_Mesh2Dual(idxtype *elmdist, idxtype *eptr, idxtype *eind, + int *numflag, int *ncommonnodes, idxtype **xadj, + idxtype **adjncy, MPI_Comm *comm) +{ + int i, j, jj, k, kk, m; + int npes, mype, pe, count, mask, pass; + int nelms, lnns, my_nns, node; + int firstelm, firstnode, lnode, nrecv, nsend; + int *scounts, *rcounts, *sdispl, *rdispl; + idxtype *nodedist, *nmap, *auxarray; + idxtype *gnptr, *gnind, *nptr, *nind, *myxadj, *myadjncy = NULL; + idxtype *sbuffer, *rbuffer, *htable; + KeyValueType *nodelist, *recvbuffer; + idxtype ind[200], wgt[200]; + int gmaxnode, gminnode; + CtrlType ctrl; + + + SetUpCtrl(&ctrl, -1, 0, *comm); + + npes = ctrl.npes; + mype = ctrl.mype; + + nelms = elmdist[mype+1]-elmdist[mype]; + + if (*numflag == 1) + ChangeNumberingMesh2(elmdist, eptr, eind, NULL, NULL, NULL, npes, mype, 1); + + mask = (1<<11)-1; + + /*****************************/ + /* Determine number of nodes */ + /*****************************/ + gminnode = GlobalSEMin(&ctrl, eind[idxamin(eptr[nelms], eind)]); + for (i=0; i 0); + + /* construct node distribution array */ + nodedist = idxsmalloc(npes+1, 0, "nodedist"); + for (nodedist[0]=0, i=0,j=gmaxnode+1; i nodelist[i-1].key) + count++; + } + + lnns = count; + nmap = idxmalloc(lnns, "nmap"); + + /* renumber the nodes of the elements array */ + count = 1; + nmap[0] = nodelist[0].key; + eind[nodelist[0].val] = 0; + nodelist[0].val = auxarray[nodelist[0].val]; /* Store the local element ID */ + for (i=1; i nodelist[i-1].key) { + nmap[count] = nodelist[i].key; + count++; + } + eind[nodelist[i].val] = count-1; + nodelist[i].val = auxarray[nodelist[i].val]; /* Store the local element ID */ + } + MPI_Barrier(*comm); + + /**********************************************************/ + /* perform comms necessary to construct node-element list */ + /**********************************************************/ + iset(npes, 0, scounts); + for (pe=i=0; i= nodedist[pe+1]) + pe++; + scounts[pe] += 2; + } + ASSERTS(pe < npes); + + MPI_Alltoall((void *)scounts, 1, MPI_INT, (void *)rcounts, 1, MPI_INT, *comm); + + icopy(npes, scounts, sdispl); + MAKECSR(i, npes, sdispl); + + icopy(npes, rcounts, rdispl); + MAKECSR(i, npes, rdispl); + + ASSERTS(sdispl[npes] == eptr[nelms]*2); + + nrecv = rdispl[npes]/2; + recvbuffer = (KeyValueType *)GKmalloc(amax(1, nrecv)*sizeof(KeyValueType), "recvbuffer"); + + MPI_Alltoallv((void *)nodelist, scounts, sdispl, IDX_DATATYPE, (void *)recvbuffer, + rcounts, rdispl, IDX_DATATYPE, *comm); + + /**************************************/ + /* construct global node-element list */ + /**************************************/ + gnptr = idxsmalloc(my_nns+1, 0, "gnptr"); + + for (i=0; i= 0 && lnode < my_nns) + + gnptr[lnode]++; + } + } + MAKECSR(i, my_nns, gnptr); + + gnind = idxmalloc(amax(1, gnptr[my_nns]), "gnind"); + for (pe=0; pe= *ncommonnodes) { + if (pass == 0) + myxadj[i]++; + else + myadjncy[myxadj[i]++] = ind[j]; + } + } + } + + if (pass == 0) { + MAKECSR(i, nelms, myxadj); + myadjncy = *adjncy = idxmalloc(myxadj[nelms], "adjncy"); + } + else { + SHIFTCSR(i, nelms, myxadj); + } + } + + /*****************************************/ + /* correctly renumber the elements array */ + /*****************************************/ + for (i=0; i + + +/*********************************************************************************** +* This function is the entry point of the parallel k-way multilevel mesh partitionioner. +* This function assumes nothing about the mesh distribution. +* It is the general case. +************************************************************************************/ +void ParMETIS_V3_PartMeshKway(idxtype *elmdist, idxtype *eptr, idxtype *eind, idxtype *elmwgt, + int *wgtflag, int *numflag, int *ncon, int *ncommonnodes, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm) +{ + int i, nvtxs, nedges, gnedges, npes, mype; + idxtype *xadj, *adjncy; + timer TotalTmr, Mesh2DualTmr, ParMETISTmr; + CtrlType ctrl; + + /********************************/ + /* Try and take care bad inputs */ + /********************************/ + if (elmdist == NULL || eptr == NULL || eind == NULL || wgtflag == NULL || + numflag == NULL || ncon == NULL || ncommonnodes == NULL || nparts == NULL || + tpwgts == NULL || ubvec == NULL || options == NULL || edgecut == NULL || + part == NULL || comm == NULL) { + printf("ERROR: One or more required parameters is NULL. Aborting.\n"); + abort(); + } + if (((*wgtflag)&2) && elmwgt == NULL) { + printf("ERROR: elmwgt == NULL when vertex weights were specified. Aborting.\n"); + abort(); + } + + + SetUpCtrl(&ctrl, *nparts, (options[0] == 1 ? options[PMV3_OPTION_DBGLVL] : 0), *comm); + npes = ctrl.npes; + mype = ctrl.mype; + + cleartimer(TotalTmr); + cleartimer(Mesh2DualTmr); + cleartimer(ParMETISTmr); + + MPI_Barrier(ctrl.comm); + starttimer(TotalTmr); + starttimer(Mesh2DualTmr); + + ParMETIS_V3_Mesh2Dual(elmdist, eptr, eind, numflag, ncommonnodes, &xadj, &adjncy, &(ctrl.comm)); + + if (ctrl.dbglvl&DBG_INFO) { + nvtxs = elmdist[mype+1]-elmdist[mype]; + nedges = xadj[nvtxs] + (*numflag == 0 ? 0 : -1); + rprintf(&ctrl, "Completed Dual Graph -- Nvtxs: %d, Nedges: %d \n", + elmdist[npes], GlobalSESum(&ctrl, nedges)); + } + + MPI_Barrier(ctrl.comm); + stoptimer(Mesh2DualTmr); + + + /***********************/ + /* Partition the graph */ + /***********************/ + starttimer(ParMETISTmr); + + ParMETIS_V3_PartKway(elmdist, xadj, adjncy, elmwgt, NULL, wgtflag, numflag, ncon, + nparts, tpwgts, ubvec, options, edgecut, part, &(ctrl.comm)); + + MPI_Barrier(ctrl.comm); + stoptimer(ParMETISTmr); + stoptimer(TotalTmr); + + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimer(&ctrl, Mesh2DualTmr, " Mesh2Dual")); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimer(&ctrl, ParMETISTmr, " ParMETIS")); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimer(&ctrl, TotalTmr, " Total")); + + GKfree((void **)&xadj, (void **)&adjncy, LTERM); + + FreeCtrl(&ctrl); + + return; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/move.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/move.c new file mode 100644 index 0000000..06a8e5c --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/move.c @@ -0,0 +1,338 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * mmove.c + * + * This file contains functions that move the graph given a partition + * + * Started 11/22/96 + * George + * + * $Id: move.c,v 1.3 2003/07/31 16:23:30 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function moves the graph, and returns a new graph. +* This routine can be called with or without performing refinement. +* In the latter case it allocates and computes lpwgts itself. +**************************************************************************/ +GraphType *Moc_MoveGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int h, i, ii, j, jj, nvtxs, ncon, nparts; + idxtype *xadj, *vwgt, *adjncy, *adjwgt, *mvtxdist; + idxtype *where, *newlabel, *lpwgts, *gpwgts; + idxtype *sgraph, *rgraph; + KeyValueType *sinfo, *rinfo; + GraphType *mgraph; + + nparts = ctrl->nparts; + ASSERT(ctrl, nparts == ctrl->npes); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + vwgt = graph->vwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + + mvtxdist = idxmalloc(nparts+1, "MoveGraph: mvtxdist"); + + /* Let's do a prefix scan to determine the labeling of the nodes given */ + lpwgts = wspace->pv1; + gpwgts = wspace->pv2; + sinfo = wspace->pepairs1; + rinfo = wspace->pepairs2; + for (i=0; icomm); + MPI_Allreduce((void *)lpwgts, (void *)mvtxdist, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + + MAKECSR(i, nparts, mvtxdist); + + /* gpwgts[i] will store the label of the first vertex for each domain in each processor */ + for (i=0; inrecv, "MoveGraph: newlabel"); + + for (i=0; iindices, newlabel+nvtxs); + + /* Now lets tell everybody what and from where he will get it. Assume nparts == npes */ + MPI_Alltoall((void *)sinfo, 2, IDX_DATATYPE, (void *)rinfo, 2, IDX_DATATYPE, ctrl->comm); + + /* Use lpwgts and gpwgts as pointers to where data will be received and send */ + lpwgts[0] = 0; /* Send part */ + gpwgts[0] = 0; /* Received part */ + for (i=0; i wspace->maxcore) { + /* Adjust core memory, incase the graph was originally very memory unbalanced */ + free(wspace->core); + wspace->maxcore = lpwgts[nparts]+4*gpwgts[nparts]; /* In spirit of the 8*nedges */ + wspace->core = idxmalloc(wspace->maxcore, "Moc_MoveGraph: wspace->core"); + } + + sgraph = wspace->core; + rgraph = wspace->core + lpwgts[nparts]; + + /* Issue the receives first */ + for (i=0; i 0) + MPI_Irecv((void *)(rgraph+gpwgts[i]), gpwgts[i+1]-gpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->rreq+i); + else + ASSERT(ctrl, gpwgts[i+1]-gpwgts[i] == 0); + } + + /* Assemble the graph to be sent and send it */ + for (i=0; i0; i--) + lpwgts[i] = lpwgts[i-1]; + lpwgts[0] = 0; + + for (i=0; i 0) + MPI_Isend((void *)(sgraph+lpwgts[i]), lpwgts[i+1]-lpwgts[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->sreq+i); + else + ASSERT(ctrl, lpwgts[i+1]-lpwgts[i] == 0); + } + +/* +#ifdef DMALLOC + ASSERT(ctrl, dmalloc_verify(NULL) == DMALLOC_VERIFY_NOERROR); +#endif +*/ + + /* Wait for the send/recv to finish */ + for (i=0; i 0) + MPI_Wait(ctrl->sreq+i, &ctrl->status); + } + for (i=0; i 0) + MPI_Wait(ctrl->rreq+i, &ctrl->status); + } + + /* OK, now go and put the graph into GraphType Format */ + mgraph = CreateGraph(); + mgraph->gnvtxs = graph->gnvtxs; + mgraph->ncon = ncon; + mgraph->level = 0; + mgraph->nvtxs = mgraph->nedges = 0; + for (i=0; invtxs += rinfo[i].key; + mgraph->nedges += rinfo[i].val; + } + nvtxs = mgraph->nvtxs; + xadj = mgraph->xadj = idxmalloc(nvtxs+1, "MMG: mgraph->xadj"); + vwgt = mgraph->vwgt = idxmalloc(nvtxs*ncon, "MMG: mgraph->vwgt"); + adjncy = mgraph->adjncy = idxmalloc(mgraph->nedges, "MMG: mgraph->adjncy"); + adjwgt = mgraph->adjwgt = idxmalloc(mgraph->nedges, "MMG: mgraph->adjwgt"); + mgraph->vtxdist = mvtxdist; + + for (jj=ii=i=0; inedges, (ctrl, "%d %d\n", jj, mgraph->nedges)); + ASSERTP(ctrl, ii == gpwgts[nparts], (ctrl, "%d %d %d %d %d\n", ii, gpwgts[nparts], jj, mgraph->nedges, nvtxs)); + + free(newlabel); + +#ifdef DEBUG + IFSET(ctrl->dbglvl, DBG_INFO, rprintf(ctrl, "Checking moved graph...\n")); + CheckMGraph(ctrl, mgraph); + IFSET(ctrl->dbglvl, DBG_INFO, rprintf(ctrl, "Moved graph is consistent.\n")); +#endif + + return mgraph; +} + + +/************************************************************************* +* This function is used to transfer information from the moved graph +* back to the original graph. The information is transfered from array +* minfo to array info. The routine assumes that graph->where is left intact +* and it is used to get the inverse mapping information. +* The routine assumes that graph->where corresponds to a npes-way partition. +**************************************************************************/ +void ProjectInfoBack(CtrlType *ctrl, GraphType *graph, idxtype *info, idxtype *minfo, + WorkSpaceType *wspace) +{ + int i, nvtxs, nparts; + idxtype *where, *auxinfo, *sinfo, *rinfo; + + nparts = ctrl->npes; + + nvtxs = graph->nvtxs; + where = graph->where; + + sinfo = wspace->pv1; + rinfo = wspace->pv2; + + /* Find out in rinfo how many entries are received per partition */ + idxset(nparts, 0, rinfo); + for (i=0; icomm); + + MAKECSR(i, nparts, sinfo); + MAKECSR(i, nparts, rinfo); + + /* allocate memory for auxinfo */ + auxinfo = idxmalloc(rinfo[nparts], "ProjectInfoBack: auxinfo"); + + /*----------------------------------------------------------------- + * Now, go and send back the minfo + -----------------------------------------------------------------*/ + for (i=0; i 0) + MPI_Irecv((void *)(auxinfo+rinfo[i]), rinfo[i+1]-rinfo[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->rreq+i); + } + + for (i=0; i 0) + MPI_Isend((void *)(minfo+sinfo[i]), sinfo[i+1]-sinfo[i], IDX_DATATYPE, i, 1, ctrl->comm, ctrl->sreq+i); + } + + /* Wait for the send/recv 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); + } + + /* Scatter the info received in auxinfo back to info. */ + for (i=0; inparts; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + + mvtxdist = idxmalloc(nparts+1, "MoveGraph: mvtxdist"); + + /* Let's do a prefix scan to determine the labeling of the nodes given */ + lpwgts = wspace->pv1; + gpwgts = wspace->pv2; + + /* Here we care about the count and not total weight (diff since graph may be weighted */ + idxset(nparts, 0, lpwgts); + for (i=0; icomm); + MPI_Allreduce((void *)lpwgts, (void *)mvtxdist, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + + MAKECSR(i, nparts, mvtxdist); + + for (i=0; invtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + vtxdist = graph->vtxdist; + + firstvtx = vtxdist[ctrl->mype]; + lastvtx = vtxdist[ctrl->mype+1]; + + for (i=0; i= firstvtx && adjncy[j] < lastvtx) { + k = adjncy[j]-firstvtx; + for (jj=xadj[k]; jj + + + +/************************************************************************* +* This function setsup the CtrlType structure +**************************************************************************/ +MeshType *SetUpMesh(int *etype, int *ncon, idxtype *elmdist, idxtype *elements, + idxtype *elmwgt, int *wgtflag, MPI_Comm *comm) +{ + MeshType *mesh; + int i, npes, mype; + int esizes[5] = {-1, 3, 4, 8, 4}; + int maxnode, gmaxnode, minnode, gminnode; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + mesh = CreateMesh(); + mesh->elmdist = elmdist; + mesh->gnelms = elmdist[npes]; + mesh->nelms = elmdist[mype+1]-elmdist[mype]; + mesh->elements = elements; + mesh->elmwgt = elmwgt; + mesh->etype = *etype; + mesh->ncon = *ncon; + mesh->esize = esizes[*etype]; + + if (((*wgtflag)&1) == 0) { + mesh->elmwgt = idxsmalloc(mesh->nelms*mesh->ncon, 1, "SetUpMesh: elmwgt"); + } + + minnode = elements[idxamin(mesh->nelms*mesh->esize, elements)]; + MPI_Allreduce((void *)&minnode, (void *)&gminnode, 1, MPI_INT, MPI_MIN, *comm); + for (i=0; inelms*mesh->esize; i++) + elements[i] -= gminnode; + mesh->gminnode = gminnode; + + maxnode = elements[idxamax(mesh->nelms*mesh->esize, elements)]; + MPI_Allreduce((void *)&maxnode, (void *)&gmaxnode, 1, MPI_INT, MPI_MAX, *comm); + mesh->gnns = gmaxnode+1; + + return mesh; +} + +/************************************************************************* +* This function creates a MeshType data structure and initializes +* the various fields +**************************************************************************/ +MeshType *CreateMesh(void) +{ + MeshType *mesh; + + mesh = (MeshType *)GKmalloc(sizeof(MeshType), "CreateMesh: mesh"); + + InitMesh(mesh); + + return mesh; +} + +/************************************************************************* +* This function initializes the various fields of a MeshType. +**************************************************************************/ +void InitMesh(MeshType *mesh) +{ + + mesh->etype = -1; + mesh->gnelms = -1; + mesh->gnns = -1; + mesh->nelms = -1; + mesh->nns = -1; + mesh->ncon = -1; + mesh->esize = -1; + mesh->gminnode = 0; + mesh->elmdist = NULL; + mesh->elements = NULL; + mesh->elmwgt = NULL; + + return; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/node_refine.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/node_refine.c new file mode 100644 index 0000000..3f57aa7 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/node_refine.c @@ -0,0 +1,383 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * node_refine.c + * + * This file contains code that performs the k-way refinement + * + * Started 3/1/96 + * George + * + * $Id: node_refine.c,v 1.2 2003/07/21 17:18:50 karypis Exp $ + */ + +#include + +#define PackWeightWhereInfo(a, b) (((a)<<10) + (b)) +#define SelectWhere(a) ((a)%1024) +#define SelectWeight(a) (((a)>>10)) + + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void ComputeNodePartitionParams(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j, nparts, nvtxs, nsep, firstvtx, lastvtx; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *vwgt, *lpwgts, *gpwgts, *sepind; + idxtype *where, *swhere, *rwhere; + NRInfoType *rinfo, *myrinfo; + int me, other, otherwgt; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayInitTmr)); + + nvtxs = graph->nvtxs; + nparts = ctrl->nparts; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; + + where = graph->where; + rinfo = graph->nrinfo = (NRInfoType *)GKmalloc(sizeof(NRInfoType)*nvtxs, "ComputeNodePartitionParams: rinfo"); + lpwgts = graph->lpwgts = idxsmalloc(2*nparts, 0, "ComputePartitionParams: lpwgts"); + gpwgts = graph->gpwgts = idxmalloc(2*nparts, "ComputePartitionParams: gpwgts"); + sepind = graph->sepind = idxmalloc(nvtxs, "ComputePartitionParams: sepind"); + + firstvtx = vtxdist[ctrl->mype]; + lastvtx = vtxdist[ctrl->mype+1]; + + /*------------------------------------------------------------ + / Send/Receive the where information of interface vertices. + / Also use this to also encode the vwgt information of this + / vertex. This is a hack, but it should work for now! + /------------------------------------------------------------*/ + swhere = wspace->indices; + rwhere = where + nvtxs; + + for (i=0; i= 0 && where[i] < 2*nparts, (ctrl, "%d\n", where[i]) ); + where[i] = PackWeightWhereInfo(vwgt[i], where[i]); + } + + CommInterfaceData(ctrl, graph, where, swhere, rwhere); + + /*------------------------------------------------------------ + / Compute now the degrees + /------------------------------------------------------------*/ + for (nsep=i=0; i= 0 && me < 2*nparts); + lpwgts[me] += vwgt[i]; + + if (me >= nparts) { /* If it is a separator vertex */ + sepind[nsep++] = i; + lpwgts[2*nparts-1] += vwgt[i]; + + myrinfo = rinfo+i; + myrinfo->edegrees[0] = myrinfo->edegrees[1] = 0; + + for (j=xadj[i]; jedegrees[other%2] += otherwgt; + } + } + } + graph->nsep = nsep; + + /* Finally, sum-up the partition weights */ + MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + graph->mincut = gpwgts[2*nparts-1]; + +#ifdef XX + /* Print Weight information */ + if (ctrl->mype == 0) { + for (i=0; idbglvl, DBG_TIME, stoptimer(ctrl->KWayInitTmr)); +} + + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void KWayNodeRefine(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace, int npasses, float ubfraction) +{ + int i, ii, j, k, pass, nvtxs, firstvtx, lastvtx, otherlastvtx, c, nmoves, + nlupd, nsupd, nnbrs, nchanged, nsep; + int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; + idxtype *xadj, *ladjncy, *adjwgt, *vtxdist, *vwgt; + idxtype *where, *lpwgts, *gpwgts, *sepind; + idxtype *peind, *recvptr, *sendptr; + idxtype *update, *supdate, *rupdate, *pe_updates, *htable, *changed; + idxtype *badminpwgt, *badmaxpwgt; + KeyValueType *swchanges, *rwchanges; + int *nupds_pe; + NRInfoType *rinfo, *myrinfo; + int from, me, other, otherwgt, oldcut; + + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); + + nvtxs = graph->nvtxs; + + vtxdist = graph->vtxdist; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + where = graph->where; + rinfo = graph->nrinfo; + lpwgts = graph->lpwgts; + gpwgts = graph->gpwgts; + + nsep = graph->nsep; + sepind = graph->sepind; + + nnbrs = graph->nnbrs; + peind = graph->peind; + recvptr = graph->recvptr; + sendptr = graph->sendptr; + + changed = idxmalloc(nvtxs, "KWayRefine: changed"); + rwchanges = wspace->pairs; + swchanges = rwchanges + recvptr[nnbrs]; + + update = idxmalloc(nvtxs, "KWayRefine: update"); + supdate = wspace->indices; + rupdate = supdate + recvptr[nnbrs]; + nupds_pe = imalloc(npes, "KWayRefine: nupds_pe"); + + htable = idxsmalloc(nvtxs+graph->nrecv, 0, "KWayRefine: lhtable"); + + badminpwgt = wspace->pv1; + badmaxpwgt = wspace->pv2; + + for (i=0; idbglvl, DBG_REFINEINFO, PrintNodeBalanceInfo(ctrl, nparts, gpwgts, badminpwgt, badmaxpwgt, 1)); + + for (pass=0; passmincut; + + for (c=0; c<2; c++) { + for (i=0; i= nparts); + + /* Go through the loop if gain is possible for the separator vertex */ + if (rinfo[i].edegrees[(c+1)%2] <= vwgt[i]) { + other = from%nparts+c; /* It is one-sided move so we know where it goes */ + + if (gpwgts[other]+vwgt[i] > badmaxpwgt[other]) { + /* printf("Skip because of weight! %d\n", vwgt[i]-rinfo[i].edegrees[(c+1)%2]); */ + continue; /* We cannot move it there because it gets too heavy */ + } + + /* Update where, weight, and ID/ED information of the vertex you moved */ + where[i] = PackWeightWhereInfo(vwgt[i], other); + + /* Remove this vertex from the sepind. Note the trick for looking at the sepind[ii] again */ + sepind[ii--] = sepind[--nsep]; + + /* myprintf(ctrl, "Vertex %d [%d %d] is moving to %d from %d [%d]\n", i+firstvtx, vwgt[i], rinfo[i].edegrees[(c+1)%2], other, from, SelectWhere(where[i])); */ + + lpwgts[from] -= vwgt[i]; + lpwgts[2*nparts-1] -= vwgt[i]; + lpwgts[other] += vwgt[i]; + gpwgts[other] += vwgt[i]; + + /* + * Put the vertices adjacent to i that belong to either the separator or + * the (c+1)%2 partition into the update array + */ + for (j=xadj[i]; jpexadj[i+1]-graph->pexadj[i] > 0) + changed[nchanged++] = i; + } + } + + /* myprintf(ctrl, "nmoves: %d, nlupd: %d, nsupd: %d\n", nmoves, nlupd, nsupd); */ + + /* Tell everybody interested what the new where[] info is for the interface vertices */ + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); + + + IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%d %d %d]\n", + pass, c, GlobalSESum(ctrl, nmoves), GlobalSESum(ctrl, nsupd), GlobalSESum(ctrl, nlupd))); + + + /*------------------------------------------------------------- + / Time to communicate with processors to send the vertices + / whose degrees need to be update. + /-------------------------------------------------------------*/ + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends next. This needs some preporcessing */ + for (i=0; iimap[supdate[i]]; + } + iidxsort(nsupd, supdate); + + for (j=i=0; icomm, ctrl->sreq+i); + j = k; + } + + /* OK, now get into the loop waiting for the send/recv operations to finish */ + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + for (i=0; istatuses+i, IDX_DATATYPE, nupds_pe+i); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + /*------------------------------------------------------------- + / Place the received to-be updated vertices into update[] + /-------------------------------------------------------------*/ + for (i=0; ipexadj[i+1]-graph->pexadj[i] > 0) + changed[nchanged++] = i; + + lpwgts[SelectWhere(where[i])] += vwgt[i]; + lpwgts[2*nparts-1] += vwgt[i]; + /* myprintf(ctrl, "Vertex %d moves into the separator from %d to %d\n", i+firstvtx, me, SelectWhere(where[i])); */ + } + } + + /* Tell everybody interested what the new where[] info is for the interface vertices */ + CommChangedInterfaceData(ctrl, graph, nchanged, changed, where, swchanges, rwchanges, wspace->pv4); + + + /*------------------------------------------------------------- + / Update the rinfo of the vertices in the update[] array + /-------------------------------------------------------------*/ + for (ii=0; ii= nparts) { /* If it is a separator vertex */ + /* myprintf(ctrl, "Updating %d %d\n", i+firstvtx, me); */ + + myrinfo = rinfo+i; + myrinfo->edegrees[0] = myrinfo->edegrees[1] = 0; + + for (j=xadj[i]; jedegrees[other%2] += otherwgt; + } + } + } + + /* Finally, sum-up the partition weights */ + MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + graph->mincut = gpwgts[2*nparts-1]; + + IFSET(ctrl->dbglvl, DBG_REFINEINFO, PrintNodeBalanceInfo(ctrl, nparts, gpwgts, badminpwgt, badmaxpwgt, 0)); + } + + if (graph->mincut == oldcut) + break; + } + + /* Go and clear-up the where array */ + for (i=0; inrecv; i++) + where[i] = SelectWhere(where[i]); + + GKfree((void **)&update, (void **)&nupds_pe, (void **)&htable, (void **)&changed, LTERM); + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +} + + + + +/************************************************************************* +* This function prints balance information for the parallel k-section +* refinement algorithm +**************************************************************************/ +void PrintNodeBalanceInfo(CtrlType *ctrl, int nparts, idxtype *gpwgts, idxtype *badminpwgt, idxtype *badmaxpwgt, int title) +{ + int i; + + if (ctrl->mype == 0) { + if (title) + printf("K-way sep-refinement: TotalSep: %d, ", gpwgts[2*nparts-1]); + else + printf("\tTotalSep: %d, ", gpwgts[2*nparts-1]); + + for (i=0; icomm); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ometis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ometis.c new file mode 100644 index 0000000..1a461f1 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/ometis.c @@ -0,0 +1,188 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * ometis.c + * + * This is the entry point of parallel ordering + * + * Started 10/19/96 + * George + * + * $Id: ometis.c,v 1.4 2003/07/25 04:01:04 karypis Exp $ + * + */ + +#include + + + + +/*********************************************************************************** +* This function is the entry point of the parallel ordering algorithm. +* This function assumes that the graph is already nice partitioned among the +* processors and then proceeds to perform recursive bisection. +************************************************************************************/ +void ParMETIS_V3_NodeND(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, + int *options, idxtype *order, idxtype *sizes, MPI_Comm *comm) +{ + int i, j; + int ltvwgts[MAXNCON]; + int nparts, npes, mype, wgtflag = 0, seed = GLOBAL_SEED; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph, *mgraph; + idxtype *morder; + int minnvtxs; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + nparts = npes; + + if (!ispow2(npes)) { + if (mype == 0) + printf("Error: The number of processors must be a power of 2!\n"); + return; + } + + if (vtxdist[npes] < (int)((float)(npes*npes)*1.2)) { + if (mype == 0) + printf("Error: Too many processors for this many vertices.\n"); + return; + } + + minnvtxs = vtxdist[1]-vtxdist[0]; + for (i=0; incon = 1; + mgraph = Moc_MoveGraph(&ctrl, graph, &wspace); + MALLOC_CHECK(NULL); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.MoveTmr)); + + /*======================================================= + * Now compute an ordering of the moved graph + =======================================================*/ + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + FreeWSpace(&wspace); + PreAllocateMemory(&ctrl, mgraph, &wspace); + + ctrl.ipart = ISEP_NODE; + ctrl.CoarsenTo = amin(vtxdist[npes]+1, amax(20*npes, 1000)); + + /* compute tvwgts */ + for (j=0; jncon; j++) + ltvwgts[j] = 0; + + for (i=0; invtxs; i++) + for (j=0; jncon; j++) + ltvwgts[j] += mgraph->vwgt[i*mgraph->ncon+j]; + + for (j=0; jncon; j++) + ctrl.tvwgts[j] = GlobalSESum(&ctrl, ltvwgts[j]); + + mgraph->nvwgt = fmalloc(mgraph->nvtxs*mgraph->ncon, "mgraph->nvwgt"); + for (i=0; invtxs; i++) + for (j=0; jncon; j++) + mgraph->nvwgt[i*mgraph->ncon+j] = (float)(mgraph->vwgt[i*mgraph->ncon+j]) / (float)(ctrl.tvwgts[j]); + + + morder = idxmalloc(mgraph->nvtxs, "PAROMETIS: morder"); + MultilevelOrder(&ctrl, mgraph, morder, sizes, &wspace); + + MALLOC_CHECK(NULL); + + /* Invert the ordering back to the original graph */ + ProjectInfoBack(&ctrl, graph, order, morder, &wspace); + + MALLOC_CHECK(NULL); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + + free(ctrl.tpwgts); + free(morder); + FreeGraph(mgraph); + FreeInitialGraphAndRemap(graph, 0); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + if (*numflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, order, npes, mype, 0); + + MALLOC_CHECK(NULL); +} + + +/*********************************************************************************** +* This function is the entry point of the parallel ordering algorithm. +* This function assumes that the graph is already nice partitioned among the +* processors and then proceeds to perform recursive bisection. +************************************************************************************/ +void PAROMETIS(idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *order, idxtype *sizes, int *options, MPI_Comm comm) +{ + int numflag, newoptions[5]; + + newoptions[0] = 1; + newoptions[PMV3_OPTION_DBGLVL] = options[4]; + newoptions[PMV3_OPTION_SEED] = GLOBAL_SEED; + + numflag = options[3]; + + ParMETIS_V3_NodeND(vtxdist, xadj, adjncy, &numflag, newoptions, order, sizes, &comm); + + options[0] = -1; + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/order.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/order.c new file mode 100644 index 0000000..a73c87b --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/order.c @@ -0,0 +1,348 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * order.c + * + * This file contains the driving routines for the multilevel ordering algorithm + * + * Started 5/3/97 + * George + * + * $Id: order.c,v 1.2 2003/07/21 17:18:50 karypis Exp $ + * + */ + +#define DEBUG_ORDER_ + +#include + +/************************************************************************* +* This is the top level ordering routine +**************************************************************************/ +void MultilevelOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, idxtype *sizes, WorkSpaceType *wspace) +{ + int i, nparts, nvtxs, npes; + idxtype *perm, *lastnode, *morder, *porder; + GraphType *mgraph; + + npes = ctrl->npes; + nvtxs = graph->nvtxs; + + perm = idxmalloc(nvtxs, "MultilevelOrder: perm"); + lastnode = idxsmalloc(4*npes, -1, "MultilevelOrder: lastnode"); + + for (i=0; ignvtxs; + + idxset(nvtxs, -1, order); + + sizes[0] = 2*npes-1; + + graph->where = idxsmalloc(nvtxs, 0, "MultilevelOrder: graph->where"); + + for (nparts=2; nparts<=ctrl->npes; nparts*=2) { + ctrl->nparts = nparts; + + Order_Partition(ctrl, graph, wspace); + + LabelSeparators(ctrl, graph, lastnode, perm, order, sizes, wspace); + + CompactGraph(ctrl, graph, perm, wspace); + + if (ctrl->CoarsenTo < 100*nparts) { + ctrl->CoarsenTo = 1.5*ctrl->CoarsenTo; + } + ctrl->CoarsenTo = amin(ctrl->CoarsenTo, graph->gnvtxs-1); + } + + + /*----------------------------------------------------------------- + / Move the graph so that each processor gets its partition + -----------------------------------------------------------------*/ + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->MoveTmr)); + + SetUp(ctrl, graph, wspace); + graph->ncon = 1; /*needed for Moc_MoveGraph */ + mgraph = Moc_MoveGraph(ctrl, graph, wspace); + + /* Fill in the sizes[] array for the local part. Just the vtxdist of the mgraph */ + for (i=0; ivtxdist[i+1]-mgraph->vtxdist[i]; + + porder = idxmalloc(graph->nvtxs, "MultilevelOrder: porder"); + morder = idxmalloc(mgraph->nvtxs, "MultilevelOrder: morder"); + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->MoveTmr)); + + /* Find the local ordering */ + LocalNDOrder(ctrl, mgraph, morder, lastnode[2*(ctrl->npes+ctrl->mype)]-mgraph->nvtxs, wspace); + + /* Project the ordering back to the before-move graph */ + ProjectInfoBack(ctrl, graph, porder, morder, wspace); + + /* Copy the ordering from porder to order using perm */ + for (i=0; invtxs; i++) { + ASSERT(ctrl, order[perm[i]] == -1); + order[perm[i]] = porder[i]; + } + + FreeGraph(mgraph); + GKfree((void **)&perm, (void **)&lastnode, (void **)&porder, (void **)&morder, LTERM); + + /* PrintVector(ctrl, 2*npes-1, 0, sizes, "SIZES"); */ +} + + +/************************************************************************* +* This function is used to assign labels to the nodes in the separators +* It uses the appropriate entry in the lastnode array to select label +* boundaries and adjusts it for the next level +**************************************************************************/ +void LabelSeparators(CtrlType *ctrl, GraphType *graph, idxtype *lastnode, idxtype *perm, idxtype *order, idxtype *sizes, WorkSpaceType *wspace) +{ + int i, nvtxs, nparts, sid; + idxtype *where, *lpwgts, *gpwgts, *sizescan; + + nparts = ctrl->nparts; + + nvtxs = graph->nvtxs; + where = graph->where; + lpwgts = graph->lpwgts; + gpwgts = graph->gpwgts; + + /* Compute the local size of the separator. This is required in case the + * graph has vertex weights */ + idxset(2*nparts, 0, lpwgts); + for (i=0; icomm); + MPI_Allreduce((void *)lpwgts, (void *)gpwgts, 2*nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); + +#ifdef DEBUG_ORDER + PrintVector(ctrl, 2*nparts, 0, lpwgts, "Lpwgts"); + PrintVector(ctrl, 2*nparts, 0, sizescan, "SizeScan"); + PrintVector(ctrl, 2*nparts, 0, lastnode, "LastNode"); +#endif + + /* Fillin the sizes[] array */ + for (i=nparts-2; i>=0; i-=2) + sizes[--sizes[0]] = gpwgts[nparts+i]; + + if (ctrl->dbglvl&DBG_INFO) { + if (ctrl->mype == 0) { + printf("SepSizes: "); + for (i=0; icomm); + } + + for (i=0; i<2*nparts; i++) + sizescan[i] -= lpwgts[i]; + + for (i=0; i= nparts) { + sid = where[i]; + sizescan[sid]++; + ASSERT(ctrl, order[perm[i]] == -1); + order[perm[i]] = lastnode[sid] - sizescan[sid]; + /* myprintf(ctrl, "order[%d] = %d, %d\n", perm[i], order[perm[i]], sid); */ + } + } + + /* Update lastnode array */ + idxcopy(2*nparts, lastnode, sizescan); + for (i=0; inparts; + npes = ctrl->npes; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + ladjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + + if (graph->cmap == NULL) + graph->cmap = idxmalloc(nvtxs+graph->nrecv, "CompactGraph: cmap"); + cmap = graph->cmap; + + vtxdist = graph->vtxdist; + + /************************************************************* + * Construct the cvtxdist of the contracted graph. Uses the fact + * that lpwgts stores the local non separator vertices. + **************************************************************/ + cvtxdist = wspace->pv1; + cnvtxs = cvtxdist[npes] = idxsum(nparts, graph->lpwgts); + + MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); + MAKECSR(i, npes, cvtxdist); + +#ifdef DEBUG_ORDER + PrintVector(ctrl, npes+1, 0, cvtxdist, "cvtxdist"); +#endif + + + /************************************************************* + * Construct the cmap vector + **************************************************************/ + cfirstvtx = cvtxdist[ctrl->mype]; + + /* Create the cmap of what you know so far locally */ + for (cnvtxs=0, i=0; iindices, cmap+nvtxs); + + + /************************************************************* + * Finally, compact the graph + **************************************************************/ + newwhere = idxmalloc(cnvtxs, "CompactGraph: newwhere"); + cnvtxs = l = 0; + for (i=0; ivwgt[cnvtxs] = graph->vwgt[i]; + newwhere[cnvtxs] = where[i]; + cnvtxs++; + } + } + for (i=cnvtxs; i>0; i--) + xadj[i] = xadj[i-1]; + xadj[0] = 0; + + GKfree((void **)&graph->match, (void **)&graph->cmap, (void **)&graph->lperm, (void **)&graph->where, (void **)&graph->label, (void **)&graph->rinfo, + (void **)&graph->nrinfo, (void **)&graph->lpwgts, (void **)&graph->gpwgts, (void **)&graph->sepind, (void **)&graph->peind, + (void **)&graph->sendptr, (void **)&graph->sendind, (void **)&graph->recvptr, (void **)&graph->recvind, + (void **)&graph->imap, (void **)&graph->rlens, (void **)&graph->slens, (void **)&graph->rcand, (void **)&graph->pexadj, + (void **)&graph->peadjncy, (void **)&graph->peadjloc, LTERM); + + graph->nvtxs = cnvtxs; + graph->nedges = l; + graph->gnvtxs = cvtxdist[npes]; + idxcopy(npes+1, cvtxdist, graph->vtxdist); + graph->where = newwhere; + +} + + +/************************************************************************* +* This function orders the locally stored graph using MMD. +* The vertices will be ordered from firstnode onwards. +**************************************************************************/ +void LocalNDOrder(CtrlType *ctrl, GraphType *graph, idxtype *order, int firstnode, WorkSpaceType *wspace) +{ + int i, j, nvtxs, firstvtx, lastvtx; + idxtype *xadj, *adjncy; + idxtype *perm, *iperm; + int numflag=0, options[10]; + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + + firstvtx = graph->vtxdist[ctrl->mype]; + lastvtx = graph->vtxdist[ctrl->mype+1]; + + /* Relabel the vertices so that they are in local index space */ + for (i=0; i=firstvtx && adjncy[j]maxcore); + + perm = wspace->core; + iperm = perm + nvtxs + 5; + + options[0] = 0; + METIS_NodeND(&nvtxs, xadj, adjncy, &numflag, options, perm, iperm); + + for (i=0; i=0 && iperm[i]ncon = 1; + + IFSET(ctrl->dbglvl, DBG_PROGRESS, rprintf(ctrl, "[%6d %8d %5d %5d][%d][%d]\n", + graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), GlobalSEMin(ctrl, graph->nvtxs), + GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo, + GlobalSEMax(ctrl, graph->vwgt[idxamax(graph->nvtxs, graph->vwgt)]))); + + if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || (graph->finer != NULL && graph->gnvtxs > graph->finer->gnvtxs*COARSEN_FRACTION)) { + /* Compute the initial npart-way multisection */ + InitMultisection(ctrl, graph, wspace); + + if (graph->finer == NULL) { /* Do that only of no-coarsening took place */ + ComputeNodePartitionParams(ctrl, graph, wspace); + KWayNodeRefine(ctrl, graph, wspace, 2*NGR_PASSES, ORDER_UNBALANCE_FRACTION); + } + } + else { /* Coarsen it and the partition it */ + Mc_LocalMatch_HEM(ctrl, graph, wspace); + + Order_Partition(ctrl, graph->coarser, wspace); + + Moc_ProjectPartition(ctrl, graph, wspace); + ComputeNodePartitionParams(ctrl, graph, wspace); + KWayNodeRefine(ctrl, graph, wspace, 2*NGR_PASSES, ORDER_UNBALANCE_FRACTION); + } +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/parmetislib.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/parmetislib.h new file mode 100644 index 0000000..36c1041 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/parmetislib.h @@ -0,0 +1,31 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * par_metis.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: parmetislib.h,v 1.2 2003/07/21 17:50:22 karypis Exp $ + */ + +/* +#define DEBUG 1 +#define DMALLOC 1 +*/ + +#include +#include "../parmetis.h" + +#ifdef DMALLOC +#include +#endif + +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/proto.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/proto.h new file mode 100644 index 0000000..bbab2e5 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/proto.h @@ -0,0 +1,352 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * proto.h + * + * This file contains header files + * + * Started 10/19/95 + * George + * + * $Id: proto.h,v 1.11 2003/07/25 13:52:03 karypis Exp $ + * + */ + +/* kmetis.c */ +void Moc_Global_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* mmetis.c */ + +/* gkmetis.c */ + +/* match.c */ +void Moc_GlobalMatch_Balance(CtrlType *, GraphType *, WorkSpaceType *); + +/* coarsen.c */ +void Moc_Global_CreateCoarseGraph(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* initpart.c */ +void Moc_InitPartition_RB(CtrlType *, GraphType *, WorkSpaceType *); +void Moc_KeepPart(GraphType *, WorkSpaceType *, idxtype *, int); + +/* kwayrefine.c */ +void Moc_ProjectPartition(CtrlType *, GraphType *, WorkSpaceType *); +void Moc_ComputePartitionParams(CtrlType *, GraphType *, WorkSpaceType *); + +/* kwayfm.c */ +void Moc_KWayFM(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* kwaybalance.c */ +void Moc_KWayBalance(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* remap.c */ +void ParallelReMapGraph(CtrlType *, GraphType *, WorkSpaceType *); +void ParallelTotalVReMap(CtrlType *, idxtype *, idxtype *, WorkSpaceType *, int, int); +int SimilarTpwgts(float *, int, int, int); + +/* move.c */ +GraphType *Moc_MoveGraph(CtrlType *, GraphType *, WorkSpaceType *); +/* move.c */ +void CheckMGraph(CtrlType *, GraphType *); +void ProjectInfoBack(CtrlType *, GraphType *, idxtype *, idxtype *, WorkSpaceType *); +void FindVtxPerm(CtrlType *, GraphType *, idxtype *, WorkSpaceType *); + +/* memory.c */ +void PreAllocateMemory(CtrlType *, GraphType *, WorkSpaceType *); +void FreeWSpace(WorkSpaceType *); +void FreeCtrl(CtrlType *); +GraphType *CreateGraph(void); +void InitGraph(GraphType *); +void FreeGraph(GraphType *); +void FreeInitialGraphAndRemap(GraphType *, int); + + +/* ametis.c */ +void Adaptive_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* rmetis.c */ + + +/* lmatch.c */ +void Mc_LocalMatch_HEM(CtrlType *, GraphType *, WorkSpaceType *); +void Mc_Local_CreateCoarseGraph(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* wave.c */ +float WavefrontDiffusion(CtrlType *, GraphType *, idxtype *); + +/* balancemylink.c */ +int BalanceMyLink(CtrlType *, GraphType *, idxtype *, int, int, float *, float, float *, float *, float); + +/* redomylink.c */ +void RedoMyLink(CtrlType *, GraphType *, idxtype *, int, int, float *, float *, float *); + +/* initbalance.c */ +void Balance_Partition(CtrlType *, GraphType *, WorkSpaceType *); +GraphType *Moc_AssembleAdaptiveGraph(CtrlType *, GraphType *, WorkSpaceType *); + +/* mdiffusion.c */ +int Moc_Diffusion(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *, WorkSpaceType *, int); +GraphType *ExtractGraph(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *); + +/* diffutil.c */ +void SetUpConnectGraph(GraphType *, MatrixType *, idxtype *); +void Mc_ComputeMoveStatistics(CtrlType *, GraphType *, int *, int *, int *); + int Mc_ComputeSerialTotalV(GraphType *, idxtype *); +void ComputeLoad(GraphType *, int, float *, float *, int); +void ConjGrad2(MatrixType *, float *, float *, float, float *); +void mvMult2(MatrixType *, float *, float *); +void ComputeTransferVector(int, MatrixType *, float *, float *, int); +int ComputeSerialEdgeCut(GraphType *); +int ComputeSerialTotalV(GraphType *, idxtype *); + +/* akwayfm.c */ +void Moc_KWayAdaptiveRefine(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* selectq.c */ +void Moc_DynamicSelectQueue(int, int, int, int, idxtype *, float *, int *, int *, int, float, float); +int Moc_HashVwgts(int, float *); +int Moc_HashVRank(int, int *); + + +/* csrmatch.c */ +void CSR_Match_SHEM(MatrixType *, idxtype *, idxtype *, idxtype *, int); + +/* serial.c */ +void Moc_SerialKWayAdaptRefine(GraphType *, int, idxtype *, float *, int); +void Moc_ComputeSerialPartitionParams(GraphType *, int, EdgeType *); +int AreAllHVwgtsBelow(int, float, float *, float, float *, float *); +void ComputeHKWayLoadImbalance(int, int, float *, float *); +void SerialRemap(GraphType *, int, idxtype *, idxtype *, idxtype *, float *); +int SSMIncKeyCmp(const void *, const void *); +void Moc_Serial_FM_2WayRefine(GraphType *, float *, int); +void Serial_SelectQueue(int, float *, float *, int *, int *, FPQueueType [MAXNCON][2]); +int Serial_BetterBalance(int, float *, float *, float *); +float Serial_Compute2WayHLoadImbalance(int, float *, float *); +void Moc_Serial_Balance2Way(GraphType *, float *, float); +void Moc_Serial_Init2WayBalance(GraphType *, float *); +int Serial_SelectQueueOneWay(int, float *, float *, int, FPQueueType [MAXNCON][2]); +void Moc_Serial_Compute2WayPartitionParams(GraphType *); +int Serial_AreAnyVwgtsBelow(int, float, float *, float, float *, float *); + +/* weird.c */ +void PartitionSmallGraph(CtrlType *, GraphType *, WorkSpaceType *); +void CheckInputs(int partType, int npes, int dbglvl, int *wgtflag, int *iwgtflag, + int *numflag, int *inumflag, int *ncon, int *incon, int *nparts, + int *inparts, float *tpwgts, float **itpwgts, float *ubvec, + float *iubvec, float *ipc2redist, float *iipc2redist, int *options, + int *ioptions, idxtype *part, MPI_Comm *comm); + +/* mesh.c */ + +/* ometis.c */ + +/* pspases.c */ +GraphType *AssembleEntireGraph(CtrlType *, idxtype *, idxtype *, idxtype *); + +/* node_refine.c */ +void ComputeNodePartitionParams0(CtrlType *, GraphType *, WorkSpaceType *); +void ComputeNodePartitionParams(CtrlType *, GraphType *, WorkSpaceType *); +void KWayNodeRefine0(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void KWayNodeRefine(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void KWayNodeRefine2(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void PrintNodeBalanceInfo(CtrlType *, int, idxtype *, idxtype *, idxtype *, int); + +/* initmsection.c */ +void InitMultisection(CtrlType *, GraphType *, WorkSpaceType *); +GraphType *AssembleMultisectedGraph(CtrlType *, GraphType *, WorkSpaceType *); + +/* order.c */ +void MultilevelOrder(CtrlType *, GraphType *, idxtype *, idxtype *, WorkSpaceType *); +void LabelSeparators(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *, idxtype *, WorkSpaceType *); +void CompactGraph(CtrlType *, GraphType *, idxtype *, WorkSpaceType *); +void LocalOrder(CtrlType *, GraphType *, idxtype *, int, WorkSpaceType *); +void LocalNDOrder(CtrlType *, GraphType *, idxtype *, int, WorkSpaceType *); +void Order_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* xyzpart.c */ +void Coordinate_Partition(CtrlType *, GraphType *, int, float *, int, WorkSpaceType *); +void PartSort(CtrlType *, GraphType *, KeyValueType *, WorkSpaceType *); + + +/* fpqueue.c */ +void FPQueueInit(FPQueueType *, int); +void FPQueueReset(FPQueueType *); +void FPQueueFree(FPQueueType *); +int FPQueueGetSize(FPQueueType *); +int FPQueueInsert(FPQueueType *, int, float); +int FPQueueDelete(FPQueueType *, int); +int FPQueueUpdate(FPQueueType *, int, float, float); +void FPQueueUpdateUp(FPQueueType *, int, float, float); +int FPQueueGetMax(FPQueueType *); +int FPQueueSeeMaxVtx(FPQueueType *); +float FPQueueSeeMaxGain(FPQueueType *); +float FPQueueGetKey(FPQueueType *); +int FPQueueGetQSize(FPQueueType *); +int CheckHeapFloat(FPQueueType *); + +/* stat.c */ +void Moc_ComputeSerialBalance(CtrlType *, GraphType *, idxtype *, float *); +void Moc_ComputeParallelBalance(CtrlType *, GraphType *, idxtype *, float *); +void Moc_PrintThrottleMatrix(CtrlType *, GraphType *, float *); +void Moc_ComputeRefineStats(CtrlType *, GraphType *, float *); + +/* debug.c */ +void PrintVector(CtrlType *, int, int, idxtype *, char *); +void PrintVector2(CtrlType *, int, int, idxtype *, char *); +void PrintPairs(CtrlType *, int, KeyValueType *, char *); +void PrintGraph(CtrlType *, GraphType *); +void PrintGraph2(CtrlType *, GraphType *); +void PrintSetUpInfo(CtrlType *ctrl, GraphType *graph); +void PrintTransferedGraphs(CtrlType *, int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *); +void WriteMetisGraph(int, idxtype *, idxtype *, idxtype *, idxtype *); + +/* comm.c */ +void CommInterfaceData(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *); +void CommChangedInterfaceData(CtrlType *, GraphType *, int, idxtype *, idxtype *, KeyValueType *, KeyValueType *, idxtype *); +int GlobalSEMax(CtrlType *, int); +double GlobalSEMaxDouble(CtrlType *, double); +int GlobalSEMin(CtrlType *, int); +int GlobalSESum(CtrlType *, int); +float GlobalSEMaxFloat(CtrlType *, float); +float GlobalSEMinFloat(CtrlType *, float); +float GlobalSESumFloat(CtrlType *, float); + +/* util.c */ +void errexit(char *,...); +void myprintf(CtrlType *, char *f_str,...); +void rprintf(CtrlType *, char *f_str,...); +#ifndef DMALLOC +int *imalloc(int, char *); +idxtype *idxmalloc(int, char *); +float *fmalloc(int, char *); +int *ismalloc(int, int, char *); +idxtype *idxsmalloc(int, idxtype, char *); +void *GKmalloc(int, char *); +#endif +/*void GKfree(void **,...); */ +int *iset(int n, int val, int *x); +idxtype * idxset(int n, idxtype val, idxtype *x); +int idxamax(int n, idxtype *x); +int idxamin(int n, idxtype *x); +int idxasum(int n, idxtype *x); +float snorm2(int, float *); +float sdot(int n, float *, float *); +void saxpy(int, float, float *, float *); +void ikeyvalsort_org(int, KeyValueType *); +int IncKeyValueCmp(const void *, const void *); +void dkeyvalsort(int, KeyValueType *); +int DecKeyValueCmp(const void *, const void *); +int BSearch(int, idxtype *, int); +void RandomPermute(int, idxtype *, int); +void FastRandomPermute(int, idxtype *, int); +int ispow2(int); +int log2Int(int); +void BucketSortKeysDec(int, int, idxtype *, idxtype *); +float *sset(int n, float val, float *x); +int iamax(int, int *); +int idxamax_strd(int, idxtype *, int); +int idxamin_strd(int, idxtype *, int); +int samax_strd(int, float *, int); +int sfamax(int, float *); +int samin_strd(int, float *, int); +float idxavg(int, idxtype *); +float savg(int, float *); +int samax(int, float *); +int sfavg(int n, float *x); +int samax2(int, float *); +int samin(int, float *); +int idxsum(int, idxtype *); +int idxsum_strd(int, idxtype *, int); +void idxadd(int, idxtype *, idxtype *); +float ssum(int, float *); +float ssum_strd(int, float *, int); +void sscale(int, float, float *); +void saneg(int, float *); +float BetterVBalance(int, float *, float *, float *); +int IsHBalanceBetterTT(int, float *, float *, float *, float *); +int IsHBalanceBetterFT(int, float *, float *, float *, float *); +int myvalkeycompare(const void *, const void *); +int imyvalkeycompare(const void *, const void *); +float *fsmalloc(int, float, char *); +void saxpy2(int, float, float *, int, float *, int); +void GetThreeMax(int, float *, int *, int *, int *); + +/* qsort_special.c */ +void iidxsort(int, idxtype *); +void iintsort(int, int *); +void ikeysort(int, KeyValueType *); +void ikeyvalsort(int, KeyValueType *); + +/* grsetup.c */ +GraphType *Moc_SetUpGraph(CtrlType *, int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *); +void SetUpCtrl(CtrlType *ctrl, int, int, MPI_Comm); +void ChangeNumbering(idxtype *, idxtype *, idxtype *, idxtype *, int, int, int); +void ChangeNumberingMesh(idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int, int, int); +void ChangeNumberingMesh2(idxtype *elmdist, idxtype *eptr, idxtype *eind, + idxtype *xadj, idxtype *adjncy, idxtype *part, + int npes, int mype, int from); +void GraphRandomPermute(GraphType *); +void ComputeMoveStatistics(CtrlType *, GraphType *, int *, int *, int *); + +/* timer.c */ +void InitTimers(CtrlType *); +void PrintTimingInfo(CtrlType *); +void PrintTimer(CtrlType *, timer, char *); + +/* setup.c */ +void SetUp(CtrlType *, GraphType *, WorkSpaceType *); +int Home_PE(int, int, idxtype *, int); + + +/*********************/ +/* METIS subroutines */ +/*********************/ +void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_mCPartGraphRecursive2(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MCMlevelRecursiveBisection2(CtrlType *, GraphType *, int, float *, idxtype *, float, int); +void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *); + + + +/***********************/ +/* TESTing subroutines */ +/***********************/ + +/* pio.c */ +void ParallelReadGraph(GraphType *, char *, MPI_Comm); +void Moc_ParallelWriteGraph(CtrlType *, GraphType *, char *, int, int); +void ReadTestGraph(GraphType *, char *, MPI_Comm); +float *ReadTestCoordinates(GraphType *, char *, int, MPI_Comm); +void ReadMetisGraph(char *, int *, idxtype **, idxtype **); +void Moc_SerialReadGraph(GraphType *, char *, int *, MPI_Comm); +void Moc_SerialReadMetisGraph(char *, int *, int *, int *, int *, idxtype **, idxtype **, idxtype **, idxtype **, int *); + +/* adaptgraph */ +void AdaptGraph(GraphType *, int, MPI_Comm); +void AdaptGraph2(GraphType *, int, MPI_Comm); +void Mc_AdaptGraph(GraphType *, idxtype *, int, int, MPI_Comm); + +/* ptest.c */ +void TestParMetis(char *, MPI_Comm); + +/* NEW_ptest.c */ +void TestParMetis_V3(char *, MPI_Comm); +int ComputeRealCut(idxtype *, idxtype *, char *, MPI_Comm); +int ComputeRealCut2(idxtype *, idxtype *, idxtype *, idxtype *, char *, MPI_Comm); +void TestMoveGraph(GraphType *, GraphType *, idxtype *, MPI_Comm); +GraphType *SetUpGraph(CtrlType *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int); + +/* mienio.c */ +void mienIO(MeshType *, char *, int, int, MPI_Comm); + +/* meshio.c */ +void ParallelReadMesh(MeshType *, char *, MPI_Comm); + +/* parmetis.c */ +void ChangeToFortranNumbering(idxtype *, idxtype *, idxtype *, int, int); + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/pspases.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/pspases.c new file mode 100644 index 0000000..8b7a182 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/pspases.c @@ -0,0 +1,167 @@ +/* + * pspases.c + * + * This file contains ordering routines that are to be used with the + * parallel Cholesky factorization code PSPASES + * + * Started 10/14/97 + * George + * + * $Id: pspases.c,v 1.3 2003/07/21 17:18:53 karypis Exp $ + * + */ + +#include + + +/*********************************************************************************** +* This function is the entry point of the serial ordering algorithm. +************************************************************************************/ +void ParMETIS_SerialNodeND(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, + int *options, idxtype *order, idxtype *sizes, MPI_Comm *comm) +{ + int i, npes, mype, seroptions[10]; + CtrlType ctrl; + GraphType *agraph; + idxtype *perm=NULL, *iperm=NULL; + int *sendcount, *displs; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + if (!ispow2(npes)) { + if (mype == 0) + printf("Error: The number of processors must be a power of 2!\n"); + return; + } + + if (*numflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, order, npes, mype, 1); + + SetUpCtrl(&ctrl, npes, options[OPTION_DBGLVL], *comm); + + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.MoveTmr)); + + agraph = AssembleEntireGraph(&ctrl, vtxdist, xadj, adjncy); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.MoveTmr)); + + + if (mype == 0) { + perm = idxmalloc(agraph->nvtxs, "PAROMETISS: perm"); + iperm = idxmalloc(agraph->nvtxs, "PAROMETISS: iperm"); + + seroptions[0] = 0; + /* + seroptions[1] = 3; + seroptions[2] = 1; + seroptions[3] = 2; + seroptions[4] = 128; + seroptions[5] = 1; + seroptions[6] = 0; + seroptions[7] = 1; + */ + + METIS_NodeNDP(agraph->nvtxs, agraph->xadj, agraph->adjncy, npes, seroptions, perm, iperm, sizes); + } + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.MoveTmr)); + + /* Broadcast the sizes array */ + MPI_Bcast((void *)sizes, 2*npes, IDX_DATATYPE, 0, ctrl.gcomm); + + /* Scatter the iperm */ + sendcount = imalloc(npes, "PAROMETISS: sendcount"); + displs = imalloc(npes, "PAROMETISS: displs"); + for (i=0; ixadj, (void **)&agraph->adjncy, (void **)&perm, (void **)&iperm, (void **)&sendcount, (void **)&displs, LTERM); + free(agraph); + FreeCtrl(&ctrl); + + if (*numflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, order, npes, mype, 0); + +} + + + +/************************************************************************* +* This function assembles the graph into a single processor +**************************************************************************/ +GraphType *AssembleEntireGraph(CtrlType *ctrl, idxtype *vtxdist, idxtype *xadj, idxtype *adjncy) +{ + int i, gnvtxs, nvtxs, gnedges, nedges; + int npes = ctrl->npes, mype = ctrl->mype; + idxtype *axadj, *aadjncy; + int *recvcounts, *displs; + GraphType *agraph; + + gnvtxs = vtxdist[npes]; + nvtxs = vtxdist[mype+1]-vtxdist[mype]; + nedges = xadj[nvtxs]; + + recvcounts = imalloc(npes, "AssembleGraph: recvcounts"); + displs = imalloc(npes+1, "AssembleGraph: displs"); + + /* Gather all the xadj arrays first */ + for (i=0; icomm); + + MAKECSR(i, nvtxs, xadj); + MAKECSR(i, gnvtxs, axadj); + + /* Gather all the adjncy arrays next */ + /* Determine the # of edges stored at each processor */ + MPI_Allgather((void *)(&nedges), 1, MPI_INT, (void *)recvcounts, 1, MPI_INT, ctrl->comm); + + displs[0] = 0; + for (i=1; icomm); + + /* myprintf(ctrl, "Gnvtxs: %d, Gnedges: %d\n", gnvtxs, gnedges); */ + + agraph = CreateGraph(); + agraph->nvtxs = gnvtxs; + agraph->nedges = gnedges; + agraph->xadj = axadj; + agraph->adjncy = aadjncy; + + return agraph; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/redomylink.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/redomylink.c new file mode 100644 index 0000000..98b6810 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/redomylink.c @@ -0,0 +1,175 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * redomylink.c + * + * This file contains code that implements the edge-based FM refinement + * + * Started 7/23/97 + * George + * + * $Id: redomylink.c,v 1.2 2003/07/21 17:18:53 karypis Exp $ + */ + +#include +#define PE 0 + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void RedoMyLink(CtrlType *ctrl, GraphType *graph, idxtype *home, int me, + int you, float *flows, float *sr_cost, float *sr_lbavg) +{ + int h, i, r; + int nvtxs, nedges, ncon; + int pass, lastseed, totalv; + idxtype *xadj, *adjncy, *adjwgt, *where, *vsize; + idxtype *costwhere, *lbwhere, *selectwhere; + idxtype *rdata, *ed, *id, *bndptr, *bndind, *perm; + float *nvwgt, mycost; + float lbavg, lbvec[MAXNCON]; + float best_lbavg, other_lbavg = -1.0, bestcost, othercost = -1.0; + float npwgts[2*MAXNCON], pwgts[MAXNCON*2], tpwgts[MAXNCON*2]; + float ipc_factor, redist_factor, ftmp; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + nvtxs = graph->nvtxs; + nedges = graph->nedges; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + vsize = graph->vsize; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + ipc_factor = ctrl->ipc_factor; + redist_factor = ctrl->redist_factor; + + /**************************/ + /* set up data structures */ + /**************************/ + rdata = idxmalloc(7*nvtxs, "rdata"); + id = graph->sendind = rdata; + ed = graph->recvind = rdata + nvtxs; + bndptr = graph->sendptr = rdata + 2*nvtxs; + bndind = graph->recvptr = rdata + 3*nvtxs; + costwhere = rdata + 4*nvtxs; + lbwhere = rdata + 5*nvtxs; + perm = rdata + 6*nvtxs; + graph->gnpwgts = npwgts; + + RandomPermute(nvtxs, perm, 1); + idxcopy(nvtxs, where, costwhere); + idxcopy(nvtxs, where, lbwhere); + + /*****************************/ + /* compute target pwgts */ + /*****************************/ + sset(ncon*2, 0.0, pwgts); + for (h=0; h0; pass--) { + idxset(nvtxs, 1, where); + + /***************************/ + /* find seed vertices */ + /***************************/ + r = perm[lastseed] % nvtxs; + lastseed = (lastseed+1) % nvtxs; + where[r] = 0; + + Moc_Serial_Compute2WayPartitionParams(graph); + Moc_Serial_Init2WayBalance(graph, tpwgts); + Moc_Serial_FM_2WayRefine(graph, tpwgts, 4); + Moc_Serial_Balance2Way(graph, tpwgts, 1.02); + Moc_Serial_FM_2WayRefine(graph, tpwgts, 4); + + for (i=0; imincut)*ipc_factor + (float)totalv*redist_factor; + + if (bestcost >= mycost) { + bestcost = mycost; + other_lbavg = lbavg; + idxcopy(nvtxs, where, costwhere); + } + + if (best_lbavg >= lbavg) { + best_lbavg = lbavg; + othercost = mycost; + idxcopy(nvtxs, where, lbwhere); + } + } + + if (other_lbavg <= .05) { + selectwhere = costwhere; + *sr_cost = bestcost; + *sr_lbavg = other_lbavg; + } + else { + selectwhere = lbwhere; + *sr_cost = othercost; + *sr_lbavg = best_lbavg; + } + + idxcopy(nvtxs, selectwhere, where); + + GKfree((void **)&rdata, LTERM); + return; +} + 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 + +/************************************************************************* +* 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; incon); + + for (i=0; idbglvl, 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 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; iitpwgts, 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; jtpwgts, 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; idbglvl, 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; idbglvl, 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 SMALLFLOAT) + break; + + if (i == ncon) + return 1; + + return 0; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rename.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rename.h new file mode 100644 index 0000000..d993257 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rename.h @@ -0,0 +1,290 @@ +/* kmetis.c */ +#define Moc_Global_Partition Moc_Global_Partition__ + +/* mmetis.c */ + +/* gkmetis.c */ + +/* match.c */ +#define Moc_GlobalMatch_Balance Moc_GlobalMatch_Balance__ + +/* coarsen.c */ +#define Moc_Global_CreateCoarseGraph Moc_Global_CreateCoarseGraph__ + +/* initpart.c */ +#define Moc_InitPartition_RB Moc_InitPartition_RB__ +#define Moc_KeepPart Moc_KeepPart__ + +/* kwayrefine.c */ +#define Moc_ProjectPartition Moc_ProjectPartition__ +#define Moc_ComputePartitionParams Moc_ComputePartitionParams__ + +/* kwayfm.c */ +#define Moc_KWayFM Moc_KWayFM__ + +/* kwaybalance.c */ +#define Moc_KWayBalance Moc_KWayBalance__ + +/* remap.c */ +#define ParallelReMapGraph ParallelReMapGraph__ +#define ParallelTotalVReMap ParallelTotalVReMap__ +#define SimilarTpwgts SimilarTpwgts__ + +/* move.c */ +#define Moc_MoveGraph Moc_MoveGraph__ +#define CheckMGraph CheckMGraph__ +#define ProjectInfoBack ProjectInfoBack__ +#define FindVtxPerm FindVtxPerm__ + +/* memory.c */ +#define PreAllocateMemory PreAllocateMemory__ +#define FreeWSpace FreeWSpace__ +#define FreeCtrl FreeCtrl__ +#define CreateGraph CreateGraph__ +#define InitGraph InitGraph__ +#define FreeGraph FreeGraph__ +#define FreeInitialGraphAndRemap FreeInitialGraphAndRemap__ + + +/************************/ +/* Adaptive subroutines */ +/************************/ +/* ametis.c */ +#define Adaptive_Partition Adaptive_Partition__ + +/* rmetis.c */ + +/* lmatch.c */ +#define Mc_LocalMatch_HEM Mc_LocalMatch_HEM__ +#define Mc_Local_CreateCoarseGraph Mc_Local_CreateCoarseGraph__ + +/* wave.c */ +#define WavefrontDiffusion WavefrontDiffusion__ + +/* balancemylink.c */ +#define BalanceMyLink BalanceMyLink__ + +/* redomylink.c */ +#define RedoMyLink RedoMyLink__ + +/* initbalance.c */ +#define Balance_Partition Balance_Partition__ +#define Moc_AssembleAdaptiveGraph Moc_AssembleAdaptiveGraph__ + +/* mdiffusion.c */ +#define Moc_Diffusion Moc_Diffusion__ +#define ExtractGraph ExtractGraph__ + +/* diffutil.c */ +#define SetUpConnectGraph SetUpConnectGraph__ +#define Mc_ComputeMoveStatistics Mc_ComputeMoveStatistics__ +#define Mc_ComputeSerialTotalV Mc_ComputeSerialTotalV__ +#define ComputeLoad ComputeLoad__ +#define ConjGrad2 ConjGrad2__ +#define mvMult2 mvMult2__ +#define ComputeTransferVector ComputeTransferVector__ +#define ComputeSerialEdgeCut ComputeSerialEdgeCut__ +#define ComputeSerialTotalV ComputeSerialTotalV__ + +/* akwayfm.c */ +#define Moc_KWayAdaptiveRefine Moc_KWayAdaptiveRefine__ + +/* selectq.c */ +#define Moc_DynamicSelectQueue Moc_DynamicSelectQueue__ +#define Moc_HashVwgts Moc_HashVwgts__ +#define Moc_HashVRank Moc_HashVRank__ + +/* csrmatch.c */ +#define CSR_Match_SHEM CSR_Match_SHEM__ + +/* serial.c */ +#define Moc_SerialKWayAdaptRefine Moc_SerialKWayAdaptRefine__ +#define Moc_ComputeSerialPartitionParams Moc_ComputeSerialPartitionParams__ +#define AreAllHVwgtsBelow AreAllHVwgtsBelow__ +#define ComputeHKWayLoadImbalance ComputeHKWayLoadImbalance__ +#define SerialRemap SerialRemap__ +#define SSMIncKeyCmp SSMIncKeyCmp__ +#define Moc_Serial_FM_2WayRefine Moc_Serial_FM_2WayRefine__ +#define Serial_SelectQueue Serial_SelectQueue__ +#define Serial_BetterBalance Serial_BetterBalance__ +#define Serial_Compute2WayHLoadImbalance Serial_Compute2WayHLoadImbalance__ +#define Moc_Serial_Balance2Way Moc_Serial_Balance2Way__ +#define Moc_Serial_Init2WayBalance Moc_Serial_Init2WayBalance__ +#define Serial_SelectQueueOneWay Serial_SelectQueueOneWay__ +#define Moc_Serial_Compute2WayPartitionParams Moc_Serial_Compute2WayPartitionParams__ +#define Serial_AreAnyVwgtsBelow Serial_AreAnyVwgtsBelow__ + +/* weird.c */ +#define PartitionSmallGraph PartitionSmallGraph__ +#define CheckInputs CheckInputs__ + + +/****************************/ +/* Mesh to Dual subroutines */ +/****************************/ +/* mesh.c */ +/* msetup.c */ +#define SetUpMesh SetUpMesh__ +#define CreateMesh CreateMesh__ +#define InitMesh InitMesh__ + + +/************************/ +/* Ordering subroutines */ +/************************/ +/* ometis.c */ +/* pspases.c */ +#define AssembleEntireGraph AssembleEntireGraph__ + +/* node_refine.c */ +#define ComputeNodePartitionParams0 ComputeNodePartitionParams0__ +#define ComputeNodePartitionParams ComputeNodePartitionParams__ +#define KWayNodeRefine0 KWayNodeRefine0__ +#define KWayNodeRefine KWayNodeRefine__ +#define KWayNodeRefine2 KWayNodeRefine2__ +#define PrintNodeBalanceInfo PrintNodeBalanceInfo__ + +/* initmsection.c */ +#define InitMultisection InitMultisection__ +#define AssembleMultisectedGraph AssembleMultisectedGraph__ + +/* order.c */ +#define MultilevelOrder MultilevelOrder__ +#define LabelSeparators LabelSeparators__ +#define CompactGraph CompactGraph__ +#define LocalOrder LocalOrder__ +#define LocalNDOrder LocalNDOrder__ +#define Order_Partition Order_Partition__ + +/* xyzpart.c */ +#define Coordinate_Partition Coordinate_Partition__ +#define PartSort PartSort__ + +/***********************/ +/* Utility subroutines */ +/***********************/ +/* fpqueue.c */ +#define FPQueueInit FPQueueInit__ +#define FPQueueReset FPQueueReset__ +#define FPQueueFree FPQueueFree__ +#define FPQueueGetSize FPQueueGetSize__ +#define FPQueueInsert FPQueueInsert__ +#define FPQueueDelete FPQueueDelete__ +#define FPQueueUpdate FPQueueUpdate__ +#define FPQueueUpdateUp FPQueueUpdateUp__ +#define FPQueueGetMax FPQueueGetMax__ +#define FPQueueSeeMaxVtx FPQueueSeeMaxVtx__ +#define FPQueueSeeMaxGain FPQueueSeeMaxGain__ +#define FPQueueGetKey FPQueueGetKey__ +#define FPQueueGetQSize FPQueueGetQSize__ +#define CheckHeapFloat CheckHeapFloat__ + +/* stat.c */ +#define Moc_ComputeSerialBalance Moc_ComputeSerialBalance__ +#define Moc_ComputeParallelBalance Moc_ComputeParallelBalance__ +#define Moc_PrintThrottleMatrix Moc_PrintThrottleMatrix__ +#define Moc_ComputeRefineStats Moc_ComputeRefineStats__ + +/* debug.c */ +#define PrintVector PrintVector__ +#define PrintVector2 PrintVector2__ +#define PrintPairs PrintPairs__ +#define PrintGraph PrintGraph__ +#define PrintGraph2 PrintGraph2__ +#define PrintSetUpInfo PrintSetUpInfo__ +#define PrintTransferedGraphs PrintTransferedGraphs__ +#define WriteMetisGraph WriteMetisGraph__ + +/* comm.c */ +#define CommInterfaceData CommInterfaceData__ +#define CommChangedInterfaceData CommChangedInterfaceData__ +#define GlobalSEMax GlobalSEMax__ +#define GlobalSEMaxDouble GlobalSEMaxDouble__ +#define GlobalSEMin GlobalSEMin__ +#define GlobalSESum GlobalSESum__ +#define GlobalSEMaxFloat GlobalSEMaxFloat__ +#define GlobalSEMinFloat GlobalSEMinFloat__ +#define GlobalSESumFloat GlobalSESumFloat__ + +/* util.c */ +#define errexit errexit__ +#define myprintf myprintf__ +#define rprintf rprintf__ +#define imalloc imalloc__ +#define idxmalloc idxmalloc__ +#define fmalloc fmalloc__ +#define ismalloc ismalloc__ +#define idxsmalloc idxsmalloc__ +#define GKmalloc GKmalloc__ +#define GKfree GKfree__ +#define iset iset__ +#define idxset idxset__ +#define idxamax idxamax__ +#define idxamin idxamin__ +#define idxasum idxasum__ +#define snorm2 snorm2__ +#define sdot sdot__ +#define saxpy saxpy__ +#define ikeyvalsort_org ikeyvalsort_org__ +#define IncKeyValueCmp IncKeyValueCmp__ +#define dkeyvalsort dkeyvalsort__ +#define DecKeyValueCmp DecKeyValueCmp__ +#define BSearch BSearch__ +#define RandomPermute RandomPermute__ +#define FastRandomPermute FastRandomPermute__ +#define ispow2 ispow2__ +#define log2Int log2Int__ +#define BucketSortKeysDec BucketSortKeysDec__ +#define sset sset__ +#define iamax iamax__ +#define idxamax_strd idxamax_strd__ +#define idxamin_strd idxamin_strd__ +#define samax_strd samax_strd__ +#define sfamax sfamax__ +#define samin_strd samin_strd__ +#define idxavg idxavg__ +#define savg savg__ +#define samax samax__ +#define sfavg sfavg__ +#define samax2 samax2__ +#define samin samin__ +#define idxsum idxsum__ +#define idxsum_strd idxsum_strd__ +#define idxadd idxadd__ +#define ssum ssum__ +#define ssum_strd ssum_strd__ +#define sscale sscale__ +#define saneg saneg__ +#define BetterVBalance BetterVBalance__ +#define IsHBalanceBetterTT IsHBalanceBetterTT__ +#define IsHBalanceBetterFT IsHBalanceBetterFT__ +#define myvalkeycompare myvalkeycompare__ +#define imyvalkeycompare imyvalkeycompare__ +#define fsmalloc fsmalloc__ +#define saxpy2 saxpy2__ +#define GetThreeMax GetThreeMax__ + +/* qsort_special.c */ +#define iidxsort iidxsort__ +#define iintsort iintsort__ +#define ikeysort ikeysort__ +#define ikeyvalsort ikeyvalsort__ + +/* grsetup.c */ +#define Moc_SetUpGraph Moc_SetUpGraph__ +#define SetUpCtrl SetUpCtrl__ +#define ChangeNumbering ChangeNumbering__ +#define ChangeNumberingMesh ChangeNumberingMesh__ +#define GraphRandomPermute GraphRandomPermute__ +#define ComputeMoveStatistics ComputeMoveStatistics__ + +/* timer.c */ +#define InitTimers InitTimers__ +#define PrintTimingInfo PrintTimingInfo__ +#define PrintTimer PrintTimer__ + +/* setup.c */ +#define SetUp SetUp__ +#define Home_PE Home_PE__ + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rmetis.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rmetis.c new file mode 100644 index 0000000..3755209 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/rmetis.c @@ -0,0 +1,165 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * rmetis.c + * + * This is the entry point of the partitioning refinement routine + * + * Started 10/19/96 + * George + * + * $Id: rmetis.c,v 1.5 2003/07/25 04:01:05 karypis Exp $ + * + */ + +#include + + + +/*********************************************************************************** +* This function is the entry point of the parallel multilevel local diffusion +* algorithm. It uses parallel undirected diffusion followed by adaptive k-way +* refinement. This function utilizes local coarsening. +************************************************************************************/ +void ParMETIS_V3_RefineKway(idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, + idxtype *vwgt, idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, + int *nparts, float *tpwgts, float *ubvec, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm) +{ + int h, i; + int npes, mype; + CtrlType ctrl; + WorkSpaceType wspace; + GraphType *graph; + int tewgt, tvsize, nmoved, maxin, maxout; + float gtewgt, gtvsize, avg, maximb; + int ps_relation, seed, dbglvl = 0; + int iwgtflag, inumflag, incon, inparts, ioptions[10]; + float *itpwgts, iubvec[MAXNCON]; + + MPI_Comm_size(*comm, &npes); + MPI_Comm_rank(*comm, &mype); + + /********************************/ + /* Try and take care bad inputs */ + /********************************/ + if (options != NULL && options[0] == 1) + dbglvl = options[PMV3_OPTION_DBGLVL]; + CheckInputs(REFINE_PARTITION, npes, dbglvl, wgtflag, &iwgtflag, numflag, &inumflag, + ncon, &incon, nparts, &inparts, tpwgts, &itpwgts, ubvec, iubvec, + NULL, NULL, options, ioptions, part, comm); + + /* ADD: take care of disconnected graph */ + /* ADD: take care of highly unbalanced vtxdist */ + /*********************************/ + /* Take care the nparts = 1 case */ + /*********************************/ + if (inparts <= 1) { + idxset(vtxdist[mype+1]-vtxdist[mype], 0, part); + *edgecut = 0; + return; + } + + /**************************/ + /* Set up data structures */ + /**************************/ + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 1); + + /*****************************/ + /* Set up control structures */ + /*****************************/ + if (ioptions[0] == 1) { + dbglvl = ioptions[PMV3_OPTION_DBGLVL]; + seed = ioptions[PMV3_OPTION_SEED]; + ps_relation = (npes == inparts) ? ioptions[PMV3_OPTION_PSR] : DISCOUPLED; + } + else { + dbglvl = GLOBAL_DBGLVL; + seed = GLOBAL_SEED; + ps_relation = (npes == inparts) ? COUPLED : DISCOUPLED; + } + + SetUpCtrl(&ctrl, inparts, dbglvl, *comm); + ctrl.CoarsenTo = amin(vtxdist[npes]+1, 50*incon*amax(npes, inparts)); + ctrl.ipc_factor = 1000.0; + ctrl.redist_factor = 1.0; + ctrl.redist_base = 1.0; + ctrl.seed = (seed == 0) ? mype : seed*mype; + ctrl.sync = GlobalSEMax(&ctrl, seed); + ctrl.partType = REFINE_PARTITION; + ctrl.ps_relation = ps_relation; + ctrl.tpwgts = itpwgts; + + graph = Moc_SetUpGraph(&ctrl, incon, vtxdist, xadj, vwgt, adjncy, adjwgt, &iwgtflag); + graph->vsize = idxsmalloc(graph->nvtxs, 1, "vsize"); + + graph->home = idxmalloc(graph->nvtxs, "home"); + if (ctrl.ps_relation == COUPLED) + idxset(graph->nvtxs, mype, graph->home); + else + idxcopy(graph->nvtxs, part, graph->home); + + tewgt = idxsum(graph->nedges, graph->adjwgt); + tvsize = idxsum(graph->nvtxs, graph->vsize); + gtewgt = (float) GlobalSESum(&ctrl, tewgt) + 1.0/graph->gnvtxs; + gtvsize = (float) GlobalSESum(&ctrl, tvsize) + 1.0/graph->gnvtxs; + ctrl.edge_size_ratio = gtewgt/gtvsize; + scopy(incon, iubvec, ctrl.ubvec); + + PreAllocateMemory(&ctrl, graph, &wspace); + + /***********************/ + /* Partition and Remap */ + /***********************/ + IFSET(ctrl.dbglvl, DBG_TIME, InitTimers(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, starttimer(ctrl.TotalTmr)); + + Adaptive_Partition(&ctrl, graph, &wspace); + ParallelReMapGraph(&ctrl, graph, &wspace); + + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + IFSET(ctrl.dbglvl, DBG_TIME, stoptimer(ctrl.TotalTmr)); + + idxcopy(graph->nvtxs, graph->where, part); + if (edgecut != NULL) + *edgecut = graph->mincut; + + /***********************/ + /* Take care of output */ + /***********************/ + IFSET(ctrl.dbglvl, DBG_TIME, PrintTimingInfo(&ctrl)); + IFSET(ctrl.dbglvl, DBG_TIME, MPI_Barrier(ctrl.gcomm)); + + if (ctrl.dbglvl&DBG_INFO) { + Mc_ComputeMoveStatistics(&ctrl, graph, &nmoved, &maxin, &maxout); + rprintf(&ctrl, "Final %3d-way Cut: %6d \tBalance: ", inparts, graph->mincut); + avg = 0.0; + for (h=0; hgnpwgts[i*incon+h]/itpwgts[i*incon+h]); + avg += maximb; + rprintf(&ctrl, "%.3f ", maximb); + } + rprintf(&ctrl, "\nNMoved: %d %d %d %d\n", nmoved, maxin, maxout, maxin+maxout); + } + + /*************************************/ + /* Free memory, renumber, and return */ + /*************************************/ + GKfree((void **)&graph->lnpwgts, (void **)&graph->gnpwgts, (void **)&graph->nvwgt, (void **)(&graph->home), (void **)(&graph->vsize), LTERM); + + GKfree((void **)&itpwgts, LTERM); + FreeInitialGraphAndRemap(graph, iwgtflag); + FreeWSpace(&wspace); + FreeCtrl(&ctrl); + + if (inumflag == 1) + ChangeNumbering(vtxdist, xadj, adjncy, part, npes, mype, 0); + + return; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/selectq.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/selectq.c new file mode 100644 index 0000000..5ec9109 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/selectq.c @@ -0,0 +1,340 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * selectq.c + * + * This file contains the driving routines for multilevel k-way refinement + * + * Started 7/28/97 + * George + * + * $Id: selectq.c,v 1.2 2003/07/21 17:18:53 karypis Exp $ + */ + +#include + +/************************************************************************* +* This stuff is hardcoded for up to four constraints +**************************************************************************/ +void Moc_DynamicSelectQueue(int nqueues, int ncon, int subdomain1, int subdomain2, + idxtype *currentq, float *flows, int *from, int *qnum, int minval, float avgvwgt, + float maxdiff) +{ + int i, j; + int hash, index = -1, current; + int cand[MAXNCON], rank[MAXNCON], dont_cares[MAXNCON]; + int nperms, perm[24][5]; + float sign = 0.0; + KVType array[MAXNCON]; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + *qnum = -1; + + if (*from == -1) { + for (i=0; iavgvwgt*MOC_GD_GRANULARITY_FACTOR) { + *from = subdomain1; + sign = 1.0; + index = 0; + } + + if (flows[array[ncon-1].key]<-1.0*avgvwgt*MOC_GD_GRANULARITY_FACTOR) { + *from = subdomain2; + sign = -1.0; + index = nqueues; + } + + if (*from == -1) { + return; + } + } + else { + ASSERTS(*from == subdomain1 || *from == subdomain2); + + if (*from == subdomain1) { + sign = 1.0; + index = 0; + } + else { + sign = -1.0; + index = nqueues; + } + } + + for (i=0; i 0) { + *qnum = hash; + return; + } + } + + return; +} + + +/************************************************************************* +* This function sorts the nvwgts of a vertex and returns a hashed value +**************************************************************************/ +int Moc_HashVwgts(int ncon, float *nvwgt) +{ + int i; + int multiplier, retval; + int rank[MAXNCON]; + KVType array[MAXNCON]; + + + for (i=0; i + + +/************************************************************************* +* This function performs k-way refinement +**************************************************************************/ +void Moc_SerialKWayAdaptRefine(GraphType *graph, int nparts, idxtype *home, + float *orgubvec, int npasses) +{ + int i, ii, iii, j, k; + int nvtxs, ncon, pass, nmoves, myndegrees; + int from, me, myhome, to, oldcut, gain, tmp; + idxtype *xadj, *adjncy, *adjwgt; + idxtype *where; + EdgeType *mydegrees; + RInfoType *rinfo, *myrinfo; + float *npwgts, *nvwgt, *minwgt, *maxwgt, ubvec[MAXNCON]; + int gain_is_greater, gain_is_same, fit_in_to, fit_in_from, going_home; + int zero_gain, better_balance_ft, better_balance_tt; + KeyValueType *cand; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->rinfo; + npwgts = graph->gnpwgts; + + /* Setup the weight intervals of the various subdomains */ + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "cand"); + minwgt = fmalloc(nparts*ncon, "minwgt"); + maxwgt = fmalloc(nparts*ncon, "maxwgt"); + + ComputeHKWayLoadImbalance(ncon, nparts, npwgts, ubvec); + for (i=0; imincut; + + for (i=0; ied >= myrinfo->id) { + from = where[i]; + myhome = home[i]; + nvwgt = graph->nvwgt+i*ncon; + + if (myrinfo->id > 0 && + AreAllHVwgtsBelow(ncon, 1.0, npwgts+from*ncon, -1.0, nvwgt, minwgt+from*ncon)) + continue; + + mydegrees = myrinfo->degrees; + myndegrees = myrinfo->ndegrees; + + for (k=0; kid; + if (gain >= 0 && + (AreAllHVwgtsBelow(ncon, 1.0, npwgts+to*ncon, 1.0, nvwgt, maxwgt+to*ncon) || + IsHBalanceBetterFT(ncon,npwgts+from*ncon,npwgts+to*ncon,nvwgt,ubvec))) { + break; + } + } + + /* break out if you did not find a candidate */ + if (k == myndegrees) + continue; + + for (j=k+1; j mydegrees[k].ewgt); + fit_in_to = AreAllHVwgtsBelow(ncon,1.0,npwgts+to*ncon,1.0,nvwgt,maxwgt+to*ncon); + better_balance_ft = IsHBalanceBetterFT(ncon,npwgts+from*ncon, + npwgts+to*ncon,nvwgt,ubvec); + better_balance_tt = IsHBalanceBetterTT(ncon,npwgts+mydegrees[k].edge*ncon, + npwgts+to*ncon,nvwgt,ubvec); + + if ( + (gain_is_greater && + (fit_in_to || + better_balance_ft) + ) + || + (gain_is_same && + ( + (fit_in_to && + going_home) + || + better_balance_tt + ) + ) + ) { + k = j; + } + } + + to = mydegrees[k].edge; + going_home = (myhome == to); + zero_gain = (mydegrees[k].ewgt == myrinfo->id); + + fit_in_from = AreAllHVwgtsBelow(ncon,1.0,npwgts+from*ncon,0.0,npwgts+from*ncon, + maxwgt+from*ncon); + better_balance_ft = IsHBalanceBetterFT(ncon,npwgts+from*ncon, + npwgts+to*ncon,nvwgt,ubvec); + + if (zero_gain && + !going_home && + !better_balance_ft && + fit_in_from) + continue; + + /*===================================================================== + * If we got here, we can now move the vertex from 'from' to 'to' + *======================================================================*/ + graph->mincut -= mydegrees[k].ewgt-myrinfo->id; + + /* Update where, weight, and ID/ED information of the vertex you moved */ + saxpy2(ncon, 1.0, nvwgt, 1, npwgts+to*ncon, 1); + saxpy2(ncon, -1.0, nvwgt, 1, npwgts+from*ncon, 1); + where[i] = to; + myrinfo->ed += myrinfo->id-mydegrees[k].ewgt; + SWAP(myrinfo->id, mydegrees[k].ewgt, tmp); + + if (mydegrees[k].ewgt == 0) { + myrinfo->ndegrees--; + mydegrees[k].edge = mydegrees[myrinfo->ndegrees].edge; + mydegrees[k].ewgt = mydegrees[myrinfo->ndegrees].ewgt; + } + else + mydegrees[k].edge = from; + + /* Update the degrees of adjacent vertices */ + for (j=xadj[i]; jdegrees; + + if (me == from) { + INC_DEC(myrinfo->ed, myrinfo->id, adjwgt[j]); + } + else { + if (me == to) { + INC_DEC(myrinfo->id, myrinfo->ed, adjwgt[j]); + } + } + + /* Remove contribution of the ed from 'from' */ + if (me != from) { + for (k=0; kndegrees; k++) { + if (mydegrees[k].edge == from) { + if (mydegrees[k].ewgt == adjwgt[j]) { + myrinfo->ndegrees--; + mydegrees[k].edge = mydegrees[myrinfo->ndegrees].edge; + mydegrees[k].ewgt = mydegrees[myrinfo->ndegrees].ewgt; + } + else + mydegrees[k].ewgt -= adjwgt[j]; + break; + } + } + } + + /* Add contribution of the ed to 'to' */ + if (me != to) { + for (k=0; kndegrees; k++) { + if (mydegrees[k].edge == to) { + mydegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + mydegrees[myrinfo->ndegrees].edge = to; + mydegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + + } + nmoves++; + } + } + + if (graph->mincut == oldcut) + break; + } + + GKfree((void **)&minwgt, (void **)&maxwgt, (void **)&cand, LTERM); + + return; +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Moc_ComputeSerialPartitionParams(GraphType *graph, int nparts, + EdgeType *degrees) +{ + int i, j, k; + int nvtxs, nedges, ncon, mincut, me, other; + idxtype *xadj, *adjncy, *adjwgt, *where; + RInfoType *rinfo, *myrinfo; + EdgeType *mydegrees; + float *nvwgt, *npwgts; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + rinfo = graph->rinfo; + + npwgts = sset(ncon*nparts, 0.0, graph->gnpwgts); + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nedges = mincut = 0; + for (i=0; iid = myrinfo->ed = myrinfo->ndegrees = 0; + myrinfo->degrees = degrees + nedges; + nedges += xadj[i+1]-xadj[i]; + + for (j=xadj[i]; jid += adjwgt[j]; + } + else { + myrinfo->ed += adjwgt[j]; + } + } + + mincut += myrinfo->ed; + + /* Time to compute the particular external degrees */ + if (myrinfo->ed > 0) { + mydegrees = myrinfo->degrees; + + for (j=xadj[i]; jndegrees; k++) { + if (mydegrees[k].edge == other) { + mydegrees[k].ewgt += adjwgt[j]; + break; + } + } + if (k == myrinfo->ndegrees) { + mydegrees[myrinfo->ndegrees].edge = other; + mydegrees[myrinfo->ndegrees++].ewgt = adjwgt[j]; + } + } + } + } + } + + graph->mincut = mincut/2; + + return; +} + + +/************************************************************************* +* This function checks if the vertex weights of two vertices are below +* a given set of values +**************************************************************************/ +int AreAllHVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit) +{ + int i; + + for (i=0; i limit[i]) + return 0; + + return 1; +} + + +/************************************************************************* +* This function computes the load imbalance over all the constrains +* For now assume that we just want balanced partitionings +**************************************************************************/ +void ComputeHKWayLoadImbalance(int ncon, int nparts, float *npwgts, float *lbvec) +{ + int i, j; + float max; + + for (i=0; i max) + max = npwgts[j*ncon+i]; + } + + lbvec[i] = max*nparts; + } +} + + +/************************************************************** +* This subroutine remaps a partitioning on a single processor +**************************************************************/ +void SerialRemap(GraphType *graph, int nparts, idxtype *base, idxtype *scratch, + idxtype *remap, float *tpwgts) +{ + int i, ii, j, k; + int nvtxs, nmapped, max_mult; + int from, to, current_from, smallcount, bigcount; + KeyValueType *flowto, *bestflow; + KeyKeyValueType *sortvtx; + idxtype *vsize, *htable, *map, *rowmap; + + nvtxs = graph->nvtxs; + vsize = graph->vsize; + max_mult = amin(MAX_NPARTS_MULTIPLIER, nparts); + + sortvtx = (KeyKeyValueType *)GKmalloc(nvtxs*sizeof(KeyKeyValueType), "sortvtx"); + flowto = (KeyValueType *)GKmalloc((nparts*max_mult+nparts)*sizeof(KeyValueType), "flowto"); + bestflow = flowto+nparts; + map = htable = idxsmalloc(nparts*2, -1, "htable"); + rowmap = map+nparts; + + for (i=0; i current_from) { + /* reset the hash table */ + for (j=0; jncon, j, k)) { + map[j] = k; + rowmap[k] = j; + nmapped++; + } + + if (nmapped == nparts) + break; + } + + + /* remap the rest */ + /* it may help try remapping to the same label first */ + if (nmapped < nparts) { + for (j=0; jncon, 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; ikey1 > second->key1) + return 1; + + if (first->key1 < second->key1) + return -1; + + if (first->key2 < second->key2) + return 1; + + if (first->key2 > second->key2) + return -1; + + return 0; +} + + +/************************************************************************* +* This function performs an edge-based FM refinement +**************************************************************************/ +void Moc_Serial_FM_2WayRefine(GraphType *graph, float *tpwgts, int npasses) +{ + int i, ii, j, k; + int kwgt, nvtxs, ncon, nbnd, nswaps, from, to, pass, limit, tmp, cnum; + idxtype *xadj, *adjncy, *adjwgt, *where, *id, *ed, *bndptr, *bndind; + idxtype *moved, *swaps, *qnum; + float *nvwgt, *npwgts, mindiff[MAXNCON], origbal, minbal, newbal; + FPQueueType parts[MAXNCON][2]; + int higain, oldgain, mincut, initcut, newcut, mincutorder; + float rtpwgts[MAXNCON*2]; + KeyValueType *cand; +int mype; +MPI_Comm_rank(MPI_COMM_WORLD, &mype); + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->sendind; + ed = graph->recvind; + npwgts = graph->gnpwgts; + bndptr = graph->sendptr; + bndind = graph->recvptr; + + moved = idxmalloc(nvtxs, "moved"); + swaps = idxmalloc(nvtxs, "swaps"); + qnum = idxmalloc(nvtxs, "qnum"); + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "cand"); + + limit = amin(amax(0.01*nvtxs, 25), 150); + + /* Initialize the queues */ + for (i=0; imincut; + for (i=0; ignvtxs; + + for (i=0; i limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy2(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy2(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0) { /* It will now become a boundary vertex */ + BNDInsert(nbnd, bndind, bndptr, k); + if (moved[k] == -1) + FPQueueInsert(&parts[qnum[k]][where[k]], k, (float)(ed[k]-id[k])); + } + } + } + } + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (i=0; imincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy2(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy2(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + graph->mincut = mincut; + graph->gnvtxs = nbnd; + + if (mincutorder == -1 || mincut == initcut) + break; + } + + for (i=0; i= maxdiff) { + maxdiff = npwgts[part*ncon+i]-tpwgts[part*ncon+i]; + *from = part; + *cnum = i; + } + } + } + + if (*from != -1 && FPQueueGetQSize(&queues[*cnum][*from]) == 0) { + /* The desired queue is empty, select a node from that side anyway */ + for (i=0; i 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + break; + } + } + + for (i++; i max && FPQueueGetQSize(&queues[i][*from]) > 0) { + max = npwgts[(*from)*ncon + i]; + *cnum = i; + } + } + } + + + /* Check to see if you can focus on the cut */ + if (maxdiff <= 0.0 || *from == -1) { + maxgain = -100000.0; + + for (part=0; part<2; part++) { + for (i=0; i 0 && + FPQueueSeeMaxGain(&queues[i][part]) > maxgain) { + maxgain = FPQueueSeeMaxGain(&queues[i][part]); + *from = part; + *cnum = i; + } + } + } + } + + return; +} + +/************************************************************************* +* This function checks if the balance achieved is better than the diff +* For now, it uses a 2-norm measure +**************************************************************************/ +int Serial_BetterBalance(int ncon, float *npwgts, float *tpwgts, float *diff) +{ + int i; + float ndiff[MAXNCON]; + + for (i=0; invtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->sendind; + ed = graph->recvind; + npwgts = graph->gnpwgts; + bndptr = graph->sendptr; + bndind = graph->recvptr; + + moved = idxmalloc(nvtxs, "moved"); + swaps = idxmalloc(nvtxs, "swaps"); + qnum = idxmalloc(nvtxs, "qnum"); + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "cand"); + + + limit = amin(amax(0.01*nvtxs, 15), 100); + + /* Initialize the queues */ + for (i=0; i qsizes[j][from] && + nvwgt[i*ncon+qnum[i]] < 1.3*nvwgt[i*ncon+j]) { + qsizes[qnum[i]][from]--; + qsizes[j][from]++; + qnum[i] = j; + } + } + } + } + } + + + for (i=0; imincut; + mincutorder = -1; + + idxset(nvtxs, -1, moved); + + /* Insert all nodes in the priority queues */ + nbnd = graph->gnvtxs; + for (i=0; i limit) { /* We hit the limit, undo last move */ + newcut += (ed[higain]-id[higain]); + saxpy2(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+from*ncon, 1); + saxpy2(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + break; + } + + where[higain] = to; + moved[higain] = nswaps; + swaps[nswaps] = higain; + + /************************************************************** + * Update the id[i]/ed[i] values of the affected nodes + ***************************************************************/ + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + + /**************************************************************** + * Roll back computations + *****************************************************************/ + for (nswaps--; nswaps>mincutorder; nswaps--) { + higain = swaps[nswaps]; + + to = where[higain] = (where[higain]+1)%2; + SWAP(id[higain], ed[higain], tmp); + if (ed[higain] == 0 && bndptr[higain] != -1 && xadj[higain] < xadj[higain+1]) + BNDDelete(nbnd, bndind, bndptr, higain); + else if (ed[higain] > 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + saxpy2(ncon, 1.0, nvwgt+higain*ncon, 1, npwgts+to*ncon, 1); + saxpy2(ncon, -1.0, nvwgt+higain*ncon, 1, npwgts+((to+1)%2)*ncon, 1); + for (j=xadj[higain]; j 0) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + graph->mincut = mincut; + graph->gnvtxs = nbnd; + + + for (i=0; invtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + nvwgt = graph->nvwgt; + adjwgt = graph->adjwgt; + where = graph->where; + id = graph->sendind; + ed = graph->recvind; + npwgts = graph->gnpwgts; + bndptr = graph->sendptr; + bndind = graph->recvptr; + + qnum = idxmalloc(nvtxs, "qnum"); + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "cand"); + + /* This is called for initial partitioning so we know from where to pick nodes */ + from = 1; + to = (from+1)%2; + + for (i=0; i 0) + FPQueueInsert(&parts[qnum[i]][0], i, (float)(ed[i]-id[i])); + else + FPQueueInsert(&parts[qnum[i]][1], i, (float)(ed[i]-id[i])); + } + } + + mincut = graph->mincut; + nbnd = graph->gnvtxs; + for (nswaps=0; nswaps 0 && bndptr[higain] == -1) + BNDInsert(nbnd, bndind, bndptr, higain); + + for (j=xadj[higain]; j 0 && bndptr[k] == -1) { /* It moves in boundary */ + FPQueueDelete(&parts[qnum[k]][1], k); + FPQueueInsert(&parts[qnum[k]][0], k, (float)(ed[k]-id[k])); + } + else { /* It must be in the boundary already */ + FPQueueUpdate(&parts[qnum[k]][0], k, (float)(oldgain), (float)(ed[k]-id[k])); + } + } + + /* Update its boundary information */ + if (ed[k] == 0 && bndptr[k] != -1) + BNDDelete(nbnd, bndind, bndptr, k); + else if (ed[k] > 0 && bndptr[k] == -1) + BNDInsert(nbnd, bndind, bndptr, k); + } + } + + graph->mincut = mincut; + graph->gnvtxs = nbnd; + + for (i=0; i= max && + FPQueueGetQSize(&queues[i][0]) + FPQueueGetQSize(&queues[i][1]) > 0) { + max = npwgts[from*ncon+i]-tpwgts[i]; + cnum = i; + } + } + + return cnum; +} + + +/************************************************************************* +* This function computes the initial id/ed +**************************************************************************/ +void Moc_Serial_Compute2WayPartitionParams(GraphType *graph) +{ + int i, j, me, nvtxs, ncon, nbnd, mincut; + idxtype *xadj, *adjncy, *adjwgt; + float *nvwgt, *npwgts; + idxtype *id, *ed, *where; + idxtype *bndptr, *bndind; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + + npwgts = sset(2*ncon, 0.0, graph->gnpwgts); + id = idxset(nvtxs, 0, graph->sendind); + ed = idxset(nvtxs, 0, graph->recvind); + bndptr = idxset(nvtxs, -1, graph->sendptr); + bndind = graph->recvptr; + + /*------------------------------------------------------------ + / Compute now the id/ed degrees + /------------------------------------------------------------*/ + nbnd = mincut = 0; + for (i=0; i 0 || xadj[i] == xadj[i+1]) { + mincut += ed[i]; + bndptr[i] = nbnd; + bndind[nbnd++] = i; + } + } + + graph->mincut = mincut/2; + graph->gnvtxs = nbnd; + +} + +/************************************************************************* +* This function checks if the vertex weights of two vertices are below +* a given set of values +**************************************************************************/ +int Serial_AreAnyVwgtsBelow(int ncon, float alpha, float *vwgt1, float beta, float *vwgt2, float *limit) +{ + int i; + + for (i=0; invtxs; i++) { + for (j=graph->xadj[i]; jxadj[i+1]; j++) + if (graph->where[i] != graph->where[graph->adjncy[j]]) + cut += graph->adjwgt[j]; + } + graph->mincut = cut/2; + + return graph->mincut; +} + +/************************************************************************* +* This function computes the TotalV of a serial graph. +**************************************************************************/ +int ComputeSerialTotalV(GraphType *graph, idxtype *home) +{ + int i; + int totalv = 0; + + for (i=0; invtxs; i++) + if (graph->where[i] != home[i]) + totalv += (graph->vsize == NULL) ? graph->vwgt[i] : graph->vsize[i]; + + return totalv; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/setup.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/setup.c new file mode 100644 index 0000000..682a31d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/setup.c @@ -0,0 +1,219 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * setup.c + * + * This file contains functions that setup the various communication + * data structures for parallel KWAY + * + * Started 2/21/96 + * George + * + * $Id: setup.c,v 1.3 2003/07/31 16:23:30 karypis Exp $ + * + */ + + +#include + +#define DEBUG_SETUPINFO_ + + +/************************************************************************* +* This function tests the repeated shmem_put +**************************************************************************/ +void SetUp(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, j, k, islocal, penum, gnvtxs, nvtxs, nlocal, firstvtx, lastvtx, nsend, nrecv, nnbrs, nadj; + int npes=ctrl->npes, mype=ctrl->mype; + idxtype *vtxdist, *xadj, *adjncy; + idxtype *peind, *recvptr, *recvind, *sendptr, *sendind; + idxtype *receive, *pemap, *imap, *lperm; + idxtype *pexadj, *peadjncy, *peadjloc, *startsind; + KeyValueType *recvrequests, *sendrequests, *adjpairs; + + IFSET(ctrl->dbglvl, DBG_TIME, MPI_Barrier(ctrl->comm)); + IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->SetupTmr)); + + gnvtxs = graph->gnvtxs; + nvtxs = graph->nvtxs; + vtxdist = graph->vtxdist; + xadj = graph->xadj; + adjncy = graph->adjncy; + + firstvtx = vtxdist[mype]; + lastvtx = vtxdist[mype+1]; + + pemap = wspace->pv1; + idxset(npes, -1, pemap); + + lperm = graph->lperm = idxmalloc(nvtxs, "SetUp: graph->lperm"); + for (i=0; iindices; /* Use the large global received array for now */ + adjpairs = wspace->pairs; + + for (nlocal = nadj = i = 0; i= firstvtx && k < lastvtx) { + adjncy[j] = k-firstvtx; + continue; /* local vertex */ + } + adjpairs[nadj].key = k; + adjpairs[nadj++].val = j; + islocal = 0; + } + if (islocal) { + lperm[i] = lperm[nlocal]; + lperm[nlocal++] = i; + } + } + + /* Take care the received part now */ + ikeysort(nadj, adjpairs); + adjpairs[nadj].key = gnvtxs+1; /* Boundary condition */ + for (nrecv=i=0; ipeind = idxmalloc(npes, "SetUp: peind"); + recvptr = graph->recvptr = idxmalloc(npes+1, "SetUp: recvptr"); + recvind = graph->recvind = idxmalloc(nrecv, "SetUp: recvind"); + + /* Take care of the received portion */ + idxcopy(nrecv, receive, recvind); /* Copy the vertices to be received into recvind */ + + i = nnbrs = recvptr[0] = 0; + for (penum=0; penum= vtxdist[penum+1]) + break; + } + if (j > i) { + peind[nnbrs] = penum; + recvptr[++nnbrs] = j; + i = j; + } + } + + + /************************************************************* + * Determine what you need to send + *************************************************************/ + /* Tell the other processors what they need to send you */ + recvrequests = wspace->pepairs1; + sendrequests = wspace->pepairs2; + for (i=0; icomm); + + + sendptr = graph->sendptr = idxmalloc(npes+1, "SetUp: sendptr"); + startsind = wspace->pv2; + for (j=i=0; i 0) { + sendptr[j] = sendrequests[i].key; + startsind[j] = sendrequests[i].val; + j++; + } + } + ASSERT(ctrl, nnbrs == j); + MAKECSR(i, j, sendptr); + + nsend = sendptr[nnbrs]; + sendind = graph->sendind = idxmalloc(nsend, "SetUp: sendind"); + + + /* Issue the receives for sendind */ + for (i=0; icomm, ctrl->rreq+i); + } + + /* Issue the sends. My recvind[penum] becomes penum's sendind[mype] */ + for (i=0; icomm, ctrl->sreq+i); + } + + MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); + MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); + + + + /* Create the peadjncy data structure for sparse boundary exchanges */ + pexadj = graph->pexadj = idxsmalloc(nvtxs+1, 0, "SetUp: pexadj"); + peadjncy = graph->peadjncy = idxmalloc(nsend, "SetUp: peadjncy"); + peadjloc = graph->peadjloc = idxmalloc(nsend, "SetUp: peadjloc"); + + for (i=0; i= firstvtx && sendind[i] < lastvtx, (ctrl, "%d %d %d\n", sendind[i], firstvtx, lastvtx)); + pexadj[sendind[i]-firstvtx]++; + } + MAKECSR(i, nvtxs, pexadj); + + for (i=0; i0; i--) + pexadj[i] = pexadj[i-1]; + pexadj[0] = 0; + + + graph->nnbrs = nnbrs; + graph->nrecv = nrecv; + graph->nsend = nsend; + graph->nlocal = nlocal; + + + /* Create the inverse map from ladjncy to adjncy */ + imap = graph->imap = idxmalloc(nvtxs+nrecv, "SetUp: imap"); + for (i=0; inlarge is large enough for nrecv and nsend */ + if (wspace->nlarge < nrecv+nsend) { + free(wspace->indices); + free(wspace->pairs); + wspace->nlarge = nrecv+nsend; + wspace->indices = idxmalloc(wspace->nlarge, "SetUp: wspace->indices"); + wspace->pairs = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*wspace->nlarge, "SetUp: wspace->pairs"); + } + + IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->SetupTmr)); + +#ifdef DEBUG_SETUPINFO + rprintf(ctrl, "[%5d %5d] \tl:[%5d %5d] \ts:[%5d, %5d] \tr:[%5d, %5d]\n", + GlobalSEMin(ctrl, nvtxs), GlobalSEMax(ctrl, nvtxs), + GlobalSEMin(ctrl, nlocal), GlobalSEMax(ctrl, nlocal), + GlobalSEMin(ctrl, nsend), GlobalSEMax(ctrl, nsend), + GlobalSEMin(ctrl, nrecv), GlobalSEMax(ctrl, nrecv)); + + PrintSetUpInfo(ctrl, graph); +#endif +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stat.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stat.c new file mode 100644 index 0000000..4a32bc8 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stat.c @@ -0,0 +1,332 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stat.c + * + * This file computes various statistics + * + * Started 7/25/97 + * George + * + * $Id: stat.c,v 1.3 2003/07/23 00:54:56 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function computes the balance of the partitioning +**************************************************************************/ +void Moc_ComputeSerialBalance(CtrlType *ctrl, GraphType *graph, idxtype *where, float *ubvec) +{ + int i, j, nvtxs, ncon, nparts; + idxtype *pwgts, *tvwgts, *vwgt; + float *tpwgts, maximb; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + vwgt = graph->vwgt; + nparts = ctrl->nparts; + tpwgts = ctrl->tpwgts; + + pwgts = idxsmalloc(nparts*ncon, 0, "pwgts"); + tvwgts = idxsmalloc(ncon, 0, "tvwgts"); + + for (i=0; invtxs; i++) { + for (j=0; jncon; + nvtxs = graph->nvtxs; + nvwgt = graph->nvwgt; + nparts = ctrl->nparts; + tpwgts = ctrl->tpwgts; + + lnpwgts = fmalloc(nparts*ncon, "CPB: lnpwgts"); + gnpwgts = fmalloc(nparts*ncon, "CPB: gnpwgts"); + sset(nparts*ncon, 0.0, lnpwgts); + sset(ncon, 1.0, lminvwgts); + + for (i=0; i 0.0 && lminvwgts[j] > nvwgt[i*ncon+j] ? nvwgt[i*ncon+j] : lminvwgts[j]); + } + } + + MPI_Allreduce((void *)(lnpwgts), (void *)(gnpwgts), nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); + MPI_Allreduce((void *)(lminvwgts), (void *)(gminvwgts), ncon, MPI_FLOAT, MPI_MIN, ctrl->comm); + + /* The +gminvwgts[j] in the following code is to deal with bad cases of tpwgts[i*ncon+j] == 0 */ + for (j=0; jnpes; i++) { + if (i == ctrl->mype) { + for (j=0; jnpes; j++) + printf("%.3f ", matrix[j]); + printf("\n"); + fflush(stdout); + } + MPI_Barrier(ctrl->comm); + } + + if (ctrl->mype == 0) { + printf("****************************\n"); + fflush(stdout); + } + MPI_Barrier(ctrl->comm); + + return; +} + + +/************************************************************************* +* This function computes stats for refinement +**************************************************************************/ +void Moc_ComputeRefineStats(CtrlType *ctrl, GraphType *graph, float *ubvec) +{ + int h, i, j, k; + int nvtxs, ncon; + idxtype *xadj, *adjncy, *adjwgt, *where; + float *nvwgt, *lnpwgts, *gnpwgts; + RInfoType *rinfo; + int mype = ctrl->mype, nparts = ctrl->nparts; + idxtype *gborder, *border, *gfrom, *from, *gto, *to, *connect, *gconnect; + idxtype gain[20] = {0}, ggain[20]; + int lnborders, gnborders; + int bestgain, pmoves, gpmoves, other; + float tpwgts[MAXNCON], badmaxpwgt[MAXNCON]; + int HIST_FACTOR = graph->level + 1; + + nvtxs = graph->nvtxs; + ncon = graph->ncon; + xadj = graph->xadj; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + lnpwgts = graph->lnpwgts; + gnpwgts = graph->gnpwgts; + rinfo = graph->rinfo; + + connect = idxsmalloc(nparts*nparts, 0, "CRS: connect"); + gconnect = idxmalloc(nparts*nparts, "CRS: gconnect"); + border = idxsmalloc(nparts, 0, "CRS: border"); + gborder = idxmalloc(nparts, "CRS: gborder"); + from = idxsmalloc(nparts, 0, "CRS: from"); + gfrom = idxmalloc(nparts, "CRS: gfrom"); + to = idxsmalloc(nparts, 0, "CRS: to"); + gto = idxmalloc(nparts, "CRS: gto"); + + for (h=0; hcomm); + if (mype == 0) { + printf("connectivity\n"); + for (i=0; i 0) { + lnborders++; + border[where[i]]++; + } + + MPI_Reduce((void *)border, (void *)gborder, nparts, IDX_DATATYPE, MPI_SUM, 0, ctrl->comm); + gnborders = GlobalSESum(ctrl, lnborders); + if (mype == 0) { + printf("number of borders: %d\n", gnborders); + for (i=0; invwgt+i*ncon; + + for (j=0; j badmaxpwgt[h]) + break; + + if (h == ncon) + break; + } + + if (j < rinfo[i].ndegrees) { + pmoves++; + from[where[i]]++; + to[other]++; + for (k=j+1; k badmaxpwgt[h]) + break; + + if (h == ncon) { + pmoves++; + from[where[i]]++; + to[other]++; + } + } + } + } + + gpmoves = GlobalSESum(ctrl, pmoves); + MPI_Reduce((void *)from, (void *)gfrom, nparts, IDX_DATATYPE, MPI_SUM, 0, ctrl->comm); + MPI_Reduce((void *)to, (void *)gto, nparts, IDX_DATATYPE, MPI_SUM, 0, ctrl->comm); + + if (mype == 0) { + printf("possible moves: %d\n", gpmoves); + printf("from "); + for (i=0; i 0) { + bestgain = rinfo[i].degrees[0].ewgt-rinfo[i].id; + for (j=0; j= 10) { + gain[19]++; + continue; + } + + if (bestgain / HIST_FACTOR < -10) { + gain[0]++; + continue; + } + + gain[(bestgain/HIST_FACTOR)+10]++; + } + } + + MPI_Reduce((void *)gain, (void *)ggain, 20, IDX_DATATYPE, MPI_SUM, 0, ctrl->comm); + if (mype == 0) { + printf("gain histogram (buckets of %d)\n", HIST_FACTOR); + for (i=0; i<20; i++) { + if (i == 10 || i == 11) + printf(" "); + printf("%d ", ggain[i]); + } + printf("\n\n"); + } + + + + + /***************************************/ + if (mype == 0) printf("******************************\n"); + if (mype == 0) printf("******************************\n"); + + GKfree((void **)&gconnect, (void **)&connect, (void **)&gborder, (void **)&border, (void **)&gfrom, (void **)&from, (void **)>o, (void **)&to, LTERM); + return; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stdheaders.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stdheaders.h new file mode 100644 index 0000000..e30f989 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/stdheaders.h @@ -0,0 +1,25 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stdheaders.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: stdheaders.h,v 1.4 2003/07/25 14:31:47 karypis Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/struct.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/struct.h new file mode 100644 index 0000000..3016c5e --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/struct.h @@ -0,0 +1,290 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * struct.h + * + * This file contains data structures for ILU routines. + * + * Started 9/26/95 + * George + * + * $Id: struct.h,v 1.2 2003/07/21 17:50:22 karypis Exp $ + */ + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +#define IDX_DATATYPE MPI_INT +#define MAX_INT INT_MAX +#define MIN_INT INT_MIN +#else +#define IDX_DATATYPE MPI_SHORT +#define MAX_INT SHRT_MAX +#define MIN_INT SHRT_MIN +#endif + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KeyValueType { + idxtype key; + idxtype val; +}; + +typedef struct KeyValueType KeyValueType; + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KVType { + int key; + float val; +}; + +typedef struct KVType KVType; + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct FKeyValueType { + float key; + idxtype val; +}; + +typedef struct FKeyValueType FKeyValueType; + +/************************************************************************* +* The following data structure stores key-key-value triplets +**************************************************************************/ +struct KeyKeyValueType { + idxtype key1, key2; + idxtype val; +}; + +typedef struct KeyKeyValueType KeyKeyValueType; + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct PQueueType { + int nnodes; + int maxnnodes; + idxtype *perm, *iperm, *values; + /* iperm[i] stores where the ith entry is located + perm[i] stores the entry that is located in the ith position */ +}; + +typedef struct PQueueType PQueueType; + + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct FPQueueType { + int type; /* The type of the representation used */ + int nnodes; + int maxnodes; + + /* Heap version of the data structure */ + FKeyValueType *heap; + idxtype *locator; +}; + +typedef struct FPQueueType FPQueueType; + +/************************************************************************* +* The following data structure stores an edge +**************************************************************************/ +struct edgedef { + idxtype edge; + idxtype ewgt; +}; +typedef struct edgedef EdgeType; + + +/************************************************************************* +* This data structure holds various working space data +**************************************************************************/ +struct workspacedef { + idxtype *core; /* Where pairs, indices, and degrees are coming from */ + int maxcore; + + int nlarge; /* The size of 'Large' */ + + KeyValueType *pairs; /* Large pair array used during setup */ + idxtype *indices; /* Large array of indxtype used for various purposes */ + + /* Auxiliary parameters */ + idxtype *pv1, *pv2, *pv3, *pv4; /* Vectors of npes+1 size used in various places */ + KeyValueType *pepairs1, *pepairs2; + + EdgeType *degrees; +}; + +typedef struct workspacedef WorkSpaceType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct rinfodef { + int id, ed; /* ID/ED of edges */ + int ndegrees; /* The number of different ext-degrees */ + EdgeType *degrees; /* List of edges */ +}; + +typedef struct rinfodef RInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct nrinfodef { + int edegrees[2]; +}; + +typedef struct nrinfodef NRInfoType; + + +/************************************************************************* +* The following data structure stores a sparse matrix in CSR format +* The diagonal entry is in the first position of each row. +**************************************************************************/ +struct matrixdef { + int nrows, nnzs; /* Number of rows and nonzeros in the matrix */ + idxtype *rowptr; + idxtype *colind; + float *values; + float *transfer; +}; + +typedef struct matrixdef MatrixType; + + +/************************************************************************* +* This data structure holds the input graph +**************************************************************************/ +struct graphdef { + int gnvtxs, nvtxs, nedges, ncon, nobj; + idxtype *xadj; /* Pointers to the locally stored vertices */ + idxtype *vwgt; /* Vertex weights */ + float *nvwgt; /* Vertex weights */ + idxtype *vsize; /* Vertex size */ + idxtype *adjncy; /* Array that stores the adjacency lists of nvtxs */ + idxtype *adjwgt; /* Array that stores the weights of the adjacency lists */ + idxtype *vtxdist; /* Distribution of vertices */ + + idxtype *match; + idxtype *cmap; + + idxtype *label; + + /* Communication/Setup parameters */ + int nnbrs, nrecv, nsend; /* The number of neighboring processors */ + idxtype *peind; /* Array of size nnbrs storing the neighboring PEs */ + idxtype *sendptr, *sendind; /* CSR format of the vertices that are sent */ + idxtype *recvptr, *recvind; /* CSR format of the vertices that are received */ + idxtype *imap; /* The inverse map of local to global indices */ + idxtype *pexadj, *peadjncy, + *peadjloc; /* CSR format of the PEs each vertex is adjancent to */ + + int nlocal; /* Number of interior vertices */ + idxtype *lperm; /* lperm[0:nlocal] points to interior vertices, the rest are interface */ + + /* Communication parameters for projecting the partition. + * These are computed during CreateCoarseGraph and used during projection + * Note that during projection, the meaning of received and sent is reversed! */ + idxtype *rlens, *slens; /* Arrays of size nnbrs of how many vertices you are sending and receiving */ + KeyValueType *rcand; + + + /* Partition parameters */ + idxtype *where, *home; + idxtype *lpwgts, *gpwgts; + float *lnpwgts, *gnpwgts; + RInfoType *rinfo; + + /* Node refinement information */ + NRInfoType *nrinfo; + int nsep; /* The number of vertices in the separator */ + idxtype *sepind; /* The indices of the vertices in the separator */ + + int lmincut, mincut; + + int level; + int match_type; + int edgewgt_type; + + struct graphdef *coarser, *finer; +}; + +typedef struct graphdef GraphType; + + +/************************************************************************* +* The following data type implements a timer +**************************************************************************/ +typedef double timer; + + +/************************************************************************* +* The following structure stores information used by parallel kmetis +**************************************************************************/ +struct controldef { + int mype, npes; /* Info about the parallel system */ + int CoarsenTo; /* The # of vertices in the coarsest graph */ + int dbglvl; /* Controls the debuging output of the program */ + int nparts; /* The number of partitions */ + int foldf; /* What is the folding factor */ + int ipart; /* The type of initial partitioning */ + int xyztype; /* The type of coordinate indexing */ + int seed; /* Random number seed */ + int sync; /* Random number seed */ + float *tpwgts; /* Target subdomain weights */ + int tvwgts[MAXNCON]; + float ubvec[MAXNCON]; + int partType; + int ps_relation; + + float redist_factor, redist_base, ipc_factor; + float edge_size_ratio; + MatrixType *matrix; + + MPI_Comm gcomm; + MPI_Comm comm; /* MPI Communicator */ + MPI_Request sreq[MAX_PES], + rreq[MAX_PES]; /* MPI send and receive requests */ + MPI_Status statuses[MAX_PES]; + MPI_Status status; + + /* Various Timers */ + timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, RefTmr, + SetupTmr, ColorTmr, ProjectTmr, KWayInitTmr, KWayTmr, MoveTmr, + RemapTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6; +}; + +typedef struct controldef CtrlType; + + + +/************************************************************************* +* The following data structure stores a mesh. +**************************************************************************/ +struct meshdef { + int etype; + int gnelms, gnns; + int nelms, nns; + int ncon; + int esize, gminnode; + idxtype *elmdist; + idxtype *elements; + idxtype *elmwgt; +}; + +typedef struct meshdef MeshType; + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/sync b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/sync new file mode 100644 index 0000000..11a0cfb --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/sync @@ -0,0 +1,186 @@ +adrivers.c: ubavg = savg(graph->ncon, ctrl->ubvec); +adrivers.c: ctrl->redist_factor = ctrl->redist_base * ((gtewgt/gtvsize)/ ctrl->edge_size_ratio); +adrivers.c: IFSET(ctrl->dbglvl, DBG_PROGRESS, rprintf(ctrl, "[%6d %8d %5d %5d][%d]\n", +adrivers.c: graph->gnvtxs, GlobalSESum(ctrl, graph->nedges), GlobalSEMin(ctrl, graph->nvtxs), GlobalSEMax(ctrl, graph->nvtxs), ctrl->CoarsenTo)); +adrivers.c: if (graph->gnvtxs < 1.3*ctrl->CoarsenTo || +adrivers.c: if (lbavg > ubavg + 0.035 && ctrl->partType != REFINE_PARTITION) +adrivers.c: if (ctrl->dbglvl&DBG_PROGRESS) { +adrivers.c: switch (ctrl->ps_relation) { +adrivers.c: if (ctrl->dbglvl&DBG_PROGRESS) { +akwayfm.c: int npes = ctrl->npes, mype = ctrl->mype, nparts = ctrl->nparts; +akwayfm.c: IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->KWayTmr)); +akwayfm.c: ubvec = ctrl->ubvec; +akwayfm.c: tpwgts = ctrl->tpwgts; +akwayfm.c: ipc_factor = ctrl->ipc_factor; +akwayfm.c: redist_factor = ctrl->redist_factor; +akwayfm.c: MPI_Bcast((void *)pperm, nparts, IDX_DATATYPE, 0, ctrl->comm); +akwayfm.c: switch (ctrl->ps_relation) { +akwayfm.c: switch (ctrl->ps_relation) { +akwayfm.c: MPI_Allreduce((void *)lnpwgts, (void *)pgnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); +akwayfm.c: IFSET(ctrl->dbglvl, DBG_RMOVEINFO, rprintf(ctrl, "\t[%d %d], [%.4f], [%d %d %d]\n", +akwayfm.c: MPI_Irecv((void *)(rupdate+sendptr[i]), sendptr[i+1]-sendptr[i], IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); +akwayfm.c: MPI_Isend((void *)(supdate+j), k-j, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +akwayfm.c: MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); +akwayfm.c: MPI_Get_count(ctrl->statuses+i, IDX_DATATYPE, nupds_pe+i); +akwayfm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +akwayfm.c: MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); +akwayfm.c: IFSET(ctrl->dbglvl, DBG_TIME, stoptimer(ctrl->KWayTmr)); +balancemylink.c: ipc_factor = ctrl->ipc_factor; +balancemylink.c: redist_factor = ctrl->redist_factor; +coarsen.c: int npes=ctrl->npes, mype=ctrl->mype; +coarsen.c: MPI_Allgather((void *)(cvtxdist+npes), 1, IDX_DATATYPE, (void *)cvtxdist, 1, IDX_DATATYPE, ctrl->comm); +coarsen.c: MPI_Irecv((void *)(rsizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->rreq+i); +coarsen.c: MPI_Isend((void *)(ssizes+i), 1, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +coarsen.c: MPI_Wait(ctrl->rreq+i, &ctrl->status); +coarsen.c: MPI_Wait(ctrl->sreq+i, &ctrl->status); +coarsen.c: 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); +coarsen.c: sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : vsize[ii]; +coarsen.c: sgraph[ll++] = (ctrl->partType == STATIC_PARTITION) ? -1 : home[ii]; +coarsen.c: MPI_Isend((void *)(sgraph+l), ll-l, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +coarsen.c: MPI_Wait(ctrl->rreq+i, &ctrl->status); +coarsen.c: MPI_Wait(ctrl->sreq+i, &ctrl->status); +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: if (ctrl->partType == ADAPTIVE_PARTITION || ctrl->partType == REFINE_PARTITION) { +coarsen.c: cgraph->nvwgt[j*ncon+h] = (float)(cvwgt[j*ncon+h])/(float)(ctrl->tvwgts[h]); +comm.c: firstvtx = graph->vtxdist[ctrl->mype]; +comm.c: peind[i], 1, ctrl->comm, ctrl->rreq+i); +comm.c: peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Waitall(nnbrs, ctrl->rreq, ctrl->statuses); +comm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +comm.c: firstvtx = graph->vtxdist[ctrl->mype]; +comm.c: peind[i], 1, ctrl->comm, ctrl->rreq+i); +comm.c: idxcopy(ctrl->npes, sendptr, psendptr); +comm.c: peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Isend((void *)(sendpairs), 0, IDX_DATATYPE, peind[i], 1, ctrl->comm, ctrl->sreq+i); +comm.c: MPI_Wait(ctrl->rreq+i, &(ctrl->status)); +comm.c: MPI_Get_count(&ctrl->status, IDX_DATATYPE, &n); +comm.c: MPI_Waitall(nnbrs, ctrl->sreq, ctrl->statuses); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_INT, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_DOUBLE, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_INT, MPI_MIN, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_INT, MPI_SUM, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&max, 1, MPI_FLOAT, MPI_MAX, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&min, 1, MPI_FLOAT, MPI_MIN, ctrl->comm); +comm.c: MPI_Allreduce((void *)&value, (void *)&sum, 1, MPI_FLOAT, MPI_SUM, ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: if (ctrl->mype == 0) +debug.c: printf("\t%3d. ", ctrl->mype); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: firstvtx = graph->vtxdist[ctrl->mype]; +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: firstvtx = graph->vtxdist[ctrl->mype]; +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: printf("PE: %d, nnbrs: %d\n", ctrl->mype, graph->nnbrs); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: MPI_Barrier(ctrl->comm); +debug.c: for (penum=0; penumnpes; penum++) { +debug.c: if (ctrl->mype == penum) { +debug.c: printf("PE: %d, nnbrs: %d", ctrl->mype, nnbrs); +debug.c: MPI_Barrier(ctrl->comm); +diffutil.c: nparts = ctrl->nparts; +diffutil.c: myhome = (ctrl->ps_relation == COUPLED) ? ctrl->mype : graph->home[i]; +diffutil.c: /* PrintVector(ctrl, ctrl->npes, 0, lend, "Lend: "); */ +diffutil.c: MPI_Allreduce((void *)lstart, (void *)gstart, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +diffutil.c: MPI_Allreduce((void *)lleft, (void *)gleft, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +diffutil.c: MPI_Allreduce((void *)lend, (void *)gend, nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +grsetup.c: graph->gnvtxs = vtxdist[ctrl->npes]; +grsetup.c: graph->nvtxs = vtxdist[ctrl->mype+1]-vtxdist[ctrl->mype]; +grsetup.c: ctrl->tvwgts[j] = GlobalSESum(ctrl, ltvwgts[j]); +grsetup.c: if (ctrl->tvwgts[i] == 0) { +grsetup.c: graph->nvwgt[i*ncon+j] = (float)(graph->vwgt[i*ncon+j]) / (float)(ctrl->tvwgts[j]); +grsetup.c: srand(ctrl->seed); +grsetup.c: MPI_Comm_dup(comm, &(ctrl->gcomm)); +grsetup.c: MPI_Comm_rank(ctrl->gcomm, &ctrl->mype); +grsetup.c: MPI_Comm_size(ctrl->gcomm, &ctrl->npes); +grsetup.c: ctrl->dbglvl = dbglvl; +grsetup.c: ctrl->nparts = nparts; /* Set the # of partitions is de-coupled from the # of domains */ +grsetup.c: ctrl->comm = ctrl->gcomm; +grsetup.c: ctrl->xyztype = XYZ_SPFILL; +grsetup.c: srand(ctrl->mype); +grsetup.c: lpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: lpvtxs"); +grsetup.c: gpvtxs = idxsmalloc(ctrl->nparts, 0, "ComputeMoveStatistics: gpvtxs"); +grsetup.c: if (where[i] != ctrl->mype) +grsetup.c: /* PrintVector(ctrl, ctrl->npes, 0, lpvtxs, "Lpvtxs: "); */ +grsetup.c: MPI_Allreduce((void *)lpvtxs, (void *)gpvtxs, ctrl->nparts, IDX_DATATYPE, MPI_SUM, ctrl->comm); +grsetup.c: *maxin = GlobalSEMax(ctrl, gpvtxs[ctrl->mype]-(nvtxs-j)); +initbalance.c: IFSET(ctrl->dbglvl, DBG_TIME, starttimer(ctrl->InitPartTmr)); +initbalance.c: mytpwgts = fsmalloc(ctrl->nparts, 0.0, "mytpwgts"); +initbalance.c: for (i=0; inparts; i++) +initbalance.c: mytpwgts[i] += ctrl->tpwgts[i*ncon+j]; +initbalance.c: for (i=0; inparts; i++) +initbalance.c: if (ctrl->ps_relation == DISCOUPLED) { +initbalance.c: rcounts = imalloc(ctrl->npes, "rcounts"); +initbalance.c: rdispls = imalloc(ctrl->npes+1, "rdispls"); +initbalance.c: for (i=0; inpes; i++) { +initbalance.c: MAKECSR(i, ctrl->npes, rdispls); +initbalance.c: (void *)part, rcounts, rdispls, IDX_DATATYPE, ctrl->comm); +initbalance.c: for (i=0; inpes; i++) +initbalance.c: if (part[i] >= ctrl->nparts) +initbalance.c: part[i] = home[i] = part[i] % ctrl->nparts; +initbalance.c: part[i] = home[i] = (-1*part[i]) % ctrl->nparts; +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, Moc_ComputeSerialBalance(ctrl, agraph, agraph->where, lbvec)); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "input cut: %d, balance: ", ComputeSerialEdgeCut(agraph))); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "%.3f ", lbvec[i])); +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, rprintf(ctrl, "\n")); +initbalance.c: sr = (ctrl->mype % 2 == 0) ? 1 : 0; +initbalance.c: gd = (ctrl->mype % 2 == 1) ? 1 : 0; +initbalance.c: if (graph->ncon > MAX_NCON_FOR_DIFFUSION || ctrl->npes == 1) { +initbalance.c: MPI_Comm_split(ctrl->gcomm, sr, 0, &ipcomm); +initbalance.c: myctrl.sync = ctrl->sync; +initbalance.c: myctrl.seed = ctrl->seed; +initbalance.c: myctrl.nparts = ctrl->nparts; +initbalance.c: myctrl.ipc_factor = ctrl->ipc_factor; +initbalance.c: myctrl.redist_factor = ctrl->redist_base; +initbalance.c: myctrl.tpwgts = ctrl->tpwgts; +initbalance.c: icopy(ncon, ctrl->tvwgts, myctrl.tvwgts); +initbalance.c: icopy(ncon, ctrl->ubvec, myctrl.ubvec); +initbalance.c: moptions[7] = ctrl->sync + (mype % ngroups) + 1; +initbalance.c: lnparts = ctrl->nparts; +initbalance.c: lpecost.rank = ctrl->mype; +initbalance.c: if (ctrl->mype == gpecost.rank && ctrl->mype != sr_pe) { +initbalance.c: MPI_Send((void *)part, nvtxs, IDX_DATATYPE, sr_pe, 1, ctrl->comm); +initbalance.c: if (ctrl->mype != gpecost.rank && ctrl->mype == sr_pe) { +initbalance.c: MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == sr_pe) { +initbalance.c: SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); +initbalance.c: lpecost.rank = ctrl->mype; +initbalance.c: if (ctrl->mype == gpecost.rank && ctrl->mype != gd_pe) +initbalance.c: MPI_Send((void *)part, nvtxs, IDX_DATATYPE, gd_pe, 1, ctrl->comm); +initbalance.c: if (ctrl->mype != gpecost.rank && ctrl->mype == gd_pe) +initbalance.c: MPI_Recv((void *)part, nvtxs, IDX_DATATYPE, gpecost.rank, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == gd_pe) { +initbalance.c: SerialRemap(&cgraph, ctrl->nparts, home, lwhere, part, ctrl->tpwgts); +initbalance.c: if (ctrl->mype == sr_pe || ctrl->mype == gd_pe) { +initbalance.c: my_cost = ctrl->ipc_factor * my_cut + REDIST_WGT * ctrl->redist_base * my_totalv; +initbalance.c: IFSET(ctrl->dbglvl, DBG_REFINEINFO, printf("%s initial cut: %.1f, totalv: %.1f, balance: %.3f\n", +initbalance.c: (ctrl->mype == sr_pe ? "scratch-remap" : "diffusion"), my_cut, my_totalv, my_balance)); +initbalance.c: if (ctrl->mype == gd_pe) { +initbalance.c: MPI_Send((void *)buffer, 2, MPI_FLOAT, sr_pe, 1, ctrl->comm); +initbalance.c: MPI_Recv((void *)buffer, 2, MPI_FLOAT, gd_pe, 1, ctrl->comm, &status); +initbalance.c: if (ctrl->mype == sr_pe) { +initbalance.c: MPI_Bcast((void *)&who_wins, 1, MPI_INT, sr_pe, ctrl->comm); +initbalance.c: MPI_Bcast((void *)part, nvtxs, IDX_DATATYPE, who_wins, ctrl->comm); +initbalance.c: idxcopy(graph->nvtxs, part+vtxdist[ctrl->mype], graph->where); +initbalance.c: IFSET(ctrl->dbglvl, DBG_TIME, stoptim \ No newline at end of file diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/timer.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/timer.c new file mode 100644 index 0000000..73cc11a --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/timer.c @@ -0,0 +1,90 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * timer.c + * + * This file contain various timing routines + * + * Started 10/19/96 + * George + * + * $Id: timer.c,v 1.2 2003/07/21 17:18:54 karypis Exp $ + * + */ + +#include + + + + +/************************************************************************* +* This function initializes the various timers +**************************************************************************/ +void InitTimers(CtrlType *ctrl) +{ + cleartimer(ctrl->TotalTmr); + cleartimer(ctrl->InitPartTmr); + cleartimer(ctrl->MatchTmr); + cleartimer(ctrl->ContractTmr); + cleartimer(ctrl->CoarsenTmr); + cleartimer(ctrl->RefTmr); + cleartimer(ctrl->SetupTmr); + cleartimer(ctrl->ProjectTmr); + cleartimer(ctrl->KWayInitTmr); + cleartimer(ctrl->KWayTmr); + cleartimer(ctrl->MoveTmr); + cleartimer(ctrl->RemapTmr); + + cleartimer(ctrl->AuxTmr1); + cleartimer(ctrl->AuxTmr2); + cleartimer(ctrl->AuxTmr3); + cleartimer(ctrl->AuxTmr4); + cleartimer(ctrl->AuxTmr5); + cleartimer(ctrl->AuxTmr6); +} + + +/************************************************************************* +* This function prints timing information about KMETIS +**************************************************************************/ +void PrintTimingInfo(CtrlType *ctrl) +{ +/* PrintTimer(ctrl, ctrl->CoarsenTmr, " Coarsening"); */ + PrintTimer(ctrl, ctrl->SetupTmr, " Setup"); + PrintTimer(ctrl, ctrl->MatchTmr, " Matching"); + PrintTimer(ctrl, ctrl->ContractTmr, "Contraction"); + PrintTimer(ctrl, ctrl->InitPartTmr, " InitPart"); +/* PrintTimer(ctrl, ctrl->RefTmr, " Refinement"); */ + PrintTimer(ctrl, ctrl->ProjectTmr, " Project"); + PrintTimer(ctrl, ctrl->KWayInitTmr, " Initialize"); + PrintTimer(ctrl, ctrl->KWayTmr, " K-way"); + PrintTimer(ctrl, ctrl->MoveTmr, " Move"); + PrintTimer(ctrl, ctrl->RemapTmr, " Remap"); + PrintTimer(ctrl, ctrl->TotalTmr, " Total"); + PrintTimer(ctrl, ctrl->AuxTmr1, " Aux1"); + PrintTimer(ctrl, ctrl->AuxTmr2, " Aux2"); + PrintTimer(ctrl, ctrl->AuxTmr3, " Aux3"); + PrintTimer(ctrl, ctrl->AuxTmr4, " Aux4"); + PrintTimer(ctrl, ctrl->AuxTmr5, " Aux5"); + PrintTimer(ctrl, ctrl->AuxTmr6, " Aux6"); +} + + +/************************************************************************* +* This function prints timer stat +**************************************************************************/ +void PrintTimer(CtrlType *ctrl, timer tmr, char *msg) +{ + double sum, max, tsec; + + tsec = gettimer(tmr); + MPI_Reduce((void *)&tsec, (void *)&sum, 1, MPI_DOUBLE, MPI_SUM, 0, ctrl->comm); + + tsec = gettimer(tmr); + MPI_Reduce((void *)&tsec, (void *)&max, 1, MPI_DOUBLE, MPI_MAX, 0, ctrl->comm); + + if (ctrl->mype == 0 && sum != 0.0) + printf("%s: Max: %7.3f, Sum: %7.3f, Balance: %7.3f\n", + msg, (float)max, (float)sum, (float)(max*ctrl->npes/sum)); +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/util.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/util.c new file mode 100644 index 0000000..34c657d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/util.c @@ -0,0 +1,983 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * util.c + * + * This function contains various utility routines + * + * Started 9/28/95 + * George + * + * $Id: util.c,v 1.2 2003/07/21 17:18:54 karypis Exp $ + */ + +#include + + +/************************************************************************* +* This function prints an error message and exits +**************************************************************************/ +void errexit(char *f_str,...) +{ + va_list argp; + char out1[256], out2[256]; + + va_start(argp, f_str); + vsprintf(out1, f_str, argp); + va_end(argp); + + sprintf(out2, "Error! %s", out1); + + fprintf(stdout, out2); + fflush(stdout); + + abort(); +} + + +/************************************************************************* +* This function prints an error message and exits +**************************************************************************/ +void myprintf(CtrlType *ctrl, char *f_str,...) +{ + va_list argp; + char out1[256], out2[256]; + + va_start(argp, f_str); + vsprintf(out1, f_str, argp); + va_end(argp); + + sprintf(out2, "[%2d] %s", ctrl->mype, out1); + + fprintf(stdout, out2); + fflush(stdout); + +} + + + +/************************************************************************* +* This function prints an error message and exits +**************************************************************************/ +void rprintf(CtrlType *ctrl, char *f_str,...) +{ + va_list argp; + + if (ctrl->mype == 0) { + va_start(argp, f_str); + vfprintf(stdout, f_str, argp); + va_end(argp); + } + + fflush(stdout); + + MPI_Barrier(ctrl->comm); + +} + + +#ifndef DMALLOC +/************************************************************************* +* The following function allocates an array of integers +**************************************************************************/ +int *imalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (int *)GKmalloc(sizeof(int)*n, msg); +} + + +/************************************************************************* +* The following function allocates an array of integers +**************************************************************************/ +idxtype *idxmalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (idxtype *)GKmalloc(sizeof(idxtype)*n, msg); +} + + +/************************************************************************* +* The following function allocates an array of float +**************************************************************************/ +float *fmalloc(int n, char *msg) +{ + if (n == 0) + return NULL; + + return (float *)GKmalloc(sizeof(float)*n, msg); +} + + +/************************************************************************* +* The follwoing function allocates an array of integers +**************************************************************************/ +int *ismalloc(int n, int ival, char *msg) +{ + if (n == 0) + return NULL; + + return iset(n, ival, (int *)GKmalloc(sizeof(int)*n, msg)); +} + + + +/************************************************************************* +* The follwoing function allocates an array of integers +**************************************************************************/ +idxtype *idxsmalloc(int n, idxtype ival, char *msg) +{ + if (n == 0) + return NULL; + + return idxset(n, ival, (idxtype *)GKmalloc(sizeof(idxtype)*n, msg)); +} + + +/************************************************************************* +* This function is my wrapper around malloc +**************************************************************************/ +void *GKmalloc(int nbytes, char *msg) +{ + void *ptr; + + if (nbytes == 0) + return NULL; + + ptr = (void *)malloc(nbytes); + if (ptr == NULL) + errexit("***Memory allocation failed for %s. Requested size: %d bytes", msg, nbytes); + + return ptr; +} +#endif + +/************************************************************************* +* This function is my wrapper around free, allows multiple pointers +**************************************************************************/ +void GKfree(void **ptr1,...) +{ + va_list plist; + void **ptr; + + if (*ptr1 != NULL) + free(*ptr1); + *ptr1 = NULL; + + va_start(plist, ptr1); + + while ((ptr = va_arg(plist, void **)) != LTERM) { + if (*ptr != NULL) + free(*ptr); + *ptr = NULL; + } + + va_end(plist); +} + + +/************************************************************************* +* These functions set the values of a vector +**************************************************************************/ +int *iset(int n, int val, int *x) +{ + int i; + + for (i=0; i x[max] ? i : max); + + return max; +} + + +/************************************************************************* +* These functions return the index of the minimum element in a vector +**************************************************************************/ +int idxamin(int n, idxtype *x) +{ + int i, min=0; + + for (i=1; ikey != n2->key ? n1->key - n2->key : n1->val - n2->val); +} + + + +/************************************************************************* +* This function sorts an array of type KeyValueType in increasing order +**************************************************************************/ +void dkeyvalsort(int n, KeyValueType *nodes) +{ + qsort((void *)nodes, (size_t)n, (size_t)sizeof(KeyValueType), DecKeyValueCmp); +} + + +/************************************************************************* +* This function compares 2 KeyValueType variables for sorting in inc order +**************************************************************************/ +int DecKeyValueCmp(const void *v1, const void *v2) +{ + KeyValueType *n1, *n2; + + n1 = (KeyValueType *)v1; + n2 = (KeyValueType *)v2; + + return n2->key - n1->key; + +} + + + +/************************************************************************* +* This function does a binary search on an array for a key and returns +* the index +**************************************************************************/ +int BSearch(int n, idxtype *array, int key) +{ + int a=0, b=n, c; + + while (b-a > 8) { + c = (a+b)>>1; + if (array[c] > key) + b = c; + else + a = c; + } + + for (c=a; c>1); + return (a > 1 ? 0 : 1); +} + +/************************************************************************* +* This function returns the log2(x) +**************************************************************************/ +int log2Int(int a) +{ + int i; + + for (i=1; a > 1; i++, a = a>>1); + return i-1; +} + + +/************************************************************************* +* These functions set the values of a vector +**************************************************************************/ +float *sset(int n, float val, float *x) +{ + int i; + + for (i=0; i x[max] ? i : max); + + return max; +} + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int samax_strd(int n, float *x, int incx) +{ + int i; + int max=0; + + n *= incx; + for (i=incx; i x[max] ? i : max); + + return max/incx; +} + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int sfamax(int n, float *x) +{ + int i; + int max=0; + + for (i=1; i fabs(x[max]) ? i : max); + + return max; +} + + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int samin_strd(int n, float *x, int incx) +{ + int i; + int min=0; + + n *= incx; + for (i=incx; i x[max] ? i : max); + + return max/incx; +} + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int idxamin_strd(int n, idxtype *x, int incx) +{ + int i, min=0; + + n *= incx; + for (i=incx; i x[max] ? i : max); + + return max; +} + + +/************************************************************************* +* These functions return the index of the maximum element in a vector +**************************************************************************/ +int sfavg(int n, float *x) +{ + int i; + float total = 0.0; + + if (n == 0) + return 0.0; + + for (i=0; i x[1]) { + max1 = 0; + max2 = 1; + } + else { + max1 = 1; + max2 = 0; + } + + for (i=2; i x[max1]) { + max2 = max1; + max1 = i; + } + else if (x[i] > x[max2]) + max2 = i; + } + + return max2; +} + + +/************************************************************************* +* These functions return the index of the minimum element in a vector +**************************************************************************/ +int samin(int n, float *x) +{ + int i, min=0; + + for (i=1; i=0; n--) + y[n] += x[n]; +} + + +/************************************************************************* +* This function sums the entries in an array +**************************************************************************/ +float ssum(int n, float *x) +{ + int i; + float sum = 0.0; + + for (i=0; i m11) + return 0; + if (m22 < m12) + return 1; + if (m22 > m12) + return 0; + + return sm2 < sm1; +} + +/************************************************************************* +* This is a comparison function +**************************************************************************/ +int myvalkeycompare(const void *fptr, const void *sptr) +{ + KVType *first, *second; + + first = (KVType *)(fptr); + second = (KVType *)(sptr); + + if (first->val > second->val) + return 1; + + if (first->val < second->val) + return -1; + + return 0; +} + +/************************************************************************* +* This is the inverse comparison function +**************************************************************************/ +int imyvalkeycompare(const void *fptr, const void *sptr) +{ + KVType *first, *second; + + first = (KVType *)(fptr); + second = (KVType *)(sptr); + + if (first->val > second->val) + return -1; + + if (first->val < second->val) + return 1; + + return 0; +} + + +/************************************************************************* +* The following function allocates and sets an array of floats +**************************************************************************/ +float *fsmalloc(int n, float fval, char *msg) +{ + if (n == 0) + return NULL; + + return sset(n, fval, (float *)GKmalloc(sizeof(float)*n, msg)); +} + + +/************************************************************************* +* This function computes a 2-norm +**************************************************************************/ +void saxpy2(int n, float alpha, float *x, int incx, float *y, int incy) +{ + int i; + + for (i=0; i x[*first]) { + *third = *second; + *second = *first; + *first = i; + continue; + } + + if (*second == -1 || x[i] > x[*second]) { + *third = *second; + *second = i; + continue; + } + + if (*third == -1 || x[i] > x[*third]) + *third = i; + } + + return; +} diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/wave.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/wave.c new file mode 100644 index 0000000..0f1cb3f --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/wave.c @@ -0,0 +1,241 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * wave.c + * + * This file contains code for directed diffusion at the coarsest graph + * + * Started 5/19/97, Kirk, George + * + * $Id: wave.c,v 1.3 2003/07/22 21:47:18 karypis Exp $ + * + */ + +#include + +/************************************************************************* +* This function performs a k-way directed diffusion +**************************************************************************/ +float WavefrontDiffusion(CtrlType *ctrl, GraphType *graph, idxtype *home) +{ + int ii, i, j, k, l, nvtxs, nedges, nparts; + int from, to, edge, done, nswaps, noswaps, totalv, wsize; + int npasses, first, second, third, mind, maxd; + idxtype *xadj, *adjncy, *adjwgt, *where, *perm; + idxtype *rowptr, *colind, *ed, *psize; + float *transfer, *tmpvec; + float balance = -1.0, *load, *solution, *workspace; + float *nvwgt, *npwgts, flowFactor, cost, ubfactor; + MatrixType matrix; + KeyValueType *cand; + int ndirty, nclean, dptr, clean; + + nvtxs = graph->nvtxs; + nedges = graph->nedges; + xadj = graph->xadj; + nvwgt = graph->nvwgt; + adjncy = graph->adjncy; + adjwgt = graph->adjwgt; + where = graph->where; + nparts = ctrl->nparts; + ubfactor = ctrl->ubvec[0]; + matrix.nrows = nparts; + + flowFactor = 0.35; + flowFactor = (ctrl->mype == 2) ? 0.50 : flowFactor; + flowFactor = (ctrl->mype == 3) ? 0.75 : flowFactor; + flowFactor = (ctrl->mype == 4) ? 1.00 : flowFactor; + + /* allocate memory */ + solution = fmalloc(4*nparts+2*nedges, "WavefrontDiffusion: solution"); + tmpvec = solution + nparts; + npwgts = solution + 2*nparts; + load = solution + 3*nparts; + matrix.values = solution + 4*nparts; + transfer = matrix.transfer = solution + 4*nparts + nedges; + + perm = idxmalloc(2*nvtxs+2*nparts+nedges+1, "WavefrontDiffusion: perm"); + ed = perm + nvtxs; + psize = perm + 2*nvtxs; + rowptr = matrix.rowptr = perm + 2*nvtxs + nparts; + colind = matrix.colind = perm + 2*nvtxs + 2*nparts + 1; + + wsize = amax(sizeof(float)*nparts*6, sizeof(idxtype)*(nvtxs+nparts*2+1)); + workspace = (float *)GKmalloc(wsize, "WavefrontDiffusion: workspace"); + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "WavefrontDiffusion: cand"); + + + /*****************************/ + /* Populate empty subdomains */ + /*****************************/ + idxset(nparts, 0, psize); + for (i=0; itpwgts, 0); + done = 0; + + npasses = amin(nparts/2, NGD_PASSES); + for (l=0; lmype); + goto CleanUpAndExit; + } + } + + ConjGrad2(&matrix, load, solution, 0.001, workspace); + ComputeTransferVector(1, &matrix, solution, transfer, 0); + + GetThreeMax(nparts, load, &first, &second, &third); + + if (l%3 == 0) { + FastRandomPermute(nvtxs, perm, 1); + } + else { + /*****************************/ + /* move dirty vertices first */ + /*****************************/ + ndirty = 0; + for (i=0; imype == 0) { + for (j=nvtxs, k=0, ii=0; iimype == 0) ? cand[ii].val : perm[ii]; + from = where[i]; + + /* don't move out the last vertex in a subdomain */ + if (psize[from] == 1) + continue; + + clean = (from == home[i]) ? 1 : 0; + + /* only move from top three or dirty vertices */ + if (from != first && from != second && from != third && clean) + continue; + + /* Scatter the sparse transfer row into the dense tmpvec row */ + for (j=rowptr[from]+1; j (flowFactor * nvwgt[i])) { + tmpvec[to] -= nvwgt[i]; + INC_DEC(psize[to], psize[from], 1); + INC_DEC(npwgts[to], npwgts[from], nvwgt[i]); + INC_DEC(load[to], load[from], nvwgt[i]); + where[i] = to; + nswaps++; + + /* Update external degrees */ + ed[i] = 0; + for (k=xadj[i]; k 0) + break; + + noswaps = (nswaps > 0) ? 0 : 1; + if (GlobalSESum(ctrl, noswaps) > ctrl->npes/2) + break; + + } + } + + graph->mincut = ComputeSerialEdgeCut(graph); + totalv = Mc_ComputeSerialTotalV(graph, home); + cost = ctrl->ipc_factor * (float)graph->mincut + ctrl->redist_factor * (float)totalv; + + +CleanUpAndExit: + GKfree((void **)&solution, (void **)&perm, (void **)&workspace, (void **)&cand, LTERM); + + return cost; +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/weird.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/weird.c new file mode 100644 index 0000000..69d0e5d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/weird.c @@ -0,0 +1,275 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * weird.c + * + * This file contain various graph setting up routines + * + * Started 10/19/96 + * George + * + * $Id: weird.c,v 1.9 2003/07/31 16:27:28 karypis Exp $ + * + */ + +#include + + + +/************************************************************************* +* This function computes a partitioning of a small graph +**************************************************************************/ +void PartitionSmallGraph(CtrlType *ctrl, GraphType *graph, WorkSpaceType *wspace) +{ + int i, h, ncon, nparts, npes, mype; + int moptions[10]; + int mynumflag, mywgtflag, me; + idxtype *mypart; + int lpecut[2], gpecut[2]; + GraphType *agraph; + int *sendcounts, *displs; + float *mytpwgts, *gnpwgts, *lnpwgts; + + ncon = graph->ncon; + nparts = ctrl->nparts; + + MPI_Comm_size(ctrl->comm, &npes); + MPI_Comm_rank(ctrl->comm, &mype); + + SetUp(ctrl, graph, wspace); + graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "PartitionSmallGraph: where"); + agraph = Moc_AssembleAdaptiveGraph(ctrl, graph, wspace); + mypart = idxmalloc(agraph->nvtxs, "mypart"); + + moptions[0] = 0; + moptions[7] = ctrl->sync + mype; + mynumflag = 0; + mywgtflag = 3; + if (ncon == 1) { + METIS_WPartGraphKway2(&agraph->nvtxs, agraph->xadj, agraph->adjncy, agraph->vwgt, + agraph->adjwgt, &mywgtflag, &mynumflag, &nparts, ctrl->tpwgts, moptions, + &graph->mincut, mypart); + } + else { + mytpwgts = fmalloc(nparts, "mytpwgts"); + for (i=0; itpwgts[i*ncon]; + + METIS_mCPartGraphRecursive2(&agraph->nvtxs, &ncon, agraph->xadj, agraph->adjncy, + agraph->vwgt, agraph->adjwgt, &mywgtflag, &mynumflag, &nparts, mytpwgts, + moptions, &graph->mincut, mypart); + + free(mytpwgts); + } + + lpecut[0] = graph->mincut; + lpecut[1] = mype; + MPI_Allreduce(lpecut, gpecut, 1, MPI_2INT, MPI_MINLOC, ctrl->comm); + graph->mincut = gpecut[0]; + + if (lpecut[1] == gpecut[1] && gpecut[1] != 0) + MPI_Send((void *)mypart, agraph->nvtxs, IDX_DATATYPE, 0, 1, ctrl->comm); + if (lpecut[1] == 0 && gpecut[1] != 0) + MPI_Recv((void *)mypart, agraph->nvtxs, IDX_DATATYPE, gpecut[1], 1, ctrl->comm, &ctrl->status); + + sendcounts = imalloc(npes, "sendcounts"); + displs = imalloc(npes, "displs"); + + for (i=0; ivtxdist[i+1]-graph->vtxdist[i]; + displs[i] = graph->vtxdist[i]; + } + + MPI_Scatterv((void *)mypart, sendcounts, displs, IDX_DATATYPE, + (void *)graph->where, graph->nvtxs, IDX_DATATYPE, 0, ctrl->comm); + + lnpwgts = graph->lnpwgts = fmalloc(nparts*ncon, "lnpwgts"); + gnpwgts = graph->gnpwgts = fmalloc(nparts*ncon, "gnpwgts"); + sset(nparts*ncon, 0, lnpwgts); + for (i=0; invtxs; i++) { + me = graph->where[i]; + for (h=0; hnvwgt[i*ncon+h]; + } + MPI_Allreduce((void *)lnpwgts, (void *)gnpwgts, nparts*ncon, MPI_FLOAT, MPI_SUM, ctrl->comm); + GKfree((void**)&mypart, (void**)&sendcounts, (void**)&displs, LTERM); + FreeGraph(agraph); + + return; +} + + + +/************************************************************************* +* This function checks the inputs for the partitioning routines +**************************************************************************/ +void CheckInputs(int partType, int npes, int dbglvl, int *wgtflag, int *iwgtflag, + int *numflag, int *inumflag, int *ncon, int *incon, int *nparts, + int *inparts, float *tpwgts, float **itpwgts, float *ubvec, + float *iubvec, float *ipc2redist, float *iipc2redist, int *options, + int *ioptions, idxtype *part, MPI_Comm *comm) +{ + int i, j; + int doweabort, doiabort = 0; + float tsum, *myitpwgts; + int mgcnums[5] = {-1, 2, 3, 4, 2}; + + /**************************************/ + if (part == NULL) { + doiabort = 1; + IFSET(dbglvl, DBG_INFO, printf("ERROR: part array is set to NULL.\n")); + } + /**************************************/ + + + /**************************************/ + if (wgtflag == NULL) { + *iwgtflag = 0; + IFSET(dbglvl, DBG_INFO, printf("WARNING: wgtflag is NULL. Using a value of 0.\n")); + } + else { + *iwgtflag = *wgtflag; + } + /**************************************/ + + + /**************************************/ + if (numflag == NULL) { + *inumflag = 0; + IFSET(dbglvl, DBG_INFO, printf("WARNING: numflag is NULL. Using a value of 0.\n")); + } + else { + if (*numflag != 0 && *numflag != 1) { + IFSET(dbglvl, DBG_INFO, printf("WARNING: bad value for numflag %d. Using a value of 0.\n", *numflag)); + *inumflag = 0; + } + else { + *inumflag = *numflag; + } + } + /**************************************/ + + + /**************************************/ + if (ncon == NULL) { + *incon = 1; + IFSET(dbglvl, DBG_INFO, printf("WARNING: ncon is NULL. Using a value of 1.\n")); + } + else { + if (*ncon < 1 || *ncon > MAXNCON) { + IFSET(dbglvl, DBG_INFO, printf("WARNING: bad value for ncon %d. Using a value of 1.\n", *ncon)); + *incon = 1; + } + else { + *incon = *ncon; + } + } + /**************************************/ + + + /**************************************/ + if (nparts == NULL) { + *inparts = npes; + IFSET(dbglvl, DBG_INFO, printf("WARNING: nparts is NULL. Using a value of %d.\n", npes)); + } + else { + if (*nparts < 1 || *nparts > MAX_NPARTS) { + IFSET(dbglvl, DBG_INFO, printf("WARNING: bad value for nparts %d. Using a value of %d.\n", *nparts, npes)); + *inparts = npes; + } + else { + *inparts = *nparts; + } + } + /**************************************/ + + + /**************************************/ + myitpwgts = *itpwgts = fmalloc((*inparts)*(*incon), "CheckInputs: itpwgts"); + if (tpwgts == NULL) { + sset((*inparts)*(*incon), 1.0/(float)(*inparts), myitpwgts); + IFSET(dbglvl, DBG_INFO, printf("WARNING: tpwgts is NULL. Setting all array elements to %.3f.\n", 1.0/(float)(*inparts))); + } + else { + for (i=0; i<*incon; i++) { + tsum = 0.0; + for (j=0; j<*inparts; j++) { + tsum += tpwgts[j*(*incon)+i]; + } + if (fabs(1.0-tsum) < SMALLFLOAT) + tsum = 1.0; + for (j=0; j<*inparts; j++) + myitpwgts[j*(*incon)+i] = tpwgts[j*(*incon)+i] / tsum; + } + } + /**************************************/ + + + /**************************************/ + if (ubvec == NULL) { + sset(*incon, 1.05, iubvec); + IFSET(dbglvl, DBG_INFO, printf("WARNING: ubvec is NULL. Setting all array elements to 1.05.\n")); + } + else { + for (i=0; i<*incon; i++) { + if (ubvec[i] < 1.0 || ubvec[i] > (float)(*inparts)) { + iubvec[i] = 1.05; + IFSET(dbglvl, DBG_INFO, printf("WARNING: bad value for ubvec[%d]: %.3f. Setting value to 1.05.[%d]\n", i, ubvec[i], *inparts)); + } + else { + iubvec[i] = ubvec[i]; + } + } + } + /**************************************/ + + + /**************************************/ + if (partType == ADAPTIVE_PARTITION) { + if (ipc2redist != NULL) { + if (*ipc2redist < SMALLFLOAT || *ipc2redist > 1000000.0) { + IFSET(dbglvl, DBG_INFO, printf("WARNING: bad value for ipc2redist %.3f. Using a value of 1000.\n", *ipc2redist)); + *iipc2redist = 1000.0; + } + else { + *iipc2redist = *ipc2redist; + } + } + else { + IFSET(dbglvl, DBG_INFO, printf("WARNING: ipc2redist is NULL. Using a value of 1000.\n")); + *iipc2redist = 1000.0; + } + } + /**************************************/ + + + /**************************************/ + if (options == NULL) { + ioptions[0] = 0; + IFSET(dbglvl, DBG_INFO, printf("WARNING: options is NULL. Using defaults\n")); + } + else { + ioptions[0] = options[0]; + ioptions[1] = options[1]; + ioptions[2] = options[2]; + if (partType == ADAPTIVE_PARTITION || partType == REFINE_PARTITION) + ioptions[3] = options[3]; + } + /**************************************/ + + + /**************************************/ + if (comm == NULL) { + IFSET(dbglvl, DBG_INFO, printf("ERROR: comm is NULL. Aborting\n")); + abort(); + } + else { + MPI_Allreduce((void *)&doiabort, (void *)&doweabort, 1, MPI_INT, MPI_MAX, *comm); + if (doweabort > 0) + abort(); + } + /**************************************/ + +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/xyzpart.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/xyzpart.c new file mode 100644 index 0000000..e538034 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/ParMETISLib/xyzpart.c @@ -0,0 +1,257 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * xyzpart.c + * + * This file contains code that implements a coordinate based partitioning + * + * Started 7/11/97 + * George + * + * $Id: xyzpart.c,v 1.3 2003/07/30 18:37:59 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function implements a simple coordinate based partitioning +**************************************************************************/ +void Coordinate_Partition(CtrlType *ctrl, GraphType *graph, int ndims, float *xyz, + int setup, WorkSpaceType *wspace) +{ + int i, j, k, nvtxs, firstvtx, icoord, coords[3]; + idxtype *vtxdist; + float max[3], min[3], gmin[3], gmax[3], shift[3], scale[3]; + KeyValueType *cand; + + if (setup) + SetUp(ctrl, graph, wspace); + else + graph->nrecv = 0; + + nvtxs = graph->nvtxs; + vtxdist = graph->vtxdist; + + firstvtx = vtxdist[ctrl->mype]; + + cand = (KeyValueType *)GKmalloc(nvtxs*sizeof(KeyValueType), "Coordinate_Partition: cand"); + + /* Compute parameters for coordinate transformation */ + for (k=0; k max[k]) + max[k] = xyz[i*ndims+k]; + } + } + + /* Compute global min and max */ + MPI_Allreduce((void *)min, (void *)gmin, ndims, MPI_FLOAT, MPI_MIN, ctrl->comm); + MPI_Allreduce((void *)max, (void *)gmax, ndims, MPI_FLOAT, MPI_MAX, ctrl->comm); + + /* myprintf(ctrl, "Coordinate Range: %e %e, Global %e %e\n", min[0], max[0], gmin[0], gmax[0]); */ + + for (k=0; kxyztype) { + case XYZ_XCOORD: + for (i=0; i=0 && cand[i].key<=1000000); + cand[i].val = firstvtx+i; + } + break; + case XYZ_SPFILL: + for (i=0; i=0; j--) { + for (k=0; knpes, mype=ctrl->mype, firstvtx, lastvtx; + idxtype *scounts, *rcounts, *vtxdist, *perm; + KeyValueType *relmnts, *mypicks, *allpicks; + + nvtxs = graph->nvtxs; + vtxdist = graph->vtxdist; + + scounts = wspace->pv1; + rcounts = wspace->pv2; + + /* Allocate memory for the splitters */ + mypicks = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*(npes+1), "ParSort: mypicks"); + allpicks = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*npes*npes, "ParSort: allpicks"); + + /* Sort the local elements */ + ikeysort(nvtxs, elmnts); + + /* Select the local npes-1 equally spaced elements */ + for (i=1; icomm); + + /* PrintPairs(ctrl, npes*(npes-1), allpicks, "Allpicks"); */ + + /* Sort all the picks */ + ikeyvalsort(npes*(npes-1), allpicks); + + /* PrintPairs(ctrl, npes*(npes-1), allpicks, "Allpicks"); */ + + /* Select the final splitters. Set the boundaries to simplify coding */ + for (i=1; icomm); + +/* + PrintVector(ctrl, npes, 0, scounts, "Scounts"); + PrintVector(ctrl, npes, 0, rcounts, "Rcounts"); +*/ + + /* Allocate memory for sorted elements and receive them */ + MAKECSR(i, npes, scounts); + MAKECSR(i, npes, rcounts); + nrecv = rcounts[npes]; + if (wspace->nlarge >= nrecv) + relmnts = (KeyValueType *)wspace->pairs; + else + relmnts = (KeyValueType *)GKmalloc(sizeof(KeyValueType)*nrecv, "ParSort: relmnts"); + + /* Issue the receives first */ + for (i=0; icomm, ctrl->rreq+i); + + /* Issue the sends next */ + for (i=0; icomm, ctrl->sreq+i); + + MPI_Waitall(npes, ctrl->rreq, ctrl->statuses); + MPI_Waitall(npes, ctrl->sreq, ctrl->statuses); + + + /* OK, now do the local sort of the relmnts. Use perm to keep track original order */ + perm = idxmalloc(nrecv, "ParSort: perm"); + for (i=0; icomm); + firstvtx = lastvtx-nrecv; + + /*myprintf(ctrl, "first, last: %d %d\n", firstvtx, lastvtx); */ + + for (j=0, i=0; i firstvtx) { /* Found the first PE that is passed me */ + if (vtxdist[i+1] >= lastvtx) { + /* myprintf(ctrl, "Shifting %d elements to processor %d\n", lastvtx-firstvtx, i); */ + for (k=0; k= lastvtx) + break; + } + + /* Reverse the ordering on the relmnts[].val */ + for (i=0; i=0 && relmnts[i].keycomm, ctrl->rreq+i); + + /* Issue the sends next */ + for (i=0; icomm, ctrl->sreq+i); + + MPI_Waitall(npes, ctrl->rreq, ctrl->statuses); + MPI_Waitall(npes, ctrl->sreq, ctrl->statuses); + + + /* Construct a partition for the graph */ + graph->where = idxmalloc(graph->nvtxs+graph->nrecv, "PartSort: graph->where"); + firstvtx = vtxdist[mype]; + for (i=0; i=0 && elmnts[i].key=vtxdist[mype] && elmnts[i].valwhere[elmnts[i].val-firstvtx] = elmnts[i].key; + } + + + GKfree((void **)&mypicks, (void **)&allpicks, (void **)&perm, LTERM); + if (wspace->nlarge < nrecv) + free(relmnts); + +} + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/Makefile b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/Makefile new file mode 100644 index 0000000..0254eec --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/Makefile @@ -0,0 +1,56 @@ +include ../Makefile.in + +BINDIR = ../Graphs + +INCLUDES = -I./ -I../ParMETISLib $(INCDIR) +CFLAGS = $(COPTIONS) $(OPTFLAGS) $(INCLUDES) + + +LIBSDIR = -L.. $(LIBDIR) +LIBS = -lparmetis -lmetis $(XTRALIBS) -lm +PARMETISLIB = ../libparmetis.a ../libmetis.a + + +PTESTOBJS = ptest.o io.o adaptgraph.o +MESHTESTOBJS = mtest.o io.o +PARMETISOBJS = parmetis.o io.o adaptgraph.o + + +.c.o: + $(CC) $(CFLAGS) -c $*.c + + +default: $(BINDIR)/ptest$(VERNUM) $(BINDIR)/mtest$(VERNUM) + +$(BINDIR)/mtest$(VERNUM): $(MESHTESTOBJS) $(PARMETISLIB) + $(LD) -o $@ $(MESHTESTOBJS) $(LIBSDIR) $(LIBS) + chmod 744 $@ + +$(BINDIR)/ptest$(VERNUM): $(PTESTOBJS) $(PARMETISLIB) + $(LD) -o $@ $(PTESTOBJS) $(LIBSDIR) $(LIBS) + chmod 744 $@ + +clean: + rm -f *.o ;\ + rm -f $(BINDIR)/ptest$(VERNUM) + rm -f $(BINDIR)/mtest$(VERNUM) + +realclean: + rm -f *.o ;\ + rm -f $(BINDIR)/ptest$(VERNUM) + rm -f $(BINDIR)/mtest$(VERNUM) + + +checkin: + @for file in *.[c,h]; \ + do \ + ci -u -m'Maintance' $$file;\ + done + +checkin2: + @for file in *.[c,h]; \ + do \ + ci $$file;\ + rcs -U $$file;\ + co $$file;\ + done diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/adaptgraph.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/adaptgraph.c new file mode 100644 index 0000000..50de22e --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/adaptgraph.c @@ -0,0 +1,171 @@ +/* + * Copyright 1998, Regents of the University of Minnesota + * + * tstadpt.c + * + * This file contains code for testing teh adaptive partitioning routines + * + * Started 5/19/97 + * George + * + * $Id: adaptgraph.c,v 1.2 2003/07/21 17:50:22 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* This function implements a simple graph adaption strategy. +**************************************************************************/ +void AdaptGraph(GraphType *graph, int afactor, MPI_Comm comm) +{ + int i, nvtxs, nadapt, firstvtx, lastvtx; + int npes, mype, mypwgt, max, min, sum; + idxtype *vwgt, *xadj, *adjncy, *adjwgt, *perm; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + srand(mype*afactor); + srand48(mype*afactor); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + if (graph->adjwgt == NULL) + adjwgt = graph->adjwgt = idxsmalloc(graph->nedges, 1, "AdaptGraph: adjwgt"); + else + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; + + firstvtx = graph->vtxdist[mype]; + lastvtx = graph->vtxdist[mype+1]; + + perm = idxmalloc(nvtxs, "AdaptGraph: perm"); + FastRandomPermute(nvtxs, perm, 1); + + nadapt = RandomInRange(nvtxs); + nadapt = RandomInRange(nvtxs); + nadapt = RandomInRange(nvtxs); + + for (i=0; i= firstvtx && k < lastvtx) { + adjwgt[j] = (int)pow(1.0*(amin(vwgt[i],vwgt[k-firstvtx])), .6667); + if (adjwgt[j] == 0) + adjwgt[j] = 1; + } + } + } +*/ + + mypwgt = idxsum(nvtxs, vwgt); + + MPI_Allreduce((void *)&mypwgt, (void *)&max, 1, MPI_INT, MPI_MAX, comm); + MPI_Allreduce((void *)&mypwgt, (void *)&min, 1, MPI_INT, MPI_MIN, comm); + MPI_Allreduce((void *)&mypwgt, (void *)&sum, 1, MPI_INT, MPI_SUM, comm); + + if (mype == 0) + printf("Initial Load Imbalance: %5.4f, [%5d %5d %5d] for afactor: %d\n", (1.0*max*npes)/(1.0*sum), min, max, sum, afactor); + + free(perm); +} + + +/************************************************************************* +* This function implements a simple graph adaption strategy. +**************************************************************************/ +void AdaptGraph2(GraphType *graph, int afactor, MPI_Comm comm) +{ + int i, j, k, nvtxs, firstvtx, lastvtx; + int npes, mype, mypwgt, max, min, sum; + idxtype *vwgt, *xadj, *adjncy, *adjwgt; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + srand(mype*afactor); + srand48(mype*afactor); + + nvtxs = graph->nvtxs; + xadj = graph->xadj; + adjncy = graph->adjncy; + if (graph->adjwgt == NULL) + adjwgt = graph->adjwgt = idxsmalloc(graph->nedges, 1, "AdaptGraph: adjwgt"); + else + adjwgt = graph->adjwgt; + vwgt = graph->vwgt; + + firstvtx = graph->vtxdist[mype]; + lastvtx = graph->vtxdist[mype+1]; + + +/* if (RandomInRange(npes+1) < .05*npes) { */ + if (RandomInRange(npes+1) < 2) { + printf("[%d] is adapting\n", mype); + for (i=0; i= firstvtx && k < lastvtx) { + adjwgt[j] = (int)pow(1.0*(amin(vwgt[i],vwgt[k-firstvtx])), .6667); + if (adjwgt[j] == 0) + adjwgt[j] = 1; + } + } + } + + mypwgt = idxsum(nvtxs, vwgt); + + MPI_Allreduce((void *)&mypwgt, (void *)&max, 1, MPI_INT, MPI_MAX, comm); + MPI_Allreduce((void *)&mypwgt, (void *)&min, 1, MPI_INT, MPI_MIN, comm); + MPI_Allreduce((void *)&mypwgt, (void *)&sum, 1, MPI_INT, MPI_SUM, comm); + + if (mype == 0) + printf("Initial Load Imbalance: %5.4f, [%5d %5d %5d]\n", (1.0*max*npes)/(1.0*sum), min, max, sum); + +} + + +/************************************************************************* +* This function implements a simple graph adaption strategy. +**************************************************************************/ +void Mc_AdaptGraph(GraphType *graph, idxtype *part, int ncon, int nparts, MPI_Comm comm) +{ + int h, i; + int nvtxs; + int npes, mype; + idxtype *vwgt, *pwgts; + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + nvtxs = graph->nvtxs; + vwgt = graph->vwgt; + pwgts = idxsmalloc(nparts*ncon, 1, "pwgts"); + + if (mype == 0) { + for (i=0; i +#define MAXLINE 8192 + +/************************************************************************* +* This function reads the CSR matrix +**************************************************************************/ +void ParallelReadGraph(GraphType *graph, char *filename, MPI_Comm comm) +{ + int i, k, l, pe; + int npes, mype, ier; + int gnvtxs, nvtxs, your_nvtxs, your_nedges, gnedges; + int maxnvtxs = -1, maxnedges = -1; + int readew = -1, readvw = -1, dummy, edge; + idxtype *vtxdist, *xadj, *adjncy, *vwgt, *adjwgt; + idxtype *your_xadj, *your_adjncy, *your_vwgt, *your_adjwgt, graphinfo[4]; + int fmt, ncon, nobj; + MPI_Status stat; + char *line = NULL, *oldstr, *newstr; + FILE *fpin = NULL; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + vtxdist = graph->vtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); + + if (mype == npes-1) { + ier = 0; + fpin = fopen(filename, "r"); + + if (fpin == NULL){ + printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); + ier++; + } + + MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); + if (ier > 0){ + MPI_Finalize(); + exit(0); + } + + line = (char *)GKmalloc(sizeof(char)*(MAXLINE+1), "line"); + + do { + fgets(line, MAXLINE, fpin); + } while (line[0] == '%' && !feof(fpin)); + + fmt = ncon = nobj = 0; + sscanf(line, "%d %d %d %d %d", &gnvtxs, &gnedges, &fmt, &ncon, &nobj); + gnedges *=2; + readew = (fmt%10 > 0); + readvw = ((fmt/10)%10 > 0); + graph->ncon = ncon = (ncon == 0 ? 1 : ncon); + graph->nobj = nobj = (nobj == 0 ? 1 : nobj); + +/* printf("Nvtxs: %d, Nedges: %d, Ncon: %d\n", gnvtxs, gnedges, ncon); */ + + graphinfo[0] = ncon; + graphinfo[1] = nobj; + graphinfo[2] = readvw; + graphinfo[3] = readew; + MPI_Bcast((void *)graphinfo, 4, IDX_DATATYPE, npes-1, comm); + + /* Construct vtxdist and send it to all the processors */ + vtxdist[0] = 0; + for (i=0,k=gnvtxs; i 0){ + MPI_Finalize(); + exit(0); + } + + MPI_Bcast((void *)graphinfo, 4, IDX_DATATYPE, npes-1, comm); + graph->ncon = ncon = graphinfo[0]; + graph->nobj = nobj = graphinfo[1]; + readvw = graphinfo[2]; + readew = graphinfo[3]; + + MPI_Bcast((void *)vtxdist, npes+1, IDX_DATATYPE, npes-1, comm); + } + + if ((ncon > 1 && !readvw) || (nobj > 1 && !readew)) { + printf("fmt and ncon/nobj are inconsistant. Exiting...\n"); + MPI_Finalize(); + exit(-1); + } + + graph->gnvtxs = vtxdist[npes]; + nvtxs = graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; + xadj = graph->xadj = idxmalloc(graph->nvtxs+1, "ParallelReadGraph: xadj"); + vwgt = graph->vwgt = idxmalloc(graph->nvtxs*ncon, "ParallelReadGraph: vwgt"); + /*******************************************/ + /* Go through first time and generate xadj */ + /*******************************************/ + if (mype == npes-1) { + maxnvtxs = 0; + for (i=0; inedges = xadj[nvtxs]; + adjncy = graph->adjncy = idxmalloc(xadj[nvtxs], "ParallelReadGraph: adjncy"); + adjwgt = graph->adjwgt = idxmalloc(xadj[nvtxs]*nobj, "ParallelReadGraph: adjwgt"); + /***********************************************/ + /* Now go through again and record adjncy data */ + /***********************************************/ + if (mype == npes-1) { + ier = 0; + fpin = fopen(filename, "r"); + + if (fpin == NULL){ + printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); + ier++; + } + + MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); + if (ier > 0){ + MPI_Finalize(); + exit(0); + } + + /* get first line again */ + do { + fgets(line, MAXLINE, fpin); + } while (line[0] == '%' && !feof(fpin)); + + your_adjncy = idxmalloc(maxnedges, "your_adjncy"); + your_adjwgt = idxmalloc(maxnedges*nobj, "your_adjwgt"); + + for (pe=0; pe 0){ + MPI_Finalize(); + exit(0); + } + + MPI_Recv((void *)adjncy, xadj[nvtxs], IDX_DATATYPE, npes-1, 0, comm, &stat); + MPI_Recv((void *)adjwgt, xadj[nvtxs]*nobj, IDX_DATATYPE, npes-1, 1, comm, &stat); + } + +} + + + +/************************************************************************* +* This function writes a distributed graph to file +**************************************************************************/ +void Moc_ParallelWriteGraph(CtrlType *ctrl, GraphType *graph, char *filename, + int nparts, int testset) +{ + int h, i, j; + int npes, mype, penum, gnedges; + char partfile[256]; + FILE *fpin; + MPI_Comm comm; + + comm = ctrl->comm; + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + gnedges = GlobalSESum(ctrl, graph->nedges); + sprintf(partfile, "%s.%d.%d.%d", filename, testset, graph->ncon, nparts); + + if (mype == 0) { + if ((fpin = fopen(partfile, "w")) == NULL) + errexit("Failed to open file %s", partfile); + + fprintf(fpin, "%d %d %d %d %d\n", graph->gnvtxs, gnedges/2, 11, graph->ncon, 1); + fclose(fpin); + } + + MPI_Barrier(comm); + for (penum=0; penumnvtxs; i++) { + for (h=0; hncon; h++) + fprintf(fpin, "%d ", graph->vwgt[i*graph->ncon+h]); + + for (j=graph->xadj[i]; jxadj[i+1]; j++) { + fprintf(fpin, "%d ", graph->adjncy[j]+1); + fprintf(fpin, "%d ", graph->adjwgt[j]); + } + fprintf(fpin, "\n"); + } + fclose(fpin); + } + MPI_Barrier(comm); + } + + return; +} + + +/************************************************************************* +* This function reads the CSR matrix +**************************************************************************/ +void ReadTestGraph(GraphType *graph, char *filename, MPI_Comm comm) +{ + int i, k, l, npes, mype; + int nvtxs, penum, snvtxs; + idxtype *gxadj, *gadjncy; + idxtype *vtxdist, *sxadj, *ssize = NULL; + MPI_Status status; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + vtxdist = graph->vtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); + + if (mype == 0) { + ssize = idxsmalloc(npes, 0, "ReadGraph: ssize"); + + ReadMetisGraph(filename, &nvtxs, &gxadj, &gadjncy); + + printf("Nvtxs: %d, Nedges: %d\n", nvtxs, gxadj[nvtxs]); + + /* Construct vtxdist and send it to all the processors */ + vtxdist[0] = 0; + for (i=0,k=nvtxs; ignvtxs = vtxdist[npes]; + graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; + graph->xadj = idxmalloc(graph->nvtxs+1, "ReadGraph: xadj"); + + if (mype == 0) { + for (penum=0; penum=0; i--) + sxadj[i] -= sxadj[0]; + + ssize[penum] = gxadj[vtxdist[penum+1]] - gxadj[vtxdist[penum]]; + + if (penum == mype) + idxcopy(snvtxs+1, sxadj, graph->xadj); + else + MPI_Send((void *)sxadj, snvtxs+1, IDX_DATATYPE, penum, 1, comm); + + free(sxadj); + } + } + else + MPI_Recv((void *)graph->xadj, graph->nvtxs+1, IDX_DATATYPE, 0, 1, comm, &status); + + + graph->nedges = graph->xadj[graph->nvtxs]; + graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: graph->adjncy"); + + if (mype == 0) { + for (penum=0; penumadjncy); + else + MPI_Send((void *)(gadjncy+gxadj[vtxdist[penum]]), ssize[penum], IDX_DATATYPE, penum, 1, comm); + } + + free(ssize); + } + else + MPI_Recv((void *)graph->adjncy, graph->nedges, IDX_DATATYPE, 0, 1, comm, &status); + + graph->vwgt = NULL; + graph->adjwgt = NULL; + + if (mype == 0) + GKfree(&gxadj, &gadjncy, LTERM); + + MALLOC_CHECK(NULL); +} + + + +/************************************************************************* +* This function reads the CSR matrix +**************************************************************************/ +float *ReadTestCoordinates(GraphType *graph, char *filename, int ndims, MPI_Comm comm) +{ + int i, j, k, npes, mype, penum; + float *xyz, *txyz; + FILE *fpin; + idxtype *vtxdist; + MPI_Status status; + char xyzfile[256]; + + MPI_Comm_size(comm, &npes); + MPI_Comm_rank(comm, &mype); + + vtxdist = graph->vtxdist; + + xyz = fmalloc(graph->nvtxs*ndims, "io"); + + if (mype == 0) { + sprintf(xyzfile, "%s.xyz", filename); + if ((fpin = fopen(xyzfile, "r")) == NULL) + errexit("Failed to open file %s\n", xyzfile); + } + + if (mype == 0) { + txyz = fmalloc(2*graph->nvtxs*ndims, "io"); + + for (penum=0; penumnvtxs, MPI_FLOAT, 0, 1, comm, &status); + + return xyz; +} + + + +/************************************************************************* +* This function reads the spd matrix +**************************************************************************/ +void ReadMetisGraph(char *filename, int *r_nvtxs, idxtype **r_xadj, idxtype **r_adjncy) +{ + int i, k, edge, nvtxs, nedges; + idxtype *xadj, *adjncy; + char *line, *oldstr, *newstr; + FILE *fpin; + + line = (char *)malloc(sizeof(char)*(8192+1)); + + if ((fpin = fopen(filename, "r")) == NULL) { + printf("Failed to open file %s\n", filename); + exit(0); + } + + fgets(line, 8192, fpin); + sscanf(line, "%d %d", &nvtxs, &nedges); + nedges *=2; + + xadj = idxmalloc(nvtxs+1, "ReadGraph: xadj"); + adjncy = idxmalloc(nedges, "ReadGraph: adjncy"); + + /* Start reading the graph file */ + for (xadj[0]=0, k=0, i=0; ivtxdist = idxsmalloc(npes+1, 0, "ReadGraph: vtxdist"); + + if (mype == 0) { + ssize = idxsmalloc(npes, 0, "ReadGraph: ssize"); + + Moc_SerialReadMetisGraph(filename, &nvtxs, &ncon, &nobj, &fmt, &gxadj, &gvwgt, + &gadjncy, &gadjwgt, wgtflag); + + printf("Nvtxs: %d, Nedges: %d\n", nvtxs, gxadj[nvtxs]); + + /* Construct vtxdist and send it to all the processors */ + vtxdist[0] = 0; + for (i=0,k=nvtxs; ignvtxs = vtxdist[npes]; + graph->nvtxs = vtxdist[mype+1]-vtxdist[mype]; + graph->ncon = ncon; + graph->xadj = idxmalloc(graph->nvtxs+1, "ReadGraph: xadj"); + /*************************************************/ + /* distribute xadj array */ + if (mype == 0) { + for (penum=0; penum=0; i--) + sxadj[i] -= sxadj[0]; + + ssize[penum] = gxadj[vtxdist[penum+1]] - gxadj[vtxdist[penum]]; + + if (penum == mype) + idxcopy(snvtxs+1, sxadj, graph->xadj); + else + MPI_Send((void *)sxadj, snvtxs+1, IDX_DATATYPE, penum, 1, comm); + + free(sxadj); + } + } + else + MPI_Recv((void *)graph->xadj, graph->nvtxs+1, IDX_DATATYPE, 0, 1, comm, + &status); + + + + graph->nedges = graph->xadj[graph->nvtxs]; + graph->adjncy = idxmalloc(graph->nedges, "ReadGraph: graph->adjncy"); + /*************************************************/ + /* distribute adjncy array */ + if (mype == 0) { + for (penum=0; penumadjncy); + else + MPI_Send((void *)(gadjncy+gxadj[vtxdist[penum]]), ssize[penum], + IDX_DATATYPE, penum, 1, comm); + } + + } + else + MPI_Recv((void *)graph->adjncy, graph->nedges, IDX_DATATYPE, 0, 1, comm, + &status); + + + graph->adjwgt = idxmalloc(graph->nedges*nobj, "ReadGraph: graph->adjwgt"); + if (fmt%10 > 0) { + /*************************************************/ + /* distribute adjwgt array */ + if (mype == 0) { + for (penum=0; penumadjwgt); + else + MPI_Send((void *)(gadjwgt+(gxadj[vtxdist[penum]]*nobj)), ssize[penum], + IDX_DATATYPE, penum, 1, comm); + } + + } + else + MPI_Recv((void *)graph->adjwgt, graph->nedges*nobj, IDX_DATATYPE, 0, 1, + comm, &status); + + } + else { + for (i=0; inedges*nobj; i++) + graph->adjwgt[i] = 1; + } + + graph->vwgt = idxmalloc(graph->nvtxs*ncon, "ReadGraph: graph->vwgt"); + if ((fmt/10)%10 > 0) { + /*************************************************/ + /* distribute vwgt array */ + + if (mype == 0) { + for (penum=0; penumvwgt); + else + MPI_Send((void *)(gvwgt+(vtxdist[penum]*ncon)), ssize[penum], + IDX_DATATYPE, penum, 1, comm); + } + + free(ssize); + } + else + MPI_Recv((void *)graph->vwgt, graph->nvtxs*ncon, IDX_DATATYPE, 0, 1, + comm, &status); + + } + else { + for (i=0; invtxs*ncon; i++) + graph->vwgt[i] = 1; + } + + if (mype == 0) + GKfree((void *)&gxadj, (void *)&gadjncy, (void *)&gvwgt, (void *)&gadjwgt, LTERM); + + MALLOC_CHECK(NULL); +} + + + +/************************************************************************* +* This function reads the spd matrix +**************************************************************************/ +void Moc_SerialReadMetisGraph(char *filename, int *r_nvtxs, int *r_ncon, int *r_nobj, + int *r_fmt, idxtype **r_xadj, idxtype **r_vwgt, idxtype **r_adjncy, + idxtype **r_adjwgt, int *wgtflag) +{ + int i, k, l; + int ncon, nobj, edge, nvtxs, nedges; + idxtype *xadj, *adjncy, *vwgt, *adjwgt; + char *line, *oldstr, *newstr; + int fmt, readew, readvw; + int ewgt[MAXNOBJ]; + FILE *fpin; + + line = (char *)GKmalloc(sizeof(char)*(8192+1), "line"); + + if ((fpin = fopen(filename, "r")) == NULL) { + printf("Failed to open file %s\n", filename); + exit(-1); + } + + fgets(line, 8192, fpin); + fmt = ncon = nobj = 0; + sscanf(line, "%d %d %d %d %d", &nvtxs, &nedges, &fmt, &ncon, &nobj); + readew = (fmt%10 > 0); + readvw = ((fmt/10)%10 > 0); + + *wgtflag = 0; + if (readew) + *wgtflag += 1; + if (readvw) + *wgtflag += 2; + + if ((ncon > 0 && !readvw) || (nobj > 0 && !readew)) { + printf("fmt and ncon/nobj are inconsistant.\n"); + exit(-1); + } + + nedges *=2; + ncon = (ncon == 0 ? 1 : ncon); + nobj = (nobj == 0 ? 1 : nobj); + + xadj = idxmalloc(nvtxs+1, "ReadGraph: xadj"); + adjncy = idxmalloc(nedges, "Moc_ReadGraph: adjncy"); + vwgt = (readvw ? idxmalloc(ncon*nvtxs, "RG: vwgt") : NULL); + adjwgt = (readew ? idxmalloc(nobj*nedges, "RG: adjwgt") : NULL); + + /* Start reading the graph file */ + for (xadj[0]=0, k=0, i=0; ielmdist = idxsmalloc(npes+1, 0, "ReadGraph: elmdist"); + + if (mype == npes-1) { + ier = 0; + fpin = fopen(filename, "r"); + + if (fpin == NULL){ + printf("COULD NOT OPEN FILE '%s' FOR SOME REASON!\n", filename); + ier++; + } + + MPI_Bcast(&ier, 1, MPI_INT, npes-1, comm); + if (ier > 0){ + fclose(fpin); + MPI_Finalize(); + exit(0); + } + + line = (char *)GKmalloc(sizeof(char)*(MAXLINE+1), "line"); + + fgets(line, MAXLINE, fpin); + sscanf(line, "%d %d", &gnelms, &etype); + + /* Construct elmdist and send it to all the processors */ + elmdist[0] = 0; + for (i=0,j=gnelms; i 0){ + MPI_Finalize(); + exit(0); + } + + MPI_Bcast((void *)elmdist, npes+1, IDX_DATATYPE, npes-1, comm); + } + + MPI_Bcast((void *)(&etype), 1, MPI_INT, npes-1, comm); + + gnelms = mesh->gnelms = elmdist[npes]; + nelms = mesh->nelms = elmdist[mype+1]-elmdist[mype]; + mesh->etype = etype; + esize = esizes[etype]; + mgcnum = mgcnums[etype]; + + elements = mesh->elements = idxmalloc(nelms*esize, "ParallelReadMesh: elements"); + + if (mype == npes-1) { + maxnelms = 0; + for (i=0; i elmdist[i+1]-elmdist[i]) ? + maxnelms : elmdist[i+1]-elmdist[i]; + } + + your_elements = idxmalloc(maxnelms*esize, "your_elements"); + + for (pe=0; pegnns = gmaxnode+1; + + if (mype==0) printf("Nelements: %d, Nnodes: %d, EType: %d\n", gnelms, mesh->gnns, etype); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/mtest.c b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/mtest.c new file mode 100644 index 0000000..9aa2f7d --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/mtest.c @@ -0,0 +1,96 @@ +/* + * 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: mtest.c,v 1.3 2003/07/25 14:31:47 karypis Exp $ + * + */ + +#include + + +/************************************************************************* +* Let the game begin +**************************************************************************/ +int main(int argc, char *argv[]) +{ + int i, mype, npes, nelms; + idxtype *part, *eptr; + MeshType mesh; + MPI_Comm comm; + int wgtflag, numflag, edgecut, nparts, options[10]; + int mgcnum = -1, mgcnums[5] = {-1, 2, 3, 4, 2}, esizes[5] = {-1, 3, 4, 8, 4}; + float *tpwgts, ubvec[MAXNCON]; + + 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 [NCommonNodes]\n", argv[0]); + + MPI_Finalize(); + exit(0); + } + + ParallelReadMesh(&mesh, argv[1], comm); + mgcnum = mgcnums[mesh.etype]; + mesh.ncon = 1; + + if (argc > 2) + mgcnum = atoi(argv[2]); + + if (mype == 0) printf("MGCNUM: %d\n", mgcnum); + + nparts = npes; + tpwgts = fmalloc(nparts*mesh.ncon, "tpwgts"); + for (i=0; inedges), (void *)&gnedges, 1, MPI_INT, MPI_SUM, comm); + if (mype == 0) + printf("Completed Dual Graph -- Nvtxs: %d, Nedges: %d\n", graph->gnvtxs, gnedges/2); + + numflag = wgtflag = 0; + ParMETIS_V3_PartKway(graph->vtxdist, graph->xadj, graph->adjncy, NULL, NULL, &wgtflag, + &numflag, &(graph->ncon), &nparts, tpwgts, ubvec, options, &edgecut, part, &comm); + GKfree((void *)&(graph.vtxdist), (void *)&(graph.xadj), (void *)&(graph.vwgt), (void *)&(graph.adjncy), (void *)&(graph.adjwgt), LTERM); +*/ + + GKfree((void *)&part, (void *)&tpwgts, (void *)&eptr, LTERM); + MPI_Comm_free(&comm); + MPI_Finalize(); + return 0; +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/parmetisbin.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/parmetisbin.h new file mode 100644 index 0000000..d331af3 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/Programs/parmetisbin.h @@ -0,0 +1,31 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * par_metis.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: parmetisbin.h,v 1.1 2003/07/21 17:50:23 karypis Exp $ + */ + +/* +#define DEBUG 1 +#define DMALLOC 1 +*/ + +#include +#include "../parmetis.h" + +#ifdef DMALLOC +#include +#endif + +#include +#include +#include +#include +#include + 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 + + +/************************************************************************* +* 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 \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; ivtxdist, 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); +} + + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/README b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/README new file mode 100644 index 0000000..abcde38 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/README @@ -0,0 +1,9 @@ +This is ParMetis version 3.1. You can find the manual describing the +various routines in the directory 'Manual'. Also, the file called +INSTALL contains instructions on how to build and test ParMetis. + + +Please let me know of any problems that you have found with it. + +George Karypis +karypis@cs.umn.edu diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/VERSION b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/VERSION new file mode 100644 index 0000000..1a26826 --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/VERSION @@ -0,0 +1,5 @@ +ParMetis Version 3.1.0 Fri Aug 15 13:59:41 CDT 2003 +ParMetis Version 3.0.0 Wed Mar 27 23:56:38 CST 2002 +ParMetis Version 2.0.0 Tue Sep 22 18:58:31 CDT 1998 +ParMetis Version 1.0.2 Wed Apr 15 13:14:50 CDT 1998 + diff --git a/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/parmetis.h b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/parmetis.h new file mode 100644 index 0000000..64a90ea --- /dev/null +++ b/benchmarks/CUDA/DG/3rdParty/ParMetis-3.1/parmetis.h @@ -0,0 +1,193 @@ +/* + * Copyright 1997-2003, Regents of the University of Minnesota + * + * parmetis.h + * + * This file contains function prototypes and constrant definitions for + * ParMETIS + * + * Started 7/21/03 + * George + * + */ + +#ifndef __parmetis_h__ +#define __parmetis_h__ + +#include + +#ifndef _MSC_VER +#define __cdecl +#endif + + +/************************************************************************* +* Data-structures +**************************************************************************/ +/* Undefine the following #define in order to use short int as the idxtype */ +#define IDXTYPE_INT + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +typedef int idxtype; +#else +typedef short idxtype; +#endif + + +/************************************************************************* +* Constants +**************************************************************************/ +#define PARMETIS_MAJOR_VERSION 3 +#define PARMETIS_MINOR_VERSION 1 + + +/************************************************************************* +* Function prototypes +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------- +* API Introduced with Release 3.0 (current API) +*--------------------------------------------------------------------*/ +void __cdecl ParMETIS_V3_AdaptiveRepart( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *vsize, idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, + int *nparts, float *tpwgts, float *ubvec, float *ipc2redist, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartGeomKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, float *xyz, + int *ncon, int *nparts, float *tpwgts, float *ubvec, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartGeom( + idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_V3_Mesh2Dual( + idxtype *elmdist, idxtype *eptr, idxtype *eind, int *numflag, + int *ncommonnodes, idxtype **xadj, idxtype **adjncy, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartMeshKway( + idxtype *elmdist, idxtype *eptr, idxtype *eind, idxtype *elmwgt, + int *wgtflag, int *numflag, int *ncon, int *ncommonnodes, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_V3_NodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, + int *options, idxtype *order, idxtype *sizes, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_RefineKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + + + +/*------------------------------------------------------------------ +* Backward compatibility routines with Release 2.0 +*-------------------------------------------------------------------*/ +void __cdecl ParMETIS_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeomKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ndims, float *xyz, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeom( + idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeomRefine( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, float *xyz, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RefineKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartLDiffusion( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartGDiffusion( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartRemap( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_RepartMLRemap( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_NodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm); + +void __cdecl ParMETIS_SerialNodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm); + + + + +/*------------------------------------------------------------------- +* Backward compatibility routines with Release 1.0 +*--------------------------------------------------------------------*/ +void __cdecl PARKMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGKMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGRMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int ndims, float *xyz, + idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARRMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, + idxtype *adjwgt, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARUAMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, + idxtype *adjwgt, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARDAMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm); + +#ifdef __cplusplus +} +#endif + + + + +#endif diff --git a/benchmarks/CUDA/DG/Makefile b/benchmarks/CUDA/DG/Makefile new file mode 100644 index 0000000..5988bab --- /dev/null +++ b/benchmarks/CUDA/DG/Makefile @@ -0,0 +1,62 @@ +################################################################################ +# +# Copyright 1993-2006 NVIDIA Corporation. All rights reserved. +# +# NOTICE TO USER: +# +# This source code is subject to NVIDIA ownership rights under U.S. and +# international Copyright laws. +# +# NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE +# CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR +# IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, +# OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +# OR PERFORMANCE OF THIS SOURCE CODE. +# +# U.S. Government End Users. This source code is a "commercial item" as +# that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of +# "commercial computer software" and "commercial computer software +# documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) +# and is provided to the U.S. Government only as a commercial end item. +# Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through +# 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the +# source code with only those rights set forth herein. +# +################################################################################ +# +# Build script for project +# +############################################################################### + +# Add source files here +EXECUTABLE := gpuDG3d +# Cuda source files (compiled with cudacc) +CUFILES := src/MaxwellsKernel3d.cu +# C/C++ source files (compiled with gcc / c++) +CFILES := src/Mesh3d.c src/Utils.c src/LoadBalance3d.c src/FacePair3d.c src/ParallelPairs.c src/BuildMaps3d.c src/StartUp3d.c src/MaxwellsRun3d.c \ + src/MaxwellsMPI3d.c src/MaxwellsDriver3d.c +GPGPUSIM_ROOT := ../../.. +LIB := -lparmetis -lmetis -lm -lmpi +HDRDIR = ./include +NEWLIBDIR := -L./3rdParty/ParMetis-3.1/ -L/usr/lib64/mpi/gcc/openmpi/lib64/ +N ?= 6 +HOSTNAME=$(shell hostname | awk '/aamodt/ {print 1;}') +ifeq ($(HOSTNAME),1) +CFLAGS = -Dp_N=$(N) -DNDG3d -DCUDA -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 -I/opt/mpich/include +else +CFLAGS = -Dp_N=$(N) -DNDG3d -DCUDA -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 +endif +CUFLAGS = $(CFLAGS) + +NEWCC = mpicc +LD = mpicc +NEWCPP = mpicxx +############################################################################### +# Rules and targets + +include ../../../common/common.mk diff --git a/benchmarks/CUDA/DG/MakefileCPU2d b/benchmarks/CUDA/DG/MakefileCPU2d new file mode 100644 index 0000000..04fd7c7 --- /dev/null +++ b/benchmarks/CUDA/DG/MakefileCPU2d @@ -0,0 +1,51 @@ +# define variables +VPATH = ./ +HDRDIR = ./include +LIBDIR = ./lib +# adjust this for your system + +# set options for this machine +# specify which compilers to use for c, fortran and linking +CC = mpicc +LD = mpicc + +# compiler flags to be used (set to compile with debugging on) +CFLAGS = -Dp_N=$(N) -DNDG2d -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 + +# link flags to be used +LDFLAGS = -I$(HDRDIR) -L. -L./$(LIBDIR) -O3 + +# libraries to be linked in +LIBS = -lparmetis -lmetis -lm + +# types of files we are going to construct rules for +.SUFFIXES: .c .f .cu + +# rule for .c files +.c.o: + $(CC) $(CFLAGS) -o $*.o -c $*.c + +# list of objects to be compiled +OBJS = \ + src/Mesh2d.o\ + src/Utils.o\ + src/LoadBalance2d.o\ + src/FacePair2d.o\ + src/ParallelPairs.o\ + src/BuildMaps2d.o\ + src/StartUp2d.o\ + src/MaxwellsRun2d.o\ + src/MaxwellsMPI2d.o\ + src/MaxwellsDriver2d.o\ + src/MaxwellsRHS2d.o\ + src/InitCPU2d.o + +MaxwellsCPU2d:$(OBJS) + $(LD) $(LDFLAGS) -o MaxwellsCPU2d $(OBJS) $(LIBS) + rm -r $(OBJS) + +# what to do if user types "make clean" +clean : + rm -r $(OBJS) + + diff --git a/benchmarks/CUDA/DG/MakefileGPU2d b/benchmarks/CUDA/DG/MakefileGPU2d new file mode 100644 index 0000000..faf1d94 --- /dev/null +++ b/benchmarks/CUDA/DG/MakefileGPU2d @@ -0,0 +1,57 @@ +################################################################################ +# +# Copyright 1993-2006 NVIDIA Corporation. All rights reserved. +# +# NOTICE TO USER: +# +# This source code is subject to NVIDIA ownership rights under U.S. and +# international Copyright laws. +# +# NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE +# CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR +# IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, +# OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +# OR PERFORMANCE OF THIS SOURCE CODE. +# +# U.S. Government End Users. This source code is a "commercial item" as +# that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of +# "commercial computer software" and "commercial computer software +# documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) +# and is provided to the U.S. Government only as a commercial end item. +# Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through +# 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the +# source code with only those rights set forth herein. +# +################################################################################ +# +# Build script for project +# +############################################################################### + +# Add source files here +EXECUTABLE := MaxwellsGPU2d +# Cuda source files (compiled with cudacc) +CUFILES := src/MaxwellsKernel2d.cu +# C/C++ source files (compiled with gcc / c++) +CFILES := src/Mesh2d.c src/Utils.c src/LoadBalance2d.c src/FacePair2d.c src/ParallelPairs.c src/BuildMaps2d.c src/StartUp2d.c src/MaxwellsRun2d.c \ + src/MaxwellsMPI2d.c src/MaxwellsDriver2d.c +GPGPUSIM_ROOT := ../../.. +LIB := -lparmetis -lmetis -lm +HDRDIR = /home/gyuan/perforce/gpgpu_sim/cuda-sim-dev/tests/gpuDG/include +NEWLIBDIR := -L./lib/ +N ?= 6 +CFLAGS = -Dp_N=$(N) -DNDG2d -DCUDA -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 +CUFLAGS = $(CFLAGS) + +NEWCC = mpicc +LD = mpicc +NEWCPP = mpicxx +############################################################################### +# Rules and targets + +include ../cuda_sdk_1.1/common/common.mk diff --git a/benchmarks/CUDA/DG/Makefiles/Makefile b/benchmarks/CUDA/DG/Makefiles/Makefile new file mode 100644 index 0000000..742c1d7 --- /dev/null +++ b/benchmarks/CUDA/DG/Makefiles/Makefile @@ -0,0 +1,49 @@ +################################################################################ +# +# Copyright 1993-2006 NVIDIA Corporation. All rights reserved. +# +# NOTICE TO USER: +# +# This source code is subject to NVIDIA ownership rights under U.S. and +# international Copyright laws. +# +# NVIDIA MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF THIS SOURCE +# CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR +# IMPLIED WARRANTY OF ANY KIND. NVIDIA DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE. +# IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL, +# OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE +# OR PERFORMANCE OF THIS SOURCE CODE. +# +# U.S. Government End Users. This source code is a "commercial item" as +# that term is defined at 48 C.F.R. 2.101 (OCT 1995), consisting of +# "commercial computer software" and "commercial computer software +# documentation" as such terms are used in 48 C.F.R. 12.212 (SEPT 1995) +# and is provided to the U.S. Government only as a commercial end item. +# Consistent with 48 C.F.R.12.212 and 48 C.F.R. 227.7202-1 through +# 227.7202-4 (JUNE 1995), all U.S. Government End Users acquire the +# source code with only those rights set forth herein. +# +################################################################################ +# +# Build script for project +# +############################################################################### + +# Add source files here +EXECUTABLE := MaxwellsGPU2d +# Cuda source files (compiled with cudacc) +CUFILES := src/MaxwellsKernel2d.cu +# C/C++ source files (compiled with gcc / c++) +CCFILES := src/Mesh2d.c src/Utils.c src/LoadBalance2d.c src/FacePair2d.c src/ParallelPairs.c src/BuildMaps2d.c src/StartUp2d.c src/MaxwellsRun2d.c \ + src/MaxwellsMPI2d.c src/MaxwellsDriver2d.c +GPGPUSIM_ROOT := ../../.. +LIB := -lparmetis -lmetis -lm -lcuda -lcudart + +############################################################################### +# Rules and targets + +include ../cuda_sdk_1.1/common/common.mk diff --git a/benchmarks/CUDA/DG/Makefiles/MakefileCPU3d b/benchmarks/CUDA/DG/Makefiles/MakefileCPU3d new file mode 100644 index 0000000..771a15f --- /dev/null +++ b/benchmarks/CUDA/DG/Makefiles/MakefileCPU3d @@ -0,0 +1,51 @@ +# define variables +VPATH = ./ +HDRDIR = ./include +LIBDIR = ./lib +# adjust this for your system + +# set options for this machine +# specify which compilers to use for c, fortran and linking +CC = mpicc +LD = mpicc + +# compiler flags to be used (set to compile with debugging on) +CFLAGS = -Dp_N=$(N) -DNDG3d -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 + +# link flags to be used +LDFLAGS = -I$(HDRDIR) -L. -L./$(LIBDIR) -O3 + +# libraries to be linked in +LIBS = -lparmetis -lmetis -lm + +# types of files we are going to construct rules for +.SUFFIXES: .c .f .cu + +# rule for .c files +.c.o: + $(CC) $(CFLAGS) -o $*.o -c $*.c + +# list of objects to be compiled +OBJS = \ + src/Mesh3d.o\ + src/Utils.o\ + src/LoadBalance3d.o\ + src/FacePair3d.o\ + src/ParallelPairs.o\ + src/BuildMaps3d.o\ + src/StartUp3d.o\ + src/MaxwellsRun3d.o\ + src/MaxwellsRHS3d.o\ + src/MaxwellsMPI3d.o\ + src/MaxwellsDriver3d.o\ + src/InitCPU3d.o + +MaxwellsCPU3d:$(OBJS) + $(LD) $(LDFLAGS) -o MaxwellsCPU3d $(OBJS) $(LIBS) +# rm -r $(OBJS) + +# what to do if user types "make clean" +clean : + rm -r $(OBJS) + + diff --git a/benchmarks/CUDA/DG/Makefiles/MakefileGPU3d b/benchmarks/CUDA/DG/Makefiles/MakefileGPU3d new file mode 100644 index 0000000..1af50c2 --- /dev/null +++ b/benchmarks/CUDA/DG/Makefiles/MakefileGPU3d @@ -0,0 +1,54 @@ +# define variables +VPATH = ./ +HDRDIR = ./include +LIBDIR = ./lib +# adjust this for your system +CUDADIR=/usr/local/cuda/ + +# set options for this machine +# specify which compilers to use for c, fortran and linking +CC = mpicc +LD = mpicc +NVCC = nvcc + +# compiler flags to be used (set to compile with debugging on) +CFLAGS = -Dp_N=$(N) -DNDG3d -DCUDA -I/opt/local/include -I/usr/include/malloc -I$(HDRDIR) -O3 -I$(CUDADIR)/include + +# link flags to be used +LDFLAGS = -I$(HDRDIR) -L. -L./$(LIBDIR) -O3 -L$(CUDADIR)/lib + +# libraries to be linked in +LIBS = -lparmetis -lmetis -lm -lcuda -lcudart + +# types of files we are going to construct rules for +.SUFFIXES: .c .f .cu + +# rule for .c files +.c.o: + $(CC) $(CFLAGS) -o $*.o -c $*.c +.cu.o: + $(NVCC) -o $*.o -c $*.cu --compiler-options -O3 --use_fast_math $(CFLAGS) + +# list of objects to be compiled +OBJS = \ + src/Mesh3d.o\ + src/Utils.o\ + src/LoadBalance3d.o\ + src/FacePair3d.o\ + src/ParallelPairs.o\ + src/BuildMaps3d.o\ + src/StartUp3d.o\ + src/MaxwellsRun3d.o\ + src/MaxwellsMPI3d.o\ + src/MaxwellsKernel3d.o\ + src/MaxwellsDriver3d.o + +MaxwellsGPU3d:$(OBJS) + $(LD) $(LDFLAGS) -o MaxwellsGPU3d $(OBJS) $(LIBS) + rm -r $(OBJS) + +# what to do if user types "make clean" +clean : + rm -r $(OBJS) + + diff --git a/benchmarks/CUDA/DG/Meshes/F072.neu b/benchmarks/CUDA/DG/Meshes/F072.neu new file mode 100644 index 0000000..6e02b5b --- /dev/null +++ b/benchmarks/CUDA/DG/Meshes/F072.neu @@ -0,0 +1,186 @@ + CONTROL INFO 1.3.0 +** GAMBIT NEUTRAL FILE +Sledge++ 3D mesh file, generated by GRUMMP v0.3.0: +vWriteFile_VolMesh_Neu( D:/__TW_HIDE/SVN/trunk/Examples/Experimental/GUI/Demo/Bdry/test/F13_01 ) +Sledge++ mesh generator module, Sept 2005 + NUMNP NELEM NGRPS NBSETS NDFCD NDFVL + 32 72 1 1 3 3 +ENDOFSECTION + NODAL COORDINATES 1.3.0 + 1 -1.0000000000e+000 -1.0000000000e+000 1.0000000000e+000 + 2 -1.0000000000e+000 -1.0000000000e+000 0.0000000000e+000 + 3 5.4213934109e-001 -4.5788434093e-001 3.1151508327e-001 + 4 0.0000000000e+000 -1.0000000000e+000 0.0000000000e+000 + 5 -1.0000000000e+000 0.0000000000e+000 1.0000000000e+000 + 6 -1.0000000000e+000 0.0000000000e+000 0.0000000000e+000 + 7 0.0000000000e+000 -5.0000000000e-001 -5.0000000000e-001 + 8 4.9883692752e-001 -1.0000000000e+000 -6.1871188755e-001 + 9 1.0000000000e+000 -1.0000000000e+000 0.0000000000e+000 + 10 0.0000000000e+000 -1.0000000000e+000 1.0000000000e+000 + 11 1.0000000000e+000 -1.0000000000e+000 1.0000000000e+000 + 12 0.0000000000e+000 -1.0000000000e+000 -1.0000000000e+000 + 13 -5.0000000000e-001 0.0000000000e+000 -5.0000000000e-001 + 14 -1.0000000000e+000 1.0000000000e+000 1.0000000000e+000 + 15 0.0000000000e+000 0.0000000000e+000 0.0000000000e+000 + 16 -4.0495657274e-001 4.3398602602e-001 -5.6601397398e-001 + 17 4.5040636913e-001 9.1266213338e-002 -5.1075464744e-001 + 18 0.0000000000e+000 0.0000000000e+000 -1.0000000000e+000 + 19 1.0000000000e+000 8.7061901850e-002 1.8038330930e-001 + 20 -2.4089572359e-001 1.0000000000e+000 1.9389639762e-001 + 21 0.0000000000e+000 0.0000000000e+000 1.0000000000e+000 + 22 1.0000000000e+000 -3.6055224425e-001 -3.9144582417e-001 + 23 -1.0000000000e+000 1.0000000000e+000 0.0000000000e+000 + 24 5.0009979922e-001 -5.0669729411e-001 -1.0000000000e+000 + 25 -1.0000000000e+000 0.0000000000e+000 -1.0000000000e+000 + 26 1.0000000000e+000 1.0000000000e+000 1.0000000000e+000 + 27 1.0000000000e+000 -1.0000000000e+000 -1.0000000000e+000 + 28 -1.0000000000e+000 1.0000000000e+000 -1.0000000000e+000 + 29 0.0000000000e+000 1.0000000000e+000 -1.0000000000e+000 + 30 1.0000000000e+000 1.0000000000e+000 0.0000000000e+000 + 31 1.0000000000e+000 0.0000000000e+000 -1.0000000000e+000 + 32 1.0000000000e+000 1.0000000000e+000 -1.0000000000e+000 +ENDOFSECTION + ELEMENTS/CELLS 1.3.0 + 1 6 4 2 1 4 5 + 2 6 4 4 6 2 5 + 3 6 4 10 4 1 5 + 4 6 4 3 4 7 8 + 5 6 4 3 9 4 8 + 6 6 4 4 10 9 3 + 7 6 4 4 15 6 5 + 8 6 4 7 4 12 8 + 9 6 4 4 7 15 3 + 10 6 4 10 15 4 5 + 11 6 4 10 11 9 3 + 12 6 4 10 4 15 3 + 13 6 4 8 7 3 22 + 14 6 4 8 3 9 22 + 15 6 4 3 7 15 17 + 16 6 4 19 9 11 3 + 17 6 4 20 5 6 15 + 18 6 4 11 10 21 3 + 19 6 4 17 3 7 22 + 20 6 4 16 15 6 13 + 21 6 4 10 21 15 5 + 22 6 4 24 7 12 8 + 23 6 4 10 15 21 3 + 24 6 4 3 19 9 22 + 25 6 4 20 6 5 23 + 26 6 4 3 15 19 17 + 27 6 4 19 11 21 3 + 28 6 4 20 6 16 15 + 29 6 4 7 18 15 17 + 30 6 4 19 21 15 3 + 31 6 4 17 19 3 22 + 32 6 4 8 24 7 22 + 33 6 4 16 18 15 13 + 34 6 4 16 6 25 13 + 35 6 4 20 21 14 5 + 36 6 4 20 15 21 5 + 37 6 4 14 23 20 5 + 38 6 4 18 7 12 24 + 39 6 4 8 9 27 22 + 40 6 4 20 16 6 23 + 41 6 4 17 18 15 16 + 42 6 4 17 7 18 24 + 43 6 4 24 17 7 22 + 44 6 4 23 6 25 16 + 45 6 4 27 24 12 8 + 46 6 4 16 25 18 13 + 47 6 4 11 21 26 19 + 48 6 4 30 15 16 17 + 49 6 4 8 27 24 22 + 50 6 4 17 15 19 30 + 51 6 4 26 21 14 20 + 52 6 4 30 16 15 20 + 53 6 4 17 29 18 16 + 54 6 4 20 21 15 30 + 55 6 4 19 15 21 30 + 56 6 4 17 31 19 22 + 57 6 4 23 29 20 16 + 58 6 4 29 25 18 16 + 59 6 4 17 18 31 24 + 60 6 4 24 31 17 22 + 61 6 4 30 29 16 20 + 62 6 4 23 25 28 16 + 63 6 4 30 16 29 17 + 64 6 4 31 29 18 17 + 65 6 4 20 26 21 30 + 66 6 4 17 19 31 30 + 67 6 4 19 21 26 30 + 68 6 4 23 28 29 16 + 69 6 4 25 29 28 16 + 70 6 4 24 27 31 22 + 71 6 4 30 31 17 29 + 72 6 4 31 30 32 29 +ENDOFSECTION + ELEMENT GROUP 1.3.0 +GROUP: 1 ELEMENTS: 72 MATERIAL: 1.000 NFLAGS: 0 + FLUID + 0 + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 +ENDOFSECTION + BOUNDARY CONDITIONS 1.3.0 + Diri 1 54 0 0 + 51 6 1 + 47 6 1 + 8 6 1 + 38 6 1 + 56 6 3 + 24 6 3 + 70 6 3 + 39 6 3 + 20 6 3 + 34 6 3 + 2 6 1 + 7 6 1 + 33 6 3 + 46 6 3 + 21 6 2 + 37 6 2 + 35 6 3 + 3 6 4 + 25 6 3 + 1 6 2 + 2 6 3 + 61 6 2 + 66 6 3 + 65 6 2 + 29 6 1 + 9 6 1 + 67 6 4 + 72 6 3 + 72 6 1 + 57 6 1 + 37 6 1 + 47 6 4 + 68 6 1 + 44 6 1 + 62 6 1 + 51 6 4 + 5 6 3 + 8 6 3 + 39 6 1 + 45 6 4 + 16 6 1 + 59 6 3 + 38 6 4 + 70 6 1 + 45 6 1 + 72 6 4 + 69 6 1 + 1 6 1 + 6 6 1 + 3 6 1 + 18 6 1 + 11 6 1 + 64 6 1 + 58 6 1 +ENDOFSECTION diff --git a/benchmarks/CUDA/DG/Meshes/FS_K01022.neu b/benchmarks/CUDA/DG/Meshes/FS_K01022.neu new file mode 100644 index 0000000..1201e26 --- /dev/null +++ b/benchmarks/CUDA/DG/Meshes/FS_K01022.neu @@ -0,0 +1,1929 @@ + CONTROL INFO 1.3.0 +** GAMBIT NEUTRAL FILE +NuDG++ 3D mesh file, generated by Netgen v4.5: +WriteGambitFormat ( sim.neu ) +NuDG++ mesh generator module, January 2008 + NUMNP NELEM NGRPS NBSETS NDFCD NDFVL + 309 1022 1 2 3 3 +ENDOFSECTION + NODAL COORDINATES 1.3.0 + 1 0.0000000000e+000 0.0000000000e+000 -1.0000000000e+000 + 2 0.0000000000e+000 -1.0000000000e+000 0.0000000000e+000 + 3 -1.0000000000e+000 0.0000000000e+000 0.0000000000e+000 + 4 1.0e-5 1.0e-5 1.0e-5 + 5 0.0000000000e+000 -2.5881920596e-001 -9.6592578319e-001 + 6 0.0000000000e+000 -4.9999982246e-001 -8.6602550629e-001 + 7 0.0000000000e+000 -7.0710662540e-001 -7.0710693697e-001 + 8 0.0000000000e+000 -8.6602545668e-001 -4.9999990837e-001 + 9 0.0000000000e+000 -9.6592576708e-001 -2.5881926607e-001 + 10 0.0000000000e+000 0.0000000000e+000 -2.5000000000e-001 + 11 0.0000000000e+000 0.0000000000e+000 -5.0000000000e-001 + 12 0.0000000000e+000 0.0000000000e+000 -7.5000000000e-001 + 13 -7.5000000000e-001 0.0000000000e+000 0.0000000000e+000 + 14 -5.0000000000e-001 0.0000000000e+000 0.0000000000e+000 + 15 -2.5000000000e-001 0.0000000000e+000 0.0000000000e+000 + 16 -9.6592578319e-001 0.0000000000e+000 -2.5881920596e-001 + 17 -8.6602550629e-001 0.0000000000e+000 -4.9999982246e-001 + 18 -7.0710693697e-001 0.0000000000e+000 -7.0710662540e-001 + 19 -4.9999990837e-001 0.0000000000e+000 -8.6602545668e-001 + 20 -2.5881926607e-001 0.0000000000e+000 -9.6592576708e-001 + 21 0.0000000000e+000 -7.5000000000e-001 0.0000000000e+000 + 22 0.0000000000e+000 -5.0000000000e-001 0.0000000000e+000 + 23 0.0000000000e+000 -2.5000000000e-001 0.0000000000e+000 + 24 -9.6592578319e-001 -2.5881920596e-001 0.0000000000e+000 + 25 -8.6602550629e-001 -4.9999982246e-001 0.0000000000e+000 + 26 -7.0710693697e-001 -7.0710662540e-001 0.0000000000e+000 + 27 -4.9999990837e-001 -8.6602545668e-001 0.0000000000e+000 + 28 -2.5881926607e-001 -9.6592576708e-001 0.0000000000e+000 + 29 2.1532618485e-001 -9.5336846041e-002 -9.7187731731e-001 + 30 2.2898609006e-001 -3.5660397314e-001 -9.0575878516e-001 + 31 2.2843350641e-001 -5.8910664536e-001 -7.7509450620e-001 + 32 2.2603822680e-001 -7.7648156433e-001 -5.8820328143e-001 + 33 2.2990555611e-001 -9.0433103358e-001 -3.5962315967e-001 + 34 2.3730900158e-001 -9.6508366340e-001 -1.1089616944e-001 + 35 -9.7181171496e-001 2.0013224727e-001 -1.2461570638e-001 + 36 -9.0391977821e-001 2.0772698033e-001 -3.7386967811e-001 + 37 -7.7167195716e-001 2.1775691252e-001 -5.9758205929e-001 + 38 -5.8475901608e-001 2.2871348297e-001 -7.7829752397e-001 + 39 -3.5472548036e-001 2.3084954377e-001 -9.0602335606e-001 + 40 -9.7714299200e-002 2.1885715659e-001 -9.7085192524e-001 + 41 -9.7644532926e-001 -9.1845809774e-002 1.9524053417e-001 + 42 -7.8353478113e-001 -5.8092263190e-001 2.2045893610e-001 + 43 -3.8404300685e-001 -8.9741139835e-001 2.1717216904e-001 + 44 2.4686782035e-001 -9.5973383137e-001 1.3404197922e-001 + 45 -9.7780553128e-001 1.6645914152e-001 1.2723088150e-001 + 46 1.6384448629e-001 1.6993285653e-001 -9.7173957858e-001 + 47 -9.1209694105e-001 -3.4966218999e-001 2.1404560968e-001 + 48 -6.0244603155e-001 -7.6710665287e-001 2.2046805256e-001 + 49 5.9181568487e-002 -9.7258513381e-001 2.2489041651e-001 + 50 -1.5220022599e-001 -9.6486139312e-001 2.1419053032e-001 + 51 -9.2181653438e-001 3.8722316735e-001 1.7677545422e-002 + 52 4.4454081959e-001 -4.3346052781e-001 -7.8389758933e-001 + 53 4.3137044853e-001 -6.3982360213e-001 -6.3603875219e-001 + 54 4.3251568594e-001 -7.9012840949e-001 -4.3431241974e-001 + 55 4.5327918002e-001 -8.6830394634e-001 -2.0146027335e-001 + 56 -6.5602113448e-001 -6.2203768224e-001 4.2744051399e-001 + 57 -7.9264495007e-001 4.0724383138e-001 -4.5372507638e-001 + 58 -6.3416072305e-001 4.3627571355e-001 -6.3836014843e-001 + 59 -4.2690086458e-001 4.4978583510e-001 -7.8450516529e-001 + 60 -1.8265474813e-001 4.4268086623e-001 -8.7787863265e-001 + 61 -2.4412937794e-001 -8.7604375015e-001 4.1587040608e-001 + 62 -4.6395173382e-001 -7.7792262854e-001 4.2377490804e-001 + 63 2.1463770896e-001 -9.0609982590e-001 3.6457339370e-001 + 64 -8.9936907641e-001 -1.7114716762e-001 4.0229828661e-001 + 65 -9.3087897460e-001 9.1658377997e-002 3.5364258282e-001 + 66 -8.9105008221e-001 3.9360433558e-001 -2.2606498623e-001 + 67 4.5909970228e-001 -8.8716381372e-001 4.6559972094e-002 + 68 4.0290822957e-001 8.4731006320e-002 -9.1130983486e-001 + 69 8.1157720419e-002 4.0924408737e-001 -9.0880839640e-001 + 70 -8.0624363211e-001 -4.1481075357e-001 4.2178578024e-001 + 71 4.3795259470e-001 -1.8510098086e-001 -8.7973584199e-001 + 72 -1.5027889784e-002 -9.1369083993e-001 4.0613201248e-001 + 73 -9.0025120847e-001 3.4407210496e-001 2.6676234412e-001 + 74 4.3272357138e-001 -8.5322281856e-001 2.9113765242e-001 + 75 3.4013028882e-001 3.4554586209e-001 -8.7459101517e-001 + 76 6.3400658296e-001 -2.6398803555e-001 -7.2687410867e-001 + 77 5.8746757232e-001 -6.4963779866e-001 -4.8254801008e-001 + 78 6.3220537442e-001 -7.2041958417e-001 -2.8515256845e-001 + 79 6.1445518691e-001 -8.5064272394e-003 -7.8890586509e-001 + 80 -8.2584394394e-001 2.6935165591e-001 4.9541040130e-001 + 81 -4.7154436625e-001 6.3748511379e-001 -6.0930997067e-001 + 82 -2.5239313945e-001 6.4085225094e-001 -7.2498696238e-001 + 83 -8.2966220924e-001 1.5352715501e-002 5.5805457859e-001 + 84 6.5410592921e-001 -7.5490453717e-001 -4.7587531276e-002 + 85 -2.8201410983e-003 6.1842295298e-001 -7.8584037694e-001 + 86 6.2486423703e-001 -4.8250458311e-001 -6.1378661810e-001 + 87 2.5696448116e-001 5.7288248623e-001 -7.7831543245e-001 + 88 -8.1218656949e-001 5.6347397943e-001 1.5116233276e-001 + 89 -8.7369793748e-002 -8.1025684856e-001 5.7952597742e-001 + 90 5.7068811051e-001 2.5578395081e-001 -7.8031381574e-001 + 91 -7.6346217996e-001 5.0944753202e-001 3.9697444740e-001 + 92 -6.5077284802e-001 6.0550401670e-001 -4.5810433967e-001 + 93 -7.7306115423e-001 -2.3055641419e-001 5.9094855250e-001 + 94 -4.9841122826e-001 -6.1945974753e-001 6.0651122722e-001 + 95 6.3926649234e-001 -7.4171729641e-001 2.0296256792e-001 + 96 3.6757234885e-001 -7.7781971756e-001 5.0979118797e-001 + 97 -6.5895972301e-001 -4.4607262595e-001 6.0563297122e-001 + 98 1.4325750234e-001 -8.1981605706e-001 5.5441764097e-001 + 99 -3.0547906676e-001 -7.4333638162e-001 5.9509122287e-001 + 100 -8.1302973549e-001 5.7489997520e-001 -9.2047095163e-002 + 101 5.0173363516e-001 4.9959627359e-001 -7.0616352410e-001 + 102 1.6357440760e-001 7.5074051027e-001 -6.4002507718e-001 + 103 -6.6615187504e-001 4.2208899400e-001 6.1488418464e-001 + 104 -4.9680214226e-001 7.7684054810e-001 -3.8691910560e-001 + 105 -6.8850531590e-001 -4.8669991478e-002 7.2359633906e-001 + 106 -6.4780917746e-001 7.1228578762e-001 2.7017073557e-001 + 107 5.8134888963e-001 -6.8424363475e-001 4.4027731809e-001 + 108 7.4757716153e-001 -5.3191362641e-001 -3.9773896163e-001 + 109 -7.7902497325e-001 5.5064527796e-001 -2.9984974389e-001 + 110 -7.0198144902e-001 1.8539303429e-001 6.8764196212e-001 + 111 -7.9482320075e-002 7.8282420394e-001 -6.1714570931e-001 + 112 7.5294067809e-001 1.5062594206e-001 -6.4061857673e-001 + 113 7.8003030611e-001 -9.9691244062e-002 -6.1774944549e-001 + 114 -2.9891027280e-001 7.9930383709e-001 -5.2131183070e-001 + 115 8.0327463800e-001 -5.7395041850e-001 -1.5915644207e-001 + 116 -6.6602361499e-001 7.0941197794e-001 -2.3053674290e-001 + 117 -1.4484880870e-001 -6.7320837454e-001 7.2512709718e-001 + 118 -5.7553635766e-001 6.3994511070e-001 5.0914453380e-001 + 119 -4.8568170235e-001 -4.3674175869e-001 7.5721193877e-001 + 120 2.7805761018e-001 -6.6942239290e-001 6.8888143051e-001 + 121 8.1084643047e-001 -5.7727742325e-001 9.6326750194e-002 + 122 -6.7562331730e-001 7.3705437105e-001 1.6851921038e-002 + 123 -6.1277713954e-001 -2.6282195281e-001 7.4527095635e-001 + 124 -3.2813585328e-001 -5.7700352691e-001 7.4792632774e-001 + 125 7.1029093661e-001 3.9241675326e-001 -5.8437648578e-001 + 126 7.8763261159e-001 -3.2593316736e-001 -5.2287899133e-001 + 127 6.7115215005e-002 -7.0430664974e-001 7.0671613187e-001 + 128 4.0345314921e-001 7.0386010322e-001 -5.8464220810e-001 + 129 4.8395829035e-001 -5.9485393679e-001 6.4182019841e-001 + 130 7.1476246371e-002 8.6890519745e-001 -4.8979067370e-001 + 131 -4.4014601343e-001 8.1451204843e-001 3.7794392419e-001 + 132 -4.6637564364e-001 5.3131733245e-001 7.0724511399e-001 + 133 8.8674590384e-001 -3.6464501102e-001 -2.8410511781e-001 + 134 7.6667369874e-001 -5.3873546529e-001 3.4924996507e-001 + 135 8.7226159298e-001 4.6085512494e-002 -4.8686326514e-001 + 136 6.2603049946e-001 6.1359444461e-001 -4.8123556735e-001 + 137 -3.0533531792e-001 -3.8996316153e-001 8.6873418045e-001 + 138 -3.5032059063e-001 7.1506087693e-001 6.0494911031e-001 + 139 -5.3542186731e-001 -9.6974193875e-002 8.3899906420e-001 + 140 9.2666147840e-001 -3.7486202766e-001 -2.7874085910e-002 + 141 -4.9077862160e-001 8.6220466987e-001 1.2545697208e-001 + 142 -4.2748285065e-001 -2.4152800168e-001 8.7116165940e-001 + 143 9.0383564974e-001 -1.5011428797e-001 -4.0068294049e-001 + 144 -4.5443993464e-003 -5.7929347161e-001 8.1510638703e-001 + 145 3.6444272802e-001 -4.6767385996e-001 8.0527179182e-001 + 146 -5.0583098702e-001 8.5213341242e-001 -1.3417771798e-001 + 147 -1.5730348072e-001 -5.0754343973e-001 8.4714536635e-001 + 148 2.7798218134e-001 8.5565028507e-001 -4.3656442424e-001 + 149 -3.1519132081e-001 9.0624439673e-001 -2.8173662291e-001 + 150 6.7412756122e-001 -4.6299876235e-001 5.7548603568e-001 + 151 -5.2899464158e-001 3.1493823587e-001 7.8802193926e-001 + 152 -1.1459129853e-001 9.0765014756e-001 -4.0378217387e-001 + 153 8.6491478375e-001 2.5482459732e-001 -4.3241975145e-001 + 154 -5.3975329050e-001 1.0060967750e-001 8.3578949394e-001 + 155 5.4280217319e-001 -3.8976869036e-001 7.4393962712e-001 + 156 9.0564157203e-001 -3.5329991019e-001 2.3450483253e-001 + 157 1.7467873233e-001 -5.3773165727e-001 8.2482240830e-001 + 158 2.1755574232e-001 -3.1783593593e-001 9.2284875078e-001 + 159 3.0386121111e-002 -4.1742612258e-001 9.0820268433e-001 + 160 4.9885362481e-001 7.9456342494e-001 -3.4614162529e-001 + 161 -2.3419031039e-001 5.6924504761e-001 7.8810847876e-001 + 162 1.0221912533e-001 9.4995480390e-001 -2.9518997436e-001 + 163 -2.0784951151e-001 8.5806168985e-001 4.6960485194e-001 + 164 9.5608422718e-001 6.5079397569e-002 -2.8577547576e-001 + 165 9.7519509036e-001 -1.5379065595e-001 -1.5919475455e-001 + 166 -2.7315486208e-001 9.3429193926e-001 2.2909603567e-001 + 167 -3.6242754991e-001 -2.0873752729e-002 9.3177816969e-001 + 168 -1.3047786374e-001 -3.4087350736e-001 9.3101062242e-001 + 169 8.2235013583e-001 -2.9802259148e-001 4.8468834220e-001 + 170 -3.0496782519e-001 9.5199768735e-001 -2.6363400311e-002 + 171 8.0872473008e-001 4.7686786548e-001 -3.4432738756e-001 + 172 -3.3914429640e-001 2.0391199862e-001 9.1836868579e-001 + 173 4.2917126284e-001 -2.1995409205e-001 8.7603209105e-001 + 174 -3.4642575363e-001 4.0411990207e-001 8.4656736411e-001 + 175 -1.0191121773e-001 9.8026159568e-001 -1.6941460308e-001 + 176 -2.2523829260e-001 -1.8017704166e-001 9.5749879645e-001 + 177 6.6524197910e-001 -1.7559885251e-001 7.2568460934e-001 + 178 9.8497493578e-001 -1.4096669826e-001 9.9763549839e-002 + 179 -1.0674019147e-001 7.2749022712e-001 6.7776434029e-001 + 180 -9.4939398149e-002 6.2534756458e-002 9.9351694244e-001 + 181 -1.3398596295e-001 3.5037962265e-001 9.2697458529e-001 + 182 1.0934542329e-002 -1.9785497401e-001 9.8017031431e-001 + 183 9.3580142189e-001 2.9501178640e-001 -1.9298638471e-001 + 184 3.2954098528e-001 9.2257332088e-001 -2.0065195394e-001 + 185 1.2929539539e-001 9.8965041305e-001 -6.2247575744e-002 + 186 9.9572933888e-001 8.1703957969e-002 -4.2983100746e-002 + 187 6.9914654273e-001 6.7834970267e-001 -2.2591102823e-001 + 188 -7.9211950408e-002 9.9381961187e-001 7.7769183964e-002 + 189 5.3154081678e-003 5.3810740567e-001 8.4285951759e-001 + 190 2.1214441981e-001 -4.6844978914e-002 9.7611489749e-001 + 191 2.9946621019e-002 8.4557229173e-001 5.3302035547e-001 + 192 9.2907635791e-001 -1.0790610017e-001 3.5379852277e-001 + 193 3.5368839144e-001 9.3388635307e-001 5.2543327906e-002 + 194 8.5414609729e-001 5.1219308478e-001 -8.9959370827e-002 + 195 1.6505112841e-001 2.7066980276e-001 9.4841762050e-001 + 196 9.4842042854e-001 3.1162067738e-001 5.8234389837e-002 + 197 -4.7331933657e-002 9.4717143816e-001 3.1721594347e-001 + 198 1.4009252710e-001 6.9526023421e-001 7.0497325522e-001 + 199 4.6038588478e-001 6.6553316561e-002 8.8522059011e-001 + 200 9.7207488626e-001 9.9975178755e-002 2.1230963034e-001 + 201 8.1909295256e-001 -5.9199497295e-002 5.7059806746e-001 + 202 5.4331785983e-001 8.3502169681e-001 -8.6858903120e-002 + 203 1.5552273831e-001 9.1149717604e-001 3.8076971511e-001 + 204 2.7684249080e-001 7.9964379834e-001 5.3284897585e-001 + 205 1.4883265750e-001 9.7308840487e-001 1.7591985778e-001 + 206 6.8893981233e-001 1.7057213790e-001 7.0446226354e-001 + 207 3.5264414356e-001 8.8484565300e-001 3.0445078153e-001 + 208 2.3457364817e-001 5.0626842543e-001 8.2985991890e-001 + 209 8.4546280110e-001 5.1216150880e-001 1.5127207561e-001 + 210 8.7822131047e-001 1.3381294239e-001 4.5915294433e-001 + 211 4.4037835518e-001 3.5780517792e-001 8.2343327534e-001 + 212 7.1981055620e-001 6.9335424893e-001 3.3654846195e-002 + 213 9.0026101587e-001 3.1672430760e-001 2.9869016769e-001 + 214 3.8355234225e-001 6.1560158159e-001 6.8842014315e-001 + 215 5.4745194298e-001 8.1735007238e-001 1.7954172026e-001 + 216 7.9989801697e-001 4.8805249031e-001 3.4923907162e-001 + 217 5.1465387399e-001 7.2024765471e-001 4.6516094620e-001 + 218 7.7819737599e-001 3.5571907472e-001 5.1756427996e-001 + 219 5.9152772158e-001 4.7595936482e-001 6.5081305890e-001 + 220 6.9837896181e-001 6.5999490402e-001 2.7689989595e-001 + 221 6.8305943980e-001 5.5799011314e-001 4.7125028948e-001 + 222 0.0000000000e+000 -4.5034168076e-001 -5.6728845373e-001 + 223 0.0000000000e+000 -6.3537561488e-001 -4.6094725735e-001 + 224 0.0000000000e+000 -2.2890668139e-001 -3.8095007324e-001 + 225 0.0000000000e+000 -2.3706992798e-001 -6.7134463345e-001 + 226 0.0000000000e+000 -6.9992435747e-001 -2.4458708052e-001 + 227 0.0000000000e+000 -4.5345977374e-001 -2.7878943355e-001 + 228 -2.3432151346e-001 0.0000000000e+000 -3.6605910945e-001 + 229 -6.7719523420e-001 0.0000000000e+000 -2.5472507455e-001 + 230 -5.1855179730e-001 0.0000000000e+000 -5.0909302141e-001 + 231 -2.5711637389e-001 0.0000000000e+000 -6.5705385194e-001 + 232 -4.3254383779e-001 0.0000000000e+000 -2.3215638322e-001 + 233 -6.6573071360e-001 -2.5443204529e-001 0.0000000000e+000 + 234 -3.9889376330e-001 -2.2484389352e-001 0.0000000000e+000 + 235 -1.7682713312e-001 -1.7684703930e-001 0.0000000000e+000 + 236 -2.5439157893e-001 -6.6573400483e-001 0.0000000000e+000 + 237 -2.2478902859e-001 -3.9888835698e-001 0.0000000000e+000 + 238 -5.1176337056e-001 -5.1178193067e-001 0.0000000000e+000 + 239 4.5785188675e-001 2.6312454045e-001 -2.3159828037e-002 + 240 1.7173628602e-001 -1.6032659821e-001 3.0873429403e-001 + 241 4.5785188675e-001 -3.7777449191e-001 -1.1471683532e-001 + 242 2.7473790944e-001 -1.1546459049e-002 -2.3159828037e-002 + 243 5.2651962638e-001 -3.4435711801e-002 2.2862192243e-001 + 244 -4.5771813393e-001 4.4623854756e-001 -2.3159828037e-002 + 245 6.6909939051e-005 2.6312454045e-001 -1.1471683532e-001 + 246 -9.1490097344e-002 2.6312454045e-001 2.5151117146e-001 + 247 -6.8600846455e-002 -3.5488524288e-001 2.2862192243e-001 + 248 -4.5771813393e-001 -1.0310346633e-001 3.4306816757e-001 + 249 -4.1193963587e-001 2.1734604239e-001 2.2618673742e-002 + 250 -4.1193963587e-001 3.4232042730e-002 2.0573267341e-001 + 251 2.2895941138e-001 1.2578904256e-001 -1.6049534082e-001 + 252 2.2895941138e-001 -5.7324964553e-002 -4.3516637385e-001 + 253 1.3740241155e-001 2.1734604239e-001 -3.4360936284e-001 + 254 -1.3726860285e-001 2.1734604239e-001 2.2618673742e-002 + 255 -1.3726860285e-001 3.4232042730e-002 2.0573267341e-001 + 256 2.2895941138e-001 -2.8621748835e-001 2.2618673742e-002 + 257 -5.0349664688e-001 -3.3199599385e-001 2.0573267341e-001 + 258 -3.2038262486e-001 -3.3199599385e-001 2.0573267341e-001 + 259 9.1623911634e-002 -6.0666701198e-001 2.0573267341e-001 + 260 5.0363038480e-001 -4.2355300486e-001 2.0573267341e-001 + 261 -3.2038262486e-001 -3.3199599385e-001 3.8884666562e-001 + 262 -3.2038262486e-001 -5.1511001587e-001 2.0573267341e-001 + 263 1.3740241155e-001 5.3779555112e-001 -1.6049534082e-001 + 264 -2.2882561386e-001 1.2578904256e-001 5.7196068764e-001 + 265 5.9518736601e-001 -1.4888197184e-001 -2.5205235183e-001 + 266 -3.2038262486e-001 4.0046003461e-001 5.7196068764e-001 + 267 2.2895941138e-001 -1.9466047920e-001 5.7196068764e-001 + 268 -1.3726860285e-001 5.8357405663e-001 2.9728966951e-001 + 269 -1.3726860285e-001 7.6668810844e-001 2.2618673742e-002 + 270 4.5845411718e-002 -5.7324964553e-002 5.7196068764e-001 + 271 4.5845411718e-002 -3.3199599385e-001 5.7196068764e-001 + 272 -1.3726860285e-001 5.8357405663e-001 -1.6049534082e-001 + 273 -1.3726860285e-001 5.8357405663e-001 2.2618673742e-002 + 274 -7.6175699580e-002 2.9546118346e-001 6.7861773474e-001 + 275 -1.3726860285e-001 -1.4888197184e-001 5.7196068764e-001 + 276 5.9518736601e-001 -1.4888197184e-001 2.2618673742e-002 + 277 5.9518736601e-001 3.4232042730e-002 2.2618673742e-002 + 278 4.5845411718e-002 5.8357405663e-001 2.0573267341e-001 + 279 9.9150924083e-002 1.9148376846e-001 6.8600878620e-001 + 280 4.5845411718e-002 5.8357405663e-001 2.2618673742e-002 + 281 2.2895941138e-001 4.9201704562e-001 2.0573267341e-001 + 282 5.9518736601e-001 2.1734604239e-001 2.0573267341e-001 + 283 2.7473790944e-001 1.2578904256e-001 2.5151117146e-001 + 284 2.2895941138e-001 -6.9822400808e-001 2.2618673742e-002 + 285 -6.8661063910e-001 2.1734604239e-001 2.2618673742e-002 + 286 -6.8661063910e-001 3.4232042730e-002 2.0573267341e-001 + 287 -1.3726860285e-001 2.1734604239e-001 -5.2672338486e-001 + 288 -5.0349664688e-001 2.1734604239e-001 -1.6049534082e-001 + 289 -5.0349664688e-001 2.1734604239e-001 -3.4360936284e-001 + 290 -3.2038262486e-001 2.1734604239e-001 -3.4360936284e-001 + 291 -3.2038262486e-001 4.0046003461e-001 -3.4360936284e-001 + 292 5.9518736601e-001 1.2578904256e-001 -1.6049534082e-001 + 293 2.2895941138e-001 2.1734604239e-001 2.2618673742e-002 + 294 -1.3726860285e-001 -1.4888197184e-001 2.0573267341e-001 + 295 -3.2038262486e-001 -1.4888197184e-001 2.0573267341e-001 + 296 -1.3726860285e-001 -1.4888197184e-001 3.8884666562e-001 + 297 2.2895941138e-001 -5.1511001587e-001 -2.5205235183e-001 + 298 2.2895941138e-001 -1.9466047734e-001 -2.5205235183e-001 + 299 2.2895941138e-001 -3.3199599385e-001 3.8884666562e-001 + 300 -1.3726860285e-001 2.1734604239e-001 -1.6049534082e-001 + 301 -3.2038262486e-001 2.1734604239e-001 -1.6049534082e-001 + 302 -1.3726860285e-001 4.0046003461e-001 -1.6049534082e-001 + 303 -1.3726860285e-001 2.1734604239e-001 -3.4360936284e-001 + 304 -1.3726860285e-001 -5.1511001587e-001 2.0573267341e-001 + 305 -1.3726860285e-001 -5.1511001587e-001 3.8884666562e-001 + 306 -5.0349664688e-001 -1.4888197184e-001 2.0573267341e-001 + 307 3.8762960704e-002 5.2640076413e-001 5.5749703743e-001 + 308 1.7155903653e-001 5.0791188870e-001 7.1839229659e-001 + 309 5.7874565354e-002 -5.4497430020e-001 4.6074580343e-001 +ENDOFSECTION + ELEMENTS/CELLS 1.3.0 + 1 6 4 122 146 244 116 + 2 6 4 270 296 240 299 + 3 6 4 291 92 109 116 + 4 6 4 293 254 4 246 + 5 6 4 38 289 230 290 + 6 6 4 100 122 244 116 + 7 6 4 282 292 239 194 + 8 6 4 238 42 48 257 + 9 6 4 71 29 252 68 + 10 6 4 307 308 279 283 + 11 6 4 90 75 253 101 + 12 6 4 91 106 118 244 + 13 6 4 285 45 286 73 + 14 6 4 40 12 1 46 + 15 6 4 271 182 270 275 + 16 6 4 243 276 256 242 + 17 6 4 268 106 244 118 + 18 6 4 263 185 162 175 + 19 6 4 232 228 230 290 + 20 6 4 27 236 238 48 + 21 6 4 220 281 217 215 + 22 6 4 291 82 81 114 + 23 6 4 266 110 250 264 + 24 6 4 266 110 103 250 + 25 6 4 103 286 91 250 + 26 6 4 117 144 271 147 + 27 6 4 121 276 241 260 + 28 6 4 97 119 94 261 + 29 6 4 243 178 277 200 + 30 6 4 12 69 75 46 + 31 6 4 181 172 174 274 + 32 6 4 111 82 291 114 + 33 6 4 281 207 217 215 + 34 6 4 234 238 257 233 + 35 6 4 7 222 223 32 + 36 6 4 241 115 140 121 + 37 6 4 219 282 283 281 + 38 6 4 5 225 6 30 + 39 6 4 111 82 85 287 + 40 6 4 283 206 243 282 + 41 6 4 283 206 279 267 + 42 6 4 51 285 35 66 + 43 6 4 194 292 196 282 + 44 6 4 265 108 241 86 + 45 6 4 292 253 136 125 + 46 6 4 38 18 230 37 + 47 6 4 49 44 2 21 + 48 6 4 282 292 277 239 + 49 6 4 187 292 136 171 + 50 6 4 283 206 219 279 + 51 6 4 222 53 32 31 + 52 6 4 148 128 160 263 + 53 6 4 210 201 243 192 + 54 6 4 261 304 305 262 + 55 6 4 206 177 267 243 + 56 6 4 128 263 253 136 + 57 6 4 50 304 259 21 + 58 6 4 128 136 160 263 + 59 6 4 252 71 79 76 + 60 6 4 124 117 305 271 + 61 6 4 236 262 238 48 + 62 6 4 261 271 305 247 + 63 6 4 309 96 259 299 + 64 6 4 182 267 271 270 + 65 6 4 245 300 10 4 + 66 6 4 275 296 271 261 + 67 6 4 29 71 252 30 + 68 6 4 262 56 94 261 + 69 6 4 45 286 65 41 + 70 6 4 158 145 267 173 + 71 6 4 264 279 246 274 + 72 6 4 216 221 282 218 + 73 6 4 283 206 282 219 + 74 6 4 73 45 286 65 + 75 6 4 165 178 186 277 + 76 6 4 284 256 259 260 + 77 6 4 157 145 267 158 + 78 6 4 150 177 169 243 + 79 6 4 206 282 210 243 + 80 6 4 292 265 277 242 + 81 6 4 266 307 274 246 + 82 6 4 75 287 253 87 + 83 6 4 161 307 189 274 + 84 6 4 202 239 187 212 + 85 6 4 267 206 243 283 + 86 6 4 292 196 186 183 + 87 6 4 101 128 253 136 + 88 6 4 289 232 230 290 + 89 6 4 241 133 140 115 + 90 6 4 163 307 268 191 + 91 6 4 227 298 297 224 + 92 6 4 234 14 295 15 + 93 6 4 287 111 291 272 + 94 6 4 166 141 268 131 + 95 6 4 293 280 281 263 + 96 6 4 23 227 224 298 + 97 6 4 278 269 205 280 + 98 6 4 282 194 239 212 + 99 6 4 275 180 264 167 + 100 6 4 34 9 226 33 + 101 6 4 95 121 260 134 + 102 6 4 275 176 182 180 + 103 6 4 260 84 284 241 + 104 6 4 252 68 90 79 + 105 6 4 177 199 206 267 + 106 6 4 300 302 303 290 + 107 6 4 86 241 265 297 + 108 6 4 32 222 31 7 + 109 6 4 240 270 299 267 + 110 6 4 295 14 306 250 + 111 6 4 214 281 217 219 + 112 6 4 102 287 253 263 + 113 6 4 268 106 141 244 + 114 6 4 204 308 214 198 + 115 6 4 157 158 267 271 + 116 6 4 182 267 158 271 + 117 6 4 4 246 254 255 + 118 6 4 191 278 307 268 + 119 6 4 278 269 268 197 + 120 6 4 185 263 184 193 + 121 6 4 266 307 246 268 + 122 6 4 29 12 252 68 + 123 6 4 244 268 118 266 + 124 6 4 292 263 136 253 + 125 6 4 222 53 297 32 + 126 6 4 222 52 252 297 + 127 6 4 260 276 241 256 + 128 6 4 111 272 263 152 + 129 6 4 97 56 70 257 + 130 6 4 284 256 22 259 + 131 6 4 207 203 281 204 + 132 6 4 257 262 258 261 + 133 6 4 13 233 286 41 + 134 6 4 189 307 308 279 + 135 6 4 287 12 253 11 + 136 6 4 20 231 39 19 + 137 6 4 263 287 111 102 + 138 6 4 245 4 10 251 + 139 6 4 289 36 37 229 + 140 6 4 291 301 288 290 + 141 6 4 34 33 226 284 + 142 6 4 91 103 266 118 + 143 6 4 10 242 23 298 + 144 6 4 204 308 307 281 + 145 6 4 276 265 277 165 + 146 6 4 279 190 270 267 + 147 6 4 134 150 169 260 + 148 6 4 281 202 193 215 + 149 6 4 251 298 252 265 + 150 6 4 234 257 258 306 + 151 6 4 261 304 247 305 + 152 6 4 249 246 255 254 + 153 6 4 95 284 260 84 + 154 6 4 252 253 10 251 + 155 6 4 207 281 193 215 + 156 6 4 260 95 107 74 + 157 6 4 96 260 129 107 + 158 6 4 308 189 198 307 + 159 6 4 242 293 239 251 + 160 6 4 253 245 10 251 + 161 6 4 291 146 116 244 + 162 6 4 75 12 46 68 + 163 6 4 282 194 209 196 + 164 6 4 242 23 298 256 + 165 6 4 203 278 205 281 + 166 6 4 100 285 51 66 + 167 6 4 269 188 197 205 + 168 6 4 285 14 288 249 + 169 6 4 281 205 193 280 + 170 6 4 244 301 249 288 + 171 6 4 291 289 59 290 + 172 6 4 279 181 274 180 + 173 6 4 188 166 269 197 + 174 6 4 300 303 228 290 + 175 6 4 292 90 253 125 + 176 6 4 296 240 294 255 + 177 6 4 307 204 198 308 + 178 6 4 281 293 283 246 + 179 6 4 25 47 233 24 + 180 6 4 191 179 307 198 + 181 6 4 287 291 59 290 + 182 6 4 179 189 307 198 + 183 6 4 291 244 288 301 + 184 6 4 253 101 136 125 + 185 6 4 163 307 138 268 + 186 6 4 301 14 249 288 + 187 6 4 161 179 189 307 + 188 6 4 139 275 142 248 + 189 6 4 84 78 55 241 + 190 6 4 296 275 248 261 + 191 6 4 251 265 292 242 + 192 6 4 242 241 298 265 + 193 6 4 291 146 104 116 + 194 6 4 279 307 274 189 + 195 6 4 55 84 241 284 + 196 6 4 148 102 263 130 + 197 6 4 90 101 253 125 + 198 6 4 232 301 15 228 + 199 6 4 272 302 291 303 + 200 6 4 293 280 246 281 + 201 6 4 200 243 282 277 + 202 6 4 301 300 228 290 + 203 6 4 279 181 189 274 + 204 6 4 61 236 262 304 + 205 6 4 308 281 283 307 + 206 6 4 278 246 307 268 + 207 6 4 97 257 248 261 + 208 6 4 221 219 217 281 + 209 6 4 296 270 271 299 + 210 6 4 251 4 242 293 + 211 6 4 4 294 255 15 + 212 6 4 36 285 35 229 + 213 6 4 166 269 141 170 + 214 6 4 294 261 247 296 + 215 6 4 265 298 242 251 + 216 6 4 293 254 245 4 + 217 6 4 294 261 258 247 + 218 6 4 302 249 244 301 + 219 6 4 308 281 219 283 + 220 6 4 222 52 30 252 + 221 6 4 195 308 279 189 + 222 6 4 97 56 261 94 + 223 6 4 74 259 63 96 + 224 6 4 274 264 266 246 + 225 6 4 10 242 4 23 + 226 6 4 102 287 111 85 + 227 6 4 292 90 252 253 + 228 6 4 292 242 277 239 + 229 6 4 60 69 85 287 + 230 6 4 103 132 266 118 + 231 6 4 204 217 214 281 + 232 6 4 244 91 266 118 + 233 6 4 307 203 281 278 + 234 6 4 307 203 204 281 + 235 6 4 75 252 253 12 + 236 6 4 253 263 245 251 + 237 6 4 275 168 147 271 + 238 6 4 260 84 121 95 + 239 6 4 97 119 261 123 + 240 6 4 153 292 112 135 + 241 6 4 195 308 211 279 + 242 6 4 10 242 251 4 + 243 6 4 129 150 299 267 + 244 6 4 271 117 147 124 + 245 6 4 203 205 207 281 + 246 6 4 161 266 307 274 + 247 6 4 264 275 270 180 + 248 6 4 298 252 10 251 + 249 6 4 272 170 244 269 + 250 6 4 15 294 235 4 + 251 6 4 10 242 298 251 + 252 6 4 272 269 244 273 + 253 6 4 304 262 258 237 + 254 6 4 152 263 162 175 + 255 6 4 227 22 226 297 + 256 6 4 302 249 254 273 + 257 6 4 185 269 263 280 + 258 6 4 292 252 265 251 + 259 6 4 126 86 265 76 + 260 6 4 55 78 297 241 + 261 6 4 242 240 283 4 + 262 6 4 78 241 84 115 + 263 6 4 262 238 258 237 + 264 6 4 75 252 90 253 + 265 6 4 242 23 240 4 + 266 6 4 153 292 135 164 + 267 6 4 272 269 273 280 + 268 6 4 166 163 131 268 + 269 6 4 225 222 6 30 + 270 6 4 183 194 171 292 + 271 6 4 194 187 292 239 + 272 6 4 287 272 291 303 + 273 6 4 289 36 57 37 + 274 6 4 264 174 266 151 + 275 6 4 247 304 259 305 + 276 6 4 223 33 32 297 + 277 6 4 261 137 124 275 + 278 6 4 297 256 284 241 + 279 6 4 243 299 150 267 + 280 6 4 285 91 88 73 + 281 6 4 242 240 256 243 + 282 6 4 103 132 151 266 + 283 6 4 300 301 15 254 + 284 6 4 287 69 85 87 + 285 6 4 269 166 268 197 + 286 6 4 205 269 185 280 + 287 6 4 301 249 15 254 + 288 6 4 281 246 307 278 + 289 6 4 280 254 246 273 + 290 6 4 93 257 248 97 + 291 6 4 262 56 48 62 + 292 6 4 40 287 39 231 + 293 6 4 260 150 243 299 + 294 6 4 302 291 303 290 + 295 6 4 53 77 297 54 + 296 6 4 279 190 180 270 + 297 6 4 28 2 21 50 + 298 6 4 56 262 94 62 + 299 6 4 166 269 268 141 + 300 6 4 14 295 15 250 + 301 6 4 281 263 280 193 + 302 6 4 265 165 143 164 + 303 6 4 305 124 271 261 + 304 6 4 113 126 265 76 + 305 6 4 194 187 171 292 + 306 6 4 278 205 281 280 + 307 6 4 238 262 258 257 + 308 6 4 138 268 118 131 + 309 6 4 283 246 307 281 + 310 6 4 248 64 286 306 + 311 6 4 279 246 274 307 + 312 6 4 264 279 270 246 + 313 6 4 292 125 136 171 + 314 6 4 234 235 258 237 + 315 6 4 130 111 263 152 + 316 6 4 117 309 89 305 + 317 6 4 279 246 283 270 + 318 6 4 202 239 263 187 + 319 6 4 18 38 230 19 + 320 6 4 100 285 288 244 + 321 6 4 234 295 258 235 + 322 6 4 289 229 37 230 + 323 6 4 291 146 272 104 + 324 6 4 279 246 307 283 + 325 6 4 291 146 244 272 + 326 6 4 5 225 30 29 + 327 6 4 281 282 221 219 + 328 6 4 87 287 69 75 + 329 6 4 33 223 8 226 + 330 6 4 217 220 221 281 + 331 6 4 291 289 109 92 + 332 6 4 111 272 152 114 + 333 6 4 58 289 92 57 + 334 6 4 291 302 244 301 + 335 6 4 287 253 263 303 + 336 6 4 244 285 288 249 + 337 6 4 272 302 244 291 + 338 6 4 242 243 283 240 + 339 6 4 164 265 165 292 + 340 6 4 307 204 191 198 + 341 6 4 38 231 230 19 + 342 6 4 300 302 245 303 + 343 6 4 259 44 21 284 + 344 6 4 287 12 11 231 + 345 6 4 101 75 253 87 + 346 6 4 269 185 263 175 + 347 6 4 187 263 292 239 + 348 6 4 146 122 244 141 + 349 6 4 291 244 109 288 + 350 6 4 232 289 230 229 + 351 6 4 238 234 258 237 + 352 6 4 239 283 293 242 + 353 6 4 242 283 277 239 + 354 6 4 121 134 156 260 + 355 6 4 91 250 249 266 + 356 6 4 281 308 214 204 + 357 6 4 241 78 108 115 + 358 6 4 256 276 241 242 + 359 6 4 195 308 208 211 + 360 6 4 260 96 129 299 + 361 6 4 12 29 1 46 + 362 6 4 102 287 87 253 + 363 6 4 12 40 1 20 + 364 6 4 307 203 191 204 + 365 6 4 307 203 278 191 + 366 6 4 203 197 278 191 + 367 6 4 47 64 257 306 + 368 6 4 297 256 22 284 + 369 6 4 168 275 147 137 + 370 6 4 227 223 297 226 + 371 6 4 227 256 297 298 + 372 6 4 42 238 48 26 + 373 6 4 197 268 278 191 + 374 6 4 260 150 299 129 + 375 6 4 291 302 301 290 + 376 6 4 15 4 254 255 + 377 6 4 20 40 39 231 + 378 6 4 104 272 291 114 + 379 6 4 82 287 291 59 + 380 6 4 22 304 247 237 + 381 6 4 208 214 308 198 + 382 6 4 265 292 277 165 + 383 6 4 302 272 273 280 + 384 6 4 208 198 308 189 + 385 6 4 283 281 239 293 + 386 6 4 302 300 301 290 + 387 6 4 264 279 180 270 + 388 6 4 82 291 81 59 + 389 6 4 293 254 280 245 + 390 6 4 272 302 263 280 + 391 6 4 136 187 160 263 + 392 6 4 269 272 263 280 + 393 6 4 124 305 99 94 + 394 6 4 249 15 255 250 + 395 6 4 139 275 248 264 + 396 6 4 273 278 280 269 + 397 6 4 166 188 269 170 + 398 6 4 104 291 116 92 + 399 6 4 104 291 81 114 + 400 6 4 15 300 10 228 + 401 6 4 279 190 195 180 + 402 6 4 252 297 298 224 + 403 6 4 265 165 133 143 + 404 6 4 192 156 169 243 + 405 6 4 243 177 201 206 + 406 6 4 256 299 259 260 + 407 6 4 241 78 297 77 + 408 6 4 222 52 31 30 + 409 6 4 222 31 6 30 + 410 6 4 133 241 108 115 + 411 6 4 279 181 195 189 + 412 6 4 53 86 297 77 + 413 6 4 225 29 252 30 + 414 6 4 252 79 112 265 + 415 6 4 223 227 297 222 + 416 6 4 172 264 274 180 + 417 6 4 135 292 112 265 + 418 6 4 247 271 296 261 + 419 6 4 266 174 274 161 + 420 6 4 113 135 112 265 + 421 6 4 283 281 282 239 + 422 6 4 291 104 81 92 + 423 6 4 279 181 180 195 + 424 6 4 181 189 274 161 + 425 6 4 296 255 264 270 + 426 6 4 174 181 274 161 + 427 6 4 287 11 228 231 + 428 6 4 267 190 158 173 + 429 6 4 102 287 85 87 + 430 6 4 80 286 83 65 + 431 6 4 302 272 263 303 + 432 6 4 303 263 302 245 + 433 6 4 188 269 185 205 + 434 6 4 201 192 169 243 + 435 6 4 163 307 179 138 + 436 6 4 301 300 15 228 + 437 6 4 138 161 307 179 + 438 6 4 224 10 298 252 + 439 6 4 79 113 112 265 + 440 6 4 266 161 307 138 + 441 6 4 249 246 268 266 + 442 6 4 187 263 136 292 + 443 6 4 231 38 39 19 + 444 6 4 264 246 250 266 + 445 6 4 91 285 88 244 + 446 6 4 102 128 263 253 + 447 6 4 266 138 307 268 + 448 6 4 309 259 98 89 + 449 6 4 246 249 250 266 + 450 6 4 205 185 193 280 + 451 6 4 234 238 258 257 + 452 6 4 200 210 213 282 + 453 6 4 309 96 98 259 + 454 6 4 308 281 214 219 + 455 6 4 279 190 267 199 + 456 6 4 246 249 268 273 + 457 6 4 120 309 271 299 + 458 6 4 292 252 112 265 + 459 6 4 286 64 65 41 + 460 6 4 289 36 66 57 + 461 6 4 249 246 254 273 + 462 6 4 223 33 8 32 + 463 6 4 289 66 288 109 + 464 6 4 280 254 302 245 + 465 6 4 262 62 61 305 + 466 6 4 281 202 263 193 + 467 6 4 22 226 297 284 + 468 6 4 238 27 48 26 + 469 6 4 178 200 186 277 + 470 6 4 206 282 218 210 + 471 6 4 36 16 17 229 + 472 6 4 206 282 219 218 + 473 6 4 93 257 64 248 + 474 6 4 181 172 274 180 + 475 6 4 256 299 247 259 + 476 6 4 93 257 70 64 + 477 6 4 246 249 255 250 + 478 6 4 51 285 88 73 + 479 6 4 93 257 97 70 + 480 6 4 262 236 237 304 + 481 6 4 248 264 110 105 + 482 6 4 9 33 8 226 + 483 6 4 23 235 237 247 + 484 6 4 271 120 299 267 + 485 6 4 77 78 297 54 + 486 6 4 117 309 127 89 + 487 6 4 33 34 55 284 + 488 6 4 103 286 80 91 + 489 6 4 302 272 244 273 + 490 6 4 308 219 279 283 + 491 6 4 100 285 88 51 + 492 6 4 199 279 206 267 + 493 6 4 232 14 301 288 + 494 6 4 120 309 127 271 + 495 6 4 56 42 70 257 + 496 6 4 60 287 59 39 + 497 6 4 161 132 138 266 + 498 6 4 295 248 258 261 + 499 6 4 199 190 267 173 + 500 6 4 266 103 91 250 + 501 6 4 259 260 96 74 + 502 6 4 264 279 274 180 + 503 6 4 132 174 151 266 + 504 6 4 271 120 157 127 + 505 6 4 255 283 246 270 + 506 6 4 207 205 193 281 + 507 6 4 289 38 230 37 + 508 6 4 244 291 109 116 + 509 6 4 245 300 4 254 + 510 6 4 272 170 146 244 + 511 6 4 60 287 39 40 + 512 6 4 272 104 149 114 + 513 6 4 304 262 61 305 + 514 6 4 120 299 267 129 + 515 6 4 229 285 35 13 + 516 6 4 259 304 50 61 + 517 6 4 284 226 21 22 + 518 6 4 216 209 213 282 + 519 6 4 309 96 120 98 + 520 6 4 305 62 61 99 + 521 6 4 291 58 81 59 + 522 6 4 293 4 245 251 + 523 6 4 302 245 263 280 + 524 6 4 270 255 240 296 + 525 6 4 269 188 175 170 + 526 6 4 287 38 59 39 + 527 6 4 259 89 72 98 + 528 6 4 11 287 228 303 + 529 6 4 100 244 109 116 + 530 6 4 143 135 265 164 + 531 6 4 50 259 61 72 + 532 6 4 159 158 271 182 + 533 6 4 240 4 255 283 + 534 6 4 202 239 281 263 + 535 6 4 285 91 73 286 + 536 6 4 309 89 305 259 + 537 6 4 124 117 99 305 + 538 6 4 49 259 50 72 + 539 6 4 275 124 147 137 + 540 6 4 264 275 296 270 + 541 6 4 7 31 6 222 + 542 6 4 82 60 287 59 + 543 6 4 252 86 297 52 + 544 6 4 225 11 224 252 + 545 6 4 259 89 61 72 + 546 6 4 56 262 48 257 + 547 6 4 61 236 43 262 + 548 6 4 159 157 271 158 + 549 6 4 252 225 30 222 + 550 6 4 23 22 256 247 + 551 6 4 22 304 259 247 + 552 6 4 5 12 225 29 + 553 6 4 69 60 40 287 + 554 6 4 12 69 40 287 + 555 6 4 298 23 10 224 + 556 6 4 95 284 74 260 + 557 6 4 146 170 141 244 + 558 6 4 248 295 258 306 + 559 6 4 124 275 271 261 + 560 6 4 58 291 81 92 + 561 6 4 49 259 21 50 + 562 6 4 248 110 250 286 + 563 6 4 236 27 28 43 + 564 6 4 61 236 50 43 + 565 6 4 309 89 98 127 + 566 6 4 45 285 51 73 + 567 6 4 139 264 248 105 + 568 6 4 308 219 214 211 + 569 6 4 117 309 305 271 + 570 6 4 227 256 22 297 + 571 6 4 264 139 154 105 + 572 6 4 263 148 184 160 + 573 6 4 233 47 286 41 + 574 6 4 242 241 265 276 + 575 6 4 58 38 289 37 + 576 6 4 58 289 57 37 + 577 6 4 294 23 240 247 + 578 6 4 9 34 21 2 + 579 6 4 232 301 290 288 + 580 6 4 305 262 94 261 + 581 6 4 62 262 94 305 + 582 6 4 202 263 184 160 + 583 6 4 93 248 105 123 + 584 6 4 297 256 241 298 + 585 6 4 47 233 286 306 + 586 6 4 262 62 43 61 + 587 6 4 117 89 99 305 + 588 6 4 145 155 267 173 + 589 6 4 275 137 176 142 + 590 6 4 248 139 105 123 + 591 6 4 276 165 178 140 + 592 6 4 289 232 290 288 + 593 6 4 287 231 228 290 + 594 6 4 210 192 243 200 + 595 6 4 172 264 180 167 + 596 6 4 289 291 109 288 + 597 6 4 163 307 191 179 + 598 6 4 182 267 190 158 + 599 6 4 275 124 271 147 + 600 6 4 155 177 267 173 + 601 6 4 14 285 13 286 + 602 6 4 14 232 229 288 + 603 6 4 268 106 131 141 + 604 6 4 110 80 286 83 + 605 6 4 244 100 109 288 + 606 6 4 270 283 240 255 + 607 6 4 247 309 271 305 + 608 6 4 250 264 110 248 + 609 6 4 275 182 168 271 + 610 6 4 309 96 299 120 + 611 6 4 78 55 297 54 + 612 6 4 57 289 92 109 + 613 6 4 252 71 68 79 + 614 6 4 135 292 265 164 + 615 6 4 277 196 292 282 + 616 6 4 49 259 63 44 + 617 6 4 308 211 279 219 + 618 6 4 260 74 107 96 + 619 6 4 250 285 249 14 + 620 6 4 102 128 253 87 + 621 6 4 260 259 284 74 + 622 6 4 308 211 214 208 + 623 6 4 292 90 112 252 + 624 6 4 259 49 63 72 + 625 6 4 289 38 59 290 + 626 6 4 299 243 260 256 + 627 6 4 216 221 220 282 + 628 6 4 240 267 283 270 + 629 6 4 38 287 59 290 + 630 6 4 250 248 286 306 + 631 6 4 128 101 253 87 + 632 6 4 243 192 178 200 + 633 6 4 229 37 230 17 + 634 6 4 138 132 118 266 + 635 6 4 287 38 231 290 + 636 6 4 14 232 301 15 + 637 6 4 269 188 185 175 + 638 6 4 42 56 48 257 + 639 6 4 252 222 297 224 + 640 6 4 113 135 265 143 + 641 6 4 252 10 11 224 + 642 6 4 2 49 21 50 + 643 6 4 284 256 260 241 + 644 6 4 285 45 51 35 + 645 6 4 238 25 26 42 + 646 6 4 231 38 230 290 + 647 6 4 236 28 50 43 + 648 6 4 225 252 224 222 + 649 6 4 295 234 258 306 + 650 6 4 261 304 258 247 + 651 6 4 261 304 262 258 + 652 6 4 253 252 10 11 + 653 6 4 240 296 247 299 + 654 6 4 125 292 153 171 + 655 6 4 195 308 189 208 + 656 6 4 249 302 254 301 + 657 6 4 263 251 253 292 + 658 6 4 247 309 299 271 + 659 6 4 264 296 250 255 + 660 6 4 304 237 258 247 + 661 6 4 267 299 240 243 + 662 6 4 302 300 254 301 + 663 6 4 252 86 265 297 + 664 6 4 298 256 241 242 + 665 6 4 260 259 96 299 + 666 6 4 277 196 186 292 + 667 6 4 117 309 271 127 + 668 6 4 263 185 184 162 + 669 6 4 262 236 238 237 + 670 6 4 292 165 186 277 + 671 6 4 196 200 213 282 + 672 6 4 277 196 200 186 + 673 6 4 279 283 267 270 + 674 6 4 292 183 153 171 + 675 6 4 285 100 288 66 + 676 6 4 102 148 263 128 + 677 6 4 166 163 268 197 + 678 6 4 111 287 263 272 + 679 6 4 289 232 288 229 + 680 6 4 245 263 253 303 + 681 6 4 276 178 277 243 + 682 6 4 279 199 211 195 + 683 6 4 263 293 251 239 + 684 6 4 249 14 301 15 + 685 6 4 242 293 4 283 + 686 6 4 182 267 270 190 + 687 6 4 4 246 255 283 + 688 6 4 235 295 258 294 + 689 6 4 89 305 61 99 + 690 6 4 293 246 4 283 + 691 6 4 259 44 284 74 + 692 6 4 270 275 296 271 + 693 6 4 79 113 265 76 + 694 6 4 250 14 306 286 + 695 6 4 82 111 291 287 + 696 6 4 100 66 109 288 + 697 6 4 272 111 291 114 + 698 6 4 253 287 11 303 + 699 6 4 175 272 269 170 + 700 6 4 170 272 149 175 + 701 6 4 222 53 52 297 + 702 6 4 272 152 149 175 + 703 6 4 152 272 263 175 + 704 6 4 244 269 268 273 + 705 6 4 7 223 8 32 + 706 6 4 120 309 98 127 + 707 6 4 296 295 248 250 + 708 6 4 145 157 267 120 + 709 6 4 294 296 247 240 + 710 6 4 264 172 154 167 + 711 6 4 24 47 233 41 + 712 6 4 202 187 263 160 + 713 6 4 207 281 217 204 + 714 6 4 23 4 294 240 + 715 6 4 304 259 305 61 + 716 6 4 212 281 215 202 + 717 6 4 34 67 284 44 + 718 6 4 134 150 260 107 + 719 6 4 252 71 76 52 + 720 6 4 212 220 215 281 + 721 6 4 282 212 239 281 + 722 6 4 292 251 239 263 + 723 6 4 281 212 220 282 + 724 6 4 139 264 154 167 + 725 6 4 262 236 43 48 + 726 6 4 234 257 306 233 + 727 6 4 14 234 306 233 + 728 6 4 49 259 44 21 + 729 6 4 233 286 306 14 + 730 6 4 33 55 297 284 + 731 6 4 14 286 13 233 + 732 6 4 133 126 265 143 + 733 6 4 276 241 265 140 + 734 6 4 262 238 48 257 + 735 6 4 228 231 230 290 + 736 6 4 300 303 10 228 + 737 6 4 229 36 37 17 + 738 6 4 61 236 304 50 + 739 6 4 291 287 303 290 + 740 6 4 265 108 133 241 + 741 6 4 281 263 239 293 + 742 6 4 225 12 252 29 + 743 6 4 4 300 10 15 + 744 6 4 305 124 261 94 + 745 6 4 110 264 154 105 + 746 6 4 305 62 99 94 + 747 6 4 287 12 75 253 + 748 6 4 300 245 10 303 + 749 6 4 156 276 178 140 + 750 6 4 75 252 68 90 + 751 6 4 69 12 75 287 + 752 6 4 62 262 43 48 + 753 6 4 12 29 46 68 + 754 6 4 303 287 228 290 + 755 6 4 227 256 23 22 + 756 6 4 245 253 10 303 + 757 6 4 252 79 265 76 + 758 6 4 252 71 52 30 + 759 6 4 256 243 240 299 + 760 6 4 303 11 10 228 + 761 6 4 86 252 76 52 + 762 6 4 252 86 76 265 + 763 6 4 91 80 73 286 + 764 6 4 235 294 258 247 + 765 6 4 42 47 70 257 + 766 6 4 264 296 248 250 + 767 6 4 119 124 94 261 + 768 6 4 237 235 258 247 + 769 6 4 64 93 248 83 + 770 6 4 296 295 261 248 + 771 6 4 286 110 83 248 + 772 6 4 277 196 282 200 + 773 6 4 13 3 24 41 + 774 6 4 304 236 237 22 + 775 6 4 56 97 261 257 + 776 6 4 64 47 257 70 + 777 6 4 93 97 248 123 + 778 6 4 262 56 261 257 + 779 6 4 121 276 260 156 + 780 6 4 257 64 248 306 + 781 6 4 64 47 286 306 + 782 6 4 283 282 277 239 + 783 6 4 265 276 277 242 + 784 6 4 275 264 296 248 + 785 6 4 272 170 149 146 + 786 6 4 243 242 283 277 + 787 6 4 266 110 151 103 + 788 6 4 264 174 274 266 + 789 6 4 209 196 213 282 + 790 6 4 250 285 91 249 + 791 6 4 45 285 13 35 + 792 6 4 104 146 272 149 + 793 6 4 152 272 149 114 + 794 6 4 264 246 255 250 + 795 6 4 67 84 55 284 + 796 6 4 244 249 268 266 + 797 6 4 240 243 283 267 + 798 6 4 281 282 220 221 + 799 6 4 247 309 305 259 + 800 6 4 264 246 270 255 + 801 6 4 199 279 211 206 + 802 6 4 91 244 266 249 + 803 6 4 263 202 184 193 + 804 6 4 130 148 162 263 + 805 6 4 67 34 284 55 + 806 6 4 272 269 263 175 + 807 6 4 152 130 162 263 + 808 6 4 44 67 284 74 + 809 6 4 256 299 240 247 + 810 6 4 243 276 242 277 + 811 6 4 241 298 265 297 + 812 6 4 292 112 125 153 + 813 6 4 199 190 195 279 + 814 6 4 265 108 126 133 + 815 6 4 216 218 282 213 + 816 6 4 111 102 130 263 + 817 6 4 243 210 200 282 + 818 6 4 283 243 277 282 + 819 6 4 177 201 169 243 + 820 6 4 212 209 220 282 + 821 6 4 265 108 86 126 + 822 6 4 260 150 169 243 + 823 6 4 163 268 197 191 + 824 6 4 145 155 129 267 + 825 6 4 285 45 13 286 + 826 6 4 80 73 286 65 + 827 6 4 42 47 257 233 + 828 6 4 271 120 267 157 + 829 6 4 103 286 110 80 + 830 6 4 156 276 260 243 + 831 6 4 236 27 43 48 + 832 6 4 156 260 169 243 + 833 6 4 270 182 180 275 + 834 6 4 300 245 302 254 + 835 6 4 268 138 118 266 + 836 6 4 144 159 271 147 + 837 6 4 276 265 165 140 + 838 6 4 3 45 13 35 + 839 6 4 3 45 41 13 + 840 6 4 249 244 268 273 + 841 6 4 13 45 41 286 + 842 6 4 257 248 258 306 + 843 6 4 276 156 178 243 + 844 6 4 156 192 178 243 + 845 6 4 280 254 273 302 + 846 6 4 250 295 248 306 + 847 6 4 37 18 230 17 + 848 6 4 91 285 244 249 + 849 6 4 25 47 42 233 + 850 6 4 167 180 176 275 + 851 6 4 93 248 83 105 + 852 6 4 270 182 190 180 + 853 6 4 156 134 169 260 + 854 6 4 248 97 261 123 + 855 6 4 100 122 88 244 + 856 6 4 268 106 118 131 + 857 6 4 275 168 176 137 + 858 6 4 168 159 147 271 + 859 6 4 264 174 172 274 + 860 6 4 168 275 176 182 + 861 6 4 47 64 286 41 + 862 6 4 144 157 127 271 + 863 6 4 12 5 1 29 + 864 6 4 74 44 63 259 + 865 6 4 95 284 84 67 + 866 6 4 157 144 159 271 + 867 6 4 121 276 140 241 + 868 6 4 209 216 220 282 + 869 6 4 12 11 252 253 + 870 6 4 183 292 164 186 + 871 6 4 4 23 294 235 + 872 6 4 249 302 244 273 + 873 6 4 210 201 206 243 + 874 6 4 95 260 107 134 + 875 6 4 144 117 271 127 + 876 6 4 223 33 297 226 + 877 6 4 232 301 228 290 + 878 6 4 235 23 294 247 + 879 6 4 55 284 241 297 + 880 6 4 270 271 299 267 + 881 6 4 168 159 271 182 + 882 6 4 21 304 236 50 + 883 6 4 106 122 244 88 + 884 6 4 289 291 288 290 + 885 6 4 38 287 231 39 + 886 6 4 58 38 59 289 + 887 6 4 163 268 138 131 + 888 6 4 289 58 92 291 + 889 6 4 234 14 306 295 + 890 6 4 47 257 233 306 + 891 6 4 248 110 83 105 + 892 6 4 261 137 275 142 + 893 6 4 95 284 67 74 + 894 6 4 249 14 15 250 + 895 6 4 202 239 212 281 + 896 6 4 161 174 132 266 + 897 6 4 292 90 125 112 + 898 6 4 15 249 255 254 + 899 6 4 177 155 267 150 + 900 6 4 239 187 212 194 + 901 6 4 140 133 241 265 + 902 6 4 129 299 96 120 + 903 6 4 22 256 247 259 + 904 6 4 293 280 263 245 + 905 6 4 292 183 164 153 + 906 6 4 226 34 284 21 + 907 6 4 75 252 12 68 + 908 6 4 12 225 252 11 + 909 6 4 281 278 280 246 + 910 6 4 22 259 21 284 + 911 6 4 222 53 31 52 + 912 6 4 248 257 258 261 + 913 6 4 23 22 247 237 + 914 6 4 234 295 235 15 + 915 6 4 129 145 267 120 + 916 6 4 69 12 40 46 + 917 6 4 86 241 297 77 + 918 6 4 34 9 21 226 + 919 6 4 236 28 21 50 + 920 6 4 292 252 251 253 + 921 6 4 259 72 63 98 + 922 6 4 36 285 66 35 + 923 6 4 259 89 305 61 + 924 6 4 285 229 288 14 + 925 6 4 14 229 13 285 + 926 6 4 297 33 32 54 + 927 6 4 241 78 77 108 + 928 6 4 86 241 77 108 + 929 6 4 121 276 156 140 + 930 6 4 36 285 288 66 + 931 6 4 36 289 66 288 + 932 6 4 3 16 35 13 + 933 6 4 16 229 35 13 + 934 6 4 36 285 229 288 + 935 6 4 16 36 35 229 + 936 6 4 289 36 229 288 + 937 6 4 53 297 32 54 + 938 6 4 211 279 219 206 + 939 6 4 242 23 256 240 + 940 6 4 242 292 251 239 + 941 6 4 294 261 295 258 + 942 6 4 260 150 129 107 + 943 6 4 15 295 235 294 + 944 6 4 250 285 286 91 + 945 6 4 141 269 268 244 + 946 6 4 272 287 263 303 + 947 6 4 255 295 294 296 + 948 6 4 44 34 21 284 + 949 6 4 255 295 15 294 + 950 6 4 255 295 250 15 + 951 6 4 250 285 14 286 + 952 6 4 255 295 296 250 + 953 6 4 64 248 286 83 + 954 6 4 13 24 233 41 + 955 6 4 177 150 267 243 + 956 6 4 103 286 250 110 + 957 6 4 115 241 84 121 + 958 6 4 241 260 84 121 + 959 6 4 264 110 154 151 + 960 6 4 172 264 154 151 + 961 6 4 266 110 264 151 + 962 6 4 252 297 265 298 + 963 6 4 293 254 246 280 + 964 6 4 126 113 265 143 + 965 6 4 282 194 212 209 + 966 6 4 170 269 141 244 + 967 6 4 66 289 57 109 + 968 6 4 276 260 243 256 + 969 6 4 139 275 264 167 + 970 6 4 64 286 65 83 + 971 6 4 256 23 247 240 + 972 6 4 264 174 151 172 + 973 6 4 265 133 165 140 + 974 6 4 227 256 298 23 + 975 6 4 106 91 88 244 + 976 6 4 261 137 119 124 + 977 6 4 148 263 184 162 + 978 6 4 247 309 259 299 + 979 6 4 285 100 88 244 + 980 6 4 218 210 282 213 + 981 6 4 238 25 42 233 + 982 6 4 293 263 251 245 + 983 6 4 278 203 205 197 + 984 6 4 63 259 98 96 + 985 6 4 273 278 246 280 + 986 6 4 300 4 254 15 + 987 6 4 278 269 197 205 + 988 6 4 253 11 10 303 + 989 6 4 176 275 142 167 + 990 6 4 218 221 282 219 + 991 6 4 292 196 183 194 + 992 6 4 296 271 247 299 + 993 6 4 263 185 280 193 + 994 6 4 273 278 268 246 + 995 6 4 273 278 269 268 + 996 6 4 55 33 297 54 + 997 6 4 40 12 231 20 + 998 6 4 287 12 231 40 + 999 6 4 122 106 244 141 + 1000 6 4 248 123 261 142 + 1001 6 4 275 248 261 142 + 1002 6 4 34 44 21 2 + 1003 6 4 259 304 22 21 + 1004 6 4 304 236 22 21 + 1005 6 4 58 289 59 291 + 1006 6 4 82 60 85 287 + 1007 6 4 139 248 142 123 + 1008 6 4 165 292 186 164 + 1009 6 4 275 139 142 167 + 1010 6 4 165 276 178 277 + 1011 6 4 123 119 261 142 + 1012 6 4 238 42 257 233 + 1013 6 4 261 137 142 119 + 1014 6 4 294 261 296 295 + 1015 6 4 255 4 240 294 + 1016 6 4 222 227 297 224 + 1017 6 4 223 222 297 32 + 1018 6 4 226 33 297 284 + 1019 6 4 79 252 112 90 + 1020 6 4 86 53 297 52 + 1021 6 4 177 199 267 173 + 1022 6 4 155 150 129 267 +ENDOFSECTION + ELEMENT GROUP 1.3.0 +GROUP: 1 ELEMENTS: 1022 MATERIAL: 1.000 NFLAGS: 0 + FLUID + 0 + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + 251 252 253 254 255 256 257 258 259 260 + 261 262 263 264 265 266 267 268 269 270 + 271 272 273 274 275 276 277 278 279 280 + 281 282 283 284 285 286 287 288 289 290 + 291 292 293 294 295 296 297 298 299 300 + 301 302 303 304 305 306 307 308 309 310 + 311 312 313 314 315 316 317 318 319 320 + 321 322 323 324 325 326 327 328 329 330 + 331 332 333 334 335 336 337 338 339 340 + 341 342 343 344 345 346 347 348 349 350 + 351 352 353 354 355 356 357 358 359 360 + 361 362 363 364 365 366 367 368 369 370 + 371 372 373 374 375 376 377 378 379 380 + 381 382 383 384 385 386 387 388 389 390 + 391 392 393 394 395 396 397 398 399 400 + 401 402 403 404 405 406 407 408 409 410 + 411 412 413 414 415 416 417 418 419 420 + 421 422 423 424 425 426 427 428 429 430 + 431 432 433 434 435 436 437 438 439 440 + 441 442 443 444 445 446 447 448 449 450 + 451 452 453 454 455 456 457 458 459 460 + 461 462 463 464 465 466 467 468 469 470 + 471 472 473 474 475 476 477 478 479 480 + 481 482 483 484 485 486 487 488 489 490 + 491 492 493 494 495 496 497 498 499 500 + 501 502 503 504 505 506 507 508 509 510 + 511 512 513 514 515 516 517 518 519 520 + 521 522 523 524 525 526 527 528 529 530 + 531 532 533 534 535 536 537 538 539 540 + 541 542 543 544 545 546 547 548 549 550 + 551 552 553 554 555 556 557 558 559 560 + 561 562 563 564 565 566 567 568 569 570 + 571 572 573 574 575 576 577 578 579 580 + 581 582 583 584 585 586 587 588 589 590 + 591 592 593 594 595 596 597 598 599 600 + 601 602 603 604 605 606 607 608 609 610 + 611 612 613 614 615 616 617 618 619 620 + 621 622 623 624 625 626 627 628 629 630 + 631 632 633 634 635 636 637 638 639 640 + 641 642 643 644 645 646 647 648 649 650 + 651 652 653 654 655 656 657 658 659 660 + 661 662 663 664 665 666 667 668 669 670 + 671 672 673 674 675 676 677 678 679 680 + 681 682 683 684 685 686 687 688 689 690 + 691 692 693 694 695 696 697 698 699 700 + 701 702 703 704 705 706 707 708 709 710 + 711 712 713 714 715 716 717 718 719 720 + 721 722 723 724 725 726 727 728 729 730 + 731 732 733 734 735 736 737 738 739 740 + 741 742 743 744 745 746 747 748 749 750 + 751 752 753 754 755 756 757 758 759 760 + 761 762 763 764 765 766 767 768 769 770 + 771 772 773 774 775 776 777 778 779 780 + 781 782 783 784 785 786 787 788 789 790 + 791 792 793 794 795 796 797 798 799 800 + 801 802 803 804 805 806 807 808 809 810 + 811 812 813 814 815 816 817 818 819 820 + 821 822 823 824 825 826 827 828 829 830 + 831 832 833 834 835 836 837 838 839 840 + 841 842 843 844 845 846 847 848 849 850 + 851 852 853 854 855 856 857 858 859 860 + 861 862 863 864 865 866 867 868 869 870 + 871 872 873 874 875 876 877 878 879 880 + 881 882 883 884 885 886 887 888 889 890 + 891 892 893 894 895 896 897 898 899 900 + 901 902 903 904 905 906 907 908 909 910 + 911 912 913 914 915 916 917 918 919 920 + 921 922 923 924 925 926 927 928 929 930 + 931 932 933 934 935 936 937 938 939 940 + 941 942 943 944 945 946 947 948 949 950 + 951 952 953 954 955 956 957 958 959 960 + 961 962 963 964 965 966 967 968 969 970 + 971 972 973 974 975 976 977 978 979 980 + 981 982 983 984 985 986 987 988 989 990 + 991 992 993 994 995 996 997 998 999 1000 + 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 + 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 + 1021 1022 +ENDOFSECTION + BOUNDARY CONDITIONS 1.3.0 + Wall 1 70 0 0 + 863 6 1 + 541 6 4 + 705 6 1 + 35 6 1 + 329 6 3 + 578 6 4 + 225 6 4 + 641 6 3 + 908 6 2 + 544 6 1 + 555 6 3 + 517 6 3 + 755 6 4 + 96 6 1 + 255 6 1 + 552 6 1 + 269 6 1 + 38 6 1 + 918 6 3 + 482 6 4 + 648 6 4 + 370 6 2 + 1016 6 2 + 415 6 2 + 743 6 4 + 760 6 3 + 363 6 4 + 932 6 2 + 925 6 1 + 471 6 3 + 847 6 3 + 319 6 4 + 633 6 4 + 136 6 2 + 997 6 3 + 341 6 3 + 933 6 2 + 400 6 4 + 427 6 3 + 344 6 3 + 602 6 1 + 350 6 4 + 636 6 2 + 198 6 4 + 19 6 1 + 735 6 1 + 773 6 1 + 731 6 4 + 92 6 2 + 727 6 2 + 250 6 4 + 871 6 2 + 914 6 4 + 297 6 1 + 1004 6 3 + 913 6 2 + 774 6 3 + 483 6 1 + 179 6 4 + 645 6 1 + 981 6 2 + 468 6 2 + 563 6 1 + 954 6 1 + 919 6 1 + 20 6 1 + 314 6 2 + 669 6 3 + 34 6 2 + 351 6 2 +ENDOFSECTION + BOUNDARY CONDITIONS 1.3.0 + Far 1 402 0 0 + 863 6 3 + 38 6 4 + 326 6 4 + 541 6 1 + 409 6 3 + 705 6 4 + 108 6 4 + 482 6 1 + 462 6 3 + 578 6 2 + 100 6 2 + 932 6 1 + 471 6 1 + 935 6 1 + 847 6 2 + 737 6 3 + 319 6 2 + 46 6 2 + 136 6 4 + 443 6 3 + 363 6 3 + 377 6 1 + 773 6 3 + 645 6 3 + 563 6 3 + 1002 6 2 + 838 6 2 + 14 6 4 + 179 6 2 + 849 6 1 + 468 6 3 + 831 6 3 + 47 6 1 + 297 6 2 + 839 6 1 + 361 6 3 + 372 6 4 + 647 6 3 + 711 6 2 + 644 6 3 + 408 6 3 + 51 6 3 + 911 6 3 + 926 6 3 + 937 6 4 + 487 6 1 + 996 6 2 + 638 6 1 + 273 6 3 + 575 6 2 + 576 6 4 + 526 6 3 + 886 6 1 + 511 6 4 + 496 6 4 + 564 6 4 + 752 6 4 + 291 6 3 + 586 6 3 + 642 6 2 + 616 6 4 + 861 6 2 + 69 6 4 + 922 6 4 + 460 6 3 + 42 6 4 + 717 6 2 + 805 6 2 + 753 6 3 + 916 6 4 + 553 6 1 + 765 6 1 + 776 6 2 + 495 6 1 + 9 6 2 + 538 6 4 + 531 6 4 + 624 6 3 + 566 6 4 + 74 6 2 + 459 6 3 + 864 6 1 + 808 6 2 + 67 6 2 + 758 6 3 + 162 6 4 + 30 6 3 + 719 6 3 + 295 6 2 + 611 6 2 + 485 6 2 + 613 6 3 + 826 6 2 + 521 6 3 + 542 6 2 + 388 6 4 + 970 6 4 + 795 6 1 + 189 6 1 + 229 6 1 + 1006 6 1 + 1020 6 2 + 412 6 2 + 761 6 4 + 328 6 4 + 478 6 4 + 59 6 3 + 545 6 3 + 284 6 3 + 104 6 3 + 750 6 4 + 763 6 1 + 560 6 4 + 333 6 4 + 430 6 4 + 476 6 4 + 769 6 2 + 280 6 3 + 298 6 4 + 893 6 4 + 865 6 4 + 223 6 4 + 129 6 1 + 479 6 4 + 222 6 2 + 921 6 3 + 527 6 3 + 984 6 4 + 520 6 3 + 746 6 3 + 689 6 4 + 166 6 4 + 491 6 4 + 11 6 2 + 345 6 2 + 429 6 4 + 488 6 4 + 422 6 3 + 851 6 4 + 975 6 1 + 618 6 3 + 156 6 3 + 927 6 3 + 967 6 4 + 604 6 2 + 829 6 4 + 891 6 3 + 39 6 1 + 1019 6 4 + 693 6 2 + 439 6 1 + 22 6 3 + 32 6 2 + 399 6 4 + 262 6 4 + 357 6 3 + 612 6 4 + 696 6 1 + 3 6 3 + 398 6 4 + 529 6 4 + 587 6 1 + 142 6 2 + 226 6 4 + 28 6 1 + 519 6 3 + 928 6 4 + 238 6 3 + 957 6 4 + 855 6 1 + 883 6 2 + 777 6 2 + 583 6 4 + 239 6 2 + 393 6 4 + 767 6 1 + 537 6 1 + 897 6 3 + 197 6 2 + 259 6 2 + 304 6 2 + 565 6 3 + 486 6 4 + 706 6 4 + 631 6 2 + 620 6 2 + 902 6 4 + 157 6 4 + 12 6 1 + 816 6 1 + 821 6 3 + 856 6 3 + 230 6 2 + 410 6 4 + 874 6 4 + 101 6 2 + 420 6 1 + 814 6 3 + 184 6 3 + 87 6 2 + 6 6 2 + 976 6 3 + 308 6 4 + 634 6 1 + 590 6 3 + 36 6 3 + 89 6 3 + 999 6 2 + 603 6 3 + 1011 6 2 + 1007 6 4 + 1013 6 3 + 964 6 2 + 640 6 2 + 875 6 2 + 915 6 2 + 193 6 3 + 244 6 3 + 539 6 3 + 26 6 2 + 676 6 2 + 196 6 2 + 512 6 3 + 792 6 2 + 942 6 3 + 718 6 2 + 282 6 1 + 787 6 3 + 315 6 2 + 332 6 4 + 240 6 4 + 812 6 3 + 745 6 4 + 959 6 3 + 571 6 3 + 1 6 2 + 348 6 2 + 824 6 1 + 1022 6 1 + 354 6 1 + 929 6 4 + 708 6 2 + 504 6 3 + 732 6 2 + 77 6 2 + 862 6 1 + 866 6 1 + 836 6 2 + 548 6 2 + 793 6 4 + 58 6 1 + 52 6 1 + 497 6 1 + 804 6 1 + 887 6 4 + 530 6 2 + 403 6 3 + 973 6 3 + 302 6 3 + 94 6 2 + 268 6 1 + 807 6 1 + 266 6 4 + 1009 6 3 + 369 6 4 + 858 6 1 + 147 6 1 + 853 6 1 + 557 6 1 + 654 6 4 + 313 6 3 + 724 6 4 + 710 6 3 + 70 6 2 + 588 6 2 + 785 6 3 + 896 6 1 + 254 6 4 + 589 6 3 + 899 6 2 + 78 6 1 + 749 6 4 + 591 6 3 + 700 6 4 + 960 6 4 + 435 6 4 + 437 6 2 + 989 6 4 + 503 6 1 + 857 6 3 + 972 6 3 + 850 6 1 + 426 6 2 + 213 6 4 + 860 6 4 + 102 6 3 + 881 6 2 + 905 6 3 + 674 6 3 + 702 6 3 + 572 6 3 + 977 6 4 + 18 6 3 + 668 6 3 + 1008 6 4 + 31 6 1 + 49 6 4 + 391 6 1 + 600 6 2 + 525 6 3 + 637 6 3 + 397 6 2 + 595 6 4 + 187 6 1 + 424 6 2 + 870 6 4 + 532 6 2 + 428 6 3 + 597 6 4 + 404 6 1 + 844 6 1 + 598 6 4 + 120 6 4 + 270 6 1 + 305 6 1 + 852 6 3 + 474 6 2 + 423 6 3 + 75 6 1 + 86 6 3 + 991 6 3 + 677 6 2 + 180 6 2 + 182 6 2 + 499 6 2 + 823 6 4 + 401 6 3 + 469 6 1 + 632 6 3 + 672 6 3 + 819 6 1 + 434 6 1 + 1021 6 2 + 582 6 4 + 712 6 2 + 803 6 3 + 173 6 2 + 366 6 2 + 364 6 3 + 340 6 3 + 167 6 3 + 433 6 4 + 983 6 3 + 411 6 3 + 813 6 1 + 450 6 1 + 105 6 1 + 405 6 3 + 245 6 1 + 506 6 1 + 131 6 2 + 384 6 2 + 655 6 4 + 163 6 3 + 53 6 2 + 594 6 2 + 682 6 3 + 359 6 4 + 801 6 4 + 900 6 3 + 965 6 3 + 84 6 4 + 789 6 1 + 381 6 2 + 114 6 4 + 622 6 3 + 148 6 3 + 716 6 4 + 155 6 4 + 518 6 1 + 873 6 1 + 671 6 1 + 713 6 4 + 33 6 3 + 231 6 1 + 452 6 1 + 470 6 4 + 815 6 2 + 938 6 4 + 568 6 3 + 472 6 4 + 820 6 1 + 868 6 1 + 720 6 1 + 980 6 2 + 72 6 2 + 990 6 2 + 627 6 1 + 111 6 4 + 21 6 4 + 208 6 1 + 330 6 1 +ENDOFSECTION diff --git a/benchmarks/CUDA/DG/Meshes/block2.neu b/benchmarks/CUDA/DG/Meshes/block2.neu new file mode 100755 index 0000000..7f137da --- /dev/null +++ b/benchmarks/CUDA/DG/Meshes/block2.neu @@ -0,0 +1,443 @@ + CONTROL INFO 1.3.0 +** GAMBIT NEUTRAL FILE +block2 +PROGRAM: Gambit VERSION: 1.3.0 +22 Mar 2001 16:06:01 + NUMNP NELEM NGRPS NBSETS NDFCD NDFVL + 134 226 1 1 2 2 +ENDOFSECTION + NODAL COORDINATES 1.3.0 + 1 -1.0000000000e+00 -1.0000000000e+00 + 2 1.0000000000e+00 -1.0000000000e+00 + 3 -8.0000000000e-01 -1.0000000000e+00 + 4 -6.0000000000e-01 -1.0000000000e+00 + 5 -4.0000000000e-01 -1.0000000000e+00 + 6 -2.0000000000e-01 -1.0000000000e+00 + 7 0.0000000000e+00 -1.0000000000e+00 + 8 2.0000000000e-01 -1.0000000000e+00 + 9 4.0000000000e-01 -1.0000000000e+00 + 10 6.0000000000e-01 -1.0000000000e+00 + 11 8.0000000000e-01 -1.0000000000e+00 + 12 1.0000000000e+00 1.0000000000e+00 + 13 1.0000000000e+00 -8.0000000000e-01 + 14 1.0000000000e+00 -6.0000000000e-01 + 15 1.0000000000e+00 -4.0000000000e-01 + 16 1.0000000000e+00 -2.0000000000e-01 + 17 1.0000000000e+00 0.0000000000e+00 + 18 1.0000000000e+00 2.0000000000e-01 + 19 1.0000000000e+00 4.0000000000e-01 + 20 1.0000000000e+00 6.0000000000e-01 + 21 1.0000000000e+00 8.0000000000e-01 + 22 -1.0000000000e+00 1.0000000000e+00 + 23 8.0000000000e-01 1.0000000000e+00 + 24 6.0000000000e-01 1.0000000000e+00 + 25 4.0000000000e-01 1.0000000000e+00 + 26 2.0000000000e-01 1.0000000000e+00 + 27 0.0000000000e+00 1.0000000000e+00 + 28 -2.0000000000e-01 1.0000000000e+00 + 29 -4.0000000000e-01 1.0000000000e+00 + 30 -6.0000000000e-01 1.0000000000e+00 + 31 -8.0000000000e-01 1.0000000000e+00 + 32 -1.0000000000e+00 8.0000000000e-01 + 33 -1.0000000000e+00 6.0000000000e-01 + 34 -1.0000000000e+00 4.0000000000e-01 + 35 -1.0000000000e+00 2.0000000000e-01 + 36 -1.0000000000e+00 0.0000000000e+00 + 37 -1.0000000000e+00 -2.0000000000e-01 + 38 -1.0000000000e+00 -4.0000000000e-01 + 39 -1.0000000000e+00 -6.0000000000e-01 + 40 -1.0000000000e+00 -8.0000000000e-01 + 41 -8.5721187102e-01 -8.6153274544e-01 + 42 1.1658418411e-01 -8.5811365315e-01 + 43 -8.6205388985e-01 8.5633202927e-01 + 44 8.6186144819e-01 8.5680800786e-01 + 45 8.5698582442e-01 -8.6220999015e-01 + 46 -8.0065264501e-01 -6.7467101753e-01 + 47 -6.8713188167e-01 -8.3483626569e-01 + 48 -8.3688195192e-01 6.8407996794e-01 + 49 6.8649101914e-01 -8.3744463999e-01 + 50 7.9990621514e-01 -6.7669934990e-01 + 51 -6.7589448121e-01 7.9805737348e-01 + 52 8.3635088134e-01 6.8514699709e-01 + 53 6.7525803432e-01 8.0028692073e-01 + 54 -8.2225148977e-01 -4.6390446952e-01 + 55 -4.8825932332e-01 -8.2241945486e-01 + 56 4.8718768068e-01 -8.3082585315e-01 + 57 -8.3044853756e-01 4.8015620887e-01 + 58 8.2124405293e-01 -4.6582142744e-01 + 59 -4.6509974677e-01 8.2035850641e-01 + 60 8.2909386694e-01 4.8160077948e-01 + 61 4.6412961731e-01 8.2612920078e-01 + 62 2.8833011425e-01 -8.3492760737e-01 + 63 -8.3946187974e-01 2.7472773487e-01 + 64 -8.2662490534e-01 -2.6379801438e-01 + 65 -2.8536984345e-01 -8.1120419135e-01 + 66 8.2487450096e-01 -2.6547018770e-01 + 67 -2.6581236668e-01 8.2555762216e-01 + 68 8.3716731938e-01 2.7565204692e-01 + 69 2.6650472321e-01 8.3952304376e-01 + 70 -8.3904759367e-01 -6.1738451857e-02 + 71 -5.9414388902e-02 -7.9117830460e-01 + 72 -6.5123388435e-02 8.3874088358e-01 + 73 -8.7195272921e-01 1.0504505999e-01 + 74 8.6985066355e-01 1.0517484129e-01 + 75 8.3657193250e-01 -6.2407478518e-02 + 76 -6.5863270171e-01 5.7053871080e-01 + 77 1.0072075355e-01 8.7195369580e-01 + 78 1.1249672634e-01 -3.0036586961e-02 + 79 -5.1564428728e-01 6.5698912274e-01 + 80 -3.3838540787e-01 6.4504153993e-01 + 81 -1.2920930150e-01 6.5502846816e-01 + 82 -6.5532702309e-01 3.5124703561e-01 + 83 -6.8711583492e-01 1.0987827463e-01 + 84 5.7811218640e-01 -6.6189671241e-01 + 85 6.6115788516e-01 -5.1926123873e-01 + 86 6.4619047841e-01 -3.4256629327e-01 + 87 6.5039468241e-01 -1.2972079516e-01 + 88 3.7405753085e-01 -6.5935782063e-01 + 89 1.5499609007e-01 -6.6910223352e-01 + 90 6.5702739523e-01 5.7489247531e-01 + 91 5.1389793483e-01 6.6424770068e-01 + 92 3.3397231098e-01 6.5952655122e-01 + 93 1.0318914134e-01 6.8753405783e-01 + 94 6.5050763925e-01 3.5604368985e-01 + 95 6.7993036091e-01 1.1080988718e-01 + 96 -5.8060405926e-01 -6.5420441887e-01 + 97 -6.6323324417e-01 -5.1406082092e-01 + 98 -6.4935181590e-01 -3.3678538279e-01 + 99 -6.5646512543e-01 -1.2588036016e-01 + 100 -3.8137320874e-01 -6.3853772031e-01 + 101 -1.8717649984e-01 -6.1927330591e-01 + 102 -1.6546657247e-02 -5.8743580875e-01 + 103 -4.4807945807e-01 4.5378826621e-01 + 104 4.6608058440e-01 -4.6187926231e-01 + 105 4.4612356484e-01 4.6784603172e-01 + 106 -4.7130479174e-01 -4.4813336270e-01 + 107 -2.8409847181e-01 -4.8347119748e-01 + 108 4.6319735835e-01 2.2807648739e-01 + 109 2.7515763260e-01 -5.1227337129e-01 + 110 -4.8050010015e-01 2.1673404592e-01 + 111 -4.6762302563e-01 -2.1425067678e-01 + 112 4.6076409037e-01 -2.2775920672e-01 + 113 -2.1352210678e-01 4.6502216288e-01 + 114 2.1618406219e-01 4.8356444989e-01 + 115 -2.8623165885e-01 -3.0712473081e-01 + 116 -2.8716187588e-01 2.7360860386e-01 + 117 2.7478141636e-01 -3.3063531367e-01 + 118 2.9801514415e-01 3.1852651310e-01 + 119 -1.0250143369e-01 -4.1175546706e-01 + 120 1.0921788484e-01 -4.5429444734e-01 + 121 4.6164429451e-01 -1.3989103119e-03 + 122 -4.8142803392e-01 3.1674360994e-03 + 123 1.6470937479e-03 4.7869850757e-01 + 124 -3.3626423335e-01 1.0545144197e-01 + 125 2.5024284982e-01 1.1787638894e-01 + 126 2.7127572036e-01 -1.1499004536e-01 + 127 -8.5896643356e-02 2.9110055784e-01 + 128 1.1810520262e-01 3.0092968665e-01 + 129 -2.7357234511e-01 -8.0113414523e-02 + 130 -1.6762845694e-01 1.1038110616e-01 + 131 2.8702669359e-02 1.2296215094e-01 + 132 -1.2913291758e-01 -2.1447265387e-01 + 133 6.8789327160e-02 -2.2804710312e-01 + 134 -5.8946707370e-02 -5.2314460243e-02 +ENDOFSECTION + ELEMENTS/CELLS 1.3.0 + 1 3 3 40 1 41 + 2 3 3 41 1 3 + 3 3 3 22 32 43 + 4 3 3 22 43 31 + 5 3 3 21 12 44 + 6 3 3 44 12 23 + 7 3 3 11 2 45 + 8 3 3 45 2 13 + 9 3 3 40 41 46 + 10 3 3 40 46 39 + 11 3 3 41 3 47 + 12 3 3 47 3 4 + 13 3 3 43 32 48 + 14 3 3 48 32 33 + 15 3 3 11 45 49 + 16 3 3 11 49 10 + 17 3 3 45 13 50 + 18 3 3 50 13 14 + 19 3 3 31 43 51 + 20 3 3 31 51 30 + 21 3 3 21 44 52 + 22 3 3 21 52 20 + 23 3 3 44 23 53 + 24 3 3 53 23 24 + 25 3 3 39 46 54 + 26 3 3 39 54 38 + 27 3 3 47 4 55 + 28 3 3 55 4 5 + 29 3 3 10 49 56 + 30 3 3 10 56 9 + 31 3 3 48 33 57 + 32 3 3 57 33 34 + 33 3 3 50 14 58 + 34 3 3 58 14 15 + 35 3 3 30 51 59 + 36 3 3 30 59 29 + 37 3 3 20 52 60 + 38 3 3 20 60 19 + 39 3 3 53 24 61 + 40 3 3 61 24 25 + 41 3 3 9 56 62 + 42 3 3 9 62 8 + 43 3 3 57 34 63 + 44 3 3 63 34 35 + 45 3 3 38 54 64 + 46 3 3 38 64 37 + 47 3 3 55 5 65 + 48 3 3 65 5 6 + 49 3 3 58 15 66 + 50 3 3 66 15 16 + 51 3 3 29 59 67 + 52 3 3 29 67 28 + 53 3 3 19 60 68 + 54 3 3 19 68 18 + 55 3 3 61 25 69 + 56 3 3 69 25 26 + 57 3 3 37 64 70 + 58 3 3 37 70 36 + 59 3 3 65 6 71 + 60 3 3 71 6 7 + 61 3 3 8 62 42 + 62 3 3 8 42 7 + 63 3 3 63 35 73 + 64 3 3 73 35 36 + 65 3 3 28 67 72 + 66 3 3 28 72 27 + 67 3 3 66 16 75 + 68 3 3 75 16 17 + 69 3 3 18 68 74 + 70 3 3 18 74 17 + 71 3 3 69 26 77 + 72 3 3 77 26 27 + 73 3 3 7 42 71 + 74 3 3 73 36 70 + 75 3 3 17 74 75 + 76 3 3 27 72 77 + 77 3 3 46 41 47 + 78 3 3 43 48 51 + 79 3 3 49 45 50 + 80 3 3 44 53 52 + 81 3 3 48 57 76 + 82 3 3 48 76 51 + 83 3 3 59 51 79 + 84 3 3 79 51 76 + 85 3 3 67 59 80 + 86 3 3 80 59 79 + 87 3 3 72 67 81 + 88 3 3 81 67 80 + 89 3 3 57 63 82 + 90 3 3 57 82 76 + 91 3 3 63 73 83 + 92 3 3 63 83 82 + 93 3 3 56 49 84 + 94 3 3 84 49 50 + 95 3 3 50 58 85 + 96 3 3 50 85 84 + 97 3 3 58 66 86 + 98 3 3 58 86 85 + 99 3 3 66 75 87 + 100 3 3 66 87 86 + 101 3 3 62 56 88 + 102 3 3 88 56 84 + 103 3 3 42 62 89 + 104 3 3 89 62 88 + 105 3 3 60 52 90 + 106 3 3 90 52 53 + 107 3 3 53 61 91 + 108 3 3 53 91 90 + 109 3 3 61 69 92 + 110 3 3 61 92 91 + 111 3 3 69 77 93 + 112 3 3 69 93 92 + 113 3 3 68 60 94 + 114 3 3 94 60 90 + 115 3 3 74 68 95 + 116 3 3 95 68 94 + 117 3 3 47 55 96 + 118 3 3 47 96 46 + 119 3 3 54 46 97 + 120 3 3 97 46 96 + 121 3 3 64 54 98 + 122 3 3 98 54 97 + 123 3 3 70 64 99 + 124 3 3 99 64 98 + 125 3 3 55 65 100 + 126 3 3 55 100 96 + 127 3 3 65 71 101 + 128 3 3 65 101 100 + 129 3 3 77 72 93 + 130 3 3 72 81 93 + 131 3 3 71 42 89 + 132 3 3 101 71 102 + 133 3 3 102 71 89 + 134 3 3 73 70 83 + 135 3 3 70 99 83 + 136 3 3 75 74 95 + 137 3 3 87 75 95 + 138 3 3 79 76 103 + 139 3 3 103 76 82 + 140 3 3 80 79 103 + 141 3 3 88 84 104 + 142 3 3 104 84 85 + 143 3 3 85 86 104 + 144 3 3 94 90 105 + 145 3 3 105 90 91 + 146 3 3 91 92 105 + 147 3 3 96 100 106 + 148 3 3 96 106 97 + 149 3 3 98 97 106 + 150 3 3 100 101 107 + 151 3 3 100 107 106 + 152 3 3 95 94 108 + 153 3 3 108 94 105 + 154 3 3 89 88 109 + 155 3 3 109 88 104 + 156 3 3 82 83 110 + 157 3 3 82 110 103 + 158 3 3 99 98 111 + 159 3 3 111 98 106 + 160 3 3 86 87 112 + 161 3 3 86 112 104 + 162 3 3 81 80 113 + 163 3 3 113 80 103 + 164 3 3 92 93 114 + 165 3 3 92 114 105 + 166 3 3 111 106 115 + 167 3 3 115 106 107 + 168 3 3 103 110 116 + 169 3 3 103 116 113 + 170 3 3 109 104 117 + 171 3 3 117 104 112 + 172 3 3 105 114 118 + 173 3 3 105 118 108 + 174 3 3 101 102 119 + 175 3 3 101 119 107 + 176 3 3 89 109 120 + 177 3 3 89 120 102 + 178 3 3 87 95 121 + 179 3 3 121 95 108 + 180 3 3 112 87 121 + 181 3 3 83 99 122 + 182 3 3 83 122 110 + 183 3 3 99 111 122 + 184 3 3 93 81 123 + 185 3 3 93 123 114 + 186 3 3 81 113 123 + 187 3 3 119 102 120 + 188 3 3 107 119 115 + 189 3 3 120 109 117 + 190 3 3 110 122 124 + 191 3 3 110 124 116 + 192 3 3 108 118 125 + 193 3 3 108 125 121 + 194 3 3 112 121 126 + 195 3 3 126 121 125 + 196 3 3 117 112 126 + 197 3 3 113 116 127 + 198 3 3 113 127 123 + 199 3 3 114 123 128 + 200 3 3 128 123 127 + 201 3 3 118 114 128 + 202 3 3 122 111 129 + 203 3 3 129 111 115 + 204 3 3 124 122 129 + 205 3 3 125 118 128 + 206 3 3 116 124 130 + 207 3 3 116 130 127 + 208 3 3 128 127 131 + 209 3 3 131 127 130 + 210 3 3 115 119 132 + 211 3 3 115 132 129 + 212 3 3 119 120 133 + 213 3 3 119 133 132 + 214 3 3 120 117 133 + 215 3 3 117 126 133 + 216 3 3 126 125 78 + 217 3 3 126 78 133 + 218 3 3 128 131 125 + 219 3 3 78 125 131 + 220 3 3 130 124 129 + 221 3 3 129 132 134 + 222 3 3 129 134 130 + 223 3 3 131 130 134 + 224 3 3 132 133 134 + 225 3 3 133 78 134 + 226 3 3 134 78 131 +ENDOFSECTION + ELEMENT GROUP 1.3.0 +GROUP: 1 ELEMENTS: 226 MATERIAL: 2 NFLAGS: 1 + fluid + 0 + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 +ENDOFSECTION + BOUNDARY CONDITIONS 1.3.0 + Wall 1 40 0 6 + 3 3 1 + 14 3 2 + 32 3 2 + 44 3 2 + 64 3 2 + 58 3 3 + 46 3 3 + 26 3 3 + 10 3 3 + 1 3 1 + 6 3 2 + 24 3 2 + 40 3 2 + 56 3 2 + 72 3 2 + 66 3 3 + 52 3 3 + 36 3 3 + 20 3 3 + 4 3 3 + 8 3 2 + 18 3 2 + 34 3 2 + 50 3 2 + 68 3 2 + 70 3 3 + 54 3 3 + 38 3 3 + 22 3 3 + 5 3 1 + 2 3 2 + 12 3 2 + 28 3 2 + 48 3 2 + 60 3 2 + 62 3 3 + 42 3 3 + 30 3 3 + 16 3 3 + 7 3 1 +ENDOFSECTION diff --git a/benchmarks/CUDA/DG/Meshes/block3.neu b/benchmarks/CUDA/DG/Meshes/block3.neu new file mode 100644 index 0000000..27da445 --- /dev/null +++ b/benchmarks/CUDA/DG/Meshes/block3.neu @@ -0,0 +1,9764 @@ +Mesh generated by MeshGen +Gambit neutral format +Dummy Line +Dummy Line +Dummy Line +NUMNP NELEM NGRPS NBSETS NDFCD NDFVL + 3058 5710 1 1 1 1 +ENDOFSECTION +NODAL COORDINATES + 1 0.158 0.846 + 2 0.15664706 0.8361176 + 3 0.15529412 0.8262353 + 4 0.15394117 0.81635296 + 5 0.15258823 0.8064706 + 6 0.1512353 0.79658824 + 7 0.14988235 0.7867059 + 8 0.14852941 0.7768235 + 9 0.14717647 0.7669412 + 10 0.14582352 0.7570588 + 11 0.14447059 0.74717647 + 12 0.14311765 0.73729414 + 13 0.1417647 0.72741175 + 14 0.14041176 0.7175294 + 15 0.13905883 0.7076471 + 16 0.13770588 0.6977647 + 17 0.13635294 0.68788236 + 18 0.135 0.678 + 19 0.13364705 0.66811764 + 20 0.13229412 0.6582353 + 21 0.13094118 0.6483529 + 22 0.12958823 0.6384706 + 23 0.1282353 0.62858826 + 24 0.12688236 0.61870587 + 25 0.12552941 0.60882354 + 26 0.12417647 0.59894115 + 27 0.12282353 0.5890588 + 28 0.121470585 0.5791765 + 29 0.12011765 0.5692941 + 30 0.118764706 0.55941176 + 31 0.11741176 0.54952943 + 32 0.11605883 0.53964704 + 33 0.11470588 0.5297647 + 34 0.11335294 0.5198824 + 35 0.112 0.51 + 36 0.11742857 0.5018857 + 37 0.122857146 0.49377143 + 38 0.12828572 0.48565716 + 39 0.13371429 0.47754285 + 40 0.13914286 0.46942857 + 41 0.14457142 0.4613143 + 42 0.15 0.4532 + 43 0.15542857 0.4450857 + 44 0.16085714 0.43697143 + 45 0.16628571 0.42885715 + 46 0.17171429 0.42074287 + 47 0.17714286 0.41262856 + 48 0.18257143 0.40451428 + 49 0.188 0.3964 + 50 0.19342858 0.38828573 + 51 0.19885714 0.38017142 + 52 0.20428571 0.37205714 + 53 0.20971428 0.36394286 + 54 0.21514286 0.35582858 + 55 0.22057143 0.34771428 + 56 0.226 0.3396 + 57 0.23142858 0.33148572 + 58 0.23685715 0.32337144 + 59 0.24228571 0.31525713 + 60 0.24771428 0.30714285 + 61 0.25314286 0.29902858 + 62 0.25857142 0.2909143 + 63 0.264 0.2828 + 64 0.26942858 0.2746857 + 65 0.27485713 0.26657143 + 66 0.28028572 0.25845715 + 67 0.2857143 0.25034285 + 68 0.29114285 0.24222857 + 69 0.29657143 0.23411429 + 70 0.302 0.226 + 71 0.31133333 0.2292 + 72 0.32066667 0.2324 + 73 0.33 0.2356 + 74 0.33933333 0.2388 + 75 0.34866667 0.242 + 76 0.358 0.2452 + 77 0.36733332 0.2484 + 78 0.37666667 0.2516 + 79 0.386 0.2548 + 80 0.39533332 0.258 + 81 0.40466666 0.2612 + 82 0.414 0.2644 + 83 0.42333335 0.2676 + 84 0.43266666 0.2708 + 85 0.442 0.274 + 86 0.45133334 0.2772 + 87 0.46066666 0.2804 + 88 0.47 0.2836 + 89 0.47933334 0.2868 + 90 0.48866665 0.29 + 91 0.498 0.2932 + 92 0.50733334 0.2964 + 93 0.51666665 0.2996 + 94 0.526 0.3028 + 95 0.53533334 0.306 + 96 0.54466665 0.3092 + 97 0.554 0.3124 + 98 0.56333333 0.3156 + 99 0.57266665 0.3188 + 100 0.582 0.322 + 101 0.57733333 0.33022222 + 102 0.57266665 0.33844444 + 103 0.568 0.34666666 + 104 0.56333333 0.3548889 + 105 0.55866665 0.3631111 + 106 0.554 0.37133333 + 107 0.54933333 0.37955555 + 108 0.54466665 0.38777778 + 109 0.54 0.396 + 110 0.53066665 0.3928 + 111 0.52133334 0.3896 + 112 0.512 0.3864 + 113 0.50266665 0.3832 + 114 0.49333334 0.38 + 115 0.484 0.3768 + 116 0.47466666 0.3736 + 117 0.46533334 0.3704 + 118 0.456 0.3672 + 119 0.44666666 0.364 + 120 0.43733335 0.3608 + 121 0.428 0.3576 + 122 0.41866666 0.3544 + 123 0.40933332 0.3512 + 124 0.4 0.348 + 125 0.39634484 0.3572414 + 126 0.39268965 0.36648276 + 127 0.38903448 0.37572414 + 128 0.3853793 0.3849655 + 129 0.38172415 0.3942069 + 130 0.37806895 0.40344828 + 131 0.3744138 0.41268966 + 132 0.37075862 0.42193103 + 133 0.36710346 0.4311724 + 134 0.36344826 0.4404138 + 135 0.3597931 0.44965518 + 136 0.35613793 0.45889655 + 137 0.35248277 0.46813792 + 138 0.3488276 0.47737932 + 139 0.3451724 0.4866207 + 140 0.34151724 0.49586207 + 141 0.33786207 0.50510347 + 142 0.3342069 0.5143448 + 143 0.3305517 0.5235862 + 144 0.32689655 0.5328276 + 145 0.32324138 0.54206896 + 146 0.31958622 0.55131036 + 147 0.31593102 0.5605517 + 148 0.31227586 0.5697931 + 149 0.3086207 0.5790345 + 150 0.30496553 0.58827585 + 151 0.30131033 0.59751725 + 152 0.29765517 0.6067586 + 153 0.294 0.616 + 154 0.30381396 0.6148372 + 155 0.3136279 0.6136744 + 156 0.32344186 0.61251163 + 157 0.33325583 0.6113488 + 158 0.34306976 0.61018604 + 159 0.35288373 0.6090233 + 160 0.36269766 0.60786045 + 161 0.37251163 0.6066977 + 162 0.3823256 0.6055349 + 163 0.39213952 0.6043721 + 164 0.4019535 0.6032093 + 165 0.41176745 0.6020465 + 166 0.4215814 0.6008837 + 167 0.43139535 0.59972095 + 168 0.44120932 0.5985581 + 169 0.45102325 0.59739536 + 170 0.46083722 0.59623253 + 171 0.47065115 0.59506977 + 172 0.4804651 0.593907 + 173 0.49027908 0.5927442 + 174 0.50009304 0.5915814 + 175 0.50990695 0.5904186 + 176 0.5197209 0.5892558 + 177 0.5295349 0.58809304 + 178 0.53934884 0.5869302 + 179 0.5491628 0.58576745 + 180 0.55897677 0.5846047 + 181 0.5687907 0.58344185 + 182 0.57860464 0.5822791 + 183 0.5884186 0.58111626 + 184 0.59823257 0.5799535 + 185 0.60804653 0.5787907 + 186 0.61786044 0.5776279 + 187 0.6276744 0.57646513 + 188 0.63748837 0.5753023 + 189 0.6473023 0.57413954 + 190 0.6571163 0.57297677 + 191 0.66693026 0.57181394 + 192 0.67674416 0.5706512 + 193 0.6865581 0.56948835 + 194 0.6963721 0.5683256 + 195 0.70618606 0.5671628 + 196 0.716 0.566 + 197 0.7164571 0.55628574 + 198 0.7169143 0.54657143 + 199 0.7173714 0.5368571 + 200 0.7178286 0.5271429 + 201 0.71828574 0.5174286 + 202 0.71874285 0.5077143 + 203 0.7192 0.498 + 204 0.7196571 0.48828572 + 205 0.7201143 0.47857141 + 206 0.72057146 0.46885714 + 207 0.72102857 0.45914286 + 208 0.72148573 0.44942856 + 209 0.72194284 0.43971428 + 210 0.7224 0.43 + 211 0.7228571 0.4202857 + 212 0.7233143 0.41057143 + 213 0.72377145 0.40085715 + 214 0.72422856 0.39114285 + 215 0.7246857 0.38142857 + 216 0.72514284 0.3717143 + 217 0.7256 0.362 + 218 0.7260572 0.3522857 + 219 0.7265143 0.34257144 + 220 0.72697145 0.33285713 + 221 0.72742856 0.32314286 + 222 0.7278857 0.31342858 + 223 0.72834283 0.30371428 + 224 0.7288 0.294 + 225 0.72925717 0.28428572 + 226 0.7297143 0.27457142 + 227 0.73017144 0.26485714 + 228 0.73062855 0.25514287 + 229 0.7310857 0.24542858 + 230 0.7315429 0.23571429 + 231 0.732 0.226 + 232 0.7226316 0.22410527 + 233 0.71326315 0.22221053 + 234 0.70389473 0.22031578 + 235 0.6945263 0.21842106 + 236 0.6851579 0.21652631 + 237 0.6757895 0.21463157 + 238 0.66642106 0.21273685 + 239 0.65705264 0.2108421 + 240 0.6476842 0.20894738 + 241 0.6383158 0.20705263 + 242 0.6289474 0.20515789 + 243 0.61957896 0.20326316 + 244 0.61021054 0.20136842 + 245 0.6008421 0.19947368 + 246 0.5914737 0.19757895 + 247 0.5821053 0.19568421 + 248 0.57273686 0.19378947 + 249 0.56336844 0.19189474 + 250 0.554 0.19 + 251 0.5638621 0.18944828 + 252 0.57372415 0.18889655 + 253 0.5835862 0.18834482 + 254 0.5934483 0.1877931 + 255 0.60331035 0.18724138 + 256 0.6131724 0.18668966 + 257 0.6230345 0.18613793 + 258 0.63289654 0.18558621 + 259 0.6427586 0.18503448 + 260 0.6526207 0.18448275 + 261 0.66248274 0.18393104 + 262 0.6723448 0.1833793 + 263 0.68220687 0.18282759 + 264 0.692069 0.18227586 + 265 0.70193106 0.18172413 + 266 0.7117931 0.18117242 + 267 0.7216552 0.18062069 + 268 0.73151726 0.18006897 + 269 0.7413793 0.17951724 + 270 0.7512414 0.17896552 + 271 0.76110345 0.1784138 + 272 0.7709655 0.17786206 + 273 0.7808276 0.17731035 + 274 0.79068965 0.17675862 + 275 0.8005517 0.1762069 + 276 0.8104138 0.17565517 + 277 0.82027584 0.17510344 + 278 0.8301379 0.17455173 + 279 0.84 0.174 + 280 0.83992857 0.18392856 + 281 0.83985716 0.19385715 + 282 0.8397857 0.20378572 + 283 0.8397143 0.21371429 + 284 0.8396429 0.22364286 + 285 0.8395714 0.23357143 + 286 0.8395 0.2435 + 287 0.83942854 0.25342858 + 288 0.83935714 0.26335713 + 289 0.83928573 0.27328572 + 290 0.83921427 0.28321427 + 291 0.83914286 0.29314286 + 292 0.83907145 0.30307144 + 293 0.839 0.313 + 294 0.8389286 0.32292858 + 295 0.8388571 0.33285713 + 296 0.8387857 0.34278572 + 297 0.8387143 0.3527143 + 298 0.83864284 0.36264285 + 299 0.8385714 0.37257144 + 300 0.8385 0.3825 + 301 0.83842856 0.39242858 + 302 0.83835715 0.40235713 + 303 0.8382857 0.41228572 + 304 0.8382143 0.4222143 + 305 0.8381429 0.43214285 + 306 0.8380714 0.44207144 + 307 0.838 0.452 + 308 0.8379286 0.46192858 + 309 0.8378571 0.47185713 + 310 0.8377857 0.4817857 + 311 0.8377143 0.4917143 + 312 0.83764285 0.5016429 + 313 0.83757144 0.5115714 + 314 0.8375 0.5215 + 315 0.83742857 0.5314286 + 316 0.83735716 0.54135716 + 317 0.8372857 0.55128574 + 318 0.8372143 0.56121427 + 319 0.8371429 0.57114285 + 320 0.8370714 0.58107144 + 321 0.837 0.591 + 322 0.83692855 0.60092854 + 323 0.83685714 0.6108571 + 324 0.83678573 0.6207857 + 325 0.83671427 0.6307143 + 326 0.83664286 0.6406429 + 327 0.83657146 0.6505714 + 328 0.8365 0.6605 + 329 0.8364286 0.6704286 + 330 0.8363571 0.68035716 + 331 0.8362857 0.69028574 + 332 0.8362143 0.70021427 + 333 0.83614284 0.71014285 + 334 0.83607143 0.72007143 + 335 0.836 0.73 + 336 0.82632434 0.7318919 + 337 0.81664866 0.7337838 + 338 0.806973 0.7356757 + 339 0.7972973 0.73756754 + 340 0.7876216 0.73945946 + 341 0.77794594 0.74135137 + 342 0.76827025 0.7432432 + 343 0.7585946 0.7451351 + 344 0.7489189 0.74702704 + 345 0.73924327 0.7489189 + 346 0.7295676 0.7508108 + 347 0.7198919 0.7527027 + 348 0.7102162 0.7545946 + 349 0.70054054 0.7564865 + 350 0.69086486 0.7583784 + 351 0.6811892 0.7602703 + 352 0.6715135 0.76216215 + 353 0.6618378 0.76405406 + 354 0.65216213 0.765946 + 355 0.6424865 0.7678378 + 356 0.63281083 0.76972973 + 357 0.62313515 0.77162164 + 358 0.61345947 0.7735135 + 359 0.6037838 0.7754054 + 360 0.5941081 0.7772973 + 361 0.5844324 0.77918917 + 362 0.57475674 0.7810811 + 363 0.56508106 0.782973 + 364 0.5554054 0.78486484 + 365 0.54572976 0.78675675 + 366 0.5360541 0.78864866 + 367 0.5263784 0.7905405 + 368 0.5167027 0.7924324 + 369 0.50702703 0.79432434 + 370 0.49735135 0.7962162 + 371 0.48767567 0.7981081 + 372 0.478 0.8 + 373 0.46830302 0.8013939 + 374 0.45860606 0.8027879 + 375 0.4489091 0.8041818 + 376 0.4392121 0.8055757 + 377 0.42951515 0.8069697 + 378 0.4198182 0.8083636 + 379 0.4101212 0.8097576 + 380 0.40042424 0.8111515 + 381 0.39072728 0.8125455 + 382 0.3810303 0.8139394 + 383 0.37133333 0.8153333 + 384 0.36163637 0.8167273 + 385 0.35193938 0.8181212 + 386 0.34224242 0.81951517 + 387 0.33254546 0.8209091 + 388 0.3228485 0.82230306 + 389 0.3131515 0.823697 + 390 0.30345455 0.8250909 + 391 0.2937576 0.82648486 + 392 0.2840606 0.8278788 + 393 0.27436364 0.82927275 + 394 0.26466668 0.83066666 + 395 0.2549697 0.83206064 + 396 0.24527273 0.83345455 + 397 0.23557575 0.83484846 + 398 0.22587879 0.83624244 + 399 0.21618181 0.83763635 + 400 0.20648485 0.8390303 + 401 0.19678788 0.84042424 + 402 0.1870909 0.84181815 + 403 0.17739394 0.8432121 + 404 0.16769697 0.84460604 + 405 0.123192765 0.49938777 + 406 0.12309117 0.50510734 + 407 0.122965045 0.51457614 + 408 0.12321077 0.52454984 + 409 0.12419162 0.534211 + 410 0.12507969 0.54381466 + 411 0.12582757 0.5529906 + 412 0.12650278 0.5608873 + 413 0.12394176 0.5749223 + 414 0.13502386 0.48870122 + 415 0.12941839 0.49682617 + 416 0.13359912 0.5080578 + 417 0.1326101 0.5199773 + 418 0.13151443 0.52901065 + 419 0.1346519 0.5385892 + 420 0.13239722 0.5480063 + 421 0.13485245 0.55634874 + 422 0.13297236 0.56641114 + 423 0.13023603 0.5762906 + 424 0.12938973 0.5848069 + 425 0.13214588 0.5935259 + 426 0.13378969 0.60390353 + 427 0.1356019 0.6148225 + 428 0.1347661 0.6247447 + 429 0.13423198 0.63250965 + 430 0.1363374 0.6390848 + 431 0.1343263 0.65359044 + 432 0.14528123 0.46813482 + 433 0.14634484 0.47498414 + 434 0.14382263 0.48635474 + 435 0.13995002 0.49718902 + 436 0.1458084 0.50691694 + 437 0.14149743 0.5159867 + 438 0.14299496 0.52784485 + 439 0.14488222 0.53903234 + 440 0.1416315 0.5483551 + 441 0.14204551 0.5556361 + 442 0.14265108 0.5622045 + 443 0.1434869 0.5734306 + 444 0.14026986 0.5859578 + 445 0.14242916 0.59844655 + 446 0.14287576 0.608817 + 447 0.14399806 0.6165337 + 448 0.1414269 0.62216836 + 449 0.14226921 0.63162893 + 450 0.1446981 0.6444175 + 451 0.13974869 0.6541587 + 452 0.14405389 0.66411537 + 453 0.14357308 0.674719 + 454 0.1438686 0.68418336 + 455 0.14491875 0.6937409 + 456 0.14577062 0.7035451 + 457 0.14599602 0.7130816 + 458 0.14506191 0.7196403 + 459 0.15448911 0.45769545 + 460 0.1511249 0.4668323 + 461 0.15559824 0.47324035 + 462 0.15589416 0.48340905 + 463 0.15214781 0.49637085 + 464 0.15524568 0.5067728 + 465 0.15259022 0.5172466 + 466 0.15476628 0.527907 + 467 0.1516373 0.5351607 + 468 0.15360048 0.54528224 + 469 0.14908178 0.5556483 + 470 0.15349293 0.5657268 + 471 0.15420265 0.57522535 + 472 0.15057875 0.582116 + 473 0.15362278 0.59302056 + 474 0.15189573 0.60539407 + 475 0.1495935 0.61373997 + 476 0.15056165 0.6230628 + 477 0.15395834 0.635331 + 478 0.15752164 0.6460921 + 479 0.15218884 0.6561166 + 480 0.15294601 0.6645306 + 481 0.15393837 0.6726143 + 482 0.15086111 0.6809795 + 483 0.15243031 0.6894473 + 484 0.15332176 0.6992774 + 485 0.1535959 0.7094386 + 486 0.15208977 0.72043484 + 487 0.15421176 0.73286366 + 488 0.15181418 0.7427533 + 489 0.15547818 0.75292146 + 490 0.15362431 0.7625335 + 491 0.1562338 0.7717105 + 492 0.15873833 0.78394103 + 493 0.1567123 0.7959383 + 494 0.16761677 0.43829963 + 495 0.1642395 0.44393778 + 496 0.16533367 0.45411563 + 497 0.16059391 0.4656616 + 498 0.16421366 0.47535533 + 499 0.16740058 0.48514172 + 500 0.1619772 0.49245673 + 501 0.16253272 0.5015512 + 502 0.16329972 0.5118085 + 503 0.16469453 0.523533 + 504 0.16204499 0.5357583 + 505 0.16492899 0.5463251 + 506 0.16111118 0.5566508 + 507 0.1617899 0.56492203 + 508 0.16213696 0.5718806 + 509 0.16130848 0.58287954 + 510 0.16469346 0.5928262 + 511 0.16421428 0.60344136 + 512 0.15870446 0.61484575 + 513 0.1641038 0.62711805 + 514 0.16471483 0.6395572 + 515 0.16486645 0.6467433 + 516 0.16479144 0.6541647 + 517 0.16155653 0.66502106 + 518 0.16402985 0.6748068 + 519 0.16039194 0.683555 + 520 0.16108255 0.6944078 + 521 0.16204219 0.70455164 + 522 0.16234306 0.7152794 + 523 0.16172619 0.7249438 + 524 0.16723831 0.7335012 + 525 0.16190474 0.74334127 + 526 0.1674167 0.7533831 + 527 0.16353332 0.7638859 + 528 0.16598159 0.7759266 + 529 0.16838166 0.7855862 + 530 0.16564037 0.79466754 + 531 0.1622584 0.80716264 + 532 0.16249044 0.8198821 + 533 0.16156791 0.8289559 + 534 0.16440746 0.83613247 + 535 0.17606144 0.42881906 + 536 0.17474245 0.43653217 + 537 0.17205155 0.44526336 + 538 0.17776303 0.45447403 + 539 0.17298292 0.46676764 + 540 0.1730378 0.47792655 + 541 0.17744765 0.48586518 + 542 0.17205335 0.49579695 + 543 0.17063338 0.5060592 + 544 0.17424512 0.51561654 + 545 0.17471147 0.524906 + 546 0.171368 0.5313519 + 547 0.17345838 0.5406325 + 548 0.1745087 0.55316484 + 549 0.17042343 0.56533086 + 550 0.17160285 0.5770596 + 551 0.17232653 0.5879166 + 552 0.1720265 0.5968212 + 553 0.17669596 0.6048659 + 554 0.17195535 0.61628264 + 555 0.17353052 0.62577367 + 556 0.17546485 0.634901 + 557 0.17248702 0.6470108 + 558 0.17404775 0.65592414 + 559 0.17086488 0.66186494 + 560 0.17200759 0.6705582 + 561 0.17206922 0.68178695 + 562 0.16809714 0.6901622 + 563 0.17003427 0.6988125 + 564 0.17178982 0.7095036 + 565 0.17285265 0.72230524 + 566 0.1774838 0.7327912 + 567 0.17548893 0.74430317 + 568 0.1759385 0.7546426 + 569 0.17249799 0.76076305 + 570 0.1738097 0.7695881 + 571 0.17545621 0.78053766 + 572 0.17628543 0.7926186 + 573 0.17160384 0.80256295 + 574 0.17289312 0.81413376 + 575 0.1689969 0.82637644 + 576 0.17352794 0.8347024 + 577 0.18537475 0.40680927 + 578 0.18445088 0.4147852 + 579 0.18383524 0.4243038 + 580 0.18380691 0.43375838 + 581 0.18276428 0.44431347 + 582 0.18679996 0.4530938 + 583 0.18686458 0.46338192 + 584 0.18329556 0.4764671 + 585 0.1856524 0.48577774 + 586 0.18339734 0.49395734 + 587 0.18112417 0.5054173 + 588 0.1840416 0.51529485 + 589 0.18132386 0.52205896 + 590 0.18202561 0.5317801 + 591 0.1859813 0.5451911 + 592 0.18522845 0.5557147 + 593 0.18051739 0.56202394 + 594 0.1813237 0.5714073 + 595 0.18211077 0.58280486 + 596 0.18224615 0.59503525 + 597 0.18594557 0.6044657 + 598 0.18388537 0.6131594 + 599 0.18268766 0.62477267 + 600 0.18750557 0.6353739 + 601 0.1833517 0.6445888 + 602 0.18021804 0.6529506 + 603 0.18182875 0.6633398 + 604 0.18148409 0.6760364 + 605 0.18141596 0.68492633 + 606 0.17671567 0.69174516 + 607 0.18029238 0.70189965 + 608 0.18312478 0.7136614 + 609 0.18638656 0.7259878 + 610 0.18565488 0.73752576 + 611 0.1861301 0.74632907 + 612 0.18253721 0.7523933 + 613 0.18204422 0.7620071 + 614 0.18364239 0.77405393 + 615 0.18488155 0.7851496 + 616 0.1872122 0.79544795 + 617 0.18101 0.8040876 + 618 0.18482804 0.8143172 + 619 0.17908452 0.8243814 + 620 0.18356942 0.83345526 + 621 0.19497015 0.39654514 + 622 0.19472599 0.40577054 + 623 0.19395755 0.41856727 + 624 0.193105 0.42930055 + 625 0.19246298 0.43944547 + 626 0.19191048 0.44778273 + 627 0.19484778 0.45559558 + 628 0.19698702 0.46387935 + 629 0.19553554 0.47338283 + 630 0.19166988 0.48205575 + 631 0.1924997 0.4903934 + 632 0.19164208 0.50030214 + 633 0.19189124 0.51065695 + 634 0.19165485 0.52250165 + 635 0.19578816 0.5355285 + 636 0.1969296 0.5455393 + 637 0.19406733 0.5536348 + 638 0.19114397 0.56432164 + 639 0.19218165 0.5767204 + 640 0.19301884 0.5885874 + 641 0.19366078 0.5997613 + 642 0.19331224 0.6095357 + 643 0.19281736 0.61907005 + 644 0.19377427 0.6288489 + 645 0.1947155 0.635617 + 646 0.19511434 0.64344865 + 647 0.18933871 0.65367997 + 648 0.19354348 0.66231555 + 649 0.19291407 0.6729275 + 650 0.18838787 0.68222165 + 651 0.18815182 0.6923947 + 652 0.19177222 0.7048383 + 653 0.19564362 0.7171098 + 654 0.19533195 0.7255001 + 655 0.19478281 0.7327224 + 656 0.19389474 0.7427451 + 657 0.19331446 0.754417 + 658 0.19287968 0.7678372 + 659 0.19301353 0.77893037 + 660 0.1938423 0.7890795 + 661 0.19406144 0.7962606 + 662 0.19327419 0.8052888 + 663 0.19200853 0.814649 + 664 0.19066247 0.8232205 + 665 0.19362219 0.83334833 + 666 0.20483398 0.37821135 + 667 0.20405252 0.3843285 + 668 0.20373914 0.39578745 + 669 0.20380612 0.4048293 + 670 0.20356545 0.41263205 + 671 0.20413962 0.42479467 + 672 0.20053144 0.43512148 + 673 0.20278008 0.44655257 + 674 0.20383634 0.4589202 + 675 0.20388177 0.4680614 + 676 0.20467752 0.4755444 + 677 0.20136395 0.48411793 + 678 0.20121887 0.49593198 + 679 0.19965339 0.5052164 + 680 0.20318566 0.5149578 + 681 0.20335326 0.5269457 + 682 0.2045037 0.5343072 + 683 0.20618941 0.5421134 + 684 0.20274244 0.5509887 + 685 0.2024977 0.5597904 + 686 0.20228122 0.57071835 + 687 0.20326701 0.5823452 + 688 0.20469813 0.5948029 + 689 0.20280553 0.60615605 + 690 0.20083413 0.6146511 + 691 0.2024887 0.6234943 + 692 0.20249209 0.6347703 + 693 0.20646814 0.64474255 + 694 0.20190609 0.6552463 + 695 0.2015858 0.6661685 + 696 0.20552759 0.6755276 + 697 0.19774653 0.6845237 + 698 0.20045649 0.6962265 + 699 0.20283538 0.70752794 + 700 0.20547466 0.7160314 + 701 0.2045915 0.7261123 + 702 0.20300056 0.73834646 + 703 0.20069511 0.7469722 + 704 0.20411271 0.7532772 + 705 0.20449749 0.7635525 + 706 0.20094244 0.77389127 + 707 0.20202135 0.7834115 + 708 0.20192526 0.7951408 + 709 0.20586815 0.80656207 + 710 0.19922271 0.8156991 + 711 0.20222436 0.8266079 + 712 0.20135204 0.8345322 + 713 0.21704325 0.36619303 + 714 0.21213539 0.37632978 + 715 0.21131872 0.3872824 + 716 0.21441282 0.39421028 + 717 0.21322975 0.40525386 + 718 0.21160476 0.41677764 + 719 0.21608162 0.42575774 + 720 0.21023482 0.4356355 + 721 0.21568759 0.44514376 + 722 0.21278587 0.45486507 + 723 0.21171366 0.46451205 + 724 0.21046752 0.47198927 + 725 0.21203095 0.47999537 + 726 0.21176995 0.4912776 + 727 0.21022655 0.504045 + 728 0.21313553 0.51340026 + 729 0.21226488 0.5216658 + 730 0.21274617 0.5324941 + 731 0.21663521 0.54199886 + 732 0.21414113 0.55368954 + 733 0.2107358 0.56519365 + 734 0.21395396 0.5757891 + 735 0.21353717 0.58737063 + 736 0.2150744 0.5962004 + 737 0.2115911 0.603184 + 738 0.21278639 0.6150384 + 739 0.2122554 0.6286196 + 740 0.21261726 0.6386103 + 741 0.2133326 0.6447844 + 742 0.21326633 0.6515335 + 743 0.2138953 0.6646851 + 744 0.21596679 0.67704195 + 745 0.21082087 0.68764913 + 746 0.21121924 0.7003106 + 747 0.21234223 0.7106447 + 748 0.2119442 0.71881944 + 749 0.21574716 0.7249515 + 750 0.2148989 0.7354896 + 751 0.20928393 0.7460363 + 752 0.21289541 0.7554053 + 753 0.21509708 0.7643576 + 754 0.21236418 0.77567697 + 755 0.21005902 0.78770906 + 756 0.21428654 0.7976273 + 757 0.21514386 0.8077808 + 758 0.21120553 0.81781054 + 759 0.21178514 0.8283691 + 760 0.20761128 0.83323693 + 761 0.22785394 0.34839192 + 762 0.22451544 0.3539132 + 763 0.22464108 0.3620616 + 764 0.22356318 0.37287495 + 765 0.2222514 0.38588074 + 766 0.22154263 0.39701876 + 767 0.22617935 0.4054391 + 768 0.2210776 0.41560256 + 769 0.22729804 0.42535836 + 770 0.22223592 0.4365438 + 771 0.22272627 0.4446992 + 772 0.22335032 0.45258552 + 773 0.21927394 0.46141002 + 774 0.21990678 0.47167882 + 775 0.22378685 0.48513168 + 776 0.22175565 0.49820477 + 777 0.2206346 0.50908786 + 778 0.21922562 0.51708764 + 779 0.22188549 0.5249482 + 780 0.22445899 0.5353208 + 781 0.22576056 0.5462792 + 782 0.22787096 0.55711067 + 783 0.2209043 0.5658778 + 784 0.22575144 0.57577395 + 785 0.22133137 0.58314055 + 786 0.22297351 0.5919011 + 787 0.2226237 0.60373795 + 788 0.22676437 0.61519456 + 789 0.22294194 0.62532055 + 790 0.22016731 0.63451093 + 791 0.22091302 0.6442318 + 792 0.22296067 0.6554548 + 793 0.22515775 0.6639338 + 794 0.22457919 0.67245775 + 795 0.22484724 0.6848245 + 796 0.21976472 0.6950277 + 797 0.22094592 0.7048241 + 798 0.22155799 0.71646684 + 799 0.22576702 0.7280155 + 800 0.22579738 0.73834926 + 801 0.22020786 0.74679416 + 802 0.22426409 0.75852907 + 803 0.2215047 0.76873446 + 804 0.22513707 0.7771475 + 805 0.2196343 0.7867185 + 806 0.22538146 0.79572 + 807 0.22178389 0.8038238 + 808 0.22239445 0.81310195 + 809 0.22163062 0.8265447 + 810 0.22123541 0.8334743 + 811 0.23669255 0.3362518 + 812 0.23382421 0.3451576 + 813 0.23436075 0.3556092 + 814 0.23319359 0.36803854 + 815 0.23207626 0.3788805 + 816 0.23127493 0.3862208 + 817 0.2316723 0.39446038 + 818 0.23748395 0.40531212 + 819 0.23217762 0.4151757 + 820 0.23830265 0.424426 + 821 0.2340618 0.43475282 + 822 0.22961853 0.44451442 + 823 0.23476772 0.4540696 + 824 0.22849292 0.46328956 + 825 0.23333855 0.47518232 + 826 0.23465507 0.48519298 + 827 0.23269588 0.4940814 + 828 0.23114987 0.505397 + 829 0.22810993 0.5162373 + 830 0.23447466 0.52680004 + 831 0.23533438 0.53936327 + 832 0.23627488 0.55016524 + 833 0.2372284 0.5589759 + 834 0.23310314 0.5676438 + 835 0.23484191 0.5773085 + 836 0.23051754 0.5848309 + 837 0.23483904 0.59610444 + 838 0.23438825 0.60855544 + 839 0.23425615 0.6157444 + 840 0.23357882 0.6228085 + 841 0.2320354 0.6357877 + 842 0.2318713 0.64893204 + 843 0.23250854 0.6593718 + 844 0.2317053 0.6676469 + 845 0.23574099 0.67655087 + 846 0.23598911 0.68745244 + 847 0.23086733 0.6975573 + 848 0.22981113 0.70903593 + 849 0.23430268 0.719153 + 850 0.23410432 0.72742164 + 851 0.23399547 0.7345164 + 852 0.23418549 0.7471139 + 853 0.23536287 0.7594423 + 854 0.23065929 0.7680965 + 855 0.23612015 0.7773146 + 856 0.23045175 0.78652656 + 857 0.2343508 0.7947992 + 858 0.23152114 0.8049317 + 859 0.23285232 0.8177476 + 860 0.23135328 0.8279799 + 861 0.24735151 0.31456426 + 862 0.24700211 0.3206874 + 863 0.24785507 0.33195713 + 864 0.24422494 0.34596884 + 865 0.24518156 0.35716215 + 866 0.24142833 0.36427528 + 867 0.24303882 0.3746412 + 868 0.23908822 0.3857701 + 869 0.2439255 0.39574665 + 870 0.24822259 0.40615082 + 871 0.24287538 0.41501564 + 872 0.24717557 0.42302012 + 873 0.24645296 0.4332817 + 874 0.24057922 0.44439682 + 875 0.24633366 0.45484278 + 876 0.24015954 0.4646396 + 877 0.24510303 0.47444126 + 878 0.24094042 0.48158666 + 879 0.24222805 0.48974523 + 880 0.24230239 0.50060153 + 881 0.24117747 0.5140348 + 882 0.24557835 0.5242745 + 883 0.24476537 0.5334344 + 884 0.246377 0.5442253 + 885 0.24523118 0.55507684 + 886 0.2438072 0.564897 + 887 0.2414903 0.5735393 + 888 0.24346916 0.5847256 + 889 0.24441834 0.5948317 + 890 0.24559496 0.60412145 + 891 0.24228328 0.6164366 + 892 0.24313052 0.62839425 + 893 0.24363278 0.6377413 + 894 0.23986827 0.644385 + 895 0.24277182 0.6543467 + 896 0.2404143 0.6658697 + 897 0.24735047 0.673734 + 898 0.24510452 0.68378323 + 899 0.2432525 0.69451106 + 900 0.2413141 0.70725954 + 901 0.24515535 0.71790886 + 902 0.2423682 0.72812843 + 903 0.24180637 0.73827225 + 904 0.24596839 0.74521756 + 905 0.24618979 0.7560715 + 906 0.24155456 0.767593 + 907 0.24688323 0.7771341 + 908 0.2419149 0.7875781 + 909 0.24224338 0.79931855 + 910 0.24131426 0.81005746 + 911 0.24071294 0.81710553 + 912 0.24074078 0.8245144 + 913 0.25604355 0.30868062 + 914 0.25244248 0.31519055 + 915 0.2552996 0.32382792 + 916 0.25786772 0.33198255 + 917 0.25714478 0.3416781 + 918 0.25454217 0.35402513 + 919 0.25132108 0.36598843 + 920 0.25156105 0.37486923 + 921 0.25252476 0.38476816 + 922 0.25461856 0.39808357 + 923 0.25653273 0.40672642 + 924 0.25408605 0.41605103 + 925 0.2543864 0.4263269 + 926 0.25861076 0.43515489 + 927 0.2523061 0.44484904 + 928 0.25739896 0.45510888 + 929 0.25277507 0.46582204 + 930 0.2539988 0.47597462 + 931 0.249139 0.48316175 + 932 0.25334007 0.4936234 + 933 0.25298914 0.5066009 + 934 0.2534945 0.5183137 + 935 0.2539559 0.5288593 + 936 0.2529206 0.5371885 + 937 0.25599575 0.54327434 + 938 0.254243 0.5512055 + 939 0.2535945 0.5610523 + 940 0.25234112 0.57310575 + 941 0.25563255 0.58368224 + 942 0.2538436 0.59434277 + 943 0.25751555 0.6056661 + 944 0.25196478 0.6128607 + 945 0.25305465 0.62256724 + 946 0.2540964 0.6350297 + 947 0.2488855 0.64511526 + 948 0.25336602 0.653205 + 949 0.25225118 0.6635078 + 950 0.25575018 0.67232764 + 951 0.2546516 0.6802694 + 952 0.25349152 0.69010496 + 953 0.25261545 0.7008771 + 954 0.2530868 0.711813 + 955 0.2546664 0.72326154 + 956 0.2525708 0.73652697 + 957 0.25516707 0.74826187 + 958 0.2570697 0.7574313 + 959 0.25409728 0.76766217 + 960 0.25595674 0.7781701 + 961 0.2515228 0.78462243 + 962 0.25156963 0.7934251 + 963 0.2524717 0.8051348 + 964 0.24776343 0.816087 + 965 0.25146836 0.8243531 + 966 0.2672297 0.2898006 + 967 0.26395136 0.29629537 + 968 0.26566398 0.30580744 + 969 0.26132816 0.31629664 + 970 0.26542866 0.32693863 + 971 0.26371947 0.33558747 + 972 0.2666309 0.341798 + 973 0.2652506 0.35051012 + 974 0.26410422 0.3628912 + 975 0.2593067 0.37410605 + 976 0.26405442 0.38218072 + 977 0.2645581 0.39277408 + 978 0.26203287 0.40232614 + 979 0.26386303 0.41099927 + 980 0.26582158 0.42409754 + 981 0.2683863 0.4360753 + 982 0.26458514 0.44621834 + 983 0.2659435 0.4560816 + 984 0.26250282 0.46267328 + 985 0.26380217 0.4728542 + 986 0.2589865 0.48339912 + 987 0.26376027 0.49105692 + 988 0.26370013 0.50064486 + 989 0.26376554 0.512385 + 990 0.26342964 0.52382344 + 991 0.26354957 0.5362695 + 992 0.26294845 0.54761845 + 993 0.26140696 0.5560926 + 994 0.26464972 0.56598043 + 995 0.26388046 0.57783556 + 996 0.26473776 0.58833 + 997 0.26566425 0.59893787 + 998 0.26671714 0.60815483 + 999 0.2613949 0.61547446 + 1000 0.2654143 0.627173 + 1001 0.264983 0.6382226 + 1002 0.25940487 0.6459745 + 1003 0.26333693 0.6570562 + 1004 0.26255518 0.66795564 + 1005 0.26178718 0.67610633 + 1006 0.2642711 0.6854865 + 1007 0.2609175 0.69564635 + 1008 0.26351637 0.70590514 + 1009 0.26117668 0.71568567 + 1010 0.26451173 0.7220637 + 1011 0.26377335 0.73078305 + 1012 0.2643085 0.7419014 + 1013 0.26498 0.7525586 + 1014 0.26496542 0.76271415 + 1015 0.26603281 0.7746384 + 1016 0.26111877 0.78683496 + 1017 0.2598546 0.7970386 + 1018 0.26452982 0.8046133 + 1019 0.2596379 0.8153053 + 1020 0.26027995 0.82464635 + 1021 0.27593693 0.27488962 + 1022 0.27446982 0.28306824 + 1023 0.27519578 0.29598963 + 1024 0.276907 0.30707014 + 1025 0.2732033 0.31743082 + 1026 0.2751349 0.32797357 + 1027 0.27161205 0.33561382 + 1028 0.27548382 0.34567365 + 1029 0.27358592 0.3570465 + 1030 0.27242905 0.36464095 + 1031 0.27218908 0.3739443 + 1032 0.2716254 0.3852888 + 1033 0.27637374 0.3937094 + 1034 0.27068824 0.40301436 + 1035 0.27421045 0.41373473 + 1036 0.2771672 0.42276227 + 1037 0.27621844 0.43160638 + 1038 0.27692857 0.44322798 + 1039 0.2727205 0.45290995 + 1040 0.2725737 0.46337596 + 1041 0.27594233 0.47496742 + 1042 0.2696968 0.48358425 + 1043 0.27292135 0.4939726 + 1044 0.27528173 0.50625634 + 1045 0.27361315 0.5187967 + 1046 0.27216944 0.52850026 + 1047 0.27611017 0.5368096 + 1048 0.2708907 0.5443399 + 1049 0.271658 0.554672 + 1050 0.27733296 0.56557655 + 1051 0.27242985 0.5735385 + 1052 0.27359334 0.5822941 + 1053 0.27591875 0.5927578 + 1054 0.27534854 0.60423523 + 1055 0.27371868 0.6163548 + 1056 0.27630767 0.6267874 + 1057 0.27427828 0.63571215 + 1058 0.27160102 0.6472095 + 1059 0.2735112 0.65728575 + 1060 0.27044484 0.6642487 + 1061 0.27158692 0.6744643 + 1062 0.27670544 0.68596494 + 1063 0.2706043 0.69584227 + 1064 0.27605474 0.706086 + 1065 0.2700557 0.71540254 + 1066 0.27286068 0.7252224 + 1067 0.27373636 0.7357874 + 1068 0.2756739 0.7475689 + 1069 0.27274773 0.7575493 + 1070 0.27486536 0.7664933 + 1071 0.27779874 0.7757831 + 1072 0.27328768 0.7847828 + 1073 0.2693442 0.79509616 + 1074 0.2754223 0.8035483 + 1075 0.27012467 0.81137836 + 1076 0.27057496 0.8208024 + 1077 0.28672472 0.25704262 + 1078 0.28600505 0.2635037 + 1079 0.28500366 0.27526948 + 1080 0.28453353 0.2881331 + 1081 0.2842652 0.29555014 + 1082 0.284649 0.302362 + 1083 0.28592423 0.3138874 + 1084 0.28218028 0.32419205 + 1085 0.2833563 0.33580235 + 1086 0.28355694 0.3451232 + 1087 0.28441343 0.35390666 + 1088 0.27976334 0.36468384 + 1089 0.2851844 0.37393567 + 1090 0.28089017 0.3838048 + 1091 0.28727478 0.39283076 + 1092 0.28317592 0.4045065 + 1093 0.28471735 0.41699633 + 1094 0.28507793 0.42734483 + 1095 0.2841904 0.43607193 + 1096 0.28898683 0.4440497 + 1097 0.28366333 0.45555604 + 1098 0.28346157 0.46846226 + 1099 0.28339502 0.47625166 + 1100 0.2826498 0.48520336 + 1101 0.28232998 0.49713826 + 1102 0.28769824 0.50601053 + 1103 0.28286058 0.5150526 + 1104 0.28413415 0.5269843 + 1105 0.2857129 0.5385477 + 1106 0.28020534 0.5464627 + 1107 0.28421175 0.55674654 + 1108 0.2883464 0.5665697 + 1109 0.28274867 0.57594985 + 1110 0.28192306 0.58522797 + 1111 0.28556126 0.5910003 + 1112 0.28469718 0.5990904 + 1113 0.28543597 0.6099826 + 1114 0.28543302 0.6225804 + 1115 0.28266707 0.6320792 + 1116 0.28461555 0.6427957 + 1117 0.28092748 0.6534488 + 1118 0.281113 0.6645105 + 1119 0.2840953 0.67704546 + 1120 0.2875032 0.68706304 + 1121 0.2820861 0.69600856 + 1122 0.28783724 0.70595956 + 1123 0.2821714 0.71748877 + 1124 0.28289706 0.72985893 + 1125 0.28290984 0.73942924 + 1126 0.28778374 0.747352 + 1127 0.28325334 0.7584177 + 1128 0.28433403 0.76981294 + 1129 0.28451276 0.77625126 + 1130 0.28361273 0.78259563 + 1131 0.28161767 0.7936082 + 1132 0.2863675 0.8038687 + 1133 0.2802848 0.81249666 + 1134 0.28453386 0.8217464 + 1135 0.29410306 0.2454548 + 1136 0.2948961 0.25588772 + 1137 0.29426453 0.2678437 + 1138 0.29439172 0.2750236 + 1139 0.2955736 0.2832295 + 1140 0.29272494 0.29580387 + 1141 0.2929575 0.3059994 + 1142 0.2983274 0.3143356 + 1143 0.2933693 0.3259518 + 1144 0.2946267 0.3368449 + 1145 0.29098076 0.34514827 + 1146 0.29678562 0.35506582 + 1147 0.29067644 0.3646285 + 1148 0.29484344 0.37343386 + 1149 0.29259112 0.3830998 + 1150 0.2958601 0.39171416 + 1151 0.2946613 0.4001524 + 1152 0.294341 0.41111115 + 1153 0.29446363 0.42252147 + 1154 0.29390767 0.43408686 + 1155 0.2980291 0.44270644 + 1156 0.29737386 0.45256227 + 1157 0.29369915 0.46419922 + 1158 0.29149643 0.4763638 + 1159 0.29228246 0.48505378 + 1160 0.29305482 0.49437007 + 1161 0.29907954 0.5061031 + 1162 0.29355475 0.5174152 + 1163 0.2935806 0.52623475 + 1164 0.29545575 0.5348666 + 1165 0.29265535 0.5478006 + 1166 0.29508442 0.55947447 + 1167 0.29689512 0.5673418 + 1168 0.2938263 0.57431626 + 1169 0.2918382 0.5840335 + 1170 0.29347357 0.59377575 + 1171 0.29249138 0.6026724 + 1172 0.2923939 0.60885847 + 1173 0.29322904 0.6243109 + 1174 0.29267845 0.63252914 + 1175 0.29637825 0.64316857 + 1176 0.2937202 0.65551794 + 1177 0.2934068 0.66971 + 1178 0.29420263 0.68074584 + 1179 0.29412514 0.68758094 + 1180 0.29377848 0.6952704 + 1181 0.2986955 0.70578337 + 1182 0.29422078 0.71530104 + 1183 0.29123968 0.7246817 + 1184 0.2944344 0.73658043 + 1185 0.29631734 0.747093 + 1186 0.29404125 0.7549662 + 1187 0.2932524 0.7650976 + 1188 0.29221368 0.7767107 + 1189 0.2920807 0.7882548 + 1190 0.29098773 0.7968683 + 1191 0.29515857 0.8029551 + 1192 0.29455078 0.8134941 + 1193 0.29407862 0.82171094 + 1194 0.3064385 0.2353186 + 1195 0.3021909 0.24471636 + 1196 0.30758756 0.2546119 + 1197 0.30255926 0.263641 + 1198 0.30270022 0.27380472 + 1199 0.30569816 0.28287965 + 1200 0.30390736 0.2917792 + 1201 0.3032022 0.30366442 + 1202 0.3076269 0.31306487 + 1203 0.306945 0.32345903 + 1204 0.30232152 0.33317173 + 1205 0.30315855 0.3441541 + 1206 0.30846506 0.35577786 + 1207 0.30296656 0.3667248 + 1208 0.30266967 0.3787553 + 1209 0.30124694 0.38721997 + 1210 0.30340397 0.3952947 + 1211 0.30382797 0.40550652 + 1212 0.30519262 0.41703847 + 1213 0.30361798 0.42857617 + 1214 0.3031294 0.43730325 + 1215 0.30683908 0.4454633 + 1216 0.3073184 0.45470104 + 1217 0.30317134 0.46114206 + 1218 0.3030593 0.4710499 + 1219 0.30191058 0.4843508 + 1220 0.305412 0.49694136 + 1221 0.3084096 0.5062106 + 1222 0.30635116 0.51598835 + 1223 0.301174 0.52585536 + 1224 0.30693516 0.5346981 + 1225 0.30399066 0.54420763 + 1226 0.30392352 0.5544403 + 1227 0.30447623 0.5639904 + 1228 0.3027481 0.5723494 + 1229 0.30039862 0.5796058 + 1230 0.30715293 0.6197511 + 1231 0.3008203 0.62615746 + 1232 0.30563095 0.63669556 + 1233 0.30526564 0.6484407 + 1234 0.3058132 0.6575713 + 1235 0.30223027 0.6647598 + 1236 0.30506745 0.67592204 + 1237 0.30102214 0.6874225 + 1238 0.3051943 0.69735056 + 1239 0.30824193 0.7072684 + 1240 0.30291918 0.713798 + 1241 0.30244404 0.72423095 + 1242 0.30777934 0.7353964 + 1243 0.30400464 0.74459463 + 1244 0.30122152 0.7518917 + 1245 0.30230355 0.7598256 + 1246 0.30324793 0.77070177 + 1247 0.30431393 0.7840513 + 1248 0.29960006 0.7954658 + 1249 0.3041959 0.80488396 + 1250 0.3082493 0.8150266 + 1251 0.31299475 0.2349612 + 1252 0.3135363 0.24293128 + 1253 0.31898144 0.254434 + 1254 0.3132935 0.26609346 + 1255 0.31300694 0.27796978 + 1256 0.31318566 0.2876297 + 1257 0.31296813 0.29747218 + 1258 0.31387132 0.30717173 + 1259 0.31579727 0.31661972 + 1260 0.31768143 0.32554775 + 1261 0.3135595 0.3353965 + 1262 0.31540167 0.34755707 + 1263 0.31786758 0.35645103 + 1264 0.3145691 0.3645493 + 1265 0.31262967 0.37477672 + 1266 0.31157967 0.38724974 + 1267 0.31309065 0.3999771 + 1268 0.31215444 0.40955067 + 1269 0.3161172 0.4172247 + 1270 0.31173214 0.4248702 + 1271 0.3132922 0.4356459 + 1272 0.31395864 0.44410613 + 1273 0.31480464 0.451106 + 1274 0.31442803 0.46313578 + 1275 0.31365338 0.47709817 + 1276 0.31440842 0.48970658 + 1277 0.3156146 0.5011379 + 1278 0.31560314 0.5111312 + 1279 0.31548128 0.51938283 + 1280 0.31116608 0.5261543 + 1281 0.3162525 0.534411 + 1282 0.3135682 0.54288375 + 1283 0.31140035 0.550672 + 1284 0.31842524 0.6201651 + 1285 0.3122803 0.6277377 + 1286 0.31670797 0.6352057 + 1287 0.315392 0.6438342 + 1288 0.3147308 0.6540809 + 1289 0.31317046 0.66529053 + 1290 0.31770658 0.67596644 + 1291 0.31380197 0.6879274 + 1292 0.3156811 0.7007157 + 1293 0.31601173 0.7096875 + 1294 0.31099382 0.71654403 + 1295 0.31547865 0.7274256 + 1296 0.31539333 0.7359062 + 1297 0.31481075 0.7436433 + 1298 0.3093304 0.7528815 + 1299 0.31258678 0.7632621 + 1300 0.31470096 0.77507657 + 1301 0.3174735 0.78630495 + 1302 0.31079388 0.7955757 + 1303 0.316799 0.80659884 + 1304 0.31734848 0.8162972 + 1305 0.3255115 0.23736311 + 1306 0.32585412 0.24409117 + 1307 0.32809535 0.25501433 + 1308 0.32538942 0.26387155 + 1309 0.32265422 0.2743278 + 1310 0.32031626 0.28306407 + 1311 0.32303378 0.29256088 + 1312 0.32047695 0.3019381 + 1313 0.32309157 0.3101391 + 1314 0.325565 0.3201581 + 1315 0.32657668 0.33191654 + 1316 0.32289022 0.34174827 + 1317 0.32648844 0.35158607 + 1318 0.32438642 0.36258072 + 1319 0.32101184 0.37081775 + 1320 0.32283905 0.38047138 + 1321 0.32497817 0.39424518 + 1322 0.32240865 0.40807977 + 1323 0.32465598 0.41799727 + 1324 0.32037055 0.42589223 + 1325 0.3257271 0.43475813 + 1326 0.3208857 0.44414222 + 1327 0.32538253 0.45497617 + 1328 0.32419652 0.46356884 + 1329 0.32382414 0.4713408 + 1330 0.3242823 0.48303822 + 1331 0.32557833 0.49581188 + 1332 0.3242864 0.5072331 + 1333 0.32348818 0.51705605 + 1334 0.3208047 0.5267615 + 1335 0.32179877 0.53401023 + 1336 0.32909024 0.618834 + 1337 0.3250366 0.62857366 + 1338 0.3253228 0.6393577 + 1339 0.3248295 0.6494533 + 1340 0.3240332 0.66015965 + 1341 0.3227247 0.66890115 + 1342 0.3261626 0.67488176 + 1343 0.3254429 0.68322057 + 1344 0.3266073 0.69522876 + 1345 0.32431492 0.70710397 + 1346 0.32087332 0.71700776 + 1347 0.32738185 0.7258387 + 1348 0.32343298 0.7371605 + 1349 0.32264626 0.745532 + 1350 0.32092136 0.7539629 + 1351 0.32488835 0.7669682 + 1352 0.32563072 0.7789789 + 1353 0.32702923 0.7879497 + 1354 0.32238728 0.7959632 + 1355 0.3289659 0.80445457 + 1356 0.32571298 0.81380856 + 1357 0.33477917 0.24351472 + 1358 0.33516595 0.2514796 + 1359 0.33493608 0.26119432 + 1360 0.33415797 0.27214697 + 1361 0.3295166 0.28277385 + 1362 0.33520636 0.29267377 + 1363 0.32931867 0.30222115 + 1364 0.3334483 0.3125196 + 1365 0.33679563 0.32395202 + 1366 0.33714128 0.33419517 + 1367 0.33245438 0.3420631 + 1368 0.33664724 0.35007712 + 1369 0.3357702 0.36026162 + 1370 0.33054516 0.3715819 + 1371 0.33613405 0.3840539 + 1372 0.33656502 0.396205 + 1373 0.3319761 0.40367004 + 1374 0.33363563 0.41395718 + 1375 0.33055714 0.42486942 + 1376 0.33701518 0.43376595 + 1377 0.33209285 0.44417217 + 1378 0.33807617 0.45381135 + 1379 0.33313236 0.4647646 + 1380 0.33323187 0.4764033 + 1381 0.33498853 0.48791322 + 1382 0.33423597 0.49773887 + 1383 0.33123368 0.5040387 + 1384 0.33759317 0.6164315 + 1385 0.33687562 0.6240635 + 1386 0.33671346 0.63482684 + 1387 0.33343428 0.6444614 + 1388 0.3362399 0.6550609 + 1389 0.33266476 0.6684322 + 1390 0.332415 0.67814124 + 1391 0.33611494 0.6874571 + 1392 0.33534932 0.69587904 + 1393 0.33571556 0.7046042 + 1394 0.331091 0.71559876 + 1395 0.33652744 0.72348696 + 1396 0.3368881 0.734457 + 1397 0.3313284 0.74732107 + 1398 0.33070633 0.75801706 + 1399 0.33625486 0.76550967 + 1400 0.33331257 0.77378654 + 1401 0.3363855 0.7836023 + 1402 0.33333325 0.7947267 + 1403 0.3398603 0.80325466 + 1404 0.3358116 0.8122243 + 1405 0.34348202 0.24760793 + 1406 0.34369862 0.25745988 + 1407 0.34287846 0.26718187 + 1408 0.3418933 0.27383342 + 1409 0.34150496 0.28178832 + 1410 0.34711108 0.2932224 + 1411 0.34053916 0.30332568 + 1412 0.34533155 0.31508464 + 1413 0.34462884 0.32324472 + 1414 0.34490374 0.3301919 + 1415 0.34500957 0.34256527 + 1416 0.34351414 0.35361877 + 1417 0.34571698 0.36090928 + 1418 0.3430327 0.3711336 + 1419 0.3473478 0.38144192 + 1420 0.34744096 0.39315695 + 1421 0.3421064 0.40587524 + 1422 0.3416959 0.4143866 + 1423 0.34175846 0.42283612 + 1424 0.3463962 0.43239757 + 1425 0.34538475 0.44349605 + 1426 0.34746876 0.45358938 + 1427 0.34492862 0.4617739 + 1428 0.3422519 0.47140425 + 1429 0.34089553 0.47994483 + 1430 0.34573287 0.61778075 + 1431 0.3472198 0.6280562 + 1432 0.34511226 0.6357186 + 1433 0.34422526 0.6437625 + 1434 0.3492919 0.6541584 + 1435 0.34545606 0.6652319 + 1436 0.34183115 0.6769015 + 1437 0.34831297 0.68671256 + 1438 0.34306994 0.6963647 + 1439 0.3479409 0.7065781 + 1440 0.34180108 0.7156861 + 1441 0.3455134 0.72592974 + 1442 0.3494543 0.7356586 + 1443 0.3445292 0.7458069 + 1444 0.34004527 0.7562386 + 1445 0.3450989 0.76415145 + 1446 0.34339306 0.7737502 + 1447 0.34660572 0.78283376 + 1448 0.34547496 0.7929905 + 1449 0.35010713 0.80366045 + 1450 0.3455987 0.81134665 + 1451 0.35056144 0.24696295 + 1452 0.35205862 0.25305066 + 1453 0.3534811 0.26425657 + 1454 0.34884962 0.27419138 + 1455 0.35354385 0.28361318 + 1456 0.35899174 0.2937625 + 1457 0.35274354 0.30407536 + 1458 0.35766503 0.3146475 + 1459 0.35150692 0.32356396 + 1460 0.35437924 0.3333355 + 1461 0.35664955 0.3425904 + 1462 0.35441118 0.35403937 + 1463 0.351811 0.36525044 + 1464 0.3538013 0.3741999 + 1465 0.35621795 0.384543 + 1466 0.35945788 0.39503548 + 1467 0.35405856 0.40486383 + 1468 0.3491306 0.41487148 + 1469 0.35365966 0.42557588 + 1470 0.3540399 0.43626758 + 1471 0.35509574 0.44395608 + 1472 0.35278067 0.44992307 + 1473 0.35683453 0.6189924 + 1474 0.3570367 0.6288322 + 1475 0.3524258 0.63632923 + 1476 0.35659948 0.6459473 + 1477 0.35676184 0.65368026 + 1478 0.35672054 0.66139936 + 1479 0.35620123 0.6755706 + 1480 0.3577336 0.6870121 + 1481 0.35514003 0.69707674 + 1482 0.35797015 0.7078196 + 1483 0.3540974 0.7179976 + 1484 0.3543432 0.72830945 + 1485 0.358296 0.73483545 + 1486 0.35710326 0.7445515 + 1487 0.35225692 0.7565306 + 1488 0.35348034 0.7686121 + 1489 0.35261086 0.77759516 + 1490 0.3552312 0.786103 + 1491 0.35693455 0.79660755 + 1492 0.35920727 0.80641216 + 1493 0.35369027 0.81125855 + 1494 0.36302182 0.25683984 + 1495 0.3640467 0.2666412 + 1496 0.35960376 0.2744775 + 1497 0.3650692 0.2842506 + 1498 0.36864033 0.29310116 + 1499 0.36681643 0.30431974 + 1500 0.3674805 0.31602293 + 1501 0.36217475 0.32466906 + 1502 0.36607555 0.33618438 + 1503 0.3633864 0.34659657 + 1504 0.3671261 0.35464936 + 1505 0.36204112 0.36579284 + 1506 0.3622689 0.3768656 + 1507 0.36688542 0.3864508 + 1508 0.36730343 0.39659646 + 1509 0.36471826 0.40454155 + 1510 0.36134896 0.41567266 + 1511 0.3626191 0.42521894 + 1512 0.36018115 0.4317319 + 1513 0.36806744 0.6163647 + 1514 0.36430869 0.62511104 + 1515 0.36453426 0.6357687 + 1516 0.36463076 0.64478254 + 1517 0.36458263 0.6532718 + 1518 0.36823475 0.66654855 + 1519 0.3675797 0.67728984 + 1520 0.36398613 0.6835129 + 1521 0.36518046 0.6921958 + 1522 0.36593875 0.70287293 + 1523 0.36681974 0.71455455 + 1524 0.36434448 0.72708213 + 1525 0.36616552 0.73847663 + 1526 0.36655676 0.74711615 + 1527 0.36231196 0.7532689 + 1528 0.36311248 0.762935 + 1529 0.36436835 0.7765697 + 1530 0.36547247 0.78989726 + 1531 0.36622387 0.8004884 + 1532 0.3667355 0.8096755 + 1533 0.36656633 0.81391317 + 1534 0.37463725 0.25665742 + 1535 0.37150773 0.2637325 + 1536 0.37252763 0.27397594 + 1537 0.37708533 0.28667516 + 1538 0.37528884 0.29658672 + 1539 0.37900785 0.30409658 + 1540 0.3748258 0.31229717 + 1541 0.3760001 0.3241139 + 1542 0.37731725 0.33641443 + 1543 0.3726698 0.34534302 + 1544 0.37775376 0.3538031 + 1545 0.3724665 0.36210603 + 1546 0.37234032 0.3732435 + 1547 0.376787 0.38423142 + 1548 0.37374216 0.3945541 + 1549 0.37165385 0.4023682 + 1550 0.37695876 0.61391926 + 1551 0.3751726 0.62566864 + 1552 0.3733911 0.63541174 + 1553 0.37293467 0.6441986 + 1554 0.37640113 0.65641093 + 1555 0.38008472 0.66657925 + 1556 0.37624466 0.6753101 + 1557 0.37334743 0.6854637 + 1558 0.3750504 0.6971707 + 1559 0.37554073 0.7083334 + 1560 0.37514558 0.7154414 + 1561 0.37469506 0.7221907 + 1562 0.37590173 0.73305917 + 1563 0.374626 0.7440376 + 1564 0.3724166 0.75508416 + 1565 0.37373796 0.76739067 + 1566 0.37473068 0.7754593 + 1567 0.3765627 0.7843982 + 1568 0.37358642 0.7951234 + 1569 0.375485 0.80515385 + 1570 0.38326833 0.26462185 + 1571 0.38710102 0.2775825 + 1572 0.38608715 0.2865981 + 1573 0.38498238 0.29485646 + 1574 0.38737038 0.30371508 + 1575 0.38491017 0.3129435 + 1576 0.38781804 0.32224727 + 1577 0.3875054 0.33205462 + 1578 0.38436416 0.3442582 + 1579 0.38683626 0.3533804 + 1580 0.38304207 0.3629349 + 1581 0.382844 0.37421986 + 1582 0.38315508 0.3826716 + 1583 0.3870725 0.60842156 + 1584 0.38677344 0.6153754 + 1585 0.38649178 0.6274488 + 1586 0.38103053 0.6360764 + 1587 0.3861527 0.64775735 + 1588 0.38654235 0.6601372 + 1589 0.38679922 0.66698396 + 1590 0.38636407 0.6740393 + 1591 0.38192758 0.6818563 + 1592 0.3835384 0.6907894 + 1593 0.38678008 0.7032266 + 1594 0.38348043 0.71657044 + 1595 0.38235015 0.72624505 + 1596 0.38527933 0.7327271 + 1597 0.3835811 0.74039245 + 1598 0.38289663 0.74989265 + 1599 0.38346645 0.7607571 + 1600 0.384231 0.77340794 + 1601 0.38933265 0.78460556 + 1602 0.38423267 0.79563224 + 1603 0.38529322 0.80585134 + 1604 0.39578304 0.26770929 + 1605 0.39978975 0.27630025 + 1606 0.39525795 0.28743437 + 1607 0.39492637 0.29913244 + 1608 0.3931478 0.3077069 + 1609 0.39632547 0.31652558 + 1610 0.39441198 0.32560745 + 1611 0.39686427 0.33156914 + 1612 0.39580324 0.3401006 + 1613 0.3926697 0.34860212 + 1614 0.40087104 0.608797 + 1615 0.39671317 0.61357963 + 1616 0.39744586 0.6241678 + 1617 0.39218023 0.6360674 + 1618 0.39848512 0.6455603 + 1619 0.3956558 0.65594333 + 1620 0.39422637 0.66714454 + 1621 0.39512223 0.67670643 + 1622 0.39015523 0.68357545 + 1623 0.3939527 0.69327813 + 1624 0.398336 0.7023787 + 1625 0.39746457 0.71381736 + 1626 0.39222032 0.7265004 + 1627 0.39209142 0.73723316 + 1628 0.39039436 0.7451921 + 1629 0.3926313 0.7537209 + 1630 0.39470458 0.7649347 + 1631 0.39699605 0.77624387 + 1632 0.39956963 0.7856471 + 1633 0.3943936 0.7922848 + 1634 0.3950038 0.80197585 + 1635 0.40457988 0.26865655 + 1636 0.4086908 0.2737452 + 1637 0.4074151 0.28288332 + 1638 0.4066251 0.29496175 + 1639 0.40229005 0.30635217 + 1640 0.40819418 0.31530157 + 1641 0.40357232 0.32564756 + 1642 0.4030333 0.33442208 + 1643 0.4061818 0.34175363 + 1644 0.40719834 0.6076273 + 1645 0.40644243 0.61527807 + 1646 0.41012034 0.626106 + 1647 0.4036317 0.63551545 + 1648 0.40912583 0.6452368 + 1649 0.40432957 0.652967 + 1650 0.4042709 0.6621234 + 1651 0.4048412 0.6740205 + 1652 0.39999652 0.68464524 + 1653 0.40484312 0.6948599 + 1654 0.4085409 0.7065107 + 1655 0.40831727 0.7163845 + 1656 0.40435955 0.72486687 + 1657 0.400227 0.7337989 + 1658 0.4005374 0.7445963 + 1659 0.40354323 0.756862 + 1660 0.40720883 0.7686059 + 1661 0.40686485 0.7802944 + 1662 0.40597865 0.78692967 + 1663 0.40383452 0.79356563 + 1664 0.4061286 0.8028048 + 1665 0.4177143 0.27660748 + 1666 0.416481 0.28847095 + 1667 0.41550756 0.29609796 + 1668 0.414566 0.30466753 + 1669 0.41895023 0.31566006 + 1670 0.41343054 0.32312125 + 1671 0.41272056 0.3330399 + 1672 0.41616312 0.34376052 + 1673 0.41503844 0.608878 + 1674 0.41790915 0.6179664 + 1675 0.42094368 0.6278327 + 1676 0.41461906 0.6361103 + 1677 0.41969404 0.6453992 + 1678 0.41418424 0.6560192 + 1679 0.41242507 0.66663957 + 1680 0.41680554 0.67547977 + 1681 0.4110139 0.6852846 + 1682 0.4171377 0.6968554 + 1683 0.41846195 0.7072998 + 1684 0.41507265 0.71368986 + 1685 0.41598296 0.72283524 + 1686 0.41170827 0.7356707 + 1687 0.41287392 0.74959546 + 1688 0.4131112 0.7597382 + 1689 0.41735205 0.76611 + 1690 0.41775984 0.7761724 + 1691 0.4136339 0.7882541 + 1692 0.41212565 0.7971086 + 1693 0.41525897 0.8032903 + 1694 0.42682272 0.27526587 + 1695 0.4272786 0.28404433 + 1696 0.42435214 0.29645813 + 1697 0.42598414 0.30808806 + 1698 0.42773408 0.31692994 + 1699 0.4236398 0.3260299 + 1700 0.42291158 0.33658934 + 1701 0.42708406 0.34559077 + 1702 0.42677638 0.35246316 + 1703 0.42545038 0.60957104 + 1704 0.42968142 0.62032604 + 1705 0.4292182 0.6299916 + 1706 0.4244113 0.63675123 + 1707 0.4285267 0.64414436 + 1708 0.42750296 0.65429133 + 1709 0.42204013 0.6655239 + 1710 0.42809156 0.675597 + 1711 0.42241773 0.6856973 + 1712 0.4270931 0.6940824 + 1713 0.42752388 0.7039932 + 1714 0.4239455 0.71524227 + 1715 0.42421612 0.7230093 + 1716 0.42404762 0.730762 + 1717 0.42369312 0.74313504 + 1718 0.4244693 0.7575924 + 1719 0.424128 0.76856124 + 1720 0.4279815 0.7754053 + 1721 0.4270844 0.7861313 + 1722 0.42176437 0.7976622 + 1723 0.42158976 0.8040693 + 1724 0.43311524 0.27734953 + 1725 0.43679067 0.2826913 + 1726 0.43561545 0.29165587 + 1727 0.43491074 0.30242056 + 1728 0.43519408 0.31258878 + 1729 0.43468466 0.3224145 + 1730 0.43481517 0.33454907 + 1731 0.43676156 0.34511915 + 1732 0.4333158 0.35225976 + 1733 0.43722898 0.60976243 + 1734 0.43969983 0.6193584 + 1735 0.43760315 0.628031 + 1736 0.4336842 0.6372088 + 1737 0.43751138 0.6471967 + 1738 0.43742922 0.6567315 + 1739 0.43327755 0.665088 + 1740 0.4396891 0.6749453 + 1741 0.43435585 0.686736 + 1742 0.43402272 0.6969523 + 1743 0.43851537 0.7047025 + 1744 0.4334479 0.7125549 + 1745 0.4328026 0.7230891 + 1746 0.43575022 0.73672795 + 1747 0.433181 0.7484563 + 1748 0.4382614 0.75762343 + 1749 0.43302593 0.7676336 + 1750 0.4378686 0.7786289 + 1751 0.43741778 0.78903306 + 1752 0.43313015 0.79785603 + 1753 0.433953 0.8034657 + 1754 0.4458759 0.2864934 + 1755 0.44431922 0.2979835 + 1756 0.44374192 0.3079254 + 1757 0.44378963 0.31790262 + 1758 0.44260606 0.32657894 + 1759 0.4458839 0.33289316 + 1760 0.4445586 0.34120697 + 1761 0.44385466 0.35197645 + 1762 0.44769064 0.6062995 + 1763 0.44563618 0.6146188 + 1764 0.4485359 0.6241876 + 1765 0.44502518 0.63728315 + 1766 0.4466271 0.6471417 + 1767 0.44396588 0.6536889 + 1768 0.44497895 0.66341674 + 1769 0.45092866 0.67414105 + 1770 0.4465762 0.68460864 + 1771 0.4426439 0.69509643 + 1772 0.44905695 0.7038116 + 1773 0.4444296 0.7156043 + 1774 0.4437221 0.7275681 + 1775 0.4490629 0.73679733 + 1776 0.44367418 0.74721295 + 1777 0.4497625 0.75680774 + 1778 0.4453982 0.76805943 + 1779 0.44809136 0.77778935 + 1780 0.44603112 0.7863948 + 1781 0.44295067 0.79618347 + 1782 0.4567253 0.2864383 + 1783 0.454174 0.29557583 + 1784 0.45131475 0.3039561 + 1785 0.45256016 0.3128219 + 1786 0.45355454 0.32516283 + 1787 0.45355383 0.3369578 + 1788 0.45219427 0.34571153 + 1789 0.45598143 0.35469952 + 1790 0.45536458 0.3619158 + 1791 0.45599562 0.60395557 + 1792 0.45515543 0.6135657 + 1793 0.4588259 0.6228589 + 1794 0.458019 0.6337259 + 1795 0.45337692 0.6436132 + 1796 0.45336428 0.6539944 + 1797 0.45629135 0.665337 + 1798 0.45960546 0.6735103 + 1799 0.4585236 0.6830007 + 1800 0.45339945 0.6936336 + 1801 0.45851633 0.7018742 + 1802 0.4569333 0.71181196 + 1803 0.4565694 0.72553474 + 1804 0.45867056 0.7368152 + 1805 0.45599714 0.7468197 + 1806 0.4587629 0.7563182 + 1807 0.45644185 0.76472497 + 1808 0.4542811 0.77316916 + 1809 0.45683265 0.7826533 + 1810 0.4529875 0.794061 + 1811 0.4631228 0.28588507 + 1812 0.46504566 0.29311064 + 1813 0.46150482 0.30553812 + 1814 0.46106055 0.31649163 + 1815 0.4664877 0.32458535 + 1816 0.461965 0.333047 + 1817 0.4628283 0.34366173 + 1818 0.46800977 0.353804 + 1819 0.4627759 0.3617425 + 1820 0.4653327 0.6063118 + 1821 0.4642154 0.6167943 + 1822 0.46833128 0.62608117 + 1823 0.4682581 0.6361721 + 1824 0.4639368 0.64598465 + 1825 0.46446872 0.65884876 + 1826 0.46447465 0.66815585 + 1827 0.46788067 0.67694557 + 1828 0.4662213 0.6848142 + 1829 0.46517485 0.693334 + 1830 0.46812087 0.70670974 + 1831 0.46500498 0.7172329 + 1832 0.46931976 0.72534525 + 1833 0.46549246 0.7329413 + 1834 0.46625105 0.7418631 + 1835 0.46578097 0.7517709 + 1836 0.46579608 0.76132137 + 1837 0.4645944 0.772529 + 1838 0.46720284 0.7823617 + 1839 0.46457124 0.79213107 + 1840 0.47447148 0.29226252 + 1841 0.47512776 0.3024905 + 1842 0.47090894 0.31433526 + 1843 0.4779339 0.32359657 + 1844 0.47315016 0.3347997 + 1845 0.4746864 0.3464943 + 1846 0.47574154 0.35372138 + 1847 0.47591767 0.36239302 + 1848 0.476047 0.59745944 + 1849 0.47703627 0.6034088 + 1850 0.47352657 0.61519384 + 1851 0.48005736 0.62488794 + 1852 0.4755606 0.6330143 + 1853 0.4755323 0.642127 + 1854 0.47462818 0.65351623 + 1855 0.4741752 0.6662034 + 1856 0.47887763 0.67703795 + 1857 0.473373 0.68599534 + 1858 0.47818914 0.69730186 + 1859 0.47900277 0.7086652 + 1860 0.47415853 0.71668506 + 1861 0.4780891 0.7245059 + 1862 0.47667766 0.73502475 + 1863 0.474885 0.74761486 + 1864 0.47295558 0.756466 + 1865 0.47618 0.7658825 + 1866 0.47534707 0.77734995 + 1867 0.47461027 0.786984 + 1868 0.4734147 0.79457504 + 1869 0.48277268 0.29530618 + 1870 0.4878809 0.30358648 + 1871 0.48311025 0.31326795 + 1872 0.4897814 0.3231435 + 1873 0.4839707 0.33135307 + 1874 0.48396668 0.3407334 + 1875 0.4843101 0.35212228 + 1876 0.49036917 0.36242923 + 1877 0.48611733 0.3712409 + 1878 0.48802495 0.5968383 + 1879 0.48701853 0.60223496 + 1880 0.48627377 0.61373174 + 1881 0.49106425 0.62553 + 1882 0.4857012 0.6358722 + 1883 0.48518395 0.6483148 + 1884 0.48451722 0.65975565 + 1885 0.4844149 0.669324 + 1886 0.4894938 0.67731285 + 1887 0.48395997 0.68660265 + 1888 0.4886493 0.6948288 + 1889 0.48912686 0.70502216 + 1890 0.48548794 0.71756893 + 1891 0.4848408 0.72778046 + 1892 0.48902836 0.7350864 + 1893 0.48551503 0.7447763 + 1894 0.48209074 0.75551474 + 1895 0.48847342 0.764541 + 1896 0.4839216 0.77307445 + 1897 0.4855078 0.78301406 + 1898 0.48156926 0.79230785 + 1899 0.49110186 0.29668573 + 1900 0.49817413 0.30132928 + 1901 0.49693948 0.3124146 + 1902 0.5017586 0.32375044 + 1903 0.49496782 0.33441553 + 1904 0.49269077 0.34511042 + 1905 0.4968209 0.35386667 + 1906 0.5006888 0.36268765 + 1907 0.49843636 0.37219903 + 1908 0.49434784 0.598493 + 1909 0.49599952 0.60709417 + 1910 0.499296 0.6178766 + 1911 0.49962378 0.6274484 + 1912 0.49554032 0.6334964 + 1913 0.49706584 0.64386994 + 1914 0.49370474 0.6548992 + 1915 0.49500522 0.66645014 + 1916 0.49948242 0.6774072 + 1917 0.49519283 0.6872443 + 1918 0.4967853 0.69804466 + 1919 0.4974928 0.7051122 + 1920 0.4983041 0.713633 + 1921 0.49491987 0.72657406 + 1922 0.49629804 0.7344826 + 1923 0.49587432 0.7415994 + 1924 0.49448687 0.75350237 + 1925 0.5000516 0.7645208 + 1926 0.49405986 0.7743443 + 1927 0.4988192 0.7856974 + 1928 0.49018648 0.79108095 + 1929 0.50779927 0.3056837 + 1930 0.51013076 0.31613448 + 1931 0.509642 0.32399103 + 1932 0.5092541 0.33240372 + 1933 0.50346047 0.34435326 + 1934 0.50954086 0.3564351 + 1935 0.50839037 0.36846593 + 1936 0.5075588 0.37733707 + 1937 0.50468427 0.6005198 + 1938 0.5044095 0.6098156 + 1939 0.50979453 0.61609083 + 1940 0.5079838 0.62559676 + 1941 0.50431967 0.63486695 + 1942 0.508325 0.6435849 + 1943 0.5067585 0.6562374 + 1944 0.5066228 0.67041624 + 1945 0.5070408 0.6789251 + 1946 0.5034421 0.6842909 + 1947 0.5044761 0.6923738 + 1948 0.50573605 0.7037557 + 1949 0.5102115 0.71455777 + 1950 0.50510335 0.7227662 + 1951 0.5053279 0.7344946 + 1952 0.50452894 0.7469357 + 1953 0.50482666 0.756205 + 1954 0.51088226 0.7631602 + 1955 0.5075727 0.77495104 + 1956 0.5100303 0.7857549 + 1957 0.5176169 0.30823982 + 1958 0.5197903 0.31521207 + 1959 0.51757395 0.32370305 + 1960 0.52000326 0.33278003 + 1961 0.51765454 0.34385815 + 1962 0.5221124 0.35607746 + 1963 0.5178929 0.36569494 + 1964 0.51634353 0.37640437 + 1965 0.51888007 0.38343486 + 1966 0.5157453 0.5987336 + 1967 0.5122861 0.6076061 + 1968 0.51733714 0.61371094 + 1969 0.5174868 0.6221164 + 1970 0.51745933 0.6353344 + 1971 0.5160779 0.64774436 + 1972 0.520517 0.65652394 + 1973 0.516745 0.6666087 + 1974 0.5146134 0.6770355 + 1975 0.5109334 0.68562466 + 1976 0.51466864 0.6953949 + 1977 0.5181216 0.70722055 + 1978 0.51720643 0.71546566 + 1979 0.51669526 0.7244666 + 1980 0.5166656 0.7359553 + 1981 0.51243776 0.7428588 + 1982 0.5141739 0.75259835 + 1983 0.5195458 0.7606734 + 1984 0.5191559 0.76960707 + 1985 0.5200466 0.7812726 + 1986 0.5254085 0.31004336 + 1987 0.52837735 0.317996 + 1988 0.52608764 0.32748136 + 1989 0.5296887 0.336505 + 1990 0.52979976 0.34846395 + 1991 0.5308069 0.35737616 + 1992 0.5272141 0.36460608 + 1993 0.5239061 0.37213963 + 1994 0.5258655 0.38132504 + 1995 0.5261154 0.59780145 + 1996 0.521737 0.6068915 + 1997 0.5253861 0.61599135 + 1998 0.52701265 0.6261348 + 1999 0.5312139 0.63567996 + 2000 0.52737546 0.64713955 + 2001 0.52924496 0.6568999 + 2002 0.52691543 0.66463906 + 2003 0.5249728 0.6749317 + 2004 0.5212439 0.68585217 + 2005 0.5273769 0.69764584 + 2006 0.5277829 0.7081819 + 2007 0.5237236 0.7156086 + 2008 0.5278451 0.7230864 + 2009 0.52734995 0.7336962 + 2010 0.5214536 0.74407893 + 2011 0.52553964 0.75390464 + 2012 0.5280268 0.7638072 + 2013 0.5289337 0.77349776 + 2014 0.53160745 0.7819559 + 2015 0.53965634 0.3171252 + 2016 0.53499144 0.3264831 + 2017 0.5394788 0.33360058 + 2018 0.54010546 0.34293053 + 2019 0.53865474 0.35403734 + 2020 0.53641915 0.36366934 + 2021 0.5322972 0.37263778 + 2022 0.53768814 0.3822341 + 2023 0.5382545 0.38970348 + 2024 0.5363912 0.59629357 + 2025 0.5335372 0.60762537 + 2026 0.53523016 0.61962324 + 2027 0.5353863 0.6282181 + 2028 0.53988177 0.6337781 + 2029 0.5403127 0.64362776 + 2030 0.5369059 0.65428936 + 2031 0.53454065 0.6619897 + 2032 0.5354389 0.6709812 + 2033 0.5347841 0.6845915 + 2034 0.5398862 0.6971668 + 2035 0.5349947 0.7052496 + 2036 0.53458863 0.71526045 + 2037 0.5367836 0.7264072 + 2038 0.53940505 0.7365154 + 2039 0.5325339 0.7452562 + 2040 0.53754205 0.75676996 + 2041 0.53752935 0.76814723 + 2042 0.53732544 0.7760023 + 2043 0.5409607 0.78167504 + 2044 0.5478484 0.31686926 + 2045 0.5468366 0.32625198 + 2046 0.54594535 0.33587918 + 2047 0.54933923 0.3417881 + 2048 0.5480586 0.3502664 + 2049 0.5468953 0.36150336 + 2050 0.5427655 0.37182453 + 2051 0.5463215 0.59439784 + 2052 0.54345906 0.60298985 + 2053 0.54643553 0.613931 + 2054 0.54368865 0.6259942 + 2055 0.5489443 0.63549954 + 2056 0.55222166 0.6461896 + 2057 0.5458341 0.65296537 + 2058 0.54420775 0.6632073 + 2059 0.5471695 0.6766243 + 2060 0.5472837 0.689061 + 2061 0.54949844 0.69850403 + 2062 0.5452464 0.7080796 + 2063 0.5456341 0.7203015 + 2064 0.5458169 0.7296227 + 2065 0.5500075 0.73763305 + 2066 0.54392546 0.7464543 + 2067 0.5495444 0.7556353 + 2068 0.5457837 0.7640103 + 2069 0.5476583 0.7746373 + 2070 0.54743475 0.78198814 + 2071 0.55413765 0.3193945 + 2072 0.5587065 0.32586756 + 2073 0.5540882 0.33485395 + 2074 0.5586106 0.3450269 + 2075 0.55485404 0.35631102 + 2076 0.55359995 0.3630655 + 2077 0.55436355 0.5873485 + 2078 0.5549404 0.59168684 + 2079 0.5545886 0.6027938 + 2080 0.55821943 0.61362237 + 2081 0.55636317 0.6250555 + 2082 0.5613724 0.6384984 + 2083 0.56145453 0.64908886 + 2084 0.55561656 0.65759003 + 2085 0.55399495 0.6681094 + 2086 0.55919284 0.6762877 + 2087 0.55521965 0.6842404 + 2088 0.5570358 0.693341 + 2089 0.55794144 0.70496875 + 2090 0.5540757 0.7152266 + 2091 0.55723685 0.7272967 + 2092 0.55912554 0.73905724 + 2093 0.5545608 0.7468695 + 2094 0.5588323 0.75485504 + 2095 0.5567125 0.7647815 + 2096 0.5601957 0.7755382 + 2097 0.5687296 0.3247948 + 2098 0.5651728 0.3343311 + 2099 0.56610954 0.3411168 + 2100 0.56688493 0.5880543 + 2101 0.56618524 0.59527546 + 2102 0.5665024 0.60780495 + 2103 0.5672134 0.6186798 + 2104 0.5687914 0.62934524 + 2105 0.5717679 0.6379847 + 2106 0.5703101 0.64649 + 2107 0.5679265 0.6567701 + 2108 0.56380665 0.66690016 + 2109 0.5695837 0.6759809 + 2110 0.5653443 0.68595445 + 2111 0.5668205 0.69740814 + 2112 0.5685258 0.70677996 + 2113 0.56427586 0.7155551 + 2114 0.57107353 0.7251162 + 2115 0.56787825 0.73593 + 2116 0.56599003 0.7475676 + 2117 0.5674301 0.75938994 + 2118 0.5676303 0.76934737 + 2119 0.56872827 0.7765975 + 2120 0.5780381 0.19167876 + 2121 0.5751819 0.32395405 + 2122 0.5735426 0.5889425 + 2123 0.5773766 0.5951785 + 2124 0.57652986 0.6033062 + 2125 0.5761985 0.61333036 + 2126 0.57722026 0.623098 + 2127 0.5789372 0.63290405 + 2128 0.5796058 0.6427877 + 2129 0.57994723 0.6539006 + 2130 0.57657534 0.6667247 + 2131 0.57831645 0.6770328 + 2132 0.5742475 0.68305445 + 2133 0.5752096 0.6914507 + 2134 0.57675767 0.7020325 + 2135 0.57675374 0.7139993 + 2136 0.5818608 0.724205 + 2137 0.57842517 0.7337355 + 2138 0.57546765 0.7428066 + 2139 0.57872343 0.75404036 + 2140 0.57677406 0.76571083 + 2141 0.5759993 0.7740362 + 2142 0.58765334 0.19235027 + 2143 0.58332336 0.5895055 + 2144 0.5871511 0.59899193 + 2145 0.58559483 0.6094343 + 2146 0.58403176 0.6178401 + 2147 0.5881591 0.6266381 + 2148 0.5882 0.63767314 + 2149 0.5886673 0.64783686 + 2150 0.5886671 0.6547502 + 2151 0.5881058 0.6619891 + 2152 0.5884351 0.67454535 + 2153 0.58272755 0.6849016 + 2154 0.58525926 0.69541955 + 2155 0.58786625 0.7071997 + 2156 0.5868273 0.7171502 + 2157 0.5901195 0.72362673 + 2158 0.58792955 0.7315959 + 2159 0.5863772 0.7427321 + 2160 0.5919021 0.7548763 + 2161 0.5872191 0.7651431 + 2162 0.5837026 0.7722774 + 2163 0.5992622 0.19315286 + 2164 0.5947143 0.5906141 + 2165 0.595677 0.5986026 + 2166 0.59655505 0.60648775 + 2167 0.5929075 0.6168151 + 2168 0.5995355 0.62497807 + 2169 0.59626245 0.6332659 + 2170 0.59769535 0.64264154 + 2171 0.59807795 0.65526986 + 2172 0.5970806 0.66673905 + 2173 0.6014509 0.6764926 + 2174 0.5948403 0.687949 + 2175 0.59404624 0.69903344 + 2176 0.5978007 0.70607793 + 2177 0.5974625 0.7167266 + 2178 0.5964604 0.7284354 + 2179 0.5943368 0.73679316 + 2180 0.59792054 0.745207 + 2181 0.6030982 0.7554404 + 2182 0.59815466 0.7666253 + 2183 0.5986801 0.77311087 + 2184 0.60723627 0.19367698 + 2185 0.60587364 0.58782727 + 2186 0.60409826 0.59840804 + 2187 0.6067114 0.6077076 + 2188 0.60341984 0.6156122 + 2189 0.6086085 0.6231762 + 2190 0.6077625 0.63440716 + 2191 0.60733247 0.6473644 + 2192 0.6078764 0.65539694 + 2193 0.6094398 0.6653602 + 2194 0.61145204 0.6775872 + 2195 0.6075318 0.6867164 + 2196 0.6043635 0.69854206 + 2197 0.6051331 0.708894 + 2198 0.6094626 0.7165257 + 2199 0.6058572 0.725875 + 2200 0.60301054 0.7359384 + 2201 0.6088459 0.7453788 + 2202 0.61350006 0.7554086 + 2203 0.60833675 0.7650676 + 2204 0.61661994 0.1941352 + 2205 0.61434656 0.5850678 + 2206 0.6156187 0.59419453 + 2207 0.6132243 0.6035374 + 2208 0.6160196 0.6145735 + 2209 0.6162091 0.6263241 + 2210 0.6205507 0.63459235 + 2211 0.6159605 0.64285797 + 2212 0.6167829 0.65351945 + 2213 0.62256604 0.6635881 + 2214 0.620459 0.67412305 + 2215 0.61845446 0.68514335 + 2216 0.6146097 0.6945178 + 2217 0.61644727 0.70657146 + 2218 0.6176721 0.7173294 + 2219 0.6140207 0.72368914 + 2220 0.614627 0.73386765 + 2221 0.6209389 0.7463218 + 2222 0.6217757 0.7561852 + 2223 0.61806023 0.7639787 + 2224 0.6264862 0.19367306 + 2225 0.6296243 0.19932391 + 2226 0.6242218 0.5869362 + 2227 0.6238164 0.59481215 + 2228 0.6234745 0.6028662 + 2229 0.62822384 0.61256564 + 2230 0.6280783 0.62485623 + 2231 0.6278906 0.63470745 + 2232 0.62748116 0.6443235 + 2233 0.6270356 0.65558547 + 2234 0.63143337 0.66208345 + 2235 0.6304714 0.6706471 + 2236 0.63050836 0.68223363 + 2237 0.6261919 0.69553864 + 2238 0.6280459 0.7060954 + 2239 0.6258967 0.7149962 + 2240 0.62237287 0.72478384 + 2241 0.6272554 0.7349839 + 2242 0.632326 0.745204 + 2243 0.6282283 0.75311697 + 2244 0.6281817 0.7620432 + 2245 0.63716054 0.19358549 + 2246 0.63594633 0.20093267 + 2247 0.63827807 0.5851485 + 2248 0.63182545 0.5953047 + 2249 0.6354076 0.6051626 + 2250 0.63808155 0.615417 + 2251 0.64217645 0.6256499 + 2252 0.6355234 0.6350044 + 2253 0.6392476 0.6438799 + 2254 0.6370771 0.65427077 + 2255 0.6402021 0.6661371 + 2256 0.63783604 0.67549133 + 2257 0.6405611 0.682311 + 2258 0.63968664 0.6921159 + 2259 0.63552386 0.7019059 + 2260 0.6360344 0.7113307 + 2261 0.6346232 0.723742 + 2262 0.63852227 0.73587704 + 2263 0.6410105 0.7450472 + 2264 0.63791823 0.7557798 + 2265 0.6353497 0.7638504 + 2266 0.646727 0.19099912 + 2267 0.6456817 0.19953665 + 2268 0.648671 0.57879674 + 2269 0.65237457 0.58634275 + 2270 0.64567995 0.59698397 + 2271 0.6451434 0.6079303 + 2272 0.64952856 0.6163982 + 2273 0.65362406 0.6256804 + 2274 0.64839613 0.63654315 + 2275 0.64792734 0.6491435 + 2276 0.6464313 0.65853333 + 2277 0.65083367 0.6657123 + 2278 0.64755434 0.6759354 + 2279 0.6473061 0.6855597 + 2280 0.65013474 0.69268644 + 2281 0.64756787 0.7043036 + 2282 0.6443713 0.7167739 + 2283 0.6476848 0.7272949 + 2284 0.6480492 0.73887277 + 2285 0.6481151 0.749423 + 2286 0.6475838 0.75965095 + 2287 0.64741313 0.7644796 + 2288 0.65541166 0.19234703 + 2289 0.6585244 0.20287985 + 2290 0.6594968 0.578922 + 2291 0.66250753 0.58496904 + 2292 0.6597128 0.5933624 + 2293 0.65710735 0.6057729 + 2294 0.6612322 0.6180197 + 2295 0.6605225 0.6253661 + 2296 0.6601536 0.63212675 + 2297 0.6603436 0.6442336 + 2298 0.65625906 0.6572404 + 2299 0.65709734 0.66466945 + 2300 0.6576391 0.67150295 + 2301 0.6586431 0.68456084 + 2302 0.65745693 0.69668853 + 2303 0.6613762 0.70559007 + 2304 0.6557641 0.7170638 + 2305 0.65602875 0.7257708 + 2306 0.65609825 0.732773 + 2307 0.6566248 0.74270165 + 2308 0.6573473 0.75440747 + 2309 0.6670867 0.18651864 + 2310 0.6664328 0.19224097 + 2311 0.6709869 0.20349413 + 2312 0.6694497 0.57870257 + 2313 0.6716335 0.58763164 + 2314 0.6691619 0.59863126 + 2315 0.6695388 0.60924214 + 2316 0.6713772 0.61813414 + 2317 0.6672576 0.6256575 + 2318 0.6710139 0.6352562 + 2319 0.67128015 0.6450823 + 2320 0.667607 0.6541007 + 2321 0.6637611 0.6640747 + 2322 0.66807735 0.67384124 + 2323 0.67153764 0.68384695 + 2324 0.66950357 0.69613224 + 2325 0.66909814 0.7054557 + 2326 0.668652 0.7136655 + 2327 0.6643419 0.7258363 + 2328 0.6635275 0.7360084 + 2329 0.66633755 0.7446095 + 2330 0.6686028 0.7543999 + 2331 0.6775815 0.18644437 + 2332 0.67819387 0.19312029 + 2333 0.6805622 0.20533817 + 2334 0.68268746 0.2114379 + 2335 0.6794883 0.578311 + 2336 0.6831351 0.58596283 + 2337 0.6782377 0.59367675 + 2338 0.67900956 0.6022863 + 2339 0.6796281 0.61276865 + 2340 0.67946905 0.62507695 + 2341 0.67939 0.6337497 + 2342 0.6794465 0.6408291 + 2343 0.6781372 0.6508939 + 2344 0.67601967 0.66291976 + 2345 0.68098617 0.67595536 + 2346 0.6805243 0.6885848 + 2347 0.68056 0.69777477 + 2348 0.6767079 0.70629936 + 2349 0.6769329 0.7138035 + 2350 0.6759474 0.7213702 + 2351 0.6739516 0.73400736 + 2352 0.6776679 0.7460212 + 2353 0.6767516 0.75509036 + 2354 0.6877457 0.18541478 + 2355 0.68896335 0.19113863 + 2356 0.6864791 0.20007695 + 2357 0.6892429 0.20924845 + 2358 0.68953234 0.5775195 + 2359 0.6917098 0.58479536 + 2360 0.68846273 0.5940243 + 2361 0.68930954 0.6055668 + 2362 0.6893171 0.6164564 + 2363 0.6902896 0.6248534 + 2364 0.6877408 0.6338276 + 2365 0.6892632 0.646104 + 2366 0.68534875 0.65620947 + 2367 0.6883829 0.6651993 + 2368 0.6921514 0.67388797 + 2369 0.69035435 0.68324655 + 2370 0.69020885 0.6944129 + 2371 0.68573743 0.70330685 + 2372 0.6861784 0.7137586 + 2373 0.68521315 0.72698134 + 2374 0.68416744 0.73706615 + 2375 0.68881303 0.7442984 + 2376 0.68468577 0.7525678 + 2377 0.7005563 0.18610679 + 2378 0.7006191 0.19272572 + 2379 0.6954412 0.20152958 + 2380 0.69985497 0.21140528 + 2381 0.70006377 0.5783253 + 2382 0.69755584 0.5882852 + 2383 0.7005696 0.5978095 + 2384 0.6991003 0.6102378 + 2385 0.6982778 0.620373 + 2386 0.69675124 0.62860346 + 2387 0.69969916 0.63758755 + 2388 0.6995527 0.6474615 + 2389 0.6950514 0.65584815 + 2390 0.7008946 0.66628397 + 2391 0.70026845 0.67869246 + 2392 0.6980578 0.68786573 + 2393 0.7012779 0.6958154 + 2394 0.6948477 0.70418406 + 2395 0.69782835 0.7123265 + 2396 0.6957135 0.7216215 + 2397 0.6948625 0.73393553 + 2398 0.69845426 0.7448081 + 2399 0.6926911 0.7513121 + 2400 0.7076137 0.1877229 + 2401 0.7122106 0.19576363 + 2402 0.70750153 0.20459974 + 2403 0.7085348 0.21433961 + 2404 0.71212447 0.5757102 + 2405 0.7071554 0.586604 + 2406 0.7118846 0.59456325 + 2407 0.7107711 0.60560507 + 2408 0.70649296 0.6157791 + 2409 0.7077929 0.62642586 + 2410 0.71000177 0.63675964 + 2411 0.7068449 0.64396346 + 2412 0.70698714 0.65378726 + 2413 0.71154565 0.66284347 + 2414 0.71207297 0.6737233 + 2415 0.70819813 0.68714 + 2416 0.7086126 0.69585145 + 2417 0.7076337 0.7054167 + 2418 0.70444256 0.71658903 + 2419 0.7053096 0.72605014 + 2420 0.70589757 0.7366363 + 2421 0.7076409 0.7461345 + 2422 0.71858704 0.18890193 + 2423 0.72126716 0.1974342 + 2424 0.7177065 0.20331793 + 2425 0.71816903 0.21319476 + 2426 0.72160834 0.512668 + 2427 0.7204148 0.5223805 + 2428 0.7228329 0.5362165 + 2429 0.72178066 0.5425752 + 2430 0.7230136 0.5504199 + 2431 0.72337276 0.5603907 + 2432 0.7225885 0.5712064 + 2433 0.72092944 0.58507156 + 2434 0.72016746 0.5978829 + 2435 0.7207488 0.60680884 + 2436 0.71655583 0.61636573 + 2437 0.7169048 0.6244478 + 2438 0.7176474 0.63163924 + 2439 0.71803045 0.64425313 + 2440 0.71712416 0.6559044 + 2441 0.7208063 0.66458935 + 2442 0.72313386 0.67359364 + 2443 0.7198595 0.68303406 + 2444 0.7172767 0.69505376 + 2445 0.7210522 0.70601916 + 2446 0.71542186 0.7174944 + 2447 0.7151097 0.72997695 + 2448 0.71365666 0.7388718 + 2449 0.7168858 0.7453889 + 2450 0.72714126 0.18609188 + 2451 0.7284538 0.19362919 + 2452 0.7294088 0.20569651 + 2453 0.7281588 0.21817964 + 2454 0.72759604 0.22275873 + 2455 0.7333395 0.31163543 + 2456 0.7326683 0.31823 + 2457 0.7340157 0.32623464 + 2458 0.73498195 0.3371883 + 2459 0.732668 0.34677032 + 2460 0.73417294 0.35596704 + 2461 0.73184514 0.365733 + 2462 0.73389685 0.37509862 + 2463 0.7313999 0.3852446 + 2464 0.7338051 0.39458287 + 2465 0.73224026 0.406241 + 2466 0.73017025 0.41507146 + 2467 0.7316777 0.42367485 + 2468 0.7329091 0.43513265 + 2469 0.7304745 0.44606873 + 2470 0.7291461 0.45565724 + 2471 0.72750175 0.4637938 + 2472 0.7295044 0.4722942 + 2473 0.73114455 0.48372155 + 2474 0.7285348 0.49481112 + 2475 0.7258855 0.50332457 + 2476 0.7277999 0.5128543 + 2477 0.7251363 0.52256787 + 2478 0.7284139 0.5316938 + 2479 0.7288331 0.54282784 + 2480 0.73084736 0.5539145 + 2481 0.73150593 0.56459963 + 2482 0.7318238 0.5755949 + 2483 0.733898 0.5859454 + 2484 0.72809553 0.5932993 + 2485 0.7287135 0.6021371 + 2486 0.7275736 0.6122187 + 2487 0.7255852 0.6234605 + 2488 0.72753185 0.63463646 + 2489 0.7298053 0.643379 + 2490 0.7283671 0.654153 + 2491 0.73277754 0.6674945 + 2492 0.73030984 0.6792934 + 2493 0.7282584 0.6895409 + 2494 0.72726554 0.6984737 + 2495 0.7319609 0.70591277 + 2496 0.7265523 0.7138183 + 2497 0.7275096 0.7245782 + 2498 0.72253644 0.7362019 + 2499 0.72722554 0.74381214 + 2500 0.73550797 0.18732107 + 2501 0.7388418 0.1964941 + 2502 0.7435558 0.20615304 + 2503 0.73916155 0.21738549 + 2504 0.74013394 0.22573128 + 2505 0.740758 0.23334274 + 2506 0.737952 0.24156857 + 2507 0.7407788 0.2509301 + 2508 0.7392713 0.2622539 + 2509 0.73698074 0.27095708 + 2510 0.73951846 0.28147855 + 2511 0.7365618 0.2949205 + 2512 0.7371215 0.30609137 + 2513 0.7407267 0.3167488 + 2514 0.7414353 0.3293205 + 2515 0.74174434 0.33678836 + 2516 0.7417456 0.3459054 + 2517 0.7410063 0.35525355 + 2518 0.74055505 0.36393684 + 2519 0.7434037 0.37371284 + 2520 0.7405229 0.38400707 + 2521 0.7430505 0.39284614 + 2522 0.7416902 0.4017969 + 2523 0.740859 0.41458187 + 2524 0.7409979 0.42695662 + 2525 0.742721 0.43550757 + 2526 0.7402595 0.4439462 + 2527 0.73713875 0.45247534 + 2528 0.73725903 0.46297455 + 2529 0.7404321 0.47577596 + 2530 0.73959553 0.48395145 + 2531 0.740168 0.49226463 + 2532 0.7351559 0.50321424 + 2533 0.73950833 0.5119767 + 2534 0.738113 0.5239075 + 2535 0.73783284 0.5375265 + 2536 0.73727745 0.54751694 + 2537 0.7413033 0.55784607 + 2538 0.73937345 0.56880635 + 2539 0.7429318 0.57813793 + 2540 0.7429658 0.58819443 + 2541 0.73689586 0.5956173 + 2542 0.7388695 0.60720503 + 2543 0.73494107 0.61754394 + 2544 0.7378677 0.6276021 + 2545 0.73621905 0.6377128 + 2546 0.7389107 0.64636296 + 2547 0.74125355 0.65736455 + 2548 0.7449621 0.6671083 + 2549 0.7408156 0.676689 + 2550 0.737142 0.6856229 + 2551 0.73772866 0.6959244 + 2552 0.7423819 0.70621073 + 2553 0.73665076 0.71509594 + 2554 0.7413914 0.7248726 + 2555 0.73464185 0.7345597 + 2556 0.7397344 0.74319047 + 2557 0.7457331 0.1882441 + 2558 0.75042367 0.19813013 + 2559 0.7512593 0.20561029 + 2560 0.75227666 0.2138462 + 2561 0.7486152 0.22620627 + 2562 0.7494655 0.23575601 + 2563 0.74557596 0.24236472 + 2564 0.75006586 0.24964085 + 2565 0.7508273 0.2599701 + 2566 0.74620336 0.2715671 + 2567 0.7516486 0.2825691 + 2568 0.7462224 0.29139996 + 2569 0.7466727 0.30346304 + 2570 0.75234425 0.3148681 + 2571 0.7483672 0.3242614 + 2572 0.7489865 0.33484215 + 2573 0.7530288 0.3453384 + 2574 0.7477622 0.35529304 + 2575 0.75215083 0.36662638 + 2576 0.75019985 0.37898466 + 2577 0.74826276 0.38766977 + 2578 0.7512712 0.39623594 + 2579 0.74921125 0.40633658 + 2580 0.752954 0.41447565 + 2581 0.7482526 0.42210993 + 2582 0.749748 0.430697 + 2583 0.7498062 0.44075185 + 2584 0.74857634 0.45366564 + 2585 0.7485208 0.46705765 + 2586 0.7503557 0.47632608 + 2587 0.7466339 0.48397118 + 2588 0.75106287 0.4920687 + 2589 0.7490595 0.5040019 + 2590 0.74746245 0.5158759 + 2591 0.7520978 0.52506757 + 2592 0.7467843 0.53372955 + 2593 0.7477391 0.54557025 + 2594 0.7531695 0.5567264 + 2595 0.7495309 0.56802404 + 2596 0.7509196 0.5763404 + 2597 0.7523237 0.58436126 + 2598 0.74893343 0.59712577 + 2599 0.75026375 0.60866296 + 2600 0.7447547 0.61742663 + 2601 0.7489896 0.62596714 + 2602 0.7469693 0.6368147 + 2603 0.75090003 0.64908177 + 2604 0.7517241 0.6603291 + 2605 0.7521813 0.6670846 + 2606 0.75116843 0.6740527 + 2607 0.74864256 0.6868167 + 2608 0.748427 0.69902897 + 2609 0.7494521 0.70616126 + 2610 0.74998856 0.7151728 + 2611 0.75009364 0.72510326 + 2612 0.74934477 0.73467183 + 2613 0.7491511 0.74250835 + 2614 0.75701904 0.18918195 + 2615 0.7577849 0.19705448 + 2616 0.75879925 0.20448178 + 2617 0.764008 0.21385284 + 2618 0.760552 0.22345631 + 2619 0.7579498 0.2339537 + 2620 0.7544019 0.24283992 + 2621 0.7587009 0.25196314 + 2622 0.76177704 0.26118588 + 2623 0.7589212 0.27207077 + 2624 0.76226515 0.28426227 + 2625 0.756693 0.29454255 + 2626 0.7570712 0.30570078 + 2627 0.7628551 0.31351435 + 2628 0.7584968 0.32564616 + 2629 0.7583788 0.33683163 + 2630 0.7632575 0.3445287 + 2631 0.7583985 0.35482606 + 2632 0.7645084 0.3641269 + 2633 0.7606778 0.37564504 + 2634 0.7565658 0.38633928 + 2635 0.7610346 0.3941195 + 2636 0.7595416 0.40462798 + 2637 0.76330876 0.41540098 + 2638 0.7568883 0.42383116 + 2639 0.7600059 0.43499717 + 2640 0.7576329 0.44564345 + 2641 0.7615367 0.45425636 + 2642 0.7564997 0.4621126 + 2643 0.7579954 0.4713841 + 2644 0.75818604 0.48333836 + 2645 0.76128215 0.4966804 + 2646 0.7593047 0.5054363 + 2647 0.75860304 0.5144209 + 2648 0.7635033 0.52587646 + 2649 0.7582635 0.5366543 + 2650 0.7597667 0.54917365 + 2651 0.7606722 0.55642545 + 2652 0.7602517 0.5635764 + 2653 0.75903624 0.5750122 + 2654 0.76157504 0.58387613 + 2655 0.76007384 0.5921482 + 2656 0.761187 0.6039596 + 2657 0.75752676 0.61782527 + 2658 0.75775933 0.6304456 + 2659 0.7581045 0.6409162 + 2660 0.75918114 0.6476205 + 2661 0.7601967 0.6546244 + 2662 0.7609266 0.6670687 + 2663 0.75953716 0.67982256 + 2664 0.7589834 0.6887235 + 2665 0.7553457 0.6948898 + 2666 0.7569748 0.7042297 + 2667 0.763274 0.7139864 + 2668 0.75961334 0.7256462 + 2669 0.7614831 0.73629296 + 2670 0.7679444 0.18707514 + 2671 0.7649007 0.19660375 + 2672 0.7709408 0.20657593 + 2673 0.7710338 0.21420383 + 2674 0.7704273 0.22080222 + 2675 0.7700191 0.23217788 + 2676 0.7646157 0.24325626 + 2677 0.77046597 0.25475922 + 2678 0.76991355 0.26705983 + 2679 0.76972866 0.2777644 + 2680 0.77039224 0.28634074 + 2681 0.76612175 0.29222915 + 2682 0.766814 0.30217114 + 2683 0.77206695 0.3114082 + 2684 0.7704259 0.32145685 + 2685 0.7683272 0.33396095 + 2686 0.77173865 0.34325555 + 2687 0.7699764 0.35317424 + 2688 0.7734888 0.36218464 + 2689 0.7727123 0.37242636 + 2690 0.76829654 0.38545296 + 2691 0.7698385 0.3980114 + 2692 0.76957434 0.4078979 + 2693 0.77396166 0.41632545 + 2694 0.7672735 0.425323 + 2695 0.77058506 0.43422353 + 2696 0.76829517 0.44451773 + 2697 0.7723754 0.45541546 + 2698 0.76586515 0.4641306 + 2699 0.7685287 0.47524068 + 2700 0.7714386 0.4875815 + 2701 0.77164483 0.49762583 + 2702 0.7683233 0.5066097 + 2703 0.7705814 0.5180727 + 2704 0.7728023 0.5272901 + 2705 0.7688192 0.53382593 + 2706 0.7693046 0.54348135 + 2707 0.7696142 0.55637753 + 2708 0.76964 0.569123 + 2709 0.76915014 0.58004403 + 2710 0.7673382 0.58801335 + 2711 0.7690899 0.5957708 + 2712 0.7713278 0.6035195 + 2713 0.77099955 0.6129254 + 2714 0.768623 0.6256864 + 2715 0.7662606 0.63578767 + 2716 0.7675128 0.64610755 + 2717 0.77091926 0.6578843 + 2718 0.77186465 0.6671522 + 2719 0.7697844 0.6759754 + 2720 0.76767784 0.6864854 + 2721 0.7636702 0.6956962 + 2722 0.76861376 0.7046398 + 2723 0.77291924 0.7126373 + 2724 0.7715026 0.7214571 + 2725 0.7715868 0.73272735 + 2726 0.77675736 0.1850776 + 2727 0.77689075 0.19548833 + 2728 0.78215694 0.20600462 + 2729 0.77873296 0.2157543 + 2730 0.7781802 0.22556272 + 2731 0.7822427 0.23451392 + 2732 0.7761219 0.243801 + 2733 0.7809792 0.25269166 + 2734 0.78110164 0.26331627 + 2735 0.7774253 0.27321595 + 2736 0.77938 0.28361508 + 2737 0.7744022 0.2938468 + 2738 0.77848065 0.30407256 + 2739 0.78180164 0.3160093 + 2740 0.7791218 0.3284431 + 2741 0.77707535 0.33783096 + 2742 0.7802365 0.3469774 + 2743 0.7784722 0.3565013 + 2744 0.78198785 0.3647964 + 2745 0.7821887 0.37402958 + 2746 0.77818173 0.3808614 + 2747 0.77945447 0.39086923 + 2748 0.7814869 0.40521166 + 2749 0.78335226 0.41703478 + 2750 0.77909255 0.4272221 + 2751 0.7783914 0.4391144 + 2752 0.7776177 0.44799492 + 2753 0.78270096 0.4552672 + 2754 0.7782375 0.4663161 + 2755 0.77941954 0.4786118 + 2756 0.78124315 0.48682588 + 2757 0.7797529 0.49463296 + 2758 0.77745926 0.50255466 + 2759 0.7794699 0.5114285 + 2760 0.78088975 0.52282137 + 2761 0.78031397 0.53590417 + 2762 0.7791473 0.54908264 + 2763 0.77892834 0.556518 + 2764 0.77928585 0.56385183 + 2765 0.78051597 0.5760358 + 2766 0.77676994 0.58836395 + 2767 0.7777416 0.5987724 + 2768 0.7774962 0.6063009 + 2769 0.7808197 0.61203676 + 2770 0.7798375 0.62136185 + 2771 0.779227 0.63601553 + 2772 0.77859807 0.6502401 + 2773 0.77856654 0.65722674 + 2774 0.77862376 0.66310257 + 2775 0.7789522 0.671931 + 2776 0.77962863 0.6835566 + 2777 0.7743633 0.69521326 + 2778 0.7804169 0.7059797 + 2779 0.78075767 0.716979 + 2780 0.7808566 0.72661567 + 2781 0.78143704 0.7343914 + 2782 0.7871228 0.18777607 + 2783 0.7883278 0.1996073 + 2784 0.7890578 0.20626548 + 2785 0.7888742 0.2127243 + 2786 0.7894352 0.22473772 + 2787 0.7912673 0.23555003 + 2788 0.788381 0.24546292 + 2789 0.7888044 0.2561904 + 2790 0.79312646 0.26502967 + 2791 0.786963 0.2743575 + 2792 0.791505 0.2851615 + 2793 0.7851919 0.29475504 + 2794 0.79061437 0.30647007 + 2795 0.79082215 0.3156172 + 2796 0.7911407 0.32497776 + 2797 0.7860581 0.33672577 + 2798 0.791684 0.34614658 + 2799 0.7868013 0.3554983 + 2800 0.790664 0.36255527 + 2801 0.7897773 0.37055534 + 2802 0.7884763 0.38161874 + 2803 0.7907492 0.3942113 + 2804 0.7947188 0.4045853 + 2805 0.7906589 0.4130127 + 2806 0.79179347 0.42356843 + 2807 0.78850126 0.43512005 + 2808 0.7863509 0.44570148 + 2809 0.79292405 0.45381856 + 2810 0.7886818 0.46240443 + 2811 0.7900377 0.4731092 + 2812 0.7869765 0.4825257 + 2813 0.7885942 0.49070004 + 2814 0.78813875 0.50242984 + 2815 0.79148793 0.51605594 + 2816 0.7907537 0.52819115 + 2817 0.79177654 0.53713036 + 2818 0.78907585 0.5454719 + 2819 0.7876457 0.5568171 + 2820 0.78929335 0.56830394 + 2821 0.79104006 0.57704407 + 2822 0.7882512 0.58556414 + 2823 0.7851364 0.5944331 + 2824 0.7864504 0.60432637 + 2825 0.7891447 0.6153485 + 2826 0.790037 0.62628967 + 2827 0.79354066 0.6362913 + 2828 0.78918695 0.6465967 + 2829 0.7860065 0.6578308 + 2830 0.7852451 0.6667928 + 2831 0.7883721 0.6751542 + 2832 0.79196125 0.6853104 + 2833 0.7860695 0.6948847 + 2834 0.79193646 0.7045802 + 2835 0.7881437 0.7127549 + 2836 0.7906731 0.7222556 + 2837 0.7891758 0.73175263 + 2838 0.7984484 0.18495192 + 2839 0.7978324 0.19546989 + 2840 0.79678506 0.2069847 + 2841 0.7969615 0.21697775 + 2842 0.801677 0.22511865 + 2843 0.79743665 0.23215155 + 2844 0.7988002 0.2411313 + 2845 0.8004297 0.2545838 + 2846 0.80223966 0.2660129 + 2847 0.7992246 0.2759524 + 2848 0.80150515 0.28698775 + 2849 0.7967616 0.29557657 + 2850 0.8015141 0.304417 + 2851 0.7997533 0.3152638 + 2852 0.8033245 0.32698068 + 2853 0.7971418 0.3362671 + 2854 0.8020602 0.34554595 + 2855 0.7978318 0.35620567 + 2856 0.79698205 0.36590478 + 2857 0.79849094 0.37461302 + 2858 0.800721 0.38641164 + 2859 0.7998987 0.39681983 + 2860 0.8036727 0.40371755 + 2861 0.80214554 0.41485807 + 2862 0.801551 0.42573437 + 2863 0.7974842 0.43228745 + 2864 0.79799765 0.44299534 + 2865 0.8023192 0.45312294 + 2866 0.7994574 0.46353146 + 2867 0.8018503 0.47502396 + 2868 0.79553485 0.4833295 + 2869 0.7998726 0.49439248 + 2870 0.8003365 0.50719243 + 2871 0.8019853 0.51663935 + 2872 0.79887235 0.5236661 + 2873 0.8011978 0.5335626 + 2874 0.797518 0.54251176 + 2875 0.79799086 0.5513762 + 2876 0.79966193 0.56309503 + 2877 0.79740703 0.5729213 + 2878 0.7995102 0.5823246 + 2879 0.7962941 0.5951405 + 2880 0.79826665 0.6082603 + 2881 0.7992414 0.6198402 + 2882 0.79902947 0.628932 + 2883 0.80348384 0.6356267 + 2884 0.8000491 0.64435345 + 2885 0.79748875 0.6549758 + 2886 0.79409045 0.6660551 + 2887 0.8001123 0.6773614 + 2888 0.7993691 0.68629676 + 2889 0.7979566 0.6946122 + 2890 0.8019968 0.7052576 + 2891 0.7968756 0.71385026 + 2892 0.8016887 0.7235119 + 2893 0.7971636 0.73016113 + 2894 0.80657876 0.18250759 + 2895 0.8078449 0.1911635 + 2896 0.80835295 0.20263998 + 2897 0.80794793 0.21564241 + 2898 0.8122277 0.22715607 + 2899 0.8059594 0.23449896 + 2900 0.80930203 0.24486652 + 2901 0.8138132 0.25546455 + 2902 0.80898726 0.26289505 + 2903 0.8094543 0.2718583 + 2904 0.80979997 0.28257072 + 2905 0.8102522 0.29596204 + 2906 0.8102098 0.30915642 + 2907 0.81066585 0.3196851 + 2908 0.8126611 0.32858768 + 2909 0.80857235 0.337563 + 2910 0.8086352 0.34517127 + 2911 0.8084501 0.3523179 + 2912 0.80818427 0.36578444 + 2913 0.8069008 0.37766445 + 2914 0.8109221 0.38489714 + 2915 0.8098139 0.39541835 + 2916 0.8119846 0.40720397 + 2917 0.8142513 0.4174546 + 2918 0.8088013 0.42400748 + 2919 0.8076579 0.43419755 + 2920 0.8107743 0.44692522 + 2921 0.8103967 0.4584653 + 2922 0.80988926 0.46884942 + 2923 0.81025606 0.47714266 + 2924 0.8057986 0.48419347 + 2925 0.8104034 0.491654 + 2926 0.8102241 0.5012124 + 2927 0.8102922 0.5124011 + 2928 0.8089322 0.52386427 + 2929 0.8129898 0.53454953 + 2930 0.80747706 0.5449746 + 2931 0.80641276 0.5552992 + 2932 0.811284 0.56305236 + 2933 0.8073168 0.57373303 + 2934 0.8079134 0.5819894 + 2935 0.80799013 0.5897035 + 2936 0.8081525 0.6012699 + 2937 0.8100698 0.6135712 + 2938 0.808679 0.62660533 + 2939 0.81126165 0.63569456 + 2940 0.8081033 0.6418691 + 2941 0.80826664 0.6508018 + 2942 0.80709517 0.6642949 + 2943 0.8123071 0.6765637 + 2944 0.80728155 0.68789554 + 2945 0.80684227 0.6979976 + 2946 0.8114628 0.70576876 + 2947 0.8067265 0.7146214 + 2948 0.8116608 0.72441286 + 2949 0.8155941 0.18465832 + 2950 0.82017875 0.19697447 + 2951 0.819424 0.20992944 + 2952 0.820098 0.22112404 + 2953 0.8213393 0.23007749 + 2954 0.81627506 0.23691238 + 2955 0.82052964 0.24695145 + 2956 0.82463276 0.25703397 + 2957 0.81902564 0.26679015 + 2958 0.8174842 0.27723077 + 2959 0.8209104 0.28774607 + 2960 0.8203009 0.29647633 + 2961 0.82105017 0.30521497 + 2962 0.818041 0.31477913 + 2963 0.8200042 0.32374147 + 2964 0.8207143 0.33530474 + 2965 0.8154149 0.3454984 + 2966 0.8185285 0.35602236 + 2967 0.8220557 0.36707246 + 2968 0.8162476 0.3768478 + 2969 0.82102215 0.38841453 + 2970 0.82065564 0.40081766 + 2971 0.82153577 0.4112843 + 2972 0.82269305 0.41969278 + 2973 0.8184979 0.42802006 + 2974 0.81856644 0.43968287 + 2975 0.8189993 0.44669485 + 2976 0.81945205 0.4535379 + 2977 0.8204069 0.4649387 + 2978 0.81685555 0.4740537 + 2979 0.8167809 0.48361322 + 2980 0.8192678 0.4948541 + 2981 0.82112217 0.50677043 + 2982 0.8191231 0.51871556 + 2983 0.8180235 0.5274883 + 2984 0.8216349 0.53382146 + 2985 0.82058597 0.543527 + 2986 0.8154943 0.55388975 + 2987 0.82006794 0.5616395 + 2988 0.8184949 0.5704767 + 2989 0.81664133 0.5820791 + 2990 0.8191549 0.5952658 + 2991 0.81688863 0.60555756 + 2992 0.8201254 0.61231774 + 2993 0.81886715 0.62103486 + 2994 0.8185752 0.63147485 + 2995 0.817292 0.64286304 + 2996 0.8193607 0.65647274 + 2997 0.8177905 0.667877 + 2998 0.82254755 0.67596287 + 2999 0.8187773 0.68601054 + 3000 0.81535816 0.69640833 + 3001 0.8211059 0.70540494 + 3002 0.8165796 0.71484625 + 3003 0.82129484 0.7239914 + 3004 0.8282326 0.18664968 + 3005 0.8316341 0.1975341 + 3006 0.83009475 0.20647015 + 3007 0.8297992 0.21699773 + 3008 0.82979065 0.22724697 + 3009 0.8282719 0.238222 + 3010 0.83088887 0.2494746 + 3011 0.8329769 0.25782856 + 3012 0.83058655 0.26592952 + 3013 0.828256 0.2773952 + 3014 0.831304 0.2877143 + 3015 0.8290067 0.2971651 + 3016 0.8312804 0.30694035 + 3017 0.82827926 0.3163523 + 3018 0.8296511 0.32803446 + 3019 0.8311128 0.33715257 + 3020 0.82754105 0.3468779 + 3021 0.82948965 0.358821 + 3022 0.83144027 0.36770222 + 3023 0.8284394 0.3774835 + 3024 0.8312552 0.38740954 + 3025 0.8299088 0.39630672 + 3026 0.8297757 0.4065309 + 3027 0.82995933 0.41625696 + 3028 0.82929456 0.425653 + 3029 0.82829124 0.43570194 + 3030 0.8271852 0.44673988 + 3031 0.8288999 0.45758396 + 3032 0.8303976 0.46640775 + 3033 0.82686573 0.47575542 + 3034 0.8279241 0.48765624 + 3035 0.829095 0.4982222 + 3036 0.83087593 0.5066987 + 3037 0.828935 0.5152882 + 3038 0.8273993 0.5264705 + 3039 0.8291197 0.5370372 + 3040 0.830276 0.5455945 + 3041 0.8269909 0.55473524 + 3042 0.82792294 0.5659271 + 3043 0.8275357 0.576285 + 3044 0.8278422 0.5869426 + 3045 0.829556 0.5958919 + 3046 0.8267843 0.6052788 + 3047 0.8278708 0.61606956 + 3048 0.8277267 0.6261021 + 3049 0.8274751 0.6365033 + 3050 0.82782894 0.6472049 + 3051 0.82956433 0.65617085 + 3052 0.82750744 0.66610724 + 3053 0.83027345 0.6753471 + 3054 0.82847446 0.6838844 + 3055 0.8265336 0.6953442 + 3056 0.82943696 0.70519006 + 3057 0.82714933 0.71483225 + 3058 0.82937026 0.7241587 +ENDOFSECTION +ELEMENTS/CELLS + 1 3 3 668 621 50 + 2 3 3 577 48 49 + 3 3 3 49 50 621 + 4 3 3 622 49 621 + 5 3 3 667 50 51 + 6 3 3 714 52 53 + 7 3 3 54 713 53 + 8 3 3 714 666 52 + 9 3 3 668 50 667 + 10 3 3 714 667 666 + 11 3 3 715 668 667 + 12 3 3 667 51 666 + 13 3 3 717 669 668 + 14 3 3 666 51 52 + 15 3 3 622 621 668 + 16 3 3 47 577 578 + 17 3 3 47 48 577 + 18 3 3 622 578 577 + 19 3 3 46 47 578 + 20 3 3 46 579 535 + 21 3 3 46 578 579 + 22 3 3 580 535 579 + 23 3 3 45 46 535 + 24 3 3 623 579 578 + 25 3 3 670 623 622 + 26 3 3 577 49 622 + 27 3 3 670 622 669 + 28 3 3 623 578 622 + 29 3 3 624 623 671 + 30 3 3 671 623 670 + 31 3 3 718 671 670 + 32 3 3 672 624 671 + 33 3 3 717 670 669 + 34 3 3 624 579 623 + 35 3 3 622 668 669 + 36 3 3 580 579 624 + 37 3 3 714 53 713 + 38 3 3 55 761 762 + 39 3 3 56 761 55 + 40 3 3 813 763 762 + 41 3 3 54 55 762 + 42 3 3 764 713 763 + 43 3 3 763 713 54 + 44 3 3 54 762 763 + 45 3 3 714 713 764 + 46 3 3 813 762 761 + 47 3 3 56 57 811 + 48 3 3 58 811 57 + 49 3 3 812 56 811 + 50 3 3 866 814 813 + 51 3 3 864 813 812 + 52 3 3 814 763 813 + 53 3 3 813 761 812 + 54 3 3 864 812 811 + 55 3 3 812 761 56 + 56 3 3 764 763 814 + 57 3 3 715 714 765 + 58 3 3 765 714 764 + 59 3 3 815 765 764 + 60 3 3 716 715 765 + 61 3 3 718 670 717 + 62 3 3 766 717 716 + 63 3 3 768 718 717 + 64 3 3 717 668 716 + 65 3 3 766 716 765 + 66 3 3 716 668 715 + 67 3 3 817 765 816 + 68 3 3 816 765 815 + 69 3 3 868 816 815 + 70 3 3 766 765 817 + 71 3 3 819 768 767 + 72 3 3 767 766 817 + 73 3 3 819 769 768 + 74 3 3 768 717 767 + 75 3 3 868 817 816 + 76 3 3 767 717 766 + 77 3 3 764 814 815 + 78 3 3 719 671 718 + 79 3 3 867 815 814 + 80 3 3 715 667 714 + 81 3 3 719 718 768 + 82 3 3 44 494 495 + 83 3 3 45 494 44 + 84 3 3 537 495 494 + 85 3 3 43 44 495 + 86 3 3 42 43 459 + 87 3 3 496 459 43 + 88 3 3 41 42 459 + 89 3 3 496 43 495 + 90 3 3 45 535 536 + 91 3 3 536 535 580 + 92 3 3 581 536 580 + 93 3 3 537 494 536 + 94 3 3 538 496 537 + 95 3 3 496 495 537 + 96 3 3 537 536 581 + 97 3 3 538 537 581 + 98 3 3 625 581 580 + 99 3 3 536 494 45 + 100 3 3 497 459 496 + 101 3 3 432 41 460 + 102 3 3 40 41 432 + 103 3 3 41 459 460 + 104 3 3 433 432 460 + 105 3 3 40 432 433 + 106 3 3 433 460 461 + 107 3 3 462 433 461 + 108 3 3 39 40 433 + 109 3 3 497 461 460 + 110 3 3 497 496 539 + 111 3 3 460 459 497 + 112 3 3 538 581 582 + 113 3 3 583 539 538 + 114 3 3 498 539 540 + 115 3 3 498 497 539 + 116 3 3 584 540 539 + 117 3 3 462 461 498 + 118 3 3 583 538 582 + 119 3 3 498 461 497 + 120 3 3 539 496 538 + 121 3 3 499 498 540 + 122 3 3 626 582 581 + 123 3 3 673 626 625 + 124 3 3 625 624 672 + 125 3 3 673 625 672 + 126 3 3 627 582 626 + 127 3 3 627 673 674 + 128 3 3 627 626 673 + 129 3 3 722 674 673 + 130 3 3 628 627 674 + 131 3 3 720 673 672 + 132 3 3 583 582 627 + 133 3 3 770 720 719 + 134 3 3 719 768 769 + 135 3 3 770 719 769 + 136 3 3 672 671 720 + 137 3 3 721 770 771 + 138 3 3 721 720 770 + 139 3 3 821 770 769 + 140 3 3 722 673 721 + 141 3 3 822 771 770 + 142 3 3 721 673 720 + 143 3 3 580 624 625 + 144 3 3 772 721 771 + 145 3 3 629 583 628 + 146 3 3 583 627 628 + 147 3 3 628 674 675 + 148 3 3 629 628 675 + 149 3 3 630 584 629 + 150 3 3 584 583 629 + 151 3 3 629 675 676 + 152 3 3 677 629 676 + 153 3 3 724 676 675 + 154 3 3 584 539 583 + 155 3 3 773 723 722 + 156 3 3 722 721 772 + 157 3 3 773 722 772 + 158 3 3 724 675 723 + 159 3 3 724 723 774 + 160 3 3 774 723 773 + 161 3 3 824 773 772 + 162 3 3 725 724 774 + 163 3 3 822 772 771 + 164 3 3 675 674 723 + 165 3 3 723 674 722 + 166 3 3 541 540 584 + 167 3 3 824 774 773 + 168 3 3 626 581 625 + 169 3 3 720 671 719 + 170 3 3 725 676 724 + 171 3 3 818 767 817 + 172 3 3 60 61 913 + 173 3 3 968 913 61 + 174 3 3 914 861 60 + 175 3 3 862 58 59 + 176 3 3 59 60 861 + 177 3 3 862 59 861 + 178 3 3 914 60 913 + 179 3 3 62 966 967 + 180 3 3 63 966 62 + 181 3 3 1023 968 967 + 182 3 3 968 61 967 + 183 3 3 914 913 969 + 184 3 3 969 913 968 + 185 3 3 1025 970 969 + 186 3 3 862 861 914 + 187 3 3 1025 969 968 + 188 3 3 967 61 62 + 189 3 3 915 914 969 + 190 3 3 862 915 863 + 191 3 3 862 914 915 + 192 3 3 917 864 863 + 193 3 3 864 811 863 + 194 3 3 866 813 865 + 195 3 3 918 865 864 + 196 3 3 919 866 865 + 197 3 3 865 813 864 + 198 3 3 916 863 915 + 199 3 3 863 58 862 + 200 3 3 916 970 971 + 201 3 3 916 915 970 + 202 3 3 1027 971 970 + 203 3 3 917 916 971 + 204 3 3 973 918 917 + 205 3 3 974 919 918 + 206 3 3 919 865 918 + 207 3 3 918 864 917 + 208 3 3 972 917 971 + 209 3 3 917 863 916 + 210 3 3 915 969 970 + 211 3 3 867 866 919 + 212 3 3 1023 967 966 + 213 3 3 867 814 866 + 214 3 3 64 65 1021 + 215 3 3 1079 1022 1021 + 216 3 3 1022 64 1021 + 217 3 3 1023 966 1022 + 218 3 3 63 64 1022 + 219 3 3 1080 1023 1022 + 220 3 3 1024 968 1023 + 221 3 3 1079 1021 65 + 222 3 3 66 1077 1078 + 223 3 3 67 1077 66 + 224 3 3 1136 1078 1077 + 225 3 3 1079 65 1078 + 226 3 3 1140 1081 1080 + 227 3 3 1140 1082 1081 + 228 3 3 1081 1023 1080 + 229 3 3 1080 1022 1079 + 230 3 3 1139 1080 1079 + 231 3 3 1078 65 66 + 232 3 3 1082 1023 1081 + 233 3 3 1084 1026 1025 + 234 3 3 1083 1025 1024 + 235 3 3 1027 970 1026 + 236 3 3 1026 970 1025 + 237 3 3 1028 973 972 + 238 3 3 1029 974 973 + 239 3 3 974 918 973 + 240 3 3 973 917 972 + 241 3 3 972 971 1027 + 242 3 3 1025 968 1024 + 243 3 3 1084 1025 1083 + 244 3 3 1141 1083 1082 + 245 3 3 1143 1084 1083 + 246 3 3 1085 1027 1026 + 247 3 3 1029 973 1028 + 248 3 3 1085 1028 1027 + 249 3 3 1087 1029 1028 + 250 3 3 1028 972 1027 + 251 3 3 1088 1030 1029 + 252 3 3 1083 1024 1082 + 253 3 3 1024 1023 1082 + 254 3 3 1030 974 1029 + 255 3 3 1137 1079 1078 + 256 3 3 1022 966 63 + 257 3 3 975 919 974 + 258 3 3 921 869 868 + 259 3 3 921 868 867 + 260 3 3 818 817 869 + 261 3 3 869 817 868 + 262 3 3 871 819 818 + 263 3 3 818 869 870 + 264 3 3 871 818 870 + 265 3 3 819 767 818 + 266 3 3 922 870 869 + 267 3 3 868 815 867 + 268 3 3 978 923 922 + 269 3 3 977 922 921 + 270 3 3 923 870 922 + 271 3 3 922 869 921 + 272 3 3 871 870 924 + 273 3 3 924 870 923 + 274 3 3 980 925 924 + 275 3 3 872 871 924 + 276 3 3 979 924 923 + 277 3 3 921 867 920 + 278 3 3 867 919 920 + 279 3 3 820 819 871 + 280 3 3 873 821 820 + 281 3 3 820 871 872 + 282 3 3 874 822 821 + 283 3 3 821 769 820 + 284 3 3 824 772 823 + 285 3 3 874 823 822 + 286 3 3 876 824 823 + 287 3 3 823 772 822 + 288 3 3 873 820 872 + 289 3 3 822 770 821 + 290 3 3 873 925 926 + 291 3 3 873 872 925 + 292 3 3 980 926 925 + 293 3 3 927 874 873 + 294 3 3 876 823 875 + 295 3 3 927 875 874 + 296 3 3 929 876 875 + 297 3 3 875 823 874 + 298 3 3 927 873 926 + 299 3 3 874 821 873 + 300 3 3 872 924 925 + 301 3 3 825 774 824 + 302 3 3 975 921 920 + 303 3 3 820 769 819 + 304 3 3 977 921 976 + 305 3 3 1031 976 975 + 306 3 3 1034 978 977 + 307 3 3 978 922 977 + 308 3 3 1035 980 979 + 309 3 3 1034 979 978 + 310 3 3 981 926 980 + 311 3 3 979 923 978 + 312 3 3 1032 977 976 + 313 3 3 980 924 979 + 314 3 3 1032 976 1031 + 315 3 3 1088 1031 1030 + 316 3 3 1090 1032 1031 + 317 3 3 975 974 1031 + 318 3 3 1092 1034 1033 + 319 3 3 1092 1035 1034 + 320 3 3 1035 979 1034 + 321 3 3 1034 977 1033 + 322 3 3 1090 1033 1032 + 323 3 3 1033 977 1032 + 324 3 3 920 919 975 + 325 3 3 1036 980 1035 + 326 3 3 927 926 982 + 327 3 3 982 926 981 + 328 3 3 1039 983 982 + 329 3 3 928 927 982 + 330 3 3 984 929 928 + 331 3 3 928 982 983 + 332 3 3 984 928 983 + 333 3 3 929 875 928 + 334 3 3 1038 982 981 + 335 3 3 928 875 927 + 336 3 3 1094 1037 1036 + 337 3 3 1093 1036 1035 + 338 3 3 1039 982 1038 + 339 3 3 1038 981 1037 + 340 3 3 984 983 1040 + 341 3 3 1040 983 1039 + 342 3 3 1097 1040 1039 + 343 3 3 985 929 984 + 344 3 3 1097 1039 1038 + 345 3 3 981 980 1037 + 346 3 3 1037 980 1036 + 347 3 3 877 876 929 + 348 3 3 1095 1038 1037 + 349 3 3 976 921 975 + 350 3 3 1031 974 1030 + 351 3 3 825 824 876 + 352 3 3 1098 1041 1040 + 353 3 3 863 811 58 + 354 3 3 985 984 1040 + 355 3 3 415 405 37 + 356 3 3 36 405 406 + 357 3 3 36 37 405 + 358 3 3 415 406 405 + 359 3 3 35 36 406 + 360 3 3 415 37 38 + 361 3 3 414 39 434 + 362 3 3 414 38 39 + 363 3 3 39 433 434 + 364 3 3 435 414 434 + 365 3 3 415 414 435 + 366 3 3 463 435 434 + 367 3 3 463 436 435 + 368 3 3 416 406 415 + 369 3 3 434 433 462 + 370 3 3 415 38 414 + 371 3 3 416 415 435 + 372 3 3 35 407 34 + 373 3 3 35 406 407 + 374 3 3 408 34 407 + 375 3 3 33 408 409 + 376 3 3 33 34 408 + 377 3 3 418 409 408 + 378 3 3 32 33 409 + 379 3 3 417 408 407 + 380 3 3 437 417 416 + 381 3 3 416 435 436 + 382 3 3 437 416 436 + 383 3 3 418 408 417 + 384 3 3 418 417 438 + 385 3 3 438 417 437 + 386 3 3 465 437 436 + 387 3 3 419 409 418 + 388 3 3 465 438 437 + 389 3 3 417 407 416 + 390 3 3 407 406 416 + 391 3 3 419 418 438 + 392 3 3 463 434 462 + 393 3 3 463 462 500 + 394 3 3 500 462 499 + 395 3 3 462 498 499 + 396 3 3 542 500 499 + 397 3 3 464 463 501 + 398 3 3 501 463 500 + 399 3 3 542 501 500 + 400 3 3 502 464 501 + 401 3 3 542 499 541 + 402 3 3 465 436 464 + 403 3 3 542 541 586 + 404 3 3 586 541 585 + 405 3 3 499 540 541 + 406 3 3 631 585 630 + 407 3 3 587 542 586 + 408 3 3 587 543 542 + 409 3 3 586 585 631 + 410 3 3 632 586 631 + 411 3 3 678 632 631 + 412 3 3 543 501 542 + 413 3 3 585 584 630 + 414 3 3 502 501 543 + 415 3 3 503 465 502 + 416 3 3 465 464 502 + 417 3 3 502 543 544 + 418 3 3 503 502 544 + 419 3 3 504 466 503 + 420 3 3 466 465 503 + 421 3 3 503 544 545 + 422 3 3 546 503 545 + 423 3 3 589 545 544 + 424 3 3 466 438 465 + 425 3 3 633 588 587 + 426 3 3 587 586 632 + 427 3 3 633 587 632 + 428 3 3 589 544 588 + 429 3 3 589 588 634 + 430 3 3 634 588 633 + 431 3 3 680 634 633 + 432 3 3 590 545 589 + 433 3 3 679 633 632 + 434 3 3 588 544 587 + 435 3 3 544 543 587 + 436 3 3 467 438 466 + 437 3 3 677 631 630 + 438 3 3 464 436 463 + 439 3 3 541 584 585 + 440 3 3 590 589 634 + 441 3 3 32 409 410 + 442 3 3 410 409 419 + 443 3 3 420 410 419 + 444 3 3 31 32 410 + 445 3 3 31 410 411 + 446 3 3 411 410 420 + 447 3 3 421 411 420 + 448 3 3 30 31 411 + 449 3 3 440 420 419 + 450 3 3 468 440 439 + 451 3 3 439 438 467 + 452 3 3 468 439 467 + 453 3 3 421 420 440 + 454 3 3 421 440 441 + 455 3 3 469 441 440 + 456 3 3 469 440 468 + 457 3 3 412 411 421 + 458 3 3 504 468 467 + 459 3 3 440 419 439 + 460 3 3 419 438 439 + 461 3 3 442 421 441 + 462 3 3 30 411 412 + 463 3 3 412 421 422 + 464 3 3 29 412 422 + 465 3 3 29 30 412 + 466 3 3 29 413 28 + 467 3 3 423 413 29 + 468 3 3 423 28 413 + 469 3 3 423 29 422 + 470 3 3 443 422 442 + 471 3 3 422 421 442 + 472 3 3 470 443 442 + 473 3 3 423 422 443 + 474 3 3 424 423 444 + 475 3 3 444 423 443 + 476 3 3 472 444 443 + 477 3 3 425 424 444 + 478 3 3 470 442 469 + 479 3 3 424 28 423 + 480 3 3 442 441 469 + 481 3 3 27 28 424 + 482 3 3 506 469 468 + 483 3 3 547 505 504 + 484 3 3 467 466 504 + 485 3 3 547 504 546 + 486 3 3 506 468 505 + 487 3 3 506 505 548 + 488 3 3 548 505 547 + 489 3 3 591 548 547 + 490 3 3 549 506 548 + 491 3 3 590 547 546 + 492 3 3 470 469 506 + 493 3 3 590 635 591 + 494 3 3 590 634 635 + 495 3 3 636 591 635 + 496 3 3 592 548 591 + 497 3 3 592 591 637 + 498 3 3 637 591 636 + 499 3 3 684 637 636 + 500 3 3 638 593 592 + 501 3 3 683 636 635 + 502 3 3 591 547 590 + 503 3 3 504 503 546 + 504 3 3 593 548 592 + 505 3 3 508 471 470 + 506 3 3 470 506 507 + 507 3 3 508 470 507 + 508 3 3 471 443 470 + 509 3 3 472 471 509 + 510 3 3 509 471 508 + 511 3 3 550 509 508 + 512 3 3 473 472 509 + 513 3 3 549 508 507 + 514 3 3 472 443 471 + 515 3 3 594 550 549 + 516 3 3 507 506 549 + 517 3 3 594 549 593 + 518 3 3 550 508 549 + 519 3 3 551 550 595 + 520 3 3 595 550 594 + 521 3 3 638 594 593 + 522 3 3 596 551 595 + 523 3 3 639 595 594 + 524 3 3 551 509 550 + 525 3 3 549 548 593 + 526 3 3 473 444 472 + 527 3 3 638 592 637 + 528 3 3 505 468 504 + 529 3 3 546 545 590 + 530 3 3 510 509 551 + 531 3 3 681 635 634 + 532 3 3 726 678 677 + 533 3 3 677 676 725 + 534 3 3 726 677 725 + 535 3 3 679 632 678 + 536 3 3 679 678 727 + 537 3 3 727 678 726 + 538 3 3 776 727 726 + 539 3 3 680 679 727 + 540 3 3 775 726 725 + 541 3 3 680 633 679 + 542 3 3 775 825 826 + 543 3 3 725 774 775 + 544 3 3 880 828 827 + 545 3 3 827 775 826 + 546 3 3 828 777 776 + 547 3 3 776 775 827 + 548 3 3 828 776 827 + 549 3 3 777 727 776 + 550 3 3 879 827 826 + 551 3 3 776 726 775 + 552 3 3 630 629 677 + 553 3 3 728 727 777 + 554 3 3 729 681 680 + 555 3 3 680 727 728 + 556 3 3 729 680 728 + 557 3 3 682 635 681 + 558 3 3 682 681 730 + 559 3 3 730 681 729 + 560 3 3 779 730 729 + 561 3 3 683 682 730 + 562 3 3 778 729 728 + 563 3 3 681 634 680 + 564 3 3 778 777 829 + 565 3 3 728 777 778 + 566 3 3 881 829 828 + 567 3 3 779 778 829 + 568 3 3 779 830 780 + 569 3 3 779 829 830 + 570 3 3 831 780 830 + 571 3 3 780 730 779 + 572 3 3 881 830 829 + 573 3 3 779 729 778 + 574 3 3 829 777 828 + 575 3 3 731 730 780 + 576 3 3 878 826 825 + 577 3 3 683 635 682 + 578 3 3 931 878 877 + 579 3 3 877 929 930 + 580 3 3 931 877 930 + 581 3 3 878 825 877 + 582 3 3 879 931 932 + 583 3 3 879 878 931 + 584 3 3 986 932 931 + 585 3 3 880 879 932 + 586 3 3 986 931 930 + 587 3 3 880 827 879 + 588 3 3 1042 986 985 + 589 3 3 985 1040 1041 + 590 3 3 1042 985 1041 + 591 3 3 986 930 985 + 592 3 3 987 1042 1043 + 593 3 3 987 986 1042 + 594 3 3 1100 1042 1041 + 595 3 3 988 932 987 + 596 3 3 1100 1043 1042 + 597 3 3 987 932 986 + 598 3 3 930 929 985 + 599 3 3 988 987 1043 + 600 3 3 880 933 881 + 601 3 3 880 932 933 + 602 3 3 934 881 933 + 603 3 3 881 828 880 + 604 3 3 882 934 935 + 605 3 3 882 881 934 + 606 3 3 990 935 934 + 607 3 3 883 830 882 + 608 3 3 989 934 933 + 609 3 3 882 830 881 + 610 3 3 988 1044 989 + 611 3 3 988 1043 1044 + 612 3 3 1045 989 1044 + 613 3 3 990 934 989 + 614 3 3 990 1045 1046 + 615 3 3 990 989 1045 + 616 3 3 1103 1045 1044 + 617 3 3 991 935 990 + 618 3 3 1104 1046 1045 + 619 3 3 989 933 988 + 620 3 3 933 932 988 + 621 3 3 883 882 935 + 622 3 3 1101 1044 1043 + 623 3 3 879 826 878 + 624 3 3 825 876 877 + 625 3 3 991 990 1046 + 626 3 3 732 684 683 + 627 3 3 683 730 731 + 628 3 3 732 683 731 + 629 3 3 685 637 684 + 630 3 3 638 637 685 + 631 3 3 685 684 732 + 632 3 3 733 685 732 + 633 3 3 686 638 685 + 634 3 3 781 732 731 + 635 3 3 684 636 683 + 636 3 3 781 831 832 + 637 3 3 731 780 781 + 638 3 3 884 832 831 + 639 3 3 782 781 832 + 640 3 3 783 732 782 + 641 3 3 783 733 732 + 642 3 3 782 832 833 + 643 3 3 834 782 833 + 644 3 3 885 833 832 + 645 3 3 782 732 781 + 646 3 3 781 780 831 + 647 3 3 686 685 733 + 648 3 3 687 639 686 + 649 3 3 639 638 686 + 650 3 3 686 733 734 + 651 3 3 687 686 734 + 652 3 3 640 639 687 + 653 3 3 687 734 735 + 654 3 3 688 687 735 + 655 3 3 688 640 687 + 656 3 3 785 735 734 + 657 3 3 640 595 639 + 658 3 3 783 834 784 + 659 3 3 783 782 834 + 660 3 3 835 784 834 + 661 3 3 785 734 784 + 662 3 3 785 784 836 + 663 3 3 836 784 835 + 664 3 3 888 836 835 + 665 3 3 786 735 785 + 666 3 3 887 835 834 + 667 3 3 784 734 783 + 668 3 3 734 733 783 + 669 3 3 596 595 640 + 670 3 3 886 834 833 + 671 3 3 639 594 638 + 672 3 3 883 936 884 + 673 3 3 883 935 936 + 674 3 3 937 884 936 + 675 3 3 885 832 884 + 676 3 3 885 884 938 + 677 3 3 938 884 937 + 678 3 3 992 938 937 + 679 3 3 939 885 938 + 680 3 3 991 937 936 + 681 3 3 884 831 883 + 682 3 3 1048 992 991 + 683 3 3 936 935 991 + 684 3 3 1048 991 1047 + 685 3 3 992 937 991 + 686 3 3 993 992 1049 + 687 3 3 1049 992 1048 + 688 3 3 1106 1048 1047 + 689 3 3 994 993 1049 + 690 3 3 1106 1049 1048 + 691 3 3 993 938 992 + 692 3 3 991 1046 1047 + 693 3 3 939 938 993 + 694 3 3 940 887 886 + 695 3 3 886 885 939 + 696 3 3 940 886 939 + 697 3 3 888 835 887 + 698 3 3 888 940 941 + 699 3 3 888 887 940 + 700 3 3 995 941 940 + 701 3 3 942 888 941 + 702 3 3 994 940 939 + 703 3 3 887 834 886 + 704 3 3 1051 995 994 + 705 3 3 939 993 994 + 706 3 3 1051 994 1050 + 707 3 3 996 941 995 + 708 3 3 996 995 1052 + 709 3 3 1052 995 1051 + 710 3 3 1109 1051 1050 + 711 3 3 1053 996 1052 + 712 3 3 1109 1052 1051 + 713 3 3 995 940 994 + 714 3 3 994 1049 1050 + 715 3 3 837 836 888 + 716 3 3 1104 1047 1046 + 717 3 3 886 833 885 + 718 3 3 831 830 883 + 719 3 3 786 785 836 + 720 3 3 1107 1050 1049 + 721 3 3 678 631 677 + 722 3 3 775 774 825 + 723 3 3 942 941 996 + 724 3 3 1085 1026 1084 + 725 3 3 1195 1135 69 + 726 3 3 67 68 1135 + 727 3 3 68 69 1135 + 728 3 3 1136 67 1135 + 729 3 3 1194 69 70 + 730 3 3 1251 1194 71 + 731 3 3 1194 70 71 + 732 3 3 1251 71 72 + 733 3 3 1195 1194 1252 + 734 3 3 1252 1194 1251 + 735 3 3 1251 72 1252 + 736 3 3 1136 1135 1195 + 737 3 3 1306 1253 1252 + 738 3 3 1195 69 1194 + 739 3 3 1196 1195 1252 + 740 3 3 1197 1137 1136 + 741 3 3 1136 1195 1196 + 742 3 3 1197 1136 1196 + 743 3 3 1137 1078 1136 + 744 3 3 1198 1139 1138 + 745 3 3 1198 1138 1137 + 746 3 3 1198 1137 1197 + 747 3 3 1139 1079 1138 + 748 3 3 1254 1197 1196 + 749 3 3 1138 1079 1137 + 750 3 3 1198 1197 1254 + 751 3 3 1254 1196 1253 + 752 3 3 1308 1254 1253 + 753 3 3 1255 1198 1254 + 754 3 3 1199 1255 1256 + 755 3 3 1199 1198 1255 + 756 3 3 1310 1256 1255 + 757 3 3 1200 1199 1256 + 758 3 3 1309 1255 1254 + 759 3 3 1199 1139 1198 + 760 3 3 1196 1252 1253 + 761 3 3 1200 1139 1199 + 762 3 3 1306 1252 72 + 763 3 3 1140 1080 1139 + 764 3 3 1305 73 1306 + 765 3 3 1305 72 73 + 766 3 3 1357 1306 73 + 767 3 3 1307 1253 1306 + 768 3 3 1307 1306 1358 + 769 3 3 1358 1306 1357 + 770 3 3 1405 1358 1357 + 771 3 3 1359 1307 1358 + 772 3 3 74 1357 73 + 773 3 3 1308 1253 1307 + 774 3 3 74 75 1405 + 775 3 3 1451 1405 75 + 776 3 3 1406 1358 1405 + 777 3 3 1406 1405 1452 + 778 3 3 1452 1405 1451 + 779 3 3 1494 1453 1452 + 780 3 3 1453 1406 1452 + 781 3 3 76 1451 75 + 782 3 3 1405 1357 74 + 783 3 3 1359 1358 1406 + 784 3 3 1360 1309 1308 + 785 3 3 1308 1307 1359 + 786 3 3 1360 1308 1359 + 787 3 3 1309 1254 1308 + 788 3 3 1310 1309 1361 + 789 3 3 1361 1309 1360 + 790 3 3 1409 1361 1360 + 791 3 3 1311 1310 1361 + 792 3 3 1407 1360 1359 + 793 3 3 1310 1255 1309 + 794 3 3 1454 1408 1407 + 795 3 3 1359 1406 1407 + 796 3 3 1454 1407 1453 + 797 3 3 1409 1360 1408 + 798 3 3 1409 1454 1455 + 799 3 3 1409 1408 1454 + 800 3 3 1496 1455 1454 + 801 3 3 1362 1361 1409 + 802 3 3 1496 1454 1453 + 803 3 3 1408 1360 1407 + 804 3 3 1407 1406 1453 + 805 3 3 1311 1256 1310 + 806 3 3 1497 1456 1455 + 807 3 3 1306 72 1305 + 808 3 3 1410 1409 1455 + 809 3 3 1201 1141 1140 + 810 3 3 1140 1139 1200 + 811 3 3 1201 1140 1200 + 812 3 3 1142 1083 1141 + 813 3 3 1203 1143 1142 + 814 3 3 1142 1141 1201 + 815 3 3 1202 1142 1201 + 816 3 3 1143 1083 1142 + 817 3 3 1257 1201 1200 + 818 3 3 1085 1084 1143 + 819 3 3 1202 1201 1258 + 820 3 3 1258 1201 1257 + 821 3 3 1313 1259 1258 + 822 3 3 1259 1202 1258 + 823 3 3 1203 1259 1260 + 824 3 3 1203 1202 1259 + 825 3 3 1315 1261 1260 + 826 3 3 1204 1143 1203 + 827 3 3 1314 1260 1259 + 828 3 3 1203 1142 1202 + 829 3 3 1200 1256 1257 + 830 3 3 1261 1203 1260 + 831 3 3 1145 1086 1085 + 832 3 3 1085 1143 1144 + 833 3 3 1145 1085 1144 + 834 3 3 1087 1028 1086 + 835 3 3 1087 1145 1146 + 836 3 3 1087 1086 1145 + 837 3 3 1205 1146 1145 + 838 3 3 1147 1087 1146 + 839 3 3 1205 1145 1144 + 840 3 3 1088 1029 1087 + 841 3 3 1204 1261 1205 + 842 3 3 1144 1143 1204 + 843 3 3 1262 1205 1261 + 844 3 3 1205 1144 1204 + 845 3 3 1206 1262 1263 + 846 3 3 1206 1205 1262 + 847 3 3 1317 1263 1262 + 848 3 3 1207 1146 1206 + 849 3 3 1316 1262 1261 + 850 3 3 1206 1146 1205 + 851 3 3 1204 1203 1261 + 852 3 3 1264 1206 1263 + 853 3 3 1312 1258 1257 + 854 3 3 1141 1082 1140 + 855 3 3 1363 1312 1311 + 856 3 3 1311 1361 1362 + 857 3 3 1363 1311 1362 + 858 3 3 1312 1257 1311 + 859 3 3 1313 1363 1364 + 860 3 3 1313 1312 1363 + 861 3 3 1411 1364 1363 + 862 3 3 1314 1313 1364 + 863 3 3 1411 1363 1362 + 864 3 3 1314 1259 1313 + 865 3 3 1457 1411 1410 + 866 3 3 1362 1409 1410 + 867 3 3 1457 1410 1456 + 868 3 3 1412 1364 1411 + 869 3 3 1412 1457 1458 + 870 3 3 1412 1411 1457 + 871 3 3 1499 1458 1457 + 872 3 3 1459 1413 1412 + 873 3 3 1499 1457 1456 + 874 3 3 1411 1362 1410 + 875 3 3 1257 1256 1311 + 876 3 3 1365 1364 1412 + 877 3 3 1314 1365 1315 + 878 3 3 1314 1364 1365 + 879 3 3 1366 1315 1365 + 880 3 3 1316 1261 1315 + 881 3 3 1367 1317 1316 + 882 3 3 1367 1316 1315 + 883 3 3 1367 1315 1366 + 884 3 3 1317 1262 1316 + 885 3 3 1414 1366 1365 + 886 3 3 1315 1260 1314 + 887 3 3 1415 1366 1414 + 888 3 3 1414 1365 1413 + 889 3 3 1459 1414 1413 + 890 3 3 1367 1366 1415 + 891 3 3 1368 1415 1416 + 892 3 3 1368 1367 1415 + 893 3 3 1460 1415 1414 + 894 3 3 1369 1317 1368 + 895 3 3 1462 1416 1415 + 896 3 3 1368 1317 1367 + 897 3 3 1365 1412 1413 + 898 3 3 1318 1263 1317 + 899 3 3 1459 1412 1458 + 900 3 3 1313 1258 1312 + 901 3 3 1410 1455 1456 + 902 3 3 1369 1368 1416 + 903 3 3 76 1452 1451 + 904 3 3 1136 1077 67 + 905 3 3 76 77 1494 + 906 3 3 1534 1494 77 + 907 3 3 1495 1453 1494 + 908 3 3 1536 1496 1495 + 909 3 3 1535 1495 1494 + 910 3 3 1535 1494 1534 + 911 3 3 1496 1453 1495 + 912 3 3 78 1534 77 + 913 3 3 1497 1455 1496 + 914 3 3 1570 1534 79 + 915 3 3 79 1534 78 + 916 3 3 1535 1534 1570 + 917 3 3 1571 1536 1570 + 918 3 3 1536 1535 1570 + 919 3 3 80 1604 1570 + 920 3 3 1571 1570 1604 + 921 3 3 80 1570 79 + 922 3 3 1536 1495 1535 + 923 3 3 1497 1496 1536 + 924 3 3 1497 1537 1498 + 925 3 3 1497 1536 1537 + 926 3 3 1538 1498 1537 + 927 3 3 1499 1456 1498 + 928 3 3 1499 1538 1539 + 929 3 3 1499 1498 1538 + 930 3 3 1573 1539 1538 + 931 3 3 1540 1499 1539 + 932 3 3 1573 1538 1537 + 933 3 3 1498 1456 1497 + 934 3 3 1606 1572 1571 + 935 3 3 1571 1604 1605 + 936 3 3 1606 1571 1605 + 937 3 3 1573 1537 1572 + 938 3 3 1607 1574 1573 + 939 3 3 1573 1572 1606 + 940 3 3 1607 1573 1606 + 941 3 3 1574 1539 1573 + 942 3 3 1637 1606 1605 + 943 3 3 1572 1537 1571 + 944 3 3 1537 1536 1571 + 945 3 3 1575 1539 1574 + 946 3 3 1635 1605 1604 + 947 3 3 1500 1458 1499 + 948 3 3 1635 1604 81 + 949 3 3 82 1635 81 + 950 3 3 1636 1605 1635 + 951 3 3 1665 1637 1636 + 952 3 3 1636 1635 82 + 953 3 3 1665 1636 82 + 954 3 3 1637 1605 1636 + 955 3 3 1638 1606 1637 + 956 3 3 1694 83 84 + 957 3 3 1724 84 85 + 958 3 3 1695 1665 1694 + 959 3 3 1665 83 1694 + 960 3 3 1694 84 1724 + 961 3 3 1666 1637 1665 + 962 3 3 1695 1694 1724 + 963 3 3 1665 82 83 + 964 3 3 1725 1724 85 + 965 3 3 1607 1606 1638 + 966 3 3 1638 1637 1666 + 967 3 3 1667 1638 1666 + 968 3 3 1639 1607 1638 + 969 3 3 1608 1607 1639 + 970 3 3 1668 1639 1638 + 971 3 3 1668 1638 1667 + 972 3 3 1609 1608 1639 + 973 3 3 1696 1667 1666 + 974 3 3 1608 1574 1607 + 975 3 3 1726 1695 1725 + 976 3 3 1695 1724 1725 + 977 3 3 1725 85 1754 + 978 3 3 1726 1725 1754 + 979 3 3 1727 1696 1726 + 980 3 3 1696 1695 1726 + 981 3 3 1726 1754 1755 + 982 3 3 1668 1667 1696 + 983 3 3 1784 1756 1755 + 984 3 3 1696 1666 1695 + 985 3 3 1666 1665 1695 + 986 3 3 1727 1726 1755 + 987 3 3 86 1754 85 + 988 3 3 81 1604 80 + 989 3 3 1575 1574 1608 + 990 3 3 1459 1458 1501 + 991 3 3 1501 1458 1500 + 992 3 3 1540 1539 1575 + 993 3 3 1541 1500 1540 + 994 3 3 1502 1460 1501 + 995 3 3 1460 1459 1501 + 996 3 3 1501 1500 1541 + 997 3 3 1502 1501 1541 + 998 3 3 1575 1541 1540 + 999 3 3 1460 1414 1459 + 1000 3 3 1576 1575 1609 + 1001 3 3 1575 1608 1609 + 1002 3 3 1609 1639 1640 + 1003 3 3 1641 1609 1640 + 1004 3 3 1576 1609 1610 + 1005 3 3 1610 1609 1641 + 1006 3 3 1577 1576 1610 + 1007 3 3 1577 1541 1576 + 1008 3 3 1670 1641 1640 + 1009 3 3 1576 1541 1575 + 1010 3 3 1500 1499 1540 + 1011 3 3 1611 1610 1641 + 1012 3 3 1503 1461 1502 + 1013 3 3 1461 1460 1502 + 1014 3 3 1502 1541 1542 + 1015 3 3 1543 1503 1502 + 1016 3 3 1462 1503 1504 + 1017 3 3 1462 1461 1503 + 1018 3 3 1543 1504 1503 + 1019 3 3 1417 1416 1462 + 1020 3 3 1543 1502 1542 + 1021 3 3 1462 1415 1461 + 1022 3 3 1543 1542 1578 + 1023 3 3 1578 1542 1577 + 1024 3 3 1577 1610 1611 + 1025 3 3 1612 1577 1611 + 1026 3 3 1613 1578 1612 + 1027 3 3 1578 1577 1612 + 1028 3 3 1643 124 1612 + 1029 3 3 1544 1543 1578 + 1030 3 3 1642 1612 1611 + 1031 3 3 1544 1504 1543 + 1032 3 3 1542 1541 1577 + 1033 3 3 1613 1612 124 + 1034 3 3 1642 1611 1641 + 1035 3 3 1461 1415 1460 + 1036 3 3 1668 1697 1669 + 1037 3 3 1668 1696 1697 + 1038 3 3 1698 1669 1697 + 1039 3 3 1670 1640 1669 + 1040 3 3 1670 1669 1699 + 1041 3 3 1699 1669 1698 + 1042 3 3 1729 1699 1698 + 1043 3 3 1671 1670 1699 + 1044 3 3 1728 1698 1697 + 1045 3 3 1671 1641 1670 + 1046 3 3 1727 1756 1728 + 1047 3 3 1727 1755 1756 + 1048 3 3 1757 1728 1756 + 1049 3 3 1728 1697 1727 + 1050 3 3 1729 1757 1758 + 1051 3 3 1729 1728 1757 + 1052 3 3 1786 1759 1758 + 1053 3 3 1730 1699 1729 + 1054 3 3 1786 1758 1757 + 1055 3 3 1729 1698 1728 + 1056 3 3 1697 1696 1727 + 1057 3 3 1730 1729 1758 + 1058 3 3 1642 1671 1643 + 1059 3 3 1642 1641 1671 + 1060 3 3 1672 1643 1671 + 1061 3 3 1643 1612 1642 + 1062 3 3 123 1672 122 + 1063 3 3 123 1643 1672 + 1064 3 3 1701 122 1672 + 1065 3 3 1700 1672 1671 + 1066 3 3 123 124 1643 + 1067 3 3 1700 1699 1730 + 1068 3 3 1671 1699 1700 + 1069 3 3 1760 1730 1759 + 1070 3 3 1701 1700 1730 + 1071 3 3 1701 1730 1731 + 1072 3 3 1731 1730 1760 + 1073 3 3 1732 1701 1731 + 1074 3 3 1702 122 1701 + 1075 3 3 1788 1761 1760 + 1076 3 3 1701 1672 1700 + 1077 3 3 1730 1758 1759 + 1078 3 3 1761 1731 1760 + 1079 3 3 1785 1757 1756 + 1080 3 3 1669 1640 1668 + 1081 3 3 1640 1639 1668 + 1082 3 3 1783 1755 1754 + 1083 3 3 1494 1452 76 + 1084 3 3 1505 1462 1504 + 1085 3 3 1090 1031 1089 + 1086 3 3 1147 1089 1088 + 1087 3 3 1092 1033 1091 + 1088 3 3 1149 1091 1090 + 1089 3 3 1151 1092 1091 + 1090 3 3 1091 1033 1090 + 1091 3 3 1149 1090 1089 + 1092 3 3 1089 1031 1088 + 1093 3 3 1147 1207 1148 + 1094 3 3 1207 1206 1264 + 1095 3 3 1208 1149 1148 + 1096 3 3 1148 1089 1147 + 1097 3 3 1151 1091 1150 + 1098 3 3 1209 1150 1149 + 1099 3 3 1210 1151 1150 + 1100 3 3 1150 1091 1149 + 1101 3 3 1211 1152 1151 + 1102 3 3 1149 1089 1148 + 1103 3 3 1147 1146 1207 + 1104 3 3 1152 1092 1151 + 1105 3 3 1095 1037 1094 + 1106 3 3 1153 1094 1093 + 1107 3 3 1154 1095 1094 + 1108 3 3 1096 1038 1095 + 1109 3 3 1157 1098 1097 + 1110 3 3 1156 1097 1096 + 1111 3 3 1099 1041 1098 + 1112 3 3 1097 1038 1096 + 1113 3 3 1154 1096 1095 + 1114 3 3 1094 1036 1093 + 1115 3 3 1212 1153 1152 + 1116 3 3 1213 1154 1153 + 1117 3 3 1154 1094 1153 + 1118 3 3 1153 1093 1152 + 1119 3 3 1157 1097 1156 + 1120 3 3 1214 1155 1154 + 1121 3 3 1215 1156 1155 + 1122 3 3 1156 1096 1155 + 1123 3 3 1217 1157 1156 + 1124 3 3 1155 1096 1154 + 1125 3 3 1093 1092 1152 + 1126 3 3 1158 1098 1157 + 1127 3 3 1208 1148 1207 + 1128 3 3 1093 1035 1092 + 1129 3 3 1208 1207 1265 + 1130 3 3 1265 1207 1264 + 1131 3 3 1319 1265 1264 + 1132 3 3 1266 1209 1208 + 1133 3 3 1211 1151 1210 + 1134 3 3 1266 1210 1209 + 1135 3 3 1267 1211 1210 + 1136 3 3 1210 1150 1209 + 1137 3 3 1266 1208 1265 + 1138 3 3 1209 1149 1208 + 1139 3 3 1320 1265 1319 + 1140 3 3 1319 1264 1318 + 1141 3 3 1370 1320 1319 + 1142 3 3 1266 1265 1320 + 1143 3 3 1267 1266 1321 + 1144 3 3 1321 1266 1320 + 1145 3 3 1371 1321 1320 + 1146 3 3 1268 1211 1267 + 1147 3 3 1370 1319 1318 + 1148 3 3 1267 1210 1266 + 1149 3 3 1264 1263 1318 + 1150 3 3 1322 1268 1267 + 1151 3 3 1214 1154 1213 + 1152 3 3 1271 1214 1213 + 1153 3 3 1271 1215 1214 + 1154 3 3 1213 1153 1212 + 1155 3 3 1217 1156 1216 + 1156 3 3 1273 1216 1215 + 1157 3 3 1274 1217 1216 + 1158 3 3 1216 1156 1215 + 1159 3 3 1270 1213 1212 + 1160 3 3 1215 1155 1214 + 1161 3 3 1270 1212 1269 + 1162 3 3 1322 1269 1268 + 1163 3 3 1324 1270 1269 + 1164 3 3 1271 1213 1270 + 1165 3 3 1273 1215 1272 + 1166 3 3 1326 1272 1271 + 1167 3 3 1326 1273 1272 + 1168 3 3 1272 1215 1271 + 1169 3 3 1324 1271 1270 + 1170 3 3 1269 1212 1268 + 1171 3 3 1212 1211 1268 + 1172 3 3 1274 1216 1273 + 1173 3 3 1327 1274 1273 + 1174 3 3 1212 1152 1211 + 1175 3 3 1088 1087 1147 + 1176 3 3 1218 1157 1217 + 1177 3 3 1099 1158 1100 + 1178 3 3 1158 1157 1218 + 1179 3 3 1160 1101 1100 + 1180 3 3 1101 1043 1100 + 1181 3 3 1103 1044 1102 + 1182 3 3 1160 1102 1101 + 1183 3 3 1162 1103 1102 + 1184 3 3 1102 1044 1101 + 1185 3 3 1159 1100 1158 + 1186 3 3 1104 1045 1103 + 1187 3 3 1159 1158 1219 + 1188 3 3 1219 1158 1218 + 1189 3 3 1275 1219 1218 + 1190 3 3 1160 1159 1219 + 1191 3 3 1162 1102 1161 + 1192 3 3 1220 1161 1160 + 1193 3 3 1222 1162 1161 + 1194 3 3 1161 1102 1160 + 1195 3 3 1223 1163 1162 + 1196 3 3 1160 1100 1159 + 1197 3 3 1099 1098 1158 + 1198 3 3 1104 1103 1162 + 1199 3 3 1106 1047 1105 + 1200 3 3 1164 1105 1104 + 1201 3 3 1165 1107 1106 + 1202 3 3 1107 1049 1106 + 1203 3 3 1109 1050 1108 + 1204 3 3 1166 1108 1107 + 1205 3 3 1168 1109 1108 + 1206 3 3 1108 1050 1107 + 1207 3 3 1165 1106 1105 + 1208 3 3 1105 1047 1104 + 1209 3 3 1165 1105 1164 + 1210 3 3 1223 1164 1163 + 1211 3 3 1225 1165 1164 + 1212 3 3 1164 1104 1163 + 1213 3 3 1168 1108 1167 + 1214 3 3 1227 1167 1166 + 1215 3 3 1228 1168 1167 + 1216 3 3 1167 1108 1166 + 1217 3 3 1226 1166 1165 + 1218 3 3 1166 1107 1165 + 1219 3 3 1104 1162 1163 + 1220 3 3 1169 1109 1168 + 1221 3 3 1220 1160 1219 + 1222 3 3 1100 1041 1099 + 1223 3 3 1277 1221 1220 + 1224 3 3 1275 1218 1274 + 1225 3 3 1278 1222 1221 + 1226 3 3 1221 1161 1220 + 1227 3 3 1280 1223 1222 + 1228 3 3 1280 1224 1223 + 1229 3 3 1225 1164 1224 + 1230 3 3 1223 1162 1222 + 1231 3 3 1276 1219 1275 + 1232 3 3 1224 1164 1223 + 1233 3 3 1277 1220 1276 + 1234 3 3 1332 1278 1277 + 1235 3 3 1333 1279 1278 + 1236 3 3 1278 1221 1277 + 1237 3 3 1280 1222 1279 + 1238 3 3 1334 1280 1279 + 1239 3 3 1334 1281 1280 + 1240 3 3 1279 1222 1278 + 1241 3 3 1331 1277 1276 + 1242 3 3 1220 1219 1276 + 1243 3 3 1329 1275 1274 + 1244 3 3 1281 1224 1280 + 1245 3 3 147 148 1227 + 1246 3 3 147 1227 1226 + 1247 3 3 1227 1166 1226 + 1248 3 3 1226 1165 1225 + 1249 3 3 1228 148 149 + 1250 3 3 1228 1227 148 + 1251 3 3 1229 1168 1228 + 1252 3 3 1283 1226 1225 + 1253 3 3 1228 1167 1227 + 1254 3 3 1281 145 1282 + 1255 3 3 1335 145 1281 + 1256 3 3 146 1282 145 + 1257 3 3 1283 1225 1282 + 1258 3 3 1283 146 147 + 1259 3 3 1283 1282 146 + 1260 3 3 147 1226 1283 + 1261 3 3 1225 1224 1282 + 1262 3 3 1282 1224 1281 + 1263 3 3 1330 1276 1275 + 1264 3 3 1222 1161 1221 + 1265 3 3 1218 1217 1274 + 1266 3 3 1110 1052 1109 + 1267 3 3 1322 1267 1321 + 1268 3 3 1098 1040 1097 + 1269 3 3 1418 1370 1369 + 1270 3 3 1369 1416 1417 + 1271 3 3 1418 1369 1417 + 1272 3 3 1371 1320 1370 + 1273 3 3 1371 1418 1419 + 1274 3 3 1371 1370 1418 + 1275 3 3 1464 1419 1418 + 1276 3 3 1420 1371 1419 + 1277 3 3 1463 1418 1417 + 1278 3 3 1372 1321 1371 + 1279 3 3 1463 1505 1464 + 1280 3 3 1463 1462 1505 + 1281 3 3 1506 1464 1505 + 1282 3 3 1465 1419 1464 + 1283 3 3 1465 1506 1507 + 1284 3 3 1465 1464 1506 + 1285 3 3 1546 1507 1506 + 1286 3 3 1420 1419 1465 + 1287 3 3 1546 1506 1505 + 1288 3 3 1464 1418 1463 + 1289 3 3 1417 1462 1463 + 1290 3 3 1466 1465 1507 + 1291 3 3 1322 1321 1373 + 1292 3 3 1373 1321 1372 + 1293 3 3 1372 1371 1420 + 1294 3 3 1421 1373 1372 + 1295 3 3 1323 1322 1374 + 1296 3 3 1374 1322 1373 + 1297 3 3 1421 1374 1373 + 1298 3 3 1375 1323 1374 + 1299 3 3 1421 1372 1420 + 1300 3 3 1324 1269 1323 + 1301 3 3 1421 1420 1467 + 1302 3 3 1467 1420 1466 + 1303 3 3 1420 1465 1466 + 1304 3 3 1509 1467 1466 + 1305 3 3 1422 1421 1468 + 1306 3 3 1468 1421 1467 + 1307 3 3 1510 1468 1467 + 1308 3 3 1423 1374 1422 + 1309 3 3 1509 1466 1508 + 1310 3 3 1422 1374 1421 + 1311 3 3 1466 1507 1508 + 1312 3 3 1423 1422 1468 + 1313 3 3 1548 1508 1507 + 1314 3 3 1370 1318 1369 + 1315 3 3 1580 1544 1579 + 1316 3 3 1544 1578 1579 + 1317 3 3 1579 1578 1613 + 1318 3 3 125 1580 1579 + 1319 3 3 1546 1545 1580 + 1320 3 3 1545 1544 1580 + 1321 3 3 125 126 1580 + 1322 3 3 1581 1580 126 + 1323 3 3 125 1579 1613 + 1324 3 3 1546 1505 1545 + 1325 3 3 121 1702 1732 + 1326 3 3 121 122 1702 + 1327 3 3 1732 1731 1761 + 1328 3 3 120 1732 1761 + 1329 3 3 121 1732 120 + 1330 3 3 1613 124 125 + 1331 3 3 1702 1701 1732 + 1332 3 3 1548 1507 1547 + 1333 3 3 1581 1547 1546 + 1334 3 3 130 1549 1548 + 1335 3 3 1549 1508 1548 + 1336 3 3 1509 1549 131 + 1337 3 3 1509 1508 1549 + 1338 3 3 130 131 1549 + 1339 3 3 1510 1467 1509 + 1340 3 3 129 1548 1547 + 1341 3 3 1547 1507 1546 + 1342 3 3 1581 127 1582 + 1343 3 3 1581 126 127 + 1344 3 3 128 1582 127 + 1345 3 3 129 1547 1582 + 1346 3 3 130 1548 129 + 1347 3 3 129 1582 128 + 1348 3 3 1582 1547 1581 + 1349 3 3 1546 1580 1581 + 1350 3 3 1505 1504 1545 + 1351 3 3 1318 1317 1369 + 1352 3 3 1510 1509 131 + 1353 3 3 1326 1271 1325 + 1354 3 3 1375 1325 1324 + 1355 3 3 1377 1327 1326 + 1356 3 3 1327 1273 1326 + 1357 3 3 1329 1274 1328 + 1358 3 3 1379 1328 1327 + 1359 3 3 1379 1329 1328 + 1360 3 3 1328 1274 1327 + 1361 3 3 1377 1326 1325 + 1362 3 3 1330 1275 1329 + 1363 3 3 1377 1325 1376 + 1364 3 3 1423 1376 1375 + 1365 3 3 1425 1378 1377 + 1366 3 3 1378 1327 1377 + 1367 3 3 1428 1380 1379 + 1368 3 3 1427 1379 1378 + 1369 3 3 1380 1329 1379 + 1370 3 3 1379 1327 1378 + 1371 3 3 1425 1377 1376 + 1372 3 3 1376 1325 1375 + 1373 3 3 1324 1323 1375 + 1374 3 3 1330 1329 1380 + 1375 3 3 1332 1277 1331 + 1376 3 3 1381 1331 1330 + 1377 3 3 142 1333 1332 + 1378 3 3 1333 1278 1332 + 1379 3 3 144 1335 1334 + 1380 3 3 143 1334 1333 + 1381 3 3 1335 1281 1334 + 1382 3 3 1334 1279 1333 + 1383 3 3 1383 1332 1331 + 1384 3 3 1331 1276 1330 + 1385 3 3 1383 1331 1382 + 1386 3 3 140 1382 1381 + 1387 3 3 141 1383 1382 + 1388 3 3 142 1332 1383 + 1389 3 3 144 1334 143 + 1390 3 3 143 1333 142 + 1391 3 3 141 142 1383 + 1392 3 3 1382 1331 1381 + 1393 3 3 1330 1380 1381 + 1394 3 3 144 145 1335 + 1395 3 3 1429 1381 1380 + 1396 3 3 1325 1271 1324 + 1397 3 3 1423 1469 1424 + 1398 3 3 1423 1468 1469 + 1399 3 3 1470 1424 1469 + 1400 3 3 1425 1376 1424 + 1401 3 3 1425 1470 1471 + 1402 3 3 1425 1424 1470 + 1403 3 3 134 1471 1470 + 1404 3 3 1472 1425 1471 + 1405 3 3 1512 1470 1469 + 1406 3 3 1426 1378 1425 + 1407 3 3 1510 132 1511 + 1408 3 3 1510 131 132 + 1409 3 3 133 1511 132 + 1410 3 3 1512 1469 1511 + 1411 3 3 134 1512 133 + 1412 3 3 134 1470 1512 + 1413 3 3 1512 1511 133 + 1414 3 3 1511 1469 1510 + 1415 3 3 1375 1374 1423 + 1416 3 3 135 1471 134 + 1417 3 3 1428 1379 1427 + 1418 3 3 136 1427 1426 + 1419 3 3 137 1428 1427 + 1420 3 3 1429 1380 1428 + 1421 3 3 141 1382 140 + 1422 3 3 139 1381 1429 + 1423 3 3 140 1381 139 + 1424 3 3 138 1429 1428 + 1425 3 3 1427 1378 1426 + 1426 3 3 1472 135 136 + 1427 3 3 1426 1425 1472 + 1428 3 3 137 1427 136 + 1429 3 3 139 1429 138 + 1430 3 3 138 1428 137 + 1431 3 3 136 1426 1472 + 1432 3 3 1472 1471 135 + 1433 3 3 1424 1376 1423 + 1434 3 3 1469 1468 1510 + 1435 3 3 1323 1269 1322 + 1436 3 3 1545 1504 1544 + 1437 3 3 119 120 1761 + 1438 3 3 1086 1028 1085 + 1439 3 3 1229 1228 149 + 1440 3 3 26 27 425 + 1441 3 3 27 424 425 + 1442 3 3 26 426 25 + 1443 3 3 26 425 426 + 1444 3 3 427 25 426 + 1445 3 3 445 426 425 + 1446 3 3 474 446 445 + 1447 3 3 425 444 445 + 1448 3 3 474 445 473 + 1449 3 3 427 426 446 + 1450 3 3 427 446 447 + 1451 3 3 475 447 446 + 1452 3 3 475 446 474 + 1453 3 3 448 427 447 + 1454 3 3 511 474 473 + 1455 3 3 446 426 445 + 1456 3 3 445 444 473 + 1457 3 3 24 25 427 + 1458 3 3 24 428 23 + 1459 3 3 24 427 428 + 1460 3 3 429 23 428 + 1461 3 3 22 429 430 + 1462 3 3 22 23 429 + 1463 3 3 449 430 429 + 1464 3 3 21 22 430 + 1465 3 3 449 429 428 + 1466 3 3 448 447 476 + 1467 3 3 428 427 448 + 1468 3 3 512 476 475 + 1469 3 3 449 448 476 + 1470 3 3 449 477 450 + 1471 3 3 449 476 477 + 1472 3 3 478 450 477 + 1473 3 3 450 430 449 + 1474 3 3 513 477 476 + 1475 3 3 449 428 448 + 1476 3 3 476 447 475 + 1477 3 3 21 430 450 + 1478 3 3 512 475 474 + 1479 3 3 510 552 511 + 1480 3 3 473 509 510 + 1481 3 3 553 511 552 + 1482 3 3 512 474 511 + 1483 3 3 512 511 554 + 1484 3 3 554 511 553 + 1485 3 3 598 554 553 + 1486 3 3 513 512 554 + 1487 3 3 596 553 552 + 1488 3 3 511 473 510 + 1489 3 3 552 551 596 + 1490 3 3 510 551 552 + 1491 3 3 689 641 688 + 1492 3 3 597 596 641 + 1493 3 3 597 641 642 + 1494 3 3 642 641 689 + 1495 3 3 598 597 642 + 1496 3 3 598 553 597 + 1497 3 3 738 690 689 + 1498 3 3 597 553 596 + 1499 3 3 641 640 688 + 1500 3 3 690 642 689 + 1501 3 3 513 554 555 + 1502 3 3 599 554 598 + 1503 3 3 555 554 599 + 1504 3 3 556 513 555 + 1505 3 3 514 513 556 + 1506 3 3 556 555 599 + 1507 3 3 600 556 599 + 1508 3 3 557 514 556 + 1509 3 3 643 599 598 + 1510 3 3 514 477 513 + 1511 3 3 691 644 643 + 1512 3 3 598 642 643 + 1513 3 3 691 643 690 + 1514 3 3 600 599 644 + 1515 3 3 600 644 645 + 1516 3 3 692 645 644 + 1517 3 3 692 646 645 + 1518 3 3 601 556 600 + 1519 3 3 738 691 690 + 1520 3 3 644 599 643 + 1521 3 3 643 642 690 + 1522 3 3 478 477 514 + 1523 3 3 737 689 688 + 1524 3 3 513 476 512 + 1525 3 3 596 640 641 + 1526 3 3 646 600 645 + 1527 3 3 21 451 431 + 1528 3 3 21 450 451 + 1529 3 3 20 431 451 + 1530 3 3 20 21 431 + 1531 3 3 20 452 19 + 1532 3 3 20 451 452 + 1533 3 3 453 19 452 + 1534 3 3 479 452 451 + 1535 3 3 516 479 478 + 1536 3 3 478 514 515 + 1537 3 3 516 478 515 + 1538 3 3 480 452 479 + 1539 3 3 480 479 517 + 1540 3 3 517 479 516 + 1541 3 3 560 518 517 + 1542 3 3 481 452 480 + 1543 3 3 559 517 516 + 1544 3 3 451 450 479 + 1545 3 3 479 450 478 + 1546 3 3 481 480 517 + 1547 3 3 18 453 454 + 1548 3 3 18 19 453 + 1549 3 3 483 455 454 + 1550 3 3 17 18 454 + 1551 3 3 17 455 16 + 1552 3 3 17 454 455 + 1553 3 3 456 16 455 + 1554 3 3 482 454 453 + 1555 3 3 519 482 481 + 1556 3 3 481 517 518 + 1557 3 3 519 483 482 + 1558 3 3 483 454 482 + 1559 3 3 456 455 484 + 1560 3 3 484 455 483 + 1561 3 3 520 484 483 + 1562 3 3 485 456 484 + 1563 3 3 519 481 518 + 1564 3 3 482 453 481 + 1565 3 3 453 452 481 + 1566 3 3 15 16 456 + 1567 3 3 557 516 515 + 1568 3 3 602 558 557 + 1569 3 3 557 556 601 + 1570 3 3 602 557 601 + 1571 3 3 559 516 558 + 1572 3 3 603 560 559 + 1573 3 3 603 559 558 + 1574 3 3 603 558 602 + 1575 3 3 560 517 559 + 1576 3 3 647 602 601 + 1577 3 3 561 518 560 + 1578 3 3 603 602 647 + 1579 3 3 647 601 646 + 1580 3 3 694 647 646 + 1581 3 3 648 603 647 + 1582 3 3 604 603 649 + 1583 3 3 649 603 648 + 1584 3 3 695 649 648 + 1585 3 3 650 604 649 + 1586 3 3 694 648 647 + 1587 3 3 604 560 603 + 1588 3 3 515 514 557 + 1589 3 3 561 560 604 + 1590 3 3 562 520 519 + 1591 3 3 519 518 561 + 1592 3 3 562 519 561 + 1593 3 3 520 483 519 + 1594 3 3 521 520 563 + 1595 3 3 563 520 562 + 1596 3 3 606 563 562 + 1597 3 3 564 521 563 + 1598 3 3 606 562 561 + 1599 3 3 521 484 520 + 1600 3 3 651 606 605 + 1601 3 3 605 604 650 + 1602 3 3 651 605 650 + 1603 3 3 606 561 605 + 1604 3 3 607 651 652 + 1605 3 3 607 606 651 + 1606 3 3 697 651 650 + 1607 3 3 608 607 652 + 1608 3 3 698 652 651 + 1609 3 3 607 563 606 + 1610 3 3 561 604 605 + 1611 3 3 485 484 521 + 1612 3 3 697 650 649 + 1613 3 3 558 516 557 + 1614 3 3 601 600 646 + 1615 3 3 564 563 607 + 1616 3 3 692 644 691 + 1617 3 3 787 737 736 + 1618 3 3 736 735 786 + 1619 3 3 787 736 786 + 1620 3 3 738 689 737 + 1621 3 3 738 787 788 + 1622 3 3 738 737 787 + 1623 3 3 838 788 787 + 1624 3 3 789 738 788 + 1625 3 3 837 787 786 + 1626 3 3 739 691 738 + 1627 3 3 890 838 837 + 1628 3 3 837 888 889 + 1629 3 3 890 837 889 + 1630 3 3 838 787 837 + 1631 3 3 839 838 891 + 1632 3 3 891 838 890 + 1633 3 3 945 892 891 + 1634 3 3 840 839 891 + 1635 3 3 944 891 890 + 1636 3 3 839 788 838 + 1637 3 3 786 836 837 + 1638 3 3 840 788 839 + 1639 3 3 740 692 739 + 1640 3 3 692 691 739 + 1641 3 3 739 738 789 + 1642 3 3 790 740 739 + 1643 3 3 693 740 741 + 1644 3 3 693 692 740 + 1645 3 3 791 741 740 + 1646 3 3 742 693 741 + 1647 3 3 790 739 789 + 1648 3 3 694 646 693 + 1649 3 3 790 789 841 + 1650 3 3 841 789 840 + 1651 3 3 840 891 892 + 1652 3 3 841 840 892 + 1653 3 3 791 841 842 + 1654 3 3 791 790 841 + 1655 3 3 894 842 841 + 1656 3 3 742 741 791 + 1657 3 3 893 841 892 + 1658 3 3 791 740 790 + 1659 3 3 789 788 840 + 1660 3 3 792 791 842 + 1661 3 3 942 890 889 + 1662 3 3 737 688 736 + 1663 3 3 942 997 943 + 1664 3 3 942 996 997 + 1665 3 3 998 943 997 + 1666 3 3 944 890 943 + 1667 3 3 944 943 999 + 1668 3 3 999 943 998 + 1669 3 3 1055 999 998 + 1670 3 3 945 944 999 + 1671 3 3 1054 998 997 + 1672 3 3 945 891 944 + 1673 3 3 1053 1110 1111 + 1674 3 3 997 996 1053 + 1675 3 3 1170 1112 1111 + 1676 3 3 1112 1053 1111 + 1677 3 3 1113 1055 1054 + 1678 3 3 1054 1053 1112 + 1679 3 3 1113 1054 1112 + 1680 3 3 1055 998 1054 + 1681 3 3 1169 1111 1110 + 1682 3 3 1054 997 1053 + 1683 3 3 889 888 942 + 1684 3 3 1000 999 1055 + 1685 3 3 893 892 946 + 1686 3 3 946 892 945 + 1687 3 3 945 999 1000 + 1688 3 3 946 945 1000 + 1689 3 3 894 893 947 + 1690 3 3 947 893 946 + 1691 3 3 1002 947 946 + 1692 3 3 895 842 894 + 1693 3 3 1001 946 1000 + 1694 3 3 894 841 893 + 1695 3 3 1056 1055 1114 + 1696 3 3 1057 1000 1056 + 1697 3 3 153 1114 1113 + 1698 3 3 1115 1056 1114 + 1699 3 3 1058 1001 1057 + 1700 3 3 1001 1000 1057 + 1701 3 3 1057 1056 1115 + 1702 3 3 1002 946 1001 + 1703 3 3 1174 1115 1114 + 1704 3 3 1000 1055 1056 + 1705 3 3 1114 1055 1113 + 1706 3 3 1116 1058 1057 + 1707 3 3 1171 1113 1112 + 1708 3 3 943 890 942 + 1709 3 3 688 735 736 + 1710 3 3 895 894 947 + 1711 3 3 743 695 694 + 1712 3 3 694 693 742 + 1713 3 3 743 694 742 + 1714 3 3 695 648 694 + 1715 3 3 696 743 744 + 1716 3 3 696 695 743 + 1717 3 3 794 744 743 + 1718 3 3 745 696 744 + 1719 3 3 792 743 742 + 1720 3 3 697 649 696 + 1721 3 3 792 843 793 + 1722 3 3 792 842 843 + 1723 3 3 844 793 843 + 1724 3 3 794 743 793 + 1725 3 3 794 844 845 + 1726 3 3 794 793 844 + 1727 3 3 898 846 845 + 1728 3 3 795 794 845 + 1729 3 3 896 845 844 + 1730 3 3 793 743 792 + 1731 3 3 742 791 792 + 1732 3 3 795 744 794 + 1733 3 3 697 745 698 + 1734 3 3 697 696 745 + 1735 3 3 746 698 745 + 1736 3 3 698 651 697 + 1737 3 3 699 746 747 + 1738 3 3 699 698 746 + 1739 3 3 797 747 746 + 1740 3 3 653 652 699 + 1741 3 3 796 746 745 + 1742 3 3 699 652 698 + 1743 3 3 847 796 795 + 1744 3 3 795 845 846 + 1745 3 3 847 795 846 + 1746 3 3 796 745 795 + 1747 3 3 797 847 848 + 1748 3 3 797 796 847 + 1749 3 3 900 848 847 + 1750 3 3 798 747 797 + 1751 3 3 899 847 846 + 1752 3 3 797 746 796 + 1753 3 3 745 744 795 + 1754 3 3 700 699 747 + 1755 3 3 896 844 843 + 1756 3 3 696 649 695 + 1757 3 3 949 896 895 + 1758 3 3 895 947 948 + 1759 3 3 949 895 948 + 1760 3 3 896 843 895 + 1761 3 3 897 949 950 + 1762 3 3 897 896 949 + 1763 3 3 1004 950 949 + 1764 3 3 951 897 950 + 1765 3 3 1003 949 948 + 1766 3 3 898 845 897 + 1767 3 3 1002 1058 1003 + 1768 3 3 1002 1001 1058 + 1769 3 3 1059 1003 1058 + 1770 3 3 1004 949 1003 + 1771 3 3 1004 1003 1060 + 1772 3 3 1060 1003 1059 + 1773 3 3 1117 1059 1058 + 1774 3 3 1005 950 1004 + 1775 3 3 1118 1060 1059 + 1776 3 3 1003 948 1002 + 1777 3 3 843 842 895 + 1778 3 3 1061 1004 1060 + 1779 3 3 952 899 898 + 1780 3 3 898 897 951 + 1781 3 3 952 898 951 + 1782 3 3 899 846 898 + 1783 3 3 900 899 953 + 1784 3 3 953 899 952 + 1785 3 3 1007 953 952 + 1786 3 3 849 848 900 + 1787 3 3 1006 952 951 + 1788 3 3 900 847 899 + 1789 3 3 1005 1061 1006 + 1790 3 3 1005 1004 1061 + 1791 3 3 1062 1006 1061 + 1792 3 3 1007 952 1006 + 1793 3 3 1007 1006 1063 + 1794 3 3 1063 1006 1062 + 1795 3 3 1121 1063 1062 + 1796 3 3 1008 953 1007 + 1797 3 3 1118 1061 1060 + 1798 3 3 1006 951 1005 + 1799 3 3 951 950 1005 + 1800 3 3 1008 1007 1063 + 1801 3 3 1119 1062 1061 + 1802 3 3 897 845 896 + 1803 3 3 948 947 1002 + 1804 3 3 954 900 953 + 1805 3 3 1121 1064 1063 + 1806 3 3 693 646 692 + 1807 3 3 1053 1052 1110 + 1808 3 3 798 797 848 + 1809 3 3 14 15 457 + 1810 3 3 15 456 457 + 1811 3 3 14 458 13 + 1812 3 3 14 457 458 + 1813 3 3 486 13 458 + 1814 3 3 486 458 457 + 1815 3 3 485 522 486 + 1816 3 3 457 456 485 + 1817 3 3 523 486 522 + 1818 3 3 486 457 485 + 1819 3 3 487 523 524 + 1820 3 3 487 486 523 + 1821 3 3 565 524 523 + 1822 3 3 525 487 524 + 1823 3 3 565 523 522 + 1824 3 3 487 13 486 + 1825 3 3 485 521 522 + 1826 3 3 12 13 487 + 1827 3 3 12 488 11 + 1828 3 3 12 487 488 + 1829 3 3 489 11 488 + 1830 3 3 490 9 10 + 1831 3 3 10 11 489 + 1832 3 3 490 10 489 + 1833 3 3 525 489 488 + 1834 3 3 527 489 526 + 1835 3 3 526 489 525 + 1836 3 3 567 526 525 + 1837 3 3 490 489 527 + 1838 3 3 491 527 528 + 1839 3 3 491 490 527 + 1840 3 3 570 528 527 + 1841 3 3 492 491 528 + 1842 3 3 569 527 526 + 1843 3 3 491 9 490 + 1844 3 3 488 487 525 + 1845 3 3 8 9 491 + 1846 3 3 567 525 524 + 1847 3 3 564 608 565 + 1848 3 3 522 521 564 + 1849 3 3 609 565 608 + 1850 3 3 565 522 564 + 1851 3 3 566 609 610 + 1852 3 3 566 565 609 + 1853 3 3 655 610 609 + 1854 3 3 567 566 610 + 1855 3 3 653 609 608 + 1856 3 3 566 524 565 + 1857 3 3 701 654 653 + 1858 3 3 564 607 608 + 1859 3 3 701 653 700 + 1860 3 3 654 609 653 + 1861 3 3 655 701 702 + 1862 3 3 655 654 701 + 1863 3 3 751 703 702 + 1864 3 3 656 610 655 + 1865 3 3 748 701 700 + 1866 3 3 655 609 654 + 1867 3 3 653 699 700 + 1868 3 3 656 655 702 + 1869 3 3 612 568 567 + 1870 3 3 567 610 611 + 1871 3 3 612 567 611 + 1872 3 3 568 526 567 + 1873 3 3 569 568 613 + 1874 3 3 613 568 612 + 1875 3 3 657 613 612 + 1876 3 3 570 569 613 + 1877 3 3 657 612 611 + 1878 3 3 569 526 568 + 1879 3 3 656 703 657 + 1880 3 3 656 702 703 + 1881 3 3 704 657 703 + 1882 3 3 657 611 656 + 1883 3 3 658 657 705 + 1884 3 3 705 657 704 + 1885 3 3 754 706 705 + 1886 3 3 614 613 658 + 1887 3 3 751 704 703 + 1888 3 3 658 613 657 + 1889 3 3 611 610 656 + 1890 3 3 570 527 569 + 1891 3 3 750 702 701 + 1892 3 3 567 524 566 + 1893 3 3 608 652 653 + 1894 3 3 706 658 705 + 1895 3 3 8 491 492 + 1896 3 3 492 528 529 + 1897 3 3 530 493 492 + 1898 3 3 7 8 492 + 1899 3 3 7 493 6 + 1900 3 3 7 492 493 + 1901 3 3 5 6 493 + 1902 3 3 530 492 529 + 1903 3 3 572 529 571 + 1904 3 3 529 528 571 + 1905 3 3 615 572 571 + 1906 3 3 530 529 572 + 1907 3 3 531 530 573 + 1908 3 3 573 530 572 + 1909 3 3 617 574 573 + 1910 3 3 574 531 573 + 1911 3 3 617 573 572 + 1912 3 3 531 493 530 + 1913 3 3 571 528 570 + 1914 3 3 5 493 531 + 1915 3 3 5 531 4 + 1916 3 3 4 531 532 + 1917 3 3 3 4 532 + 1918 3 3 533 2 3 + 1919 3 3 534 1 2 + 1920 3 3 533 3 532 + 1921 3 3 533 532 575 + 1922 3 3 575 532 574 + 1923 3 3 619 576 575 + 1924 3 3 534 533 575 + 1925 3 3 534 576 404 + 1926 3 3 534 575 576 + 1927 3 3 403 404 576 + 1928 3 3 404 1 534 + 1929 3 3 619 575 574 + 1930 3 3 534 2 533 + 1931 3 3 532 531 574 + 1932 3 3 614 571 570 + 1933 3 3 614 659 615 + 1934 3 3 614 658 659 + 1935 3 3 660 615 659 + 1936 3 3 616 572 615 + 1937 3 3 662 617 616 + 1938 3 3 616 615 660 + 1939 3 3 661 616 660 + 1940 3 3 617 572 616 + 1941 3 3 707 660 659 + 1942 3 3 618 574 617 + 1943 3 3 708 660 707 + 1944 3 3 707 659 706 + 1945 3 3 755 708 707 + 1946 3 3 661 660 708 + 1947 3 3 662 708 709 + 1948 3 3 662 661 708 + 1949 3 3 756 709 708 + 1950 3 3 710 662 709 + 1951 3 3 754 707 706 + 1952 3 3 662 616 661 + 1953 3 3 659 658 706 + 1954 3 3 618 617 662 + 1955 3 3 664 619 618 + 1956 3 3 618 662 663 + 1957 3 3 664 620 619 + 1958 3 3 620 576 619 + 1959 3 3 403 620 402 + 1960 3 3 403 576 620 + 1961 3 3 665 402 620 + 1962 3 3 664 618 663 + 1963 3 3 619 574 618 + 1964 3 3 664 710 711 + 1965 3 3 664 663 710 + 1966 3 3 758 711 710 + 1967 3 3 665 664 711 + 1968 3 3 665 712 401 + 1969 3 3 665 711 712 + 1970 3 3 400 401 712 + 1971 3 3 401 402 665 + 1972 3 3 760 712 711 + 1973 3 3 665 620 664 + 1974 3 3 663 662 710 + 1975 3 3 758 710 709 + 1976 3 3 615 571 614 + 1977 3 3 570 613 614 + 1978 3 3 752 705 704 + 1979 3 3 748 798 749 + 1980 3 3 748 747 798 + 1981 3 3 799 749 798 + 1982 3 3 750 701 749 + 1983 3 3 750 799 800 + 1984 3 3 750 749 799 + 1985 3 3 851 800 799 + 1986 3 3 801 750 800 + 1987 3 3 849 799 798 + 1988 3 3 751 702 750 + 1989 3 3 902 850 849 + 1990 3 3 849 900 901 + 1991 3 3 902 849 901 + 1992 3 3 851 799 850 + 1993 3 3 851 902 903 + 1994 3 3 851 850 902 + 1995 3 3 956 903 902 + 1996 3 3 852 800 851 + 1997 3 3 955 902 901 + 1998 3 3 850 799 849 + 1999 3 3 798 848 849 + 2000 3 3 852 851 903 + 2001 3 3 751 801 752 + 2002 3 3 751 750 801 + 2003 3 3 802 752 801 + 2004 3 3 752 704 751 + 2005 3 3 803 754 753 + 2006 3 3 753 752 802 + 2007 3 3 803 753 802 + 2008 3 3 754 705 753 + 2009 3 3 852 802 801 + 2010 3 3 755 707 754 + 2011 3 3 854 802 853 + 2012 3 3 853 802 852 + 2013 3 3 905 853 852 + 2014 3 3 803 802 854 + 2015 3 3 804 854 855 + 2016 3 3 804 803 854 + 2017 3 3 906 854 853 + 2018 3 3 856 804 855 + 2019 3 3 906 855 854 + 2020 3 3 804 754 803 + 2021 3 3 801 800 852 + 2022 3 3 805 754 804 + 2023 3 3 904 852 903 + 2024 3 3 753 705 752 + 2025 3 3 954 1008 1009 + 2026 3 3 901 900 954 + 2027 3 3 1065 1009 1008 + 2028 3 3 955 954 1009 + 2029 3 3 904 903 956 + 2030 3 3 956 902 955 + 2031 3 3 1011 956 955 + 2032 3 3 957 904 956 + 2033 3 3 1010 955 1009 + 2034 3 3 955 901 954 + 2035 3 3 1010 1009 1065 + 2036 3 3 1065 1008 1064 + 2037 3 3 1123 1066 1065 + 2038 3 3 1066 1010 1065 + 2039 3 3 1011 1066 1067 + 2040 3 3 1011 1010 1066 + 2041 3 3 1124 1067 1066 + 2042 3 3 1012 956 1011 + 2043 3 3 1125 1068 1067 + 2044 3 3 1011 955 1010 + 2045 3 3 1008 1063 1064 + 2046 3 3 1012 1011 1067 + 2047 3 3 905 957 958 + 2048 3 3 905 904 957 + 2049 3 3 1013 958 957 + 2050 3 3 959 905 958 + 2051 3 3 906 959 907 + 2052 3 3 906 905 959 + 2053 3 3 960 907 959 + 2054 3 3 907 855 906 + 2055 3 3 1014 959 958 + 2056 3 3 906 853 905 + 2057 3 3 1012 1068 1013 + 2058 3 3 1012 1067 1068 + 2059 3 3 1069 1013 1068 + 2060 3 3 1013 957 1012 + 2061 3 3 1014 1069 1070 + 2062 3 3 1014 1013 1069 + 2063 3 3 1127 1070 1069 + 2064 3 3 1015 959 1014 + 2065 3 3 1127 1069 1068 + 2066 3 3 1014 958 1013 + 2067 3 3 957 956 1012 + 2068 3 3 1015 1014 1070 + 2069 3 3 1123 1065 1064 + 2070 3 3 905 852 904 + 2071 3 3 700 747 748 + 2072 3 3 908 855 907 + 2073 3 3 755 805 756 + 2074 3 3 805 804 856 + 2075 3 3 806 756 805 + 2076 3 3 757 709 756 + 2077 3 3 757 756 807 + 2078 3 3 807 756 806 + 2079 3 3 858 807 806 + 2080 3 3 808 757 807 + 2081 3 3 856 806 805 + 2082 3 3 758 709 757 + 2083 3 3 856 908 857 + 2084 3 3 856 855 908 + 2085 3 3 909 857 908 + 2086 3 3 857 806 856 + 2087 3 3 858 909 910 + 2088 3 3 858 857 909 + 2089 3 3 963 910 909 + 2090 3 3 808 807 858 + 2091 3 3 962 909 908 + 2092 3 3 858 806 857 + 2093 3 3 755 754 805 + 2094 3 3 859 858 910 + 2095 3 3 809 759 758 + 2096 3 3 758 757 808 + 2097 3 3 809 399 759 + 2098 3 3 760 711 759 + 2099 3 3 400 760 399 + 2100 3 3 400 712 760 + 2101 3 3 760 759 399 + 2102 3 3 809 758 808 + 2103 3 3 759 711 758 + 2104 3 3 809 859 860 + 2105 3 3 809 808 859 + 2106 3 3 912 860 859 + 2107 3 3 398 809 860 + 2108 3 3 810 809 398 + 2109 3 3 398 860 397 + 2110 3 3 398 399 810 + 2111 3 3 912 397 860 + 2112 3 3 810 399 809 + 2113 3 3 808 858 859 + 2114 3 3 911 859 910 + 2115 3 3 756 708 755 + 2116 3 3 1016 961 960 + 2117 3 3 960 959 1015 + 2118 3 3 1016 960 1015 + 2119 3 3 962 908 961 + 2120 3 3 1017 963 962 + 2121 3 3 962 961 1016 + 2122 3 3 1017 962 1016 + 2123 3 3 963 909 962 + 2124 3 3 1072 1016 1015 + 2125 3 3 964 910 963 + 2126 3 3 1073 1016 1072 + 2127 3 3 1072 1015 1071 + 2128 3 3 1131 1073 1072 + 2129 3 3 1017 1016 1073 + 2130 3 3 1018 1073 1074 + 2131 3 3 1018 1017 1073 + 2132 3 3 1133 1075 1074 + 2133 3 3 1019 963 1018 + 2134 3 3 1130 1072 1071 + 2135 3 3 1018 963 1017 + 2136 3 3 1015 1070 1071 + 2137 3 3 1075 1018 1074 + 2138 3 3 911 964 912 + 2139 3 3 911 910 964 + 2140 3 3 965 912 964 + 2141 3 3 912 859 911 + 2142 3 3 396 965 395 + 2143 3 3 396 912 965 + 2144 3 3 1020 395 965 + 2145 3 3 1019 965 964 + 2146 3 3 396 397 912 + 2147 3 3 1076 1020 1019 + 2148 3 3 964 963 1019 + 2149 3 3 1076 1019 1075 + 2150 3 3 1020 965 1019 + 2151 3 3 394 1076 393 + 2152 3 3 394 1020 1076 + 2153 3 3 1134 393 1076 + 2154 3 3 1133 1076 1075 + 2155 3 3 394 395 1020 + 2156 3 3 1019 1018 1075 + 2157 3 3 1128 1071 1070 + 2158 3 3 908 907 961 + 2159 3 3 961 907 960 + 2160 3 3 1131 1074 1073 + 2161 3 3 749 701 748 + 2162 3 3 954 953 1008 + 2163 3 3 1116 1057 1115 + 2164 3 3 1171 1112 1170 + 2165 3 3 151 1171 1170 + 2166 3 3 1171 152 1172 + 2167 3 3 151 152 1171 + 2168 3 3 1172 1113 1171 + 2169 3 3 150 1170 1169 + 2170 3 3 153 1113 1172 + 2171 3 3 151 1170 150 + 2172 3 3 150 1169 1229 + 2173 3 3 154 155 1230 + 2174 3 3 1284 1230 155 + 2175 3 3 153 1172 152 + 2176 3 3 156 1284 155 + 2177 3 3 1169 1168 1229 + 2178 3 3 153 154 1230 + 2179 3 3 153 1231 1173 + 2180 3 3 153 1230 1231 + 2181 3 3 1174 1173 1231 + 2182 3 3 1174 1114 1173 + 2183 3 3 1116 1174 1175 + 2184 3 3 1116 1115 1174 + 2185 3 3 1232 1175 1174 + 2186 3 3 1176 1116 1175 + 2187 3 3 1232 1174 1231 + 2188 3 3 1173 1114 153 + 2189 3 3 1232 1231 1285 + 2190 3 3 1231 1230 1285 + 2191 3 3 1337 1286 1285 + 2192 3 3 1286 1232 1285 + 2193 3 3 1233 1232 1287 + 2194 3 3 1287 1232 1286 + 2195 3 3 1338 1287 1286 + 2196 3 3 1288 1233 1287 + 2197 3 3 1337 1285 1284 + 2198 3 3 1233 1175 1232 + 2199 3 3 1285 1230 1284 + 2200 3 3 1176 1175 1233 + 2201 3 3 1229 149 150 + 2202 3 3 1170 1111 1169 + 2203 3 3 156 157 1336 + 2204 3 3 1384 1336 157 + 2205 3 3 1337 1284 1336 + 2206 3 3 1337 1336 1385 + 2207 3 3 1385 1336 1384 + 2208 3 3 1430 1385 1384 + 2209 3 3 1386 1337 1385 + 2210 3 3 158 1384 157 + 2211 3 3 1338 1286 1337 + 2212 3 3 1430 158 159 + 2213 3 3 1473 159 160 + 2214 3 3 1430 159 1473 + 2215 3 3 1473 160 1513 + 2216 3 3 1431 1430 1473 + 2217 3 3 1431 1385 1430 + 2218 3 3 161 1513 160 + 2219 3 3 1430 1384 158 + 2220 3 3 1514 1473 1513 + 2221 3 3 1338 1337 1386 + 2222 3 3 1386 1385 1431 + 2223 3 3 1432 1386 1431 + 2224 3 3 1387 1338 1386 + 2225 3 3 1339 1338 1387 + 2226 3 3 1433 1387 1386 + 2227 3 3 1433 1386 1432 + 2228 3 3 1388 1339 1387 + 2229 3 3 1475 1432 1431 + 2230 3 3 1339 1287 1338 + 2231 3 3 1515 1475 1474 + 2232 3 3 1431 1473 1474 + 2233 3 3 1515 1474 1514 + 2234 3 3 1433 1432 1475 + 2235 3 3 1433 1475 1476 + 2236 3 3 1476 1475 1515 + 2237 3 3 1517 1477 1476 + 2238 3 3 1388 1387 1433 + 2239 3 3 1551 1515 1514 + 2240 3 3 1475 1431 1474 + 2241 3 3 1474 1473 1514 + 2242 3 3 1434 1433 1476 + 2243 3 3 1551 1514 1513 + 2244 3 3 1336 1284 156 + 2245 3 3 1288 1287 1339 + 2246 3 3 1117 1176 1118 + 2247 3 3 1117 1116 1176 + 2248 3 3 1177 1118 1176 + 2249 3 3 1119 1061 1118 + 2250 3 3 1119 1177 1178 + 2251 3 3 1119 1118 1177 + 2252 3 3 1236 1178 1177 + 2253 3 3 1120 1119 1178 + 2254 3 3 1235 1177 1176 + 2255 3 3 1120 1062 1119 + 2256 3 3 1289 1235 1234 + 2257 3 3 1176 1233 1234 + 2258 3 3 1289 1234 1288 + 2259 3 3 1235 1176 1234 + 2260 3 3 1236 1289 1290 + 2261 3 3 1236 1235 1289 + 2262 3 3 1341 1290 1289 + 2263 3 3 1237 1178 1236 + 2264 3 3 1340 1289 1288 + 2265 3 3 1236 1177 1235 + 2266 3 3 1234 1233 1288 + 2267 3 3 1291 1236 1290 + 2268 3 3 1180 1121 1120 + 2269 3 3 1120 1178 1179 + 2270 3 3 1180 1120 1179 + 2271 3 3 1121 1062 1120 + 2272 3 3 1122 1180 1181 + 2273 3 3 1122 1121 1180 + 2274 3 3 1238 1181 1180 + 2275 3 3 1182 1122 1181 + 2276 3 3 1237 1180 1179 + 2277 3 3 1123 1064 1122 + 2278 3 3 1237 1291 1238 + 2279 3 3 1237 1236 1291 + 2280 3 3 1292 1238 1291 + 2281 3 3 1238 1180 1237 + 2282 3 3 1239 1292 1293 + 2283 3 3 1239 1238 1292 + 2284 3 3 1345 1293 1292 + 2285 3 3 1240 1181 1239 + 2286 3 3 1344 1292 1291 + 2287 3 3 1239 1181 1238 + 2288 3 3 1179 1178 1237 + 2289 3 3 1294 1239 1293 + 2290 3 3 1343 1291 1290 + 2291 3 3 1122 1064 1121 + 2292 3 3 1389 1341 1340 + 2293 3 3 1288 1339 1340 + 2294 3 3 1389 1340 1388 + 2295 3 3 1341 1289 1340 + 2296 3 3 1342 1389 1390 + 2297 3 3 1342 1341 1389 + 2298 3 3 1436 1390 1389 + 2299 3 3 1343 1342 1390 + 2300 3 3 1435 1389 1388 + 2301 3 3 1343 1290 1342 + 2302 3 3 1478 1435 1434 + 2303 3 3 1388 1433 1434 + 2304 3 3 1478 1434 1477 + 2305 3 3 1436 1389 1435 + 2306 3 3 1436 1435 1479 + 2307 3 3 1479 1435 1478 + 2308 3 3 1518 1479 1478 + 2309 3 3 1391 1390 1436 + 2310 3 3 1517 1478 1477 + 2311 3 3 1435 1388 1434 + 2312 3 3 1340 1339 1388 + 2313 3 3 1437 1436 1479 + 2314 3 3 1343 1391 1344 + 2315 3 3 1343 1390 1391 + 2316 3 3 1392 1344 1391 + 2317 3 3 1345 1292 1344 + 2318 3 3 1345 1344 1393 + 2319 3 3 1393 1344 1392 + 2320 3 3 1438 1393 1392 + 2321 3 3 1394 1345 1393 + 2322 3 3 1438 1392 1391 + 2323 3 3 1344 1291 1343 + 2324 3 3 1481 1438 1437 + 2325 3 3 1437 1479 1480 + 2326 3 3 1481 1437 1480 + 2327 3 3 1438 1391 1437 + 2328 3 3 1439 1481 1482 + 2329 3 3 1439 1438 1481 + 2330 3 3 1520 1480 1479 + 2331 3 3 1483 1439 1482 + 2332 3 3 1521 1481 1480 + 2333 3 3 1439 1393 1438 + 2334 3 3 1391 1436 1437 + 2335 3 3 1440 1393 1439 + 2336 3 3 1522 1482 1481 + 2337 3 3 1342 1290 1341 + 2338 3 3 1434 1476 1477 + 2339 3 3 1346 1293 1345 + 2340 3 3 1516 1476 1515 + 2341 3 3 1117 1058 1116 + 2342 3 3 1550 161 162 + 2343 3 3 1584 162 1583 + 2344 3 3 1550 1584 1551 + 2345 3 3 1550 162 1584 + 2346 3 3 1585 1551 1584 + 2347 3 3 1551 1513 1550 + 2348 3 3 163 1584 1583 + 2349 3 3 1552 1515 1551 + 2350 3 3 163 164 1614 + 2351 3 3 1644 1614 164 + 2352 3 3 1615 163 1614 + 2353 3 3 1615 1614 1645 + 2354 3 3 1645 1614 1644 + 2355 3 3 1674 1646 1645 + 2356 3 3 1616 1584 1615 + 2357 3 3 165 1644 164 + 2358 3 3 1615 1584 163 + 2359 3 3 162 163 1583 + 2360 3 3 1616 1615 1645 + 2361 3 3 1552 1551 1586 + 2362 3 3 1586 1551 1585 + 2363 3 3 1617 1587 1586 + 2364 3 3 1553 1552 1586 + 2365 3 3 1517 1516 1553 + 2366 3 3 1516 1515 1553 + 2367 3 3 1553 1586 1587 + 2368 3 3 1554 1553 1587 + 2369 3 3 1617 1586 1585 + 2370 3 3 1553 1515 1552 + 2371 3 3 1647 1617 1616 + 2372 3 3 1616 1645 1646 + 2373 3 3 1647 1616 1646 + 2374 3 3 1617 1585 1616 + 2375 3 3 1618 1647 1648 + 2376 3 3 1618 1617 1647 + 2377 3 3 1676 1648 1647 + 2378 3 3 1619 1587 1618 + 2379 3 3 1676 1647 1646 + 2380 3 3 1618 1587 1617 + 2381 3 3 1585 1584 1616 + 2382 3 3 1649 1618 1648 + 2383 3 3 1673 1645 1644 + 2384 3 3 1550 1513 161 + 2385 3 3 165 166 1673 + 2386 3 3 1703 1673 166 + 2387 3 3 1674 1645 1673 + 2388 3 3 1674 1703 1704 + 2389 3 3 1674 1673 1703 + 2390 3 3 1733 1704 1703 + 2391 3 3 1675 1674 1704 + 2392 3 3 167 1703 166 + 2393 3 3 1675 1646 1674 + 2394 3 3 167 168 1733 + 2395 3 3 1762 1733 168 + 2396 3 3 1734 1704 1733 + 2397 3 3 1734 1733 1763 + 2398 3 3 1763 1733 1762 + 2399 3 3 1792 1764 1763 + 2400 3 3 1735 1704 1734 + 2401 3 3 169 1762 168 + 2402 3 3 1733 1703 167 + 2403 3 3 1764 1734 1763 + 2404 3 3 1706 1676 1675 + 2405 3 3 1675 1704 1705 + 2406 3 3 1706 1675 1705 + 2407 3 3 1676 1646 1675 + 2408 3 3 1677 1706 1707 + 2409 3 3 1677 1676 1706 + 2410 3 3 1736 1707 1706 + 2411 3 3 1708 1677 1707 + 2412 3 3 1736 1706 1705 + 2413 3 3 1677 1648 1676 + 2414 3 3 1765 1736 1735 + 2415 3 3 1705 1704 1735 + 2416 3 3 1765 1735 1764 + 2417 3 3 1736 1705 1735 + 2418 3 3 1737 1765 1766 + 2419 3 3 1737 1736 1765 + 2420 3 3 1796 1767 1766 + 2421 3 3 1708 1707 1737 + 2422 3 3 1794 1765 1764 + 2423 3 3 1737 1707 1736 + 2424 3 3 1735 1734 1764 + 2425 3 3 1678 1648 1677 + 2426 3 3 1792 1763 1762 + 2427 3 3 1673 1644 165 + 2428 3 3 1767 1737 1766 + 2429 3 3 1517 1554 1518 + 2430 3 3 1517 1553 1554 + 2431 3 3 1555 1518 1554 + 2432 3 3 1519 1479 1518 + 2433 3 3 1519 1518 1556 + 2434 3 3 1556 1518 1555 + 2435 3 3 1590 1556 1555 + 2436 3 3 1557 1519 1556 + 2437 3 3 1588 1555 1554 + 2438 3 3 1520 1479 1519 + 2439 3 3 1620 1589 1588 + 2440 3 3 1554 1587 1588 + 2441 3 3 1620 1588 1619 + 2442 3 3 1590 1555 1589 + 2443 3 3 1590 1620 1621 + 2444 3 3 1590 1589 1620 + 2445 3 3 1651 1621 1620 + 2446 3 3 1591 1556 1590 + 2447 3 3 1650 1620 1619 + 2448 3 3 1589 1555 1588 + 2449 3 3 1588 1587 1619 + 2450 3 3 1622 1590 1621 + 2451 3 3 1520 1557 1521 + 2452 3 3 1520 1519 1557 + 2453 3 3 1558 1521 1557 + 2454 3 3 1522 1481 1521 + 2455 3 3 1522 1558 1559 + 2456 3 3 1522 1521 1558 + 2457 3 3 1593 1559 1558 + 2458 3 3 1523 1482 1522 + 2459 3 3 1592 1558 1557 + 2460 3 3 1521 1480 1520 + 2461 3 3 1591 1622 1592 + 2462 3 3 1591 1590 1622 + 2463 3 3 1623 1592 1622 + 2464 3 3 1592 1557 1591 + 2465 3 3 1593 1623 1624 + 2466 3 3 1593 1592 1623 + 2467 3 3 1653 1624 1623 + 2468 3 3 1594 1559 1593 + 2469 3 3 1652 1623 1622 + 2470 3 3 1593 1558 1592 + 2471 3 3 1557 1556 1591 + 2472 3 3 1625 1593 1624 + 2473 3 3 1652 1622 1621 + 2474 3 3 1518 1478 1517 + 2475 3 3 1649 1678 1650 + 2476 3 3 1619 1618 1649 + 2477 3 3 1679 1650 1678 + 2478 3 3 1651 1620 1650 + 2479 3 3 1651 1679 1680 + 2480 3 3 1651 1650 1679 + 2481 3 3 1709 1680 1679 + 2482 3 3 1681 1651 1680 + 2483 3 3 1709 1679 1678 + 2484 3 3 1650 1619 1649 + 2485 3 3 1708 1737 1738 + 2486 3 3 1678 1677 1708 + 2487 3 3 1768 1738 1767 + 2488 3 3 1739 1708 1738 + 2489 3 3 1709 1708 1739 + 2490 3 3 1739 1738 1768 + 2491 3 3 1710 1709 1739 + 2492 3 3 1710 1680 1709 + 2493 3 3 1796 1768 1767 + 2494 3 3 1709 1678 1708 + 2495 3 3 1649 1648 1678 + 2496 3 3 1740 1739 1768 + 2497 3 3 1652 1651 1681 + 2498 3 3 1711 1680 1710 + 2499 3 3 1681 1680 1711 + 2500 3 3 1653 1652 1681 + 2501 3 3 1653 1681 1682 + 2502 3 3 1682 1681 1711 + 2503 3 3 1712 1682 1711 + 2504 3 3 1654 1624 1653 + 2505 3 3 1741 1711 1710 + 2506 3 3 1653 1623 1652 + 2507 3 3 1770 1741 1740 + 2508 3 3 1740 1768 1769 + 2509 3 3 1770 1740 1769 + 2510 3 3 1712 1711 1741 + 2511 3 3 1712 1741 1742 + 2512 3 3 1771 1742 1741 + 2513 3 3 1771 1743 1742 + 2514 3 3 1713 1682 1712 + 2515 3 3 1799 1770 1769 + 2516 3 3 1741 1710 1740 + 2517 3 3 1710 1739 1740 + 2518 3 3 1654 1653 1682 + 2519 3 3 1797 1769 1768 + 2520 3 3 1652 1621 1651 + 2521 3 3 1738 1737 1767 + 2522 3 3 1713 1712 1742 + 2523 3 3 1795 1766 1765 + 2524 3 3 1517 1476 1516 + 2525 3 3 1523 1522 1559 + 2526 3 3 1183 1124 1123 + 2527 3 3 1182 1181 1240 + 2528 3 3 1183 1123 1182 + 2529 3 3 1125 1067 1124 + 2530 3 3 1125 1124 1184 + 2531 3 3 1184 1124 1183 + 2532 3 3 1241 1184 1183 + 2533 3 3 1126 1125 1184 + 2534 3 3 1241 1183 1182 + 2535 3 3 1126 1068 1125 + 2536 3 3 1240 1294 1241 + 2537 3 3 1240 1239 1294 + 2538 3 3 1295 1241 1294 + 2539 3 3 1241 1182 1240 + 2540 3 3 1242 1295 1296 + 2541 3 3 1242 1241 1295 + 2542 3 3 1348 1297 1296 + 2543 3 3 1243 1184 1242 + 2544 3 3 1346 1295 1294 + 2545 3 3 1242 1184 1241 + 2546 3 3 1294 1293 1346 + 2547 3 3 1297 1242 1296 + 2548 3 3 1186 1127 1126 + 2549 3 3 1126 1184 1185 + 2550 3 3 1186 1126 1185 + 2551 3 3 1127 1068 1126 + 2552 3 3 1128 1127 1187 + 2553 3 3 1187 1127 1186 + 2554 3 3 1245 1187 1186 + 2555 3 3 1188 1128 1187 + 2556 3 3 1244 1186 1185 + 2557 3 3 1129 1071 1128 + 2558 3 3 1298 1244 1243 + 2559 3 3 1243 1242 1297 + 2560 3 3 1298 1243 1297 + 2561 3 3 1244 1185 1243 + 2562 3 3 1245 1298 1299 + 2563 3 3 1245 1244 1298 + 2564 3 3 1350 1299 1298 + 2565 3 3 1246 1245 1299 + 2566 3 3 1350 1298 1297 + 2567 3 3 1245 1186 1244 + 2568 3 3 1185 1184 1243 + 2569 3 3 1246 1187 1245 + 2570 3 3 1348 1296 1295 + 2571 3 3 1124 1066 1123 + 2572 3 3 1346 1394 1347 + 2573 3 3 1394 1393 1440 + 2574 3 3 1395 1347 1394 + 2575 3 3 1348 1295 1347 + 2576 3 3 1348 1347 1396 + 2577 3 3 1396 1347 1395 + 2578 3 3 1441 1396 1395 + 2579 3 3 1397 1348 1396 + 2580 3 3 1440 1395 1394 + 2581 3 3 1349 1297 1348 + 2582 3 3 1440 1483 1441 + 2583 3 3 1440 1439 1483 + 2584 3 3 1484 1441 1483 + 2585 3 3 1441 1395 1440 + 2586 3 3 1442 1484 1485 + 2587 3 3 1442 1441 1484 + 2588 3 3 1524 1485 1484 + 2589 3 3 1486 1442 1485 + 2590 3 3 1524 1484 1483 + 2591 3 3 1442 1396 1441 + 2592 3 3 1346 1345 1394 + 2593 3 3 1443 1396 1442 + 2594 3 3 1349 1397 1350 + 2595 3 3 1349 1348 1397 + 2596 3 3 1398 1350 1397 + 2597 3 3 1350 1297 1349 + 2598 3 3 1351 1398 1399 + 2599 3 3 1351 1350 1398 + 2600 3 3 1444 1399 1398 + 2601 3 3 1400 1351 1399 + 2602 3 3 1444 1398 1397 + 2603 3 3 1351 1299 1350 + 2604 3 3 1487 1444 1443 + 2605 3 3 1443 1442 1486 + 2606 3 3 1487 1443 1486 + 2607 3 3 1444 1397 1443 + 2608 3 3 1445 1487 1488 + 2609 3 3 1445 1444 1487 + 2610 3 3 1529 1489 1488 + 2611 3 3 1446 1399 1445 + 2612 3 3 1528 1488 1487 + 2613 3 3 1445 1399 1444 + 2614 3 3 1397 1396 1443 + 2615 3 3 1446 1445 1488 + 2616 3 3 1525 1486 1485 + 2617 3 3 1347 1295 1346 + 2618 3 3 1123 1122 1182 + 2619 3 3 1300 1299 1351 + 2620 3 3 1129 1188 1130 + 2621 3 3 1129 1128 1188 + 2622 3 3 1189 1130 1188 + 2623 3 3 1130 1071 1129 + 2624 3 3 1131 1189 1190 + 2625 3 3 1131 1130 1189 + 2626 3 3 1248 1190 1189 + 2627 3 3 1132 1131 1190 + 2628 3 3 1247 1189 1188 + 2629 3 3 1132 1074 1131 + 2630 3 3 1246 1300 1247 + 2631 3 3 1246 1299 1300 + 2632 3 3 1301 1247 1300 + 2633 3 3 1247 1188 1246 + 2634 3 3 1248 1247 1302 + 2635 3 3 1302 1247 1301 + 2636 3 3 1354 1302 1301 + 2637 3 3 1249 1248 1302 + 2638 3 3 1352 1301 1300 + 2639 3 3 1248 1189 1247 + 2640 3 3 1188 1187 1246 + 2641 3 3 1191 1190 1248 + 2642 3 3 1192 1133 1132 + 2643 3 3 1132 1190 1191 + 2644 3 3 1192 1134 1133 + 2645 3 3 1133 1074 1132 + 2646 3 3 1134 391 392 + 2647 3 3 1193 391 1134 + 2648 3 3 392 393 1134 + 2649 3 3 1192 1132 1191 + 2650 3 3 1134 1076 1133 + 2651 3 3 1192 1249 1250 + 2652 3 3 1192 1191 1249 + 2653 3 3 1304 389 1250 + 2654 3 3 390 1192 1250 + 2655 3 3 1193 1192 390 + 2656 3 3 390 1250 389 + 2657 3 3 390 391 1193 + 2658 3 3 1303 1250 1249 + 2659 3 3 1193 1134 1192 + 2660 3 3 1191 1248 1249 + 2661 3 3 1303 1249 1302 + 2662 3 3 1131 1072 1130 + 2663 3 3 1401 1353 1352 + 2664 3 3 1300 1351 1352 + 2665 3 3 1401 1352 1400 + 2666 3 3 1354 1301 1353 + 2667 3 3 1354 1353 1402 + 2668 3 3 1402 1353 1401 + 2669 3 3 1448 1402 1401 + 2670 3 3 1355 1354 1402 + 2671 3 3 1446 1401 1400 + 2672 3 3 1303 1302 1354 + 2673 3 3 1446 1489 1447 + 2674 3 3 1400 1399 1446 + 2675 3 3 1490 1447 1489 + 2676 3 3 1448 1401 1447 + 2677 3 3 1448 1490 1491 + 2678 3 3 1448 1447 1490 + 2679 3 3 1530 1491 1490 + 2680 3 3 1403 1402 1448 + 2681 3 3 1529 1490 1489 + 2682 3 3 1447 1401 1446 + 2683 3 3 1352 1351 1400 + 2684 3 3 1449 1448 1491 + 2685 3 3 1356 1304 1303 + 2686 3 3 1303 1354 1355 + 2687 3 3 1356 1303 1355 + 2688 3 3 1304 1250 1303 + 2689 3 3 388 1356 387 + 2690 3 3 388 1304 1356 + 2691 3 3 1404 387 1356 + 2692 3 3 1404 1356 1355 + 2693 3 3 388 389 1304 + 2694 3 3 1450 1404 1403 + 2695 3 3 1403 1448 1449 + 2696 3 3 1450 1403 1449 + 2697 3 3 1404 1355 1403 + 2698 3 3 386 1450 385 + 2699 3 3 386 1404 1450 + 2700 3 3 1493 385 1450 + 2701 3 3 1493 1450 1449 + 2702 3 3 386 387 1404 + 2703 3 3 1355 1402 1403 + 2704 3 3 1492 1449 1491 + 2705 3 3 1353 1301 1352 + 2706 3 3 1446 1488 1489 + 2707 3 3 1527 1487 1486 + 2708 3 3 1128 1070 1127 + 2709 3 3 1561 1524 1523 + 2710 3 3 1523 1559 1560 + 2711 3 3 1561 1523 1560 + 2712 3 3 1525 1485 1524 + 2713 3 3 1525 1524 1562 + 2714 3 3 1562 1524 1561 + 2715 3 3 1595 1562 1561 + 2716 3 3 1563 1525 1562 + 2717 3 3 1594 1561 1560 + 2718 3 3 1526 1486 1525 + 2719 3 3 1626 1595 1594 + 2720 3 3 1594 1593 1625 + 2721 3 3 1626 1594 1625 + 2722 3 3 1595 1561 1594 + 2723 3 3 1596 1626 1627 + 2724 3 3 1596 1595 1626 + 2725 3 3 1657 1627 1626 + 2726 3 3 1597 1562 1596 + 2727 3 3 1658 1628 1627 + 2728 3 3 1596 1562 1595 + 2729 3 3 1560 1559 1594 + 2730 3 3 1597 1596 1627 + 2731 3 3 1564 1527 1526 + 2732 3 3 1526 1525 1563 + 2733 3 3 1564 1526 1563 + 2734 3 3 1527 1486 1526 + 2735 3 3 1528 1564 1565 + 2736 3 3 1528 1527 1564 + 2737 3 3 1599 1565 1564 + 2738 3 3 1529 1528 1565 + 2739 3 3 1598 1564 1563 + 2740 3 3 1529 1488 1528 + 2741 3 3 1597 1628 1598 + 2742 3 3 1597 1627 1628 + 2743 3 3 1629 1598 1628 + 2744 3 3 1599 1564 1598 + 2745 3 3 1599 1629 1630 + 2746 3 3 1599 1598 1629 + 2747 3 3 1659 1630 1629 + 2748 3 3 1600 1565 1599 + 2749 3 3 1658 1629 1628 + 2750 3 3 1598 1563 1597 + 2751 3 3 1563 1562 1597 + 2752 3 3 1600 1599 1630 + 2753 3 3 1656 1626 1625 + 2754 3 3 1528 1487 1527 + 2755 3 3 1684 1655 1654 + 2756 3 3 1654 1682 1683 + 2757 3 3 1684 1654 1683 + 2758 3 3 1656 1625 1655 + 2759 3 3 1656 1655 1685 + 2760 3 3 1685 1655 1684 + 2761 3 3 1714 1685 1684 + 2762 3 3 1686 1656 1685 + 2763 3 3 1714 1684 1683 + 2764 3 3 1657 1626 1656 + 2765 3 3 1744 1714 1713 + 2766 3 3 1713 1742 1743 + 2767 3 3 1744 1713 1743 + 2768 3 3 1715 1685 1714 + 2769 3 3 1715 1714 1745 + 2770 3 3 1745 1714 1744 + 2771 3 3 1773 1745 1744 + 2772 3 3 1716 1685 1715 + 2773 3 3 1774 1746 1745 + 2774 3 3 1714 1683 1713 + 2775 3 3 1683 1682 1713 + 2776 3 3 1716 1715 1745 + 2777 3 3 1657 1686 1658 + 2778 3 3 1657 1656 1686 + 2779 3 3 1687 1658 1686 + 2780 3 3 1658 1627 1657 + 2781 3 3 1659 1687 1688 + 2782 3 3 1659 1658 1687 + 2783 3 3 1718 1688 1687 + 2784 3 3 1660 1659 1688 + 2785 3 3 1717 1687 1686 + 2786 3 3 1659 1629 1658 + 2787 3 3 1716 1746 1717 + 2788 3 3 1716 1745 1746 + 2789 3 3 1747 1717 1746 + 2790 3 3 1717 1686 1716 + 2791 3 3 1718 1747 1748 + 2792 3 3 1718 1717 1747 + 2793 3 3 1776 1748 1747 + 2794 3 3 1689 1688 1718 + 2795 3 3 1776 1747 1746 + 2796 3 3 1718 1687 1717 + 2797 3 3 1686 1685 1716 + 2798 3 3 1660 1630 1659 + 2799 3 3 1773 1744 1743 + 2800 3 3 1655 1625 1654 + 2801 3 3 1483 1482 1523 + 2802 3 3 1749 1718 1748 + 2803 3 3 1567 1530 1529 + 2804 3 3 1566 1565 1600 + 2805 3 3 1567 1529 1566 + 2806 3 3 1531 1491 1530 + 2807 3 3 1531 1530 1568 + 2808 3 3 1568 1530 1567 + 2809 3 3 1602 1568 1567 + 2810 3 3 1569 1531 1568 + 2811 3 3 1600 1567 1566 + 2812 3 3 1492 1491 1531 + 2813 3 3 1600 1631 1601 + 2814 3 3 1600 1630 1631 + 2815 3 3 1632 1601 1631 + 2816 3 3 1602 1567 1601 + 2817 3 3 1602 1601 1633 + 2818 3 3 1633 1601 1632 + 2819 3 3 1663 1634 1633 + 2820 3 3 1634 1602 1633 + 2821 3 3 1663 1633 1632 + 2822 3 3 1601 1567 1600 + 2823 3 3 1529 1565 1566 + 2824 3 3 1569 1568 1602 + 2825 3 3 384 1492 1532 + 2826 3 3 1492 1531 1532 + 2827 3 3 1569 383 1532 + 2828 3 3 1533 1532 383 + 2829 3 3 1493 1492 384 + 2830 3 3 384 1532 1533 + 2831 3 3 1533 383 384 + 2832 3 3 384 385 1493 + 2833 3 3 1493 1449 1492 + 2834 3 3 1532 1531 1569 + 2835 3 3 1569 1602 1603 + 2836 3 3 381 1603 1634 + 2837 3 3 382 1569 1603 + 2838 3 3 382 1603 381 + 2839 3 3 381 1634 380 + 2840 3 3 1664 380 1634 + 2841 3 3 382 383 1569 + 2842 3 3 1603 1602 1634 + 2843 3 3 1661 1632 1631 + 2844 3 3 1530 1490 1529 + 2845 3 3 1690 1661 1660 + 2846 3 3 1660 1688 1689 + 2847 3 3 1690 1660 1689 + 2848 3 3 1662 1632 1661 + 2849 3 3 1662 1661 1691 + 2850 3 3 1691 1661 1690 + 2851 3 3 1721 1691 1690 + 2852 3 3 1663 1662 1691 + 2853 3 3 1719 1690 1689 + 2854 3 3 1663 1632 1662 + 2855 3 3 1719 1749 1720 + 2856 3 3 1689 1718 1719 + 2857 3 3 1750 1720 1749 + 2858 3 3 1720 1690 1719 + 2859 3 3 1721 1750 1751 + 2860 3 3 1721 1720 1750 + 2861 3 3 1781 1752 1751 + 2862 3 3 1722 1691 1721 + 2863 3 3 1780 1751 1750 + 2864 3 3 1721 1690 1720 + 2865 3 3 1719 1718 1749 + 2866 3 3 1752 1721 1751 + 2867 3 3 1663 1692 1664 + 2868 3 3 1663 1691 1692 + 2869 3 3 1693 1664 1692 + 2870 3 3 1664 1634 1663 + 2871 3 3 379 1693 378 + 2872 3 3 379 1664 1693 + 2873 3 3 1723 378 1693 + 2874 3 3 1722 1693 1692 + 2875 3 3 379 380 1664 + 2876 3 3 377 1722 1752 + 2877 3 3 1692 1691 1722 + 2878 3 3 1781 376 1752 + 2879 3 3 1753 1752 376 + 2880 3 3 1723 1722 377 + 2881 3 3 377 1752 1753 + 2882 3 3 1753 376 377 + 2883 3 3 377 378 1723 + 2884 3 3 1723 1693 1722 + 2885 3 3 1722 1721 1752 + 2886 3 3 1778 1750 1749 + 2887 3 3 1661 1631 1660 + 2888 3 3 1631 1630 1660 + 2889 3 3 1778 1749 1748 + 2890 3 3 1524 1483 1523 + 2891 3 3 1625 1624 1654 + 2892 3 3 1771 1741 1770 + 2893 3 3 1118 1059 1117 + 2894 3 3 1110 1109 1169 + 2895 3 3 1787 1760 1759 + 2896 3 3 1782 86 87 + 2897 3 3 1782 87 1811 + 2898 3 3 1811 87 88 + 2899 3 3 1812 1811 88 + 2900 3 3 1812 1782 1811 + 2901 3 3 1783 1754 1782 + 2902 3 3 250 251 249 + 2903 3 3 248 249 251 + 2904 3 3 1840 88 89 + 2905 3 3 252 248 251 + 2906 3 3 1869 89 90 + 2907 3 3 1813 1783 1812 + 2908 3 3 1783 1782 1812 + 2909 3 3 1812 88 1840 + 2910 3 3 1841 1812 1840 + 2911 3 3 1784 1783 1813 + 2912 3 3 1813 1812 1841 + 2913 3 3 1842 1813 1841 + 2914 3 3 1785 1784 1813 + 2915 3 3 1869 1841 1840 + 2916 3 3 1784 1755 1783 + 2917 3 3 1869 90 1899 + 2918 3 3 1840 89 1869 + 2919 3 3 1900 1899 91 + 2920 3 3 1870 1869 1899 + 2921 3 3 1929 92 93 + 2922 3 3 1900 91 92 + 2923 3 3 1870 1841 1869 + 2924 3 3 1899 90 91 + 2925 3 3 1957 93 94 + 2926 3 3 1785 1756 1784 + 2927 3 3 2142 253 254 + 2928 3 3 2120 252 253 + 2929 3 3 247 2120 253 + 2930 3 3 246 2142 254 + 2931 3 3 246 254 2163 + 2932 3 3 247 253 2142 + 2933 3 3 255 2163 254 + 2934 3 3 2120 248 252 + 2935 3 3 2204 256 257 + 2936 3 3 2224 257 258 + 2937 3 3 255 256 2184 + 2938 3 3 2204 2184 256 + 2939 3 3 2184 2163 255 + 2940 3 3 2245 258 259 + 2941 3 3 245 2163 2184 + 2942 3 3 247 2142 246 + 2943 3 3 244 2184 2204 + 2944 3 3 246 2163 245 + 2945 3 3 245 2184 244 + 2946 3 3 244 2204 243 + 2947 3 3 2224 243 2204 + 2948 3 3 2224 2245 2225 + 2949 3 3 2224 258 2245 + 2950 3 3 2246 2225 2245 + 2951 3 3 2225 243 2224 + 2952 3 3 242 2246 241 + 2953 3 3 242 2225 2246 + 2954 3 3 2267 2246 2245 + 2955 3 3 2267 241 2246 + 2956 3 3 242 243 2225 + 2957 3 3 2204 257 2224 + 2958 3 3 2266 2245 259 + 2959 3 3 247 248 2120 + 2960 3 3 1785 1813 1814 + 2961 3 3 1871 1841 1870 + 2962 3 3 1814 1813 1842 + 2963 3 3 1786 1785 1814 + 2964 3 3 1815 1814 1842 + 2965 3 3 1815 1786 1814 + 2966 3 3 1842 1841 1871 + 2967 3 3 1843 1842 1871 + 2968 3 3 1901 1871 1870 + 2969 3 3 1786 1757 1785 + 2970 3 3 1901 1900 1929 + 2971 3 3 1870 1899 1900 + 2972 3 3 1929 93 1957 + 2973 3 3 1930 1929 1957 + 2974 3 3 1901 1929 1930 + 2975 3 3 1930 1957 1958 + 2976 3 3 1902 1901 1930 + 2977 3 3 1872 1871 1901 + 2978 3 3 1986 1958 1957 + 2979 3 3 1901 1870 1900 + 2980 3 3 1900 92 1929 + 2981 3 3 1959 1930 1958 + 2982 3 3 1815 1842 1843 + 2983 3 3 1843 1871 1872 + 2984 3 3 1873 1844 1843 + 2985 3 3 1844 1815 1843 + 2986 3 3 1817 1787 1816 + 2987 3 3 1787 1786 1816 + 2988 3 3 1816 1815 1844 + 2989 3 3 1817 1816 1844 + 2990 3 3 1873 1843 1872 + 2991 3 3 1816 1786 1815 + 2992 3 3 1902 1930 1931 + 2993 3 3 1931 1930 1959 + 2994 3 3 1932 1931 1959 + 2995 3 3 1932 1902 1931 + 2996 3 3 1873 1872 1903 + 2997 3 3 1903 1902 1932 + 2998 3 3 1933 1903 1932 + 2999 3 3 1874 1844 1873 + 3000 3 3 1960 1932 1959 + 3001 3 3 1903 1872 1902 + 3002 3 3 1872 1901 1902 + 3003 3 3 1874 1873 1903 + 3004 3 3 1987 1959 1958 + 3005 3 3 1787 1759 1786 + 3006 3 3 1987 1986 95 + 3007 3 3 1986 94 95 + 3008 3 3 2015 95 96 + 3009 3 3 2016 1988 1987 + 3010 3 3 1987 95 2015 + 3011 3 3 2016 1987 2015 + 3012 3 3 1960 1959 1988 + 3013 3 3 2044 2015 96 + 3014 3 3 1988 1959 1987 + 3015 3 3 2044 97 2071 + 3016 3 3 2044 96 97 + 3017 3 3 98 2071 97 + 3018 3 3 2045 2044 2071 + 3019 3 3 2097 98 99 + 3020 3 3 2072 2071 98 + 3021 3 3 2045 2015 2044 + 3022 3 3 2121 99 100 + 3023 3 3 1960 1988 1989 + 3024 3 3 1989 1988 2016 + 3025 3 3 2016 2015 2045 + 3026 3 3 2017 2016 2045 + 3027 3 3 2018 1989 2017 + 3028 3 3 1989 2016 2017 + 3029 3 3 2017 2045 2046 + 3030 3 3 2018 2017 2046 + 3031 3 3 2073 2046 2045 + 3032 3 3 1961 1932 1960 + 3033 3 3 2098 2072 2097 + 3034 3 3 2045 2071 2072 + 3035 3 3 2097 99 2121 + 3036 3 3 101 2097 2121 + 3037 3 3 2073 2072 2098 + 3038 3 3 2098 2097 101 + 3039 3 3 102 2098 101 + 3040 3 3 2047 2046 2073 + 3041 3 3 2121 100 101 + 3042 3 3 2073 2045 2072 + 3043 3 3 2072 98 2097 + 3044 3 3 2074 2073 2098 + 3045 3 3 1987 1958 1986 + 3046 3 3 1957 94 1986 + 3047 3 3 1961 1960 1989 + 3048 3 3 1788 1760 1787 + 3049 3 3 2288 260 261 + 3050 3 3 262 2309 261 + 3051 3 3 2310 261 2309 + 3052 3 3 2266 260 2288 + 3053 3 3 2288 261 2310 + 3054 3 3 2289 2288 2310 + 3055 3 3 2267 2266 2288 + 3056 3 3 262 2310 2309 + 3057 3 3 2266 259 260 + 3058 3 3 2354 263 264 + 3059 3 3 2331 262 263 + 3060 3 3 2355 263 2354 + 3061 3 3 2332 2331 263 + 3062 3 3 2355 2354 264 + 3063 3 3 2332 262 2331 + 3064 3 3 265 2377 264 + 3065 3 3 2332 2310 262 + 3066 3 3 2378 2355 264 + 3067 3 3 2289 2310 2311 + 3068 3 3 2267 2288 2289 + 3069 3 3 238 2289 2311 + 3070 3 3 240 2267 2289 + 3071 3 3 240 2289 239 + 3072 3 3 239 2289 238 + 3073 3 3 237 238 2311 + 3074 3 3 240 241 2267 + 3075 3 3 2356 2333 2332 + 3076 3 3 2332 263 2355 + 3077 3 3 2356 2332 2355 + 3078 3 3 2333 2311 2332 + 3079 3 3 2334 2333 2357 + 3080 3 3 2357 2333 2356 + 3081 3 3 2379 2357 2356 + 3082 3 3 236 2334 2357 + 3083 3 3 2379 2356 2355 + 3084 3 3 237 2311 2333 + 3085 3 3 2311 2310 2332 + 3086 3 3 237 2333 2334 + 3087 3 3 2378 264 2377 + 3088 3 3 2267 2245 2266 + 3089 3 3 265 266 2400 + 3090 3 3 2422 2400 266 + 3091 3 3 2378 2377 2400 + 3092 3 3 2378 2400 2401 + 3093 3 3 2401 2400 2422 + 3094 3 3 2423 2401 2422 + 3095 3 3 2402 2378 2401 + 3096 3 3 267 2422 266 + 3097 3 3 2400 2377 265 + 3098 3 3 2500 268 269 + 3099 3 3 2450 267 268 + 3100 3 3 2450 268 2500 + 3101 3 3 2500 269 2557 + 3102 3 3 2451 2450 2500 + 3103 3 3 2451 2422 2450 + 3104 3 3 270 2557 269 + 3105 3 3 2450 2422 267 + 3106 3 3 2501 2500 2557 + 3107 3 3 2379 2378 2402 + 3108 3 3 2424 2401 2423 + 3109 3 3 2402 2401 2424 + 3110 3 3 2380 2379 2402 + 3111 3 3 2380 2402 2403 + 3112 3 3 2425 2403 2402 + 3113 3 3 2425 2402 2424 + 3114 3 3 235 2357 2380 + 3115 3 3 2452 2424 2423 + 3116 3 3 2380 2357 2379 + 3117 3 3 2451 2500 2501 + 3118 3 3 2501 2557 2558 + 3119 3 3 2502 2501 2558 + 3120 3 3 2452 2451 2501 + 3121 3 3 2503 2452 2502 + 3122 3 3 2452 2501 2502 + 3123 3 3 2502 2558 2559 + 3124 3 3 2425 2424 2452 + 3125 3 3 2616 2559 2558 + 3126 3 3 2452 2423 2451 + 3127 3 3 2423 2422 2451 + 3128 3 3 2560 2502 2559 + 3129 3 3 2614 2558 2557 + 3130 3 3 2379 2355 2378 + 3131 3 3 234 2380 2403 + 3132 3 3 237 2334 236 + 3133 3 3 233 2403 2425 + 3134 3 3 236 2357 235 + 3135 3 3 235 2380 234 + 3136 3 3 234 2403 233 + 3137 3 3 232 233 2425 + 3138 3 3 232 2453 2454 + 3139 3 3 232 2425 2453 + 3140 3 3 231 2454 2453 + 3141 3 3 231 232 2454 + 3142 3 3 2507 228 229 + 3143 3 3 2506 229 230 + 3144 3 3 2503 231 2453 + 3145 3 3 2425 2452 2453 + 3146 3 3 222 223 2455 + 3147 3 3 2512 2455 223 + 3148 3 3 2456 222 2455 + 3149 3 3 2457 220 221 + 3150 3 3 221 222 2456 + 3151 3 3 2457 221 2456 + 3152 3 3 2513 2456 2455 + 3153 3 3 2513 2457 2456 + 3154 3 3 2509 226 227 + 3155 3 3 2511 224 225 + 3156 3 3 2511 223 224 + 3157 3 3 2510 225 226 + 3158 3 3 2508 227 228 + 3159 3 3 2458 220 2457 + 3160 3 3 2505 230 231 + 3161 3 3 2561 2505 2504 + 3162 3 3 2561 2504 2503 + 3163 3 3 2506 230 2505 + 3164 3 3 2504 231 2503 + 3165 3 3 2565 2508 2507 + 3166 3 3 2563 2507 2506 + 3167 3 3 2509 227 2508 + 3168 3 3 2507 229 2506 + 3169 3 3 2563 2506 2505 + 3170 3 3 2505 231 2504 + 3171 3 3 2619 2562 2561 + 3172 3 3 2620 2563 2562 + 3173 3 3 2563 2505 2562 + 3174 3 3 2562 2505 2561 + 3175 3 3 2565 2507 2564 + 3176 3 3 2620 2564 2563 + 3177 3 3 2623 2566 2565 + 3178 3 3 2564 2507 2563 + 3179 3 3 2618 2561 2560 + 3180 3 3 2561 2503 2560 + 3181 3 3 2453 2452 2503 + 3182 3 3 2566 2508 2565 + 3183 3 3 2568 2511 2510 + 3184 3 3 2566 2510 2509 + 3185 3 3 2512 223 2511 + 3186 3 3 2511 225 2510 + 3187 3 3 2569 2513 2512 + 3188 3 3 2571 2514 2513 + 3189 3 3 2514 2457 2513 + 3190 3 3 2513 2455 2512 + 3191 3 3 2569 2512 2511 + 3192 3 3 2510 226 2509 + 3193 3 3 2568 2510 2567 + 3194 3 3 2623 2567 2566 + 3195 3 3 2625 2569 2568 + 3196 3 3 2569 2511 2568 + 3197 3 3 2571 2513 2570 + 3198 3 3 2626 2570 2569 + 3199 3 3 2628 2572 2571 + 3200 3 3 2570 2513 2569 + 3201 3 3 2628 2571 2570 + 3202 3 3 2567 2510 2566 + 3203 3 3 2509 2508 2566 + 3204 3 3 2458 2457 2514 + 3205 3 3 2621 2565 2564 + 3206 3 3 2508 228 2507 + 3207 3 3 2503 2502 2560 + 3208 3 3 2572 2514 2571 + 3209 3 3 2616 2560 2559 + 3210 3 3 1789 1788 1817 + 3211 3 3 1817 1844 1845 + 3212 3 3 1789 1817 1818 + 3213 3 3 1818 1817 1845 + 3214 3 3 1846 1818 1845 + 3215 3 3 1819 1789 1818 + 3216 3 3 1845 1844 1874 + 3217 3 3 119 1761 1789 + 3218 3 3 1904 1903 1933 + 3219 3 3 1874 1903 1904 + 3220 3 3 1905 1904 1933 + 3221 3 3 1875 1874 1904 + 3222 3 3 1847 1846 1875 + 3223 3 3 1846 1845 1875 + 3224 3 3 1875 1904 1905 + 3225 3 3 1847 1818 1846 + 3226 3 3 1934 1905 1933 + 3227 3 3 1875 1845 1874 + 3228 3 3 1788 1787 1817 + 3229 3 3 1876 1875 1905 + 3230 3 3 1790 1789 1819 + 3231 3 3 119 1789 1790 + 3232 3 3 118 1790 1819 + 3233 3 3 118 119 1790 + 3234 3 3 118 1819 117 + 3235 3 3 1847 116 117 + 3236 3 3 1847 117 1819 + 3237 3 3 1847 1875 1876 + 3238 3 3 1819 1818 1847 + 3239 3 3 1876 1905 1906 + 3240 3 3 1877 1847 1876 + 3241 3 3 1877 1876 1907 + 3242 3 3 1907 1876 1906 + 3243 3 3 1935 1907 1906 + 3244 3 3 114 1877 1907 + 3245 3 3 1935 1906 1934 + 3246 3 3 1877 116 1847 + 3247 3 3 1906 1905 1934 + 3248 3 3 115 116 1877 + 3249 3 3 1961 1934 1933 + 3250 3 3 1789 1761 1788 + 3251 3 3 1990 1989 2018 + 3252 3 3 1961 1989 1990 + 3253 3 3 2019 1990 2018 + 3254 3 3 1962 1961 1990 + 3255 3 3 1992 1962 1991 + 3256 3 3 1962 1990 1991 + 3257 3 3 1991 1990 2019 + 3258 3 3 2020 1991 2019 + 3259 3 3 2048 2019 2018 + 3260 3 3 1963 1934 1962 + 3261 3 3 2047 2073 2074 + 3262 3 3 2018 2046 2047 + 3263 3 3 2074 2098 2099 + 3264 3 3 2048 2047 2074 + 3265 3 3 2075 2048 2074 + 3266 3 3 103 2074 2099 + 3267 3 3 2099 102 103 + 3268 3 3 104 2074 103 + 3269 3 3 2048 2018 2047 + 3270 3 3 1933 1932 1961 + 3271 3 3 2049 2019 2048 + 3272 3 3 1963 1962 1992 + 3273 3 3 1935 1934 1963 + 3274 3 3 1993 1964 1963 + 3275 3 3 1964 1935 1963 + 3276 3 3 1936 1935 1964 + 3277 3 3 1993 1963 1992 + 3278 3 3 2021 1992 2020 + 3279 3 3 113 1907 1936 + 3280 3 3 1992 1991 2020 + 3281 3 3 1936 1907 1935 + 3282 3 3 2075 104 105 + 3283 3 3 2075 2074 104 + 3284 3 3 2076 2075 105 + 3285 3 3 2049 2076 106 + 3286 3 3 2049 2075 2076 + 3287 3 3 2076 105 106 + 3288 3 3 2050 2020 2049 + 3289 3 3 2020 2019 2049 + 3290 3 3 2049 2048 2075 + 3291 3 3 2050 2049 106 + 3292 3 3 1962 1934 1961 + 3293 3 3 2099 2098 102 + 3294 3 3 112 1936 1964 + 3295 3 3 115 1877 114 + 3296 3 3 1994 1964 1993 + 3297 3 3 114 1907 113 + 3298 3 3 113 1936 112 + 3299 3 3 112 1964 1965 + 3300 3 3 111 112 1965 + 3301 3 3 1965 1964 1994 + 3302 3 3 2022 2021 2050 + 3303 3 3 1993 1992 2021 + 3304 3 3 2050 106 107 + 3305 3 3 2022 2050 107 + 3306 3 3 110 1994 2022 + 3307 3 3 1994 2021 2022 + 3308 3 3 2022 107 108 + 3309 3 3 111 1965 1994 + 3310 3 3 1994 1993 2021 + 3311 3 3 2021 2020 2050 + 3312 3 3 2023 2022 108 + 3313 3 3 111 1994 110 + 3314 3 3 110 2022 2023 + 3315 3 3 109 110 2023 + 3316 3 3 2078 2077 180 + 3317 3 3 2023 108 109 + 3318 3 3 2143 182 183 + 3319 3 3 2122 181 182 + 3320 3 3 2100 181 2122 + 3321 3 3 2122 182 2143 + 3322 3 3 2123 2122 2143 + 3323 3 3 2101 180 2100 + 3324 3 3 2164 2143 183 + 3325 3 3 2100 180 181 + 3326 3 3 2101 2100 2122 + 3327 3 3 2290 190 191 + 3328 3 3 2268 189 190 + 3329 3 3 2268 190 2290 + 3330 3 3 2290 191 2312 + 3331 3 3 2291 2269 2290 + 3332 3 3 2269 2268 2290 + 3333 3 3 192 2312 191 + 3334 3 3 188 189 2268 + 3335 3 3 2358 193 194 + 3336 3 3 2381 2358 194 + 3337 3 3 192 193 2335 + 3338 3 3 2335 193 2358 + 3339 3 3 2313 2312 2335 + 3340 3 3 2335 2312 192 + 3341 3 3 2381 194 195 + 3342 3 3 2291 2290 2312 + 3343 3 3 2185 184 185 + 3344 3 3 2205 185 186 + 3345 3 3 2186 2164 2185 + 3346 3 3 2164 184 2185 + 3347 3 3 2185 185 2205 + 3348 3 3 2206 2185 2205 + 3349 3 3 2226 2205 186 + 3350 3 3 2164 183 184 + 3351 3 3 2247 187 188 + 3352 3 3 2336 2335 2358 + 3353 3 3 2247 2268 2269 + 3354 3 3 2248 2226 2247 + 3355 3 3 2226 187 2247 + 3356 3 3 188 2268 2247 + 3357 3 3 2270 2247 2269 + 3358 3 3 2359 2358 2381 + 3359 3 3 2226 186 187 + 3360 3 3 2144 2143 2164 + 3361 3 3 2404 2381 195 + 3362 3 3 2206 2205 2226 + 3363 3 3 179 180 2077 + 3364 3 3 2460 217 218 + 3365 3 3 2461 216 217 + 3366 3 3 2462 215 216 + 3367 3 3 2463 214 215 + 3368 3 3 2459 218 219 + 3369 3 3 2460 218 2459 + 3370 3 3 2516 2460 2459 + 3371 3 3 2518 2461 2460 + 3372 3 3 2461 217 2460 + 3373 3 3 2463 215 2462 + 3374 3 3 2518 2462 2461 + 3375 3 3 2520 2464 2463 + 3376 3 3 2462 216 2461 + 3377 3 3 2520 2463 2462 + 3378 3 3 2459 219 2458 + 3379 3 3 2464 214 2463 + 3380 3 3 2465 212 213 + 3381 3 3 2467 210 211 + 3382 3 3 2469 208 209 + 3383 3 3 2468 209 210 + 3384 3 3 2466 211 212 + 3385 3 3 2523 2466 2465 + 3386 3 3 2523 2467 2466 + 3387 3 3 2467 211 2466 + 3388 3 3 2465 213 2464 + 3389 3 3 2469 209 2468 + 3390 3 3 2524 2468 2467 + 3391 3 3 2526 2469 2468 + 3392 3 3 2468 210 2467 + 3393 3 3 2522 2465 2464 + 3394 3 3 2466 212 2465 + 3395 3 3 213 214 2464 + 3396 3 3 2470 208 2469 + 3397 3 3 2516 2459 2458 + 3398 3 3 2574 2517 2516 + 3399 3 3 2572 2516 2515 + 3400 3 3 2518 2460 2517 + 3401 3 3 2516 2458 2515 + 3402 3 3 2520 2462 2519 + 3403 3 3 2575 2519 2518 + 3404 3 3 2576 2520 2519 + 3405 3 3 2519 2462 2518 + 3406 3 3 2574 2518 2517 + 3407 3 3 2521 2464 2520 + 3408 3 3 2574 2516 2573 + 3409 3 3 2631 2574 2573 + 3410 3 3 2631 2575 2574 + 3411 3 3 2573 2516 2572 + 3412 3 3 2634 2577 2576 + 3413 3 3 2633 2576 2575 + 3414 3 3 2577 2520 2576 + 3415 3 3 2576 2519 2575 + 3416 3 3 2629 2573 2572 + 3417 3 3 2575 2518 2574 + 3418 3 3 2515 2514 2572 + 3419 3 3 2521 2520 2577 + 3420 3 3 2523 2465 2522 + 3421 3 3 2578 2522 2521 + 3422 3 3 2581 2524 2523 + 3423 3 3 2522 2464 2521 + 3424 3 3 2583 2526 2525 + 3425 3 3 2582 2525 2524 + 3426 3 3 2526 2468 2525 + 3427 3 3 2525 2468 2524 + 3428 3 3 2579 2523 2522 + 3429 3 3 2524 2467 2523 + 3430 3 3 2636 2580 2579 + 3431 3 3 2636 2579 2578 + 3432 3 3 2581 2523 2580 + 3433 3 3 2579 2522 2578 + 3434 3 3 2639 2583 2582 + 3435 3 3 2640 2584 2583 + 3436 3 3 2583 2525 2582 + 3437 3 3 2582 2524 2581 + 3438 3 3 2638 2582 2581 + 3439 3 3 2580 2523 2579 + 3440 3 3 2521 2577 2578 + 3441 3 3 2527 2469 2526 + 3442 3 3 2634 2578 2577 + 3443 3 3 2517 2460 2516 + 3444 3 3 2458 2514 2515 + 3445 3 3 2584 2526 2583 + 3446 3 3 2475 202 203 + 3447 3 3 2474 203 204 + 3448 3 3 201 202 2426 + 3449 3 3 2476 2426 202 + 3450 3 3 2477 2427 201 + 3451 3 3 2473 204 205 + 3452 3 3 207 2470 2471 + 3453 3 3 207 208 2470 + 3454 3 3 2528 2472 2471 + 3455 3 3 206 207 2471 + 3456 3 3 2473 205 2472 + 3457 3 3 206 2471 2472 + 3458 3 3 2529 2473 2472 + 3459 3 3 2472 205 206 + 3460 3 3 2528 2471 2470 + 3461 3 3 2476 201 2426 + 3462 3 3 2429 198 199 + 3463 3 3 2428 199 200 + 3464 3 3 2404 195 196 + 3465 3 3 2431 196 197 + 3466 3 3 2432 2404 196 + 3467 3 3 2430 197 198 + 3468 3 3 2429 199 2428 + 3469 3 3 2477 200 2427 + 3470 3 3 2479 2429 2428 + 3471 3 3 2478 2428 200 + 3472 3 3 2432 196 2431 + 3473 3 3 2479 2430 2429 + 3474 3 3 2480 2431 2430 + 3475 3 3 2431 197 2430 + 3476 3 3 2481 2432 2431 + 3477 3 3 2430 198 2429 + 3478 3 3 200 201 2427 + 3479 3 3 2433 2404 2432 + 3480 3 3 2474 204 2473 + 3481 3 3 2585 2529 2528 + 3482 3 3 2584 2528 2527 + 3483 3 3 2530 2473 2529 + 3484 3 3 2529 2472 2528 + 3485 3 3 2532 2475 2474 + 3486 3 3 2532 2476 2475 + 3487 3 3 2477 201 2476 + 3488 3 3 2475 203 2474 + 3489 3 3 2531 2473 2530 + 3490 3 3 2528 2470 2527 + 3491 3 3 2587 2530 2529 + 3492 3 3 2585 2528 2584 + 3493 3 3 2642 2585 2584 + 3494 3 3 2587 2531 2530 + 3495 3 3 2589 2532 2531 + 3496 3 3 2589 2533 2532 + 3497 3 3 2533 2476 2532 + 3498 3 3 2532 2474 2531 + 3499 3 3 2590 2534 2533 + 3500 3 3 2474 2473 2531 + 3501 3 3 2527 2526 2584 + 3502 3 3 2534 2476 2533 + 3503 3 3 2479 2428 2478 + 3504 3 3 2534 2478 2477 + 3505 3 3 2536 2480 2479 + 3506 3 3 2478 200 2477 + 3507 3 3 2482 2432 2481 + 3508 3 3 2537 2481 2480 + 3509 3 3 2538 2482 2481 + 3510 3 3 2481 2431 2480 + 3511 3 3 2535 2479 2478 + 3512 3 3 2480 2430 2479 + 3513 3 3 2593 2536 2535 + 3514 3 3 2592 2535 2534 + 3515 3 3 2537 2480 2536 + 3516 3 3 2536 2479 2535 + 3517 3 3 2595 2538 2537 + 3518 3 3 2595 2539 2538 + 3519 3 3 2539 2482 2538 + 3520 3 3 2538 2481 2537 + 3521 3 3 2593 2537 2536 + 3522 3 3 2535 2478 2534 + 3523 3 3 2477 2476 2534 + 3524 3 3 2433 2432 2482 + 3525 3 3 2586 2529 2585 + 3526 3 3 2476 202 2475 + 3527 3 3 2470 2469 2527 + 3528 3 3 2405 2381 2404 + 3529 3 3 2638 2581 2580 + 3530 3 3 219 220 2458 + 3531 3 3 2483 2482 2539 + 3532 3 3 2625 2568 2567 + 3533 3 3 1782 1754 86 + 3534 3 3 2614 270 271 + 3535 3 3 2616 2558 2615 + 3536 3 3 2671 2615 2614 + 3537 3 3 2671 2616 2615 + 3538 3 3 2615 2558 2614 + 3539 3 3 2670 2614 271 + 3540 3 3 2617 2560 2616 + 3541 3 3 2670 272 2726 + 3542 3 3 2670 271 272 + 3543 3 3 273 2726 272 + 3544 3 3 2727 2670 2726 + 3545 3 3 2671 2727 2672 + 3546 3 3 2671 2670 2727 + 3547 3 3 2729 2673 2672 + 3548 3 3 2672 2616 2671 + 3549 3 3 2782 2727 2726 + 3550 3 3 2671 2614 2670 + 3551 3 3 2617 2616 2672 + 3552 3 3 2675 2619 2618 + 3553 3 3 2676 2620 2619 + 3554 3 3 2620 2562 2619 + 3555 3 3 2618 2560 2617 + 3556 3 3 2677 2622 2621 + 3557 3 3 2676 2621 2620 + 3558 3 3 2622 2565 2621 + 3559 3 3 2621 2564 2620 + 3560 3 3 2674 2618 2617 + 3561 3 3 2619 2561 2618 + 3562 3 3 2675 2618 2674 + 3563 3 3 2729 2674 2673 + 3564 3 3 2730 2675 2674 + 3565 3 3 2676 2619 2675 + 3566 3 3 2678 2622 2677 + 3567 3 3 2732 2676 2675 + 3568 3 3 2734 2678 2677 + 3569 3 3 2677 2621 2676 + 3570 3 3 2732 2677 2676 + 3571 3 3 2674 2617 2673 + 3572 3 3 2617 2672 2673 + 3573 3 3 2623 2622 2678 + 3574 3 3 2728 2672 2727 + 3575 3 3 2623 2565 2622 + 3576 3 3 2783 2727 2782 + 3577 3 3 274 2782 273 + 3578 3 3 2839 2783 2782 + 3579 3 3 2728 2727 2783 + 3580 3 3 2785 2729 2728 + 3581 3 3 2728 2783 2784 + 3582 3 3 2785 2728 2784 + 3583 3 3 2729 2672 2728 + 3584 3 3 2840 2784 2783 + 3585 3 3 2782 2726 273 + 3586 3 3 2839 2782 2838 + 3587 3 3 275 2838 274 + 3588 3 3 2896 2840 2839 + 3589 3 3 2840 2783 2839 + 3590 3 3 2785 2840 2841 + 3591 3 3 2785 2784 2840 + 3592 3 3 2897 2841 2840 + 3593 3 3 2786 2729 2785 + 3594 3 3 2895 2839 2838 + 3595 3 3 2838 2782 274 + 3596 3 3 2786 2785 2841 + 3597 3 3 2730 2786 2731 + 3598 3 3 2730 2729 2786 + 3599 3 3 2787 2731 2786 + 3600 3 3 2732 2675 2731 + 3601 3 3 2788 2733 2732 + 3602 3 3 2788 2732 2731 + 3603 3 3 2788 2731 2787 + 3604 3 3 2733 2677 2732 + 3605 3 3 2843 2787 2786 + 3606 3 3 2731 2675 2730 + 3607 3 3 2844 2787 2843 + 3608 3 3 2843 2786 2842 + 3609 3 3 2899 2844 2843 + 3610 3 3 2788 2787 2844 + 3611 3 3 2789 2788 2845 + 3612 3 3 2845 2788 2844 + 3613 3 3 2900 2845 2844 + 3614 3 3 2734 2733 2789 + 3615 3 3 2899 2843 2842 + 3616 3 3 2789 2733 2788 + 3617 3 3 2786 2841 2842 + 3618 3 3 2734 2677 2733 + 3619 3 3 2902 2846 2845 + 3620 3 3 2730 2674 2729 + 3621 3 3 2790 2789 2845 + 3622 3 3 2623 2679 2624 + 3623 3 3 2623 2678 2679 + 3624 3 3 2681 2625 2624 + 3625 3 3 2625 2567 2624 + 3626 3 3 2682 2626 2625 + 3627 3 3 2682 2627 2626 + 3628 3 3 2628 2570 2627 + 3629 3 3 2626 2569 2625 + 3630 3 3 2680 2624 2679 + 3631 3 3 2624 2567 2623 + 3632 3 3 2736 2680 2679 + 3633 3 3 2679 2678 2735 + 3634 3 3 2791 2735 2734 + 3635 3 3 2737 2681 2680 + 3636 3 3 2737 2682 2681 + 3637 3 3 2738 2683 2682 + 3638 3 3 2683 2627 2682 + 3639 3 3 2682 2625 2681 + 3640 3 3 2739 2684 2683 + 3641 3 3 2681 2624 2680 + 3642 3 3 2735 2678 2734 + 3643 3 3 2684 2627 2683 + 3644 3 3 2685 2630 2629 + 3645 3 3 2685 2629 2628 + 3646 3 3 2631 2573 2630 + 3647 3 3 2629 2572 2628 + 3648 3 3 2633 2575 2632 + 3649 3 3 2687 2632 2631 + 3650 3 3 2689 2633 2632 + 3651 3 3 2632 2575 2631 + 3652 3 3 2687 2631 2630 + 3653 3 3 2630 2573 2629 + 3654 3 3 2740 2685 2684 + 3655 3 3 2741 2686 2685 + 3656 3 3 2687 2630 2686 + 3657 3 3 2685 2628 2684 + 3658 3 3 2689 2632 2688 + 3659 3 3 2743 2688 2687 + 3660 3 3 2744 2689 2688 + 3661 3 3 2688 2632 2687 + 3662 3 3 2742 2687 2686 + 3663 3 3 2686 2630 2685 + 3664 3 3 2628 2627 2684 + 3665 3 3 2690 2633 2689 + 3666 3 3 2736 2679 2735 + 3667 3 3 2627 2570 2626 + 3668 3 3 2736 2735 2791 + 3669 3 3 2791 2734 2790 + 3670 3 3 2847 2791 2790 + 3671 3 3 2793 2737 2736 + 3672 3 3 2739 2683 2738 + 3673 3 3 2793 2738 2737 + 3674 3 3 2794 2739 2738 + 3675 3 3 2740 2684 2739 + 3676 3 3 2792 2736 2791 + 3677 3 3 2737 2680 2736 + 3678 3 3 2792 2791 2847 + 3679 3 3 2847 2790 2846 + 3680 3 3 2903 2847 2846 + 3681 3 3 2849 2793 2792 + 3682 3 3 2795 2739 2794 + 3683 3 3 2849 2794 2793 + 3684 3 3 2851 2795 2794 + 3685 3 3 2794 2738 2793 + 3686 3 3 2851 2796 2795 + 3687 3 3 2793 2736 2792 + 3688 3 3 2790 2845 2846 + 3689 3 3 2796 2739 2795 + 3690 3 3 2799 2743 2742 + 3691 3 3 2797 2742 2741 + 3692 3 3 2742 2686 2741 + 3693 3 3 2741 2685 2740 + 3694 3 3 2801 2745 2744 + 3695 3 3 2799 2744 2743 + 3696 3 3 2745 2689 2744 + 3697 3 3 2744 2688 2743 + 3698 3 3 2797 2741 2740 + 3699 3 3 2743 2687 2742 + 3700 3 3 2853 2797 2796 + 3701 3 3 2853 2798 2797 + 3702 3 3 2799 2742 2798 + 3703 3 3 2798 2742 2797 + 3704 3 3 2801 2744 2800 + 3705 3 3 2855 2799 2798 + 3706 3 3 2856 2801 2800 + 3707 3 3 2800 2744 2799 + 3708 3 3 2855 2800 2799 + 3709 3 3 2797 2740 2796 + 3710 3 3 2740 2739 2796 + 3711 3 3 2802 2745 2801 + 3712 3 3 2848 2792 2847 + 3713 3 3 2738 2682 2737 + 3714 3 3 2734 2789 2790 + 3715 3 3 2746 2689 2745 + 3716 3 3 2897 2842 2841 + 3717 3 3 2634 2576 2633 + 3718 3 3 2895 2838 2894 + 3719 3 3 276 2894 275 + 3720 3 3 2950 2896 2895 + 3721 3 3 2896 2839 2895 + 3722 3 3 2952 2898 2897 + 3723 3 3 2951 2897 2896 + 3724 3 3 2898 2842 2897 + 3725 3 3 2897 2840 2896 + 3726 3 3 2949 2895 2894 + 3727 3 3 2899 2842 2898 + 3728 3 3 2950 2895 2949 + 3729 3 3 277 2949 276 + 3730 3 3 3004 2950 2949 + 3731 3 3 2951 2896 2950 + 3732 3 3 2953 2898 2952 + 3733 3 3 3007 2952 2951 + 3734 3 3 3008 2953 2952 + 3735 3 3 2952 2897 2951 + 3736 3 3 3009 2954 2953 + 3737 3 3 2949 2894 276 + 3738 3 3 2954 2898 2953 + 3739 3 3 2901 2845 2900 + 3740 3 3 2954 2900 2899 + 3741 3 3 2957 2902 2901 + 3742 3 3 2902 2845 2901 + 3743 3 3 2904 2847 2903 + 3744 3 3 2903 2846 2902 + 3745 3 3 2957 2903 2902 + 3746 3 3 2848 2847 2904 + 3747 3 3 2955 2901 2900 + 3748 3 3 2900 2844 2899 + 3749 3 3 2956 2901 2955 + 3750 3 3 3009 2955 2954 + 3751 3 3 3010 2956 2955 + 3752 3 3 2957 2901 2956 + 3753 3 3 2904 2903 2958 + 3754 3 3 2958 2903 2957 + 3755 3 3 3013 2958 2957 + 3756 3 3 2959 2904 2958 + 3757 3 3 3012 2957 2956 + 3758 3 3 2955 2900 2954 + 3759 3 3 2899 2898 2954 + 3760 3 3 2905 2848 2904 + 3761 3 3 3006 2951 2950 + 3762 3 3 2894 2838 275 + 3763 3 3 277 278 3004 + 3764 3 3 281 3005 3004 + 3765 3 3 3005 2950 3004 + 3766 3 3 3007 2951 3006 + 3767 3 3 282 3006 3005 + 3768 3 3 283 3007 3006 + 3769 3 3 3006 2950 3005 + 3770 3 3 280 3004 278 + 3771 3 3 3008 2952 3007 + 3772 3 3 282 3005 281 + 3773 3 3 281 3004 280 + 3774 3 3 284 3007 283 + 3775 3 3 283 3006 282 + 3776 3 3 280 278 279 + 3777 3 3 3008 3007 284 + 3778 3 3 287 3011 3010 + 3779 3 3 286 3010 3009 + 3780 3 3 3010 2955 3009 + 3781 3 3 3009 2953 3008 + 3782 3 3 3013 2957 3012 + 3783 3 3 288 3012 3011 + 3784 3 3 289 3013 3012 + 3785 3 3 3012 2956 3011 + 3786 3 3 285 3009 3008 + 3787 3 3 3011 2956 3010 + 3788 3 3 287 3010 286 + 3789 3 3 288 3011 287 + 3790 3 3 290 3013 289 + 3791 3 3 289 3012 288 + 3792 3 3 286 3009 285 + 3793 3 3 3008 284 285 + 3794 3 3 2959 2958 3013 + 3795 3 3 3004 2949 277 + 3796 3 3 3014 3013 290 + 3797 3 3 2849 2905 2850 + 3798 3 3 2849 2848 2905 + 3799 3 3 2906 2850 2905 + 3800 3 3 2851 2794 2850 + 3801 3 3 2907 2852 2851 + 3802 3 3 2851 2850 2906 + 3803 3 3 2907 2851 2906 + 3804 3 3 2853 2796 2852 + 3805 3 3 2961 2906 2905 + 3806 3 3 2852 2796 2851 + 3807 3 3 3015 2961 2960 + 3808 3 3 3017 2963 2962 + 3809 3 3 2962 2906 2961 + 3810 3 3 2961 2905 2960 + 3811 3 3 2963 2908 2907 + 3812 3 3 2907 2906 2962 + 3813 3 3 2963 2907 2962 + 3814 3 3 2908 2852 2907 + 3815 3 3 3017 2962 2961 + 3816 3 3 2960 2905 2959 + 3817 3 3 2905 2904 2959 + 3818 3 3 2909 2852 2908 + 3819 3 3 2853 2909 2854 + 3820 3 3 2853 2852 2909 + 3821 3 3 2911 2855 2854 + 3822 3 3 2855 2798 2854 + 3823 3 3 2912 2856 2855 + 3824 3 3 2912 2857 2856 + 3825 3 3 2857 2801 2856 + 3826 3 3 2856 2800 2855 + 3827 3 3 2910 2854 2909 + 3828 3 3 2854 2798 2853 + 3829 3 3 2965 2910 2909 + 3830 3 3 2909 2908 2964 + 3831 3 3 3018 2964 2963 + 3832 3 3 2965 2911 2910 + 3833 3 3 2913 2857 2912 + 3834 3 3 2966 2912 2911 + 3835 3 3 2968 2913 2912 + 3836 3 3 2912 2855 2911 + 3837 3 3 2965 2909 2964 + 3838 3 3 2911 2854 2910 + 3839 3 3 2964 2908 2963 + 3840 3 3 2858 2857 2913 + 3841 3 3 3015 2960 2959 + 3842 3 3 2850 2794 2849 + 3843 3 3 292 3016 3015 + 3844 3 3 291 3015 3014 + 3845 3 3 3017 2961 3016 + 3846 3 3 3016 2961 3015 + 3847 3 3 3019 2964 3018 + 3848 3 3 294 3018 3017 + 3849 3 3 295 3019 3018 + 3850 3 3 3020 2964 3019 + 3851 3 3 293 3017 3016 + 3852 3 3 3018 2963 3017 + 3853 3 3 294 3017 293 + 3854 3 3 293 3016 292 + 3855 3 3 296 3019 295 + 3856 3 3 295 3018 294 + 3857 3 3 292 3015 291 + 3858 3 3 3014 290 291 + 3859 3 3 3020 3019 296 + 3860 3 3 2965 3020 2966 + 3861 3 3 2965 2964 3020 + 3862 3 3 3021 2966 3020 + 3863 3 3 2967 2912 2966 + 3864 3 3 3023 2968 2967 + 3865 3 3 2967 2966 3021 + 3866 3 3 3022 2967 3021 + 3867 3 3 2968 2912 2967 + 3868 3 3 297 3021 3020 + 3869 3 3 2966 2911 2965 + 3870 3 3 3022 3021 298 + 3871 3 3 298 3021 297 + 3872 3 3 299 3022 298 + 3873 3 3 3023 299 300 + 3874 3 3 3023 3022 299 + 3875 3 3 2969 2968 3023 + 3876 3 3 3023 2967 3022 + 3877 3 3 3020 296 297 + 3878 3 3 2914 2913 2968 + 3879 3 3 3015 2959 3014 + 3880 3 3 2959 3013 3014 + 3881 3 3 2802 2801 2857 + 3882 3 3 2849 2792 2848 + 3883 3 3 3024 3023 300 + 3884 3 3 2636 2578 2635 + 3885 3 3 2690 2635 2634 + 3886 3 3 2638 2580 2637 + 3887 3 3 2692 2637 2636 + 3888 3 3 2694 2638 2637 + 3889 3 3 2637 2580 2636 + 3890 3 3 2691 2636 2635 + 3891 3 3 2639 2582 2638 + 3892 3 3 2748 2692 2691 + 3893 3 3 2747 2691 2690 + 3894 3 3 2693 2637 2692 + 3895 3 3 2692 2636 2691 + 3896 3 3 2639 2638 2694 + 3897 3 3 2694 2637 2693 + 3898 3 3 2750 2694 2693 + 3899 3 3 2695 2639 2694 + 3900 3 3 2750 2695 2694 + 3901 3 3 2691 2635 2690 + 3902 3 3 2634 2633 2690 + 3903 3 3 2640 2583 2639 + 3904 3 3 2642 2584 2641 + 3905 3 3 2696 2641 2640 + 3906 3 3 2698 2643 2642 + 3907 3 3 2643 2585 2642 + 3908 3 3 2644 2587 2586 + 3909 3 3 2586 2585 2643 + 3910 3 3 2644 2586 2643 + 3911 3 3 2587 2529 2586 + 3912 3 3 2698 2642 2641 + 3913 3 3 2641 2584 2640 + 3914 3 3 2751 2696 2695 + 3915 3 3 2752 2697 2696 + 3916 3 3 2698 2641 2697 + 3917 3 3 2697 2641 2696 + 3918 3 3 2644 2643 2699 + 3919 3 3 2699 2643 2698 + 3920 3 3 2754 2699 2698 + 3921 3 3 2700 2644 2699 + 3922 3 3 2754 2698 2697 + 3923 3 3 2640 2639 2696 + 3924 3 3 2696 2639 2695 + 3925 3 3 2588 2587 2644 + 3926 3 3 2748 2693 2692 + 3927 3 3 2635 2578 2634 + 3928 3 3 2746 2802 2747 + 3929 3 3 2746 2745 2802 + 3930 3 3 2803 2747 2802 + 3931 3 3 2748 2691 2747 + 3932 3 3 2805 2749 2748 + 3933 3 3 2748 2747 2803 + 3934 3 3 2804 2748 2803 + 3935 3 3 2750 2693 2749 + 3936 3 3 2858 2803 2802 + 3937 3 3 2749 2693 2748 + 3938 3 3 2804 2803 2859 + 3939 3 3 2859 2803 2858 + 3940 3 3 2915 2860 2859 + 3941 3 3 2860 2804 2859 + 3942 3 3 2805 2804 2861 + 3943 3 3 2861 2804 2860 + 3944 3 3 2916 2861 2860 + 3945 3 3 2806 2749 2805 + 3946 3 3 2915 2859 2858 + 3947 3 3 2805 2748 2804 + 3948 3 3 2802 2857 2858 + 3949 3 3 2806 2805 2861 + 3950 3 3 2752 2696 2751 + 3951 3 3 2807 2751 2750 + 3952 3 3 2808 2753 2752 + 3953 3 3 2753 2697 2752 + 3954 3 3 2811 2755 2754 + 3955 3 3 2810 2754 2753 + 3956 3 3 2755 2699 2754 + 3957 3 3 2754 2697 2753 + 3958 3 3 2808 2752 2751 + 3959 3 3 2751 2695 2750 + 3960 3 3 2808 2751 2807 + 3961 3 3 2863 2807 2806 + 3962 3 3 2864 2808 2807 + 3963 3 3 2807 2750 2806 + 3964 3 3 2866 2810 2809 + 3965 3 3 2866 2811 2810 + 3966 3 3 2811 2754 2810 + 3967 3 3 2810 2753 2809 + 3968 3 3 2864 2809 2808 + 3969 3 3 2809 2753 2808 + 3970 3 3 2750 2749 2806 + 3971 3 3 2700 2699 2755 + 3972 3 3 2868 2812 2811 + 3973 3 3 2747 2690 2746 + 3974 3 3 2690 2689 2746 + 3975 3 3 2812 2755 2811 + 3976 3 3 2588 2645 2589 + 3977 3 3 2588 2644 2645 + 3978 3 3 2646 2589 2645 + 3979 3 3 2589 2531 2588 + 3980 3 3 2647 2591 2590 + 3981 3 3 2647 2590 2589 + 3982 3 3 2647 2589 2646 + 3983 3 3 2592 2534 2591 + 3984 3 3 2702 2646 2645 + 3985 3 3 2591 2534 2590 + 3986 3 3 2702 2645 2701 + 3987 3 3 2758 2702 2701 + 3988 3 3 2759 2703 2702 + 3989 3 3 2647 2646 2702 + 3990 3 3 2647 2703 2648 + 3991 3 3 2647 2702 2703 + 3992 3 3 2704 2648 2703 + 3993 3 3 2648 2591 2647 + 3994 3 3 2760 2704 2703 + 3995 3 3 2701 2645 2700 + 3996 3 3 2645 2644 2700 + 3997 3 3 2649 2591 2648 + 3998 3 3 2592 2649 2593 + 3999 3 3 2592 2591 2649 + 4000 3 3 2650 2594 2593 + 4001 3 3 2594 2537 2593 + 4002 3 3 2652 2595 2594 + 4003 3 3 2653 2596 2595 + 4004 3 3 2596 2539 2595 + 4005 3 3 2595 2537 2594 + 4006 3 3 2650 2593 2649 + 4007 3 3 2593 2535 2592 + 4008 3 3 2706 2650 2649 + 4009 3 3 2649 2648 2705 + 4010 3 3 2761 2705 2704 + 4011 3 3 2707 2651 2650 + 4012 3 3 2653 2595 2652 + 4013 3 3 2707 2652 2651 + 4014 3 3 2708 2653 2652 + 4015 3 3 2652 2594 2651 + 4016 3 3 2706 2649 2705 + 4017 3 3 2651 2594 2650 + 4018 3 3 2705 2648 2704 + 4019 3 3 2597 2596 2653 + 4020 3 3 2757 2701 2700 + 4021 3 3 2590 2533 2589 + 4022 3 3 2814 2759 2758 + 4023 3 3 2814 2758 2757 + 4024 3 3 2759 2702 2758 + 4025 3 3 2758 2701 2757 + 4026 3 3 2816 2761 2760 + 4027 3 3 2815 2760 2759 + 4028 3 3 2761 2704 2760 + 4029 3 3 2760 2703 2759 + 4030 3 3 2813 2757 2756 + 4031 3 3 2706 2705 2761 + 4032 3 3 2814 2757 2813 + 4033 3 3 2868 2813 2812 + 4034 3 3 2869 2814 2813 + 4035 3 3 2815 2759 2814 + 4036 3 3 2817 2761 2816 + 4037 3 3 2870 2815 2814 + 4038 3 3 2873 2817 2816 + 4039 3 3 2816 2760 2815 + 4040 3 3 2872 2816 2815 + 4041 3 3 2813 2756 2812 + 4042 3 3 2700 2755 2756 + 4043 3 3 2818 2761 2817 + 4044 3 3 2706 2762 2707 + 4045 3 3 2706 2761 2762 + 4046 3 3 2763 2707 2762 + 4047 3 3 2708 2652 2707 + 4048 3 3 2765 2709 2708 + 4049 3 3 2764 2708 2707 + 4050 3 3 2764 2707 2763 + 4051 3 3 2709 2653 2708 + 4052 3 3 2819 2763 2762 + 4053 3 3 2707 2650 2706 + 4054 3 3 2764 2763 2819 + 4055 3 3 2819 2762 2818 + 4056 3 3 2875 2819 2818 + 4057 3 3 2820 2764 2819 + 4058 3 3 2765 2820 2821 + 4059 3 3 2765 2764 2820 + 4060 3 3 2877 2821 2820 + 4061 3 3 2766 2709 2765 + 4062 3 3 2874 2818 2817 + 4063 3 3 2765 2708 2764 + 4064 3 3 2762 2761 2818 + 4065 3 3 2822 2765 2821 + 4066 3 3 2876 2820 2819 + 4067 3 3 2757 2700 2756 + 4068 3 3 2756 2755 2812 + 4069 3 3 2654 2653 2709 + 4070 3 3 2862 2806 2861 + 4071 3 3 2588 2531 2587 + 4072 3 3 2916 2860 2915 + 4073 3 3 2969 2915 2914 + 4074 3 3 2970 2916 2915 + 4075 3 3 2917 2861 2916 + 4076 3 3 2919 2863 2862 + 4077 3 3 2918 2861 2917 + 4078 3 3 2862 2861 2918 + 4079 3 3 2863 2806 2862 + 4080 3 3 2971 2917 2916 + 4081 3 3 2915 2858 2914 + 4082 3 3 3026 2971 2970 + 4083 3 3 3027 2972 2971 + 4084 3 3 2972 2917 2971 + 4085 3 3 2971 2916 2970 + 4086 3 3 2918 2917 2973 + 4087 3 3 2973 2917 2972 + 4088 3 3 3029 2974 2973 + 4089 3 3 2919 2862 2918 + 4090 3 3 3025 2970 2969 + 4091 3 3 2970 2915 2969 + 4092 3 3 2858 2913 2914 + 4093 3 3 2919 2918 2973 + 4094 3 3 2920 2865 2864 + 4095 3 3 2864 2863 2919 + 4096 3 3 2921 2866 2865 + 4097 3 3 2866 2809 2865 + 4098 3 3 2922 2867 2866 + 4099 3 3 2924 2868 2867 + 4100 3 3 2868 2811 2867 + 4101 3 3 2867 2811 2866 + 4102 3 3 2920 2864 2919 + 4103 3 3 2869 2813 2868 + 4104 3 3 2976 2921 2920 + 4105 3 3 2920 2919 2974 + 4106 3 3 2977 2922 2921 + 4107 3 3 2921 2865 2920 + 4108 3 3 2924 2867 2923 + 4109 3 3 2978 2923 2922 + 4110 3 3 2979 2924 2923 + 4111 3 3 2923 2867 2922 + 4112 3 3 2975 2920 2974 + 4113 3 3 2922 2866 2921 + 4114 3 3 2919 2973 2974 + 4115 3 3 2869 2868 2924 + 4116 3 3 3028 2973 2972 + 4117 3 3 2864 2807 2863 + 4118 3 3 302 3026 3025 + 4119 3 3 303 3027 3026 + 4120 3 3 3027 2971 3026 + 4121 3 3 3026 2970 3025 + 4122 3 3 304 3028 3027 + 4123 3 3 305 3029 3028 + 4124 3 3 3030 2974 3029 + 4125 3 3 3029 2973 3028 + 4126 3 3 301 3025 3024 + 4127 3 3 3028 2972 3027 + 4128 3 3 303 3026 302 + 4129 3 3 302 3025 301 + 4130 3 3 306 3029 305 + 4131 3 3 305 3028 304 + 4132 3 3 304 3027 303 + 4133 3 3 3024 300 301 + 4134 3 3 3030 3029 306 + 4135 3 3 2975 3030 2976 + 4136 3 3 2975 2974 3030 + 4137 3 3 3031 2976 3030 + 4138 3 3 2976 2920 2975 + 4139 3 3 3033 2978 2977 + 4140 3 3 2977 2976 3031 + 4141 3 3 3032 2977 3031 + 4142 3 3 2978 2922 2977 + 4143 3 3 307 3031 3030 + 4144 3 3 2977 2921 2976 + 4145 3 3 3032 3031 308 + 4146 3 3 308 3031 307 + 4147 3 3 309 3032 308 + 4148 3 3 3033 309 310 + 4149 3 3 3033 3032 309 + 4150 3 3 2979 2978 3033 + 4151 3 3 3033 2977 3032 + 4152 3 3 3030 306 307 + 4153 3 3 2979 2923 2978 + 4154 3 3 3025 2969 3024 + 4155 3 3 2969 3023 3024 + 4156 3 3 3034 3033 310 + 4157 3 3 2926 2870 2869 + 4158 3 3 2869 2924 2925 + 4159 3 3 2926 2869 2925 + 4160 3 3 2871 2815 2870 + 4161 3 3 2928 2872 2871 + 4162 3 3 2927 2871 2870 + 4163 3 3 2927 2870 2926 + 4164 3 3 2872 2815 2871 + 4165 3 3 2980 2926 2925 + 4166 3 3 2873 2816 2872 + 4167 3 3 3035 2981 2980 + 4168 3 3 3034 2980 2979 + 4169 3 3 2927 2926 2981 + 4170 3 3 2981 2926 2980 + 4171 3 3 2927 2982 2928 + 4172 3 3 2927 2981 2982 + 4173 3 3 2983 2928 2982 + 4174 3 3 2928 2871 2927 + 4175 3 3 3037 2982 2981 + 4176 3 3 2980 2925 2979 + 4177 3 3 2925 2924 2979 + 4178 3 3 2873 2872 2928 + 4179 3 3 2930 2874 2873 + 4180 3 3 2873 2928 2929 + 4181 3 3 2930 2875 2874 + 4182 3 3 2875 2818 2874 + 4183 3 3 2931 2876 2875 + 4184 3 3 2933 2877 2876 + 4185 3 3 2877 2820 2876 + 4186 3 3 2876 2819 2875 + 4187 3 3 2930 2873 2929 + 4188 3 3 2874 2817 2873 + 4189 3 3 2985 2930 2929 + 4190 3 3 2984 2929 2983 + 4191 3 3 3038 2984 2983 + 4192 3 3 2986 2931 2930 + 4193 3 3 2933 2876 2932 + 4194 3 3 2986 2932 2931 + 4195 3 3 2988 2933 2932 + 4196 3 3 2932 2876 2931 + 4197 3 3 2985 2929 2984 + 4198 3 3 2931 2875 2930 + 4199 3 3 2929 2928 2983 + 4200 3 3 2878 2877 2933 + 4201 3 3 3038 2983 2982 + 4202 3 3 2870 2814 2869 + 4203 3 3 312 3036 3035 + 4204 3 3 311 3035 3034 + 4205 3 3 3037 2981 3036 + 4206 3 3 3036 2981 3035 + 4207 3 3 315 3039 3038 + 4208 3 3 314 3038 3037 + 4209 3 3 2985 2984 3039 + 4210 3 3 3038 2982 3037 + 4211 3 3 313 3037 3036 + 4212 3 3 3039 2984 3038 + 4213 3 3 314 3037 313 + 4214 3 3 312 3035 311 + 4215 3 3 316 3039 315 + 4216 3 3 315 3038 314 + 4217 3 3 313 3036 312 + 4218 3 3 3034 310 311 + 4219 3 3 3040 3039 316 + 4220 3 3 3041 2986 2985 + 4221 3 3 2985 3039 3040 + 4222 3 3 3041 2985 3040 + 4223 3 3 2986 2930 2985 + 4224 3 3 3042 2988 2987 + 4225 3 3 2987 2986 3041 + 4226 3 3 3042 2987 3041 + 4227 3 3 2988 2932 2987 + 4228 3 3 317 3041 3040 + 4229 3 3 2987 2932 2986 + 4230 3 3 3042 3041 318 + 4231 3 3 318 3041 317 + 4232 3 3 319 3042 318 + 4233 3 3 3043 319 320 + 4234 3 3 3043 3042 319 + 4235 3 3 2989 2988 3043 + 4236 3 3 3043 2988 3042 + 4237 3 3 3040 316 317 + 4238 3 3 2989 2933 2988 + 4239 3 3 3035 2980 3034 + 4240 3 3 2979 3033 3034 + 4241 3 3 2878 2821 2877 + 4242 3 3 2865 2809 2864 + 4243 3 3 2914 2968 2969 + 4244 3 3 2597 2539 2596 + 4245 3 3 2614 2557 270 + 4246 3 3 3044 3043 320 + 4247 3 3 1820 170 171 + 4248 3 3 169 170 1791 + 4249 3 3 1791 170 1820 + 4250 3 3 1792 1791 1820 + 4251 3 3 1792 1762 1791 + 4252 3 3 1849 1820 171 + 4253 3 3 1849 1848 172 + 4254 3 3 1848 171 172 + 4255 3 3 1878 172 173 + 4256 3 3 1849 172 1879 + 4257 3 3 1879 172 1878 + 4258 3 3 1908 1879 1878 + 4259 3 3 1880 1849 1879 + 4260 3 3 1909 1880 1879 + 4261 3 3 1849 171 1848 + 4262 3 3 1850 1820 1849 + 4263 3 3 1792 1821 1793 + 4264 3 3 1792 1820 1821 + 4265 3 3 1822 1793 1821 + 4266 3 3 1794 1764 1793 + 4267 3 3 1794 1822 1823 + 4268 3 3 1794 1793 1822 + 4269 3 3 1852 1823 1822 + 4270 3 3 1824 1794 1823 + 4271 3 3 1850 1822 1821 + 4272 3 3 1793 1764 1792 + 4273 3 3 1850 1880 1851 + 4274 3 3 1821 1820 1850 + 4275 3 3 1881 1851 1880 + 4276 3 3 1852 1822 1851 + 4277 3 3 1852 1851 1882 + 4278 3 3 1882 1851 1881 + 4279 3 3 1912 1882 1881 + 4280 3 3 1853 1823 1852 + 4281 3 3 1910 1881 1880 + 4282 3 3 1851 1822 1850 + 4283 3 3 1850 1849 1880 + 4284 3 3 1853 1852 1882 + 4285 3 3 1908 1878 173 + 4286 3 3 1795 1765 1794 + 4287 3 3 1937 1908 174 + 4288 3 3 1908 173 174 + 4289 3 3 1937 174 175 + 4290 3 3 1909 1937 1938 + 4291 3 3 1909 1908 1937 + 4292 3 3 1967 1938 1937 + 4293 3 3 1910 1909 1938 + 4294 3 3 1966 1937 175 + 4295 3 3 1910 1880 1909 + 4296 3 3 1995 1966 176 + 4297 3 3 1966 175 176 + 4298 3 3 1995 176 177 + 4299 3 3 1996 1966 1995 + 4300 3 3 1996 1967 1966 + 4301 3 3 1995 177 2024 + 4302 3 3 2025 1995 2024 + 4303 3 3 178 2024 177 + 4304 3 3 1967 1937 1966 + 4305 3 3 1939 1938 1967 + 4306 3 3 1939 1967 1968 + 4307 3 3 1910 1938 1939 + 4308 3 3 1969 1940 1939 + 4309 3 3 1940 1910 1939 + 4310 3 3 1941 1912 1911 + 4311 3 3 1911 1910 1940 + 4312 3 3 1941 1911 1940 + 4313 3 3 1912 1881 1911 + 4314 3 3 1969 1939 1968 + 4315 3 3 1911 1881 1910 + 4316 3 3 1996 2025 1997 + 4317 3 3 1996 1995 2025 + 4318 3 3 2026 1997 2025 + 4319 3 3 1969 1968 1997 + 4320 3 3 1969 1997 1998 + 4321 3 3 1998 1997 2026 + 4322 3 3 2027 1999 1998 + 4323 3 3 1970 1940 1969 + 4324 3 3 2053 2026 2025 + 4325 3 3 1997 1968 1996 + 4326 3 3 1968 1967 1996 + 4327 3 3 1970 1969 1998 + 4328 3 3 2052 2025 2024 + 4329 3 3 1909 1879 1908 + 4330 3 3 1913 1882 1912 + 4331 3 3 1795 1824 1796 + 4332 3 3 1795 1794 1824 + 4333 3 3 1825 1796 1824 + 4334 3 3 1797 1768 1796 + 4335 3 3 1797 1825 1826 + 4336 3 3 1797 1796 1825 + 4337 3 3 1855 1826 1825 + 4338 3 3 1798 1797 1826 + 4339 3 3 1854 1825 1824 + 4340 3 3 1798 1769 1797 + 4341 3 3 1853 1883 1854 + 4342 3 3 1853 1882 1883 + 4343 3 3 1884 1854 1883 + 4344 3 3 1854 1824 1853 + 4345 3 3 1855 1884 1885 + 4346 3 3 1855 1854 1884 + 4347 3 3 1915 1886 1885 + 4348 3 3 1827 1826 1855 + 4349 3 3 1915 1885 1884 + 4350 3 3 1855 1825 1854 + 4351 3 3 1824 1823 1853 + 4352 3 3 1856 1855 1885 + 4353 3 3 1798 1827 1799 + 4354 3 3 1798 1826 1827 + 4355 3 3 1828 1799 1827 + 4356 3 3 1800 1770 1799 + 4357 3 3 1771 1770 1800 + 4358 3 3 1829 1800 1799 + 4359 3 3 1829 1799 1828 + 4360 3 3 1772 1771 1800 + 4361 3 3 1857 1828 1827 + 4362 3 3 1799 1769 1798 + 4363 3 3 1887 1857 1856 + 4364 3 3 1827 1855 1856 + 4365 3 3 1887 1856 1886 + 4366 3 3 1829 1828 1857 + 4367 3 3 1829 1857 1858 + 4368 3 3 1858 1857 1887 + 4369 3 3 1888 1858 1887 + 4370 3 3 1801 1800 1829 + 4371 3 3 1917 1887 1886 + 4372 3 3 1857 1827 1856 + 4373 3 3 1856 1885 1886 + 4374 3 3 1830 1829 1858 + 4375 3 3 1914 1884 1883 + 4376 3 3 1796 1766 1795 + 4377 3 3 1913 1941 1942 + 4378 3 3 1883 1882 1913 + 4379 3 3 1971 1943 1942 + 4380 3 3 1943 1913 1942 + 4381 3 3 1914 1943 1915 + 4382 3 3 1914 1913 1943 + 4383 3 3 1944 1915 1943 + 4384 3 3 1916 1886 1915 + 4385 3 3 1970 1942 1941 + 4386 3 3 1915 1884 1914 + 4387 3 3 2000 1971 1970 + 4388 3 3 1941 1940 1970 + 4389 3 3 2000 1970 1999 + 4390 3 3 1972 1943 1971 + 4391 3 3 1972 2000 2001 + 4392 3 3 1972 1971 2000 + 4393 3 3 2029 2000 1999 + 4394 3 3 1973 1943 1972 + 4395 3 3 2030 2001 2000 + 4396 3 3 1971 1942 1970 + 4397 3 3 1970 1998 1999 + 4398 3 3 2002 1972 2001 + 4399 3 3 1916 1944 1945 + 4400 3 3 1916 1915 1944 + 4401 3 3 1975 1946 1945 + 4402 3 3 1946 1916 1945 + 4403 3 3 1918 1888 1917 + 4404 3 3 1888 1887 1917 + 4405 3 3 1917 1916 1946 + 4406 3 3 1947 1917 1946 + 4407 3 3 1974 1945 1944 + 4408 3 3 1917 1886 1916 + 4409 3 3 2003 1974 1973 + 4410 3 3 1944 1943 1973 + 4411 3 3 2003 1973 2002 + 4412 3 3 1975 1945 1974 + 4413 3 3 1975 1974 2004 + 4414 3 3 2004 1974 2003 + 4415 3 3 2033 2004 2003 + 4416 3 3 1947 1946 1975 + 4417 3 3 2031 2002 2001 + 4418 3 3 1974 1944 1973 + 4419 3 3 1973 1972 2002 + 4420 3 3 1976 1975 2004 + 4421 3 3 2032 2003 2002 + 4422 3 3 1914 1883 1913 + 4423 3 3 1913 1912 1941 + 4424 3 3 1889 1858 1888 + 4425 3 3 2027 1998 2026 + 4426 3 3 1791 1762 169 + 4427 3 3 178 179 2051 + 4428 3 3 2078 2051 179 + 4429 3 3 2052 2024 2051 + 4430 3 3 2079 2053 2052 + 4431 3 3 2079 2052 2051 + 4432 3 3 2079 2051 2078 + 4433 3 3 2053 2025 2052 + 4434 3 3 179 2077 2078 + 4435 3 3 2054 2026 2053 + 4436 3 3 2102 2079 2101 + 4437 3 3 2079 2078 2101 + 4438 3 3 2078 180 2101 + 4439 3 3 2124 2101 2123 + 4440 3 3 2103 2080 2102 + 4441 3 3 2080 2079 2102 + 4442 3 3 2102 2101 2124 + 4443 3 3 2125 2102 2124 + 4444 3 3 2144 2124 2123 + 4445 3 3 2080 2053 2079 + 4446 3 3 2101 2122 2123 + 4447 3 3 2081 2053 2080 + 4448 3 3 2054 2053 2081 + 4449 3 3 2027 2026 2054 + 4450 3 3 2055 2054 2081 + 4451 3 3 2028 2027 2054 + 4452 3 3 2029 2028 2055 + 4453 3 3 2028 2054 2055 + 4454 3 3 2055 2081 2082 + 4455 3 3 2056 2055 2082 + 4456 3 3 2104 2082 2081 + 4457 3 3 2029 1999 2028 + 4458 3 3 2126 2104 2103 + 4459 3 3 2103 2102 2125 + 4460 3 3 2126 2103 2125 + 4461 3 3 2104 2081 2103 + 4462 3 3 2105 2104 2127 + 4463 3 3 2127 2104 2126 + 4464 3 3 2147 2127 2126 + 4465 3 3 2128 2105 2127 + 4466 3 3 2146 2126 2125 + 4467 3 3 2105 2082 2104 + 4468 3 3 2081 2080 2103 + 4469 3 3 2106 2082 2105 + 4470 3 3 2145 2125 2124 + 4471 3 3 2051 2024 178 + 4472 3 3 2166 2145 2144 + 4473 3 3 2123 2143 2144 + 4474 3 3 2166 2144 2165 + 4475 3 3 2146 2125 2145 + 4476 3 3 2146 2145 2167 + 4477 3 3 2167 2145 2166 + 4478 3 3 2188 2167 2166 + 4479 3 3 2147 2146 2167 + 4480 3 3 2186 2166 2165 + 4481 3 3 2145 2124 2144 + 4482 3 3 2144 2164 2165 + 4483 3 3 2186 2185 2206 + 4484 3 3 2228 2206 2227 + 4485 3 3 2207 2186 2206 + 4486 3 3 2208 2187 2207 + 4487 3 3 2187 2186 2207 + 4488 3 3 2207 2206 2228 + 4489 3 3 2188 2166 2187 + 4490 3 3 2249 2229 2228 + 4491 3 3 2187 2166 2186 + 4492 3 3 2206 2226 2227 + 4493 3 3 2208 2207 2228 + 4494 3 3 2147 2167 2168 + 4495 3 3 2168 2167 2188 + 4496 3 3 2189 2168 2188 + 4497 3 3 2169 2147 2168 + 4498 3 3 2148 2147 2169 + 4499 3 3 2190 2169 2168 + 4500 3 3 2190 2168 2189 + 4501 3 3 2170 2148 2169 + 4502 3 3 2208 2189 2188 + 4503 3 3 2148 2127 2147 + 4504 3 3 2230 2209 2208 + 4505 3 3 2188 2187 2208 + 4506 3 3 2230 2208 2229 + 4507 3 3 2190 2189 2209 + 4508 3 3 2190 2209 2210 + 4509 3 3 2210 2209 2230 + 4510 3 3 2231 2210 2230 + 4511 3 3 2170 2169 2190 + 4512 3 3 2250 2230 2229 + 4513 3 3 2209 2189 2208 + 4514 3 3 2208 2228 2229 + 4515 3 3 2211 2190 2210 + 4516 3 3 2248 2228 2227 + 4517 3 3 2147 2126 2146 + 4518 3 3 2165 2164 2186 + 4519 3 3 2128 2127 2148 + 4520 3 3 2057 2030 2029 + 4521 3 3 2056 2082 2083 + 4522 3 3 2057 2029 2056 + 4523 3 3 2030 2000 2029 + 4524 3 3 2031 2030 2058 + 4525 3 3 2058 2030 2057 + 4526 3 3 2084 2058 2057 + 4527 3 3 2032 2031 2058 + 4528 3 3 2084 2057 2056 + 4529 3 3 2032 2002 2031 + 4530 3 3 2107 2083 2106 + 4531 3 3 2083 2082 2106 + 4532 3 3 2106 2105 2128 + 4533 3 3 2129 2106 2128 + 4534 3 3 2084 2083 2107 + 4535 3 3 2107 2106 2129 + 4536 3 3 2108 2084 2107 + 4537 3 3 2085 2058 2084 + 4538 3 3 2149 2129 2128 + 4539 3 3 2084 2056 2083 + 4540 3 3 2029 2055 2056 + 4541 3 3 2130 2107 2129 + 4542 3 3 2032 2058 2059 + 4543 3 3 2059 2058 2085 + 4544 3 3 2086 2059 2085 + 4545 3 3 2033 2032 2059 + 4546 3 3 2033 2059 2060 + 4547 3 3 2087 2060 2059 + 4548 3 3 2087 2059 2086 + 4549 3 3 2005 2004 2033 + 4550 3 3 2108 2086 2085 + 4551 3 3 2033 2003 2032 + 4552 3 3 2108 2130 2109 + 4553 3 3 2108 2107 2130 + 4554 3 3 2131 2109 2130 + 4555 3 3 2110 2086 2109 + 4556 3 3 2087 2086 2110 + 4557 3 3 2132 2110 2109 + 4558 3 3 2132 2109 2131 + 4559 3 3 2088 2060 2087 + 4560 3 3 2152 2131 2130 + 4561 3 3 2109 2086 2108 + 4562 3 3 2085 2084 2108 + 4563 3 3 2088 2087 2110 + 4564 3 3 2151 2130 2129 + 4565 3 3 2031 2001 2030 + 4566 3 3 2171 2149 2170 + 4567 3 3 2149 2148 2170 + 4568 3 3 2170 2190 2191 + 4569 3 3 2171 2170 2191 + 4570 3 3 2150 2171 2151 + 4571 3 3 2150 2149 2171 + 4572 3 3 2172 2151 2171 + 4573 3 3 2152 2130 2151 + 4574 3 3 2192 2171 2191 + 4575 3 3 2151 2129 2150 + 4576 3 3 2211 2210 2232 + 4577 3 3 2191 2190 2211 + 4578 3 3 2252 2232 2231 + 4579 3 3 2212 2211 2232 + 4580 3 3 2192 2191 2212 + 4581 3 3 2212 2232 2233 + 4582 3 3 2193 2192 2212 + 4583 3 3 2193 2171 2192 + 4584 3 3 2254 2233 2232 + 4585 3 3 2212 2191 2211 + 4586 3 3 2128 2148 2149 + 4587 3 3 2213 2212 2233 + 4588 3 3 2152 2172 2173 + 4589 3 3 2153 2131 2152 + 4590 3 3 2193 2173 2172 + 4591 3 3 2174 2152 2173 + 4592 3 3 2132 2131 2153 + 4593 3 3 2153 2152 2174 + 4594 3 3 2133 2132 2153 + 4595 3 3 2133 2110 2132 + 4596 3 3 2195 2174 2173 + 4597 3 3 2152 2151 2172 + 4598 3 3 2214 2194 2193 + 4599 3 3 2193 2212 2213 + 4600 3 3 2214 2193 2213 + 4601 3 3 2194 2173 2193 + 4602 3 3 2195 2194 2215 + 4603 3 3 2215 2194 2214 + 4604 3 3 2236 2215 2214 + 4605 3 3 2196 2174 2195 + 4606 3 3 2235 2214 2213 + 4607 3 3 2195 2173 2194 + 4608 3 3 2172 2171 2193 + 4609 3 3 2154 2153 2174 + 4610 3 3 2237 2216 2215 + 4611 3 3 2150 2129 2149 + 4612 3 3 2232 2210 2231 + 4613 3 3 2034 2033 2060 + 4614 3 3 2252 2231 2230 + 4615 3 3 2028 1999 2027 + 4616 3 3 2216 2195 2215 + 4617 3 3 1802 1772 1801 + 4618 3 3 1772 1800 1801 + 4619 3 3 1803 1774 1773 + 4620 3 3 1773 1772 1802 + 4621 3 3 1803 1773 1802 + 4622 3 3 1775 1746 1774 + 4623 3 3 1830 1802 1801 + 4624 3 3 1773 1743 1772 + 4625 3 3 1830 1858 1859 + 4626 3 3 1859 1858 1889 + 4627 3 3 1890 1859 1889 + 4628 3 3 1860 1830 1859 + 4629 3 3 1832 1831 1860 + 4630 3 3 1831 1830 1860 + 4631 3 3 1860 1859 1890 + 4632 3 3 1803 1802 1831 + 4633 3 3 1921 1891 1890 + 4634 3 3 1831 1802 1830 + 4635 3 3 1801 1829 1830 + 4636 3 3 1861 1860 1890 + 4637 3 3 1804 1775 1803 + 4638 3 3 1775 1774 1803 + 4639 3 3 1803 1831 1832 + 4640 3 3 1833 1804 1803 + 4641 3 3 1776 1775 1805 + 4642 3 3 1805 1775 1804 + 4643 3 3 1834 1805 1804 + 4644 3 3 1777 1776 1805 + 4645 3 3 1833 1803 1832 + 4646 3 3 1776 1746 1775 + 4647 3 3 1833 1832 1862 + 4648 3 3 1862 1832 1861 + 4649 3 3 1832 1860 1861 + 4650 3 3 1862 1861 1891 + 4651 3 3 1834 1862 1863 + 4652 3 3 1834 1833 1862 + 4653 3 3 1893 1863 1862 + 4654 3 3 1835 1805 1834 + 4655 3 3 1892 1862 1891 + 4656 3 3 1834 1804 1833 + 4657 3 3 1861 1890 1891 + 4658 3 3 1835 1834 1863 + 4659 3 3 1920 1890 1889 + 4660 3 3 1777 1748 1776 + 4661 3 3 1948 1919 1918 + 4662 3 3 1918 1917 1947 + 4663 3 3 1948 1918 1947 + 4664 3 3 1920 1889 1919 + 4665 3 3 1920 1948 1949 + 4666 3 3 1920 1919 1948 + 4667 3 3 1977 1949 1948 + 4668 3 3 1950 1920 1949 + 4669 3 3 1976 1948 1947 + 4670 3 3 1921 1890 1920 + 4671 3 3 1976 2005 1977 + 4672 3 3 1947 1975 1976 + 4673 3 3 2006 1977 2005 + 4674 3 3 1978 1949 1977 + 4675 3 3 1978 1977 2007 + 4676 3 3 2007 1977 2006 + 4677 3 3 2036 2008 2007 + 4678 3 3 1979 1949 1978 + 4679 3 3 2036 2007 2006 + 4680 3 3 1977 1948 1976 + 4681 3 3 1976 2004 2005 + 4682 3 3 1979 1978 2007 + 4683 3 3 1922 1892 1921 + 4684 3 3 1892 1891 1921 + 4685 3 3 1921 1920 1950 + 4686 3 3 1951 1922 1921 + 4687 3 3 1893 1892 1923 + 4688 3 3 1923 1892 1922 + 4689 3 3 1951 1923 1922 + 4690 3 3 1924 1893 1923 + 4691 3 3 1951 1921 1950 + 4692 3 3 1893 1862 1892 + 4693 3 3 1980 1951 1979 + 4694 3 3 1951 1950 1979 + 4695 3 3 1979 2007 2008 + 4696 3 3 2009 1979 2008 + 4697 3 3 1981 1951 1980 + 4698 3 3 1981 1952 1951 + 4699 3 3 1980 1979 2009 + 4700 3 3 2010 1981 1980 + 4701 3 3 2037 2009 2008 + 4702 3 3 1952 1923 1951 + 4703 3 3 1950 1949 1979 + 4704 3 3 1894 1863 1893 + 4705 3 3 2035 2006 2005 + 4706 3 3 1919 1889 1918 + 4707 3 3 1889 1888 1918 + 4708 3 3 1924 1923 1952 + 4709 3 3 1807 1778 1777 + 4710 3 3 1806 1805 1835 + 4711 3 3 1807 1777 1806 + 4712 3 3 1779 1750 1778 + 4713 3 3 1779 1778 1808 + 4714 3 3 1808 1778 1807 + 4715 3 3 1837 1808 1807 + 4716 3 3 1809 1779 1808 + 4717 3 3 1836 1807 1806 + 4718 3 3 1780 1750 1779 + 4719 3 3 1835 1864 1836 + 4720 3 3 1835 1863 1864 + 4721 3 3 1865 1836 1864 + 4722 3 3 1837 1807 1836 + 4723 3 3 1837 1865 1866 + 4724 3 3 1837 1836 1865 + 4725 3 3 1897 1867 1866 + 4726 3 3 1809 1808 1837 + 4727 3 3 1896 1866 1865 + 4728 3 3 1836 1806 1835 + 4729 3 3 1777 1805 1806 + 4730 3 3 1838 1837 1866 + 4731 3 3 1810 1781 1780 + 4732 3 3 1780 1779 1809 + 4733 3 3 1810 1780 1809 + 4734 3 3 1781 1751 1780 + 4735 3 3 375 1810 374 + 4736 3 3 375 1781 1810 + 4737 3 3 1839 374 1810 + 4738 3 3 1839 1810 1809 + 4739 3 3 375 376 1781 + 4740 3 3 1838 1867 1839 + 4741 3 3 1809 1837 1838 + 4742 3 3 1868 1839 1867 + 4743 3 3 1839 1809 1838 + 4744 3 3 373 1868 372 + 4745 3 3 373 1839 1868 + 4746 3 3 1898 372 1868 + 4747 3 3 1898 1868 1867 + 4748 3 3 373 374 1839 + 4749 3 3 1838 1866 1867 + 4750 3 3 1894 1865 1864 + 4751 3 3 1778 1748 1777 + 4752 3 3 1894 1924 1895 + 4753 3 3 1894 1893 1924 + 4754 3 3 1925 1895 1924 + 4755 3 3 1896 1865 1895 + 4756 3 3 1896 1895 1926 + 4757 3 3 1926 1895 1925 + 4758 3 3 1955 1926 1925 + 4759 3 3 1897 1896 1926 + 4760 3 3 1953 1925 1924 + 4761 3 3 1895 1865 1894 + 4762 3 3 1953 1952 1982 + 4763 3 3 1924 1952 1953 + 4764 3 3 2010 1982 1981 + 4765 3 3 1954 1953 1982 + 4766 3 3 1984 1955 1954 + 4767 3 3 1954 1982 1983 + 4768 3 3 1984 1954 1983 + 4769 3 3 1955 1925 1954 + 4770 3 3 2011 1983 1982 + 4771 3 3 1954 1925 1953 + 4772 3 3 1864 1863 1894 + 4773 3 3 1927 1926 1955 + 4774 3 3 1928 1898 1897 + 4775 3 3 1897 1926 1927 + 4776 3 3 1928 1897 1927 + 4777 3 3 1898 1867 1897 + 4778 3 3 371 1928 370 + 4779 3 3 371 1898 1928 + 4780 3 3 1928 1927 370 + 4781 3 3 369 370 1927 + 4782 3 3 371 372 1898 + 4783 3 3 1956 1955 1985 + 4784 3 3 1927 1955 1956 + 4785 3 3 2014 367 1985 + 4786 3 3 368 1956 1985 + 4787 3 3 369 1956 368 + 4788 3 3 368 1985 367 + 4789 3 3 2013 1985 1984 + 4790 3 3 369 1927 1956 + 4791 3 3 1985 1955 1984 + 4792 3 3 2012 1984 1983 + 4793 3 3 1897 1866 1896 + 4794 3 3 1982 1952 1981 + 4795 3 3 2010 1980 2009 + 4796 3 3 1774 1745 1773 + 4797 3 3 2062 2035 2034 + 4798 3 3 2034 2060 2061 + 4799 3 3 2062 2034 2061 + 4800 3 3 2036 2006 2035 + 4801 3 3 2036 2062 2063 + 4802 3 3 2036 2035 2062 + 4803 3 3 2090 2063 2062 + 4804 3 3 2037 2036 2063 + 4805 3 3 2089 2062 2061 + 4806 3 3 2037 2008 2036 + 4807 3 3 2088 2110 2111 + 4808 3 3 2111 2110 2133 + 4809 3 3 2134 2112 2111 + 4810 3 3 2089 2088 2111 + 4811 3 3 2113 2090 2089 + 4812 3 3 2089 2111 2112 + 4813 3 3 2113 2089 2112 + 4814 3 3 2090 2062 2089 + 4815 3 3 2135 2113 2112 + 4816 3 3 2089 2061 2088 + 4817 3 3 2005 2033 2034 + 4818 3 3 2091 2063 2090 + 4819 3 3 2037 2064 2038 + 4820 3 3 2037 2063 2064 + 4821 3 3 2065 2038 2064 + 4822 3 3 2039 2009 2038 + 4823 3 3 2010 2009 2039 + 4824 3 3 2066 2039 2038 + 4825 3 3 2066 2038 2065 + 4826 3 3 2011 2010 2039 + 4827 3 3 2091 2065 2064 + 4828 3 3 2038 2009 2037 + 4829 3 3 2091 2113 2114 + 4830 3 3 2064 2063 2091 + 4831 3 3 2135 2114 2113 + 4832 3 3 2115 2091 2114 + 4833 3 3 2093 2065 2092 + 4834 3 3 2093 2066 2065 + 4835 3 3 2092 2091 2115 + 4836 3 3 2116 2092 2115 + 4837 3 3 2137 2115 2114 + 4838 3 3 2092 2065 2091 + 4839 3 3 2091 2090 2113 + 4840 3 3 2040 2039 2066 + 4841 3 3 2134 2111 2133 + 4842 3 3 2035 2005 2034 + 4843 3 3 2155 2134 2154 + 4844 3 3 2134 2133 2154 + 4845 3 3 2154 2174 2175 + 4846 3 3 2155 2154 2175 + 4847 3 3 2135 2155 2156 + 4848 3 3 2135 2134 2155 + 4849 3 3 2177 2156 2155 + 4850 3 3 2136 2135 2156 + 4851 3 3 2176 2155 2175 + 4852 3 3 2135 2112 2134 + 4853 3 3 2197 2176 2196 + 4854 3 3 2176 2175 2196 + 4855 3 3 2175 2174 2196 + 4856 3 3 2217 2196 2216 + 4857 3 3 2198 2177 2197 + 4858 3 3 2177 2176 2197 + 4859 3 3 2197 2196 2217 + 4860 3 3 2198 2197 2217 + 4861 3 3 2239 2218 2217 + 4862 3 3 2177 2155 2176 + 4863 3 3 2133 2153 2154 + 4864 3 3 2157 2156 2177 + 4865 3 3 2158 2136 2157 + 4866 3 3 2136 2156 2157 + 4867 3 3 2157 2177 2178 + 4868 3 3 2158 2157 2178 + 4869 3 3 2159 2137 2158 + 4870 3 3 2137 2136 2158 + 4871 3 3 2158 2178 2179 + 4872 3 3 2138 2115 2137 + 4873 3 3 2200 2179 2178 + 4874 3 3 2137 2114 2136 + 4875 3 3 2219 2199 2198 + 4876 3 3 2198 2217 2218 + 4877 3 3 2219 2198 2218 + 4878 3 3 2178 2177 2199 + 4879 3 3 2200 2199 2220 + 4880 3 3 2220 2199 2219 + 4881 3 3 2241 2221 2220 + 4882 3 3 2180 2179 2200 + 4883 3 3 2240 2219 2218 + 4884 3 3 2200 2178 2199 + 4885 3 3 2199 2177 2198 + 4886 3 3 2159 2158 2179 + 4887 3 3 2237 2217 2216 + 4888 3 3 2136 2114 2135 + 4889 3 3 2196 2195 2216 + 4890 3 3 2201 2200 2220 + 4891 3 3 2040 2066 2067 + 4892 3 3 2011 2039 2040 + 4893 3 3 2068 2040 2067 + 4894 3 3 2012 2011 2040 + 4895 3 3 2012 2040 2041 + 4896 3 3 2041 2040 2068 + 4897 3 3 2069 2041 2068 + 4898 3 3 2013 2012 2041 + 4899 3 3 2095 2068 2067 + 4900 3 3 2013 1984 2012 + 4901 3 3 2093 2116 2094 + 4902 3 3 2093 2092 2116 + 4903 3 3 2117 2094 2116 + 4904 3 3 2095 2067 2094 + 4905 3 3 2095 2117 2118 + 4906 3 3 2095 2094 2117 + 4907 3 3 2140 2118 2117 + 4908 3 3 2069 2068 2095 + 4909 3 3 2139 2117 2116 + 4910 3 3 2094 2067 2093 + 4911 3 3 2067 2066 2093 + 4912 3 3 2096 2095 2118 + 4913 3 3 2013 2042 2014 + 4914 3 3 2013 2041 2042 + 4915 3 3 2043 2014 2042 + 4916 3 3 2014 1985 2013 + 4917 3 3 366 2043 365 + 4918 3 3 366 2014 2043 + 4919 3 3 2070 365 2043 + 4920 3 3 2069 2043 2042 + 4921 3 3 366 367 2014 + 4922 3 3 2069 2095 2096 + 4923 3 3 2096 2118 2119 + 4924 3 3 363 2096 2119 + 4925 3 3 364 2069 2096 + 4926 3 3 2070 2069 364 + 4927 3 3 364 2096 363 + 4928 3 3 364 365 2070 + 4929 3 3 362 363 2119 + 4930 3 3 2070 2043 2069 + 4931 3 3 2042 2041 2069 + 4932 3 3 2141 2119 2118 + 4933 3 3 2012 1983 2011 + 4934 3 3 2138 2159 2139 + 4935 3 3 2116 2115 2138 + 4936 3 3 2160 2139 2159 + 4937 3 3 2140 2117 2139 + 4938 3 3 2140 2139 2161 + 4939 3 3 2161 2139 2160 + 4940 3 3 2182 2161 2160 + 4941 3 3 2162 2140 2161 + 4942 3 3 2180 2160 2159 + 4943 3 3 2141 2118 2140 + 4944 3 3 2180 2200 2201 + 4945 3 3 2159 2179 2180 + 4946 3 3 2202 2201 2221 + 4947 3 3 2181 2180 2201 + 4948 3 3 2203 2181 2202 + 4949 3 3 2181 2201 2202 + 4950 3 3 2202 2221 2222 + 4951 3 3 2182 2160 2181 + 4952 3 3 2244 2223 2222 + 4953 3 3 2181 2160 2180 + 4954 3 3 2201 2220 2221 + 4955 3 3 2223 2202 2222 + 4956 3 3 2141 2140 2162 + 4957 3 3 360 2161 2182 + 4958 3 3 2162 2161 360 + 4959 3 3 361 2141 2162 + 4960 3 3 362 2141 361 + 4961 3 3 361 2162 360 + 4962 3 3 2183 360 2182 + 4963 3 3 362 2119 2141 + 4964 3 3 358 2203 2223 + 4965 3 3 2182 2181 2203 + 4966 3 3 2244 357 2223 + 4967 3 3 358 2223 357 + 4968 3 3 2183 2182 359 + 4969 3 3 359 2203 358 + 4970 3 3 359 360 2183 + 4971 3 3 359 2182 2203 + 4972 3 3 2203 2202 2223 + 4973 3 3 2243 2222 2221 + 4974 3 3 2139 2116 2138 + 4975 3 3 2138 2137 2159 + 4976 3 3 2240 2220 2219 + 4977 3 3 2011 1982 2010 + 4978 3 3 2061 2060 2088 + 4979 3 3 2234 2213 2233 + 4980 3 3 1772 1743 1771 + 4981 3 3 2248 2247 2270 + 4982 3 3 2227 2226 2248 + 4983 3 3 2249 2270 2271 + 4984 3 3 2249 2248 2270 + 4985 3 3 2293 2271 2270 + 4986 3 3 2250 2249 2271 + 4987 3 3 2270 2269 2292 + 4988 3 3 2250 2229 2249 + 4989 3 3 2314 2292 2313 + 4990 3 3 2292 2291 2313 + 4991 3 3 2291 2312 2313 + 4992 3 3 2337 2313 2336 + 4993 3 3 2315 2293 2314 + 4994 3 3 2293 2292 2314 + 4995 3 3 2314 2313 2337 + 4996 3 3 2338 2314 2337 + 4997 3 3 2360 2338 2337 + 4998 3 3 2293 2270 2292 + 4999 3 3 2313 2335 2336 + 5000 3 3 2272 2271 2293 + 5001 3 3 2251 2250 2272 + 5002 3 3 2250 2271 2272 + 5003 3 3 2272 2293 2294 + 5004 3 3 2273 2272 2294 + 5005 3 3 2251 2272 2273 + 5006 3 3 2273 2294 2295 + 5007 3 3 2296 2273 2295 + 5008 3 3 2274 2251 2273 + 5009 3 3 2317 2295 2294 + 5010 3 3 2251 2230 2250 + 5011 3 3 2339 2316 2315 + 5012 3 3 2315 2314 2338 + 5013 3 3 2339 2315 2338 + 5014 3 3 2316 2294 2315 + 5015 3 3 2317 2316 2340 + 5016 3 3 2340 2316 2339 + 5017 3 3 2362 2340 2339 + 5018 3 3 2318 2317 2340 + 5019 3 3 2361 2339 2338 + 5020 3 3 2317 2294 2316 + 5021 3 3 2294 2293 2315 + 5022 3 3 2296 2295 2317 + 5023 3 3 2360 2337 2336 + 5024 3 3 2252 2230 2251 + 5025 3 3 2360 2359 2382 + 5026 3 3 2336 2358 2359 + 5027 3 3 2382 2381 2405 + 5028 3 3 2383 2382 2405 + 5029 3 3 2360 2382 2383 + 5030 3 3 2383 2405 2406 + 5031 3 3 2407 2383 2406 + 5032 3 3 2361 2360 2383 + 5033 3 3 2433 2406 2405 + 5034 3 3 2360 2336 2359 + 5035 3 3 2433 2482 2483 + 5036 3 3 2405 2404 2433 + 5037 3 3 2541 2483 2540 + 5038 3 3 2484 2433 2483 + 5039 3 3 2485 2434 2484 + 5040 3 3 2434 2433 2484 + 5041 3 3 2484 2483 2541 + 5042 3 3 2407 2406 2434 + 5043 3 3 2598 2542 2541 + 5044 3 3 2434 2406 2433 + 5045 3 3 2483 2539 2540 + 5046 3 3 2485 2484 2541 + 5047 3 3 2384 2383 2407 + 5048 3 3 2361 2383 2384 + 5049 3 3 2408 2385 2384 + 5050 3 3 2362 2361 2384 + 5051 3 3 2362 2385 2363 + 5052 3 3 2362 2384 2385 + 5053 3 3 2386 2363 2385 + 5054 3 3 2363 2340 2362 + 5055 3 3 2408 2384 2407 + 5056 3 3 2362 2339 2361 + 5057 3 3 2435 2434 2485 + 5058 3 3 2485 2541 2542 + 5059 3 3 2486 2485 2542 + 5060 3 3 2486 2435 2485 + 5061 3 3 2408 2407 2436 + 5062 3 3 2436 2435 2486 + 5063 3 3 2409 2408 2436 + 5064 3 3 2409 2385 2408 + 5065 3 3 2543 2487 2486 + 5066 3 3 2436 2407 2435 + 5067 3 3 2407 2434 2435 + 5068 3 3 2487 2436 2486 + 5069 3 3 2598 2541 2540 + 5070 3 3 2361 2338 2360 + 5071 3 3 2359 2381 2382 + 5072 3 3 2364 2340 2363 + 5073 3 3 2252 2274 2253 + 5074 3 3 2274 2273 2296 + 5075 3 3 2275 2253 2274 + 5076 3 3 2254 2232 2253 + 5077 3 3 2254 2275 2276 + 5078 3 3 2254 2253 2275 + 5079 3 3 2298 2276 2275 + 5080 3 3 2255 2254 2276 + 5081 3 3 2297 2275 2274 + 5082 3 3 2234 2233 2254 + 5083 3 3 2318 2340 2341 + 5084 3 3 2296 2317 2318 + 5085 3 3 2342 2318 2341 + 5086 3 3 2297 2296 2318 + 5087 3 3 2320 2297 2319 + 5088 3 3 2297 2318 2319 + 5089 3 3 2319 2318 2342 + 5090 3 3 2298 2275 2297 + 5091 3 3 2365 2343 2342 + 5092 3 3 2297 2274 2296 + 5093 3 3 2252 2251 2274 + 5094 3 3 2343 2319 2342 + 5095 3 3 2255 2276 2277 + 5096 3 3 2234 2254 2255 + 5097 3 3 2278 2255 2277 + 5098 3 3 2235 2234 2255 + 5099 3 3 2236 2235 2256 + 5100 3 3 2235 2255 2256 + 5101 3 3 2256 2255 2278 + 5102 3 3 2257 2256 2278 + 5103 3 3 2300 2278 2277 + 5104 3 3 2235 2213 2234 + 5105 3 3 2321 2298 2320 + 5106 3 3 2298 2297 2320 + 5107 3 3 2320 2319 2343 + 5108 3 3 2344 2320 2343 + 5109 3 3 2300 2299 2321 + 5110 3 3 2299 2298 2321 + 5111 3 3 2321 2320 2344 + 5112 3 3 2300 2277 2299 + 5113 3 3 2366 2344 2343 + 5114 3 3 2299 2277 2298 + 5115 3 3 2277 2276 2298 + 5116 3 3 2322 2321 2344 + 5117 3 3 2364 2342 2341 + 5118 3 3 2253 2232 2252 + 5119 3 3 2387 2364 2386 + 5120 3 3 2341 2340 2364 + 5121 3 3 2386 2385 2409 + 5122 3 3 2387 2386 2409 + 5123 3 3 2365 2387 2388 + 5124 3 3 2365 2364 2387 + 5125 3 3 2411 2388 2387 + 5126 3 3 2389 2365 2388 + 5127 3 3 2410 2387 2409 + 5128 3 3 2366 2343 2365 + 5129 3 3 2410 2409 2438 + 5130 3 3 2438 2409 2437 + 5131 3 3 2437 2436 2487 + 5132 3 3 2438 2437 2487 + 5133 3 3 2439 2410 2438 + 5134 3 3 2439 2411 2410 + 5135 3 3 2438 2487 2488 + 5136 3 3 2439 2438 2488 + 5137 3 3 2544 2488 2487 + 5138 3 3 2411 2387 2410 + 5139 3 3 2409 2436 2437 + 5140 3 3 2412 2388 2411 + 5141 3 3 2367 2366 2389 + 5142 3 3 2366 2365 2389 + 5143 3 3 2389 2388 2412 + 5144 3 3 2390 2389 2412 + 5145 3 3 2367 2389 2390 + 5146 3 3 2390 2412 2413 + 5147 3 3 2414 2390 2413 + 5148 3 3 2345 2344 2367 + 5149 3 3 2440 2413 2412 + 5150 3 3 2367 2344 2366 + 5151 3 3 2490 2440 2439 + 5152 3 3 2439 2488 2489 + 5153 3 3 2490 2439 2489 + 5154 3 3 2441 2413 2440 + 5155 3 3 2441 2490 2491 + 5156 3 3 2441 2440 2490 + 5157 3 3 2546 2490 2489 + 5158 3 3 2414 2413 2441 + 5159 3 3 2547 2491 2490 + 5160 3 3 2440 2412 2439 + 5161 3 3 2412 2411 2439 + 5162 3 3 2368 2367 2390 + 5163 3 3 2545 2489 2488 + 5164 3 3 2365 2342 2364 + 5165 3 3 2364 2363 2386 + 5166 3 3 2442 2441 2491 + 5167 3 3 2543 2486 2542 + 5168 3 3 2249 2228 2248 + 5169 3 3 2655 2598 2597 + 5170 3 3 2540 2539 2597 + 5171 3 3 2655 2597 2654 + 5172 3 3 2599 2542 2598 + 5173 3 3 2599 2598 2656 + 5174 3 3 2656 2598 2655 + 5175 3 3 2711 2656 2655 + 5176 3 3 2657 2599 2656 + 5177 3 3 2710 2655 2654 + 5178 3 3 2600 2542 2599 + 5179 3 3 2711 2710 2766 + 5180 3 3 2710 2709 2766 + 5181 3 3 2766 2765 2822 + 5182 3 3 2823 2766 2822 + 5183 3 3 2711 2766 2767 + 5184 3 3 2767 2766 2823 + 5185 3 3 2712 2711 2767 + 5186 3 3 2712 2656 2711 + 5187 3 3 2879 2823 2822 + 5188 3 3 2711 2655 2710 + 5189 3 3 2654 2709 2710 + 5190 3 3 2824 2768 2767 + 5191 3 3 2600 2599 2657 + 5192 3 3 2543 2542 2600 + 5193 3 3 2601 2600 2657 + 5194 3 3 2544 2543 2600 + 5195 3 3 2602 2544 2601 + 5196 3 3 2544 2600 2601 + 5197 3 3 2601 2657 2658 + 5198 3 3 2602 2601 2658 + 5199 3 3 2714 2658 2657 + 5200 3 3 2545 2488 2544 + 5201 3 3 2712 2768 2713 + 5202 3 3 2712 2767 2768 + 5203 3 3 2769 2713 2768 + 5204 3 3 2714 2657 2713 + 5205 3 3 2714 2713 2770 + 5206 3 3 2770 2713 2769 + 5207 3 3 2825 2770 2769 + 5208 3 3 2715 2658 2714 + 5209 3 3 2824 2769 2768 + 5210 3 3 2657 2656 2713 + 5211 3 3 2713 2656 2712 + 5212 3 3 2771 2714 2770 + 5213 3 3 2824 2767 2823 + 5214 3 3 2598 2540 2597 + 5215 3 3 2935 2879 2878 + 5216 3 3 2878 2933 2934 + 5217 3 3 2935 2878 2934 + 5218 3 3 2824 2823 2879 + 5219 3 3 2824 2879 2880 + 5220 3 3 2936 2880 2879 + 5221 3 3 2936 2879 2935 + 5222 3 3 2825 2824 2880 + 5223 3 3 2989 2935 2934 + 5224 3 3 2879 2822 2878 + 5225 3 3 2990 2989 3044 + 5226 3 3 2989 3043 3044 + 5227 3 3 3044 320 321 + 5228 3 3 3045 3044 321 + 5229 3 3 3046 2990 3045 + 5230 3 3 2990 3044 3045 + 5231 3 3 3045 321 322 + 5232 3 3 2936 2935 2990 + 5233 3 3 2990 2935 2989 + 5234 3 3 2822 2821 2878 + 5235 3 3 3046 3045 322 + 5236 3 3 2825 2880 2881 + 5237 3 3 2937 2880 2936 + 5238 3 3 2881 2880 2937 + 5239 3 3 2826 2825 2881 + 5240 3 3 2826 2881 2882 + 5241 3 3 2938 2882 2881 + 5242 3 3 2938 2881 2937 + 5243 3 3 2827 2826 2882 + 5244 3 3 2991 2937 2936 + 5245 3 3 2826 2770 2825 + 5246 3 3 2992 2991 3046 + 5247 3 3 2936 2990 2991 + 5248 3 3 3046 322 323 + 5249 3 3 3047 3046 323 + 5250 3 3 2993 2992 3047 + 5251 3 3 2992 3046 3047 + 5252 3 3 3047 323 324 + 5253 3 3 2993 2937 2992 + 5254 3 3 2992 2937 2991 + 5255 3 3 2991 2990 3046 + 5256 3 3 3048 3047 324 + 5257 3 3 2825 2769 2824 + 5258 3 3 2597 2653 2654 + 5259 3 3 2771 2770 2826 + 5260 3 3 2546 2545 2602 + 5261 3 3 2602 2658 2659 + 5262 3 3 2659 2658 2715 + 5263 3 3 2603 2602 2659 + 5264 3 3 2546 2602 2603 + 5265 3 3 2603 2659 2660 + 5266 3 3 2661 2603 2660 + 5267 3 3 2547 2546 2603 + 5268 3 3 2716 2660 2659 + 5269 3 3 2546 2489 2545 + 5270 3 3 2771 2826 2827 + 5271 3 3 2715 2714 2771 + 5272 3 3 2828 2771 2827 + 5273 3 3 2716 2715 2771 + 5274 3 3 2716 2771 2772 + 5275 3 3 2772 2771 2828 + 5276 3 3 2829 2772 2828 + 5277 3 3 2661 2660 2716 + 5278 3 3 2885 2829 2828 + 5279 3 3 2716 2659 2715 + 5280 3 3 2545 2544 2602 + 5281 3 3 2717 2716 2772 + 5282 3 3 2547 2603 2604 + 5283 3 3 2604 2603 2661 + 5284 3 3 2662 2604 2661 + 5285 3 3 2548 2547 2604 + 5286 3 3 2606 2548 2605 + 5287 3 3 2548 2604 2605 + 5288 3 3 2605 2604 2662 + 5289 3 3 2606 2605 2662 + 5290 3 3 2717 2662 2661 + 5291 3 3 2548 2491 2547 + 5292 3 3 2774 2717 2773 + 5293 3 3 2661 2716 2717 + 5294 3 3 2717 2772 2773 + 5295 3 3 2774 2773 2829 + 5296 3 3 2775 2718 2774 + 5297 3 3 2718 2717 2774 + 5298 3 3 2774 2829 2830 + 5299 3 3 2775 2774 2830 + 5300 3 3 2886 2830 2829 + 5301 3 3 2718 2662 2717 + 5302 3 3 2773 2772 2829 + 5303 3 3 2719 2662 2718 + 5304 3 3 2884 2828 2827 + 5305 3 3 2547 2490 2546 + 5306 3 3 2939 2883 2938 + 5307 3 3 2827 2882 2883 + 5308 3 3 2938 2937 2993 + 5309 3 3 2994 2939 2938 + 5310 3 3 2884 2883 2940 + 5311 3 3 2940 2883 2939 + 5312 3 3 2995 2940 2939 + 5313 3 3 2941 2884 2940 + 5314 3 3 2994 2938 2993 + 5315 3 3 2885 2828 2884 + 5316 3 3 3049 2994 3048 + 5317 3 3 2994 2993 3048 + 5318 3 3 3048 324 325 + 5319 3 3 3049 3048 325 + 5320 3 3 3050 2995 3049 + 5321 3 3 2995 2994 3049 + 5322 3 3 3049 325 326 + 5323 3 3 3050 3049 326 + 5324 3 3 2995 2939 2994 + 5325 3 3 2993 3047 3048 + 5326 3 3 2941 2940 2995 + 5327 3 3 2942 2885 2941 + 5328 3 3 2885 2884 2941 + 5329 3 3 2941 2995 2996 + 5330 3 3 2942 2941 2996 + 5331 3 3 2887 2886 2942 + 5332 3 3 2886 2885 2942 + 5333 3 3 2942 2996 2997 + 5334 3 3 2943 2942 2997 + 5335 3 3 3052 2997 2996 + 5336 3 3 2886 2829 2885 + 5337 3 3 3050 327 3051 + 5338 3 3 3050 326 327 + 5339 3 3 328 3051 327 + 5340 3 3 3051 2996 3050 + 5341 3 3 3052 328 329 + 5342 3 3 3052 3051 328 + 5343 3 3 2998 2997 3052 + 5344 3 3 3052 2996 3051 + 5345 3 3 2996 2995 3050 + 5346 3 3 2831 2830 2886 + 5347 3 3 2884 2827 2883 + 5348 3 3 2883 2882 2938 + 5349 3 3 2549 2491 2548 + 5350 3 3 2544 2487 2543 + 5351 3 3 2934 2933 2989 + 5352 3 3 3053 3052 329 + 5353 3 3 2257 2278 2279 + 5354 3 3 2236 2256 2257 + 5355 3 3 2258 2257 2279 + 5356 3 3 2258 2236 2257 + 5357 3 3 2237 2236 2258 + 5358 3 3 2258 2279 2280 + 5359 3 3 2281 2258 2280 + 5360 3 3 2259 2237 2258 + 5361 3 3 2301 2280 2279 + 5362 3 3 2237 2215 2236 + 5363 3 3 2300 2321 2322 + 5364 3 3 2322 2344 2345 + 5365 3 3 2323 2322 2345 + 5366 3 3 2301 2300 2322 + 5367 3 3 2324 2302 2301 + 5368 3 3 2301 2322 2323 + 5369 3 3 2324 2301 2323 + 5370 3 3 2302 2280 2301 + 5371 3 3 2346 2324 2323 + 5372 3 3 2279 2278 2301 + 5373 3 3 2301 2278 2300 + 5374 3 3 2281 2280 2302 + 5375 3 3 2259 2258 2281 + 5376 3 3 2238 2237 2259 + 5377 3 3 2260 2259 2281 + 5378 3 3 2260 2238 2259 + 5379 3 3 2261 2240 2239 + 5380 3 3 2239 2238 2260 + 5381 3 3 2261 2239 2260 + 5382 3 3 2240 2218 2239 + 5383 3 3 2282 2260 2281 + 5384 3 3 2239 2217 2238 + 5385 3 3 2303 2324 2325 + 5386 3 3 2304 2281 2303 + 5387 3 3 2348 2325 2324 + 5388 3 3 2326 2303 2325 + 5389 3 3 2282 2281 2304 + 5390 3 3 2304 2303 2326 + 5391 3 3 2283 2282 2304 + 5392 3 3 2261 2260 2282 + 5393 3 3 2348 2326 2325 + 5394 3 3 2281 2302 2303 + 5395 3 3 2303 2302 2324 + 5396 3 3 2327 2304 2326 + 5397 3 3 2346 2323 2345 + 5398 3 3 2238 2217 2237 + 5399 3 3 2346 2345 2369 + 5400 3 3 2369 2345 2368 + 5401 3 3 2368 2390 2391 + 5402 3 3 2369 2368 2391 + 5403 3 3 2347 2346 2370 + 5404 3 3 2370 2346 2369 + 5405 3 3 2392 2370 2369 + 5406 3 3 2371 2347 2370 + 5407 3 3 2392 2369 2391 + 5408 3 3 2348 2324 2347 + 5409 3 3 2392 2391 2415 + 5410 3 3 2415 2391 2414 + 5411 3 3 2345 2367 2368 + 5412 3 3 2443 2414 2442 + 5413 3 3 2416 2393 2415 + 5414 3 3 2393 2392 2415 + 5415 3 3 2415 2414 2443 + 5416 3 3 2444 2415 2443 + 5417 3 3 2492 2443 2442 + 5418 3 3 2393 2370 2392 + 5419 3 3 2391 2390 2414 + 5420 3 3 2394 2370 2393 + 5421 3 3 2371 2370 2394 + 5422 3 3 2348 2347 2371 + 5423 3 3 2372 2371 2394 + 5424 3 3 2372 2348 2371 + 5425 3 3 2350 2349 2372 + 5426 3 3 2349 2348 2372 + 5427 3 3 2372 2394 2395 + 5428 3 3 2396 2372 2395 + 5429 3 3 2417 2395 2394 + 5430 3 3 2349 2326 2348 + 5431 3 3 2416 2444 2417 + 5432 3 3 2416 2415 2444 + 5433 3 3 2445 2417 2444 + 5434 3 3 2394 2393 2417 + 5435 3 3 2418 2417 2446 + 5436 3 3 2446 2417 2445 + 5437 3 3 2497 2447 2446 + 5438 3 3 2396 2395 2418 + 5439 3 3 2494 2445 2444 + 5440 3 3 2418 2395 2417 + 5441 3 3 2417 2393 2416 + 5442 3 3 2350 2326 2349 + 5443 3 3 2496 2446 2445 + 5444 3 3 2347 2324 2346 + 5445 3 3 2414 2441 2442 + 5446 3 3 2419 2418 2446 + 5447 3 3 2262 2241 2261 + 5448 3 3 2241 2240 2261 + 5449 3 3 2261 2282 2283 + 5450 3 3 2262 2261 2283 + 5451 3 3 2242 2262 2263 + 5452 3 3 2242 2241 2262 + 5453 3 3 2284 2263 2262 + 5454 3 3 2264 2242 2263 + 5455 3 3 2284 2262 2283 + 5456 3 3 2243 2221 2242 + 5457 3 3 2284 2283 2306 + 5458 3 3 2306 2283 2305 + 5459 3 3 2283 2304 2305 + 5460 3 3 2306 2305 2327 + 5461 3 3 2307 2284 2306 + 5462 3 3 2307 2285 2284 + 5463 3 3 2306 2327 2328 + 5464 3 3 2307 2306 2328 + 5465 3 3 2351 2328 2327 + 5466 3 3 2285 2263 2284 + 5467 3 3 2305 2304 2327 + 5468 3 3 2264 2263 2285 + 5469 3 3 2243 2264 2244 + 5470 3 3 2243 2242 2264 + 5471 3 3 2265 2244 2264 + 5472 3 3 2244 2222 2243 + 5473 3 3 356 2265 355 + 5474 3 3 356 2244 2265 + 5475 3 3 2265 2264 355 + 5476 3 3 2286 355 2264 + 5477 3 3 356 357 2244 + 5478 3 3 2286 2285 2308 + 5479 3 3 2264 2285 2286 + 5480 3 3 2329 2308 2307 + 5481 3 3 354 2286 2308 + 5482 3 3 2287 2286 354 + 5483 3 3 354 2308 353 + 5484 3 3 354 355 2287 + 5485 3 3 2330 353 2308 + 5486 3 3 2287 355 2286 + 5487 3 3 2308 2285 2307 + 5488 3 3 2329 2307 2328 + 5489 3 3 2242 2221 2241 + 5490 3 3 2350 2373 2351 + 5491 3 3 2350 2372 2373 + 5492 3 3 2374 2351 2373 + 5493 3 3 2329 2328 2351 + 5494 3 3 2329 2351 2352 + 5495 3 3 2352 2351 2374 + 5496 3 3 2375 2352 2374 + 5497 3 3 2330 2329 2352 + 5498 3 3 2397 2374 2373 + 5499 3 3 2351 2327 2350 + 5500 3 3 2397 2396 2419 + 5501 3 3 2396 2418 2419 + 5502 3 3 2419 2446 2447 + 5503 3 3 2420 2419 2447 + 5504 3 3 2397 2419 2420 + 5505 3 3 2420 2447 2448 + 5506 3 3 2398 2397 2420 + 5507 3 3 2375 2374 2397 + 5508 3 3 2498 2448 2447 + 5509 3 3 2397 2373 2396 + 5510 3 3 2373 2372 2396 + 5511 3 3 2421 2420 2448 + 5512 3 3 2330 2352 2353 + 5513 3 3 2376 2352 2375 + 5514 3 3 2353 2352 2376 + 5515 3 3 352 2330 2353 + 5516 3 3 352 2353 351 + 5517 3 3 351 2353 2376 + 5518 3 3 350 351 2376 + 5519 3 3 2399 2376 2375 + 5520 3 3 352 353 2330 + 5521 3 3 349 2398 2421 + 5522 3 3 2375 2397 2398 + 5523 3 3 2449 348 2421 + 5524 3 3 349 2421 348 + 5525 3 3 350 2399 349 + 5526 3 3 350 2376 2399 + 5527 3 3 2399 2398 349 + 5528 3 3 2399 2375 2398 + 5529 3 3 2398 2420 2421 + 5530 3 3 2449 2421 2448 + 5531 3 3 2330 2308 2329 + 5532 3 3 2327 2326 2350 + 5533 3 3 2493 2444 2443 + 5534 3 3 2241 2220 2240 + 5535 3 3 2550 2492 2549 + 5536 3 3 2442 2491 2492 + 5537 3 3 2492 2491 2549 + 5538 3 3 2607 2549 2606 + 5539 3 3 2493 2492 2550 + 5540 3 3 2550 2549 2607 + 5541 3 3 2551 2550 2607 + 5542 3 3 2551 2493 2550 + 5543 3 3 2663 2607 2606 + 5544 3 3 2494 2444 2493 + 5545 3 3 2663 2662 2719 + 5546 3 3 2719 2718 2775 + 5547 3 3 2776 2719 2775 + 5548 3 3 2720 2663 2719 + 5549 3 3 2721 2664 2720 + 5550 3 3 2664 2663 2720 + 5551 3 3 2720 2719 2776 + 5552 3 3 2777 2720 2776 + 5553 3 3 2831 2776 2775 + 5554 3 3 2664 2607 2663 + 5555 3 3 2606 2662 2663 + 5556 3 3 2665 2607 2664 + 5557 3 3 2495 2494 2551 + 5558 3 3 2494 2493 2551 + 5559 3 3 2551 2607 2608 + 5560 3 3 2552 2551 2608 + 5561 3 3 2495 2551 2552 + 5562 3 3 2552 2608 2609 + 5563 3 3 2610 2552 2609 + 5564 3 3 2553 2495 2552 + 5565 3 3 2666 2609 2608 + 5566 3 3 2496 2445 2495 + 5567 3 3 2666 2665 2721 + 5568 3 3 2665 2664 2721 + 5569 3 3 2721 2720 2777 + 5570 3 3 2722 2721 2777 + 5571 3 3 2666 2721 2722 + 5572 3 3 2722 2777 2778 + 5573 3 3 2723 2722 2778 + 5574 3 3 2610 2609 2666 + 5575 3 3 2833 2778 2777 + 5576 3 3 2666 2608 2665 + 5577 3 3 2608 2607 2665 + 5578 3 3 2667 2666 2722 + 5579 3 3 2833 2777 2776 + 5580 3 3 2495 2445 2494 + 5581 3 3 2831 2886 2887 + 5582 3 3 2549 2548 2606 + 5583 3 3 2944 2887 2943 + 5584 3 3 2832 2831 2887 + 5585 3 3 2832 2887 2888 + 5586 3 3 2888 2887 2944 + 5587 3 3 2889 2888 2944 + 5588 3 3 2889 2832 2888 + 5589 3 3 2999 2944 2943 + 5590 3 3 2833 2776 2832 + 5591 3 3 3054 2998 3053 + 5592 3 3 2943 2997 2998 + 5593 3 3 3053 329 330 + 5594 3 3 3054 3053 330 + 5595 3 3 3055 2999 3054 + 5596 3 3 2999 2998 3054 + 5597 3 3 3054 330 331 + 5598 3 3 3000 2944 2999 + 5599 3 3 2999 2943 2998 + 5600 3 3 2998 3052 3053 + 5601 3 3 3055 3054 331 + 5602 3 3 2833 2832 2889 + 5603 3 3 2889 2944 2945 + 5604 3 3 2890 2889 2945 + 5605 3 3 2834 2833 2889 + 5606 3 3 2834 2889 2890 + 5607 3 3 2890 2945 2946 + 5608 3 3 2947 2890 2946 + 5609 3 3 2891 2834 2890 + 5610 3 3 3000 2946 2945 + 5611 3 3 2834 2778 2833 + 5612 3 3 3001 3000 3055 + 5613 3 3 2945 2944 3000 + 5614 3 3 3055 331 332 + 5615 3 3 3056 3055 332 + 5616 3 3 3057 3001 3056 + 5617 3 3 3001 3055 3056 + 5618 3 3 3056 332 333 + 5619 3 3 3002 2946 3001 + 5620 3 3 3001 2946 3000 + 5621 3 3 3000 2999 3055 + 5622 3 3 2835 2778 2834 + 5623 3 3 2832 2776 2831 + 5624 3 3 2775 2830 2831 + 5625 3 3 3057 3056 333 + 5626 3 3 2496 2553 2497 + 5627 3 3 2496 2495 2553 + 5628 3 3 2554 2497 2553 + 5629 3 3 2498 2447 2497 + 5630 3 3 2498 2497 2555 + 5631 3 3 2555 2497 2554 + 5632 3 3 2612 2555 2554 + 5633 3 3 2499 2498 2555 + 5634 3 3 2610 2554 2553 + 5635 3 3 2449 2448 2498 + 5636 3 3 2668 2610 2667 + 5637 3 3 2553 2552 2610 + 5638 3 3 2667 2722 2723 + 5639 3 3 2724 2667 2723 + 5640 3 3 2611 2610 2668 + 5641 3 3 2668 2667 2724 + 5642 3 3 2612 2611 2668 + 5643 3 3 2612 2554 2611 + 5644 3 3 2779 2724 2723 + 5645 3 3 2611 2554 2610 + 5646 3 3 2610 2666 2667 + 5647 3 3 2725 2669 2668 + 5648 3 3 2499 2555 2556 + 5649 3 3 2449 2498 2499 + 5650 3 3 346 2499 2556 + 5651 3 3 347 2449 2499 + 5652 3 3 347 2499 346 + 5653 3 3 346 2556 345 + 5654 3 3 344 345 2556 + 5655 3 3 347 348 2449 + 5656 3 3 343 2612 2669 + 5657 3 3 2612 2668 2669 + 5658 3 3 2725 342 2669 + 5659 3 3 343 2669 342 + 5660 3 3 344 2613 343 + 5661 3 3 344 2556 2613 + 5662 3 3 2613 2612 343 + 5663 3 3 2613 2556 2612 + 5664 3 3 2556 2555 2612 + 5665 3 3 2725 2668 2724 + 5666 3 3 2497 2446 2496 + 5667 3 3 2836 2779 2835 + 5668 3 3 2723 2778 2779 + 5669 3 3 2779 2778 2835 + 5670 3 3 2836 2835 2891 + 5671 3 3 2780 2779 2836 + 5672 3 3 2836 2891 2892 + 5673 3 3 2893 2836 2892 + 5674 3 3 2837 2780 2836 + 5675 3 3 2947 2892 2891 + 5676 3 3 2725 2724 2780 + 5677 3 3 2948 2947 3002 + 5678 3 3 2891 2890 2947 + 5679 3 3 2947 2946 3002 + 5680 3 3 3003 3002 3057 + 5681 3 3 2948 3002 3003 + 5682 3 3 3058 3003 3057 + 5683 3 3 3058 3057 334 + 5684 3 3 338 2892 2948 + 5685 3 3 3057 333 334 + 5686 3 3 2948 2892 2947 + 5687 3 3 2835 2834 2891 + 5688 3 3 337 2948 3003 + 5689 3 3 2781 2780 2837 + 5690 3 3 2725 2780 2781 + 5691 3 3 340 2781 2837 + 5692 3 3 341 2725 2781 + 5693 3 3 341 2781 340 + 5694 3 3 340 2837 339 + 5695 3 3 2893 339 2837 + 5696 3 3 341 342 2725 + 5697 3 3 336 3058 335 + 5698 3 3 337 3003 336 + 5699 3 3 3058 334 335 + 5700 3 3 2893 2892 338 + 5701 3 3 338 2948 337 + 5702 3 3 338 339 2893 + 5703 3 3 2837 2836 2893 + 5704 3 3 336 3003 3058 + 5705 3 3 2780 2724 2779 + 5706 3 3 3002 3001 3057 + 5707 3 3 2493 2443 2492 + 5708 3 3 2887 2942 2943 + 5709 3 3 2236 2214 2235 + 5710 3 3 2292 2269 2291 +ENDOFSECTION +ELEMENT GROUP +GROUP: 1 ELEMENTS: 5710 MATERIAL: 1 NFLAGS: 1 +fluid +0 + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + 251 252 253 254 255 256 257 258 259 260 + 261 262 263 264 265 266 267 268 269 270 + 271 272 273 274 275 276 277 278 279 280 + 281 282 283 284 285 286 287 288 289 290 + 291 292 293 294 295 296 297 298 299 300 + 301 302 303 304 305 306 307 308 309 310 + 311 312 313 314 315 316 317 318 319 320 + 321 322 323 324 325 326 327 328 329 330 + 331 332 333 334 335 336 337 338 339 340 + 341 342 343 344 345 346 347 348 349 350 + 351 352 353 354 355 356 357 358 359 360 + 361 362 363 364 365 366 367 368 369 370 + 371 372 373 374 375 376 377 378 379 380 + 381 382 383 384 385 386 387 388 389 390 + 391 392 393 394 395 396 397 398 399 400 + 401 402 403 404 405 406 407 408 409 410 + 411 412 413 414 415 416 417 418 419 420 + 421 422 423 424 425 426 427 428 429 430 + 431 432 433 434 435 436 437 438 439 440 + 441 442 443 444 445 446 447 448 449 450 + 451 452 453 454 455 456 457 458 459 460 + 461 462 463 464 465 466 467 468 469 470 + 471 472 473 474 475 476 477 478 479 480 + 481 482 483 484 485 486 487 488 489 490 + 491 492 493 494 495 496 497 498 499 500 + 501 502 503 504 505 506 507 508 509 510 + 511 512 513 514 515 516 517 518 519 520 + 521 522 523 524 525 526 527 528 529 530 + 531 532 533 534 535 536 537 538 539 540 + 541 542 543 544 545 546 547 548 549 550 + 551 552 553 554 555 556 557 558 559 560 + 561 562 563 564 565 566 567 568 569 570 + 571 572 573 574 575 576 577 578 579 580 + 581 582 583 584 585 586 587 588 589 590 + 591 592 593 594 595 596 597 598 599 600 + 601 602 603 604 605 606 607 608 609 610 + 611 612 613 614 615 616 617 618 619 620 + 621 622 623 624 625 626 627 628 629 630 + 631 632 633 634 635 636 637 638 639 640 + 641 642 643 644 645 646 647 648 649 650 + 651 652 653 654 655 656 657 658 659 660 + 661 662 663 664 665 666 667 668 669 670 + 671 672 673 674 675 676 677 678 679 680 + 681 682 683 684 685 686 687 688 689 690 + 691 692 693 694 695 696 697 698 699 700 + 701 702 703 704 705 706 707 708 709 710 + 711 712 713 714 715 716 717 718 719 720 + 721 722 723 724 725 726 727 728 729 730 + 731 732 733 734 735 736 737 738 739 740 + 741 742 743 744 745 746 747 748 749 750 + 751 752 753 754 755 756 757 758 759 760 + 761 762 763 764 765 766 767 768 769 770 + 771 772 773 774 775 776 777 778 779 780 + 781 782 783 784 785 786 787 788 789 790 + 791 792 793 794 795 796 797 798 799 800 + 801 802 803 804 805 806 807 808 809 810 + 811 812 813 814 815 816 817 818 819 820 + 821 822 823 824 825 826 827 828 829 830 + 831 832 833 834 835 836 837 838 839 840 + 841 842 843 844 845 846 847 848 849 850 + 851 852 853 854 855 856 857 858 859 860 + 861 862 863 864 865 866 867 868 869 870 + 871 872 873 874 875 876 877 878 879 880 + 881 882 883 884 885 886 887 888 889 890 + 891 892 893 894 895 896 897 898 899 900 + 901 902 903 904 905 906 907 908 909 910 + 911 912 913 914 915 916 917 918 919 920 + 921 922 923 924 925 926 927 928 929 930 + 931 932 933 934 935 936 937 938 939 940 + 941 942 943 944 945 946 947 948 949 950 + 951 952 953 954 955 956 957 958 959 960 + 961 962 963 964 965 966 967 968 969 970 + 971 972 973 974 975 976 977 978 979 980 + 981 982 983 984 985 986 987 988 989 990 + 991 992 993 994 995 996 997 998 999 1000 + 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 + 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 + 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 + 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 + 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 + 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 + 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 + 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 + 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 + 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 + 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 + 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 + 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 + 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 + 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 + 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 + 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 + 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 + 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 + 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 + 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 + 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 + 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 + 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 + 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 + 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 + 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 + 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 + 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 + 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 + 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 + 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 + 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 + 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 + 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 + 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 + 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 + 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 + 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 + 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 + 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 + 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 + 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 + 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 + 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 + 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 + 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 + 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 + 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 + 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 + 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 + 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 + 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 + 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 + 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 + 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 + 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 + 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 + 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 + 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 + 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 + 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 + 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 + 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 + 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 + 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 + 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 + 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 + 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 + 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 + 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 + 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 + 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 + 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 + 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 + 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 + 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 + 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 + 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 + 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 + 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 + 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 + 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 + 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 + 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 + 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 + 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 + 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 + 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 + 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 + 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 + 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 + 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 + 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 + 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 + 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 + 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 + 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 + 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 + 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 + 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 + 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 + 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 + 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 + 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 + 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 + 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 + 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 + 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 + 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 + 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 + 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 + 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 + 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 + 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 + 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 + 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 + 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 + 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 + 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 + 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 + 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 + 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 + 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 + 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 + 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 + 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 + 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 + 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 + 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 + 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 + 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 + 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 + 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 + 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 + 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 + 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 + 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 + 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 + 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 + 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 + 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 + 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 + 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 + 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 + 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 + 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 + 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 + 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 + 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 + 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 + 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 + 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 + 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 + 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 + 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 + 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 + 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 + 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 + 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 + 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 + 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 + 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 + 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 + 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 + 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 + 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 + 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 + 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 + 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 + 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 + 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 + 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 + 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 + 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 + 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 + 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 + 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 + 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 + 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 + 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 + 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 + 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 + 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 + 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 + 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 + 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 + 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 + 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 + 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 + 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 + 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 + 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 + 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 + 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 + 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 + 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 + 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 + 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 + 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 + 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 + 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 + 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 + 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 + 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 + 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 + 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 + 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 + 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 + 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 + 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 + 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 + 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 + 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 + 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 + 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 + 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 + 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 + 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 + 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 + 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 + 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 + 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 + 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 + 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 + 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 + 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 + 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 + 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 + 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 + 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 + 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 + 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 + 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 + 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 + 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 + 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 + 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 + 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 + 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 + 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 + 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 + 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 + 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 + 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 + 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 + 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 + 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 + 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 + 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 + 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 + 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 + 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 + 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 + 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 + 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 + 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 + 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 + 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 + 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 + 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 + 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 + 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 + 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 + 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 + 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 + 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 + 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 + 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 + 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 + 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 + 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 + 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 + 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 + 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 + 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 + 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 + 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 + 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 + 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 + 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 + 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 + 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 + 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 + 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 + 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 + 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 + 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 + 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 + 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 + 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 + 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 + 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 + 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 + 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 + 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 + 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 + 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 + 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 + 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 + 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 + 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 + 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 + 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 + 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 + 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 + 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 + 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 + 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 + 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 + 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 + 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 + 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 + 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 + 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 + 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 + 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 + 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 + 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 + 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 + 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 + 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 + 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 + 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 + 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 + 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 + 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 + 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 + 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 + 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 + 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 + 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 + 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 + 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 + 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 + 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 + 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 + 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 + 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 + 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 + 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 + 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 + 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 + 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 + 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 + 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 + 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 + 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 + 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 + 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 + 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 + 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 + 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 + 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 + 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 + 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 + 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 + 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 + 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 + 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 + 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 + 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 + 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 + 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 + 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 + 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 + 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 + 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 + 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 + 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 + 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 + 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 + 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 + 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 + 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 + 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 + 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 + 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 + 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 + 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 + 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 + 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 + 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 + 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 + 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 + 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 + 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 + 4871 4872 4873 4874 4875 4876 4877 4878 4879 4880 + 4881 4882 4883 4884 4885 4886 4887 4888 4889 4890 + 4891 4892 4893 4894 4895 4896 4897 4898 4899 4900 + 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 + 4911 4912 4913 4914 4915 4916 4917 4918 4919 4920 + 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 + 4931 4932 4933 4934 4935 4936 4937 4938 4939 4940 + 4941 4942 4943 4944 4945 4946 4947 4948 4949 4950 + 4951 4952 4953 4954 4955 4956 4957 4958 4959 4960 + 4961 4962 4963 4964 4965 4966 4967 4968 4969 4970 + 4971 4972 4973 4974 4975 4976 4977 4978 4979 4980 + 4981 4982 4983 4984 4985 4986 4987 4988 4989 4990 + 4991 4992 4993 4994 4995 4996 4997 4998 4999 5000 + 5001 5002 5003 5004 5005 5006 5007 5008 5009 5010 + 5011 5012 5013 5014 5015 5016 5017 5018 5019 5020 + 5021 5022 5023 5024 5025 5026 5027 5028 5029 5030 + 5031 5032 5033 5034 5035 5036 5037 5038 5039 5040 + 5041 5042 5043 5044 5045 5046 5047 5048 5049 5050 + 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 + 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 + 5071 5072 5073 5074 5075 5076 5077 5078 5079 5080 + 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 + 5091 5092 5093 5094 5095 5096 5097 5098 5099 5100 + 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 + 5111 5112 5113 5114 5115 5116 5117 5118 5119 5120 + 5121 5122 5123 5124 5125 5126 5127 5128 5129 5130 + 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 + 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 + 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 + 5161 5162 5163 5164 5165 5166 5167 5168 5169 5170 + 5171 5172 5173 5174 5175 5176 5177 5178 5179 5180 + 5181 5182 5183 5184 5185 5186 5187 5188 5189 5190 + 5191 5192 5193 5194 5195 5196 5197 5198 5199 5200 + 5201 5202 5203 5204 5205 5206 5207 5208 5209 5210 + 5211 5212 5213 5214 5215 5216 5217 5218 5219 5220 + 5221 5222 5223 5224 5225 5226 5227 5228 5229 5230 + 5231 5232 5233 5234 5235 5236 5237 5238 5239 5240 + 5241 5242 5243 5244 5245 5246 5247 5248 5249 5250 + 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 + 5261 5262 5263 5264 5265 5266 5267 5268 5269 5270 + 5271 5272 5273 5274 5275 5276 5277 5278 5279 5280 + 5281 5282 5283 5284 5285 5286 5287 5288 5289 5290 + 5291 5292 5293 5294 5295 5296 5297 5298 5299 5300 + 5301 5302 5303 5304 5305 5306 5307 5308 5309 5310 + 5311 5312 5313 5314 5315 5316 5317 5318 5319 5320 + 5321 5322 5323 5324 5325 5326 5327 5328 5329 5330 + 5331 5332 5333 5334 5335 5336 5337 5338 5339 5340 + 5341 5342 5343 5344 5345 5346 5347 5348 5349 5350 + 5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 + 5361 5362 5363 5364 5365 5366 5367 5368 5369 5370 + 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380 + 5381 5382 5383 5384 5385 5386 5387 5388 5389 5390 + 5391 5392 5393 5394 5395 5396 5397 5398 5399 5400 + 5401 5402 5403 5404 5405 5406 5407 5408 5409 5410 + 5411 5412 5413 5414 5415 5416 5417 5418 5419 5420 + 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 + 5431 5432 5433 5434 5435 5436 5437 5438 5439 5440 + 5441 5442 5443 5444 5445 5446 5447 5448 5449 5450 + 5451 5452 5453 5454 5455 5456 5457 5458 5459 5460 + 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 + 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 + 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 + 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 + 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 + 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 + 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 + 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 + 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 + 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 + 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 + 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 + 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 + 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 + 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 + 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 + 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 + 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 + 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 + 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 + 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 + 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 + 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 + 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 + 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 + +ENDOFSECTION +BOUNDARY CONDITIONS + Wall 1 404 0 6 + 2 3 2 + 3 3 1 + 5 3 2 + 6 3 2 + 7 3 3 + 14 3 2 + 17 3 1 + 19 3 1 + 23 3 1 + 39 3 3 + 41 3 1 + 47 3 1 + 48 3 3 + 83 3 3 + 85 3 1 + 86 3 1 + 88 3 1 + 102 3 1 + 108 3 1 + 172 3 1 + 175 3 2 + 176 3 1 + 180 3 3 + 188 3 2 + 214 3 1 + 218 3 1 + 223 3 3 + 231 3 2 + 357 3 1 + 359 3 1 + 360 3 2 + 362 3 2 + 372 3 3 + 376 3 1 + 378 3 1 + 444 3 1 + 448 3 1 + 465 3 1 + 466 3 3 + 481 3 1 + 726 3 1 + 727 3 1 + 729 3 2 + 731 3 2 + 732 3 2 + 765 3 2 + 772 3 3 + 774 3 1 + 781 3 3 + 905 3 1 + 912 3 3 + 915 3 3 + 921 3 3 + 949 3 3 + 956 3 2 + 957 3 2 + 963 3 2 + 987 3 3 + 988 3 3 + 1062 3 3 + 1066 3 1 + 1245 3 1 + 1249 3 2 + 1256 3 3 + 1258 3 2 + 1321 3 1 + 1326 3 1 + 1329 3 3 + 1330 3 2 + 1338 3 1 + 1343 3 2 + 1344 3 3 + 1346 3 3 + 1347 3 3 + 1389 3 3 + 1390 3 3 + 1391 3 1 + 1394 3 1 + 1408 3 2 + 1409 3 3 + 1411 3 3 + 1416 3 3 + 1421 3 3 + 1423 3 3 + 1426 3 2 + 1428 3 3 + 1429 3 3 + 1430 3 3 + 1437 3 1 + 1440 3 1 + 1442 3 3 + 1457 3 1 + 1458 3 3 + 1462 3 1 + 1464 3 1 + 1530 3 1 + 1531 3 3 + 1548 3 1 + 1550 3 1 + 1551 3 3 + 1566 3 1 + 1809 3 1 + 1811 3 3 + 1826 3 1 + 1827 3 3 + 1830 3 2 + 1831 3 1 + 1845 3 1 + 1898 3 1 + 1899 3 3 + 1901 3 1 + 1915 3 3 + 1917 3 1 + 1918 3 2 + 1919 3 2 + 1927 3 1 + 1928 3 1 + 1959 3 3 + 1970 3 1 + 1971 3 1 + 2099 3 3 + 2109 3 3 + 2110 3 1 + 2142 3 3 + 2146 3 1 + 2151 3 3 + 2155 3 1 + 2167 3 1 + 2171 3 3 + 2173 3 1 + 2175 3 3 + 2176 3 3 + 2178 3 1 + 2201 3 2 + 2203 3 1 + 2210 3 3 + 2212 3 2 + 2213 3 2 + 2218 3 3 + 2342 3 2 + 2350 3 1 + 2357 3 3 + 2359 3 1 + 2385 3 1 + 2392 3 3 + 2394 3 1 + 2401 3 3 + 2646 3 2 + 2648 3 1 + 2656 3 3 + 2657 3 1 + 2689 3 3 + 2693 3 1 + 2698 3 3 + 2702 3 1 + 2831 3 2 + 2832 3 1 + 2838 3 3 + 2839 3 3 + 2841 3 1 + 2871 3 3 + 2875 3 1 + 2882 3 2 + 2883 3 1 + 2896 3 2 + 2898 3 2 + 2902 3 1 + 2902 3 3 + 2903 3 1 + 2904 3 2 + 2905 3 3 + 2906 3 2 + 2921 3 2 + 2922 3 2 + 2924 3 2 + 2925 3 2 + 2927 3 2 + 2928 3 2 + 2933 3 3 + 2935 3 2 + 2936 3 2 + 2937 3 1 + 2940 3 2 + 2942 3 3 + 2944 3 3 + 2945 3 3 + 2946 3 3 + 2952 3 3 + 2956 3 1 + 2959 3 1 + 3007 3 2 + 3008 3 2 + 3016 3 2 + 3017 3 3 + 3019 3 2 + 3022 3 2 + 3039 3 3 + 3041 3 2 + 3049 3 2 + 3050 3 3 + 3057 3 2 + 3058 3 2 + 3059 3 2 + 3064 3 3 + 3071 3 3 + 3072 3 3 + 3073 3 1 + 3074 3 1 + 3089 3 1 + 3096 3 3 + 3098 3 2 + 3099 3 2 + 3104 3 3 + 3132 3 3 + 3134 3 3 + 3135 3 3 + 3136 3 3 + 3137 3 1 + 3141 3 1 + 3142 3 2 + 3143 3 2 + 3146 3 1 + 3149 3 2 + 3150 3 1 + 3154 3 2 + 3155 3 2 + 3156 3 2 + 3157 3 2 + 3158 3 2 + 3160 3 2 + 3233 3 1 + 3234 3 3 + 3235 3 2 + 3248 3 1 + 3267 3 2 + 3268 3 3 + 3282 3 2 + 3287 3 2 + 3295 3 3 + 3297 3 3 + 3298 3 3 + 3300 3 1 + 3304 3 2 + 3308 3 2 + 3313 3 3 + 3315 3 1 + 3317 3 2 + 3318 3 2 + 3319 3 2 + 3325 3 2 + 3327 3 2 + 3328 3 2 + 3333 3 3 + 3334 3 1 + 3335 3 2 + 3337 3 1 + 3341 3 2 + 3343 3 2 + 3344 3 2 + 3350 3 2 + 3351 3 2 + 3359 3 2 + 3363 3 1 + 3364 3 2 + 3365 3 2 + 3366 3 2 + 3367 3 2 + 3368 3 2 + 3380 3 2 + 3381 3 2 + 3382 3 2 + 3383 3 2 + 3384 3 2 + 3395 3 1 + 3446 3 2 + 3447 3 2 + 3448 3 1 + 3451 3 2 + 3453 3 1 + 3455 3 1 + 3459 3 2 + 3462 3 2 + 3463 3 2 + 3464 3 2 + 3465 3 2 + 3467 3 2 + 3478 3 1 + 3530 3 1 + 3534 3 2 + 3542 3 2 + 3543 3 3 + 3577 3 3 + 3587 3 3 + 3719 3 3 + 3729 3 3 + 3763 3 1 + 3772 3 3 + 3773 3 3 + 3774 3 3 + 3775 3 3 + 3776 3 2 + 3776 3 3 + 3788 3 3 + 3789 3 3 + 3790 3 3 + 3791 3 3 + 3792 3 3 + 3793 3 2 + 3853 3 3 + 3854 3 3 + 3855 3 3 + 3856 3 3 + 3857 3 3 + 3858 3 2 + 3871 3 3 + 3872 3 3 + 3873 3 2 + 3877 3 2 + 4128 3 3 + 4129 3 3 + 4130 3 3 + 4131 3 3 + 4132 3 3 + 4133 3 2 + 4146 3 3 + 4147 3 3 + 4148 3 2 + 4152 3 2 + 4213 3 3 + 4214 3 3 + 4215 3 3 + 4216 3 3 + 4217 3 3 + 4218 3 2 + 4231 3 3 + 4232 3 3 + 4233 3 2 + 4237 3 2 + 4247 3 2 + 4248 3 1 + 4254 3 2 + 4255 3 2 + 4288 3 2 + 4289 3 2 + 4297 3 2 + 4298 3 2 + 4303 3 3 + 4427 3 1 + 4735 3 3 + 4739 3 1 + 4744 3 3 + 4748 3 1 + 4778 3 3 + 4781 3 1 + 4782 3 1 + 4787 3 3 + 4788 3 3 + 4917 3 3 + 4921 3 1 + 4927 3 3 + 4928 3 1 + 4929 3 1 + 4960 3 3 + 4961 3 3 + 4967 3 3 + 4969 3 3 + 4970 3 1 + 5227 3 2 + 5231 3 2 + 5248 3 2 + 5252 3 2 + 5318 3 2 + 5322 3 2 + 5338 3 2 + 5339 3 3 + 5341 3 2 + 5473 3 3 + 5477 3 1 + 5483 3 3 + 5484 3 1 + 5516 3 3 + 5518 3 1 + 5520 3 1 + 5524 3 3 + 5525 3 3 + 5593 3 2 + 5597 3 2 + 5614 3 2 + 5618 3 2 + 5652 3 3 + 5653 3 3 + 5654 3 1 + 5655 3 1 + 5659 3 3 + 5660 3 3 + 5685 3 2 + 5693 3 3 + 5694 3 3 + 5696 3 1 + 5697 3 3 + 5698 3 3 + 5699 3 2 + 5701 3 3 + 5702 3 1 +ENDOFSECTION diff --git a/benchmarks/CUDA/DG/Meshes/cubeK268.neu b/benchmarks/CUDA/DG/Meshes/cubeK268.neu new file mode 100644 index 0000000..bea90c0 --- /dev/null +++ b/benchmarks/CUDA/DG/Meshes/cubeK268.neu @@ -0,0 +1,565 @@ + CONTROL INFO 1.3.0 +** GAMBIT NEUTRAL FILE +cube1 +PROGRAM: Gambit VERSION: 1.3.0 +27 Aug 2001 12:07:49 + NUMNP NELEM NGRPS NBSETS NDFCD NDFVL + 94 268 1 1 3 3 +ENDOFSECTION + NODAL COORDINATES 1.3.0 + 1 5.0000000000000000e-01 -5.0000000000e-01 5.0000000000e-01 + 2 5.0000000000000000e-01 -5.0000000000e-01 -5.0000000000e-01 + 3 5.0000000000000000e-01 -5.0000000000e-01 1.6666666667e-01 + 4 5.0000000000000000e-01 -5.0000000000e-01 -1.6666666667e-01 + 5 5.0000000000000000e-01 5.0000000000e-01 -5.0000000000e-01 + 6 5.0000000000000000e-01 1.9666666667e-01 -5.0000000000e-01 + 7 5.0000000000000000e-01 -1.9666666667e-01 -5.0000000000e-01 + 8 5.0000000000000000e-01 5.0000000000e-01 5.0000000000e-01 + 9 5.0000000000000000e-01 5.0000000000e-01 1.6666666667e-01 + 10 5.0000000000000000e-01 5.0000000000e-01 -1.6666666667e-01 + 11 5.0000000000000000e-01 -1.8666666667e-01 5.0000000000e-01 + 12 5.0000000000000000e-01 1.4666666667e-01 5.0000000000e-01 + 13 5.0000000000000000e-01 2.3507789125e-01 2.7150115797e-01 + 14 5.0000000000000000e-01 -2.4631031727e-01 2.7149457760e-01 + 15 5.0000000000000000e-01 2.5507397411e-01 -2.7236083069e-01 + 16 5.0000000000000000e-01 -2.6631416783e-01 -2.7236728279e-01 + 17 5.0000000000000000e-01 -9.5112888295e-04 1.9231307367e-01 + 18 5.0000000000000000e-01 2.7099470629e-01 -6.0965707545e-04 + 19 5.0000000000000000e-01 -2.7276183488e-01 -6.1743214209e-04 + 20 5.0000000000000000e-01 -9.3270234243e-04 -1.9364476866e-01 + 21 -5.0000000000000000e-01 5.0000000000e-01 -5.0000000000e-01 + 22 -1.6666666666999996e-01 5.0000000000e-01 -5.0000000000e-01 + 23 1.6666666667000007e-01 5.0000000000e-01 -5.0000000000e-01 + 24 -5.0000000000000000e-01 5.0000000000e-01 5.0000000000e-01 + 25 -5.0000000000000000e-01 5.0000000000e-01 1.6666666667e-01 + 26 -5.0000000000000000e-01 5.0000000000e-01 -1.6666666667e-01 + 27 1.6666666667000007e-01 5.0000000000e-01 5.0000000000e-01 + 28 -1.6666666666999996e-01 5.0000000000e-01 5.0000000000e-01 + 29 -2.7236083069000006e-01 5.0000000000e-01 2.8507397411e-01 + 30 2.7150115796999996e-01 5.0000000000e-01 2.8507789125e-01 + 31 -2.7236728279000000e-01 5.0000000000e-01 -2.8631416783e-01 + 32 2.7149457759999995e-01 5.0000000000e-01 -2.8631031727e-01 + 33 1.9231307367000006e-01 5.0000000000e-01 -9.5112888295e-04 + 34 -6.0965707545002079e-04 5.0000000000e-01 2.6099470629e-01 + 35 -6.1743214208997976e-04 5.0000000000e-01 -2.6276183488e-01 + 36 -1.9364476866000002e-01 5.0000000000e-01 -9.5270234243e-04 + 37 -5.0000000000000000e-01 -5.0000000000e-01 -5.0000000000e-01 + 38 -5.0000000000000000e-01 -1.6666666667e-01 -5.0000000000e-01 + 39 -5.0000000000000000e-01 1.6666666667e-01 -5.0000000000e-01 + 40 -5.0000000000000000e-01 -5.0000000000e-01 5.0000000000e-01 + 41 -5.0000000000000000e-01 -5.0000000000e-01 1.6666666667e-01 + 42 -5.0000000000000000e-01 -5.0000000000e-01 -1.6666666667e-01 + 43 -5.0000000000000000e-01 1.6666666667e-01 5.0000000000e-01 + 44 -5.0000000000000000e-01 -1.6666666667e-01 5.0000000000e-01 + 45 -5.0000000000000000e-01 -2.7236083069e-01 2.8507397411e-01 + 46 -5.0000000000000000e-01 2.7150115797e-01 2.8507789125e-01 + 47 -5.0000000000000000e-01 -2.7236728279e-01 -2.8631416783e-01 + 48 -5.0000000000000000e-01 2.7149457760e-01 -2.8631031727e-01 + 49 -5.0000000000000000e-01 1.9231307367e-01 -9.5112888295e-04 + 50 -5.0000000000000000e-01 -6.0965707545e-04 2.6099470629e-01 + 51 -5.0000000000000000e-01 -6.1743214209e-04 -2.6276183488e-01 + 52 -5.0000000000000000e-01 -1.9364476866e-01 -9.5270234243e-04 + 53 1.6666666667000007e-01 -5.0000000000e-01 -5.0000000000e-01 + 54 -1.6666666666999996e-01 -5.0000000000e-01 -5.0000000000e-01 + 55 -1.6666666666999996e-01 -5.0000000000e-01 5.0000000000e-01 + 56 1.6666666667000007e-01 -5.0000000000e-01 5.0000000000e-01 + 57 2.8507789125000005e-01 -5.0000000000e-01 2.7150115797e-01 + 58 -2.8631031727000000e-01 -5.0000000000e-01 2.7149457760e-01 + 59 2.8507397410999991e-01 -5.0000000000e-01 -2.7236083069e-01 + 60 -2.8631416783000008e-01 -5.0000000000e-01 -2.7236728279e-01 + 61 -9.5112888295001419e-04 -5.0000000000e-01 1.9231307367e-01 + 62 2.6099470628999999e-01 -5.0000000000e-01 -6.0965707545e-04 + 63 -2.6276183488000004e-01 -5.0000000000e-01 -6.1743214209e-04 + 64 -9.5270234242994523e-04 -5.0000000000e-01 -1.9364476866e-01 + 65 2.7150115796999996e-01 2.8507789125e-01 -5.0000000000e-01 + 66 -2.7236083069000006e-01 2.8507397411e-01 -5.0000000000e-01 + 67 2.7149457759999995e-01 -2.8631031727e-01 -5.0000000000e-01 + 68 -2.7236728279000000e-01 -2.8631416783e-01 -5.0000000000e-01 + 69 -6.0965707545002079e-04 2.6099470629e-01 -5.0000000000e-01 + 70 1.9231307367000006e-01 -9.5112888295e-04 -5.0000000000e-01 + 71 -6.1743214208997976e-04 -2.6276183488e-01 -5.0000000000e-01 + 72 -1.9364476866000002e-01 -9.5270234243e-04 -5.0000000000e-01 + 73 2.8507397410999991e-01 -2.7236083069e-01 5.0000000000e-01 + 74 -2.8631416783000008e-01 -2.7236728279e-01 5.0000000000e-01 + 75 2.8507789125000005e-01 2.7150115797e-01 5.0000000000e-01 + 76 -2.8631031727000000e-01 2.7149457760e-01 5.0000000000e-01 + 77 2.6099470628999999e-01 -6.0965707545e-04 5.0000000000e-01 + 78 -9.5112888295001419e-04 1.9231307367e-01 5.0000000000e-01 + 79 -9.5270234242994523e-04 -1.9364476866e-01 5.0000000000e-01 + 80 -2.6276183488000004e-01 -6.1743214209e-04 5.0000000000e-01 + 81 2.5829991697999999e-01 -1.8334290385e-01 -1.5554314852e-01 + 82 2.3446026444000001e-01 -1.8334108591e-01 1.5439674258e-01 + 83 2.5777769089000002e-01 1.8170532584e-01 -1.5553840995e-01 + 84 2.3437520861999994e-01 1.8170715868e-01 1.5440152586e-01 + 85 -1.5554314852000006e-01 2.5829991698e-01 -1.8334290385e-01 + 86 -1.5553840995000001e-01 2.5777769089e-01 1.8170532584e-01 + 87 -2.5829991697999999e-01 -1.5554314852e-01 -1.8334290385e-01 + 88 -2.5777769089000002e-01 -1.5553840995e-01 1.8170532584e-01 + 89 2.6753392815999999e-01 -8.0723827705e-04 1.0528176790e-03 + 90 1.4829332939999995e-02 -1.1656295974e-03 -2.3927578330e-01 + 91 3.9356499910000009e-02 2.8002762794e-01 -7.8986241715e-04 + 92 -2.4820561707000000e-01 6.1629176140e-02 -1.0985633126e-03 + 93 -1.2082404457000040e-02 -2.4497900903e-01 -2.0453006029e-02 + 94 2.6915045455000453e-03 -8.7227503536e-04 2.5509673357e-01 +ENDOFSECTION + ELEMENTS/CELLS 1.3.0 + 1 6 4 33 18 10 9 + 2 6 4 47 60 42 37 + 3 6 4 47 38 68 37 + 4 6 4 47 60 37 68 + 5 6 4 52 41 42 63 + 6 6 4 61 79 55 56 + 7 6 4 61 56 57 79 + 8 6 4 61 55 79 58 + 9 6 4 9 13 8 30 + 10 6 4 4 3 19 62 + 11 6 4 4 59 16 2 + 12 6 4 38 51 72 39 + 13 6 4 7 70 20 6 + 14 6 4 7 16 67 2 + 15 6 4 8 75 27 30 + 16 6 4 8 13 75 30 + 17 6 4 8 75 13 12 + 18 6 4 75 27 34 78 + 19 6 4 75 30 34 27 + 20 6 4 23 65 32 35 + 21 6 4 23 65 35 69 + 22 6 4 23 22 69 35 + 23 6 4 23 65 5 32 + 24 6 4 44 45 74 40 + 25 6 4 44 80 50 43 + 26 6 4 26 36 25 49 + 27 6 4 26 48 21 31 + 28 6 4 54 37 60 68 + 29 6 4 54 60 71 68 + 30 6 4 54 64 71 60 + 31 6 4 54 53 71 64 + 32 6 4 12 17 11 77 + 33 6 4 56 57 79 73 + 34 6 4 56 1 57 73 + 35 6 4 5 65 15 32 + 36 6 4 5 6 15 65 + 37 6 4 5 32 15 10 + 38 6 4 41 45 40 58 + 39 6 4 28 34 27 78 + 40 6 4 28 24 29 76 + 41 6 4 1 11 14 73 + 42 6 4 1 14 3 57 + 43 6 4 1 14 57 73 + 44 6 4 16 2 59 67 + 45 6 4 29 46 76 24 + 46 6 4 29 25 46 24 + 47 6 4 66 39 48 21 + 48 6 4 66 21 48 31 + 49 6 4 66 31 22 21 + 50 6 4 66 72 51 39 + 51 6 4 66 39 51 48 + 52 6 4 71 59 64 53 + 53 6 4 71 67 59 53 + 54 6 4 76 43 46 80 + 55 6 4 76 46 43 24 + 56 6 4 46 50 80 43 + 57 6 4 45 74 40 58 + 58 6 4 59 2 53 67 + 59 6 4 74 79 55 58 + 60 6 4 74 58 55 40 + 61 6 4 81 71 70 67 + 62 6 4 81 59 71 67 + 63 6 4 81 64 71 59 + 64 6 4 81 67 70 7 + 65 6 4 81 20 7 70 + 66 6 4 81 7 16 67 + 67 6 4 81 7 20 16 + 68 6 4 81 67 16 59 + 69 6 4 81 16 20 19 + 70 6 4 81 4 16 19 + 71 6 4 81 16 4 59 + 72 6 4 81 62 59 4 + 73 6 4 81 4 19 62 + 74 6 4 81 59 62 64 + 75 6 4 82 73 77 79 + 76 6 4 82 61 62 57 + 77 6 4 82 81 19 62 + 78 6 4 82 57 14 73 + 79 6 4 82 19 17 14 + 80 6 4 82 3 19 14 + 81 6 4 82 3 14 57 + 82 6 4 82 57 62 3 + 83 6 4 82 19 3 62 + 84 6 4 82 61 57 79 + 85 6 4 82 77 73 11 + 86 6 4 82 14 11 73 + 87 6 4 82 11 17 77 + 88 6 4 82 14 17 11 + 89 6 4 82 79 57 73 + 90 6 4 83 70 69 65 + 91 6 4 83 20 81 70 + 92 6 4 83 15 18 20 + 93 6 4 83 15 6 65 + 94 6 4 83 15 20 6 + 95 6 4 83 6 70 65 + 96 6 4 83 20 70 6 + 97 6 4 83 35 65 69 + 98 6 4 83 32 65 35 + 99 6 4 83 15 65 32 + 100 6 4 83 10 33 18 + 101 6 4 83 32 33 10 + 102 6 4 83 18 15 10 + 103 6 4 83 15 32 10 + 104 6 4 84 75 13 30 + 105 6 4 84 30 33 34 + 106 6 4 84 75 30 34 + 107 6 4 84 75 34 78 + 108 6 4 84 18 83 33 + 109 6 4 84 17 18 13 + 110 6 4 84 9 33 30 + 111 6 4 84 18 33 9 + 112 6 4 84 13 9 30 + 113 6 4 84 13 18 9 + 114 6 4 84 82 17 77 + 115 6 4 84 13 75 12 + 116 6 4 84 75 77 12 + 117 6 4 84 17 12 77 + 118 6 4 84 12 17 13 + 119 6 4 84 75 78 77 + 120 6 4 85 83 69 35 + 121 6 4 85 31 36 35 + 122 6 4 85 31 66 48 + 123 6 4 85 48 66 51 + 124 6 4 85 51 66 72 + 125 6 4 85 48 49 26 + 126 6 4 85 26 49 36 + 127 6 4 85 26 36 31 + 128 6 4 85 48 26 31 + 129 6 4 85 69 22 35 + 130 6 4 85 69 66 22 + 131 6 4 85 31 35 22 + 132 6 4 85 66 31 22 + 133 6 4 85 66 69 72 + 134 6 4 86 76 29 46 + 135 6 4 86 84 34 78 + 136 6 4 86 29 34 36 + 137 6 4 86 36 85 49 + 138 6 4 86 25 36 49 + 139 6 4 86 25 49 46 + 140 6 4 86 29 36 25 + 141 6 4 86 46 29 25 + 142 6 4 86 80 46 50 + 143 6 4 86 80 76 46 + 144 6 4 86 80 78 76 + 145 6 4 86 34 29 28 + 146 6 4 86 76 28 29 + 147 6 4 86 28 78 34 + 148 6 4 86 28 76 78 + 149 6 4 87 60 64 63 + 150 6 4 87 60 47 68 + 151 6 4 87 47 52 51 + 152 6 4 87 47 51 38 + 153 6 4 87 47 38 68 + 154 6 4 87 38 72 68 + 155 6 4 87 38 51 72 + 156 6 4 87 71 60 68 + 157 6 4 87 71 64 60 + 158 6 4 87 68 72 71 + 159 6 4 87 42 60 63 + 160 6 4 87 42 47 60 + 161 6 4 87 52 42 63 + 162 6 4 87 42 52 47 + 163 6 4 87 85 72 51 + 164 6 4 88 74 79 80 + 165 6 4 88 79 74 58 + 166 6 4 88 58 61 79 + 167 6 4 88 63 61 58 + 168 6 4 88 87 63 52 + 169 6 4 88 45 50 52 + 170 6 4 88 86 50 80 + 171 6 4 88 50 45 44 + 172 6 4 88 44 80 50 + 173 6 4 88 74 44 45 + 174 6 4 88 44 74 80 + 175 6 4 88 41 52 63 + 176 6 4 88 45 52 41 + 177 6 4 88 41 63 58 + 178 6 4 88 41 58 45 + 179 6 4 88 45 58 74 + 180 6 4 89 83 84 18 + 181 6 4 89 18 84 17 + 182 6 4 89 20 18 17 + 183 6 4 89 20 83 18 + 184 6 4 89 17 84 82 + 185 6 4 89 17 82 19 + 186 6 4 89 82 81 19 + 187 6 4 89 19 20 17 + 188 6 4 89 19 81 20 + 189 6 4 89 81 83 20 + 190 6 4 90 83 89 81 + 191 6 4 90 87 85 72 + 192 6 4 90 71 72 70 + 193 6 4 90 71 87 72 + 194 6 4 90 70 72 69 + 195 6 4 90 85 69 72 + 196 6 4 90 83 70 69 + 197 6 4 90 69 85 83 + 198 6 4 90 81 71 70 + 199 6 4 90 83 81 70 + 200 6 4 91 86 36 85 + 201 6 4 91 34 33 36 + 202 6 4 91 36 86 34 + 203 6 4 91 35 36 33 + 204 6 4 91 85 36 35 + 205 6 4 91 85 35 83 + 206 6 4 91 84 89 83 + 207 6 4 91 89 90 83 + 208 6 4 91 83 90 85 + 209 6 4 91 34 84 33 + 210 6 4 91 86 84 34 + 211 6 4 91 84 83 33 + 212 6 4 92 88 52 87 + 213 6 4 92 50 49 52 + 214 6 4 92 52 88 50 + 215 6 4 92 51 52 49 + 216 6 4 92 87 52 51 + 217 6 4 92 85 87 51 + 218 6 4 92 91 85 86 + 219 6 4 92 91 90 85 + 220 6 4 92 90 87 85 + 221 6 4 92 88 86 50 + 222 6 4 92 86 85 49 + 223 6 4 93 87 64 63 + 224 6 4 93 63 88 87 + 225 6 4 93 63 64 61 + 226 6 4 93 61 88 63 + 227 6 4 93 64 62 61 + 228 6 4 93 82 61 62 + 229 6 4 93 81 62 64 + 230 6 4 93 81 82 62 + 231 6 4 93 89 82 81 + 232 6 4 93 81 90 89 + 233 6 4 93 81 64 71 + 234 6 4 93 90 81 71 + 235 6 4 93 87 71 64 + 236 6 4 93 87 90 71 + 237 6 4 93 92 87 88 + 238 6 4 93 92 90 87 + 239 6 4 94 86 78 84 + 240 6 4 94 86 80 78 + 241 6 4 94 88 80 86 + 242 6 4 94 92 88 86 + 243 6 4 94 91 86 84 + 244 6 4 94 91 92 86 + 245 6 4 94 91 84 89 + 246 6 4 94 90 91 89 + 247 6 4 94 92 91 90 + 248 6 4 94 93 90 89 + 249 6 4 94 93 92 90 + 250 6 4 94 92 93 88 + 251 6 4 94 79 88 61 + 252 6 4 94 88 93 61 + 253 6 4 94 61 82 79 + 254 6 4 94 93 82 61 + 255 6 4 94 82 89 84 + 256 6 4 94 93 89 82 + 257 6 4 94 79 82 77 + 258 6 4 94 84 77 82 + 259 6 4 94 80 79 78 + 260 6 4 94 80 88 79 + 261 6 4 94 77 78 79 + 262 6 4 94 84 78 77 + 263 6 4 83 35 33 32 + 264 6 4 83 35 91 33 + 265 6 4 85 51 49 48 + 266 6 4 85 51 92 49 + 267 6 4 86 46 49 50 + 268 6 4 86 49 92 50 +ENDOFSECTION + ELEMENT GROUP 1.3.0 +GROUP: 1 ELEMENTS: 268 MATERIAL: 2 NFLAGS: 1 + fluid + 0 + 1 2 3 4 5 6 7 8 9 10 + 11 12 13 14 15 16 17 18 19 20 + 21 22 23 24 25 26 27 28 29 30 + 31 32 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 49 50 + 51 52 53 54 55 56 57 58 59 60 + 61 62 63 64 65 66 67 68 69 70 + 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 + 91 92 93 94 95 96 97 98 99 100 + 101 102 103 104 105 106 107 108 109 110 + 111 112 113 114 115 116 117 118 119 120 + 121 122 123 124 125 126 127 128 129 130 + 131 132 133 134 135 136 137 138 139 140 + 141 142 143 144 145 146 147 148 149 150 + 151 152 153 154 155 156 157 158 159 160 + 161 162 163 164 165 166 167 168 169 170 + 171 172 173 174 175 176 177 178 179 180 + 181 182 183 184 185 186 187 188 189 190 + 191 192 193 194 195 196 197 198 199 200 + 201 202 203 204 205 206 207 208 209 210 + 211 212 213 214 215 216 217 218 219 220 + 221 222 223 224 225 226 227 228 229 230 + 231 232 233 234 235 236 237 238 239 240 + 241 242 243 244 245 246 247 248 249 250 + 251 252 253 254 255 256 257 258 259 260 + 261 262 263 264 265 266 267 268 +ENDOFSECTION + BOUNDARY CONDITIONS 1.3.0 + Wall 1 156 0 6 + 34 6 2 + 41 6 2 + 60 6 4 + 24 6 4 + 17 6 2 + 15 6 1 + 55 6 4 + 40 6 2 + 116 6 3 + 32 6 4 + 18 6 2 + 39 6 4 + 33 6 4 + 6 6 3 + 54 6 2 + 25 6 2 + 85 6 3 + 148 6 3 + 59 6 1 + 174 6 3 + 75 6 3 + 144 6 3 + 119 6 3 + 261 6 3 + 259 6 3 + 164 6 3 + 23 6 1 + 36 6 2 + 49 6 4 + 47 6 2 + 14 6 4 + 58 6 3 + 3 6 3 + 28 6 2 + 21 6 2 + 22 6 1 + 95 6 3 + 13 6 2 + 53 6 2 + 31 6 1 + 50 6 2 + 12 6 4 + 130 6 3 + 64 6 3 + 154 6 3 + 29 6 4 + 61 6 3 + 133 6 3 + 90 6 3 + 194 6 3 + 192 6 3 + 158 6 3 + 34 6 1 + 42 6 4 + 38 6 4 + 60 6 3 + 11 6 2 + 58 6 1 + 28 6 1 + 2 6 3 + 7 6 1 + 6 6 4 + 82 6 3 + 10 6 2 + 177 6 3 + 5 6 3 + 52 6 3 + 31 6 2 + 72 6 3 + 8 6 2 + 30 6 2 + 159 6 3 + 74 6 3 + 167 6 3 + 76 6 3 + 225 6 3 + 227 6 3 + 149 6 3 + 24 6 2 + 38 6 1 + 46 6 3 + 55 6 3 + 2 6 4 + 3 6 2 + 47 6 3 + 27 6 1 + 139 6 3 + 26 6 4 + 56 6 2 + 25 6 4 + 51 6 3 + 12 6 2 + 176 6 3 + 5 6 1 + 171 6 3 + 125 6 3 + 162 6 3 + 152 6 3 + 169 6 3 + 265 6 3 + 267 6 3 + 213 6 3 + 215 6 3 + 151 6 3 + 40 6 1 + 46 6 2 + 9 6 4 + 15 6 4 + 27 6 4 + 49 6 3 + 23 6 4 + 37 6 2 + 110 6 3 + 1 6 4 + 19 6 3 + 39 6 1 + 20 6 4 + 22 6 2 + 140 6 3 + 26 6 1 + 145 6 3 + 101 6 3 + 127 6 3 + 131 6 3 + 136 6 3 + 263 6 3 + 105 6 3 + 201 6 3 + 203 6 3 + 121 6 3 + 17 6 4 + 9 6 1 + 42 6 1 + 41 6 1 + 37 6 4 + 36 6 1 + 14 6 2 + 11 6 4 + 118 6 3 + 32 6 1 + 113 6 3 + 1 6 3 + 80 6 3 + 10 6 1 + 94 6 3 + 13 6 4 + 102 6 3 + 88 6 3 + 67 6 3 + 70 6 3 + 92 6 3 + 79 6 3 + 109 6 3 + 187 6 3 + 182 6 3 + 69 6 3 +ENDOFSECTION diff --git a/benchmarks/CUDA/DG/README.GPGPU-Sim b/benchmarks/CUDA/DG/README.GPGPU-Sim new file mode 100644 index 0000000..3960ead --- /dev/null +++ b/benchmarks/CUDA/DG/README.GPGPU-Sim @@ -0,0 +1,14 @@ +dependencies: + +Open MPI + +To build: + +cd 3rdParty/ParMetis-3.1 +make +cd - +make + +To run: + +./gpgpu_ptx_sim__gpuDG3d ./data/cubeK268.neu diff --git a/benchmarks/CUDA/DG/buildsource.m b/benchmarks/CUDA/DG/buildsource.m new file mode 100644 index 0000000..c93d363 --- /dev/null +++ b/benchmarks/CUDA/DG/buildsource.m @@ -0,0 +1,106 @@ + +function buildsource(in_N) + +Globals2D; + + +NODETOL = 1e-8; + +N = in_N; + +Np = (N+1)*(N+2)/2; Nfp = N+1; Nfaces = 3; + +[x,y] = Nodes2D(N); +[r,s] = xytors(x,y); + +% find all the nodes that lie on each edge +fmask1 = find( abs(s+1) < NODETOL)'; +fmask2 = find( abs(r+s) < NODETOL)'; +fmask3 = find( abs(r+1) < NODETOL)'; +Fmask = [fmask1;fmask2;fmask3]'; + +% vandermonde matrix +V = Vandermonde2D(N, r, s); + +% derivative matrices +[Dr, Ds] = Dmatrices2D(N, r, s, V); + +% lift matrix +LIFT = Lift2D(); + +% correct to 0-index +Fmask = Fmask-1; + + +fid = fopen(sprintf('dataN%02d.h', N), 'w'); + +fprintf(fid, sprintf('#ifndef DATAN%02d \n\n', N)); +fprintf(fid, sprintf('#define DATAN%02d 1\n\n', N)); +fprintf(fid, 'double p_r[%d] = { ', Np); +fprintf(fid, '%17.15g ', r(1)); +for n=2:Np + fprintf(fid, ', %17.15g ', r(n)); +end +fprintf(fid, '};\n') + +fprintf(fid, 'double p_s[%d] = {', Np); +fprintf(fid, '%17.15g ', s(1)); +for n=2:Np + fprintf(fid, ', %17.15g ', s(n)); +end +fprintf(fid, '};\n') + +fprintf(fid, 'double p_Dr[%d][%d] = {', Np, Np); +for m=1:Np +fprintf(fid, '{%17.15g ', Dr(m,1)); +for n=2:Np + fprintf(fid, ', %17.15g ', Dr(m,n)); +end +if(mb)?a:b ) +#define min(a,b) ( (a +#include +#include +#include + +#include "Mesh.h" + +/* prototypes for storage functions (Utils.c) */ +double **BuildMatrix(int Nrows, int Ncols); +double *BuildVector(int Nrows); +int **BuildIntMatrix(int Nrows, int Ncols); +int *BuildIntVector(int Nrows); + +double **DestroyMatrix(double **); +double *DestroyVector(double *); +int **DestroyIntMatrix(int **); +int *DestroyIntVector(int *); + +void PrintMatrix(char *message, double **A, int Nrows, int Ncols); +void SaveMatrix(char *filename, double **A, int Nrows, int Ncols); + +/* geometric/mesh functions */ +Mesh *ReadMesh2d(char *filename); +Mesh *ReadMesh3d(char *filename); + +void PrintMesh ( Mesh *mesh ); + +void Normals2d(Mesh *mesh, int k, double *nx, double *ny, double *sJ); +void Normals3d(Mesh *mesh, int k, + double *nx, double *ny, double *nz, double *sJ); + +void GeometricFactors2d(Mesh *mesh, int k, + double *drdx, double *dsdx, double *drdy, double *dsdy, + double *J); + +void GeometricFactors3d(Mesh *mesh, int k, + double *drdx, double *dsdx, double *dtdx, + double *drdy, double *dsdy, double *dtdy, + double *drdz, double *dsdz, double *dtdz, + double *J); + +/* start up */ +void StartUp2d(Mesh *mesh); +void StartUp3d(Mesh *mesh); + +void BuildMaps2d(Mesh *mesh); +void BuildMaps3d(Mesh *mesh); + +/* Parallel */ +void LoadBalance2d(Mesh *mesh); +void LoadBalance3d(Mesh *mesh); + +void FacePair2d(Mesh *mesh, int *maxNv); +void FacePair3d(Mesh *mesh, int *maxNv); + +void ParallelPairs(void *objs, int Nmyobjs, int sizeobj, + int (*numget)(const void *), + void (*numset)(const void *, int ), + int (*procget)(const void *), + void (*marry)(const void *, const void *), + int (*compare_objs)(const void *, const void *)); + +void MaxwellsMPISend2d(Mesh *mesh); +void MaxwellsMPIRecv2d(Mesh *mesh, float *c_partQ); + +void MaxwellsMPISend3d(Mesh *mesh); +void MaxwellsMPIRecv3d(Mesh *mesh, float *c_partQ); + + +/* GPU functions */ +void gpu_set_data2d(int K, + double *d_Hx, double *d_Hy, double *d_Ez); +void gpu_set_data3d(int K, + double *d_Hx, double *d_Hy, double *d_Hz, + double *d_Ex, double *d_Ey, double *d_Ez); + +void gpu_get_data2d(int K, + double *d_Hx, double *d_Hy, double *d_Ez); +void gpu_get_data3d(int K, + double *d_Hx, double *d_Hy, double *d_Hz, + double *d_Ex, double *d_Ey, double *d_Ez); + +double InitGPU2d(Mesh *mesh, int Nfields); +double InitGPU3d(Mesh *mesh, int Nfields); + +/* CPU functions */ +void cpu_set_data2d(Mesh *mesh, double *Hx, double *Hy, double *Ez); +void cpu_set_data3d(Mesh *mesh, double *Hx, double *Hy, double *Hz, + double *Ex, double *Ey, double *Ez); + +double InitCPU2d(Mesh *mesh, int Nfields); +double InitCPU3d(Mesh *mesh, int Nfields); + +/* Maxwells functions */ +void MaxwellsKernel2d(Mesh *mesh, float frka, float frkb, float fdt); +void MaxwellsKernel3d(Mesh *mesh, float frka, float frkb, float fdt); + +void MaxwellsRHS2d(Mesh *mesh, float frka, float frkb, float fdt); +void MaxwellsRHS3d(Mesh *mesh, float frka, float frkb, float fdt); + +void MaxwellsRun2d(Mesh *mesh, double FinalTime, double dt); +void MaxwellsRun3d(Mesh *mesh, double FinalTime, double dt); + +/* CUDA headers */ +#ifdef CUDA +#include "cuda.h" +#include "cuda_runtime_api.h" +#endif + diff --git a/benchmarks/CUDA/DG/include/macros.h b/benchmarks/CUDA/DG/include/macros.h new file mode 100644 index 0000000..31861f7 --- /dev/null +++ b/benchmarks/CUDA/DG/include/macros.h @@ -0,0 +1,163 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * macros.h + * + * This file contains macros used in multilevel + * + * Started 9/25/94 + * George + * + * $Id: macros.h,v 1.8 2003/07/21 19:11:46 karypis Exp $ + * + */ + + +/************************************************************************* +* The following macro returns a random number in the specified range +**************************************************************************/ +#define RandomInRange(u) ((int)(1.0*(u)*rand()/(RAND_MAX+1.0))) + +#define amax(a, b) ((a) >= (b) ? (a) : (b)) +#define amin(a, b) ((a) >= (b) ? (b) : (a)) + +#define AND(a, b) ((a) < 0 ? ((-(a))&(b)) : ((a)&(b))) +#define OR(a, b) ((a) < 0 ? -((-(a))|(b)) : ((a)|(b))) +#define XOR(a, b) ((a) < 0 ? -((-(a))^(b)) : ((a)^(b))) + +#define SWAP(a, b, tmp) \ + do {(tmp) = (a); (a) = (b); (b) = (tmp);} while(0) + +#define INC_DEC(a, b, val) \ + do {(a) += (val); (b) -= (val);} while(0) + + +#define icopy(n, a, b) memcpy((b), (a), sizeof(int)*(n)) +#define scopy(n, a, b) memcpy((b), (a), sizeof(float)*(n)) +#define idxcopy(n, a, b) memcpy((b), (a), sizeof(idxtype)*(n)) + +#define HASHFCT(key, size) ((key)%(size)) + + +/************************************************************************* +* Timer macros +**************************************************************************/ +#define cleartimer(tmr) (tmr = 0.0) +#define starttimer(tmr) (tmr -= MPI_Wtime()) +#define stoptimer(tmr) (tmr += MPI_Wtime()) +#define gettimer(tmr) (tmr) + + +/************************************************************************* +* This macro is used to handle dbglvl +**************************************************************************/ +#define IFSET(a, flag, cmd) if ((a)&(flag)) (cmd); + +/************************************************************************* +* These macros are used for debuging memory leaks +**************************************************************************/ +#ifdef DMALLOC +#define imalloc(n, msg) (malloc(sizeof(int)*(n))) +#define fmalloc(n, msg) (malloc(sizeof(float)*(n))) +#define idxmalloc(n, msg) (malloc(sizeof(idxtype)*(n))) +#define ismalloc(n, val, msg) (iset((n), (val), malloc(sizeof(int)*(n)))) +#define idxsmalloc(n, val, msg) (idxset((n), (val), malloc(sizeof(idxtype)*(n)))) +#define GKmalloc(a, b) (malloc(a)) +#endif + +#ifdef DMALLOC +# define MALLOC_CHECK(ptr); +/* +# define MALLOC_CHECK(ptr) \ + if (malloc_verify((ptr)) == DMALLOC_VERIFY_ERROR) { \ + printf("***MALLOC_CHECK failed on line %d of file %s: " #ptr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +*/ +#else +# define MALLOC_CHECK(ptr) ; +#endif + +/************************************************************************* +* This macro converts a length array in a CSR one +**************************************************************************/ +#define MAKECSR(i, n, a) \ + do { \ + for (i=1; i0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + +#define SHIFTCSR(i, n, a) \ + do { \ + for (i=n; i>0; i--) a[i] = a[i-1]; \ + a[0] = 0; \ + } while(0) + + + +#ifdef DEBUG +# define ASSERT(ctrl, expr) \ + if (!(expr)) { \ + myprintf(ctrl, "***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERT(ctrl, expr) ; +#endif + +#ifdef DEBUG +# define ASSERTP(ctrl, expr, msg) \ + if (!(expr)) { \ + myprintf(ctrl, "***ASSERTION failed on line %d of file %s:" #expr "\n", \ + __LINE__, __FILE__); \ + myprintf msg ; \ + abort(); \ + } +#else +# define ASSERTP(ctrl, expr,msg) ; +#endif + +#ifdef DEBUGS +# define ASSERTS(expr) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + abort(); \ + } +#else +# define ASSERTS(expr) ; +#endif + +#ifdef DEBUGS +# define ASSERTSP(expr, msg) \ + if (!(expr)) { \ + printf("***ASSERTION failed on line %d of file %s: " #expr "\n", \ + __LINE__, __FILE__); \ + printf msg ; \ + abort(); \ + } +#else +# define ASSERTSP(expr, msg) ; +#endif + +/************************************************************************* + * * These macros insert and remove nodes from the boundary list + * **************************************************************************/ +#define BNDInsert(nbnd, bndind, bndptr, vtx) \ + do { \ + bndind[nbnd] = vtx; \ + bndptr[vtx] = nbnd++;\ + } while(0) + +#define BNDDelete(nbnd, bndind, bndptr, vtx) \ + do { \ + bndind[bndptr[vtx]] = bndind[--nbnd]; \ + bndptr[bndind[nbnd]] = bndptr[vtx]; \ + bndptr[vtx] = -1; \ + } while(0) + + diff --git a/benchmarks/CUDA/DG/include/parmetis.h b/benchmarks/CUDA/DG/include/parmetis.h new file mode 100644 index 0000000..64a90ea --- /dev/null +++ b/benchmarks/CUDA/DG/include/parmetis.h @@ -0,0 +1,193 @@ +/* + * Copyright 1997-2003, Regents of the University of Minnesota + * + * parmetis.h + * + * This file contains function prototypes and constrant definitions for + * ParMETIS + * + * Started 7/21/03 + * George + * + */ + +#ifndef __parmetis_h__ +#define __parmetis_h__ + +#include + +#ifndef _MSC_VER +#define __cdecl +#endif + + +/************************************************************************* +* Data-structures +**************************************************************************/ +/* Undefine the following #define in order to use short int as the idxtype */ +#define IDXTYPE_INT + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +typedef int idxtype; +#else +typedef short idxtype; +#endif + + +/************************************************************************* +* Constants +**************************************************************************/ +#define PARMETIS_MAJOR_VERSION 3 +#define PARMETIS_MINOR_VERSION 1 + + +/************************************************************************* +* Function prototypes +**************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/*------------------------------------------------------------------- +* API Introduced with Release 3.0 (current API) +*--------------------------------------------------------------------*/ +void __cdecl ParMETIS_V3_AdaptiveRepart( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *vsize, idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, + int *nparts, float *tpwgts, float *ubvec, float *ipc2redist, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartGeomKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, float *xyz, + int *ncon, int *nparts, float *tpwgts, float *ubvec, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartGeom( + idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_V3_Mesh2Dual( + idxtype *elmdist, idxtype *eptr, idxtype *eind, int *numflag, + int *ncommonnodes, idxtype **xadj, idxtype **adjncy, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_PartMeshKway( + idxtype *elmdist, idxtype *eptr, idxtype *eind, idxtype *elmwgt, + int *wgtflag, int *numflag, int *ncon, int *ncommonnodes, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_V3_NodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, + int *options, idxtype *order, idxtype *sizes, MPI_Comm *comm); + +void __cdecl ParMETIS_V3_RefineKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + + + +/*------------------------------------------------------------------ +* Backward compatibility routines with Release 2.0 +*-------------------------------------------------------------------*/ +void __cdecl ParMETIS_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeomKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *ndims, float *xyz, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeom( + idxtype *vtxdist, int *ndims, float *xyz, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_PartGeomRefine( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ndims, float *xyz, + int *options, int *edgecut, idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RefineKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartLDiffusion( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartGDiffusion( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *options, int *edgecut, + idxtype *part, MPI_Comm *comm); + +void __cdecl ParMETIS_RepartRemap( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_RepartMLRemap( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, + int *wgtflag, int *numflag, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + +void __cdecl ParMETIS_NodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm); + +void __cdecl ParMETIS_SerialNodeND( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int *numflag, int *options, + idxtype *order, idxtype *sizes, MPI_Comm *comm); + + + + +/*------------------------------------------------------------------- +* Backward compatibility routines with Release 1.0 +*--------------------------------------------------------------------*/ +void __cdecl PARKMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGKMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGRMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + int ndims, float *xyz, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARGMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, int ndims, float *xyz, + idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARRMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, + idxtype *adjwgt, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARUAMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, + idxtype *adjwgt, idxtype *part, int *options, MPI_Comm comm); + +void __cdecl PARDAMETIS( + idxtype *vtxdist, idxtype *xadj, idxtype *vwgt, idxtype *adjncy, idxtype *adjwgt, + idxtype *part, int *options, MPI_Comm comm); + +#ifdef __cplusplus +} +#endif + + + + +#endif diff --git a/benchmarks/CUDA/DG/include/parmetisbin.h b/benchmarks/CUDA/DG/include/parmetisbin.h new file mode 100644 index 0000000..f0e9047 --- /dev/null +++ b/benchmarks/CUDA/DG/include/parmetisbin.h @@ -0,0 +1,31 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * par_metis.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: parmetisbin.h,v 1.1 2003/07/21 17:50:23 karypis Exp $ + */ + +/* +#define DEBUG 1 +#define DMALLOC 1 +*/ + +#include +#include "parmetis.h" + +#ifdef DMALLOC +#include +#endif + +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/include/proto.h b/benchmarks/CUDA/DG/include/proto.h new file mode 100644 index 0000000..bbab2e5 --- /dev/null +++ b/benchmarks/CUDA/DG/include/proto.h @@ -0,0 +1,352 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * proto.h + * + * This file contains header files + * + * Started 10/19/95 + * George + * + * $Id: proto.h,v 1.11 2003/07/25 13:52:03 karypis Exp $ + * + */ + +/* kmetis.c */ +void Moc_Global_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* mmetis.c */ + +/* gkmetis.c */ + +/* match.c */ +void Moc_GlobalMatch_Balance(CtrlType *, GraphType *, WorkSpaceType *); + +/* coarsen.c */ +void Moc_Global_CreateCoarseGraph(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* initpart.c */ +void Moc_InitPartition_RB(CtrlType *, GraphType *, WorkSpaceType *); +void Moc_KeepPart(GraphType *, WorkSpaceType *, idxtype *, int); + +/* kwayrefine.c */ +void Moc_ProjectPartition(CtrlType *, GraphType *, WorkSpaceType *); +void Moc_ComputePartitionParams(CtrlType *, GraphType *, WorkSpaceType *); + +/* kwayfm.c */ +void Moc_KWayFM(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* kwaybalance.c */ +void Moc_KWayBalance(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* remap.c */ +void ParallelReMapGraph(CtrlType *, GraphType *, WorkSpaceType *); +void ParallelTotalVReMap(CtrlType *, idxtype *, idxtype *, WorkSpaceType *, int, int); +int SimilarTpwgts(float *, int, int, int); + +/* move.c */ +GraphType *Moc_MoveGraph(CtrlType *, GraphType *, WorkSpaceType *); +/* move.c */ +void CheckMGraph(CtrlType *, GraphType *); +void ProjectInfoBack(CtrlType *, GraphType *, idxtype *, idxtype *, WorkSpaceType *); +void FindVtxPerm(CtrlType *, GraphType *, idxtype *, WorkSpaceType *); + +/* memory.c */ +void PreAllocateMemory(CtrlType *, GraphType *, WorkSpaceType *); +void FreeWSpace(WorkSpaceType *); +void FreeCtrl(CtrlType *); +GraphType *CreateGraph(void); +void InitGraph(GraphType *); +void FreeGraph(GraphType *); +void FreeInitialGraphAndRemap(GraphType *, int); + + +/* ametis.c */ +void Adaptive_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* rmetis.c */ + + +/* lmatch.c */ +void Mc_LocalMatch_HEM(CtrlType *, GraphType *, WorkSpaceType *); +void Mc_Local_CreateCoarseGraph(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* wave.c */ +float WavefrontDiffusion(CtrlType *, GraphType *, idxtype *); + +/* balancemylink.c */ +int BalanceMyLink(CtrlType *, GraphType *, idxtype *, int, int, float *, float, float *, float *, float); + +/* redomylink.c */ +void RedoMyLink(CtrlType *, GraphType *, idxtype *, int, int, float *, float *, float *); + +/* initbalance.c */ +void Balance_Partition(CtrlType *, GraphType *, WorkSpaceType *); +GraphType *Moc_AssembleAdaptiveGraph(CtrlType *, GraphType *, WorkSpaceType *); + +/* mdiffusion.c */ +int Moc_Diffusion(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *, WorkSpaceType *, int); +GraphType *ExtractGraph(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *); + +/* diffutil.c */ +void SetUpConnectGraph(GraphType *, MatrixType *, idxtype *); +void Mc_ComputeMoveStatistics(CtrlType *, GraphType *, int *, int *, int *); + int Mc_ComputeSerialTotalV(GraphType *, idxtype *); +void ComputeLoad(GraphType *, int, float *, float *, int); +void ConjGrad2(MatrixType *, float *, float *, float, float *); +void mvMult2(MatrixType *, float *, float *); +void ComputeTransferVector(int, MatrixType *, float *, float *, int); +int ComputeSerialEdgeCut(GraphType *); +int ComputeSerialTotalV(GraphType *, idxtype *); + +/* akwayfm.c */ +void Moc_KWayAdaptiveRefine(CtrlType *, GraphType *, WorkSpaceType *, int); + +/* selectq.c */ +void Moc_DynamicSelectQueue(int, int, int, int, idxtype *, float *, int *, int *, int, float, float); +int Moc_HashVwgts(int, float *); +int Moc_HashVRank(int, int *); + + +/* csrmatch.c */ +void CSR_Match_SHEM(MatrixType *, idxtype *, idxtype *, idxtype *, int); + +/* serial.c */ +void Moc_SerialKWayAdaptRefine(GraphType *, int, idxtype *, float *, int); +void Moc_ComputeSerialPartitionParams(GraphType *, int, EdgeType *); +int AreAllHVwgtsBelow(int, float, float *, float, float *, float *); +void ComputeHKWayLoadImbalance(int, int, float *, float *); +void SerialRemap(GraphType *, int, idxtype *, idxtype *, idxtype *, float *); +int SSMIncKeyCmp(const void *, const void *); +void Moc_Serial_FM_2WayRefine(GraphType *, float *, int); +void Serial_SelectQueue(int, float *, float *, int *, int *, FPQueueType [MAXNCON][2]); +int Serial_BetterBalance(int, float *, float *, float *); +float Serial_Compute2WayHLoadImbalance(int, float *, float *); +void Moc_Serial_Balance2Way(GraphType *, float *, float); +void Moc_Serial_Init2WayBalance(GraphType *, float *); +int Serial_SelectQueueOneWay(int, float *, float *, int, FPQueueType [MAXNCON][2]); +void Moc_Serial_Compute2WayPartitionParams(GraphType *); +int Serial_AreAnyVwgtsBelow(int, float, float *, float, float *, float *); + +/* weird.c */ +void PartitionSmallGraph(CtrlType *, GraphType *, WorkSpaceType *); +void CheckInputs(int partType, int npes, int dbglvl, int *wgtflag, int *iwgtflag, + int *numflag, int *inumflag, int *ncon, int *incon, int *nparts, + int *inparts, float *tpwgts, float **itpwgts, float *ubvec, + float *iubvec, float *ipc2redist, float *iipc2redist, int *options, + int *ioptions, idxtype *part, MPI_Comm *comm); + +/* mesh.c */ + +/* ometis.c */ + +/* pspases.c */ +GraphType *AssembleEntireGraph(CtrlType *, idxtype *, idxtype *, idxtype *); + +/* node_refine.c */ +void ComputeNodePartitionParams0(CtrlType *, GraphType *, WorkSpaceType *); +void ComputeNodePartitionParams(CtrlType *, GraphType *, WorkSpaceType *); +void KWayNodeRefine0(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void KWayNodeRefine(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void KWayNodeRefine2(CtrlType *, GraphType *, WorkSpaceType *, int, float); +void PrintNodeBalanceInfo(CtrlType *, int, idxtype *, idxtype *, idxtype *, int); + +/* initmsection.c */ +void InitMultisection(CtrlType *, GraphType *, WorkSpaceType *); +GraphType *AssembleMultisectedGraph(CtrlType *, GraphType *, WorkSpaceType *); + +/* order.c */ +void MultilevelOrder(CtrlType *, GraphType *, idxtype *, idxtype *, WorkSpaceType *); +void LabelSeparators(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *, idxtype *, WorkSpaceType *); +void CompactGraph(CtrlType *, GraphType *, idxtype *, WorkSpaceType *); +void LocalOrder(CtrlType *, GraphType *, idxtype *, int, WorkSpaceType *); +void LocalNDOrder(CtrlType *, GraphType *, idxtype *, int, WorkSpaceType *); +void Order_Partition(CtrlType *, GraphType *, WorkSpaceType *); + +/* xyzpart.c */ +void Coordinate_Partition(CtrlType *, GraphType *, int, float *, int, WorkSpaceType *); +void PartSort(CtrlType *, GraphType *, KeyValueType *, WorkSpaceType *); + + +/* fpqueue.c */ +void FPQueueInit(FPQueueType *, int); +void FPQueueReset(FPQueueType *); +void FPQueueFree(FPQueueType *); +int FPQueueGetSize(FPQueueType *); +int FPQueueInsert(FPQueueType *, int, float); +int FPQueueDelete(FPQueueType *, int); +int FPQueueUpdate(FPQueueType *, int, float, float); +void FPQueueUpdateUp(FPQueueType *, int, float, float); +int FPQueueGetMax(FPQueueType *); +int FPQueueSeeMaxVtx(FPQueueType *); +float FPQueueSeeMaxGain(FPQueueType *); +float FPQueueGetKey(FPQueueType *); +int FPQueueGetQSize(FPQueueType *); +int CheckHeapFloat(FPQueueType *); + +/* stat.c */ +void Moc_ComputeSerialBalance(CtrlType *, GraphType *, idxtype *, float *); +void Moc_ComputeParallelBalance(CtrlType *, GraphType *, idxtype *, float *); +void Moc_PrintThrottleMatrix(CtrlType *, GraphType *, float *); +void Moc_ComputeRefineStats(CtrlType *, GraphType *, float *); + +/* debug.c */ +void PrintVector(CtrlType *, int, int, idxtype *, char *); +void PrintVector2(CtrlType *, int, int, idxtype *, char *); +void PrintPairs(CtrlType *, int, KeyValueType *, char *); +void PrintGraph(CtrlType *, GraphType *); +void PrintGraph2(CtrlType *, GraphType *); +void PrintSetUpInfo(CtrlType *ctrl, GraphType *graph); +void PrintTransferedGraphs(CtrlType *, int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *); +void WriteMetisGraph(int, idxtype *, idxtype *, idxtype *, idxtype *); + +/* comm.c */ +void CommInterfaceData(CtrlType *, GraphType *, idxtype *, idxtype *, idxtype *); +void CommChangedInterfaceData(CtrlType *, GraphType *, int, idxtype *, idxtype *, KeyValueType *, KeyValueType *, idxtype *); +int GlobalSEMax(CtrlType *, int); +double GlobalSEMaxDouble(CtrlType *, double); +int GlobalSEMin(CtrlType *, int); +int GlobalSESum(CtrlType *, int); +float GlobalSEMaxFloat(CtrlType *, float); +float GlobalSEMinFloat(CtrlType *, float); +float GlobalSESumFloat(CtrlType *, float); + +/* util.c */ +void errexit(char *,...); +void myprintf(CtrlType *, char *f_str,...); +void rprintf(CtrlType *, char *f_str,...); +#ifndef DMALLOC +int *imalloc(int, char *); +idxtype *idxmalloc(int, char *); +float *fmalloc(int, char *); +int *ismalloc(int, int, char *); +idxtype *idxsmalloc(int, idxtype, char *); +void *GKmalloc(int, char *); +#endif +/*void GKfree(void **,...); */ +int *iset(int n, int val, int *x); +idxtype * idxset(int n, idxtype val, idxtype *x); +int idxamax(int n, idxtype *x); +int idxamin(int n, idxtype *x); +int idxasum(int n, idxtype *x); +float snorm2(int, float *); +float sdot(int n, float *, float *); +void saxpy(int, float, float *, float *); +void ikeyvalsort_org(int, KeyValueType *); +int IncKeyValueCmp(const void *, const void *); +void dkeyvalsort(int, KeyValueType *); +int DecKeyValueCmp(const void *, const void *); +int BSearch(int, idxtype *, int); +void RandomPermute(int, idxtype *, int); +void FastRandomPermute(int, idxtype *, int); +int ispow2(int); +int log2Int(int); +void BucketSortKeysDec(int, int, idxtype *, idxtype *); +float *sset(int n, float val, float *x); +int iamax(int, int *); +int idxamax_strd(int, idxtype *, int); +int idxamin_strd(int, idxtype *, int); +int samax_strd(int, float *, int); +int sfamax(int, float *); +int samin_strd(int, float *, int); +float idxavg(int, idxtype *); +float savg(int, float *); +int samax(int, float *); +int sfavg(int n, float *x); +int samax2(int, float *); +int samin(int, float *); +int idxsum(int, idxtype *); +int idxsum_strd(int, idxtype *, int); +void idxadd(int, idxtype *, idxtype *); +float ssum(int, float *); +float ssum_strd(int, float *, int); +void sscale(int, float, float *); +void saneg(int, float *); +float BetterVBalance(int, float *, float *, float *); +int IsHBalanceBetterTT(int, float *, float *, float *, float *); +int IsHBalanceBetterFT(int, float *, float *, float *, float *); +int myvalkeycompare(const void *, const void *); +int imyvalkeycompare(const void *, const void *); +float *fsmalloc(int, float, char *); +void saxpy2(int, float, float *, int, float *, int); +void GetThreeMax(int, float *, int *, int *, int *); + +/* qsort_special.c */ +void iidxsort(int, idxtype *); +void iintsort(int, int *); +void ikeysort(int, KeyValueType *); +void ikeyvalsort(int, KeyValueType *); + +/* grsetup.c */ +GraphType *Moc_SetUpGraph(CtrlType *, int, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int *); +void SetUpCtrl(CtrlType *ctrl, int, int, MPI_Comm); +void ChangeNumbering(idxtype *, idxtype *, idxtype *, idxtype *, int, int, int); +void ChangeNumberingMesh(idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int, int, int, int); +void ChangeNumberingMesh2(idxtype *elmdist, idxtype *eptr, idxtype *eind, + idxtype *xadj, idxtype *adjncy, idxtype *part, + int npes, int mype, int from); +void GraphRandomPermute(GraphType *); +void ComputeMoveStatistics(CtrlType *, GraphType *, int *, int *, int *); + +/* timer.c */ +void InitTimers(CtrlType *); +void PrintTimingInfo(CtrlType *); +void PrintTimer(CtrlType *, timer, char *); + +/* setup.c */ +void SetUp(CtrlType *, GraphType *, WorkSpaceType *); +int Home_PE(int, int, idxtype *, int); + + +/*********************/ +/* METIS subroutines */ +/*********************/ +void METIS_WPartGraphKway2(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_mCPartGraphRecursive2(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +int MCMlevelRecursiveBisection2(CtrlType *, GraphType *, int, float *, idxtype *, float, int); +void METIS_PartGraphKway(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, int *, int *, idxtype *); +void METIS_mCPartGraphKway(int *, int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, int *, float *, int *, int *, idxtype *); +void METIS_EdgeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_NodeComputeSeparator(int *, idxtype *, idxtype *, idxtype *, idxtype *, int *, int *, idxtype *); +void METIS_NodeND(int *, idxtype *, idxtype *, int *, int *, idxtype *, idxtype *); +void METIS_NodeNDP(int, idxtype *, idxtype *, int, int *, idxtype *, idxtype *, idxtype *); + + + +/***********************/ +/* TESTing subroutines */ +/***********************/ + +/* pio.c */ +void ParallelReadGraph(GraphType *, char *, MPI_Comm); +void Moc_ParallelWriteGraph(CtrlType *, GraphType *, char *, int, int); +void ReadTestGraph(GraphType *, char *, MPI_Comm); +float *ReadTestCoordinates(GraphType *, char *, int, MPI_Comm); +void ReadMetisGraph(char *, int *, idxtype **, idxtype **); +void Moc_SerialReadGraph(GraphType *, char *, int *, MPI_Comm); +void Moc_SerialReadMetisGraph(char *, int *, int *, int *, int *, idxtype **, idxtype **, idxtype **, idxtype **, int *); + +/* adaptgraph */ +void AdaptGraph(GraphType *, int, MPI_Comm); +void AdaptGraph2(GraphType *, int, MPI_Comm); +void Mc_AdaptGraph(GraphType *, idxtype *, int, int, MPI_Comm); + +/* ptest.c */ +void TestParMetis(char *, MPI_Comm); + +/* NEW_ptest.c */ +void TestParMetis_V3(char *, MPI_Comm); +int ComputeRealCut(idxtype *, idxtype *, char *, MPI_Comm); +int ComputeRealCut2(idxtype *, idxtype *, idxtype *, idxtype *, char *, MPI_Comm); +void TestMoveGraph(GraphType *, GraphType *, idxtype *, MPI_Comm); +GraphType *SetUpGraph(CtrlType *, idxtype *, idxtype *, idxtype *, idxtype *, idxtype *, int); + +/* mienio.c */ +void mienIO(MeshType *, char *, int, int, MPI_Comm); + +/* meshio.c */ +void ParallelReadMesh(MeshType *, char *, MPI_Comm); + +/* parmetis.c */ +void ChangeToFortranNumbering(idxtype *, idxtype *, idxtype *, int, int); + diff --git a/benchmarks/CUDA/DG/include/rename.h b/benchmarks/CUDA/DG/include/rename.h new file mode 100644 index 0000000..d993257 --- /dev/null +++ b/benchmarks/CUDA/DG/include/rename.h @@ -0,0 +1,290 @@ +/* kmetis.c */ +#define Moc_Global_Partition Moc_Global_Partition__ + +/* mmetis.c */ + +/* gkmetis.c */ + +/* match.c */ +#define Moc_GlobalMatch_Balance Moc_GlobalMatch_Balance__ + +/* coarsen.c */ +#define Moc_Global_CreateCoarseGraph Moc_Global_CreateCoarseGraph__ + +/* initpart.c */ +#define Moc_InitPartition_RB Moc_InitPartition_RB__ +#define Moc_KeepPart Moc_KeepPart__ + +/* kwayrefine.c */ +#define Moc_ProjectPartition Moc_ProjectPartition__ +#define Moc_ComputePartitionParams Moc_ComputePartitionParams__ + +/* kwayfm.c */ +#define Moc_KWayFM Moc_KWayFM__ + +/* kwaybalance.c */ +#define Moc_KWayBalance Moc_KWayBalance__ + +/* remap.c */ +#define ParallelReMapGraph ParallelReMapGraph__ +#define ParallelTotalVReMap ParallelTotalVReMap__ +#define SimilarTpwgts SimilarTpwgts__ + +/* move.c */ +#define Moc_MoveGraph Moc_MoveGraph__ +#define CheckMGraph CheckMGraph__ +#define ProjectInfoBack ProjectInfoBack__ +#define FindVtxPerm FindVtxPerm__ + +/* memory.c */ +#define PreAllocateMemory PreAllocateMemory__ +#define FreeWSpace FreeWSpace__ +#define FreeCtrl FreeCtrl__ +#define CreateGraph CreateGraph__ +#define InitGraph InitGraph__ +#define FreeGraph FreeGraph__ +#define FreeInitialGraphAndRemap FreeInitialGraphAndRemap__ + + +/************************/ +/* Adaptive subroutines */ +/************************/ +/* ametis.c */ +#define Adaptive_Partition Adaptive_Partition__ + +/* rmetis.c */ + +/* lmatch.c */ +#define Mc_LocalMatch_HEM Mc_LocalMatch_HEM__ +#define Mc_Local_CreateCoarseGraph Mc_Local_CreateCoarseGraph__ + +/* wave.c */ +#define WavefrontDiffusion WavefrontDiffusion__ + +/* balancemylink.c */ +#define BalanceMyLink BalanceMyLink__ + +/* redomylink.c */ +#define RedoMyLink RedoMyLink__ + +/* initbalance.c */ +#define Balance_Partition Balance_Partition__ +#define Moc_AssembleAdaptiveGraph Moc_AssembleAdaptiveGraph__ + +/* mdiffusion.c */ +#define Moc_Diffusion Moc_Diffusion__ +#define ExtractGraph ExtractGraph__ + +/* diffutil.c */ +#define SetUpConnectGraph SetUpConnectGraph__ +#define Mc_ComputeMoveStatistics Mc_ComputeMoveStatistics__ +#define Mc_ComputeSerialTotalV Mc_ComputeSerialTotalV__ +#define ComputeLoad ComputeLoad__ +#define ConjGrad2 ConjGrad2__ +#define mvMult2 mvMult2__ +#define ComputeTransferVector ComputeTransferVector__ +#define ComputeSerialEdgeCut ComputeSerialEdgeCut__ +#define ComputeSerialTotalV ComputeSerialTotalV__ + +/* akwayfm.c */ +#define Moc_KWayAdaptiveRefine Moc_KWayAdaptiveRefine__ + +/* selectq.c */ +#define Moc_DynamicSelectQueue Moc_DynamicSelectQueue__ +#define Moc_HashVwgts Moc_HashVwgts__ +#define Moc_HashVRank Moc_HashVRank__ + +/* csrmatch.c */ +#define CSR_Match_SHEM CSR_Match_SHEM__ + +/* serial.c */ +#define Moc_SerialKWayAdaptRefine Moc_SerialKWayAdaptRefine__ +#define Moc_ComputeSerialPartitionParams Moc_ComputeSerialPartitionParams__ +#define AreAllHVwgtsBelow AreAllHVwgtsBelow__ +#define ComputeHKWayLoadImbalance ComputeHKWayLoadImbalance__ +#define SerialRemap SerialRemap__ +#define SSMIncKeyCmp SSMIncKeyCmp__ +#define Moc_Serial_FM_2WayRefine Moc_Serial_FM_2WayRefine__ +#define Serial_SelectQueue Serial_SelectQueue__ +#define Serial_BetterBalance Serial_BetterBalance__ +#define Serial_Compute2WayHLoadImbalance Serial_Compute2WayHLoadImbalance__ +#define Moc_Serial_Balance2Way Moc_Serial_Balance2Way__ +#define Moc_Serial_Init2WayBalance Moc_Serial_Init2WayBalance__ +#define Serial_SelectQueueOneWay Serial_SelectQueueOneWay__ +#define Moc_Serial_Compute2WayPartitionParams Moc_Serial_Compute2WayPartitionParams__ +#define Serial_AreAnyVwgtsBelow Serial_AreAnyVwgtsBelow__ + +/* weird.c */ +#define PartitionSmallGraph PartitionSmallGraph__ +#define CheckInputs CheckInputs__ + + +/****************************/ +/* Mesh to Dual subroutines */ +/****************************/ +/* mesh.c */ +/* msetup.c */ +#define SetUpMesh SetUpMesh__ +#define CreateMesh CreateMesh__ +#define InitMesh InitMesh__ + + +/************************/ +/* Ordering subroutines */ +/************************/ +/* ometis.c */ +/* pspases.c */ +#define AssembleEntireGraph AssembleEntireGraph__ + +/* node_refine.c */ +#define ComputeNodePartitionParams0 ComputeNodePartitionParams0__ +#define ComputeNodePartitionParams ComputeNodePartitionParams__ +#define KWayNodeRefine0 KWayNodeRefine0__ +#define KWayNodeRefine KWayNodeRefine__ +#define KWayNodeRefine2 KWayNodeRefine2__ +#define PrintNodeBalanceInfo PrintNodeBalanceInfo__ + +/* initmsection.c */ +#define InitMultisection InitMultisection__ +#define AssembleMultisectedGraph AssembleMultisectedGraph__ + +/* order.c */ +#define MultilevelOrder MultilevelOrder__ +#define LabelSeparators LabelSeparators__ +#define CompactGraph CompactGraph__ +#define LocalOrder LocalOrder__ +#define LocalNDOrder LocalNDOrder__ +#define Order_Partition Order_Partition__ + +/* xyzpart.c */ +#define Coordinate_Partition Coordinate_Partition__ +#define PartSort PartSort__ + +/***********************/ +/* Utility subroutines */ +/***********************/ +/* fpqueue.c */ +#define FPQueueInit FPQueueInit__ +#define FPQueueReset FPQueueReset__ +#define FPQueueFree FPQueueFree__ +#define FPQueueGetSize FPQueueGetSize__ +#define FPQueueInsert FPQueueInsert__ +#define FPQueueDelete FPQueueDelete__ +#define FPQueueUpdate FPQueueUpdate__ +#define FPQueueUpdateUp FPQueueUpdateUp__ +#define FPQueueGetMax FPQueueGetMax__ +#define FPQueueSeeMaxVtx FPQueueSeeMaxVtx__ +#define FPQueueSeeMaxGain FPQueueSeeMaxGain__ +#define FPQueueGetKey FPQueueGetKey__ +#define FPQueueGetQSize FPQueueGetQSize__ +#define CheckHeapFloat CheckHeapFloat__ + +/* stat.c */ +#define Moc_ComputeSerialBalance Moc_ComputeSerialBalance__ +#define Moc_ComputeParallelBalance Moc_ComputeParallelBalance__ +#define Moc_PrintThrottleMatrix Moc_PrintThrottleMatrix__ +#define Moc_ComputeRefineStats Moc_ComputeRefineStats__ + +/* debug.c */ +#define PrintVector PrintVector__ +#define PrintVector2 PrintVector2__ +#define PrintPairs PrintPairs__ +#define PrintGraph PrintGraph__ +#define PrintGraph2 PrintGraph2__ +#define PrintSetUpInfo PrintSetUpInfo__ +#define PrintTransferedGraphs PrintTransferedGraphs__ +#define WriteMetisGraph WriteMetisGraph__ + +/* comm.c */ +#define CommInterfaceData CommInterfaceData__ +#define CommChangedInterfaceData CommChangedInterfaceData__ +#define GlobalSEMax GlobalSEMax__ +#define GlobalSEMaxDouble GlobalSEMaxDouble__ +#define GlobalSEMin GlobalSEMin__ +#define GlobalSESum GlobalSESum__ +#define GlobalSEMaxFloat GlobalSEMaxFloat__ +#define GlobalSEMinFloat GlobalSEMinFloat__ +#define GlobalSESumFloat GlobalSESumFloat__ + +/* util.c */ +#define errexit errexit__ +#define myprintf myprintf__ +#define rprintf rprintf__ +#define imalloc imalloc__ +#define idxmalloc idxmalloc__ +#define fmalloc fmalloc__ +#define ismalloc ismalloc__ +#define idxsmalloc idxsmalloc__ +#define GKmalloc GKmalloc__ +#define GKfree GKfree__ +#define iset iset__ +#define idxset idxset__ +#define idxamax idxamax__ +#define idxamin idxamin__ +#define idxasum idxasum__ +#define snorm2 snorm2__ +#define sdot sdot__ +#define saxpy saxpy__ +#define ikeyvalsort_org ikeyvalsort_org__ +#define IncKeyValueCmp IncKeyValueCmp__ +#define dkeyvalsort dkeyvalsort__ +#define DecKeyValueCmp DecKeyValueCmp__ +#define BSearch BSearch__ +#define RandomPermute RandomPermute__ +#define FastRandomPermute FastRandomPermute__ +#define ispow2 ispow2__ +#define log2Int log2Int__ +#define BucketSortKeysDec BucketSortKeysDec__ +#define sset sset__ +#define iamax iamax__ +#define idxamax_strd idxamax_strd__ +#define idxamin_strd idxamin_strd__ +#define samax_strd samax_strd__ +#define sfamax sfamax__ +#define samin_strd samin_strd__ +#define idxavg idxavg__ +#define savg savg__ +#define samax samax__ +#define sfavg sfavg__ +#define samax2 samax2__ +#define samin samin__ +#define idxsum idxsum__ +#define idxsum_strd idxsum_strd__ +#define idxadd idxadd__ +#define ssum ssum__ +#define ssum_strd ssum_strd__ +#define sscale sscale__ +#define saneg saneg__ +#define BetterVBalance BetterVBalance__ +#define IsHBalanceBetterTT IsHBalanceBetterTT__ +#define IsHBalanceBetterFT IsHBalanceBetterFT__ +#define myvalkeycompare myvalkeycompare__ +#define imyvalkeycompare imyvalkeycompare__ +#define fsmalloc fsmalloc__ +#define saxpy2 saxpy2__ +#define GetThreeMax GetThreeMax__ + +/* qsort_special.c */ +#define iidxsort iidxsort__ +#define iintsort iintsort__ +#define ikeysort ikeysort__ +#define ikeyvalsort ikeyvalsort__ + +/* grsetup.c */ +#define Moc_SetUpGraph Moc_SetUpGraph__ +#define SetUpCtrl SetUpCtrl__ +#define ChangeNumbering ChangeNumbering__ +#define ChangeNumberingMesh ChangeNumberingMesh__ +#define GraphRandomPermute GraphRandomPermute__ +#define ComputeMoveStatistics ComputeMoveStatistics__ + +/* timer.c */ +#define InitTimers InitTimers__ +#define PrintTimingInfo PrintTimingInfo__ +#define PrintTimer PrintTimer__ + +/* setup.c */ +#define SetUp SetUp__ +#define Home_PE Home_PE__ + + diff --git a/benchmarks/CUDA/DG/include/stdheaders.h b/benchmarks/CUDA/DG/include/stdheaders.h new file mode 100644 index 0000000..7135ed6 --- /dev/null +++ b/benchmarks/CUDA/DG/include/stdheaders.h @@ -0,0 +1,25 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * stdheaders.h + * + * This file includes all necessary header files + * + * Started 8/27/94 + * George + * + * $Id: stdheaders.h,v 1.4 2003/07/25 14:31:47 karypis Exp $ + */ + + +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include + diff --git a/benchmarks/CUDA/DG/include/struct.h b/benchmarks/CUDA/DG/include/struct.h new file mode 100644 index 0000000..3016c5e --- /dev/null +++ b/benchmarks/CUDA/DG/include/struct.h @@ -0,0 +1,290 @@ +/* + * Copyright 1997, Regents of the University of Minnesota + * + * struct.h + * + * This file contains data structures for ILU routines. + * + * Started 9/26/95 + * George + * + * $Id: struct.h,v 1.2 2003/07/21 17:50:22 karypis Exp $ + */ + +/* Indexes are as long as integers for now */ +#ifdef IDXTYPE_INT +#define IDX_DATATYPE MPI_INT +#define MAX_INT INT_MAX +#define MIN_INT INT_MIN +#else +#define IDX_DATATYPE MPI_SHORT +#define MAX_INT SHRT_MAX +#define MIN_INT SHRT_MIN +#endif + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KeyValueType { + idxtype key; + idxtype val; +}; + +typedef struct KeyValueType KeyValueType; + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct KVType { + int key; + float val; +}; + +typedef struct KVType KVType; + + +/************************************************************************* +* The following data structure stores key-value pair +**************************************************************************/ +struct FKeyValueType { + float key; + idxtype val; +}; + +typedef struct FKeyValueType FKeyValueType; + +/************************************************************************* +* The following data structure stores key-key-value triplets +**************************************************************************/ +struct KeyKeyValueType { + idxtype key1, key2; + idxtype val; +}; + +typedef struct KeyKeyValueType KeyKeyValueType; + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct PQueueType { + int nnodes; + int maxnnodes; + idxtype *perm, *iperm, *values; + /* iperm[i] stores where the ith entry is located + perm[i] stores the entry that is located in the ith position */ +}; + +typedef struct PQueueType PQueueType; + + +/************************************************************************* +* The following data structure is used to store the buckets for the +* refinment algorithms +**************************************************************************/ +struct FPQueueType { + int type; /* The type of the representation used */ + int nnodes; + int maxnodes; + + /* Heap version of the data structure */ + FKeyValueType *heap; + idxtype *locator; +}; + +typedef struct FPQueueType FPQueueType; + +/************************************************************************* +* The following data structure stores an edge +**************************************************************************/ +struct edgedef { + idxtype edge; + idxtype ewgt; +}; +typedef struct edgedef EdgeType; + + +/************************************************************************* +* This data structure holds various working space data +**************************************************************************/ +struct workspacedef { + idxtype *core; /* Where pairs, indices, and degrees are coming from */ + int maxcore; + + int nlarge; /* The size of 'Large' */ + + KeyValueType *pairs; /* Large pair array used during setup */ + idxtype *indices; /* Large array of indxtype used for various purposes */ + + /* Auxiliary parameters */ + idxtype *pv1, *pv2, *pv3, *pv4; /* Vectors of npes+1 size used in various places */ + KeyValueType *pepairs1, *pepairs2; + + EdgeType *degrees; +}; + +typedef struct workspacedef WorkSpaceType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct rinfodef { + int id, ed; /* ID/ED of edges */ + int ndegrees; /* The number of different ext-degrees */ + EdgeType *degrees; /* List of edges */ +}; + +typedef struct rinfodef RInfoType; + + +/************************************************************************* +* The following data structure holds information on degrees for k-way +* partition +**************************************************************************/ +struct nrinfodef { + int edegrees[2]; +}; + +typedef struct nrinfodef NRInfoType; + + +/************************************************************************* +* The following data structure stores a sparse matrix in CSR format +* The diagonal entry is in the first position of each row. +**************************************************************************/ +struct matrixdef { + int nrows, nnzs; /* Number of rows and nonzeros in the matrix */ + idxtype *rowptr; + idxtype *colind; + float *values; + float *transfer; +}; + +typedef struct matrixdef MatrixType; + + +/************************************************************************* +* This data structure holds the input graph +**************************************************************************/ +struct graphdef { + int gnvtxs, nvtxs, nedges, ncon, nobj; + idxtype *xadj; /* Pointers to the locally stored vertices */ + idxtype *vwgt; /* Vertex weights */ + float *nvwgt; /* Vertex weights */ + idxtype *vsize; /* Vertex size */ + idxtype *adjncy; /* Array that stores the adjacency lists of nvtxs */ + idxtype *adjwgt; /* Array that stores the weights of the adjacency lists */ + idxtype *vtxdist; /* Distribution of vertices */ + + idxtype *match; + idxtype *cmap; + + idxtype *label; + + /* Communication/Setup parameters */ + int nnbrs, nrecv, nsend; /* The number of neighboring processors */ + idxtype *peind; /* Array of size nnbrs storing the neighboring PEs */ + idxtype *sendptr, *sendind; /* CSR format of the vertices that are sent */ + idxtype *recvptr, *recvind; /* CSR format of the vertices that are received */ + idxtype *imap; /* The inverse map of local to global indices */ + idxtype *pexadj, *peadjncy, + *peadjloc; /* CSR format of the PEs each vertex is adjancent to */ + + int nlocal; /* Number of interior vertices */ + idxtype *lperm; /* lperm[0:nlocal] points to interior vertices, the rest are interface */ + + /* Communication parameters for projecting the partition. + * These are computed during CreateCoarseGraph and used during projection + * Note that during projection, the meaning of received and sent is reversed! */ + idxtype *rlens, *slens; /* Arrays of size nnbrs of how many vertices you are sending and receiving */ + KeyValueType *rcand; + + + /* Partition parameters */ + idxtype *where, *home; + idxtype *lpwgts, *gpwgts; + float *lnpwgts, *gnpwgts; + RInfoType *rinfo; + + /* Node refinement information */ + NRInfoType *nrinfo; + int nsep; /* The number of vertices in the separator */ + idxtype *sepind; /* The indices of the vertices in the separator */ + + int lmincut, mincut; + + int level; + int match_type; + int edgewgt_type; + + struct graphdef *coarser, *finer; +}; + +typedef struct graphdef GraphType; + + +/************************************************************************* +* The following data type implements a timer +**************************************************************************/ +typedef double timer; + + +/************************************************************************* +* The following structure stores information used by parallel kmetis +**************************************************************************/ +struct controldef { + int mype, npes; /* Info about the parallel system */ + int CoarsenTo; /* The # of vertices in the coarsest graph */ + int dbglvl; /* Controls the debuging output of the program */ + int nparts; /* The number of partitions */ + int foldf; /* What is the folding factor */ + int ipart; /* The type of initial partitioning */ + int xyztype; /* The type of coordinate indexing */ + int seed; /* Random number seed */ + int sync; /* Random number seed */ + float *tpwgts; /* Target subdomain weights */ + int tvwgts[MAXNCON]; + float ubvec[MAXNCON]; + int partType; + int ps_relation; + + float redist_factor, redist_base, ipc_factor; + float edge_size_ratio; + MatrixType *matrix; + + MPI_Comm gcomm; + MPI_Comm comm; /* MPI Communicator */ + MPI_Request sreq[MAX_PES], + rreq[MAX_PES]; /* MPI send and receive requests */ + MPI_Status statuses[MAX_PES]; + MPI_Status status; + + /* Various Timers */ + timer TotalTmr, InitPartTmr, MatchTmr, ContractTmr, CoarsenTmr, RefTmr, + SetupTmr, ColorTmr, ProjectTmr, KWayInitTmr, KWayTmr, MoveTmr, + RemapTmr, AuxTmr1, AuxTmr2, AuxTmr3, AuxTmr4, AuxTmr5, AuxTmr6; +}; + +typedef struct controldef CtrlType; + + + +/************************************************************************* +* The following data structure stores a mesh. +**************************************************************************/ +struct meshdef { + int etype; + int gnelms, gnns; + int nelms, nns; + int ncon; + int esize, gminnode; + idxtype *elmdist; + idxtype *elements; + idxtype *elmwgt; +}; + +typedef struct meshdef MeshType; + diff --git a/benchmarks/CUDA/DG/license.midg b/benchmarks/CUDA/DG/license.midg new file mode 100644 index 0000000..84eaad2 --- /dev/null +++ b/benchmarks/CUDA/DG/license.midg @@ -0,0 +1,20 @@ + +MIDG: a MIni Discontinuous Galerkin solver for CPUs or GPUS with MPI parallelism +Copyright (c) 2008, Tim Warburton +http://www.nudg.org + +-------------------------------------------------------------------------------- + +MIDG is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +MIDG is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this Module; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA diff --git a/benchmarks/CUDA/DG/readme b/benchmarks/CUDA/DG/readme new file mode 100644 index 0000000..cd2e7e6 --- /dev/null +++ b/benchmarks/CUDA/DG/readme @@ -0,0 +1,73 @@ +# ------------------------------------------------------------------------ +# see the copyright information for MIDG in license.midg +# MIDG: a MIni Discontinuous Galerkin solver for CPUs or GPUS with MPI parallelism +# Copyright (c) 2008, Tim Warburton +# http://www.nudg.org +# ------------------------------------------------------------------------ + +# The following simulation codes all run in parallel +# using ParMetis for mesh partitioning and MPI for +# parallel computation. + +# First compile the ParMetis library +cd 3rdParty/ParMetis-3.1/ +make + +# you may need to adjust the paths for the MPI compilers in the Makefiles + +# ------------------------------------------------------------------------ + +# To compile the CPU/MPI only codes: + +# CPU+MPI+2d time-domain Maxwells (TM mode) with N=6 +make -f MakefileCPU2d N=6 clean +make -f MakefileCPU2d N=6 + +# CPU+MPI+3d timw-domain Maxwells with N=6 +make -f MakefileCPU3d N=6 clean +make -f MakefileCPU3d N=6 + +# ------------------------------------------------------------------------ + +# To compile the GPU/MPI only codes: + +# NOTE FOR GPU CODES: +# 1. you may wish to change the device assignment made +# near the start of the main function in MaxwellsDriver#d.m +# 2. you will need to have nvidia's cuda framework installed +# and may need to adjust the path that the Makefiles use +# to search for the nvcc compiler, libraries and include +# files + +# GPU+MPI+2d time-domain Maxwells (TM mode) with N=6 +make -f MakefileGPU2d N=6 clean +make -f MakefileGPU2d N=6 + +# GPU+MPI+3d timw-domain Maxwells with N=6 +make -f MakefileGPU3d N=6 clean +make -f MakefileGPU3d N=6 + + +# ------------------------------------------------------------------------ + +# To run the various configurations (in serial) with sample meshes: + +./MaxwellsCPU2d Meshes/block2.neu +./MaxwellsCPU3d Meshes/cubeK268.neu +./MaxwellsGPU2d Meshes/block2.neu +./MaxwellsGPU3d Meshes/cubeK268.neu + +# ------------------------------------------------------------------------ + +# To run the various configurations (in parallel using MPI) with sample meshes: + +mpirun -np 2 ./MaxwellsCPU2d Meshes/block2.neu +mpirun -np 2 ./MaxwellsCPU3d Meshes/cubeK268.neu + +mpirun -np 2 ./MaxwellsGPU2d Meshes/block2.neu +mpirun -np 2 ./MaxwellsGPU3d Meshes/cubeK268.neu + +# When running with multiple GPUs you may wish to adjust the device +# used by each cpu. + +# ------------------------------------------------------------------------ diff --git a/benchmarks/CUDA/DG/src/BuildMaps2d.c b/benchmarks/CUDA/DG/src/BuildMaps2d.c new file mode 100644 index 0000000..7d0d57c --- /dev/null +++ b/benchmarks/CUDA/DG/src/BuildMaps2d.c @@ -0,0 +1,231 @@ +#include "mpi.h" +#include + +void BuildMaps2d(Mesh *mesh){ + + int nprocs = mesh->nprocs; + int procid = mesh->procid; + + int K = mesh->K; + int Nfaces = mesh->Nfaces; + + mesh->vmapM = BuildIntVector(p_Nfp*p_Nfaces*K); + mesh->vmapP = BuildIntVector(p_Nfp*p_Nfaces*K); + + int m; + int k1,f1,p1,n1,id1, k2,f2,p2,n2,id2; + + double x1, y1, x2, y2, d12; + + double *nxk = BuildVector(Nfaces); + double *nyk = BuildVector(Nfaces); + double *sJk = BuildVector(Nfaces); + + /* first build local */ + for(k1=0;k1 face nodes */ + for(n1=0;n1vmapM[id1] = mesh->Fmask[f1][n1] + k1*p_Np; + } + + + /* find neighbor */ + k2 = mesh->EToE[k1][f1]; + f2 = mesh->EToF[k1][f1]; + p2 = mesh->EToP[k1][f1]; + + if(k1==k2 || procid!=p2 ){ + for(n1=0;n1vmapP[id1] = k1*p_Np + mesh->Fmask[f1][n1]; + } + }else{ + /* treat as boundary for the moment */ + + for(n1=0;n1x[k1][mesh->Fmask[f1][n1]]; + y1 = mesh->y[k1][mesh->Fmask[f1][n1]]; + for(n2=0;n2x[k2][mesh->Fmask[f2][n2]]; + y2 = mesh->y[k2][mesh->Fmask[f2][n2]]; + + /* find normalized distance between these nodes */ + /* [ use sJk as a measure of edge length (ignore factor of 2) ] */ + d12 = ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/(sJk[f1]*sJk[f1]); + if(d12vmapP[id1] = k2*p_Np + mesh->Fmask[f2][n2]; + } + } + } + } + } + } + +#if 0 + int n; + for(n=0;nK;++n){ + x1 = mesh->x[0][mesh->vmapM[n]]; + y1 = mesh->y[0][mesh->vmapM[n]]; + x2 = mesh->x[0][mesh->vmapP[n]]; + y2 = mesh->y[0][mesh->vmapP[n]]; + d12 = ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); + printf("n:%d %d -> %d d=%lg\n", n, mesh->vmapM[n], mesh->vmapP[n], d12); + } +#endif + + /* now build parallel maps */ + double **xsend = (double**) calloc(nprocs, sizeof(double*)); + double **ysend = (double**) calloc(nprocs, sizeof(double*)); + double **xrecv = (double**) calloc(nprocs, sizeof(double*)); + double **yrecv = (double**) calloc(nprocs, sizeof(double*)); + + int **Esend = (int**) calloc(nprocs, sizeof(int*)); + int **Fsend = (int**) calloc(nprocs, sizeof(int*)); + int **Erecv = (int**) calloc(nprocs, sizeof(int*)); + int **Frecv = (int**) calloc(nprocs, sizeof(int*)); + + for(p2=0;p2Npar[p2]){ + xsend[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + ysend[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + Esend[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + Fsend[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + + xrecv[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + yrecv[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + Erecv[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + Frecv[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + } + } + + int *skP = BuildIntVector(nprocs); + + /* send coordinates in local order */ + int cnt = 0; + for(k1=0;k1EToP[k1][f1]; + if(p2!=procid){ + for(n1=0;n1x[k1][mesh->Fmask[f1][n1]]; + ysend[p2][skP[p2]] = mesh->y[k1][mesh->Fmask[f1][n1]]; + Esend[p2][skP[p2]] = mesh->EToE[k1][f1]; + Fsend[p2][skP[p2]] = mesh->EToF[k1][f1]; + ++(skP[p2]); + } + } + } + } + + MPI_Request *xsendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *ysendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *xrecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *yrecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Esendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Fsendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Erecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Frecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + + MPI_Status *status = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status)); + + cnt = 0; + for(p2=0;p2Npar[p2]!=0){ + int Nout = mesh->Npar[p2]*p_Nfp; + + MPI_Isend(xsend[p2], Nout, MPI_DOUBLE, p2, 666+p2, MPI_COMM_WORLD, xsendrequests+cnt); + MPI_Isend(ysend[p2], Nout, MPI_DOUBLE, p2, 1666+p2, MPI_COMM_WORLD, ysendrequests+cnt); + MPI_Isend(Esend[p2], Nout, MPI_INT, p2, 2666+p2, MPI_COMM_WORLD, Esendrequests+cnt); + MPI_Isend(Fsend[p2], Nout, MPI_INT, p2, 3666+p2, MPI_COMM_WORLD, Fsendrequests+cnt); + + MPI_Irecv(xrecv[p2], Nout, MPI_DOUBLE, p2, 666+procid, MPI_COMM_WORLD, xrecvrequests+cnt); + MPI_Irecv(yrecv[p2], Nout, MPI_DOUBLE, p2, 1666+procid, MPI_COMM_WORLD, yrecvrequests+cnt); + MPI_Irecv(Erecv[p2], Nout, MPI_INT, p2, 2666+procid, MPI_COMM_WORLD, Erecvrequests+cnt); + MPI_Irecv(Frecv[p2], Nout, MPI_INT, p2, 3666+procid, MPI_COMM_WORLD, Frecvrequests+cnt); + ++cnt; + } + } + + MPI_Waitall(cnt, xsendrequests, status); + MPI_Waitall(cnt, ysendrequests, status); + MPI_Waitall(cnt, Esendrequests, status); + MPI_Waitall(cnt, Fsendrequests, status); + MPI_Waitall(cnt, xrecvrequests, status); + MPI_Waitall(cnt, yrecvrequests, status); + MPI_Waitall(cnt, Erecvrequests, status); + MPI_Waitall(cnt, Frecvrequests, status); + + /* add up the total number of outgoing/ingoing nodes */ + mesh->parNtotalout = 0; + for(p2=0;p2parNtotalout += skP[p2]*p_Nfields; + + mesh->parmapOUT = BuildIntVector(mesh->parNtotalout); + + /* now match up local nodes with the requested (recv'ed nodes) */ + int idout = -1; + int sk = 0; + for(p2=0;p2x[k1][mesh->Fmask[f1][n1]]; + y1 = mesh->y[k1][mesh->Fmask[f1][n1]]; + + d12 = ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2))/(sJk[f1]*sJk[f1]); + + if(d12parmapOUT[sk++] = k1*BSIZE*p_Nfields+mesh->Fmask[f1][n1] + BSIZE*fld; +#else + mesh->parmapOUT[sk++] = p_Nfields*(k1*p_Np+mesh->Fmask[f1][n1]) + fld; +#endif + } + } + } + } + } + + /* create incoming node map */ + int parcnt = -1; + for(p2=0;p2EToP[k1][f1]==p2 && p2!=procid){ + for(n1=0;n1vmapP[id1] = parcnt; + --parcnt; + } + } + } + } + } + + /* buffers for communication */ + mesh->f_outQ = (float*) calloc(mesh->parNtotalout+1, sizeof(float)); + mesh->f_inQ = (float*) calloc(mesh->parNtotalout+1, sizeof(float)); + +} diff --git a/benchmarks/CUDA/DG/src/BuildMaps3d.c b/benchmarks/CUDA/DG/src/BuildMaps3d.c new file mode 100644 index 0000000..89f7a44 --- /dev/null +++ b/benchmarks/CUDA/DG/src/BuildMaps3d.c @@ -0,0 +1,279 @@ +#include "mpi.h" +#include "fem.h" + +void BuildMaps3d(Mesh *mesh){ + + printf("Hello %d\n", 1002); + + int nprocs = mesh->nprocs; + int procid = mesh->procid; + + int K = mesh->K; + int Nfaces = mesh->Nfaces; + + mesh->vmapM = BuildIntVector(p_Nfp*p_Nfaces*K); + mesh->vmapP = BuildIntVector(p_Nfp*p_Nfaces*K); + + int m; + int k1,f1,p1,n1,id1, k2,f2,p2,n2,id2; + + double x1, y1,z1, x2, y2, z2, d12; + + double *nxk = BuildVector(Nfaces); + double *nyk = BuildVector(Nfaces); + double *nzk = BuildVector(Nfaces); + double *sJk = BuildVector(Nfaces); + + printf("Hello %d\n", 1001); + + /* first build local */ + for(k1=0;k1 face nodes */ + for(n1=0;n1vmapM[id1] = mesh->Fmask[f1][n1] + k1*p_Np; + } + + + /* find neighbor */ + k2 = mesh->EToE[k1][f1]; + f2 = mesh->EToF[k1][f1]; + p2 = mesh->EToP[k1][f1]; + + if(k1==k2 || procid!=p2 ){ + for(n1=0;n1vmapP[id1] = k1*p_Np + mesh->Fmask[f1][n1]; + } + }else{ + /* treat as boundary for the moment */ + + for(n1=0;n1x[k1][mesh->Fmask[f1][n1]]; + y1 = mesh->y[k1][mesh->Fmask[f1][n1]]; + z1 = mesh->z[k1][mesh->Fmask[f1][n1]]; + + for(n2=0;n2x[k2][mesh->Fmask[f2][n2]]; + y2 = mesh->y[k2][mesh->Fmask[f2][n2]]; + z2 = mesh->z[k2][mesh->Fmask[f2][n2]]; + + /* find normalized distance between these nodes */ + /* [ use sJk as a measure of edge length (ignore factor of 2) ] */ + d12 = ((x1-x2)*(x1-x2) + + (y1-y2)*(y1-y2) + + (z1-z2)*(z1-z2)); /* /(sJk[f1]*sJk[f1]); */ + if(d12vmapP[id1] = k2*p_Np + mesh->Fmask[f2][n2]; + break; + } + } + if(n2==p_Nfp){ + printf("LOST NODE !!!\n"); + } + } + } + } + } + +#if 0 + int n; + for(k1=0;k1K;++k1){ + double drdx, dsdx, dtdx; + double drdy, dsdy, dtdy; + double drdz, dsdz, dtdz, J; + + Normals3d(mesh, k1, nxk, nyk, nzk, sJk); + + GeometricFactors3d(mesh, k1, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, &J); + + for(f1=0;f1Nfaces;++f1){ + for(m=0;mx[0][mesh->vmapM[n]]; + y1 = mesh->y[0][mesh->vmapM[n]]; + z1 = mesh->z[0][mesh->vmapM[n]]; + x2 = mesh->x[0][mesh->vmapP[n]]; + y2 = mesh->y[0][mesh->vmapP[n]]; + z2 = mesh->z[0][mesh->vmapP[n]]; + d12 = ((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2) ); + printf("n:%d %d -> %d d=%lg sJ=%lg J=%lg (%d,%d,%d,%d)\n", + n, mesh->vmapM[n], mesh->vmapP[n], d12, sJk[f1], J, + mesh->EToV[k1][0],mesh->EToV[k1][1],mesh->EToV[k1][2],mesh->EToV[k1][3]); + } + } + } +#endif + + /* now build parallel maps */ + double **xsend = (double**) calloc(nprocs, sizeof(double*)); + double **ysend = (double**) calloc(nprocs, sizeof(double*)); + double **zsend = (double**) calloc(nprocs, sizeof(double*)); + double **xrecv = (double**) calloc(nprocs, sizeof(double*)); + double **yrecv = (double**) calloc(nprocs, sizeof(double*)); + double **zrecv = (double**) calloc(nprocs, sizeof(double*)); + + int **Esend = (int**) calloc(nprocs, sizeof(int*)); + int **Fsend = (int**) calloc(nprocs, sizeof(int*)); + int **Erecv = (int**) calloc(nprocs, sizeof(int*)); + int **Frecv = (int**) calloc(nprocs, sizeof(int*)); + + for(p2=0;p2Npar[p2]){ + xsend[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + ysend[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + zsend[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + Esend[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + Fsend[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + + xrecv[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + yrecv[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + zrecv[p2] = BuildVector(mesh->Npar[p2]*p_Nfp); + Erecv[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + Frecv[p2] = BuildIntVector(mesh->Npar[p2]*p_Nfp); + } + } + + int *skP = BuildIntVector(nprocs); + + /* send coordinates in local order */ + int cnt = 0; + for(k1=0;k1EToP[k1][f1]; + if(p2!=procid){ + for(n1=0;n1x[k1][mesh->Fmask[f1][n1]]; + ysend[p2][skP[p2]] = mesh->y[k1][mesh->Fmask[f1][n1]]; + zsend[p2][skP[p2]] = mesh->z[k1][mesh->Fmask[f1][n1]]; + Esend[p2][skP[p2]] = mesh->EToE[k1][f1]; + Fsend[p2][skP[p2]] = mesh->EToF[k1][f1]; + ++(skP[p2]); + } + } + } + } + + MPI_Request *xsendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *ysendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *zsendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *xrecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *yrecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *zrecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Esendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Fsendrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Erecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + MPI_Request *Frecvrequests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + + MPI_Status *status = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status)); + + cnt = 0; + for(p2=0;p2Npar[p2]!=0){ + int Nout = mesh->Npar[p2]*p_Nfp; + + MPI_Isend(xsend[p2], Nout, MPI_DOUBLE, p2, 666+p2, MPI_COMM_WORLD, xsendrequests+cnt); + MPI_Isend(ysend[p2], Nout, MPI_DOUBLE, p2, 1666+p2, MPI_COMM_WORLD, ysendrequests+cnt); + MPI_Isend(zsend[p2], Nout, MPI_DOUBLE, p2, 4666+p2, MPI_COMM_WORLD, zsendrequests+cnt); + MPI_Isend(Esend[p2], Nout, MPI_INT, p2, 2666+p2, MPI_COMM_WORLD, Esendrequests+cnt); + MPI_Isend(Fsend[p2], Nout, MPI_INT, p2, 3666+p2, MPI_COMM_WORLD, Fsendrequests+cnt); + + MPI_Irecv(xrecv[p2], Nout, MPI_DOUBLE, p2, 666+procid, MPI_COMM_WORLD, xrecvrequests+cnt); + MPI_Irecv(yrecv[p2], Nout, MPI_DOUBLE, p2, 1666+procid, MPI_COMM_WORLD, yrecvrequests+cnt); + MPI_Irecv(zrecv[p2], Nout, MPI_DOUBLE, p2, 4666+procid, MPI_COMM_WORLD, zrecvrequests+cnt); + MPI_Irecv(Erecv[p2], Nout, MPI_INT, p2, 2666+procid, MPI_COMM_WORLD, Erecvrequests+cnt); + MPI_Irecv(Frecv[p2], Nout, MPI_INT, p2, 3666+procid, MPI_COMM_WORLD, Frecvrequests+cnt); + ++cnt; + } + } + + MPI_Waitall(cnt, xsendrequests, status); + MPI_Waitall(cnt, ysendrequests, status); + MPI_Waitall(cnt, zsendrequests, status); + MPI_Waitall(cnt, Esendrequests, status); + MPI_Waitall(cnt, Fsendrequests, status); + + MPI_Waitall(cnt, xrecvrequests, status); + MPI_Waitall(cnt, yrecvrequests, status); + MPI_Waitall(cnt, zrecvrequests, status); + MPI_Waitall(cnt, Erecvrequests, status); + MPI_Waitall(cnt, Frecvrequests, status); + + /* add up the total number of outgoing/ingoing nodes */ + mesh->parNtotalout = 0; + for(p2=0;p2parNtotalout += skP[p2]*p_Nfields; + + mesh->parmapOUT = BuildIntVector(mesh->parNtotalout); + + /* now match up local nodes with the requested (recv'ed nodes) */ + int idout = -1; + int sk = 0; + for(p2=0;p2x[k1][mesh->Fmask[f1][n1]]; + y1 = mesh->y[k1][mesh->Fmask[f1][n1]]; + z1 = mesh->z[k1][mesh->Fmask[f1][n1]]; + + d12 = sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2)); /* /(sJk[f1]*sJk[f1]); */ + + if(d12parmapOUT[sk++] = k1*BSIZE*p_Nfields+mesh->Fmask[f1][n1] + BSIZE*fld; +#else + mesh->parmapOUT[sk++] = p_Nfields*(k1*p_Np+mesh->Fmask[f1][n1]) + fld; +#endif + } + } + } + } + } + + /* create incoming node map */ + int parcnt = -1; + for(p2=0;p2EToP[k1][f1]==p2 && p2!=procid){ + for(n1=0;n1vmapP[id1] = parcnt; + --parcnt; + } + } + } + } + } + + /* buffers for communication */ + mesh->f_outQ = (float*) calloc(mesh->parNtotalout+1, sizeof(float)); + mesh->f_inQ = (float*) calloc(mesh->parNtotalout+1, sizeof(float)); + +} diff --git a/benchmarks/CUDA/DG/src/FacePair2d.c b/benchmarks/CUDA/DG/src/FacePair2d.c new file mode 100644 index 0000000..92e47f5 --- /dev/null +++ b/benchmarks/CUDA/DG/src/FacePair2d.c @@ -0,0 +1,154 @@ +#include "mpi.h" +#include "fem.h" + +typedef struct foob { + int p1, k1, f1, p2, k2, f2, va, vb, g; +}face; + +int compare_pairs(const void *obj1, const void *obj2){ + + face *e1 = (face*) obj1; + face *e2 = (face*) obj2; + + int a1 = e1->va, b1 = e1->vb; + int a2 = e2->va, b2 = e2->vb; + + int va1, vb1, va2, vb2; + + va1 = min(a1, b1); + vb1 = max(a1, b1); + + va2 = min(a2, b2); + vb2 = max(a2, b2); + + if(vb1vb2) + return 1; + else if(va1va2) + return 1; + + return 0; +} + +int pairprocget(const void *obj1){ + face *e1 = (face*) obj1; + return (e1->p1); +} + + +int pairnumget(const void *obj1){ + face *e1 = (face*) obj1; + return (e1->g); +} + +void pairnumset(const void *obj1, int g){ + face *e1 = (face*) obj1; + e1->g = g; +} + +void pairmarry(const void *obj1, const void *obj2){ + + face *e1 = (face*) obj1; + face *e2 = (face*) obj2; + e1->p2 = e2->p1; e1->k2 = e2->k1; e1->f2 = e2->f1; + e2->p2 = e1->p1; e2->k2 = e1->k1; e2->f2 = e1->f1; +} + +void FacePair2d(Mesh *mesh, int *maxNv){ + + int procid = mesh->procid; + int nprocs = mesh->nprocs; + + int Klocal = mesh->K; + int Nfaces = mesh->Nfaces; + int Nverts = mesh->Nverts; + + int **EToV = mesh->EToV; + + const int vnum[3][2] = { {0,1}, {1,2}, {2,0} }; + + int n, k, e, sk, v; + + face *myfaces = (face*) calloc(Klocal*Nfaces, sizeof(face)); + + /* find maximum local vertex number */ + int localmaxgnum = 0; + for(k=0;kNpar = BuildIntVector(nprocs); + + mesh->EToE = BuildIntMatrix(Klocal, Nfaces); + mesh->EToF = BuildIntMatrix(Klocal, Nfaces); + mesh->EToP = BuildIntMatrix(Klocal, Nfaces); + + int id, k1, k2, f1, f2, p1, p2; + sk = 0; + + for(n=0;nEToE[k1][f1] = k2; + mesh->EToF[k1][f1] = f2; + mesh->EToP[k1][f1] = p2; + + if(p1!=p2){ + /* increment number of links */ + ++mesh->Npar[p2]; + } + } + + mesh->parK = (int**) calloc(nprocs, sizeof(int*)); + mesh->parF = (int**) calloc(nprocs, sizeof(int*)); + for(p2=0;p2parK[p2] = BuildIntVector(mesh->Npar[p2]); + mesh->parF[p2] = BuildIntVector(mesh->Npar[p2]); + mesh->Npar[p2] = 0; + for(n=0;nparK[p2][mesh->Npar[p2] ] = k1; + mesh->parF[p2][mesh->Npar[p2]++] = f1; + } + } + } + + free(myfaces); +} + + diff --git a/benchmarks/CUDA/DG/src/FacePair3d.c b/benchmarks/CUDA/DG/src/FacePair3d.c new file mode 100644 index 0000000..41d1fad --- /dev/null +++ b/benchmarks/CUDA/DG/src/FacePair3d.c @@ -0,0 +1,201 @@ +#include "mpi.h" +#include "fem.h" + +typedef struct foob { + int p1, k1, f1, p2, k2, f2; + int va, vb, vc, g; +}face3d; + +int compare_pairs3d(const void *obj1, const void *obj2){ + + face3d *e1 = (face3d*) obj1; + face3d *e2 = (face3d*) obj2; + + int a1 = e1->va, b1 = e1->vb, c1 = e1->vc; + int a2 = e2->va, b2 = e2->vb, c2 = e2->vc; + + int va1, vb1, vc1, va2, vb2, vc2; + + va1 = min(a1, min(b1, c1)); + vc1 = max(a1, max(b1, c1)); + + if(va1!=a1 && vc1!=a1) vb1=a1; + if(va1!=b1 && vc1!=b1) vb1=b1; + if(va1!=c1 && vc1!=c1) vb1=c1; + + va2 = min(a2, min(b2, c2)); + vc2 = max(a2, max(b2, c2)); + + if(va2!=a2 && vc2!=a2) vb2=a2; + if(va2!=b2 && vc2!=b2) vb2=b2; + if(va2!=c2 && vc2!=c2) vb2=c2; + + if(vc1vc2) + return 1; + else if(vb1vb2) + return 1; + else if(va1va2) + return 1; + + return 0; + +} + + +int pairprocget3d(const void *obj1){ + face3d *e1 = (face3d*) obj1; + return (e1->p1); +} + + +int pairnumget3d(const void *obj1){ + face3d *e1 = (face3d*) obj1; + return (e1->g); +} + +void pairnumset3d(const void *obj1, int g){ + face3d *e1 = (face3d*) obj1; + e1->g = g; +} + +void pairmarry3d(const void *obj1, const void *obj2){ + + face3d *e1 = (face3d*) obj1; + face3d *e2 = (face3d*) obj2; + e1->p2 = e2->p1; e1->k2 = e2->k1; e1->f2 = e2->f1; + e2->p2 = e1->p1; e2->k2 = e1->k1; e2->f2 = e1->f1; +} + +void FacePair3d(Mesh *mesh, int *maxNv){ + + int procid = mesh->procid; + int nprocs = mesh->nprocs; + + int Klocal = mesh->K; + int Nfaces = mesh->Nfaces; + int Nverts = mesh->Nverts; + + int **EToV = mesh->EToV; + + const int vnum[4][3] = { {0,1,2}, {0,1,3}, {1,2,3}, {0,2,3} }; + + int n, k, e, sk, v; + + face3d *myfaces = (face3d*) calloc(Klocal*Nfaces, sizeof(face3d)); + + /* find maximum local vertex number */ + int localmaxgnum = 0; + for(k=0;kNpar = BuildIntVector(nprocs); + + mesh->EToE = BuildIntMatrix(Klocal, Nfaces); + mesh->EToF = BuildIntMatrix(Klocal, Nfaces); + mesh->EToP = BuildIntMatrix(Klocal, Nfaces); + + int id, k1, k2, f1, f2, p1, p2; + sk = 0; + + for(n=0;nEToE[k1][f1] = k2; + mesh->EToF[k1][f1] = f2; + mesh->EToP[k1][f1] = p2; + + if(p1!=p2){ + /* increment number of links */ + ++mesh->Npar[p2]; + } + } + +#if 0 + char fname[BUFSIZ]; + sprintf(fname, "proc%d.dat", mesh->procid); + FILE *fp = fopen(fname, "w"); + for(k1=0;k1K;++k1){ + for(f1=0;f1Nfaces;++f1){ + fprintf(fp, "p: (%d,%d,%d)->(%d,%d,%d)\n", + k1,f1,mesh->procid, + mesh->EToE[k1][f1], + mesh->EToF[k1][f1], + mesh->EToP[k1][f1]); + + } + } + fclose(fp); +#endif + + mesh->parK = (int**) calloc(nprocs, sizeof(int*)); + mesh->parF = (int**) calloc(nprocs, sizeof(int*)); + for(p2=0;p2parK[p2] = BuildIntVector(mesh->Npar[p2]); + mesh->parF[p2] = BuildIntVector(mesh->Npar[p2]); + mesh->Npar[p2] = 0; + for(n=0;nparK[p2][mesh->Npar[p2] ] = k1; + mesh->parF[p2][mesh->Npar[p2]++] = f1; + } + } + printf("proc: %d sends %d to proc: %d\n", + mesh->procid, mesh->Npar[p2], p2); + } + + free(myfaces); +} + + diff --git a/benchmarks/CUDA/DG/src/InitCPU3d.c b/benchmarks/CUDA/DG/src/InitCPU3d.c new file mode 100644 index 0000000..2fe907f --- /dev/null +++ b/benchmarks/CUDA/DG/src/InitCPU3d.c @@ -0,0 +1,152 @@ +#include "mpi.h" +#include "fem.h" + +double InitCPU3d(Mesh *mesh, int Nfields){ + + printf("Np = %d, BSIZE = %d\n", p_Np, BSIZE); + + /* Q */ + int sz = mesh->K*(p_Np)*Nfields*sizeof(float); /* TW BLOCK */ + + mesh->f_Q = (float*) calloc(mesh->K*p_Np*Nfields, sizeof(float)); + mesh->f_rhsQ = (float*) calloc(mesh->K*p_Np*Nfields, sizeof(float)); + mesh->f_resQ = (float*) calloc(mesh->K*p_Np*Nfields, sizeof(float)); + + /* float LIFT */ + sz = p_Np*(p_Nfp)*(p_Nfaces)*sizeof(float); + mesh->f_LIFT = (float*) malloc(sz); + int sk = 0, n, m, f, k; + + for(n=0;nf_LIFT[sk++] = mesh->LIFT[n][m]; + } + } + + /* float Dr & Ds */ + sz = p_Np*p_Np*sizeof(float); + mesh->f_Dr = (float*) malloc(sz); + mesh->f_Ds = (float*) malloc(sz); + mesh->f_Dt = (float*) malloc(sz); + + sk = 0; + for(n=0;nf_Dr[sk] = mesh->Dr[n][m]; + mesh->f_Ds[sk] = mesh->Ds[n][m]; + mesh->f_Dt[sk] = mesh->Dt[n][m]; + ++sk; + } + } + + /* vgeo */ + double drdx, dsdx, dtdx; + double drdy, dsdy, dtdy; + double drdz, dsdz, dtdz, J; + mesh->vgeo = (float*) calloc(12*mesh->K, sizeof(float)); + + for(k=0;kK;++k){ + GeometricFactors3d(mesh, k, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, &J); + + mesh->vgeo[k*12+0] = drdx; mesh->vgeo[k*12+1] = drdy; mesh->vgeo[k*12+2] = drdz; + mesh->vgeo[k*12+4] = dsdx; mesh->vgeo[k*12+5] = dsdy; mesh->vgeo[k*12+6] = dsdz; + mesh->vgeo[k*12+8] = dtdx; mesh->vgeo[k*12+9] = dtdy; mesh->vgeo[k*12+10] = dtdz; + } + + /* surfinfo (vmapM, vmapP, Fscale, Bscale, nx, ny, nz, 0) */ + sz = mesh->K*p_Nfp*p_Nfaces*7*sizeof(float); + + mesh->surfinfo = (float*) malloc(sz); + + /* local-local info */ + sk = 0; + int skP = -1; + double *nxk = BuildVector(mesh->Nfaces); + double *nyk = BuildVector(mesh->Nfaces); + double *nzk = BuildVector(mesh->Nfaces); + double *sJk = BuildVector(mesh->Nfaces); + + double dt = 1e6; + + sk = 0; + for(k=0;kK;++k){ + + GeometricFactors3d(mesh, k, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, &J); + + Normals3d(mesh, k, nxk, nyk, nzk, sJk); + + for(f=0;fNfaces;++f){ + + dt = min(dt, J/sJk[f]); + + for(m=0;mvmapM[id]; + int idP = mesh->vmapP[id]; + int nM = idM%p_Np; + int nP = idP%p_Np; + int kM = (idM-nM)/p_Np; + int kP = (idP-nP)/p_Np; + idM = Nfields*(nM + p_Np*kM); + idP = Nfields*(nP + p_Np*kP); + + /* stub resolve some other way */ + if(mesh->vmapP[id]<0){ + idP = mesh->vmapP[id]; /* -ve numbers */ + } + + mesh->surfinfo[sk++] = idM; + mesh->surfinfo[sk++] = idP; + mesh->surfinfo[sk++] = sJk[f]/(2.*J); + mesh->surfinfo[sk++] = (idM==idP)?-1.:1.; + mesh->surfinfo[sk++] = nxk[f]; + mesh->surfinfo[sk++] = nyk[f]; + mesh->surfinfo[sk++] = nzk[f]; + } + } + } +} + +void cpu_set_data3d(Mesh *mesh, double *Hx, double *Hy, double *Hz, + double *Ex, double *Ey, double *Ez){ + + const int K = mesh->K; + int k, n, sk=0; + + for(k=0;kf_Q[sk++] = Hx[n+k*p_Np]; + mesh->f_Q[sk++] = Hy[n+k*p_Np]; + mesh->f_Q[sk++] = Hz[n+k*p_Np]; + mesh->f_Q[sk++] = Ex[n+k*p_Np]; + mesh->f_Q[sk++] = Ey[n+k*p_Np]; + mesh->f_Q[sk++] = Ez[n+k*p_Np]; + } + } + +} + + +void cpu_get_data3d(Mesh *mesh, double *Hx, double *Hy, double *Hz, + double *Ex, double *Ey, double *Ez){ + const int K = mesh->K; + int k, n, sk=0; + + for(k=0;kf_Q[sk++]; + Hy[n+k*p_Np] = mesh->f_Q[sk++]; + Hz[n+k*p_Np] = mesh->f_Q[sk++]; + Ex[n+k*p_Np] = mesh->f_Q[sk++]; + Ey[n+k*p_Np] = mesh->f_Q[sk++]; + Ez[n+k*p_Np] = mesh->f_Q[sk++]; + } + } + +} diff --git a/benchmarks/CUDA/DG/src/LoadBalance3d.c b/benchmarks/CUDA/DG/src/LoadBalance3d.c new file mode 100644 index 0000000..586cd8c --- /dev/null +++ b/benchmarks/CUDA/DG/src/LoadBalance3d.c @@ -0,0 +1,243 @@ +#include "mpi.h" +#include + +#include "fem.h" + +void LoadBalance3d(Mesh *mesh){ + + int n,p,k,v,f; + + int nprocs = mesh->nprocs; + int procid = mesh->procid; + int **EToV = mesh->EToV; + double **VX = mesh->GX; + double **VY = mesh->GY; + double **VZ = mesh->GZ; + + if(!procid) printf("Root: Entering LoadBalance\n"); + + int Nverts = mesh->Nverts; + + int *Kprocs = BuildIntVector(nprocs); + + /* local number of elements */ + int Klocal = mesh->K; + + /* find number of elements on all processors */ + MPI_Allgather(&Klocal, 1, MPI_INT, Kprocs, 1, MPI_INT, MPI_COMM_WORLD); + + /* element distribution -- cumulative element count on processes */ + idxtype *elmdist = idxmalloc(nprocs+1, "elmdist"); + + elmdist[0] = 0; + for(p=0;pGX!=NULL){ + DestroyMatrix(mesh->GX); + DestroyMatrix(mesh->GY); + DestroyMatrix(mesh->GZ); + DestroyIntMatrix(mesh->EToV); + } + + mesh->GX = newVX; + mesh->GY = newVY; + mesh->GZ = newVZ; + mesh->EToV = newEToV; + mesh->K = totalinK; + + for(p=0;pK*p_Np, sizeof(double)); + double *Hy = (double*) calloc(mesh->K*p_Np, sizeof(double)); + double *Hz = (double*) calloc(mesh->K*p_Np, sizeof(double)); + double *Ex = (double*) calloc(mesh->K*p_Np, sizeof(double)); + double *Ey = (double*) calloc(mesh->K*p_Np, sizeof(double)); + double *Ez = (double*) calloc(mesh->K*p_Np, sizeof(double)); + + /* initial conditions */ + for(k=0;kK;++k){ + for(n=0;nx[k][n])*cos(M_PI*mesh->y[k][n])*cos(M_PI*mesh->z[k][n]); + ++sk; + } + } + + double dt, gdt; + +#ifdef CUDA + /* initialize GPU info */ + dt = InitGPU3d(mesh, p_Nfields); + + /* load data onto GPU */ + gpu_set_data3d(mesh->K, Hx, Hy, Hz, Ex, Ey, Ez); +#else + /* initialize GPU info */ + dt = InitCPU3d(mesh, p_Nfields); + + /* load data onto CPU float storage */ + cpu_set_data3d(mesh, Hx, Hy, Hz, Ex, Ey, Ez); +#endif + + MPI_Allreduce(&dt, &gdt, 1, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD); + + dt = .5*gdt/((p_N+1)*(p_N+1)); + + if(mesh->procid==0) + printf("dt = %f\n", dt); + + double FinalTime = .00050; + + /* solve */ + MaxwellsRun3d(mesh, FinalTime, dt); + +#ifdef CUDA + /* unload data from GPU */ + gpu_get_data3d(mesh->K, Hx, Hy, Hz, Ex, Ey, Ez); +#else + cpu_get_data3d(mesh, Hx, Hy, Hz, Ex, Ey, Ez); +#endif + + /* find maximum & minimum values for Ez */ + minEz=Ez[0], maxEz=Ez[0]; + + for(n=0;nK*p_Np;++n) { + minEz = (minEz>Ez[n])?Ez[n]:minEz; + maxEz = (maxEz +#include + +texture t_LIFT; +texture t_DrDsDt; +texture t_Dr; +texture t_Ds; +texture t_Dt; +texture t_vgeo; +texture t_vgeo4; +texture t_Q; +texture t_partQ; +texture t_surfinfo; + +static float *c_LIFT; +static float *c_DrDsDt; +static float *c_surfinfo; +static float *c_vgeo; +static float *c_Q; +static float *c_partQ; +static float *c_rhsQ; +static float *c_resQ; +static float *c_tmp; + +extern "C" +{ + +#include "fem.h" + +double InitGPU3d(Mesh *mesh, int Nfields){ + + /* Q */ + int sz = mesh->K*(BSIZE)*p_Nfields*sizeof(float); + + float *f_Q = (float*) calloc(mesh->K*BSIZE*p_Nfields, sizeof(float)); + cudaMalloc ((void**) &c_Q, sz); + cudaMalloc ((void**) &c_rhsQ, sz); + cudaMalloc ((void**) &c_resQ, sz); + cudaMalloc ((void**) &c_tmp, sz); + cudaMemcpy( c_Q, f_Q, sz, cudaMemcpyHostToDevice); + cudaMemcpy( c_rhsQ, f_Q, sz, cudaMemcpyHostToDevice); + cudaMemcpy( c_resQ, f_Q, sz, cudaMemcpyHostToDevice); + cudaMemcpy( c_tmp, f_Q, sz, cudaMemcpyHostToDevice); + + cudaBindTexture(0, t_Q, c_Q, sz); + + sz = mesh->parNtotalout*sizeof(float); + cudaMalloc((void**) &c_partQ, sz); + cudaBindTexture(0, t_partQ, c_partQ, sz); + + /* LIFT */ + sz = p_Np*(p_Nfp)*p_Nfaces*sizeof(float); +#if 0 + float *f_LIFT = (float*) malloc(sz); + int skL = 0; + for(int m=0;mLIFT[0][p_Nfp*p_Nfaces*n+(f+p_Nfaces*m)]; + } + } + } +#endif + cudaMalloc ((void**) &c_LIFT, sz); + cudaMemcpy( c_LIFT, f_LIFT, sz, cudaMemcpyHostToDevice); + + /* Bind the array to the texture */ + cudaBindTexture(0, t_LIFT, c_LIFT, sz); + + /* DrDsDt */ + sz = BSIZE*BSIZE*4*sizeof(float); + + float* h_DrDsDt = (float*) calloc(BSIZE*BSIZE, sizeof(float4)); + int sk = 0; + /* note transposed arrays to avoid "bank conflicts" */ + for(int n=0;nDr[0][n+m*p_Np]; + h_DrDsDt[4*(m+n*BSIZE)+1] = mesh->Ds[0][n+m*p_Np]; + h_DrDsDt[4*(m+n*BSIZE)+2] = mesh->Dt[0][n+m*p_Np]; + } + } + + cudaMalloc ((void**) &c_DrDsDt, sz); + cudaMemcpy( c_DrDsDt, h_DrDsDt, sz, cudaMemcpyHostToDevice); + + /* Bind the array to the texture */ + cudaBindTexture(0, t_DrDsDt, c_DrDsDt, sz); + + free(h_DrDsDt); + + /* vgeo */ + double drdx, dsdx, dtdx; + double drdy, dsdy, dtdy; + double drdz, dsdz, dtdz, J; + float *vgeo = (float*) calloc(12*mesh->K, sizeof(float)); + + for(int k=0;kK;++k){ + GeometricFactors3d(mesh, k, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, &J); + + vgeo[k*12+0] = drdx; vgeo[k*12+1] = drdy; vgeo[k*12+2] = drdz; + vgeo[k*12+4] = dsdx; vgeo[k*12+5] = dsdy; vgeo[k*12+6] = dsdz; + vgeo[k*12+8] = dtdx; vgeo[k*12+9] = dtdy; vgeo[k*12+10] = dtdz; + + } + + sz = mesh->K*12*sizeof(float); + cudaMalloc ((void**) &c_vgeo, sz); + cudaMemcpy( c_vgeo, vgeo, sz, cudaMemcpyHostToDevice); + cudaBindTexture(0, t_vgeo, c_vgeo, sz); + + /* surfinfo (vmapM, vmapP, Fscale, Bscale, nx, ny, nz, 0) */ + sz = mesh->K*p_Nfp*p_Nfaces*7*sizeof(float); + float* h_surfinfo = (float*) malloc(sz); + + /* local-local info */ + sk = 0; + int skP = -1; + double *nxk = BuildVector(mesh->Nfaces); + double *nyk = BuildVector(mesh->Nfaces); + double *nzk = BuildVector(mesh->Nfaces); + double *sJk = BuildVector(mesh->Nfaces); + + double dt = 1e6; + + for(int k=0;kK;++k){ + + GeometricFactors3d(mesh, k, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, &J); + + Normals3d(mesh, k, nxk, nyk, nzk, sJk); + + for(int f=0;fNfaces;++f){ + + dt = min(dt, J/sJk[f]); + + for(int m=0;mvmapM[n]; + int idP = mesh->vmapP[n]; + int nM = idM%p_Np; + int nP = idP%p_Np; + int kM = (idM-nM)/p_Np; + int kP = (idP-nP)/p_Np; + idM = nM + Nfields*BSIZE*kM; + idP = nP + Nfields*BSIZE*kP; + + /* stub resolve some other way */ + if(mesh->vmapP[n]<0){ + idP = mesh->vmapP[n]; /* -ve numbers */ + } + + sk = 7*p_Nfp*p_Nfaces*k+m+f*p_Nfp; + h_surfinfo[sk + 0*p_Nfp*p_Nfaces] = idM; + h_surfinfo[sk + 1*p_Nfp*p_Nfaces] = idP; + h_surfinfo[sk + 2*p_Nfp*p_Nfaces] = sJk[f]/(2.*J); + h_surfinfo[sk + 3*p_Nfp*p_Nfaces] = (idM==idP)?-1.:1.; + h_surfinfo[sk + 4*p_Nfp*p_Nfaces] = nxk[f]; + h_surfinfo[sk + 5*p_Nfp*p_Nfaces] = nyk[f]; + h_surfinfo[sk + 6*p_Nfp*p_Nfaces] = nzk[f]; + } + } + } + + cudaMalloc ((void**) &c_surfinfo, sz); + cudaMemcpy( c_surfinfo, h_surfinfo, sz, cudaMemcpyHostToDevice); + + cudaBindTexture(0, t_surfinfo, c_surfinfo, sz); + + free(h_surfinfo); + + sz = mesh->parNtotalout*sizeof(int); + cudaMalloc((void**) &(mesh->c_parmapOUT), sz); + cudaMemcpy(mesh->c_parmapOUT, mesh->parmapOUT, sz, cudaMemcpyHostToDevice); + + return dt; +} + + + +__global__ void MaxwellsGPU_VOL_Kernel3D(float *g_rhsQ){ + + /* fastest */ + __device__ __shared__ float s_Q[p_Nfields*BSIZE]; + __device__ __shared__ float s_facs[12]; + + const int n = threadIdx.x; + const int k = blockIdx.x; + + /* "coalesced" */ + int m = n+k*p_Nfields*BSIZE; + int id = n; + s_Q[id] = tex1Dfetch(t_Q, m); m+=BSIZE; id+=BSIZE; + s_Q[id] = tex1Dfetch(t_Q, m); m+=BSIZE; id+=BSIZE; + s_Q[id] = tex1Dfetch(t_Q, m); m+=BSIZE; id+=BSIZE; + s_Q[id] = tex1Dfetch(t_Q, m); m+=BSIZE; id+=BSIZE; + s_Q[id] = tex1Dfetch(t_Q, m); m+=BSIZE; id+=BSIZE; + s_Q[id] = tex1Dfetch(t_Q, m); + + if(p_Np<12 && n==0) + for(m=0;m<12;++m) + s_facs[m] = tex1Dfetch(t_vgeo, 12*k+m); + else if(n<12 && p_Np>=12) + s_facs[n] = tex1Dfetch(t_vgeo, 12*k+n); + + __syncthreads(); + + float dHxdr=0,dHxds=0,dHxdt=0; + float dHydr=0,dHyds=0,dHydt=0; + float dHzdr=0,dHzds=0,dHzdt=0; + float dExdr=0,dExds=0,dExdt=0; + float dEydr=0,dEyds=0,dEydt=0; + float dEzdr=0,dEzds=0,dEzdt=0; + float Q; + + for(m=0;p_Np-m;){ + float4 D = tex1Dfetch(t_DrDsDt, n+m*BSIZE); + + id = m; + Q = s_Q[id]; dHxdr += D.x*Q; dHxds += D.y*Q; dHxdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHydr += D.x*Q; dHyds += D.y*Q; dHydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHzdr += D.x*Q; dHzds += D.y*Q; dHzdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dExdr += D.x*Q; dExds += D.y*Q; dExdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEydr += D.x*Q; dEyds += D.y*Q; dEydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEzdr += D.x*Q; dEzds += D.y*Q; dEzdt += D.z*Q; + + ++m; +#if ( (p_Np) % 2 )==0 + D = tex1Dfetch(t_DrDsDt, n+m*BSIZE); + + id = m; + Q = s_Q[id]; dHxdr += D.x*Q; dHxds += D.y*Q; dHxdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHydr += D.x*Q; dHyds += D.y*Q; dHydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHzdr += D.x*Q; dHzds += D.y*Q; dHzdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dExdr += D.x*Q; dExds += D.y*Q; dExdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEydr += D.x*Q; dEyds += D.y*Q; dEydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEzdr += D.x*Q; dEzds += D.y*Q; dEzdt += D.z*Q; + + ++m; + +#if ( (p_Np)%3 )==0 + D = tex1Dfetch(t_DrDsDt, n+m*BSIZE); + + id = m; + Q = s_Q[id]; dHxdr += D.x*Q; dHxds += D.y*Q; dHxdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHydr += D.x*Q; dHyds += D.y*Q; dHydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dHzdr += D.x*Q; dHzds += D.y*Q; dHzdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dExdr += D.x*Q; dExds += D.y*Q; dExdt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEydr += D.x*Q; dEyds += D.y*Q; dEydt += D.z*Q; id += BSIZE; + Q = s_Q[id]; dEzdr += D.x*Q; dEzds += D.y*Q; dEzdt += D.z*Q; + + ++m; +#endif +#endif + } + + const float drdx= s_facs[0]; + const float drdy= s_facs[1]; + const float drdz= s_facs[2]; + const float dsdx= s_facs[4]; + const float dsdy= s_facs[5]; + const float dsdz= s_facs[6]; + const float dtdx= s_facs[8]; + const float dtdy= s_facs[9]; + const float dtdz= s_facs[10]; + + m = n+p_Nfields*BSIZE*k; + + g_rhsQ[m] = -(drdy*dEzdr+dsdy*dEzds+dtdy*dEzdt - drdz*dEydr-dsdz*dEyds-dtdz*dEydt); m += BSIZE; + g_rhsQ[m] = -(drdz*dExdr+dsdz*dExds+dtdz*dExdt - drdx*dEzdr-dsdx*dEzds-dtdx*dEzdt); m += BSIZE; + g_rhsQ[m] = -(drdx*dEydr+dsdx*dEyds+dtdx*dEydt - drdy*dExdr-dsdy*dExds-dtdy*dExdt); m += BSIZE; + g_rhsQ[m] = (drdy*dHzdr+dsdy*dHzds+dtdy*dHzdt - drdz*dHydr-dsdz*dHyds-dtdz*dHydt); m += BSIZE; + g_rhsQ[m] = (drdz*dHxdr+dsdz*dHxds+dtdz*dHxdt - drdx*dHzdr-dsdx*dHzds-dtdx*dHzdt); m += BSIZE; + g_rhsQ[m] = (drdx*dHydr+dsdx*dHyds+dtdx*dHydt - drdy*dHxdr-dsdy*dHxds-dtdy*dHxdt); +} + +__global__ void MaxwellsGPU_SURF_Kernel3D(float *g_Q, float *g_rhsQ){ + + __device__ __shared__ float s_fluxQ[p_Nfields*p_Nfp*p_Nfaces]; + + const int n = threadIdx.x; + const int k = blockIdx.x; + int m; + + /* grab surface nodes and store flux in shared memory */ + if(n< (p_Nfp*p_Nfaces) ){ + /* coalesced reads (maybe) */ + m = 7*(k*p_Nfp*p_Nfaces)+n; + const int idM = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + int idP = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + const float Fsc = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + const float Bsc = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + const float nx = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + const float ny = tex1Dfetch(t_surfinfo, m); m += p_Nfp*p_Nfaces; + const float nz = tex1Dfetch(t_surfinfo, m); + + /* check if idP<0 */ + double dHx, dHy, dHz, dEx, dEy, dEz; + if(idP<0){ + idP = p_Nfields*(-1-idP); + + dHx = Fsc*(tex1Dfetch(t_partQ, idP+0) - tex1Dfetch(t_Q, idM+0*BSIZE)); + dHy = Fsc*(tex1Dfetch(t_partQ, idP+1) - tex1Dfetch(t_Q, idM+1*BSIZE)); + dHz = Fsc*(tex1Dfetch(t_partQ, idP+2) - tex1Dfetch(t_Q, idM+2*BSIZE)); + + dEx = Fsc*(tex1Dfetch(t_partQ, idP+3) - tex1Dfetch(t_Q, idM+3*BSIZE)); + dEy = Fsc*(tex1Dfetch(t_partQ, idP+4) - tex1Dfetch(t_Q, idM+4*BSIZE)); + dEz = Fsc*(tex1Dfetch(t_partQ, idP+5) - tex1Dfetch(t_Q, idM+5*BSIZE)); + } + else{ + dHx = Fsc*(tex1Dfetch(t_Q, idP+0*BSIZE) - tex1Dfetch(t_Q, idM+0*BSIZE)); + dHy = Fsc*(tex1Dfetch(t_Q, idP+1*BSIZE) - tex1Dfetch(t_Q, idM+1*BSIZE)); + dHz = Fsc*(tex1Dfetch(t_Q, idP+2*BSIZE) - tex1Dfetch(t_Q, idM+2*BSIZE)); + + dEx = Fsc*(Bsc*tex1Dfetch(t_Q, idP+3*BSIZE) - tex1Dfetch(t_Q, idM+3*BSIZE)); + dEy = Fsc*(Bsc*tex1Dfetch(t_Q, idP+4*BSIZE) - tex1Dfetch(t_Q, idM+4*BSIZE)); + dEz = Fsc*(Bsc*tex1Dfetch(t_Q, idP+5*BSIZE) - tex1Dfetch(t_Q, idM+5*BSIZE)); + } + + const double ndotdH = nx*dHx + ny*dHy + nz*dHz; + const double ndotdE = nx*dEx + ny*dEy + nz*dEz; + + m = n; + s_fluxQ[m] = -ny*dEz + nz*dEy + dHx - ndotdH*nx; m += p_Nfp*p_Nfaces; + s_fluxQ[m] = -nz*dEx + nx*dEz + dHy - ndotdH*ny; m += p_Nfp*p_Nfaces; + s_fluxQ[m] = -nx*dEy + ny*dEx + dHz - ndotdH*nz; m += p_Nfp*p_Nfaces; + + s_fluxQ[m] = ny*dHz - nz*dHy + dEx - ndotdE*nx; m += p_Nfp*p_Nfaces; + s_fluxQ[m] = nz*dHx - nx*dHz + dEy - ndotdE*ny; m += p_Nfp*p_Nfaces; + s_fluxQ[m] = nx*dHy - ny*dHx + dEz - ndotdE*nz; + } + + /* make sure all element data points are cached */ + __syncthreads(); + + if(n< (p_Np)) + { + float rhsHx = 0, rhsHy = 0, rhsHz = 0; + float rhsEx = 0, rhsEy = 0, rhsEz = 0; + + int sk = n; + /* can manually unroll to 4 because there are 4 faces */ + for(m=0;p_Nfaces*p_Nfp-m;){ + const float4 L = tex1Dfetch(t_LIFT, sk); sk+=p_Np; + + /* broadcast */ + int sk1 = m; + rhsHx += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHy += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHz += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEx += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEy += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEz += L.x*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + ++m; + + /* broadcast */ + sk1 = m; + rhsHx += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHy += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHz += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEx += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEy += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEz += L.y*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + ++m; + + /* broadcast */ + sk1 = m; + rhsHx += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHy += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHz += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEx += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEy += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEz += L.z*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + ++m; + + /* broadcast */ + sk1 = m; + rhsHx += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHy += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsHz += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEx += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEy += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + rhsEz += L.w*s_fluxQ[sk1]; sk1 += p_Nfp*p_Nfaces; + ++m; + + } + + m = n+p_Nfields*k*BSIZE; + g_rhsQ[m] += rhsHx; m += BSIZE; + g_rhsQ[m] += rhsHy; m += BSIZE; + g_rhsQ[m] += rhsHz; m += BSIZE; + g_rhsQ[m] += rhsEx; m += BSIZE; + g_rhsQ[m] += rhsEy; m += BSIZE; + g_rhsQ[m] += rhsEz; m += BSIZE; + + } +} + + +__global__ void MaxwellsGPU_RK_Kernel3D(int Ntotal, float *g_resQ, float *g_rhsQ, float *g_Q, float fa, float fb, float fdt){ + + int n = blockIdx.x * blockDim.x + threadIdx.x; + + if(nK; + ThreadsPerBlock = p_Np; + + /* evaluate volume derivatives */ + MaxwellsGPU_VOL_Kernel3D <<< BlocksPerGrid, ThreadsPerBlock >>> (c_rhsQ); + + /* finalize sends and recvs, and transfer to device */ + MaxwellsMPIRecv3d(mesh, c_partQ); + + BlocksPerGrid = mesh->K; + + if( ( p_Nfp*p_Nfaces ) > (p_Np) ) + ThreadsPerBlock = p_Nfp*p_Nfaces; + else + ThreadsPerBlock = p_Np; + + /* evaluate surface contributions */ + MaxwellsGPU_SURF_Kernel3D <<< BlocksPerGrid, ThreadsPerBlock >>> (c_Q, c_rhsQ); + + int Ntotal = mesh->K*BSIZE*p_Nfields; + + ThreadsPerBlock = 256; + BlocksPerGrid = (Ntotal+ThreadsPerBlock-1)/ThreadsPerBlock; + + /* update RK Step */ + MaxwellsGPU_RK_Kernel3D<<< BlocksPerGrid, ThreadsPerBlock >>> + (Ntotal, c_resQ, c_rhsQ, c_Q, frka, frkb, fdt); + +} + + + + +void gpu_set_data3d(int K, + double *d_Hx, double *d_Hy, double *d_Hz, + double *d_Ex, double *d_Ey, double *d_Ez){ + + + float *f_Q = (float*) calloc(K*p_Nfields*BSIZE,sizeof(float)); + + /* also load into usual data matrices */ + + for(int k=0;k>> (Ntotal, g_index, c_tmp); + + cudaMemcpy(h_partQ, c_tmp, Ntotal*sizeof(float), cudaMemcpyDeviceToHost); +} + +} diff --git a/benchmarks/CUDA/DG/src/MaxwellsMPI3d.c b/benchmarks/CUDA/DG/src/MaxwellsMPI3d.c new file mode 100644 index 0000000..6bdf46f --- /dev/null +++ b/benchmarks/CUDA/DG/src/MaxwellsMPI3d.c @@ -0,0 +1,71 @@ + +#include "mpi.h" +#include + +#include "fem.h" + +static MPI_Request *mpi_out_requests = NULL; +static MPI_Request *mpi_in_requests = NULL; + +static int Nmess = 0; + +void MaxwellsMPISend3d(Mesh *mesh){ + + int p; + + int procid = mesh->procid; + int nprocs = mesh->nprocs; + + MPI_Status status; + + if(mpi_out_requests==NULL){ + mpi_out_requests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + mpi_in_requests = (MPI_Request*) calloc(nprocs, sizeof(MPI_Request)); + } + +#ifdef CUDA + get_partial_gpu_data3d(mesh->parNtotalout, mesh->c_parmapOUT, mesh->f_outQ); +#endif + + /* non-blocked send/recv partition surface data */ + Nmess = 0; + + /* now send piece to each proc */ + int sk = 0; + for(p=0;pNpar[p]*p_Nfields*p_Nfp; + if(Nout){ + /* symmetric communications (different ordering) */ + MPI_Isend(mesh->f_outQ+sk, Nout, MPI_FLOAT, p, 6666+p, MPI_COMM_WORLD, mpi_out_requests +Nmess); + MPI_Irecv(mesh->f_inQ+sk, Nout, MPI_FLOAT, p, 6666+procid, MPI_COMM_WORLD, mpi_in_requests +Nmess); + sk+=Nout; + ++Nmess; + } + } + } + +} + + +void MaxwellsMPIRecv3d(Mesh *mesh, float *c_partQ){ + int p, n; + int nprocs = mesh->nprocs; + + MPI_Status *instatus = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status)); + MPI_Status *outstatus = (MPI_Status*) calloc(nprocs, sizeof(MPI_Status)); + + MPI_Waitall(Nmess, mpi_in_requests, instatus); + +#ifdef CUDA + cudaMemcpy(c_partQ, mesh->f_inQ, mesh->parNtotalout*sizeof(float), cudaMemcpyHostToDevice); +#endif + + MPI_Waitall(Nmess, mpi_out_requests, outstatus); + + free(outstatus); + free(instatus); + +} + diff --git a/benchmarks/CUDA/DG/src/MaxwellsRHS3d.c b/benchmarks/CUDA/DG/src/MaxwellsRHS3d.c new file mode 100644 index 0000000..13ed5bf --- /dev/null +++ b/benchmarks/CUDA/DG/src/MaxwellsRHS3d.c @@ -0,0 +1,220 @@ +#include "mpi.h" +#include "fem.h" + +void MaxwellsRHS3d(Mesh *mesh, float frka, float frkb, float fdt){ + + /* registers and temporary */ + register unsigned int k, n; + + /* mesh parameters */ + const int K = mesh->K; + + float *vgeo = mesh->vgeo; + float *surfinfo = mesh->surfinfo; + float *f_Dr = mesh->f_Dr; + float *f_Ds = mesh->f_Ds; + float *f_Dt = mesh->f_Dt; + float *f_LIFT = mesh->f_LIFT; + + float *f_Q = mesh->f_Q; + float *f_rhsQ = mesh->f_rhsQ; + float *f_resQ = mesh->f_resQ; + + float *f_inQ = mesh->f_inQ; + float *f_outQ = mesh->f_outQ; + + int p; + + /* mpi request buffer */ + MPI_Request *mpi_out_requests = (MPI_Request*) calloc(mesh->nprocs, sizeof(MPI_Request)); + MPI_Request *mpi_in_requests = (MPI_Request*) calloc(mesh->nprocs, sizeof(MPI_Request)); + + /* buffer outgoing node data */ + for(n=0;nparNtotalout;++n) + mesh->f_outQ[n] = f_Q[mesh->parmapOUT[n]]; + + /* do sends */ + int sk = 0, Nmess = 0; + for(p=0;pnprocs;++p){ + if(p!=mesh->procid){ + int Nout = mesh->Npar[p]*p_Nfields*p_Nfp; + if(Nout){ + /* symmetric communications (different ordering) */ + MPI_Isend(f_outQ+sk, Nout, MPI_FLOAT, p, 6666+p, MPI_COMM_WORLD, mpi_out_requests +Nmess); + MPI_Irecv(f_inQ+sk, Nout, MPI_FLOAT, p, 6666+mesh->procid, MPI_COMM_WORLD, mpi_in_requests +Nmess); + sk+=Nout; + ++Nmess; + } + } + } + + for(k=0;knprocs, sizeof(MPI_Status)); + MPI_Waitall(Nmess, mpi_in_requests, instatus); + free(instatus); + + for(k=0;knprocs, sizeof(MPI_Status)); + MPI_Waitall(Nmess, mpi_out_requests, outstatus); + free(outstatus); + + +} + diff --git a/benchmarks/CUDA/DG/src/MaxwellsRun3d.c b/benchmarks/CUDA/DG/src/MaxwellsRun3d.c new file mode 100644 index 0000000..d4ee9f9 --- /dev/null +++ b/benchmarks/CUDA/DG/src/MaxwellsRun3d.c @@ -0,0 +1,60 @@ +#include "mpi.h" +#include "fem.h" + +void MaxwellsRun3d(Mesh *mesh, double FinalTime, double dt){ + + double time = 0; + int INTRK, tstep=0; + + double mpitime0 = MPI_Wtime(); + MPI_Barrier(MPI_COMM_WORLD); + + dt = 0.001; + + /* outer time step loop */ + while (time FinalTime) { dt = FinalTime-time; } + + for (INTRK=1; INTRK<=5; ++INTRK) { + + /* compute rhs of TM-mode MaxwellsGPU's equations */ + const float fdt = dt; + const float fa = (float)mesh->rk4a[INTRK-1]; + const float fb = (float)mesh->rk4b[INTRK-1]; + +#ifdef CUDA + MaxwellsKernel3d(mesh, fa, fb, fdt); +#else + MaxwellsRHS3d(mesh, fa, fb, fdt); +#endif + } + + time += dt; /* increment current time */ + tstep++; /* increment timestep */ + } + +#ifdef CUDA + cudaThreadSynchronize(); +#endif + + double flopsV = p_Np*p_Np*36 + p_Np*66; /* V3 */ + double flopsS = p_Nfp*p_Nfaces*(15 + 10 + 36) + p_Np*(p_Nfaces*p_Nfp*12 + 6); + double flopsR = p_Np*p_Nfields*4; + + int Kloc = mesh->K; + + double mpitime1 = MPI_Wtime(); + + double time_total = mpitime1-mpitime0; + + MPI_Barrier(MPI_COMM_WORLD); + printf("%d %d %lg %lg proc, N, time taken, GFLOPS/s (GPU)\n", + mesh->procid, + p_N, + time_total, + 5*(tstep)*( (flopsV+flopsS+flopsR)*((double)Kloc/(1.e9*time_total)))); + + +} diff --git a/benchmarks/CUDA/DG/src/Mesh3d.c b/benchmarks/CUDA/DG/src/Mesh3d.c new file mode 100644 index 0000000..af76acb --- /dev/null +++ b/benchmarks/CUDA/DG/src/Mesh3d.c @@ -0,0 +1,195 @@ +#include "mpi.h" +#include "fem.h" + +Mesh *ReadMesh3d(char *filename){ + + int n; + + Mesh *mesh = (Mesh*) calloc(1, sizeof(Mesh)); + + char buf[BUFSIZ]; + + FILE *fp = fopen(filename, "r"); + + /* assume modified Gambit neutral format */ + for(n=0;n<6;++n) + fgets(buf, BUFSIZ, fp); + + fgets(buf, BUFSIZ, fp); + sscanf(buf, "%d %d \n", &(mesh->Nv), &(mesh->K)); + mesh->Nverts = 4; /* assume tets */ + mesh->Nedges = 6; /* assume tets */ + mesh->Nfaces = 4; /* assume tets */ + + fgets(buf, BUFSIZ, fp); + fgets(buf, BUFSIZ, fp); + + /* read vertex coordinates */ + double *VX = BuildVector(mesh->Nv); + double *VY = BuildVector(mesh->Nv); + double *VZ = BuildVector(mesh->Nv); + for(n=0;nNv;++n){ + fgets(buf, BUFSIZ, fp); + sscanf(buf, "%*d %lf %lf %lf", VX+n, VY+n, VZ+n); + } + + /* decide on parition */ + int procid, nprocs; + + MPI_Comm_rank(MPI_COMM_WORLD, &procid); + MPI_Comm_size(MPI_COMM_WORLD, &nprocs); + + mesh->procid = procid; + mesh->nprocs = nprocs; + + /* assume this proc owns a block of elements */ + + int Klocal, Kstart; + int *Kprocs = (int*) calloc(nprocs, sizeof(int)); + int p; + + int **newEToV, *newKprocs; + double **newVX, **newVY; + + Klocal = (int) ( (double)(mesh->K)/(double)nprocs ); + + for(p=0;pK - nprocs*Klocal; + + + Kstart= 0; + for(p=0;pEToV = BuildIntMatrix(Klocal, mesh->Nverts); + mesh->GX = BuildMatrix(Klocal, mesh->Nverts); + mesh->GY = BuildMatrix(Klocal, mesh->Nverts); + mesh->GZ = BuildMatrix(Klocal, mesh->Nverts); + + int sk = 0, v; + for(n=0;nK;++n){ + fgets(buf, BUFSIZ, fp); + if(n>=Kstart && nEToV[sk]+0, mesh->EToV[sk]+1, + mesh->EToV[sk]+2, mesh->EToV[sk]+3); + + /* correct to 0-index */ + --(mesh->EToV[sk][0]); + --(mesh->EToV[sk][1]); + --(mesh->EToV[sk][2]); + --(mesh->EToV[sk][3]); + + for(v=0;vNverts;++v){ + mesh->GX[sk][v] = VX[mesh->EToV[sk][v]]; + mesh->GY[sk][v] = VY[mesh->EToV[sk][v]]; + mesh->GZ[sk][v] = VZ[mesh->EToV[sk][v]]; + } + + ++sk; + } + } + fgets(buf, BUFSIZ, fp); + fgets(buf, BUFSIZ, fp); + + mesh->K = Klocal; + + fclose(fp); + + return mesh; + +} + +void PrintMesh ( Mesh *mesh ){ + int n; + printf("Mesh data: \n"); + printf("\n K = %d\n", mesh->K); + printf("\n Nv = %d\n", mesh->Nv); + printf("\n Nverts = %d\n", mesh->Nverts); + printf("\n Node coordinates = \n"); + printf("\n Element to vertex connectivity = \n"); + for(n=0;nK;++n){ + printf("%d: %d %d %d %d\n", n, + mesh->EToV[n][0], mesh->EToV[n][1], + mesh->EToV[n][2], mesh->EToV[n][3]); + } + +} + +void GeometricFactors3d(Mesh *mesh, int k, + double *drdx, double *dsdx, double *dtdx, + double *drdy, double *dsdy, double *dtdy, + double *drdz, double *dsdz, double *dtdz, + double *J){ + + double x1 = mesh->GX[k][0], y1 = mesh->GY[k][0], z1 = mesh->GZ[k][0]; + double x2 = mesh->GX[k][1], y2 = mesh->GY[k][1], z2 = mesh->GZ[k][1]; + double x3 = mesh->GX[k][2], y3 = mesh->GY[k][2], z3 = mesh->GZ[k][2]; + double x4 = mesh->GX[k][3], y4 = mesh->GY[k][3], z4 = mesh->GZ[k][3]; + + /* compute geometric factors of the following afine map */ + /* x = 0.5*( (-1-r-s-t)*x1 + (1+r)*x2 + (1+s)*x3 + (1+t)*x4) */ + /* y = 0.5*( (-1-r-s-t)*y1 + (1+r)*y2 + (1+s)*y3 + (1+t)*y4) */ + /* z = 0.5*( (-1-r-s-t)*z1 + (1+r)*z2 + (1+s)*z3 + (1+t)*z4) */ + + double dxdr = (x2-x1)/2, dxds = (x3-x1)/2, dxdt = (x4-x1)/2; + double dydr = (y2-y1)/2, dyds = (y3-y1)/2, dydt = (y4-y1)/2; + double dzdr = (z2-z1)/2, dzds = (z3-z1)/2, dzdt = (z4-z1)/2; + + *J = + dxdr*(dyds*dzdt-dzds*dydt) + -dydr*(dxds*dzdt-dzds*dxdt) + +dzdr*(dxds*dydt-dyds*dxdt); + + *drdx = (dyds*dzdt - dzds*dydt)/(*J); + *drdy = -(dxds*dzdt - dzds*dxdt)/(*J); + *drdz = (dxds*dydt - dyds*dxdt)/(*J); + + *dsdx = -(dydr*dzdt - dzdr*dydt)/(*J); + *dsdy = (dxdr*dzdt - dzdr*dxdt)/(*J); + *dsdz = -(dxdr*dydt - dydr*dxdt)/(*J); + + *dtdx = (dydr*dzds - dzdr*dyds)/(*J); + *dtdy = -(dxdr*dzds - dzdr*dxds)/(*J); + *dtdz = (dxdr*dyds - dydr*dxds)/(*J); + + if(*J<1e-10) + printf("warning: J = %lg\n", *J); + +} + +void Normals3d(Mesh *mesh, int k, + double *nx, double *ny, double *nz, double *sJ){ + + int f; + + double drdx, dsdx, dtdx; + double drdy, dsdy, dtdy; + double drdz, dsdz, dtdz; + double J; + + GeometricFactors3d(mesh, k, + &drdx, &dsdx, &dtdx, + &drdy, &dsdy, &dtdy, + &drdz, &dsdz, &dtdz, + &J); + + nx[0] = -dtdx; nx[1] = -dsdx; nx[2] = drdx + dsdx + dtdx; nx[3] = -drdx; + ny[0] = -dtdy; ny[1] = -dsdy; ny[2] = drdy + dsdy + dtdy; ny[3] = -drdy; + nz[0] = -dtdz; nz[1] = -dsdz; nz[2] = drdz + dsdz + dtdz; nz[3] = -drdz; + + for(f=0;f<4;++f){ + sJ[f] = sqrt(nx[f]*nx[f]+ny[f]*ny[f]+nz[f]*nz[f]); + nx[f] /= sJ[f]; + ny[f] /= sJ[f]; + nz[f] /= sJ[f]; + sJ[f] *= J; + } +} diff --git a/benchmarks/CUDA/DG/src/ParallelPairs.c b/benchmarks/CUDA/DG/src/ParallelPairs.c new file mode 100644 index 0000000..7474c0b --- /dev/null +++ b/benchmarks/CUDA/DG/src/ParallelPairs.c @@ -0,0 +1,124 @@ +#include +#include +#include +#include + +#include "mpi.h" + +#define max(a,b) ( (a>b)?a:b ) +#define min(a,b) ( (a */ + maxind = 0; + for(n=0;nr = BuildVector(p_Np); + mesh->s = BuildVector(p_Np); + mesh->t = BuildVector(p_Np); + for(n=0;nr[n] = p_r[n]; + mesh->s[n] = p_s[n]; + mesh->t[n] = p_t[n]; + } + + /* load Dr, Ds, Dt */ + mesh->Dr = BuildMatrix(p_Np, p_Np); + mesh->Ds = BuildMatrix(p_Np, p_Np); + mesh->Dt = BuildMatrix(p_Np, p_Np); + for(n=0;nDr[n][m] = p_Dr[n][m]; + mesh->Ds[n][m] = p_Ds[n][m]; + mesh->Dt[n][m] = p_Dt[n][m]; + } + } + + /* load LIFT */ + mesh->LIFT = BuildMatrix(p_Np, p_Nfp*p_Nfaces); + for(n=0;nLIFT[n][m] = p_LIFT[n][m]; + } + } + + mesh->Fmask = BuildIntMatrix(p_Nfaces, p_Nfp); + for(n=0;nFmask[n][m] = p_Fmask[n][m]; + } + } + + /* low storage RK coefficients */ + mesh->rk4a = BuildVector(5); + mesh->rk4a[0] = 0.0; + mesh->rk4a[1] = -567301805773.0 / 1357537059087.0; + mesh->rk4a[2] = -2404267990393.0 / 2016746695238.0; + mesh->rk4a[3] = -3550918686646.0 / 2091501179385.0; + mesh->rk4a[4] = -1275806237668.0 / 842570457699.0; + + mesh->rk4b = BuildVector(5); + mesh->rk4b[0] = 1432997174477.0 / 9575080441755.0; + mesh->rk4b[1] = 5161836677717.0 / 13612068292357.0; + mesh->rk4b[2] = 1720146321549.0 / 2090206949498.0; + mesh->rk4b[3] = 3134564353537.0 / 4481467310338.0; + mesh->rk4b[4] = 2277821191437.0 / 14882151754819.0; + + mesh->rk4c = BuildVector(6); + mesh->rk4c[0] = 0.0; + mesh->rk4c[1] = 1432997174477.0 / 9575080441755.0; + mesh->rk4c[2] = 2526269341429.0 / 6820363962896.0; + mesh->rk4c[3] = 2006345519317.0 / 3224310063776.0; + mesh->rk4c[4] = 2802321613138.0 / 2924317926251.0; + mesh->rk4c[5] = 1.0; + + /* build coordinates */ + mesh->x = BuildMatrix(mesh->K, p_Np); + mesh->y = BuildMatrix(mesh->K, p_Np); + mesh->z = BuildMatrix(mesh->K, p_Np); + + for(k=0;kK;++k){ + for(n=0;nr[n]; + double s = mesh->s[n]; + double t = mesh->t[n]; + + mesh->x[k][n] = 0.5*( -mesh->GX[k][0]*(r+s+t+1) + + mesh->GX[k][1]*(1.+r) + + mesh->GX[k][2]*(1.+s) + + mesh->GX[k][3]*(1.+t) + ); + + mesh->y[k][n] = 0.5*( -mesh->GY[k][0]*(r+s+t+1) + + mesh->GY[k][1]*(1.+r) + + mesh->GY[k][2]*(1.+s) + + mesh->GY[k][3]*(1.+t) + ); + + mesh->z[k][n] = 0.5*( -mesh->GZ[k][0]*(r+s+t+1) + + mesh->GZ[k][1]*(1.+r) + + mesh->GZ[k][2]*(1.+s) + + mesh->GZ[k][3]*(1.+t) + ); + } + } + + /* build node-node connectivity maps */ + void BuildMaps3d(Mesh *mesh); + BuildMaps3d(mesh); + +} diff --git a/benchmarks/CUDA/DG/src/Utils.c b/benchmarks/CUDA/DG/src/Utils.c new file mode 100644 index 0000000..e0364cf --- /dev/null +++ b/benchmarks/CUDA/DG/src/Utils.c @@ -0,0 +1,155 @@ +#include "fem.h" + +/* some very basic memory allocation routines */ + +/* row major storage for a 2D matrix array */ +double **BuildMatrix(int Nrows, int Ncols){ + int n; + double **A = (double**) calloc(Nrows, sizeof(double*)); + + A[0] = (double*) calloc(Nrows*Ncols, sizeof(double)); + + for(n=1;nGX[k][0]; + double x2 = mesh->GX[k][1]; + double x3 = mesh->GX[k][2]; + + double y1 = mesh->GY[k][0]; + double y2 = mesh->GY[k][1]; + double y3 = mesh->GY[k][2]; + + double d1 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2); + double d2 = (x2-x3)*(x2-x3) + (y2-y3)*(y2-y3); + double d3 = (x3-x1)*(x3-x1) + (y3-y1)*(y3-y1); + + /* find maximum length face */ + if(d1>=d2 && d1>=d3) + return 0; + else if(d2>=d3) + return 1; + + return 2; +} + + +int tetbase(Mesh *mesh, int k){ + + double x1 = mesh->GX[k][0]; + double x2 = mesh->GX[k][1]; + double x3 = mesh->GX[k][2]; + double x4 = mesh->GX[k][3]; + + double y1 = mesh->GY[k][0]; + double y2 = mesh->GY[k][1]; + double y3 = mesh->GY[k][2]; + double y4 = mesh->GY[k][3]; + + double z1 = mesh->GZ[k][0]; + double z2 = mesh->GZ[k][1]; + double z3 = mesh->GZ[k][2]; + double z4 = mesh->GZ[k][3]; + + double d1 = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) + (z1-z2)*(z1-z2); + double d2 = (x2-x3)*(x2-x3) + (y2-y3)*(y2-y3) + (z2-z3)*(z2-z3); + double d3 = (x3-x4)*(x3-x4) + (y3-y4)*(y3-y4) + (z3-z4)*(z3-z4); + double d4 = (x4-x1)*(x4-x1) + (y4-y1)*(y4-y1) + (z4-z1)*(z4-z1); + + /* find maximum length face */ + if(d1>=d2 && d1>=d3 && d1>=d4) + return 0; + else if(d2>=d3 && d2>=d4) + return 1; + else if(d3>=d4) + return 2; + + return 3; +} diff --git a/benchmarks/CUDA/DG/src/buildsource.m b/benchmarks/CUDA/DG/src/buildsource.m new file mode 100644 index 0000000..c93d363 --- /dev/null +++ b/benchmarks/CUDA/DG/src/buildsource.m @@ -0,0 +1,106 @@ + +function buildsource(in_N) + +Globals2D; + + +NODETOL = 1e-8; + +N = in_N; + +Np = (N+1)*(N+2)/2; Nfp = N+1; Nfaces = 3; + +[x,y] = Nodes2D(N); +[r,s] = xytors(x,y); + +% find all the nodes that lie on each edge +fmask1 = find( abs(s+1) < NODETOL)'; +fmask2 = find( abs(r+s) < NODETOL)'; +fmask3 = find( abs(r+1) < NODETOL)'; +Fmask = [fmask1;fmask2;fmask3]'; + +% vandermonde matrix +V = Vandermonde2D(N, r, s); + +% derivative matrices +[Dr, Ds] = Dmatrices2D(N, r, s, V); + +% lift matrix +LIFT = Lift2D(); + +% correct to 0-index +Fmask = Fmask-1; + + +fid = fopen(sprintf('dataN%02d.h', N), 'w'); + +fprintf(fid, sprintf('#ifndef DATAN%02d \n\n', N)); +fprintf(fid, sprintf('#define DATAN%02d 1\n\n', N)); +fprintf(fid, 'double p_r[%d] = { ', Np); +fprintf(fid, '%17.15g ', r(1)); +for n=2:Np + fprintf(fid, ', %17.15g ', r(n)); +end +fprintf(fid, '};\n') + +fprintf(fid, 'double p_s[%d] = {', Np); +fprintf(fid, '%17.15g ', s(1)); +for n=2:Np + fprintf(fid, ', %17.15g ', s(n)); +end +fprintf(fid, '};\n') + +fprintf(fid, 'double p_Dr[%d][%d] = {', Np, Np); +for m=1:Np +fprintf(fid, '{%17.15g ', Dr(m,1)); +for n=2:Np + fprintf(fid, ', %17.15g ', Dr(m,n)); +end +if(m + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/benchmarks/CUDA/DG/src/tictoc.cu b/benchmarks/CUDA/DG/src/tictoc.cu new file mode 100644 index 0000000..f1335c3 --- /dev/null +++ b/benchmarks/CUDA/DG/src/tictoc.cu @@ -0,0 +1,23 @@ +cudaEvent_t cstart, cstop; + +void cudatic(){ + + cudaEventCreate(&cstart); + cudaEventCreate(&cstop); + + cudaEventRecord(cstart, 0); +} + +float cudatoc(){ + + cudaEventRecord(cstop, 0); + cudaEventSynchronize(cstop); + float elapsedTime; + cudaEventElapsedTime(&elapsedTime, cstart, cstop); + + /* return elapsed time in seconds */ + return elapsedTime/1000.0; + +} + + -- cgit v1.3