diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..386bdfa --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.direnv +build +.cache +testing/matrices/*.mtx \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..5e41f7c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "thirdparty/gtest"] + path = thirdparty/gtest + url = https://github.com/google/googletest.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..0f41e48 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.1) + +############################################################################### +## CXX Setup ################################################################## +############################################################################### + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_COMPILER mpic++) # default, change in subdir if necessary + +# to change build type (for checking optimization flags), do: +# cmake -DCMAKE_BUILD_TYPE=Release (acc. to stackoverflow) +# set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wpedantic") +set(CMAKE_CXX_FLAGS_DEBUG "-g") +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -march=native") +set(CMAKE_EXPORT_COMPILE_COMMANDS on) + +############################################################################### +## project setup ############################################################## +############################################################################### + +project(SpCOMM3D) + +############################################################################### +## file globbing ############################################################## +############################################################################### + +file(GLOB_RECURSE GLOB_SOURCES src/*.cpp) +include_directories(src) # outdated method but not a big deal I think (Manuel) + +############################################################################### +## target definitions ######################################################### +############################################################################### + +add_subdirectory(miniapp) + +############################################################################### +## dependencies ############################################################### +############################################################################### + +add_subdirectory(thirdparty) + +############################################################################### +## testing #################################################################### +############################################################################### + +add_subdirectory(testing) \ No newline at end of file diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..ca1b5c1 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1715037484, + "narHash": "sha256-OUt8xQFmBU96Hmm4T9tOWTu4oCswCzoVl+pxSq/kiFc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ad7efee13e0d216bf29992311536fce1d3eefbef", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..6ef0100 --- /dev/null +++ b/flake.nix @@ -0,0 +1,29 @@ +{ + description = "HPC Lab"; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + outputs = { self, nixpkgs }: + let + system = "x86_64-linux"; + pkgs = import nixpkgs { + inherit system; + }; + in + { + formatter.${system} = pkgs.nixpkgs-fmt; + + devShell.${system} = pkgs.mkShell rec { + nativeBuildInputs = with pkgs; [ + cmake + clang-tools + mpich + ]; + buildInputs = with pkgs; [ + ]; + + CPATH = pkgs.lib.makeSearchPathOutput "dev" "include" buildInputs; + LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath buildInputs; + }; + }; +} diff --git a/miniapp/CMakeLists.txt b/miniapp/CMakeLists.txt new file mode 100644 index 0000000..44f89f4 --- /dev/null +++ b/miniapp/CMakeLists.txt @@ -0,0 +1,15 @@ +############################################################################### +## target definitions ######################################################### +############################################################################### + +add_executable(benchSddmm bench_sddmm.cpp ${GLOB_SOURCES}) + +add_executable(benchSpMM bench_spmm.cpp ${GLOB_SOURCES}) + +# add_executable(benchBoth main_combined.cpp ${GLOB_SOURCES}) + +# add_executable(serialSim serialSim.cpp ${GLOB_SOURCES}) + +add_executable(numCheckSeq numCheckSeq.cpp ${GLOB_SOURCES}) + +add_executable(test test.cpp ${GLOB_SOURCES}) diff --git a/miniapp/bench_sddmm.cpp b/miniapp/bench_sddmm.cpp index 5de2d48..19594ec 100644 --- a/miniapp/bench_sddmm.cpp +++ b/miniapp/bench_sddmm.cpp @@ -30,7 +30,7 @@ void vals_from_str(string str, vector& vals){ } } -void process_args(int argc, char *argv[], std::vector& fvals, int& c, int& niter, string& filename){ +void process_args(int argc, char *argv[], std::vector& fvals, int& c,/*int& niter,*/ string& filename){ int choice; while (1) { @@ -113,7 +113,8 @@ int main(int argc, char *argv[]) string filename; int c; vector fvals; - process_args(argc, argv, fvals, c, filename); + int niter = 10; + process_args(argc, argv, fvals, c, niter, filename); std::string::size_type const p(filename.find_last_of('.')); std::string mtxName = filename.substr(0, p); mtxName = mtxName.substr(mtxName.find_last_of("/\\") +1); diff --git a/miniapp/main_combined.cpp b/miniapp/main_combined.cpp index db1d1a2..4677624 100644 --- a/miniapp/main_combined.cpp +++ b/miniapp/main_combined.cpp @@ -3,9 +3,9 @@ #include #include #include -#include "../src/basic.hpp" -#include "../src/mm.hpp" -#include "../src/comm_stats.hpp" +#include "basic.hpp" +#include "mm.hpp" +#include "comm_stats.hpp" #include #include #include "distribute.hpp" diff --git a/miniapp/test.cpp b/miniapp/test.cpp new file mode 100644 index 0000000..c63675a --- /dev/null +++ b/miniapp/test.cpp @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include "basic.hpp" +#include "SparseMatrix.hpp" +#include "comm.hpp" +#include "comm_stats.hpp" +#include +#include +#include "denseComm.hpp" +#include "distribute.hpp" +#include "distributed_comp.hpp" +#include "parallel_io.hpp" +#include "comm_setup.hpp" + +using namespace std; + +template +void printfvec(vector &vec) { + for (auto &v : vec) { + cout << v << " "; + } + printf("\n"); +} + +template +void printfmap(unordered_map &map) { + for (auto &m : map) { + cout << "(" << m.first << "," << m.second << ") "; + } + printf("\n"); +} + + +int main(int argc, char *argv[]) { + MPI_Init(&argc, &argv); + int rank, size; + MPI_Comm comm = MPI_COMM_WORLD, xycomm, zcomm; + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + + string filename; + if (argc == 2) { + filename = argv[1]; + } else { + if (rank == 0) { + printf("Usage: %s filename\n", argv[0]); + } + MPI_Finalize(); + return 1; + } + + std::string::size_type const p(filename.find_last_of('.')); + std::string mtxName = filename.substr(0, p); + mtxName = mtxName.substr(mtxName.find_last_of("/\\") +1); + + std::vector rpvec, cpvec; + std::array dims = {0,0,0}; + std::array zeroArr ={0,0,0}; + std::array tdims ={0,0,0}; + MPI_Dims_create(size, 3, dims.data()); + + MPI_Comm cartcomm; + MPI_Cart_create(comm, 3, dims.data(), zeroArr.data(), 0, &cartcomm); + + int X = dims[0], Y = dims[1], Z = dims[2]; + + std::array remaindims = {true, true, false}; + MPI_Cart_sub(cartcomm, remaindims.data(), &xycomm); + + int myxyrank; + MPI_Comm_rank(xycomm, &myxyrank); + + remaindims = {false, false, true}; + MPI_Cart_sub(cartcomm, remaindims.data(), &zcomm); + cooMat Sloc; + Sloc.mtxName = mtxName; + { + std:: vector rpvec2D, cpvec2D; + /* distribute C */ + read_bin_parallel_distribute_coo(filename, Sloc, rpvec2D, cpvec2D, + cartcomm,xycomm, zcomm); + Sloc.localizeIndices(); + MPI_Comm_rank(zcomm, &Sloc.zrank); + Sloc.rank = rank; + } + + // output the matrix info on rank 0 + if (rank == 0) { + printf("Matrix %s: %d x %d, %ld nnz\n", Sloc.mtxName.c_str(), Sloc.gnrows, Sloc.gncols, Sloc.gnnz); + printf("local to global row mapping:\n"); + printfvec(Sloc.ltgR); + printf("local to global col mapping:\n"); + printfvec(Sloc.ltgC); + printf("global to local row mapping:\n"); + printfmap(Sloc.gtlR); + printf("global to local col mapping:\n"); + printfmap(Sloc.gtlC); + printf("local matrix:\n"); + Sloc.printMatrix(); + } +} \ No newline at end of file diff --git a/scripts/1138_bus.bin b/scripts/1138_bus.bin new file mode 100644 index 0000000..6fce627 Binary files /dev/null and b/scripts/1138_bus.bin differ diff --git a/scripts/1138_bus.mtx b/scripts/1138_bus.mtx new file mode 100644 index 0000000..09591c7 --- /dev/null +++ b/scripts/1138_bus.mtx @@ -0,0 +1,2610 @@ +%%MatrixMarket matrix coordinate real symmetric +%------------------------------------------------------------------------------- +% UF Sparse Matrix Collection, Tim Davis +% http://www.cise.ufl.edu/research/sparse/matrices/HB/1138_bus +% name: HB/1138_bus +% [S ADMITTANCE MATRIX 1138 BUS POWER SYSTEM, D.J.TYLAVSKY, JULY 1985.] +% id: 1 +% date: 1985 +% author: D. Tylavsky +% ed: I. Duff, R. Grimes, J. Lewis +% fields: title A name id date author ed kind +% kind: power network problem +%------------------------------------------------------------------------------- +1138 1138 2596 +1 1 1474.779 +5 1 -9.017133 +563 1 -5.730659 +2 2 9.136654 +10 2 -3.405995 +563 2 -5.730659 +3 3 69.61468 +11 3 -8.810573 +34 3 -31.15265 +35 3 -16.06684 +104 3 -4.86926 +475 3 -8.715357 +4 4 68.60106 +7 4 -34.62025 +27 4 -.4755112 +101 4 -28.66497 +102 4 -.7463244 +103 4 -4.093998 +5 5 13.88805 +9 5 -4.870921 +6 6 116.8288 +7 6 -10.96124 +37 6 -56.81818 +98 6 -10.88139 +103 6 -38.16794 +7 7 52.76726 +37 7 -4.773726 +101 7 -.7772424 +102 7 -1.072973 +103 7 -.5618293 +8 8 30.25788 +26 8 -3.752486 +35 8 -.4975867 +724 8 -26.0078 +9 9 7.174451 +10 9 -.905633 +104 9 -1.397898 +10 10 5.709526 +104 10 -1.397898 +11 11 27.18584 +12 11 -1.238697 +38 11 -7.418397 +566 11 -9.718173 +12 12 1.238697 +13 13 7.142646 +34 13 -1.85192 +104 13 -5.290726 +14 14 12.95337 +413 14 -12.95337 +15 15 1696.756 +16 15 -30.67485 +17 15 -30.4878 +18 15 -30.39514 +19 15 -30.39514 +411 15 -1574.803 +16 16 30.67485 +17 17 30.4878 +18 18 30.39514 +19 19 30.39514 +20 20 5746.122 +21 20 -5714.287 +37 20 -18.24817 +102 20 -13.58696 +21 21 5735.022 +22 21 -5.205622 +23 21 -5.186722 +24 21 -5.181347 +25 21 -5.162622 +22 22 5.205622 +23 23 5.186722 +24 24 5.181347 +25 25 5.162622 +26 26 4.371336 +35 26 -.6188502 +27 27 9.123474 +28 27 -2.373605 +29 27 -2.439024 +30 27 -1.190334 +101 27 -2.644999 +28 28 2.373605 +29 29 2.439024 +30 30 1.190334 +31 31 1.688214 +32 31 -.6254691 +100 31 -1.062744 +32 32 1.688214 +100 32 -1.062744 +33 33 .6581979 +100 33 -.6581979 +34 34 56.31459 +104 34 -10.13479 +553 34 -13.17523 +35 35 10018.3 +104 35 -1.112756 +710 35 -10000 +36 36 10000 +711 36 -10000 +37 37 80.33353 +102 37 -.4934373 +38 38 74.99123 +39 38 -15.67398 +98 38 -46.2963 +412 38 -5.602555 +39 39 16.41742 +99 39 -.7434391 +40 40 245.9335 +41 40 -126.5823 +43 40 -55.24862 +45 40 -64.10257 +41 41 988.9011 +42 41 -28.98551 +44 41 -833.3333 +42 42 28.98551 +43 43 4403.075 +146 43 -4347.826 +44 44 10833.33 +486 44 -10000 +45 45 118.7474 +49 45 -54.64481 +46 46 10000 +48 46 -10000 +47 47 104.9318 +48 47 -104.9318 +48 48 20183.36 +54 48 -78.43137 +506 48 -10000 +49 49 288.754 +50 49 -126.5823 +53 49 -107.5269 +50 50 988.9011 +51 50 -28.98551 +52 50 -833.3333 +51 51 28.98551 +52 52 874.3169 +125 52 -40.98361 +53 53 1586.098 +54 53 -1428.572 +55 53 -50 +54 54 1957.633 +425 54 -119.0476 +445 54 -184.5238 +447 54 -147.0588 +55 55 50 +56 56 29.32551 +63 56 -29.32551 +57 57 112.3596 +66 57 -112.3596 +58 58 15.64945 +70 58 -15.64945 +59 59 24.3309 +67 59 -24.3309 +60 60 104.1667 +68 60 -104.1667 +61 61 125 +130 61 -125 +62 62 50.76142 +129 62 -50.76142 +63 63 10059.54 +64 63 -30.21148 +65 63 -10000 +64 64 159.7102 +71 64 -40.98361 +131 64 -16.05136 +226 64 -72.46377 +65 65 10015.92 +1095 65 -15.92357 +66 66 442.0023 +67 66 -97.08738 +68 66 -24.27184 +74 66 -32.65326 +183 66 -147.0588 +226 66 -28.57143 +67 67 167.4071 +68 67 -30.67485 +69 67 -15.31394 +68 68 289.2932 +74 68 -47.5921 +90 68 -32.33649 +201 68 -50.25126 +69 69 190.7525 +70 69 -175.4386 +70 70 225.5077 +182 70 -4.955401 +196 70 -5.170631 +1063 70 -4.623209 +1065 70 -16.47446 +1074 70 -3.195909 +71 71 96.53917 +72 71 -55.55556 +72 72 84.92064 +73 72 -5.555555 +121 72 -23.80952 +73 73 5.555555 +74 74 384.9024 +75 74 -40.32258 +76 74 -25.44529 +78 74 -34.3871 +80 74 -15.82279 +119 74 -188.6792 +75 75 693.1041 +204 75 -645.1613 +810 75 -4.608295 +918 75 -3.012048 +76 76 147.3945 +77 76 -30.03003 +78 76 -36.36364 +127 76 -55.55556 +77 77 5030.03 +1050 77 -5000 +78 78 262.67 +79 78 -90.90909 +452 78 -101.0101 +79 79 564.4214 +416 79 -48.07692 +417 79 -48.07692 +454 79 -377.3585 +80 80 657.1666 +81 80 -67.1141 +447 80 -476.1905 +452 80 -98.03922 +81 81 420.0095 +448 81 -158.7302 +450 81 -175.4386 +464 81 -18.72659 +82 82 4.975124 +94 82 -4.975124 +83 83 17.24138 +94 83 -17.24138 +84 84 17.57469 +95 84 -17.57469 +85 85 439.0805 +87 85 -172.4138 +126 85 -266.6667 +86 86 6807.496 +87 86 -5000 +241 86 -46.51163 +251 86 -71.94245 +253 86 -74.62687 +267 86 -94.78674 +269 86 -277.7778 +283 86 -138.8889 +291 86 -49.01961 +293 86 -57.14286 +294 86 -57.14286 +302 86 -689.6552 +315 86 -250 +87 87 5319.472 +88 87 -147.0588 +88 88 147.0588 +89 89 65.3412 +105 89 -38.31417 +115 89 -27.02703 +90 90 64.83059 +91 90 -32.4941 +91 91 645.056 +92 91 -163.6515 +108 91 -67.56757 +115 91 -24.19992 +116 91 -357.1429 +92 92 258.8896 +93 92 -95.2381 +93 93 612.1849 +94 93 -10.90512 +252 93 -131.5789 +264 93 -12.67427 +271 93 -66.0066 +288 93 -65.35947 +292 93 -31.84714 +293 93 -38.31417 +294 93 -38.31417 +322 93 -32.15434 +323 93 -34.8432 +324 93 -24.03846 +325 93 -14.40922 +326 93 -16.50165 +94 94 464.0852 +96 94 -4.800768 +264 94 -239.4475 +318 94 -110.6696 +325 94 -76.04562 +95 95 76.57204 +97 95 -8.285004 +262 95 -9.67118 +268 95 -7.142857 +300 95 -33.8983 +96 96 10022.9 +145 96 -7.24113 +704 96 -10.85776 +705 96 -10000 +97 97 12.12083 +268 97 -3.835827 +98 98 57.17769 +99 99 3.134068 +413 99 -2.390629 +100 100 40.73998 +725 100 -35.58719 +732 100 -2.369107 +101 101 34.2926 +102 101 -.754091 +103 101 -1.451295 +102 102 47.04131 +103 102 -30.38753 +103 103 10074.66 +478 103 -10000 +104 104 24.20333 +105 105 420.7618 +106 105 -12.07729 +109 105 -370.3704 +106 106 12.07729 +107 107 32.15434 +108 107 -32.15434 +108 108 1008.813 +110 108 -909.0909 +109 109 10370.37 +1029 109 -10000 +110 110 10974.79 +111 110 -41.84558 +328 110 -10000 +367 110 -10.77006 +370 110 -13.08045 +111 111 10056.95 +367 111 -7.27802 +368 111 -7.824726 +701 111 -10000 +112 112 301.7592 +113 112 -7.420491 +370 112 -8.624407 +686 112 -285.7143 +113 113 10040.49 +114 113 -7.624856 +115 113 -25.44529 +690 113 -10000 +114 114 10007.63 +1009 114 -10000 +115 115 76.67225 +116 116 436.123 +117 116 -10.9529 +126 116 -68.02721 +117 117 10.9529 +118 118 5.521811 +119 118 -5.521811 +119 119 228.3307 +123 119 -34.12969 +120 120 126.5823 +121 120 -126.5823 +121 121 272.2888 +122 121 -70.87661 +504 121 -51.02041 +122 122 152.6848 +123 122 -40.48583 +124 122 -41.32232 +123 123 111.929 +125 123 -37.31343 +124 124 97.81158 +125 124 -32.67974 +127 124 -23.80952 +125 125 363.2857 +126 125 -81.38689 +129 125 -70.92198 +546 125 -100 +126 126 478.1926 +129 126 -62.1118 +127 127 84.92064 +128 127 -5.555555 +128 128 5.555555 +129 129 183.7952 +130 130 356.9032 +133 130 -136.9863 +173 130 -51.81347 +213 130 -43.10345 +131 131 896.646 +132 131 -75.18797 +133 131 -769.2308 +136 131 -36.17595 +132 132 101.0104 +144 132 -4.409171 +742 132 -21.41328 +133 133 918.7799 +134 133 -12.56281 +134 134 12.56281 +135 135 10030.19 +136 135 -25.44529 +139 135 -4.748338 +740 135 -10000 +136 136 99.82595 +141 136 -38.20471 +137 137 108.031 +139 137 -72.46377 +141 137 -27.39726 +761 137 -8.169934 +138 138 217.898 +141 138 -28.98551 +877 138 -59.88025 +882 138 -129.0323 +139 139 90.06557 +140 139 -12.85347 +140 140 45.52996 +829 140 -18.62891 +830 140 -14.04757 +141 141 94.58748 +142 142 36.70324 +258 142 -21.55172 +366 142 -15.15152 +143 143 20014.59 +144 143 -12.5 +743 143 -2.090738 +745 143 -10000 +826 143 -10000 +144 144 10016.91 +827 144 -10000 +145 145 10022.01 +318 145 -14.77105 +703 145 -10000 +146 146 7289.003 +147 146 -2941.177 +147 147 12941.18 +148 147 -10000 +148 148 10000 +149 149 5.205622 +166 149 -5.205622 +150 150 73.52941 +173 150 -73.52941 +151 151 13.29787 +175 151 -13.29787 +152 152 10.40583 +180 152 -10.40583 +153 153 34.48276 +183 153 -34.48276 +154 154 13.71742 +207 154 -13.71742 +155 155 28.98551 +198 155 -28.98551 +156 156 144.9275 +213 156 -144.9275 +157 157 38.46154 +219 157 -38.46154 +158 158 28.0112 +226 158 -28.0112 +159 159 9.64196 +182 159 -4.730369 +205 159 -4.911591 +160 160 21.37365 +172 160 -10.01001 +233 160 -11.36364 +161 161 10.90321 +222 161 -4.730369 +743 161 -6.17284 +162 162 87.51172 +163 162 -46.08295 +169 162 -11.53403 +209 162 -7.451564 +223 162 -12.61034 +232 162 -9.832842 +163 163 145.9383 +186 163 -46.51163 +201 163 -13.6612 +227 163 -39.68254 +164 164 5.205622 +166 164 -5.205622 +165 165 117.6942 +166 165 -60.60606 +167 165 -17.33102 +175 165 -11.18568 +194 165 -28.57143 +166 166 341.3369 +192 166 -80 +201 166 -14.88095 +218 166 -175.4386 +167 167 34.66204 +175 167 -17.33102 +168 168 69.63064 +180 168 -9.389671 +209 168 -60.24096 +169 169 25.6384 +187 169 -14.10437 +170 170 30.28655 +188 170 -22.77904 +194 170 -7.507507 +171 171 52.2535 +178 171 -39.21569 +217 171 -13.03781 +172 172 66.85269 +173 172 -42.55319 +222 172 -4.873294 +755 172 -9.416196 +173 173 206.2103 +184 173 -38.31417 +174 174 50.63389 +211 174 -12.7551 +216 174 -37.87879 +175 175 53.63491 +179 175 -11.82033 +176 176 860.8028 +177 176 -172.4138 +178 176 -20.98079 +207 176 -667.4082 +177 177 276.5804 +207 177 -104.1667 +178 178 88.17661 +214 178 -15.06024 +217 178 -12.9199 +179 179 23.64066 +203 179 -11.82033 +180 180 28.49115 +209 180 -8.695652 +181 181 23.14815 +183 181 -23.14815 +182 182 61.50294 +183 182 -29.94012 +205 182 -16.72241 +221 182 -5.154639 +183 183 398.0187 +184 183 -91.74312 +201 183 -35.14939 +226 183 -36.49635 +184 184 192.1349 +193 184 -41.40787 +213 184 -20.6697 +185 185 8.064516 +187 185 -8.064516 +186 186 126.2011 +187 186 -41.66667 +218 186 -38.02281 +187 187 107.524 +188 187 -29.67359 +206 187 -8.695652 +209 187 -5.319149 +188 188 52.45263 +189 189 41.49792 +211 189 -11.46789 +216 189 -30.03003 +190 190 33.0033 +199 190 -33.0033 +191 191 1149.633 +195 191 -10.71811 +197 191 -14.74926 +198 191 -1111.111 +211 191 -13.05483 +192 192 824.6421 +199 192 -666.6667 +218 192 -63.29114 +220 192 -14.68429 +193 193 247.007 +198 193 -60.60606 +199 193 -106.383 +208 193 -38.61004 +194 194 78.9974 +216 194 -42.91846 +195 195 36.89613 +211 195 -26.17801 +196 196 5.170631 +197 197 36.48839 +212 197 -21.73913 +198 198 1200.703 +199 199 806.053 +200 200 60.0913 +201 200 -43.87481 +202 200 -16.21649 +201 201 172.6985 +218 201 -14.88095 +202 202 20.9357 +203 202 -4.719207 +203 203 16.53954 +204 204 645.1613 +205 205 28.7262 +221 205 -7.092198 +206 206 18.89453 +216 206 -10.19888 +207 207 881.1484 +208 207 -84.38818 +224 207 -11.46789 +208 208 122.9982 +209 209 81.70734 +210 210 1796.925 +215 210 -11.21076 +217 210 -1666.667 +218 210 -119.0476 +211 211 84.37634 +212 211 -20.9205 +212 212 42.65963 +213 213 282.2301 +504 213 -73.52941 +214 214 65.82166 +217 214 -50.76142 +215 215 11.21076 +216 216 148.1264 +218 216 -27.10027 +217 217 1743.386 +218 218 437.7814 +219 219 150.9842 +220 219 -86.20689 +230 219 -26.31579 +220 220 100.8912 +221 221 18.99606 +222 221 -3.15856 +225 221 -3.590664 +222 222 91.18269 +225 222 -26.24672 +233 222 -49.50495 +743 222 -2.668802 +223 223 54.62715 +232 223 -42.01681 +224 224 18.73533 +1026 224 -7.267442 +225 225 29.83738 +226 226 165.5428 +227 227 85.76549 +228 227 -46.08295 +228 228 97.42727 +229 228 -27.62431 +231 228 -12.7551 +232 228 -10.96491 +229 229 27.62431 +230 230 26.31579 +231 231 31.20529 +232 231 -18.45018 +232 232 81.26475 +233 233 60.86859 +234 234 29.17592 +236 234 -14.55604 +307 234 -14.61988 +235 235 2117.081 +236 235 -67.56757 +243 235 -14.59854 +270 235 -2000 +272 235 -9.208103 +298 235 -12.85347 +299 235 -12.85347 +236 236 90.2339 +286 236 -8.1103 +237 237 123.4571 +261 237 -2.818489 +287 237 -18.97533 +309 237 -69.68641 +366 237 -4.004806 +702 237 -27.97203 +238 238 188.1504 +239 238 -41.25455 +270 238 -146.8959 +239 239 59.24802 +270 239 -15.33742 +281 239 -2.656042 +240 240 7.917656 +259 240 -7.917656 +241 241 2888.018 +242 241 -185.1852 +246 241 -89.28572 +253 241 -123.4568 +257 241 -92.59259 +266 241 -123.4568 +275 241 -13.44086 +279 241 -31.74603 +289 241 -30.03003 +291 241 -833.3333 +292 241 -833.3333 +293 241 -138.8889 +294 241 -138.8889 +299 241 -13.28021 +310 241 -16.80672 +321 241 -88.49557 +327 241 -89.28572 +242 242 314.7918 +244 242 -57.14286 +245 242 -72.46377 +243 243 14.59854 +244 244 118.4926 +272 244 -61.34969 +245 245 95.93795 +298 245 -23.47418 +246 246 113.1521 +310 246 -23.86635 +247 247 582.7703 +248 247 -270.2703 +255 247 -312.5 +248 248 502.8284 +255 248 -232.5581 +249 249 1666.667 +282 249 -1666.667 +250 250 1123.714 +257 250 -92.59259 +263 250 -78.74016 +289 250 -119.0476 +317 250 -833.3333 +251 251 210.8313 +267 251 -138.8889 +252 252 288.2195 +310 252 -21.50537 +313 252 -135.1351 +253 253 198.0837 +254 254 383.7719 +255 254 -208.3333 +285 254 -175.4386 +255 255 910.2564 +258 255 -31.44654 +260 255 -71.94245 +263 255 -53.47594 +256 256 10133 +290 256 -52.35602 +317 256 -10000 +321 256 -80.64516 +257 257 185.1852 +258 258 261.8486 +261 258 -128.2051 +327 258 -80.64516 +259 259 20.85427 +278 259 -12.93661 +260 260 190.9901 +289 260 -119.0476 +261 261 131.0236 +262 262 183.095 +268 262 -26.17801 +276 262 -62.5 +314 262 -84.74576 +263 263 132.2161 +264 264 383.7008 +311 264 -131.5789 +265 265 1017.575 +276 265 -999.9999 +300 265 -17.57469 +266 266 246.9136 +307 266 -123.4568 +267 267 566.0127 +282 267 -144.9275 +284 267 -77.51938 +302 267 -109.8901 +268 268 158.6071 +270 268 -53.88283 +301 268 -67.56757 +269 269 486.1111 +284 269 -208.3333 +270 270 2317.201 +275 270 -12.77139 +279 270 -8.257638 +280 270 -29.32551 +318 270 -34.36426 +320 270 -16.36661 +271 271 66.0066 +272 272 70.5578 +273 273 1295.094 +274 273 -303.0303 +303 273 -714.2858 +315 273 -277.7778 +274 274 606.0606 +312 274 -303.0303 +275 275 26.21225 +276 276 1062.5 +277 277 5086.957 +285 277 -86.95652 +289 277 -5000 +278 278 27.55649 +309 278 -14.61988 +279 279 40.00367 +280 280 29.32551 +281 281 2.656042 +282 282 1811.594 +283 283 214.6465 +292 283 -75.75758 +284 284 285.8527 +285 285 262.3951 +286 286 8.1103 +287 287 18.97533 +288 288 127.4713 +291 288 -62.1118 +289 289 5268.125 +290 290 52.35602 +291 291 944.4647 +292 292 940.938 +293 293 234.3459 +294 294 234.3459 +295 295 38.31417 +298 295 -38.31417 +296 296 101.0101 +297 296 -101.0101 +297 297 118.4317 +299 297 -17.4216 +298 298 74.64183 +299 299 43.55529 +300 300 122.395 +696 300 -70.92198 +301 301 153.7745 +314 301 -86.20689 +302 302 799.5453 +303 303 1428.572 +312 303 -714.2858 +304 304 1380.582 +305 304 -263.1579 +315 304 -208.3333 +329 304 -909.0909 +305 305 459.2363 +315 305 -196.0784 +306 306 37.87879 +322 306 -37.87879 +307 307 138.0767 +308 308 81.30082 +323 308 -81.30082 +309 309 84.30629 +310 310 62.17845 +311 311 200.5445 +326 311 -68.96552 +312 312 1295.094 +315 312 -277.7778 +313 313 135.1351 +314 314 170.9527 +315 315 1688.798 +316 315 -322.5806 +319 315 -125 +323 315 -31.25 +316 316 360.1746 +322 316 -37.59399 +317 317 10833.33 +318 318 169.825 +704 318 -10.02004 +319 319 1236.111 +329 319 -1111.111 +320 320 16.36661 +321 321 169.1407 +322 322 107.6271 +323 323 147.394 +324 324 51.89362 +325 324 -27.85515 +325 325 118.31 +326 326 85.46717 +327 327 169.9309 +328 328 10000 +329 329 2020.202 +330 330 2.409639 +335 330 -2.409639 +331 331 .8810573 +336 331 -.8810573 +332 332 1.666667 +337 332 -1.666667 +333 333 2.608922 +350 333 -2.608922 +334 334 1.446132 +350 334 -1.446132 +335 335 30.26479 +337 335 -27.85515 +336 336 218.2724 +337 336 -217.3913 +337 337 260.9173 +338 337 -3.840246 +339 337 -3.955696 +340 337 -6.208189 +338 338 19.08415 +340 338 -15.2439 +339 339 19.1996 +340 339 -15.2439 +340 340 59.70203 +341 340 -8.1103 +342 340 -14.89573 +341 341 20.88169 +342 341 -12.77139 +342 342 66.7209 +343 342 -5.675369 +344 342 -10.71237 +345 342 -4.215851 +370 342 -18.45018 +343 343 15.14507 +346 343 -9.469697 +344 344 28.10368 +346 344 -17.3913 +345 345 26.63738 +346 345 -22.42153 +346 346 102.5212 +347 346 -14.08451 +349 346 -20.70393 +367 346 -18.45018 +347 347 54.57034 +348 347 -40.48583 +348 348 79.09587 +349 348 -38.61004 +349 349 83.58582 +350 349 -24.27184 +350 350 28.3269 +351 351 7.374631 +366 351 -7.374631 +352 352 14.91256 +353 352 -5.289326 +408 352 -2.934273 +409 352 -6.688963 +353 353 17.04893 +363 353 -3.816794 +382 353 -7.942812 +354 354 28.97867 +382 354 -6.199628 +383 354 -22.77904 +355 355 2.164971 +375 355 -2.164971 +356 356 13.59556 +383 356 -5.344736 +398 356 -8.250825 +357 357 1.307306 +394 357 -.5700604 +395 357 -.7372456 +358 358 46.94836 +479 358 -46.94836 +359 359 18.55447 +474 359 -18.55447 +360 360 8.05153 +715 360 -8.05153 +361 361 509.4518 +479 361 -9.451796 +480 361 -500 +362 362 22.4661 +403 362 -11.03753 +714 362 -11.42857 +363 363 96.66204 +364 363 -9.149131 +365 363 -9.149131 +373 363 -9.149131 +374 363 -9.149131 +388 363 -34.96503 +395 363 -4.926108 +407 363 -10.75847 +474 363 -5.599104 +364 364 9.149131 +365 365 9.149131 +366 366 41.86838 +699 366 -15.33742 +367 367 307.3316 +368 367 -104.1667 +372 367 -166.6667 +368 368 111.9914 +369 369 72.9927 +371 369 -72.9927 +370 370 40.15504 +371 371 239.6594 +372 371 -166.6667 +372 372 333.3333 +373 373 9.149131 +374 374 9.149131 +375 375 122.031 +376 375 -2.019386 +377 375 -2.019386 +378 375 -2.019386 +379 375 -1.959632 +380 375 -1.959632 +381 375 -1.959632 +389 375 -105.8201 +404 375 -2.108815 +376 376 2.019386 +377 377 2.019386 +378 378 2.019386 +379 379 1.959632 +380 380 1.959632 +381 381 1.959632 +382 382 14.14244 +383 383 84.26632 +384 383 -8.143323 +385 383 -8.032128 +386 383 -16.50165 +387 383 -16.50165 +392 383 -6.963788 +384 384 8.143323 +385 385 8.032128 +386 386 16.50165 +387 387 16.50165 +388 388 94.03941 +389 388 -22.98851 +390 388 -7.077141 +391 388 -7.077141 +395 388 -4.739336 +401 388 -9.416196 +405 388 -7.77605 +389 389 128.8086 +390 390 7.077141 +391 391 7.077141 +392 392 10.41564 +395 392 -3.451847 +393 393 32.25806 +474 393 -16.12903 +479 393 -16.12903 +394 394 20.16254 +395 394 -19.59248 +395 395 785.9075 +398 395 -76.33588 +399 395 -77.51938 +405 395 -10.71811 +406 395 -473.7875 +407 395 -89.28572 +474 395 -24.8139 +396 396 97.03087 +406 396 -86.43042 +716 396 -5.336179 +717 396 -5.264266 +397 397 690.4763 +716 397 -357.1429 +717 397 -333.3333 +398 398 84.5867 +399 399 77.51938 +400 400 10000 +473 400 -10000 +401 401 29.10979 +402 401 -8.038586 +714 401 -11.65501 +402 402 8.038586 +403 403 11.03753 +404 404 5.644883 +409 404 -3.536068 +405 405 18.49416 +406 406 10591.18 +479 406 -23.97024 +483 406 -10000 +716 406 -3.519887 +717 406 -3.472463 +407 407 100.0442 +408 408 2.934273 +409 409 10.22503 +410 410 10155.49 +411 410 -10000 +412 410 -80.19246 +731 410 -75.30121 +411 411 11741.83 +476 411 -48.89976 +477 411 -68.37394 +486 411 -49.75124 +412 412 111.7064 +413 412 -9.425071 +478 412 -3.253196 +709 412 -.6465378 +724 412 -12.58653 +413 413 24.76907 +414 414 319.0159 +431 414 -227.2727 +433 414 -91.74312 +415 415 319.0159 +432 415 -227.2727 +433 415 -91.74312 +416 416 362.0423 +433 416 -91.74312 +462 416 -222.2222 +417 417 362.0423 +433 417 -91.74312 +462 417 -222.2222 +418 418 39.25825 +419 418 -9.389671 +545 418 -29.86858 +419 419 9.389671 +420 420 1716.987 +421 420 -38.75969 +422 420 -11.56069 +470 420 -1666.667 +421 421 38.75969 +422 422 11.56069 +423 423 606.9609 +425 423 -526.3158 +516 423 -80.64516 +424 424 293.4111 +466 424 -212.766 +516 424 -80.64516 +425 425 905.9952 +426 425 -73.52941 +427 425 -35.58719 +466 425 -151.5152 +426 426 536.205 +437 426 -454.5455 +519 426 -8.130081 +427 427 35.58719 +428 428 305.9395 +429 428 -25 +430 428 -37.03704 +431 428 -121.9512 +432 428 -121.9512 +429 429 25 +430 430 37.03704 +431 431 349.224 +432 432 349.224 +433 433 602.0284 +434 433 -32.05128 +510 433 -181.8182 +564 433 -21.18644 +434 434 32.05128 +435 435 83.68201 +510 435 -83.68201 +436 436 21.45923 +534 436 -21.45923 +437 437 548.2252 +438 437 -45.6621 +439 437 -6.222775 +441 437 -12.12121 +458 437 -29.67359 +438 438 45.6621 +439 439 22.0206 +440 439 -11.16819 +460 439 -4.62963 +440 440 11.16819 +441 441 45.41016 +442 441 -33.28895 +442 442 33.28895 +443 443 1625.394 +444 443 -73.52941 +470 443 -1111.111 +506 443 -155.0388 +516 443 -285.7143 +444 444 1323.529 +458 444 -1250 +445 445 298.3669 +446 445 -46.72897 +447 445 -67.1141 +446 446 46.72897 +447 447 1251.698 +449 447 -73.52941 +537 447 -487.8049 +448 448 178.454 +464 448 -19.72387 +449 449 2073.529 +450 449 -2000 +450 450 2196.806 +451 450 -21.36752 +451 451 21.36752 +452 452 237.3635 +453 452 -38.31417 +453 453 38.31417 +454 454 413.3297 +455 454 -35.97123 +455 455 35.97123 +456 456 105.5727 +457 456 -24.27184 +564 456 -81.30082 +457 457 24.27184 +458 458 1323.682 +459 458 -18.69159 +460 458 -25.31645 +459 459 18.69159 +460 460 51.68521 +461 460 -21.73913 +461 461 21.73913 +462 462 492.9882 +463 462 -48.54369 +463 463 48.54369 +464 464 86.29654 +465 464 -26.88172 +545 464 -20.96436 +465 465 92.6712 +968 465 -65.78947 +466 466 414.0324 +467 466 -49.75124 +467 467 49.75124 +468 468 10000 +544 468 -10000 +469 469 10000 +543 469 -10000 +470 470 2777.778 +471 471 71.30248 +472 471 -24.67105 +478 471 -11.01079 +481 471 -2.51756 +492 471 -2.24341 +707 471 -5.08647 +708 471 -25.7732 +472 472 24.67105 +473 473 10004.09 +474 473 -4.095004 +474 474 69.19151 +475 475 31.94728 +710 475 -12.28501 +724 475 -10.94691 +476 476 81.26222 +482 476 -32.36246 +477 477 228.7589 +478 477 -160.3849 +478 478 10195.93 +708 478 -20.67495 +709 478 -.6028454 +479 479 118.9729 +480 479 -9.02527 +714 479 -8.410429 +726 479 -5.037783 +480 480 509.0252 +481 481 26.89223 +484 481 -4.597701 +485 481 -4.425562 +491 481 -2.892765 +492 481 -3.441512 +733 481 -9.017133 +482 482 111.1026 +483 482 -78.74016 +483 483 10078.74 +484 484 22.31696 +709 484 -10.70664 +733 484 -7.012623 +485 485 12.73121 +491 485 -8.305648 +486 486 10101.3 +731 486 -51.54639 +487 487 5.743825 +491 487 -5.743825 +488 488 5.743825 +491 488 -5.743825 +489 489 6.968641 +492 489 -6.968641 +490 490 7.077141 +492 490 -7.077141 +491 491 41.56859 +492 491 -16.91332 +734 491 -1.969202 +492 492 10036.64 +707 492 -10000 +493 493 11.23596 +707 493 -11.23596 +494 494 121.9512 +505 494 -121.9512 +495 495 46.2963 +513 495 -46.2963 +496 496 303.0303 +521 496 -303.0303 +497 497 104.1667 +522 497 -104.1667 +498 498 20.08032 +523 498 -20.08032 +499 499 87.33171 +500 499 -39.37008 +819 499 -23.98081 +914 499 -23.98081 +500 500 39.37008 +501 501 227.9827 +502 501 -33.19632 +505 501 -18.58736 +507 501 -58.13953 +521 501 -32.67974 +531 501 -42.55319 +536 501 -42.82655 +502 502 120.8391 +607 502 -33.33334 +609 502 -11.02536 +613 502 -27.3224 +937 502 -15.96169 +503 503 121.5155 +507 503 -42.91846 +513 503 -55.55556 +553 503 -23.04147 +504 504 195.9784 +505 504 -71.42857 +505 505 292.5258 +521 505 -41.49377 +526 505 -17.60563 +578 505 -21.45923 +506 506 10155.04 +507 507 295.7078 +508 507 -12.03369 +509 507 -53.0504 +515 507 -20.4918 +521 507 -39.0625 +522 507 -40.16064 +547 507 -29.85075 +508 508 265.0443 +619 508 -175.4386 +639 508 -56.49718 +781 508 -21.07482 +509 509 912.198 +511 509 -12.0919 +515 509 -82.64463 +520 509 -238.0952 +534 509 -526.3158 +510 510 2646.453 +520 510 -2380.952 +511 511 29.78859 +914 511 -6.779661 +926 511 -10.91703 +512 512 99.0099 +520 512 -99.0099 +513 513 185.3068 +514 513 -9.380863 +540 513 -74.07407 +514 514 28.32451 +790 514 -11.28668 +795 514 -7.656968 +515 515 688.1429 +516 515 -416.6667 +517 515 -10.34126 +518 515 -18.18182 +536 515 -80.64516 +547 515 -59.1716 +516 516 863.6713 +517 517 27.53012 +993 517 -12.95337 +995 517 -4.235493 +518 518 18.18182 +519 519 93.04359 +957 519 -16.42036 +967 519 -68.49315 +520 520 2718.058 +521 521 520.433 +522 521 -104.1667 +522 522 260.4988 +523 522 -12.0048 +523 523 247.5269 +582 523 -196.0784 +770 523 -3.675795 +779 523 -11.60093 +802 523 -4.086637 +524 524 220.5431 +533 524 -158.7302 +985 524 -43.85965 +1001 524 -17.95332 +525 525 78.74016 +568 525 -78.74016 +526 526 71.7446 +527 526 -21.45923 +531 526 -32.67974 +527 527 149.7379 +921 527 -4.553734 +933 527 -5.621135 +1068 527 -35.27337 +1073 527 -30.67485 +1074 527 -25.83979 +1124 527 -26.31579 +528 528 336.2918 +529 528 -196.0784 +809 528 -56.17978 +819 528 -84.03362 +529 529 196.0784 +530 530 261.7177 +578 530 -9.708738 +583 530 -9.259259 +780 530 -5.390836 +797 530 -4.800768 +803 530 -232.5581 +531 531 204.1382 +532 531 -53.71729 +534 531 -75.18797 +532 532 527.8732 +554 532 -35.97123 +647 532 -113.6364 +652 532 -91.3242 +663 532 -45.87156 +668 532 -63.29114 +672 532 -12.97017 +673 532 -32.78688 +677 532 -28.24859 +908 532 -13.75516 +912 532 -18.48429 +918 532 -6.426735 +1047 532 -11.38952 +533 533 158.7302 +534 534 740.9194 +535 534 -21.45923 +536 534 -56.49718 +542 534 -40 +535 535 37.48487 +885 535 -16.02564 +536 536 698.459 +537 536 -416.6667 +538 536 -21.14165 +539 536 -18.18182 +542 536 -62.5 +537 537 904.4716 +538 538 105.9105 +809 538 -33.78378 +914 538 -7.002801 +948 538 -11.17318 +953 538 -10.48768 +964 538 -22.32143 +539 539 18.18182 +540 540 95.5333 +800 540 -21.45923 +541 541 13.9958 +543 541 -13.9958 +542 542 256.9678 +543 542 -42.91846 +545 542 -21.45923 +546 542 -90.0901 +543 543 10075.1 +544 543 -18.18182 +544 544 10018.18 +545 545 72.29217 +546 546 190.0901 +547 547 89.02235 +548 548 7.942812 +551 548 -7.942812 +549 549 8.532423 +563 549 -8.532423 +550 550 35.33569 +566 550 -35.33569 +551 551 65.62718 +552 551 -17.51313 +555 551 -15.47988 +566 551 -24.69136 +552 552 35.10244 +558 552 -3.012048 +560 552 -14.57726 +553 553 67.98992 +561 553 -26.73797 +710 553 -5.035247 +554 554 351.6514 +574 554 -93.45794 +909 554 -222.2222 +555 555 58.73003 +556 555 -16.26016 +557 555 -8.591065 +564 555 -10.9529 +566 555 -7.446017 +556 556 150.6284 +559 556 -64.93507 +579 556 -7.886436 +621 556 -45.04505 +903 556 -16.50165 +557 557 25.14736 +558 557 -16.55629 +558 558 103.3103 +979 558 -4.599816 +980 558 -12.40695 +986 558 -12.0919 +989 558 -14.4405 +991 558 -13.86001 +998 558 -8.061266 +1000 558 -18.28154 +559 559 73.91173 +579 559 -8.976661 +560 560 20.04772 +980 560 -5.470459 +561 561 200.6328 +562 561 -135.1351 +566 561 -38.75969 +562 562 143.5954 +563 562 -8.460238 +563 563 31.84037 +567 563 -3.386387 +564 564 113.4402 +565 565 5.017561 +567 565 -5.017561 +566 566 120.1828 +567 566 -4.231908 +567 567 12.63586 +568 568 164.0549 +773 568 -6.574622 +795 568 -78.74016 +569 569 20.08032 +785 569 -20.08032 +570 570 14.70588 +579 570 -14.70588 +571 571 11.42857 +776 571 -11.42857 +572 572 14.85884 +783 572 -14.85884 +573 573 18.51852 +796 573 -18.51852 +574 574 93.45794 +575 575 400 +581 575 -400 +576 576 23.74311 +582 576 -13.31558 +784 576 -10.42753 +577 577 897.2149 +786 577 -769.2308 +802 577 -8.93655 +1090 577 -119.0476 +578 578 45.98278 +780 578 -14.81481 +579 579 84.46193 +580 579 -2.915452 +782 579 -20.4918 +783 579 -7.85546 +895 579 -18.21494 +927 579 -3.4153 +580 580 16.74671 +587 580 -13.83126 +581 581 427.649 +776 581 -9.65717 +796 581 -4.690432 +797 581 -7.42942 +799 581 -5.87199 +582 582 209.394 +583 583 29.98347 +780 583 -13.03781 +803 583 -7.686395 +584 584 52.25406 +585 584 -45.6621 +1068 584 -6.591958 +585 585 121.8822 +607 585 -38.91051 +613 585 -34.0136 +659 585 -3.295979 +586 586 2.538071 +597 586 -2.538071 +587 587 66.82627 +598 587 -14.08451 +614 587 -38.91051 +588 588 10.00413 +595 588 -5.065856 +597 588 -4.938272 +589 589 6.075334 +591 589 -6.075334 +590 590 11.77992 +595 590 -4.405286 +616 590 -7.374631 +591 591 15.86007 +601 591 -9.784736 +592 592 7.564296 +611 592 -7.564296 +593 593 10.53741 +604 593 -10.53741 +594 594 63.69427 +600 594 -63.69427 +595 595 9.471143 +596 596 22.07258 +597 596 -4.837929 +603 596 -6.493506 +607 596 -10.74114 +597 597 12.31427 +598 598 14.08451 +599 599 6.038647 +1105 599 -6.038647 +600 600 346.1801 +601 600 -4.708098 +782 600 -277.7778 +601 601 23.91828 +602 601 -5.24659 +633 601 -4.178855 +602 602 10.19709 +640 602 -4.950495 +603 603 49.17807 +604 603 -4.837929 +605 603 -10.96491 +1092 603 -26.88172 +604 604 30.79998 +612 604 -7.843137 +615 604 -7.581501 +605 605 31.29012 +607 605 -20.3252 +606 606 3.743916 +610 606 -3.743916 +607 607 103.3102 +608 608 44.10909 +610 608 -41.15226 +1101 608 -2.95683 +609 609 20.31041 +1068 609 -9.285051 +610 610 44.89618 +611 611 19.35675 +615 611 -11.79245 +612 612 7.843137 +613 613 61.33601 +614 614 38.91051 +615 615 19.37395 +616 616 7.374631 +617 617 51.02041 +1123 617 -51.02041 +618 618 27.57334 +629 618 -10.09082 +639 618 -17.48252 +619 619 180.4386 +620 619 -5 +620 620 7.089864 +632 620 -2.089864 +621 621 137.2607 +624 621 -87.7193 +1061 621 -4.496403 +622 622 12.46672 +625 622 -10.67236 +641 622 -1.794366 +623 623 18.4185 +639 623 -10.37344 +642 623 -8.045053 +624 624 110.7608 +638 624 -23.04147 +625 625 17.12814 +635 625 -6.455778 +626 626 8.504332 +634 626 -5.627462 +635 626 -2.87687 +627 627 15.82279 +639 627 -15.82279 +628 628 43.10402 +631 628 -33.22259 +642 628 -9.881423 +629 629 5125.033 +637 629 -5000 +643 629 -114.9425 +630 630 27.86917 +631 630 -5.931198 +635 630 -4.347826 +796 630 -17.59015 +631 631 39.15379 +632 632 10.68662 +634 632 -6.830601 +641 632 -1.76616 +633 633 4.178855 +634 634 12.45806 +635 635 18.68799 +636 635 -5.007511 +636 636 8.039652 +1094 636 -3.03214 +637 637 5000 +638 638 23.04147 +639 639 100.1759 +640 640 4.950495 +641 641 3.560526 +642 642 17.92648 +643 643 114.9425 +644 644 87.81362 +652 644 -55.55556 +662 644 -32.25806 +645 645 32.23264 +650 645 -26.80965 +1060 645 -5.422993 +646 646 35.23614 +664 646 -30.4878 +1051 646 -4.748338 +647 647 132.4334 +1041 647 -18.79699 +648 648 87.5595 +678 648 -64.93507 +1042 648 -22.62444 +649 649 89.50495 +672 649 -40 +1055 649 -49.50495 +650 650 43.7588 +653 650 -16.94915 +651 651 35.83253 +670 651 -15.12859 +1045 651 -20.70393 +652 652 4092.357 +653 652 -4.440497 +663 652 -3333.333 +666 652 -97.08738 +668 652 -158.7302 +676 652 -18.55288 +1054 652 -333.3333 +653 653 31.9941 +1048 653 -10.60445 +654 654 184.7682 +677 654 -39.84064 +1057 654 -144.9275 +655 655 330.6451 +657 655 -80.64516 +665 655 -250 +656 656 4.040404 +678 656 -4.040404 +657 657 188.172 +1055 657 -107.5269 +658 658 298.2456 +671 658 -131.5789 +672 658 -166.6667 +659 659 65.79597 +677 659 -62.5 +660 660 36.60525 +1050 660 -17.03578 +1058 660 -19.56947 +661 661 500 +677 661 -500 +662 662 90.3976 +672 662 -58.13953 +663 663 3379.205 +664 664 60.0736 +1056 664 -29.5858 +665 665 340.0901 +682 665 -90.0901 +666 666 623.4032 +681 666 -526.3158 +667 667 5.494505 +1051 667 -5.494505 +668 668 222.0213 +669 669 400 +679 669 -66.66667 +1058 669 -333.3333 +670 670 69.18265 +1121 670 -54.05405 +671 671 184.7704 +679 671 -53.19149 +672 672 619.955 +673 672 -24.27184 +682 672 -117.647 +1049 672 -40 +1050 672 -16.80672 +1052 672 -18.34863 +1058 672 -19.84127 +1121 672 -105.2632 +673 673 57.05873 +674 674 340.5986 +675 674 -322.5806 +1046 674 -18.01802 +675 675 353.4448 +1050 675 -30.8642 +676 676 172.399 +1043 676 -153.8461 +677 677 945.5062 +678 677 -4.347826 +1041 677 -66.66667 +1059 677 -243.9024 +678 678 73.3233 +679 679 119.8582 +680 680 103.5542 +1047 680 -46.08295 +1057 680 -57.47126 +681 681 1637.427 +1053 681 -1111.111 +682 682 207.7372 +683 683 1.579031 +689 683 -1.579031 +684 684 1.923077 +689 684 -1.923077 +685 685 1.764913 +691 685 -1.764913 +686 686 328.5128 +687 686 -18.34863 +688 686 -24.44988 +687 687 18.34863 +688 688 71.2075 +689 688 -4.409431 +694 688 -8.312551 +699 688 -3.82995 +700 688 -7.374631 +702 688 -22.83105 +689 689 9.846897 +693 689 -1.935359 +690 690 10178.92 +691 690 -4.99002 +694 690 -161.2903 +697 690 -12.64223 +691 691 10040.88 +692 691 -10000 +695 691 -34.12969 +692 692 10000 +693 693 36.06505 +695 693 -34.12969 +694 694 187.9515 +695 694 -18.34863 +695 695 86.60801 +696 696 70.92198 +697 697 23.45304 +698 697 -10.81081 +698 698 10.81081 +699 699 27.1355 +700 699 -7.968128 +700 700 15.34276 +701 701 10000 +702 702 50.80308 +703 703 10000 +704 704 20.8778 +705 705 10000 +706 706 11.04972 +707 706 -11.04972 +707 707 10067.62 +726 707 -40.24145 +708 708 78.90948 +709 708 -32.46134 +709 709 44.41736 +710 710 10017.32 +711 711 10024.15 +724 711 -11.7096 +734 711 -12.43781 +712 712 10.78749 +714 712 -10.78749 +713 713 10.92896 +714 713 -10.92896 +714 714 102.2441 +715 714 -25.08151 +734 714 -23.9521 +715 715 33.13305 +716 716 370.5403 +717 716 -4.541326 +717 717 346.6114 +718 718 14.51379 +724 718 -14.51379 +719 719 14.51379 +724 719 -14.51379 +720 720 14.51379 +724 720 -14.51379 +721 721 14.51379 +724 721 -14.51379 +722 722 14.51379 +724 722 -14.51379 +723 723 14.51379 +724 723 -14.51379 +724 724 156.8111 +725 724 -2.262444 +734 724 -6.215041 +725 725 37.84963 +726 726 45.27923 +727 727 22.77734 +728 727 -1.437174 +731 727 -21.34016 +728 728 22.77734 +731 728 -21.34016 +729 729 22.54354 +730 729 -.5025378 +731 729 -22.041 +730 730 22.63133 +731 730 -22.12879 +731 731 213.6977 +732 732 2.369107 +733 733 16.02976 +734 734 44.57415 +735 735 3.749531 +743 735 -3.749531 +736 736 5.060729 +742 736 -5.060729 +737 737 10.41667 +743 737 -10.41667 +738 738 25.25253 +742 738 -25.25253 +739 739 6.666667 +744 739 -6.666667 +740 740 10119.13 +741 740 -29.06977 +742 740 -9.416196 +744 740 -80.64516 +741 741 66.38967 +749 741 -30.12048 +759 741 -7.199424 +742 742 97.15186 +743 742 -36.00912 +743 743 65.14973 +746 743 -4.042037 +744 744 120.6452 +756 744 -33.33334 +745 745 10004.53 +746 745 -4.531038 +746 746 8.573075 +747 747 83.11967 +748 747 -15.5521 +758 747 -67.56757 +748 748 35.75412 +757 748 -20.20202 +749 749 109.4856 +753 749 -79.36508 +750 750 36.15381 +751 750 -9.199632 +759 750 -26.95418 +751 751 9.199632 +752 752 14.23959 +757 752 -10.20408 +762 752 -4.035512 +753 753 79.36508 +754 754 101.7248 +757 754 -42.55319 +765 754 -59.1716 +755 755 34.41619 +764 755 -25 +756 756 61.14975 +757 756 -27.81641 +757 757 100.7757 +758 758 67.56757 +759 759 34.1536 +760 760 6.238303 +761 760 -6.238303 +761 761 27.13861 +766 761 -4.730369 +767 761 -8 +762 762 8.519817 +763 762 -4.484305 +763 763 4.484305 +764 764 25 +765 765 59.1716 +766 766 7.055951 +768 766 -2.325581 +767 767 8 +768 768 8.877011 +769 768 -3.030303 +772 768 -3.521127 +769 769 3.030303 +770 770 10003.68 +823 770 -10000 +771 771 4.694836 +772 771 -4.694836 +772 772 8.215962 +773 773 41.97304 +774 773 -9.191176 +795 773 -6.067961 +801 773 -5.646527 +802 773 -14.49275 +774 774 9.191176 +775 775 87.97093 +776 775 -79.36508 +781 775 -8.605852 +776 776 145.414 +781 776 -7.067138 +796 776 -2.511932 +797 776 -3.435246 +1127 776 -31.94888 +777 777 24.34617 +793 777 -3.907777 +795 777 -5.797101 +800 777 -14.64129 +778 778 27.51031 +779 778 -27.51031 +779 779 52.63487 +780 779 -3.543586 +787 779 -9.980041 +780 780 53.90431 +797 780 -2.540005 +949 780 -14.57726 +781 781 36.74781 +782 782 311.0084 +783 782 -12.73885 +783 783 35.45316 +784 784 25.00479 +802 784 -14.57726 +785 785 85.04397 +786 785 -26.66667 +788 785 -16.80672 +796 785 -5.941771 +797 785 -11.00715 +802 785 -4.541326 +786 786 1295.897 +1128 786 -500 +787 787 18.79838 +949 787 -8.818342 +788 788 201.3442 +789 788 -2.932551 +796 788 -9.191176 +1132 788 -172.4138 +789 789 6.317792 +1094 789 -3.38524 +790 790 67.99094 +791 790 -32.89474 +795 790 -23.80952 +791 791 32.89474 +792 792 18.23483 +799 792 -10.1833 +1110 792 -8.05153 +793 793 10007.82 +794 793 -3.907777 +825 793 -10000 +794 794 24.34617 +795 794 -5.797101 +800 794 -14.64129 +795 795 127.8688 +796 796 80.27805 +799 796 -21.83406 +797 797 107.3739 +798 797 -4.818348 +803 797 -4.5106 +805 797 -18.83239 +1119 797 -50 +798 798 10.82075 +1114 798 -6.002401 +799 799 37.88935 +800 800 50.74181 +801 801 5.646527 +802 802 10046.63 +1137 802 -10000 +803 803 290.2097 +804 803 -45.45454 +804 804 45.45454 +805 805 136.4794 +1138 805 -117.647 +806 806 4.975124 +821 806 -4.975124 +807 807 4.065041 +887 807 -4.065041 +808 808 13.33333 +897 808 -13.33333 +809 809 202.3231 +920 809 -112.3596 +810 810 39.62731 +811 810 -26.31579 +918 810 -8.70322 +811 811 26.31579 +812 812 500 +909 812 -500 +813 813 805.5555 +885 813 -11.13586 +940 813 -25.18892 +1122 813 -769.2308 +814 814 149.0395 +815 814 -112.3596 +909 814 -23.14815 +918 814 -13.5318 +815 815 112.3596 +816 816 67.98565 +817 816 -47.61905 +927 816 -20.3666 +817 817 139.7763 +818 817 -52.63158 +907 817 -39.52569 +818 818 52.63158 +819 819 340.5726 +820 819 -232.5581 +820 820 232.5581 +821 821 148.7724 +888 821 -22.72727 +897 821 -114.9425 +921 821 -6.127451 +822 822 133.5555 +880 822 -77.51938 +885 822 -25.64103 +935 822 -30.39514 +823 823 10000 +824 824 10000 +825 824 -10000 +825 825 20000 +826 826 10000 +827 827 10000 +828 828 12.59221 +837 828 -3.399953 +838 828 -4.568296 +874 828 -4.623957 +829 829 38.16908 +833 829 -9.785693 +839 829 -9.75447 +830 830 35.75804 +833 830 -12.15067 +840 830 -9.559799 +831 831 21.56662 +841 831 -10.30197 +869 831 -11.26464 +832 832 24.83065 +842 832 -6.55914 +869 832 -18.27151 +833 833 25.06136 +843 833 -3.125 +834 834 65.83865 +844 834 -9.816236 +874 834 -56.02241 +835 835 97.96513 +845 835 -1.626016 +862 835 -96.33911 +836 836 13.04241 +846 836 -6.806048 +869 836 -6.236358 +837 837 3.399953 +838 838 11.84409 +859 838 -6.666667 +860 838 -.6091247 +839 839 9.75447 +840 840 9.559799 +841 841 10.30197 +842 842 6.55914 +843 843 3.125 +844 844 9.816236 +845 845 1.626016 +846 846 6.806048 +847 847 6.595976 +848 847 -6.595976 +848 848 14.46535 +873 848 -7.869369 +849 849 7.853637 +854 849 -3.149802 +863 849 -2.352 +864 849 -2.351835 +850 850 9.019895 +855 850 -6.506006 +873 850 -2.513889 +851 851 1.965569 +856 851 -.805153 +858 851 -1.160416 +852 852 2.941501 +857 852 -1.692047 +869 852 -1.249453 +853 853 5.118024 +876 853 -5.118024 +854 854 3.149802 +855 855 6.506006 +856 856 .805153 +857 857 1.692047 +858 858 3.252203 +873 858 -2.091788 +859 859 6.666667 +860 860 1.422133 +861 860 -.8130081 +861 861 .8130081 +862 862 101.7126 +863 862 -5.373455 +863 863 10.56927 +869 863 -2.843818 +864 864 26.18864 +865 864 -20.9205 +869 864 -2.916302 +865 865 20.9205 +866 866 71.85119 +869 866 -67.1141 +877 866 -4.737092 +867 867 5.135919 +878 867 -5.135919 +868 868 79.89591 +869 868 -68.02721 +871 868 -7.077141 +877 868 -4.791567 +869 869 245.0375 +870 869 -67.1141 +870 870 78.94842 +871 870 -7.097232 +877 870 -4.737092 +871 871 14.17437 +872 872 3.439506 +882 872 -3.439506 +873 873 19.16737 +882 873 -6.692322 +874 874 65.74321 +878 874 -5.09684 +875 875 268.8182 +876 875 -227.2727 +882 875 -41.54549 +876 876 232.3908 +877 877 144.0989 +878 877 -54.4514 +883 877 -15.50147 +878 878 64.68417 +879 879 13.23977 +882 879 -13.23977 +880 880 77.51938 +881 881 15.55936 +882 881 -15.55936 +882 882 209.5087 +883 883 15.50147 +884 884 208.6253 +937 884 -114.2857 +1123 884 -94.33962 +885 885 67.07021 +914 885 -9.425071 +918 885 -4.842615 +886 886 34.37894 +895 886 -13.2626 +927 886 -6.146282 +937 886 -14.97006 +887 887 30.75514 +896 887 -15.94896 +897 887 -10.74114 +888 888 34.51973 +924 888 -11.79245 +889 889 526.3158 +917 889 -526.3158 +890 890 90.17906 +891 890 -55.55556 +908 890 -11.79245 +917 890 -22.83105 +891 891 55.55556 +892 892 185.8299 +893 892 -78.74016 +899 892 -68.02721 +927 892 -39.0625 +893 893 78.74016 +894 894 10037.21 +921 894 -24.93765 +936 894 -12.26994 +1126 894 -10000 +895 895 486.023 +1125 895 -454.5455 +896 896 48.8437 +897 896 -32.89474 +897 897 242.6641 +913 897 -54.05405 +917 897 -3.943218 +944 897 -12.7551 +898 898 119.8733 +914 898 -21.83406 +926 898 -98.03922 +899 899 208.295 +900 899 -36.10108 +908 899 -104.1667 +900 900 36.10108 +901 901 10010.86 +913 901 -10.85776 +1129 901 -10000 +902 902 400 +906 902 -400 +903 903 27.64992 +987 903 -11.14827 +904 904 479.299 +905 904 -256.4103 +939 904 -192.3077 +944 904 -30.58104 +905 905 256.4103 +906 906 613.7151 +922 906 -17.63668 +939 906 -196.0784 +907 907 58.35809 +923 907 -18.83239 +908 908 200.9013 +912 908 -43.47826 +917 908 -7.668712 +927 908 -20.04008 +909 909 941.4488 +910 909 -196.0784 +910 910 196.0784 +911 911 131.5789 +912 911 -131.5789 +912 912 193.5415 +913 913 64.91182 +914 914 181.033 +935 914 -29.23977 +938 914 -78.74016 +963 914 -4.030633 +915 915 103.0928 +926 915 -103.0928 +916 916 81.96722 +991 916 -81.96722 +917 917 754.9636 +918 917 -121.2121 +930 917 -72.9927 +918 918 232.832 +919 918 -52.63158 +1130 918 -22.47191 +919 919 69.87296 +940 919 -17.24138 +920 920 112.3596 +921 921 123.4495 +923 921 -22.98851 +924 921 -29.06977 +927 921 -5.208333 +933 921 -23.98081 +937 921 -6.583279 +922 922 10033.82 +930 922 -16.18123 +1133 922 -10000 +923 923 41.8209 +924 924 79.77273 +925 924 -38.91051 +925 925 38.91051 +926 926 212.049 +927 927 138.2073 +928 927 -37.17472 +937 927 -6.793478 +928 928 1045.494 +929 928 -999.9999 +937 928 -8.319468 +929 929 999.9999 +930 930 185.3278 +931 930 -96.15385 +931 931 96.15385 +932 932 78.74016 +949 932 -78.74016 +933 933 187.4276 +934 933 -131.5789 +942 933 -26.24672 +934 934 131.5789 +935 935 94.47811 +947 935 -34.8432 +936 936 10045.17 +937 936 -32.89474 +1134 936 -10000 +937 937 199.8084 +938 938 78.74016 +939 939 388.3861 +940 940 141.4402 +954 940 -99.0099 +941 941 400 +954 941 -400 +942 942 26.24672 +943 943 80.64516 +944 943 -80.64516 +944 944 123.9813 +945 945 3.323363 +961 945 -3.323363 +946 946 10.52632 +965 946 -10.52632 +947 947 34.8432 +948 948 110.8715 +952 948 -12.90323 +955 948 -10.88454 +957 948 -18.50139 +958 948 -35.08772 +964 948 -22.32143 +949 949 102.1358 +950 950 59.13499 +951 950 -4.399472 +955 950 -35.77818 +956 950 -18.95735 +951 951 26.76585 +965 951 -4.962779 +969 951 -10.17294 +975 951 -7.230658 +952 952 78.2627 +960 952 -65.35947 +953 953 32.95959 +955 953 -22.47191 +954 954 528.2497 +959 954 -29.23977 +955 955 69.13462 +956 956 18.95735 +957 957 153.211 +958 957 -17.85714 +967 957 -21.69197 +973 957 -78.74016 +958 958 52.94486 +959 959 29.23977 +960 960 465.3595 +973 960 -400 +961 961 17.72833 +962 961 -6.060606 +963 961 -2.007226 +968 961 -6.337135 +962 962 42.96098 +966 962 -36.90037 +963 963 10.88517 +972 963 -4.84731 +964 964 44.64286 +965 965 31.12432 +968 965 -5.945303 +969 965 -9.689922 +966 966 135.9103 +971 966 -99.0099 +967 967 90.18512 +968 968 78.07191 +969 969 26.28135 +970 969 -6.418485 +970 970 6.418485 +971 971 110.4385 +972 971 -11.42857 +972 972 16.27588 +973 973 478.7402 +974 974 999.9999 +983 974 -999.9999 +975 975 7.230658 +976 976 131.2277 +977 976 -72.9927 +989 976 -11.28668 +1001 976 -46.94836 +977 977 72.9927 +978 978 11.99041 +989 978 -11.99041 +979 979 212.9332 +983 979 -208.3333 +980 980 17.87741 +981 981 214.386 +982 981 -192.3077 +984 981 -12.04819 +998 981 -10.03009 +982 982 192.3077 +983 983 1216.031 +986 983 -7.69823 +984 984 12.04819 +985 985 73.44217 +987 985 -24.27184 +989 985 -5.310675 +986 986 19.79013 +987 987 74.94581 +999 987 -39.52569 +988 988 25.27583 +993 988 -12.42236 +995 988 -12.85347 +989 989 48.93494 +990 989 -5.906674 +990 990 5.906674 +991 991 98.75978 +992 991 -2.932551 +992 992 2.932551 +993 993 29.40311 +994 993 -4.027386 +994 994 4.027386 +995 995 28.39029 +997 995 -7.267442 +998 995 -4.033885 +996 996 78.74016 +997 996 -78.74016 +997 997 95.07378 +998 997 -9.066183 +998 998 31.19142 +999 999 39.52569 +1000 1000 18.28154 +1001 1001 64.90168 +1002 1002 8.319468 +1027 1002 -8.319468 +1003 1003 4.084967 +1035 1003 -4.084967 +1004 1004 3.15856 +1032 1004 -3.15856 +1005 1005 10.41667 +1039 1005 -10.41667 +1006 1006 125.0263 +1007 1006 -4.149378 +1013 1006 -19.26782 +1019 1006 -10.48218 +1021 1006 -55.24862 +1030 1006 -14.32665 +1035 1006 -21.55167 +1007 1007 4.149378 +1008 1008 24.42002 +1023 1008 -24.42002 +1009 1009 10093.68 +1010 1009 -1.567398 +1018 1009 -21.18644 +1019 1009 -6.297229 +1021 1009 -4.244482 +1022 1009 -57.14286 +1040 1009 -3.239391 +1010 1010 1.567398 +1011 1011 41.15226 +1040 1011 -41.15226 +1012 1012 5.87199 +1040 1012 -5.87199 +1013 1013 748.2476 +1023 1013 -15.07159 +1029 1013 -454.4287 +1030 1013 -32.57329 +1037 1013 -118.3432 +1038 1013 -102.5641 +1039 1013 -5.9988 +1014 1014 75.75758 +1039 1014 -75.75758 +1015 1015 34.60208 +1029 1015 -34.60208 +1016 1016 4.102139 +1024 1016 -2.283626 +1034 1016 -1.818512 +1017 1017 73.80074 +1029 1017 -73.80074 +1018 1018 21.18644 +1019 1019 60.25767 +1033 1019 -43.47826 +1020 1020 34.96503 +1021 1020 -34.96503 +1021 1021 94.45814 +1022 1022 57.14286 +1023 1023 66.38087 +1024 1023 -6.973501 +1025 1023 -7.352941 +1027 1023 -12.56281 +1024 1024 11.00568 +1034 1024 -1.748557 +1025 1025 11.7895 +1028 1025 -4.436557 +1026 1026 16.88283 +1027 1026 -9.615384 +1027 1027 38.77231 +1028 1027 -3.372681 +1035 1027 -4.901961 +1028 1028 7.809239 +1029 1029 10562.83 +1030 1030 56.26324 +1031 1030 -9.363297 +1031 1031 9.363297 +1032 1032 19.43661 +1034 1032 -5.455537 +1036 1032 -10.82251 +1033 1033 43.47826 +1034 1034 9.022608 +1035 1035 34.63528 +1036 1035 -4.096682 +1036 1036 14.91919 +1037 1037 118.3432 +1038 1038 102.5641 +1039 1039 92.17304 +1040 1040 50.26365 +1041 1041 85.46367 +1042 1042 22.62444 +1043 1043 179.8878 +1050 1043 -26.04167 +1044 1044 51.6919 +1050 1044 -33.8983 +1053 1044 -17.79359 +1045 1045 69.24763 +1047 1045 -48.54369 +1046 1046 71.20951 +1058 1046 -53.19149 +1047 1047 106.0162 +1048 1048 10.60445 +1049 1049 66.17801 +1054 1049 -26.17801 +1050 1050 5329.354 +1051 1050 -4.708098 +1052 1050 -200 +1051 1051 18.55844 +1056 1051 -3.607503 +1052 1052 218.3486 +1053 1053 1128.905 +1054 1054 359.5114 +1055 1055 267.5334 +1056 1055 -4.118616 +1058 1055 -106.383 +1056 1056 37.31192 +1057 1057 202.3988 +1058 1058 532.3185 +1059 1059 295.9858 +1061 1059 -52.08333 +1060 1060 5.422993 +1061 1061 56.57973 +1062 1062 9.573448 +1072 1062 -6.301197 +1085 1062 -3.272251 +1063 1063 14.97518 +1074 1063 -10.35197 +1064 1064 15.77324 +1075 1064 -11.49425 +1087 1064 -4.27899 +1065 1065 56.4111 +1077 1065 -7.256895 +1080 1065 -32.67974 +1066 1066 14.0056 +1068 1066 -14.0056 +1067 1067 2.654632 +1071 1067 -2.654632 +1068 1068 96.37038 +1069 1068 -21.64502 +1092 1068 -9.569378 +1069 1069 49.50018 +1086 1069 -27.85515 +1070 1070 27.63299 +1077 1070 -21.09705 +1113 1070 -6.535948 +1071 1071 6.953859 +1088 1071 -4.299226 +1072 1072 10.51705 +1075 1072 -4.215851 +1073 1073 194.6093 +1074 1073 -163.9344 +1074 1074 315.5717 +1075 1074 -5.040322 +1081 1074 -85.47009 +1086 1074 -21.73913 +1075 1075 25.04781 +1082 1075 -4.297379 +1076 1076 18.69159 +1077 1076 -18.69159 +1077 1077 82.05888 +1078 1077 -9.416196 +1080 1077 -9.328359 +1088 1077 -11.54734 +1095 1077 -4.721436 +1078 1078 30.82096 +1084 1078 -17.66784 +1085 1078 -3.736921 +1079 1079 3.007519 +1117 1079 -3.007519 +1080 1080 42.00809 +1081 1081 85.47009 +1082 1082 4.297379 +1083 1083 500 +1087 1083 -500 +1084 1084 17.66784 +1085 1085 7.009172 +1086 1086 49.59428 +1087 1087 504.279 +1088 1088 15.84657 +1089 1089 12.21374 +1106 1089 -9.225092 +1112 1089 -2.988643 +1090 1090 123.7557 +1091 1090 -4.708098 +1091 1091 14.65977 +1093 1091 -5.681818 +1108 1091 -4.269855 +1092 1092 36.4511 +1093 1093 14.98414 +1098 1093 -9.302325 +1094 1094 6.417381 +1095 1095 136.3807 +1096 1095 -4.440497 +1100 1095 -7.342144 +1105 1095 -16.23377 +1113 1095 -87.7193 +1096 1096 16.50748 +1103 1096 -7.581501 +1107 1096 -2.338634 +1112 1096 -2.146844 +1097 1097 99.0099 +1100 1097 -99.0099 +1098 1098 15.8597 +1099 1098 -6.557377 +1099 1099 6.557377 +1100 1100 110.9308 +1101 1100 -4.578754 +1101 1101 13.03916 +1120 1101 -5.503577 +1102 1102 4.524887 +1112 1102 -4.524887 +1103 1103 7.581501 +1104 1104 46.18962 +1118 1104 -23.14815 +1119 1104 -23.04147 +1105 1105 22.27241 +1106 1106 15.2311 +1109 1106 -6.006006 +1107 1107 2.338634 +1108 1108 4.269855 +1109 1109 6.006006 +1110 1110 10.67965 +1114 1110 -2.628121 +1111 1111 7.380074 +1119 1111 -7.380074 +1112 1112 9.660375 +1113 1113 94.25525 +1114 1114 15.25571 +1115 1114 -4.384042 +1116 1114 -2.241148 +1115 1115 4.384042 +1116 1116 2.241148 +1117 1117 7.461862 +1120 1117 -4.454343 +1118 1118 23.14815 +1119 1119 80.42155 +1120 1120 9.95792 +1121 1121 159.3172 +1122 1122 791.0173 +1136 1122 -21.78649 +1123 1123 145.36 +1124 1124 37.05693 +1135 1124 -10.74114 +1125 1125 454.5455 +1126 1126 10000 +1127 1127 31.94888 +1128 1128 500 +1129 1129 10015.82 +1135 1129 -15.82279 +1130 1130 22.47191 +1131 1131 24.39024 +1136 1131 -24.39024 +1132 1132 172.4138 +1133 1133 10000 +1134 1134 10000 +1135 1135 26.56392 +1136 1136 46.17674 +1137 1137 10000 +1138 1138 117.647 diff --git a/scripts/convert2bin-par.sh b/scripts/convert2bin-par.sh old mode 100644 new mode 100755 index d858e01..defec68 --- a/scripts/convert2bin-par.sh +++ b/scripts/convert2bin-par.sh @@ -1,7 +1,7 @@ ## input file: a text file n lines, each line has the full path of a sparse matrix in MM format. infile=$1 ##/path/to/conv2bin -exc=$HOME/projects/SpComm3D/conv2bin +exc=../build/conv2bin while read -r line do outFN=`echo $(dirname $line)"/"$(basename $line .mtx)".bin"` diff --git a/scripts/matrices.txt b/scripts/matrices.txt new file mode 100644 index 0000000..ccc6891 --- /dev/null +++ b/scripts/matrices.txt @@ -0,0 +1,2 @@ +1138_bus.mtx +simple.mtx diff --git a/scripts/simple.bin b/scripts/simple.bin new file mode 100644 index 0000000..95dd4cb Binary files /dev/null and b/scripts/simple.bin differ diff --git a/scripts/simple.mtx b/scripts/simple.mtx new file mode 100644 index 0000000..c4819a2 --- /dev/null +++ b/scripts/simple.mtx @@ -0,0 +1,28 @@ +%%MatrixMarket matrix coordinate real general +% This file represents a 5x5 matrix with values corresponding to the row index +5 5 25 +1 1 1.0 +1 2 1.0 +1 3 1.0 +1 4 1.0 +1 5 1.0 +2 1 2.0 +2 2 2.0 +2 3 2.0 +2 4 2.0 +2 5 2.0 +3 1 3.0 +3 2 3.0 +3 3 3.0 +3 4 3.0 +3 5 3.0 +4 1 4.0 +4 2 4.0 +4 3 4.0 +4 4 4.0 +4 5 4.0 +5 1 5.0 +5 2 5.0 +5 3 5.0 +5 4 5.0 +5 5 5.0 \ No newline at end of file diff --git a/src/SparseMatrix.hpp b/src/SparseMatrix.hpp index c965475..a68623c 100644 --- a/src/SparseMatrix.hpp +++ b/src/SparseMatrix.hpp @@ -13,16 +13,16 @@ namespace SpKernels{ class SparseMatrix { public: - std::vector ltgR, ltgC; - std::vector ownedVals; - std::unordered_map gtlR, gtlC; - virtual void localizeIndices(){}; - virtual void delocalizeIndices(){}; + std::vector ltgR, ltgC; // local to global row/col mapping + std::vector ownedVals; // local values + std::unordered_map gtlR, gtlC; // global to local mapping + virtual void localizeIndices(){}; // generate new index mappings + virtual void delocalizeIndices(){}; // not overridden? virtual void ReMapIndices(std::vector mapR, std::vectormapC){}; std::string mtxName; - int rank, xyrank, zrank; + int rank, xyrank, zrank; // rank in MPI_COMM_WORLD, 2D COMM, 3D COMM IdxT nrows, ncols, ownedNnz, gnrows, gncols; - idx_large_t nnz, gnnz; + idx_large_t nnz, gnnz; // local and global nnz private: /* data */ diff --git a/src/comm_stats.cpp b/src/comm_stats.cpp index 3f813f9..475c151 100644 --- a/src/comm_stats.cpp +++ b/src/comm_stats.cpp @@ -6,6 +6,7 @@ #include #include #include +#include using namespace DComm; using namespace SpKernels; diff --git a/src/dcomm_setup.cpp b/src/dcomm_setup.cpp index 663f7f8..e6bba8a 100644 --- a/src/dcomm_setup.cpp +++ b/src/dcomm_setup.cpp @@ -3,6 +3,7 @@ #include "denseComm.hpp" #include "mpi.h" #include "SparseMatrix.hpp" +#include using namespace DComm; diff --git a/src/distribute.hpp b/src/distribute.hpp index bd94fdf..eda0df4 100644 --- a/src/distribute.hpp +++ b/src/distribute.hpp @@ -8,7 +8,7 @@ #include "comm.hpp" #include "Mesh3D.hpp" #include "mpi.h" -#include +#include "SparseMatrix.hpp" namespace SpKernels { diff --git a/src/distributed_comp.cpp b/src/distributed_comp.cpp index 13c75a6..bb31cda 100644 --- a/src/distributed_comp.cpp +++ b/src/distributed_comp.cpp @@ -4,6 +4,7 @@ #include "distributed_comp.hpp" #include "core_ops.hpp" #include "comm_stats.hpp" +#include diff --git a/src/mm.hpp b/src/mm.hpp index ba90692..826c15b 100644 --- a/src/mm.hpp +++ b/src/mm.hpp @@ -18,45 +18,68 @@ namespace SpKernels{ _FN = FN; } void read_mm(std::string FN, cooMat& _mtx){ + // initialize symmetry info vars to false bool use_pfile = false, write_ovec=false, mm_pattern=false, mm_symm=false, mm_complex=false; + + // declare matrix dimension variables idx_t _nrows, _ncols, _nnz; + string firstline; ifstream mtxfile(FN.c_str()); + + // get first line getline(mtxfile, firstline); + + // obtain symmetry information and matrix dimension if(firstline.find("pattern") != string::npos) mm_pattern = true; if(firstline.find("symmetric") != string::npos) mm_symm = true; if(firstline.find("complex") != string::npos) mm_complex = true; while(mtxfile.peek() == '%') mtxfile.ignore(2048, '\n'); mtxfile >> _nrows >> _ncols >> _nnz; + + // DEBUG output //printf("nrows=%d ncols=%d nnz=%d nparts=%d mm_pattern is %d mm_symm is %d\n", nrows, ncols, nnz, nparts, mm_pattern, mm_symm); + if(mm_symm) _nnz*=2; + + // shape matrix to match input dimension, set corresponding meber vars in return mtx class _mtx.ii.resize(_nnz); _mtx.jj.resize(_nnz); _mtx.vv.resize(_nnz); _mtx.gnnz = _mtx.nnz = _nnz; _mtx.gncols = _mtx.ncols = _ncols; _mtx.gnrows = _mtx.nrows= _nrows; + + // COO coordinate and value vectors vector& _ii = _mtx.ii; vector& _jj = _mtx.jj; vector& _vv = _mtx.vv; + + // value index (different from col/row index due to very large matrices having + // much larger nnz than #rows / #columns idx_large_t i; idx_large_t hnnz = (mm_symm)? _nnz/2:_nnz; real_t tt; + + // if the input matrix has nonzeros that are not 1.0 if(!mm_pattern) for (i = 0; i < hnnz; ++i){ if(!mm_complex) mtxfile >> _ii[i] >> _jj[i] >> _vv[i]; else mtxfile >> _ii[i] >> _jj[i] >> _vv[i] >> tt; + // convert to 0 indexing _ii[i]--; _jj[i]--; + + // need to set two entries for symmetric matrices if(mm_symm){ _ii[i+(_nnz/2)] = _jj[i]; _jj[i+(_nnz/2)] = _ii[i]; _vv[i+(_nnz/2)]= _vv[i]; } } - + // case when all nonzero values are 1 else{ for (i = 0; i < hnnz; ++i){ mtxfile >> _ii[i] >> _jj[i]; diff --git a/src/parallel_io.hpp b/src/parallel_io.hpp index 491fde4..88e0523 100644 --- a/src/parallel_io.hpp +++ b/src/parallel_io.hpp @@ -17,22 +17,23 @@ using namespace std; namespace SpKernels{ void read_bin_parallel_distribute( - std::string filename, - std::vector& myelms, - idx_t& grows, - idx_t& gcols, - idx_large_t& gnnz, - idx_large_t& lnnz, - std::vector& rpvec2D, - std::vector& cpvec2D, - MPI_Comm worldcomm, - MPI_Comm xycomm, - MPI_Comm zcomm){ + std::string filename, // name of the file to read from + std::vector& myelms, // vector of local COO Triplets + idx_t& grows, idx_t& gcols, idx_large_t& gnnz, // global size information (#rows, #cols, nnz) + idx_large_t& lnnz, // local nnz + std::vector& rpvec2D, std::vector& cpvec2D, // row/col partition ? (2D grid) + MPI_Comm worldcomm, MPI_Comm xycomm, MPI_Comm zcomm // communicators (3D Cartesian, 2D (XY) , 1D (Z)) + ) { + // declare communicator-related variables and coordinates in COMM Grids int myworldrank, worldsize, myxyrank, myzrank, xysize, zsize; int X,Y,Z; std::array dims, t1, t2; + + // Retrieve topology information associated with the *3D* communicator MPI_Cart_get(worldcomm, 3, dims.data(), t1.data(), t2.data()); X = dims[0]; Y=dims[1]; Z=dims[2]; + + // get rank within and size for each of the 3 Communicators MPI_Comm_rank( worldcomm, &myworldrank); MPI_Comm_size( worldcomm, &worldsize); MPI_Comm_rank( xycomm, &myxyrank); @@ -53,8 +54,9 @@ namespace SpKernels{ MPI_Type_create_struct(nitems, blocklengths, offsets, types, &mpi_s_type); MPI_Type_commit(&mpi_s_type); + /* get XY comm - * if zcomm = 0 pefrorm the read + * if zcomm = 0 perfrorm the read * */ MPI_File file; MPI_File_open(xycomm, filename.data(), MPI_MODE_RDONLY, MPI_INFO_NULL, &file); diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt new file mode 100644 index 0000000..77785e8 --- /dev/null +++ b/testing/CMakeLists.txt @@ -0,0 +1,23 @@ +############################################################################### +## symlink for matrices ####################################################### +############################################################################### + +# Helper function to create relative symbolic links from the current binary directory to the source directory +function(create_relative_symlink_from_bin_dir target link_name) + # compute relative path from current binary directory to target + file(RELATIVE_PATH target_rel ${CMAKE_CURRENT_BINARY_DIR} ${target}) + # create symbolic links + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_rel} ${CMAKE_CURRENT_BINARY_DIR}/${link_name}) +endfunction() + +create_relative_symlink_from_bin_dir(${CMAKE_CURRENT_SOURCE_DIR}/matrices matrices) + +############################################################################### +## target definitions ######################################################### +############################################################################### + +add_executable(compare_matrices compare_matrices.cpp ${GLOB_SOURCES}) +target_link_libraries(compare_matrices gtest_main) + +enable_testing() +add_test(NAME compare_matrices COMMAND compare_matrices) \ No newline at end of file diff --git a/testing/README.md b/testing/README.md new file mode 100644 index 0000000..902178c --- /dev/null +++ b/testing/README.md @@ -0,0 +1,5 @@ +# How to use +- ensure that the target compare_matrices is built with all your tests added +- ensure that ``results`` folder contains all matrices you wish to compare +- go to build/testing +- run ``ctest`` \ No newline at end of file diff --git a/testing/compare_matrices.cpp b/testing/compare_matrices.cpp new file mode 100644 index 0000000..1a456b7 --- /dev/null +++ b/testing/compare_matrices.cpp @@ -0,0 +1,16 @@ +#include "compare_mtx.hpp" + +const double tol = 1e-6; + +// To add a test, use the following syntax (replace mtx filenames, tolerance and test name as needed): +// TEST(MatrixComparison, Simple) { +// std::string path_A = "matrices/simple.mtx"; +// std::string path_B = "matrices/simple_ref.mtx"; + +// test_eq_mtx(path_A, path_B, tol); +// } + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} \ No newline at end of file diff --git a/testing/compare_mtx.hpp b/testing/compare_mtx.hpp new file mode 100644 index 0000000..27928b9 --- /dev/null +++ b/testing/compare_mtx.hpp @@ -0,0 +1,70 @@ +#pragma once +#include +#include +#include +#include + +#include "mm.hpp" + +void sort_rowmaj_coo(SpKernels::cooMat& M) { + // Create a permutation vector + std::vector p(M.ii.size()); + std::iota(p.begin(), p.end(), 0); + + // Sort the permutation vector based on comparing the ii values + std::sort(p.begin(), p.end(), [&](size_t i, size_t j) { + return std::tie(M.ii[i], M.jj[i]) < std::tie(M.ii[j], M.jj[j]); + }); + + // Apply the permutation to ii, jj, and vv + std::vector ii_sorted(M.ii.size()); + std::vector jj_sorted(M.jj.size()); + std::vector vv_sorted(M.vv.size()); + + for (size_t i = 0; i < M.ii.size(); i++) { + ii_sorted[i] = M.ii[p[i]]; + jj_sorted[i] = M.jj[p[i]]; + vv_sorted[i] = M.vv[p[i]]; + } + + M.ii = ii_sorted; + M.jj = jj_sorted; + M.vv = vv_sorted; +} + +void test_eq_mtx(const std::string& path_A, const std::string& path_B, const double tol = 1e-6) { + // Check if mtx files exist + std::ifstream file_A(path_A); + std::ifstream file_B(path_B); + EXPECT_TRUE(file_A.good()); + EXPECT_TRUE(file_B.good()); + + // Read the matrices + SpKernels::mm readerA(path_A); + SpKernels::cooMat A; + SpKernels::mm readerB(path_B); + SpKernels::cooMat B; + + readerA.read_mm(path_A, A); + readerB.read_mm(path_B, B); + + // assert that the matrices have the same dimensions + ASSERT_EQ(A.gncols, B.gncols); + ASSERT_EQ(A.gnrows, B.gnrows); + ASSERT_EQ(A.gnnz, B.gnnz); + + // assert that the last value is non-zero (avoid wrong dimensions in mtx files) + ASSERT_NE(A.vv[A.gnnz - 1], 0.0) << "Last value in A is zero, are dimensions correct in " << path_A << "?"; + ASSERT_NE(B.vv[B.gnnz - 1], 0.0) << "Last value in B is zero, are dimensions correct in " << path_B << "?"; + + // sort the matrices in row-major order + sort_rowmaj_coo(A); + sort_rowmaj_coo(B); + + // compare each triplet + for (size_t i = 0; i < A.gnnz; i++) { + EXPECT_EQ(A.ii[i], B.ii[i]) << "Failed at index i=" << i << " for ii"; + EXPECT_EQ(A.jj[i], B.jj[i]) << "Failed at index i=" << i << " for jj"; + EXPECT_NEAR(A.vv[i], B.vv[i], tol) << "Failed at index i=" << i << " for vv"; + } +} \ No newline at end of file diff --git a/testing/matrices/README.md b/testing/matrices/README.md new file mode 100644 index 0000000..56536a4 --- /dev/null +++ b/testing/matrices/README.md @@ -0,0 +1,2 @@ +Put any results and their reference solution in this folder. +CMake will create a dynamic link to it so it can be found in the build folder after building. \ No newline at end of file diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt new file mode 100644 index 0000000..e67b848 --- /dev/null +++ b/thirdparty/CMakeLists.txt @@ -0,0 +1,2 @@ +# Add all submodules here +add_subdirectory(gtest) \ No newline at end of file diff --git a/thirdparty/gtest b/thirdparty/gtest new file mode 160000 index 0000000..1d17ea1 --- /dev/null +++ b/thirdparty/gtest @@ -0,0 +1 @@ +Subproject commit 1d17ea141d2c11b8917d2c7d029f1c4e2b9769b2 diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..a1b289c --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,5 @@ +############################################################################### +## target definitions ######################################################### +############################################################################### + +add_executable(conv2bin read_convert_mm.cpp) \ No newline at end of file