Add nbnxm kernel benchmark tool
authorBerk Hess <hess@kth.se>
Mon, 17 Jun 2019 07:49:56 +0000 (09:49 +0200)
committerPaul Bauer <paul.bauer.q@gmail.com>
Fri, 13 Sep 2019 10:56:35 +0000 (12:56 +0200)
This change adds a tool for benchmarking nearly all different
flavors of the Nbnxm non-bonded kernels. The tools uses prepared
coordinate input, to minimize the dependencies on the GROMACS
code base. Currently some there are some minor mdlib and ewald
dependencies beyond the Nbnxm dependency.

Also adds basic end-to-end test.

TODO: Make this tool a separate target with minimal dependencies
      on the rest of GROMACS.

Change-Id: Id9b31ccf9f372af873e08c5dd2b97fb8e5df6eef

12 files changed:
src/gromacs/nbnxm/CMakeLists.txt
src/gromacs/nbnxm/benchmark/bench_coords.h [new file with mode: 0644]
src/gromacs/nbnxm/benchmark/bench_setup.cpp [new file with mode: 0644]
src/gromacs/nbnxm/benchmark/bench_setup.h [new file with mode: 0644]
src/gromacs/nbnxm/benchmark/bench_system.cpp [new file with mode: 0644]
src/gromacs/nbnxm/benchmark/bench_system.h [new file with mode: 0644]
src/gromacs/nbnxm/gridset.cpp
src/programs/legacymodules.cpp
src/programs/mdrun/nonbonded_bench.cpp [new file with mode: 0644]
src/programs/mdrun/nonbonded_bench.h [new file with mode: 0644]
src/programs/mdrun/tests/CMakeLists.txt
src/programs/mdrun/tests/nonbonded_bench.cpp [new file with mode: 0644]

index 3c54e102f07ced1a730d92a942b2ac3c16e8cbdc..087c2696a4af2541594d537c23eaae5f9ccb2176 100644 (file)
@@ -32,7 +32,7 @@
 # To help us fund GROMACS development, we humbly ask that you cite
 # the research papers on the package. Check out http://www.gromacs.org.
 
-file(GLOB NBNXM_SOURCES kernels_reference/*.cpp kernels_simd_4xm/*.cpp kernels_simd_2xmm/*.cpp *.cpp)
+file(GLOB NBNXM_SOURCES kernels_reference/*.cpp kernels_simd_4xm/*.cpp kernels_simd_2xmm/*.cpp *.cpp benchmark/*.cpp)
 
 if(GMX_USE_CUDA)
     add_subdirectory(cuda)
diff --git a/src/gromacs/nbnxm/benchmark/bench_coords.h b/src/gromacs/nbnxm/benchmark/bench_coords.h
new file mode 100644 (file)
index 0000000..bf1a16c
--- /dev/null
@@ -0,0 +1,3059 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \internal \file
+ * \brief
+ * This file defines a box with 1000 SPC/E water molecules for use in benchmarks
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \ingroup module_nbnxm
+ */
+
+#include <vector>
+
+#include "gromacs/math/vec.h"
+
+//! A cubic simulation box matching coordinates1000 defined below
+static const matrix box1000 =
+{
+    { 3.107360, 0.0, 0.0 },
+    { 0.0, 3.107360, 0.0 },
+    { 0.0, 0.0, 3.107360 }
+};
+
+//! Coordinates of 1000 SPC/E molecules equilibrated at 300 K, 1 bar, LJ cut-off 1 nm
+static const std::vector<gmx::RVec> coordinates1000 =
+{
+    {  3.058441,  1.962230,  1.989683 },
+    {  2.975840,  1.980085,  1.936221 },
+    {  3.122664,  2.038002,  1.978114 },
+    {  2.511969,  0.591980,  0.611700 },
+    {  2.600885,  0.614626,  0.651463 },
+    {  2.439189,  0.625060,  0.671774 },
+    {  3.037115,  1.103423,  0.510358 },
+    {  3.075596,  1.113280,  0.602129 },
+    {  3.094188,  1.041190,  0.456788 },
+    {  0.625031,  2.325809,  2.735173 },
+    {  0.572419,  2.273776,  2.802438 },
+    {  0.697119,  2.267854,  2.697168 },
+    {  1.631749,  0.888913,  1.089352 },
+    {  1.722932,  0.929772,  1.085316 },
+    {  1.639399,  0.792924,  1.116324 },
+    {  0.135367,  0.404389,  0.014781 },
+    {  0.123013,  0.353549, -0.070440 },
+    {  0.065358,  0.475464,  0.021644 },
+    {  2.133195,  1.942149,  1.063163 },
+    {  2.103670,  1.932198,  1.158185 },
+    {  2.057370,  1.977206,  1.008194 },
+    {  0.974812,  1.273100,  2.779850 },
+    {  0.977014,  1.306597,  2.874047 },
+    {  0.914936,  1.331539,  2.725080 },
+    {  3.039257,  2.275091,  2.297507 },
+    {  3.077036,  2.367559,  2.292780 },
+    {  2.939914,  2.279080,  2.286772 },
+    {  3.066429,  1.655573,  0.946745 },
+    {  2.988511,  1.717413,  0.956967 },
+    {  3.146125,  1.694443,  0.992980 },
+    {  2.402943,  1.159655,  1.041159 },
+    {  2.457788,  1.113902,  0.971169 },
+    {  2.463494,  1.202601,  1.108161 },
+    {  0.198771,  2.872936,  2.409695 },
+    {  0.230047,  2.782781,  2.439593 },
+    {  0.105151,  2.887969,  2.441464 },
+    {  0.368974,  0.573758,  2.697072 },
+    {  0.309036,  0.494602,  2.708979 },
+    {  0.372528,  0.598619,  2.600277 },
+    {  0.780393,  2.245371,  0.386869 },
+    {  0.696219,  2.230132,  0.335076 },
+    {  0.803298,  2.342700,  0.385368 },
+    {  1.288811,  0.315362,  0.649111 },
+    {  1.337870,  0.256502,  0.713366 },
+    {  1.213238,  0.264277,  0.608136 },
+    {  2.939084,  1.486800,  0.541567 },
+    {  2.999762,  1.475771,  0.462849 },
+    {  2.860697,  1.543197,  0.515590 },
+    {  1.700513,  1.987843,  0.690324 },
+    {  1.683709,  2.077665,  0.649708 },
+    {  1.624542,  1.963847,  0.750761 },
+    {  2.002822,  0.880025,  2.162986 },
+    {  1.904598,  0.881033,  2.144248 },
+    {  2.021988,  0.936233,  2.243442 },
+    {  1.419121,  1.568915,  3.023597 },
+    {  1.499351,  1.625145,  3.043628 },
+    {  1.448466,  1.476567,  2.998884 },
+    {  1.659223,  2.063895,  0.003451 },
+    {  1.721702,  2.003487,  0.052920 },
+    {  1.585788,  2.009680, -0.037391 },
+    {  0.932668,  0.985297,  2.066137 },
+    {  0.841309,  1.019847,  2.087582 },
+    {  0.925293,  0.909652,  2.001149 },
+    {  2.544425,  2.069147,  0.358217 },
+    {  2.569305,  2.158265,  0.396151 },
+    {  2.491877,  2.017600,  0.425905 },
+    {  2.643055,  0.627143,  1.977899 },
+    {  2.728804,  0.579992,  1.957311 },
+    {  2.593018,  0.643929,  1.892961 },
+    {  2.525198,  2.511291,  0.851458 },
+    {  2.548718,  2.560892,  0.935043 },
+    {  2.585276,  2.431939,  0.841761 },
+    {  1.593863,  1.272151,  1.144316 },
+    {  1.641930,  1.220443,  1.073494 },
+    {  1.595331,  1.220620,  1.230004 },
+    {  0.241304,  1.026247,  1.527110 },
+    {  0.314388,  1.092000,  1.545424 },
+    {  0.153979,  1.074500,  1.520328 },
+    {  0.670527,  2.411080,  0.740280 },
+    {  0.743415,  2.366956,  0.792629 },
+    {  0.616596,  2.341413,  0.692972 },
+    {  0.506075,  0.784227,  0.136559 },
+    {  0.468598,  0.695519,  0.109607 },
+    {  0.557918,  0.823051,  0.060368 },
+    {  2.820775,  2.815071,  1.889172 },
+    {  2.815770,  2.751934,  1.811786 },
+    {  2.765318,  2.896000,  1.869805 },
+    {  0.987299,  2.128997,  0.524538 },
+    {  1.040313,  2.207735,  0.556000 },
+    {  0.919566,  2.159089,  0.457407 },
+    {  0.229879,  0.835755,  1.940027 },
+    {  0.167288,  0.879689,  2.004464 },
+    {  0.180058,  0.767698,  1.886303 },
+    {  0.378771,  0.998110,  0.493601 },
+    {  0.339751,  0.957631,  0.576299 },
+    {  0.466309,  0.954303,  0.473154 },
+    {  2.123415,  1.896470,  2.510045 },
+    {  2.077036,  1.955502,  2.443983 },
+    {  2.089467,  1.802874,  2.500702 },
+    {  1.588236,  2.328677,  1.511384 },
+    {  1.576339,  2.284743,  1.600425 },
+    {  1.526922,  2.407382,  1.504588 },
+    {  0.580119,  2.671499,  1.778415 },
+    {  0.516760,  2.699374,  1.706245 },
+    {  0.573680,  2.735504,  1.854978 },
+    {  0.236329,  1.658599,  0.482922 },
+    {  0.173161,  1.716011,  0.535014 },
+    {  0.216351,  1.562272,  0.500868 },
+    {  2.866907,  2.172310,  0.976553 },
+    {  2.911961,  2.101637,  0.922006 },
+    {  2.932579,  2.244494,  0.998384 },
+    {  2.765681,  2.315028,  2.427439 },
+    {  2.832893,  2.283105,  2.494248 },
+    {  2.712988,  2.237172,  2.393353 },
+    {  0.705927,  2.118901,  1.945963 },
+    {  0.721405,  2.171561,  1.862373 },
+    {  0.770568,  2.148338,  2.016355 },
+    {  1.781326,  0.167158,  0.154133 },
+    {  1.802628,  0.096981,  0.222114 },
+    {  1.746708,  0.123639,  0.071021 },
+    {  0.126723,  1.501790,  2.733301 },
+    {  0.156993,  1.595659,  2.716802 },
+    {  0.203411,  1.439118,  2.719470 },
+    {  0.870069,  0.129573,  0.216301 },
+    {  0.862810,  0.197557,  0.143326 },
+    {  0.959244,  0.084607,  0.211220 },
+    {  1.070536,  0.743136,  0.182829 },
+    {  1.013762,  0.666505,  0.152757 },
+    {  1.166809,  0.716182,  0.180608 },
+    {  0.440991,  3.021278,  2.594643 },
+    {  0.439645,  3.047789,  2.498230 },
+    {  0.532720,  2.990050,  2.619351 },
+    {  2.742220,  2.873495,  2.785948 },
+    {  2.707374,  2.780469,  2.774456 },
+    {  2.683663,  2.937420,  2.736102 },
+    {  0.713098,  1.865958,  0.712284 },
+    {  0.624328,  1.911507,  0.705575 },
+    {  0.712267,  1.802542,  0.789600 },
+    {  0.314657,  0.447043,  0.721110 },
+    {  0.350251,  0.534830,  0.689071 },
+    {  0.357799,  0.372848,  0.669789 },
+    {  2.969682,  2.658620,  2.862492 },
+    {  2.984106,  2.745657,  2.909572 },
+    {  2.871682,  2.639454,  2.857144 },
+    {  1.198561,  2.913779,  2.614820 },
+    {  1.150109,  2.838385,  2.659182 },
+    {  1.132291,  2.976540,  2.573961 },
+    {  2.641875,  1.268461,  1.491413 },
+    {  2.633864,  1.233835,  1.584884 },
+    {  2.682652,  1.359754,  1.493064 },
+    {  0.568633,  0.009039,  1.190356 },
+    {  0.651953,  0.059866,  1.212135 },
+    {  0.490931,  0.071934,  1.187777 },
+    {  2.645675,  1.030926,  1.996264 },
+    {  2.656484,  1.127034,  2.021689 },
+    {  2.689366,  0.973100,  2.065165 },
+    {  0.077218,  2.967854,  2.133322 },
+    {  0.044197,  3.062070,  2.127588 },
+    {  0.131490,  2.956560,  2.216550 },
+    {  0.408365,  1.237271,  1.580670 },
+    {  0.474287,  1.284063,  1.639532 },
+    {  0.359054,  1.304681,  1.525676 },
+    {  0.226492,  1.945573,  0.076363 },
+    {  0.261322,  1.853437,  0.059106 },
+    {  0.171768,  1.975692, -0.001728 },
+    {  0.468126,  2.450245,  2.524287 },
+    {  0.486194,  2.415823,  2.616421 },
+    {  0.526489,  2.402303,  2.458749 },
+    {  1.434546,  2.964952,  2.504450 },
+    {  1.477884,  3.052850,  2.524343 },
+    {  1.336295,  2.971528,  2.521873 },
+    {  1.464730,  0.522293,  0.985985 },
+    {  1.526258,  0.561016,  0.917320 },
+    {  1.461514,  0.422887,  0.975592 },
+    {  1.630397,  2.791382,  2.590973 },
+    {  1.601935,  2.722126,  2.657257 },
+    {  1.554965,  2.854999,  2.574763 },
+    {  1.972387,  0.963775,  2.902179 },
+    {  2.029530,  1.043059,  2.923363 },
+    {  1.969130,  0.950549,  2.803111 },
+    {  2.337723,  0.321846,  0.882555 },
+    {  2.314325,  0.235026,  0.926315 },
+    {  2.435069,  0.340610,  0.895658 },
+    {  0.734798,  1.529859,  3.053034 },
+    {  0.713380,  1.615060,  3.100805 },
+    {  0.672452,  1.457908,  3.083628 },
+    {  0.032173,  0.527923,  2.239826 },
+    {  0.027814,  0.477786,  2.326239 },
+    { -0.054207,  0.517106,  2.190617 },
+    {  0.022851,  1.802543,  0.630916 },
+    { -0.015108,  1.813262,  0.539024 },
+    { -0.037014,  1.847556,  0.697172 },
+    {  1.010410,  0.509648,  2.039333 },
+    {  1.003466,  0.551298,  2.129981 },
+    {  1.093583,  0.454356,  2.034335 },
+    {  2.898570,  2.091456,  1.807118 },
+    {  2.854734,  2.046376,  1.729360 },
+    {  2.829335,  2.138791,  1.861577 },
+    {  1.961915,  1.375020,  2.801540 },
+    {  1.948970,  1.298617,  2.738333 },
+    {  1.941740,  1.460950,  2.754540 },
+    {  0.290337,  0.199516,  2.503690 },
+    {  0.291054,  0.257287,  2.422069 },
+    {  0.327554,  0.250724,  2.581102 },
+    {  2.077703,  0.143438,  0.468608 },
+    {  2.065651,  0.217401,  0.402395 },
+    {  2.171157,  0.145407,  0.504141 },
+    {  0.990673,  2.712908,  0.856622 },
+    {  0.895723,  2.743789,  0.851057 },
+    {  1.037275,  2.761569,  0.930516 },
+    {  0.078677,  1.380516,  1.009080 },
+    {  0.029933,  1.464352,  1.033485 },
+    {  0.162256,  1.403821,  0.959367 },
+    {  1.836054,  2.642598,  1.704376 },
+    {  1.795981,  2.597778,  1.624468 },
+    {  1.913014,  2.588291,  1.737959 },
+    {  0.257482,  0.992506,  1.247093 },
+    {  0.281524,  1.086213,  1.221773 },
+    {  0.267620,  0.981034,  1.345914 },
+    {  1.986510,  2.050284,  0.848145 },
+    {  1.991489,  2.078718,  0.752402 },
+    {  1.906061,  1.992431,  0.861596 },
+    {  0.384118,  3.016757,  0.633530 },
+    {  0.365374,  2.938621,  0.574004 },
+    {  0.379431,  2.987730,  0.729109 },
+    {  1.061282,  2.803301,  1.113124 },
+    {  1.140678,  2.799514,  1.173803 },
+    {  0.982344,  2.762423,  1.158925 },
+    {  0.893588,  0.623562,  1.159613 },
+    {  0.935464,  0.532797,  1.156770 },
+    {  0.961163,  0.692300,  1.132990 },
+    {  0.064641,  1.597101,  1.338713 },
+    {  0.089583,  1.650727,  1.258077 },
+    {  0.000262,  1.525261,  1.312362 },
+    {  1.744692,  2.999075,  2.729173 },
+    {  1.711603,  2.931172,  2.663642 },
+    {  1.732436,  2.964397,  2.822163 },
+    {  1.010117,  1.010223,  2.690790 },
+    {  1.003234,  1.103514,  2.726136 },
+    {  1.005616,  0.945370,  2.766776 },
+    {  2.119029,  2.091893,  2.142070 },
+    {  2.053933,  2.055051,  2.208442 },
+    {  2.069727,  2.144103,  2.072475 },
+    {  0.476711,  0.278280,  2.980274 },
+    {  0.398589,  0.239525,  2.931336 },
+    {  0.546481,  0.207756,  2.992862 },
+    {  1.017548,  1.173820,  0.262341 },
+    {  0.930974,  1.150575,  0.306663 },
+    {  1.038587,  1.270192,  0.278769 },
+    {  3.006009,  2.653507,  0.115338 },
+    {  3.070976,  2.729519,  0.116520 },
+    {  2.913460,  2.688961,  0.102011 },
+    {  0.321159,  1.479760,  1.402806 },
+    {  0.401871,  1.536967,  1.417403 },
+    {  0.240644,  1.537977,  1.391482 },
+    {  1.629104,  2.275881,  0.958820 },
+    {  1.558865,  2.324456,  1.010849 },
+    {  1.624176,  2.178136,  0.979354 },
+    {  3.066126,  2.858316,  1.644953 },
+    {  3.084059,  2.953924,  1.668140 },
+    {  3.146678,  2.803116,  1.666501 },
+    {  1.051189,  2.076017,  1.920453 },
+    {  1.125807,  2.103292,  1.859722 },
+    {  0.969998,  2.130757,  1.900170 },
+    {  1.516509,  0.100229,  0.350171 },
+    {  1.560545,  0.020237,  0.309401 },
+    {  1.431952,  0.120519,  0.300791 },
+    {  0.493363,  2.189335,  1.269427 },
+    {  0.521529,  2.285282,  1.270284 },
+    {  0.404068,  2.180412,  1.313548 },
+    {  2.807439,  1.983481,  1.563125 },
+    {  2.768178,  2.068799,  1.528782 },
+    {  2.841332,  1.929104,  1.486351 },
+    {  2.853076,  0.830733,  1.400601 },
+    {  2.899426,  0.745984,  1.374732 },
+    {  2.909799,  0.908954,  1.374833 },
+    {  2.959505,  0.005017,  0.423243 },
+    {  2.864585,  0.013417,  0.453569 },
+    {  3.007911,  0.090678,  0.441104 },
+    {  2.807480,  1.919990,  2.908606 },
+    {  2.827273,  1.955044,  2.817067 },
+    {  2.804816,  1.820055,  2.906175 },
+    {  0.082000,  0.549511,  1.184398 },
+    {  0.156887,  0.615066,  1.174679 },
+    {  0.106704,  0.463752,  1.139285 },
+    {  0.629631,  0.003336,  1.945927 },
+    {  0.544066, -0.015054,  1.897548 },
+    {  0.670653,  0.087312,  1.910356 },
+    {  1.183012,  0.907457,  0.474085 },
+    {  1.250390,  0.969782,  0.434387 },
+    {  1.156401,  0.839314,  0.405907 },
+    {  3.032287,  0.465330,  0.292632 },
+    {  3.062801,  0.530277,  0.222984 },
+    {  3.089603,  0.474409,  0.374072 },
+    {  2.243416,  0.013336,  2.312642 },
+    {  2.250096,  0.111913,  2.328068 },
+    {  2.159889, -0.021479,  2.355200 },
+    {  1.164546,  0.173416,  1.168458 },
+    {  1.104884,  0.099010,  1.138385 },
+    {  1.206309,  0.149320,  1.256066 },
+    {  2.607532,  1.124091,  1.724250 },
+    {  2.622452,  1.052768,  1.655763 },
+    {  2.656772,  1.100643,  1.808069 },
+    {  2.551467,  1.338625,  1.208755 },
+    {  2.583643,  1.301105,  1.295686 },
+    {  2.619725,  1.402104,  1.172543 },
+    {  2.136262,  1.322655,  0.114168 },
+    {  2.208042,  1.328919,  0.183511 },
+    {  2.092568,  1.411940,  0.103260 },
+    {  0.941991,  1.920726,  2.868290 },
+    {  0.939600,  1.894556,  2.964776 },
+    {  0.851093,  1.908966,  2.828299 },
+    {  0.004144,  1.775721,  2.412374 },
+    { -0.041340,  1.699791,  2.365836 },
+    { -0.012548,  1.860487,  2.362015 },
+    {  0.867448,  0.363037,  0.498578 },
+    {  0.800322,  0.437082,  0.501957 },
+    {  0.953402,  0.397657,  0.460984 },
+    {  0.890184,  0.676760,  1.539212 },
+    {  0.935641,  0.621324,  1.608930 },
+    {  0.824962,  0.738580,  1.583080 },
+    {  2.539177,  1.282032,  3.012743 },
+    {  2.501141,  1.363299,  2.968595 },
+    {  2.610318,  1.309461,  3.077447 },
+    {  1.604518,  1.894267,  1.505941 },
+    {  1.686555,  1.935396,  1.545670 },
+    {  1.617543,  1.795488,  1.497399 },
+    {  2.913814,  2.506912,  1.298808 },
+    {  2.839748,  2.479654,  1.237398 },
+    {  2.888555,  2.485341,  1.393130 },
+    {  2.479043,  2.811393,  0.464821 },
+    {  2.461245,  2.785192,  0.369970 },
+    {  2.480291,  2.729592,  0.522328 },
+    {  0.000418,  2.908271,  0.684488 },
+    {  0.052322,  2.991863,  0.666647 },
+    {  0.048874,  2.852730,  0.752070 },
+    {  2.420592,  0.017713,  1.710805 },
+    {  2.390744,  0.098744,  1.761235 },
+    {  2.369678,  0.011235,  1.624981 },
+    {  2.926354,  2.206255,  0.118647 },
+    {  3.026107,  2.212509,  0.115431 },
+    {  2.891067,  2.188804,  0.026722 },
+    {  3.083248,  0.397414,  1.498830 },
+    {  3.094998,  0.418032,  1.595973 },
+    {  3.110143,  0.302695,  1.481366 },
+    {  1.151128,  1.570859,  1.066268 },
+    {  1.137265,  1.624490,  0.983012 },
+    {  1.236225,  1.518892,  1.058662 },
+    {  2.100275,  0.308399,  0.082371 },
+    {  2.063669,  0.215716,  0.074010 },
+    {  2.068801,  0.349058,  0.168139 },
+    {  2.089025,  0.726449,  2.710428 },
+    {  2.158632,  0.687899,  2.649858 },
+    {  2.125094,  0.731738,  2.803546 },
+    {  1.069548,  0.219822,  2.643919 },
+    {  1.155804,  0.212609,  2.593841 },
+    {  1.069971,  0.303144,  2.699212 },
+    {  0.215623,  1.771402,  2.733978 },
+    {  0.116525,  1.780547,  2.724178 },
+    {  0.259711,  1.857516,  2.708670 },
+    {  0.076321,  2.814589,  0.017922 },
+    {  0.153935,  2.798606, -0.043074 },
+    { -0.004197,  2.838785, -0.036221 },
+    {  0.827608,  0.266569,  2.523361 },
+    {  0.924521,  0.255060,  2.545165 },
+    {  0.782806,  0.317778,  2.596643 },
+    {  1.774364,  1.200772,  0.922419 },
+    {  1.847724,  1.268283,  0.914643 },
+    {  1.699914,  1.225138,  0.860262 },
+    {  1.843738,  0.863281,  1.426679 },
+    {  1.835180,  0.960574,  1.448143 },
+    {  1.909114,  0.820935,  1.489391 },
+    {  2.190590,  2.093015,  0.489172 },
+    {  2.114286,  2.129196,  0.542731 },
+    {  2.168165,  2.097687,  0.391831 },
+    {  2.856985,  2.708571,  2.421630 },
+    {  2.826059,  2.637500,  2.358445 },
+    {  2.940505,  2.678308,  2.467548 },
+    {  0.701585,  1.132874,  1.532032 },
+    {  0.713505,  1.046958,  1.581796 },
+    {  0.636137,  1.190763,  1.580667 },
+    {  1.112152,  1.761410,  2.730896 },
+    {  1.032952,  1.800466,  2.777823 },
+    {  1.183341,  1.740039,  2.797795 },
+    {  2.362848,  0.400039,  0.467593 },
+    {  2.413963,  0.451503,  0.536431 },
+    {  2.364750,  0.449557,  0.380735 },
+    {  1.923021,  2.539071,  1.210065 },
+    {  2.005782,  2.500150,  1.250510 },
+    {  1.911843,  2.504236,  1.116997 },
+    {  2.843027,  2.693089,  1.659378 },
+    {  2.914984,  2.761898,  1.668726 },
+    {  2.770508,  2.728503,  1.600329 },
+    {  0.128262,  0.810566,  1.667570 },
+    {  0.116881,  0.757626,  1.583499 },
+    {  0.142354,  0.906881,  1.644662 },
+    {  1.002980,  0.859088,  2.952428 },
+    {  0.921072,  0.801826,  2.948964 },
+    {  0.978573,  0.950206,  2.985621 },
+    {  0.665071,  1.176651,  0.745782 },
+    {  0.572750,  1.214473,  0.752595 },
+    {  0.662264,  1.078374,  0.764052 },
+    {  1.604419,  2.998470,  1.830186 },
+    {  1.578196,  3.085323,  1.872245 },
+    {  1.699378,  3.003726,  1.799281 },
+    {  0.766206,  2.635236,  2.266948 },
+    {  0.669570,  2.646575,  2.290034 },
+    {  0.821969,  2.650297,  2.348579 },
+    {  0.413167,  1.864376,  1.358930 },
+    {  0.436077,  1.767159,  1.354041 },
+    {  0.368949,  1.883842,  1.446484 },
+    {  2.520023,  2.005269,  2.712810 },
+    {  2.491840,  2.040054,  2.802229 },
+    {  2.615839,  2.028833,  2.696563 },
+    {  0.653971,  0.523083,  2.191540 },
+    {  0.655081,  0.426122,  2.215980 },
+    {  0.648901,  0.532338,  2.092098 },
+    {  2.064821,  2.995576,  1.899338 },
+    {  2.000715,  2.961996,  1.968351 },
+    {  2.148348,  3.027455,  1.944135 },
+    {  0.974837,  3.040805,  0.756885 },
+    {  0.947137,  2.957808,  0.708467 },
+    {  0.934946,  3.120620,  0.711736 },
+    {  2.444642,  2.518796,  2.408258 },
+    {  2.440402,  2.457240,  2.486953 },
+    {  2.370887,  2.586034,  2.414519 },
+    {  2.321767,  1.107241,  2.328455 },
+    {  2.385756,  1.168742,  2.374533 },
+    {  2.229778,  1.121331,  2.365052 },
+    {  1.605816,  0.704012,  0.201441 },
+    {  1.679042,  0.692486,  0.134321 },
+    {  1.642942,  0.745578,  0.284471 },
+    {  1.552828,  1.036090,  1.319262 },
+    {  1.570254,  0.975950,  1.241290 },
+    {  1.462357,  1.016354,  1.357017 },
+    {  3.106174,  0.095841,  1.468391 },
+    {  3.169836,  0.054846,  1.403072 },
+    {  3.016178,  0.105234,  1.425817 },
+    {  1.471106,  2.572710,  1.544631 },
+    {  1.503995,  2.624378,  1.465582 },
+    {  1.425647,  2.634814,  1.608479 },
+    {  2.479549,  1.837065,  1.139527 },
+    {  2.433902,  1.811477,  1.224742 },
+    {  2.578245,  1.842147,  1.154804 },
+    {  2.285594,  0.997748,  2.811664 },
+    {  2.337996,  0.950786,  2.882718 },
+    {  2.230949,  1.070507,  2.853138 },
+    {  2.069438,  2.790248,  2.236690 },
+    {  2.128149,  2.745234,  2.169408 },
+    {  2.071366,  2.738737,  2.322380 },
+    {  2.405399,  0.905125,  1.347911 },
+    {  2.447368,  0.898610,  1.438443 },
+    {  2.346844,  0.986097,  1.344063 },
+    {  2.196427,  0.438752,  2.136470 },
+    {  2.192188,  0.376343,  2.214491 },
+    {  2.290922,  0.445799,  2.104517 },
+    {  2.889807,  0.531760,  1.366584 },
+    {  2.900943,  0.497848,  1.273171 },
+    {  2.958704,  0.489830,  1.425704 },
+    {  1.841082,  3.042295,  1.732903 },
+    {  1.861475,  3.126049,  1.682215 },
+    {  1.919077,  3.018546,  1.790806 },
+    {  1.326290,  2.104904,  0.154356 },
+    {  1.358661,  2.045197,  0.080959 },
+    {  1.312102,  2.050989,  0.237373 },
+    {  3.049543,  1.131760,  2.722415 },
+    {  2.996461,  1.169327,  2.646448 },
+    {  3.132666,  1.088896,  2.687015 },
+    {  1.908184,  0.043121,  0.967115 },
+    {  1.972116,  0.062905,  1.041420 },
+    {  1.957530,  0.041801,  0.880148 },
+    {  2.401901,  0.513585,  1.491280 },
+    {  2.427890,  0.425841,  1.450961 },
+    {  2.344707,  0.564272,  1.426784 },
+    {  2.448317,  1.127002,  0.327588 },
+    {  2.418437,  1.074801,  0.407477 },
+    {  2.405026,  1.217141,  0.328569 },
+    {  0.576997,  2.600784,  2.855002 },
+    {  0.517158,  2.664093,  2.805898 },
+    {  0.581336,  2.513933,  2.805624 },
+    {  2.875255,  1.238762,  1.338781 },
+    {  2.892585,  1.147209,  1.302481 },
+    {  2.795469,  1.236189,  1.399010 },
+    {  1.623443,  1.734577,  3.063192 },
+    {  1.708509,  1.682883,  3.053623 },
+    {  1.635767,  1.806728,  3.131327 },
+    {  2.710919,  0.916881,  2.856473 },
+    {  2.766298,  0.905953,  2.773928 },
+    {  2.730606,  1.005542,  2.898326 },
+    {  0.413553,  0.398427,  1.586956 },
+    {  0.433660,  0.488295,  1.547974 },
+    {  0.453389,  0.327300,  1.529042 },
+    {  1.497303,  1.793333,  2.176276 },
+    {  1.451349,  1.745062,  2.250829 },
+    {  1.487507,  1.740990,  2.091634 },
+    {  1.518297,  0.712931,  1.713533 },
+    {  1.511776,  0.670016,  1.803621 },
+    {  1.431340,  0.702497,  1.665266 },
+    {  1.551914,  1.629915,  1.465708 },
+    {  1.627901,  1.578363,  1.505312 },
+    {  1.466468,  1.602561,  1.509874 },
+    {  0.817285,  0.341999,  1.337646 },
+    {  0.812267,  0.250486,  1.297643 },
+    {  0.849200,  0.406874,  1.268563 },
+    {  0.483208,  1.585241,  2.340546 },
+    {  0.455791,  1.506492,  2.285348 },
+    {  0.401919,  1.636533,  2.368138 },
+    {  0.072505,  1.709287,  2.006497 },
+    {  0.160460,  1.755185,  1.993951 },
+    { -0.001476,  1.775956,  1.997443 },
+    {  2.582320,  0.685754,  2.244482 },
+    {  2.650091,  0.637094,  2.299612 },
+    {  2.587629,  0.654280,  2.149712 },
+    {  1.501209,  2.306496,  0.101764 },
+    {  1.573483,  2.238069,  0.092060 },
+    {  1.424723,  2.267188,  0.152802 },
+    {  2.481658,  1.039356,  2.585797 },
+    {  2.460124,  0.963544,  2.524242 },
+    {  2.416564,  1.040181,  2.661705 },
+    {  0.007444,  0.131285,  3.075162 },
+    {  0.021151,  0.050319,  3.132229 },
+    { -0.077919,  0.121895,  3.023929 },
+    {  2.384391,  2.087250,  2.954037 },
+    {  2.285605,  2.102203,  2.958238 },
+    {  2.419802,  2.072319,  3.046358 },
+    {  2.522700,  1.616950,  0.785956 },
+    {  2.585893,  1.539614,  0.791042 },
+    {  2.445543,  1.593127,  0.726971 },
+    {  0.874549,  0.343416,  0.840602 },
+    {  0.833294,  0.425210,  0.800506 },
+    {  0.845368,  0.262750,  0.789208 },
+    {  1.590202,  0.346154,  1.432877 },
+    {  1.615997,  0.442727,  1.435750 },
+    {  1.615345,  0.302353,  1.519186 },
+    {  0.200720,  2.166011,  1.669131 },
+    {  0.203419,  2.079517,  1.619016 },
+    {  0.270766,  2.165386,  1.740497 },
+    {  2.718568,  1.424756,  0.815413 },
+    {  2.672368,  1.357349,  0.757778 },
+    {  2.816407,  1.424830,  0.794736 },
+    {  0.046991,  1.844195,  1.458743 },
+    {  0.084611,  1.875306,  1.546017 },
+    {  0.077274,  1.750582,  1.440864 },
+    {  2.572122,  0.480250,  0.179410 },
+    {  2.648033,  0.542352,  0.159896 },
+    {  2.607804,  0.388536,  0.197167 },
+    {  2.983852,  2.126827,  0.529426 },
+    {  2.919768,  2.105563,  0.455662 },
+    {  3.074677,  2.143297,  0.490962 },
+    {  2.481990,  1.585232,  2.950477 },
+    {  2.481605,  1.594815,  2.850938 },
+    {  2.550736,  1.646421,  2.989590 },
+    {  1.937349,  2.315709,  2.488461 },
+    {  1.866975,  2.245603,  2.476944 },
+    {  1.894483,  2.401770,  2.515955 },
+    {  2.198232,  2.608651,  1.779312 },
+    {  2.176557,  2.685274,  1.718822 },
+    {  2.121877,  2.544080,  1.779987 },
+    {  2.767491,  1.663955,  0.469798 },
+    {  2.721891,  1.697642,  0.552174 },
+    {  2.698811,  1.638682,  0.401649 },
+    {  0.406640,  1.422145,  1.928232 },
+    {  0.397242,  1.448410,  2.024263 },
+    {  0.347679,  1.343646,  1.909219 },
+    {  1.896401,  2.791342,  1.136750 },
+    {  1.924382,  2.698789,  1.162263 },
+    {  1.819455,  2.786541,  1.073062 },
+    {  1.769318,  1.881876,  2.175327 },
+    {  1.682986,  1.831440,  2.177071 },
+    {  1.835406,  1.832880,  2.118478 },
+    {  2.282848,  0.667216,  1.278688 },
+    {  2.328695,  0.755760,  1.286297 },
+    {  2.184749,  0.681493,  1.265545 },
+    {  0.082448,  2.196028,  2.545991 },
+    {  0.127614,  2.276112,  2.506664 },
+    {  0.023481,  2.153839,  2.477121 },
+    {  1.173007,  2.545388,  1.465317 },
+    {  1.261847,  2.555552,  1.510086 },
+    {  1.100823,  2.576852,  1.526958 },
+    {  0.971281,  0.476352,  1.707317 },
+    {  0.987809,  0.486035,  1.805465 },
+    {  1.034678,  0.408994,  1.669323 },
+    {  1.729149,  0.592677,  2.083464 },
+    {  1.809754,  0.606881,  2.026009 },
+    {  1.710765,  0.494708,  2.091470 },
+    {  0.139730,  0.213097,  1.878174 },
+    {  0.232551,  0.235783,  1.848687 },
+    {  0.142086,  0.178372,  1.971921 },
+    {  3.067644,  0.529023,  2.833107 },
+    {  3.055445,  0.610258,  2.890134 },
+    {  2.990385,  0.466966,  2.846527 },
+    {  1.629882,  2.760517,  1.057234 },
+    {  1.570178,  2.835637,  1.085385 },
+    {  1.576395,  2.676331,  1.050029 },
+    {  0.046460,  2.403684,  1.395527 },
+    {  0.000167,  2.351222,  1.466974 },
+    { -0.017278,  2.469978,  1.356251 },
+    {  0.979941,  2.502884,  1.685655 },
+    {  0.890348,  2.484811,  1.726232 },
+    {  1.050479,  2.455007,  1.737925 },
+    {  0.380089,  0.272073,  1.817507 },
+    {  0.405127,  0.180000,  1.787580 },
+    {  0.383922,  0.334644,  1.739596 },
+    {  1.475603,  1.663110,  1.902010 },
+    {  1.562825,  1.673352,  1.854183 },
+    {  1.453838,  1.565942,  1.911209 },
+    {  1.235365,  1.009114,  1.796560 },
+    {  1.195125,  0.917615,  1.799501 },
+    {  1.169665,  1.075583,  1.832132 },
+    {  3.102696,  0.787487,  2.857110 },
+    {  3.043825,  0.822299,  2.784156 },
+    {  3.198383,  0.805056,  2.833971 },
+    {  2.096222,  2.284527,  2.693411 },
+    {  2.058902,  2.270396,  2.601719 },
+    {  2.088818,  2.381204,  2.717880 },
+    {  2.356806,  0.691401,  2.545193 },
+    {  2.386469,  0.605803,  2.502849 },
+    {  2.396691,  0.768628,  2.495743 },
+    {  1.891409,  0.166304,  1.584899 },
+    {  1.959147,  0.204771,  1.522195 },
+    {  1.859632,  0.237563,  1.647447 },
+    {  2.518043,  2.459156,  3.101591 },
+    {  2.428358,  2.472460,  3.059407 },
+    {  2.508114,  2.457102,  3.201075 },
+    {  0.320428,  1.244524,  0.006551 },
+    {  0.286081,  1.304244,  0.079034 },
+    {  0.246629,  1.224461, -0.057879 },
+    {  2.048229,  0.089071,  0.726703 },
+    {  2.014095,  0.080462,  0.633104 },
+    {  2.088850,  0.179593,  0.739177 },
+    {  2.034245,  2.982632,  1.329181 },
+    {  2.031245,  2.911409,  1.259050 },
+    {  1.953036,  2.975792,  1.387133 },
+    {  0.538485,  2.084337,  1.023997 },
+    {  0.627754,  2.089723,  0.979252 },
+    {  0.548110,  2.108365,  1.120589 },
+    {  2.212275,  0.056864,  2.952055 },
+    {  2.213052,  0.078465,  2.854419 },
+    {  2.274182,  0.118766,  3.000384 },
+    {  1.700132,  0.240342,  0.949202 },
+    {  1.694106,  0.245036,  1.048910 },
+    {  1.789110,  0.203045,  0.922903 },
+    {  1.557351,  1.014863,  0.118569 },
+    {  1.498333,  0.953216,  0.066447 },
+    {  1.652146,  1.003249,  0.088924 },
+    {  1.370467,  1.107947,  0.345641 },
+    {  1.433625,  1.162976,  0.400256 },
+    {  1.402511,  1.104544,  0.250976 },
+    {  0.051230,  0.959064,  0.306681 },
+    {  0.137569,  0.966428,  0.256769 },
+    { -0.023371,  0.993105,  0.249444 },
+    {  1.061472,  0.435716,  0.312109 },
+    {  1.001351,  0.476028,  0.243114 },
+    {  1.147227,  0.407409,  0.269158 },
+    {  1.159078,  1.784237,  1.666312 },
+    {  1.243340,  1.831701,  1.691750 },
+    {  1.103225,  1.769421,  1.747927 },
+    {  2.346733,  2.132205,  2.314271 },
+    {  2.250042,  2.143686,  2.291489 },
+    {  2.363438,  2.166195,  2.406822 },
+    {  1.831914,  0.624811,  2.621164 },
+    {  1.918548,  0.648796,  2.664973 },
+    {  1.841155,  0.633610,  2.521981 },
+    {  2.313396,  0.217101,  1.823930 },
+    {  2.375730,  0.273528,  1.878065 },
+    {  2.246887,  0.275793,  1.777758 },
+    {  0.682445,  0.914361,  0.800937 },
+    {  0.644296,  0.833146,  0.845083 },
+    {  0.733038,  0.887148,  0.719084 },
+    {  1.290598,  2.697603,  1.716289 },
+    {  1.300953,  2.723287,  1.812378 },
+    {  1.220298,  2.754714,  1.673908 },
+    {  2.699916,  0.577677,  1.036050 },
+    {  2.781543,  0.527541,  1.064746 },
+    {  2.676811,  0.646124,  1.105196 },
+    {  2.379672,  1.923759,  2.151954 },
+    {  2.363378,  2.011183,  2.197688 },
+    {  2.414151,  1.940385,  2.059570 },
+    {  2.918502,  2.910934,  1.384671 },
+    {  2.835120,  2.891595,  1.436376 },
+    {  2.996449,  2.914455,  1.447216 },
+    {  3.076292,  0.830083,  0.821021 },
+    {  3.048771,  0.918554,  0.858645 },
+    {  3.145879,  0.844013,  0.750568 },
+    {  0.218858,  2.069650,  1.317117 },
+    {  0.146551,  2.023580,  1.368588 },
+    {  0.283616,  2.001745,  1.282544 },
+    {  0.020619,  0.874374,  2.443902 },
+    { -0.012722,  0.782671,  2.465787 },
+    {  0.091966,  0.900318,  2.508991 },
+    {  2.521324,  1.753594,  2.320911 },
+    {  2.464712,  1.785120,  2.244745 },
+    {  2.490042,  1.796457,  2.405670 },
+    {  2.057530,  3.102252,  2.695123 },
+    {  1.972974,  3.145551,  2.726356 },
+    {  2.053180,  3.088109,  2.596224 },
+    {  2.032116,  0.595488,  1.461278 },
+    {  2.063105,  0.673032,  1.516293 },
+    {  2.016531,  0.625497,  1.367169 },
+    {  1.491030,  0.686757,  2.193506 },
+    {  1.571887,  0.657781,  2.142296 },
+    {  1.456372,  0.772463,  2.155382 },
+    {  1.455156,  0.193460,  2.956994 },
+    {  1.455369,  0.291350,  2.977428 },
+    {  1.407622,  0.177574,  2.870460 },
+    {  3.024817,  1.123669,  2.374621 },
+    {  3.033344,  1.024199,  2.380361 },
+    {  2.959151,  1.155498,  2.442993 },
+    {  2.168128,  2.952341,  0.763788 },
+    {  2.136058,  3.040271,  0.728577 },
+    {  2.161865,  2.883290,  0.691728 },
+    {  0.030132,  2.537830,  0.817716 },
+    {  0.028067,  2.528831,  0.718143 },
+    { -0.043010,  2.599343,  0.847151 },
+    {  1.305384,  0.363666,  0.213584 },
+    {  1.332245,  0.277124,  0.171289 },
+    {  1.357434,  0.377131,  0.297902 },
+    {  2.632164,  0.136342,  0.656899 },
+    {  2.641994,  0.192049,  0.574437 },
+    {  2.718966,  0.090940,  0.677000 },
+    {  0.466417,  1.949597,  0.605141 },
+    {  0.461019,  1.914586,  0.511626 },
+    {  0.392703,  1.909972,  0.659877 },
+    {  0.398048,  0.367850,  2.287718 },
+    {  0.479261,  0.318780,  2.319286 },
+    {  0.398678,  0.460705,  2.324835 },
+    {  1.741551,  1.439929,  1.553944 },
+    {  1.803090,  1.434375,  1.475318 },
+    {  1.675412,  1.365036,  1.549864 },
+    {  1.050770,  2.232698,  1.500930 },
+    {  1.090450,  2.316498,  1.538386 },
+    {  1.118122,  2.186993,  1.442837 },
+    {  1.717596,  2.258860,  0.597207 },
+    {  1.699232,  2.267105,  0.499254 },
+    {  1.691849,  2.343831,  0.643217 },
+    {  2.212399,  2.773996,  0.555699 },
+    {  2.267986,  2.695320,  0.582536 },
+    {  2.270206,  2.841640,  0.510064 },
+    {  0.833825,  0.137371,  0.654410 },
+    {  0.765034,  0.067362,  0.635268 },
+    {  0.827607,  0.209855,  0.585798 },
+    {  1.484024,  2.431415,  1.172574 },
+    {  1.387432,  2.405719,  1.169462 },
+    {  1.492573,  2.524800,  1.207303 },
+    {  1.092009,  1.304918,  0.645060 },
+    {  1.037350,  1.229798,  0.608053 },
+    {  1.147515,  1.271401,  0.721189 },
+    {  2.926792,  1.120965,  0.145719 },
+    {  2.857706,  1.056880,  0.179192 },
+    {  2.991043,  1.072650,  0.086242 },
+    {  0.854119,  2.974997,  1.408124 },
+    {  0.869941,  2.893842,  1.351878 },
+    {  0.813268,  2.947735,  1.495233 },
+    {  0.395941,  1.628557,  1.722443 },
+    {  0.405298,  1.574434,  1.806008 },
+    {  0.467522,  1.602497,  1.657659 },
+    {  0.691627,  3.086008,  2.208135 },
+    {  0.612388,  3.045434,  2.253686 },
+    {  0.675996,  3.087823,  2.109380 },
+    {  1.902204,  2.035316,  0.346277 },
+    {  1.910733,  2.004423,  0.441003 },
+    {  1.831359,  2.105646,  0.340402 },
+    {  1.645593,  0.569489,  3.018336 },
+    {  1.729209,  0.620777,  3.037777 },
+    {  1.619165,  0.516928,  3.099199 },
+    {  2.037092,  0.324540,  1.440475 },
+    {  2.007342,  0.418695,  1.456280 },
+    {  2.112294,  0.323963,  1.374562 },
+    {  1.709332,  0.025492,  1.460518 },
+    {  1.782128,  0.081685,  1.499798 },
+    {  1.731019, -0.071218,  1.473815 },
+    {  1.822994,  1.386993,  1.285320 },
+    {  1.852887,  1.448187,  1.212095 },
+    {  1.740161,  1.338800,  1.256753 },
+    {  2.640290,  2.907177,  2.258028 },
+    {  2.588012,  2.895568,  2.173575 },
+    {  2.737965,  2.909498,  2.236716 },
+    {  2.830221,  1.201105,  2.554194 },
+    {  2.789919,  1.238195,  2.470528 },
+    {  2.775225,  1.229030,  2.632907 },
+    {  0.312595,  1.269209,  1.183354 },
+    {  0.399686,  1.257023,  1.230964 },
+    {  0.276338,  1.360314,  1.202979 },
+    {  1.219074,  1.304704,  1.406725 },
+    {  1.187584,  1.394406,  1.437740 },
+    {  1.171917,  1.233162,  1.458280 },
+    {  0.088165,  1.132162,  2.948754 },
+    {  0.041748,  1.067558,  3.009349 },
+    {  0.029670,  1.152032,  2.870119 },
+    {  2.146272,  1.433617,  2.390542 },
+    {  2.138419,  1.336790,  2.414267 },
+    {  2.230608,  1.448556,  2.338924 },
+    {  1.126390,  2.619047,  0.229842 },
+    {  1.067299,  2.650958,  0.155748 },
+    {  1.172580,  2.697254,  0.271677 },
+    {  0.772610,  0.713337,  2.611108 },
+    {  0.748713,  0.722431,  2.514432 },
+    {  0.849110,  0.774120,  2.632397 },
+    {  2.447981,  2.453893,  0.248781 },
+    {  2.367628,  2.396337,  0.233596 },
+    {  2.503037,  2.415403,  0.322858 },
+    {  0.263845,  2.493355,  0.144281 },
+    {  0.335474,  2.526864,  0.083072 },
+    {  0.263751,  2.547567,  0.228310 },
+    {  2.711082,  1.281642,  2.333081 },
+    {  2.719674,  1.381229,  2.336037 },
+    {  2.715094,  1.250643,  2.238091 },
+    {  2.676279,  0.650773,  2.902170 },
+    {  2.580775,  0.630422,  2.880608 },
+    {  2.692490,  0.748955,  2.892301 },
+    {  2.877642,  0.476823,  2.154497 },
+    {  2.817917,  0.409468,  2.110950 },
+    {  2.850465,  0.488665,  2.250002 },
+    {  1.876275,  1.779603,  0.923386 },
+    {  1.813814,  1.729332,  0.863624 },
+    {  1.843092,  1.775125,  1.017613 },
+    {  1.999578,  2.412161,  1.792502 },
+    {  2.001027,  2.333447,  1.854162 },
+    {  1.945209,  2.390079,  1.711530 },
+    {  1.345610,  0.547217,  1.984605 },
+    {  1.382190,  0.579678,  2.071830 },
+    {  1.346384,  0.447229,  1.983274 },
+    {  0.367515,  3.057362,  1.507738 },
+    {  0.302379,  3.058892,  1.431877 },
+    {  0.427117,  3.137462,  1.502119 },
+    {  3.011322,  0.923958,  3.084858 },
+    {  3.042668,  0.880246,  3.000557 },
+    {  2.945836,  0.864150,  3.131061 },
+    {  2.392270,  1.829070,  2.562705 },
+    {  2.428474,  1.901010,  2.621983 },
+    {  2.295803,  1.847105,  2.543500 },
+    {  1.842649,  0.637906,  1.017004 },
+    {  1.801396,  0.602764,  0.932961 },
+    {  1.785666,  0.612644,  1.095201 },
+    {  0.617497,  0.921076,  3.039116 },
+    {  0.658644,  0.998296,  3.087530 },
+    {  0.598462,  0.947354,  2.944527 },
+    {  3.000423,  0.591953,  0.667713 },
+    {  3.020428,  0.676659,  0.716955 },
+    {  3.082706,  0.560794,  0.620188 },
+    {  1.169441,  1.042230,  2.178946 },
+    {  1.245754,  0.989978,  2.140921 },
+    {  1.083286,  1.006290,  2.143090 },
+    {  2.036610,  2.690183,  0.260508 },
+    {  2.009603,  2.593929,  0.262906 },
+    {  2.055502,  2.721831,  0.353467 },
+    {  0.678618,  0.253853,  2.315954 },
+    {  0.675382,  0.155406,  2.298699 },
+    {  0.739093,  0.272140,  2.393467 },
+    {  1.005798,  2.653579,  3.072247 },
+    {  0.962132,  2.738055,  3.041310 },
+    {  1.102456,  2.654701,  3.046633 },
+    {  1.212983,  0.709212,  2.939614 },
+    {  1.130614,  0.765585,  2.945729 },
+    {  1.252068,  0.717137,  2.847911 },
+    {  1.489914,  2.604836,  0.398980 },
+    {  1.495513,  2.508495,  0.372768 },
+    {  1.561823,  2.625570,  0.465306 },
+    {  0.270020,  3.000161,  0.139979 },
+    {  0.272046,  2.929216,  0.069533 },
+    {  0.175190,  3.025624,  0.158928 },
+    {  0.116325,  2.146527,  0.405128 },
+    {  0.197633,  2.090927,  0.387876 },
+    {  0.062843,  2.154374,  0.320996 },
+    {  2.194390,  2.363083,  1.040172 },
+    {  2.203799,  2.458153,  1.069720 },
+    {  2.099466,  2.333825,  1.051723 },
+    {  2.614382,  2.672006,  2.545183 },
+    {  2.702055,  2.682635,  2.498273 },
+    {  2.547538,  2.632268,  2.482312 },
+    {  1.172490,  1.978854,  0.953816 },
+    {  1.153736,  1.956987,  0.858056 },
+    {  1.208445,  1.897823,  1.000089 },
+    {  0.312017,  1.290869,  2.693676 },
+    {  0.400078,  1.306245,  2.738496 },
+    {  0.308832,  1.197685,  2.657527 },
+    {  1.098510,  0.153188,  0.479180 },
+    {  1.082395,  0.060457,  0.445397 },
+    {  1.013706,  0.205890,  0.473643 },
+    {  1.784232,  1.875739,  2.847711 },
+    {  1.880468,  1.867252,  2.821892 },
+    {  1.756731,  1.795507,  2.900688 },
+    {  0.350440,  0.678473,  0.534561 },
+    {  0.304420,  0.661506,  0.447417 },
+    {  0.444709,  0.645498,  0.529451 },
+    {  1.169279,  2.747161,  2.285225 },
+    {  1.268213,  2.761560,  2.283046 },
+    {  1.142212,  2.689916,  2.207827 },
+    {  0.570823,  2.828304,  0.432263 },
+    {  0.477361,  2.806398,  0.460280 },
+    {  0.630151,  2.749729,  0.449758 },
+    {  2.444623,  1.342698,  1.778805 },
+    {  2.396114,  1.374737,  1.697438 },
+    {  2.502313,  1.264669,  1.754654 },
+    {  1.238327,  1.673449,  0.435189 },
+    {  1.219243,  1.771146,  0.425637 },
+    {  1.289703,  1.641577,  0.355536 },
+    {  0.153594,  2.293098,  1.181422 },
+    {  0.090310,  2.342888,  1.240718 },
+    {  0.168866,  2.201468,  1.218445 },
+    {  0.632666,  0.899307,  0.356243 },
+    {  0.723101,  0.856637,  0.355391 },
+    {  0.581983,  0.871642,  0.274598 },
+    {  1.171387,  1.540110,  0.022861 },
+    {  1.256436,  1.556098, -0.027249 },
+    {  1.158655,  1.612352,  0.090824 },
+    {  1.775234,  2.639426,  1.417896 },
+    {  1.845711,  2.597737,  1.360493 },
+    {  1.690109,  2.646981,  1.365967 },
+    {  2.286208,  0.014645,  1.462383 },
+    {  2.206073,  0.018088,  1.402662 },
+    {  2.347516,  0.090501,  1.440309 },
+    {  1.855339,  2.566208,  2.578398 },
+    {  1.790876,  2.631256,  2.618564 },
+    {  1.937501,  2.561317,  2.635191 },
+    {  1.365327,  2.886261,  0.999166 },
+    {  1.387151,  2.932093,  1.085324 },
+    {  1.306889,  2.945537,  0.943747 },
+    {  1.928061,  0.624805,  1.853047 },
+    {  2.014539,  0.628321,  1.903139 },
+    {  1.890842,  0.717205,  1.844269 },
+    {  1.819535,  1.163727,  2.634753 },
+    {  1.795091,  1.160180,  2.731654 },
+    {  1.776597,  1.087246,  2.586722 },
+    {  0.437791,  0.196657,  0.571311 },
+    {  0.395955,  0.125509,  0.627771 },
+    {  0.517613,  0.159163,  0.524167 },
+    {  0.990439,  3.084440,  1.049646 },
+    {  0.979541,  3.092549,  0.950573 },
+    {  0.982817,  2.988350,  1.076266 },
+    {  0.135630,  1.424594,  2.366009 },
+    {  0.186875,  1.452547,  2.447204 },
+    {  0.038302,  1.419049,  2.388291 },
+    {  0.774298,  0.700782,  3.014136 },
+    {  0.720206,  0.631836,  2.965965 },
+    {  0.718205,  0.782026,  3.030041 },
+    {  0.336274,  0.174819,  1.183050 },
+    {  0.314277,  0.220780,  1.097005 },
+    {  0.375410,  0.240907,  1.247087 },
+    {  2.624106,  1.198353,  2.749908 },
+    {  2.560306,  1.194010,  2.826790 },
+    {  2.597145,  1.131696,  2.680410 },
+    {  1.093957,  0.845871,  2.479553 },
+    {  1.188103,  0.816901,  2.462315 },
+    {  1.093910,  0.922684,  2.543582 },
+    {  1.144358,  2.465872,  2.785667 },
+    {  1.125932,  2.423311,  2.697072 },
+    {  1.162905,  2.394834,  2.853561 },
+    {  0.649380,  2.048907,  1.653051 },
+    {  0.724093,  2.114135,  1.665825 },
+    {  0.641274,  2.026088,  1.556027 },
+    {  2.643681,  3.013983,  1.808290 },
+    {  2.566518,  3.046667,  1.753722 },
+    {  2.715972,  3.083077,  1.808537 },
+    {  1.812965,  0.376719,  1.762352 },
+    {  1.801808,  0.339809,  1.854619 },
+    {  1.843189,  0.471878,  1.767946 },
+    {  0.234547,  1.903456,  0.762488 },
+    {  0.157170,  1.852394,  0.724997 },
+    {  0.206290,  1.997433,  0.781722 },
+    {  1.299412,  0.664482,  1.563116 },
+    {  1.311728,  0.569449,  1.534531 },
+    {  1.233073,  0.709042,  1.503004 },
+    {  0.471100,  2.414620,  0.417294 },
+    {  0.391412,  2.471872,  0.436584 },
+    {  0.481394,  2.346350,  0.489635 },
+    {  1.105199,  0.810713,  1.415766 },
+    {  1.028862,  0.771144,  1.466826 },
+    {  1.075099,  0.833553,  1.323179 },
+    {  0.357194,  1.129205,  2.166708 },
+    {  0.381063,  1.108356,  2.071863 },
+    {  0.258268,  1.120957,  2.178772 },
+    {  2.141714,  2.142842,  1.486301 },
+    {  2.214417,  2.177650,  1.427118 },
+    {  2.173165,  2.142784,  1.581227 },
+    {  1.702656,  2.224459,  0.331437 },
+    {  1.603028,  2.232063,  0.335497 },
+    {  1.732962,  2.233784,  0.236598 },
+    {  1.658323,  0.033785,  3.067776 },
+    {  1.664949, -0.057469,  3.027418 },
+    {  1.645833,  0.101485,  2.995245 },
+    {  1.569246,  2.399663,  2.180838 },
+    {  1.632507,  2.472664,  2.206702 },
+    {  1.618676,  2.312866,  2.176035 },
+    {  1.419905,  1.952344,  3.057437 },
+    {  1.445836,  1.856069,  3.049776 },
+    {  1.336568,  1.968723,  3.004648 },
+    {  0.928720,  2.693943,  2.063425 },
+    {  1.010503,  2.637688,  2.075549 },
+    {  0.868058,  2.681946,  2.142014 },
+    {  1.634044,  1.676942,  0.314676 },
+    {  1.598932,  1.702735,  0.404686 },
+    {  1.693576,  1.597106,  0.323743 },
+    {  0.830401,  2.033807,  0.958468 },
+    {  0.877584,  2.009187,  0.873806 },
+    {  0.842339,  1.960779,  1.025731 },
+    {  1.967128,  2.547359,  2.082619 },
+    {  1.876900,  2.575384,  2.115383 },
+    {  1.998137,  2.610913,  2.011912 },
+    {  1.914760,  2.240130,  2.014567 },
+    {  1.821780,  2.210964,  2.037023 },
+    {  1.919160,  2.340032,  2.014097 },
+    {  1.204308,  0.740440,  1.830255 },
+    {  1.256133,  0.732237,  1.745127 },
+    {  1.232956,  0.668707,  1.893766 },
+    {  2.380670,  2.109764,  1.022198 },
+    {  2.326708,  2.025893,  1.029529 },
+    {  2.321764,  2.184785,  0.992169 },
+    {  2.366020,  1.001282,  0.597718 },
+    {  2.285764,  1.010658,  0.656634 },
+    {  2.447119,  0.985657,  0.654100 },
+    {  0.691093,  0.752276,  2.340281 },
+    {  0.672345,  0.665438,  2.294371 },
+    {  0.638224,  0.825117,  2.296702 },
+    {  0.414470,  0.458922,  2.024676 },
+    {  0.426859,  0.408179,  1.939402 },
+    {  0.398400,  0.394716,  2.099639 },
+    {  0.167761,  2.702213,  0.308317 },
+    {  0.164799,  2.726732,  0.211415 },
+    {  0.075331,  2.705407,  0.346351 },
+    {  1.577121,  1.524739,  1.021991 },
+    {  1.589557,  1.439621,  1.072984 },
+    {  1.597070,  1.602521,  1.081588 },
+    {  1.464515,  1.174865,  1.762501 },
+    {  1.478245,  1.202376,  1.667345 },
+    {  1.399154,  1.099275,  1.766248 },
+    {  2.156436,  2.877467,  1.024294 },
+    {  2.161692,  2.918408,  0.933211 },
+    {  2.067570,  2.833082,  1.035814 },
+    {  2.271721,  2.343209,  1.882211 },
+    {  2.257455,  2.432253,  1.838994 },
+    {  2.291592,  2.356109,  1.979364 },
+    {  0.807058,  1.819083,  1.176660 },
+    {  0.777268,  1.875932,  1.253347 },
+    {  0.730406,  1.763369,  1.144717 },
+    {  0.521151,  2.636134,  0.772735 },
+    {  0.427182,  2.604330,  0.760148 },
+    {  0.582650,  2.557415,  0.777345 },
+    {  2.865336,  0.074459,  1.821400 },
+    {  2.952667,  0.047840,  1.780599 },
+    {  2.830128,  0.155624,  1.774788 },
+    {  1.032809,  2.928064,  1.935884 },
+    {  1.018040,  2.848521,  1.994662 },
+    {  1.035481,  2.898836,  1.840289 },
+    {  0.603364,  2.018313,  2.974977 },
+    {  0.686166,  2.053333,  3.018767 },
+    {  0.559972,  1.950936,  3.034789 },
+    {  2.496931,  1.651761,  1.499709 },
+    {  2.426104,  1.589820,  1.533574 },
+    {  2.465513,  1.695407,  1.415400 },
+    {  1.992895,  1.432951,  0.877265 },
+    {  2.091252,  1.415249,  0.880807 },
+    {  1.970437,  1.479332,  0.791565 },
+    {  1.349627,  0.944871,  0.891822 },
+    {  1.294930,  0.866245,  0.920567 },
+    {  1.430409,  0.952441,  0.950277 },
+    {  0.688705,  1.806392,  1.795933 },
+    {  0.675348,  1.802183,  1.894948 },
+    {  0.661166,  1.896480,  1.762382 },
+    {  2.765604,  1.268705,  0.455509 },
+    {  2.832068,  1.330161,  0.498002 },
+    {  2.804218,  1.176637,  0.449819 },
+    {  1.087520,  0.313048,  1.525021 },
+    {  1.171839,  0.329995,  1.474000 },
+    {  1.010104,  0.311057,  1.461754 },
+    {  2.264949,  1.629745,  1.089892 },
+    {  2.266355,  1.729527,  1.083429 },
+    {  2.294268,  1.590285,  1.002810 },
+    {  1.678565,  0.632669,  1.470373 },
+    {  1.624608,  0.654483,  1.551692 },
+    {  1.740148,  0.708734,  1.449838 },
+    {  2.043401,  0.809955,  1.606486 },
+    {  1.981133,  0.814050,  1.684626 },
+    {  2.114947,  0.878990,  1.617221 },
+    {  1.188958,  2.411149,  1.184279 },
+    {  1.117315,  2.345728,  1.160041 },
+    {  1.172674,  2.445693,  1.276699 },
+    {  2.032803,  1.248583,  1.710235 },
+    {  2.108155,  1.185674,  1.691144 },
+    {  2.065892,  1.323986,  1.766976 },
+    {  0.653339,  1.578073,  0.294654 },
+    {  0.578773,  1.637336,  0.325114 },
+    {  0.691682,  1.613835,  0.209501 },
+    {  0.009546,  0.004266,  0.204101 },
+    { -0.040074, -0.018504,  0.287883 },
+    {  0.072281,  0.080040,  0.222063 },
+    {  0.301904,  1.858297,  1.612515 },
+    {  0.355925,  1.926715,  1.661512 },
+    {  0.316285,  1.768475,  1.654050 },
+    {  0.210458,  0.733536,  2.307309 },
+    {  0.180804,  0.654013,  2.254425 },
+    {  0.130306,  0.783770,  2.339748 },
+    {  0.468404,  1.026549,  2.487707 },
+    {  0.469169,  0.997854,  2.391915 },
+    {  0.528829,  1.105369,  2.499377 },
+    {  1.253251,  2.170940,  2.427798 },
+    {  1.218924,  2.125540,  2.345576 },
+    {  1.292201,  2.102762,  2.489723 },
+    {  1.591250,  2.288296,  1.789703 },
+    {  1.535539,  2.354383,  1.839990 },
+    {  1.577205,  2.196951,  1.827900 },
+    {  2.946891,  1.547805,  0.043940 },
+    {  2.976856,  1.626139,  0.098401 },
+    {  3.024835,  1.510346, -0.006275 },
+    {  1.371900,  2.628764,  0.835498 },
+    {  1.372210,  2.716646,  0.883213 },
+    {  1.304040,  2.568374,  0.877306 },
+    {  0.280736,  1.464804,  0.831929 },
+    {  0.228581,  1.472811,  0.746984 },
+    {  0.347573,  1.539004,  0.837130 },
+    {  0.464336,  1.777354,  0.380566 },
+    {  0.389430,  1.725765,  0.422129 },
+    {  0.427185,  1.855411,  0.330296 },
+    {  1.262352,  0.703325,  0.972513 },
+    {  1.191673,  0.644211,  0.933656 },
+    {  1.344104,  0.649143,  0.992027 },
+    {  1.863906,  2.737826,  0.051729 },
+    {  1.794894,  2.699801,  0.113303 },
+    {  1.945526,  2.762192,  0.104117 },
+    {  1.934621,  0.339861,  2.346475 },
+    {  1.953277,  0.266858,  2.280729 },
+    {  1.887904,  0.301739,  2.426251 },
+    {  2.302869,  1.427632,  1.252785 },
+    {  2.397274,  1.397143,  1.240212 },
+    {  2.280683,  1.496666,  1.183922 },
+    {  1.499814,  2.033362,  1.994311 },
+    {  1.554854,  1.968437,  1.941819 },
+    {  1.450097,  1.984557,  2.066049 },
+    {  2.083899,  1.448550,  1.427712 },
+    {  2.155069,  1.430052,  1.359942 },
+    {  1.994861,  1.452375,  1.382351 },
+    {  1.166293,  0.405665,  2.411606 },
+    {  1.219526,  0.442955,  2.487604 },
+    {  1.089623,  0.466645,  2.391527 },
+    {  1.884977,  2.484835,  0.910720 },
+    {  1.800940,  2.508832,  0.862120 },
+    {  1.960852,  2.539311,  0.875009 },
+    {  1.112780,  1.256626,  2.318798 },
+    {  1.124735,  1.166291,  2.277606 },
+    {  1.015258,  1.277965,  2.324623 },
+    {  1.261958,  0.079632,  1.408891 },
+    {  1.210228, -0.005830,  1.413406 },
+    {  1.296352,  0.102628,  1.499931 },
+    {  2.585863,  2.434800,  1.911444 },
+    {  2.534322,  2.378065,  1.975667 },
+    {  2.671546,  2.463898,  1.954008 },
+    {  1.730110,  2.631838,  2.128379 },
+    {  1.705843,  2.703561,  2.193702 },
+    {  1.699136,  2.658108,  2.036998 },
+    {  0.786013,  0.466280,  2.703562 },
+    {  0.791829,  0.555341,  2.658458 },
+    {  0.709772,  0.466601,  2.768271 },
+    {  2.124892,  1.358270,  0.553264 },
+    {  2.034419,  1.400658,  0.549024 },
+    {  2.119175,  1.272546,  0.604438 },
+    {  1.937050,  2.839942,  0.507969 },
+    {  1.875834,  2.818483,  0.584074 },
+    {  2.028851,  2.805971,  0.528431 },
+    {  0.694033,  3.048894,  0.117965 },
+    {  0.742816,  3.121531,  0.166381 },
+    {  0.609109,  3.027780,  0.166360 },
+    {  1.831965,  2.250876,  0.092662 },
+    {  1.865896,  2.301798,  0.013570 },
+    {  1.773638,  2.175866,  0.061491 },
+    {  0.423245,  1.234308,  0.866709 },
+    {  0.360637,  1.303337,  0.830443 },
+    {  0.397879,  1.212525,  0.960954 },
+    {  0.694900,  2.540850,  0.372187 },
+    {  0.602805,  2.502432,  0.365669 },
+    {  0.720059,  2.582155,  0.284660 },
+    {  1.613218,  1.068730,  0.571353 },
+    {  1.538921,  1.001994,  0.566242 },
+    {  1.695532,  1.030236,  0.529608 },
+    {  0.351434,  0.972531,  0.811903 },
+    {  0.260612,  0.979713,  0.853132 },
+    {  0.394644,  1.062703,  0.810529 },
+    {  0.654466,  0.668950,  0.939867 },
+    {  0.702533,  0.633043,  0.859865 },
+    {  0.710634,  0.655200,  1.021452 },
+    {  0.603028,  1.706677,  1.011611 },
+    {  0.580653,  1.621617,  0.964026 },
+    {  0.523907,  1.767799,  1.009608 },
+    {  1.984519,  2.241066,  0.609025 },
+    {  2.023379,  2.331592,  0.626204 },
+    {  1.884845,  2.247855,  0.604676 },
+    {  2.409340,  0.321441,  3.077053 },
+    {  2.478278,  0.391544,  3.095303 },
+    {  2.325876,  0.364808,  3.043095 },
+    {  0.107482,  0.226784,  2.149938 },
+    {  0.116209,  0.319603,  2.186110 },
+    {  0.058157,  0.169871,  2.215724 },
+    {  2.516283,  2.299608,  1.651831 },
+    {  2.498891,  2.206877,  1.684975 },
+    {  2.522873,  2.362117,  1.729607 },
+    {  0.166350,  0.223961,  0.204554 },
+    {  0.252719,  0.174404,  0.195355 },
+    {  0.155959,  0.287342,  0.127907 },
+    {  1.790683,  2.102293,  2.508842 },
+    {  1.772161,  2.115965,  2.606156 },
+    {  1.727524,  2.033989,  2.472162 },
+    {  0.804515,  2.449580,  1.058470 },
+    {  0.834701,  2.389681,  1.132638 },
+    {  0.826442,  2.407366,  0.970509 },
+    {  0.893496,  1.408646,  1.094836 },
+    {  0.884226,  1.374665,  1.001245 },
+    {  0.977331,  1.462610,  1.102556 },
+    {  1.324336,  0.283014,  1.983930 },
+    {  1.249350,  0.246218,  1.928948 },
+    {  1.311952,  0.256118,  2.079446 },
+    {  2.246377,  2.623759,  1.150493 },
+    {  2.254787,  2.651518,  1.246195 },
+    {  2.233979,  2.704806,  1.093243 },
+    {  2.622015,  2.142252,  1.121850 },
+    {  2.689193,  2.164431,  1.051174 },
+    {  2.532526,  2.128120,  1.079520 },
+    {  2.868567,  0.744064,  0.453349 },
+    {  2.910325,  0.673469,  0.510556 },
+    {  2.806360,  0.701325,  0.387747 },
+    {  3.007500,  2.824869,  0.443635 },
+    {  3.007007,  2.870315,  0.532711 },
+    {  2.943592,  2.871184,  0.382230 },
+    {  0.618477,  0.645863,  0.479989 },
+    {  0.594221,  0.568779,  0.421086 },
+    {  0.609509,  0.731187,  0.428613 },
+    {  0.315716,  2.761151,  1.152915 },
+    {  0.333548,  2.715008,  1.239822 },
+    {  0.223414,  2.799613,  1.153918 },
+    {  2.418530,  2.718375,  0.233422 },
+    {  2.423642,  2.619487,  0.219456 },
+    {  2.380935,  2.761708,  0.151514 },
+    {  1.098775,  2.225525,  0.111034 },
+    {  1.066019,  2.283329,  0.185771 },
+    {  1.184183,  2.181157,  0.138180 },
+    {  0.073228,  2.893589,  1.127852 },
+    { -0.000546,  2.826243,  1.132538 },
+    {  0.059832,  2.952201,  1.047945 },
+    {  2.174281,  0.457878,  2.973554 },
+    {  2.121013,  0.408744,  3.042462 },
+    {  2.172823,  0.555783,  2.993862 },
+    {  1.661179,  0.921490,  2.630975 },
+    {  1.665185,  0.927948,  2.730685 },
+    {  1.665678,  0.825419,  2.603585 },
+    {  2.933824,  1.488535,  1.260173 },
+    {  2.909874,  1.400289,  1.300658 },
+    {  2.862083,  1.516509,  1.196371 },
+    {  0.456309,  2.283995,  2.966447 },
+    {  0.466757,  2.196379,  3.013504 },
+    {  0.361327,  2.294986,  2.937162 },
+    {  0.384923,  0.707170,  1.649992 },
+    {  0.418731,  0.700554,  1.556113 },
+    {  0.288802,  0.734733,  1.648941 },
+    {  1.510475,  2.724715,  1.326010 },
+    {  1.413124,  2.746983,  1.331212 },
+    {  1.562660,  2.807736,  1.306410 },
+    {  2.250746,  0.876319,  0.084095 },
+    {  2.321093,  0.946839,  0.075252 },
+    {  2.215587,  0.875860,  0.177709 },
+    {  0.977551,  0.759542,  0.731438 },
+    {  1.009700,  0.844792,  0.772656 },
+    {  1.044178,  0.686987,  0.748662 },
+    {  1.871166,  1.469743,  1.990566 },
+    {  1.831271,  1.463875,  2.082075 },
+    {  1.849894,  1.386424,  1.939522 },
+    {  2.976639,  2.909585,  2.965670 },
+    {  2.896178,  2.903513,  2.906601 },
+    {  2.955625,  2.966962,  3.044830 },
+    {  0.219237,  0.614174,  0.309084 },
+    {  0.158141,  0.621804,  0.230286 },
+    {  0.312225,  0.595369,  0.277468 },
+    {  0.981300,  0.603983,  2.324795 },
+    {  0.882565,  0.588395,  2.321892 },
+    {  1.001037,  0.681675,  2.384581 },
+    {  0.755745,  1.121905,  0.406068 },
+    {  0.691338,  1.191344,  0.438159 },
+    {  0.709373,  1.033485,  0.400449 },
+    {  1.727780,  0.415657,  0.225759 },
+    {  1.724835,  0.315869,  0.219966 },
+    {  1.637306,  0.450294,  0.250552 },
+    {  2.250400,  1.714328,  1.807288 },
+    {  2.201134,  1.794153,  1.841942 },
+    {  2.313622,  1.681184,  1.877320 },
+    {  1.251501,  3.006716,  0.790040 },
+    {  1.153176,  3.024619,  0.786643 },
+    {  1.270862,  2.918652,  0.746798 },
+    {  1.408456,  0.117617,  0.777739 },
+    {  1.355175,  0.033350,  0.785506 },
+    {  1.406323,  0.166559,  0.864918 },
+    {  0.191205,  1.398354,  0.571156 },
+    {  0.243639,  1.328404,  0.522600 },
+    {  0.109777,  1.356822,  0.611709 },
+    {  0.168897,  1.033560,  0.985840 },
+    {  0.226152,  0.997522,  1.059481 },
+    {  0.076618,  1.050336,  1.020529 },
+    {  0.899943,  2.296334,  1.263741 },
+    {  0.941794,  2.238530,  1.193690 },
+    {  0.936440,  2.271641,  1.353508 },
+    {  3.025877,  1.802499,  0.139230 },
+    {  3.014528,  1.810825,  0.238234 },
+    {  3.120663,  1.822856,  0.114713 },
+    {  2.165556,  2.121814,  1.756587 },
+    {  2.133566,  2.054018,  1.822771 },
+    {  2.183626,  2.208257,  1.803504 },
+    {  2.014080,  0.353870,  1.050143 },
+    {  1.947732,  0.401211,  1.108082 },
+    {  2.045383,  0.270858,  1.096285 },
+    {  1.032910,  0.439954,  2.784389 },
+    {  1.039158,  0.468637,  2.879983 },
+    {  0.940927,  0.458674,  2.749913 },
+    {  2.768091,  0.500326,  2.411384 },
+    {  2.832257,  0.519231,  2.485716 },
+    {  2.693746,  0.442723,  2.445366 },
+    {  2.006408,  0.715128,  1.227328 },
+    {  1.975360,  0.677657,  1.139967 },
+    {  1.940802,  0.783386,  1.259525 },
+    {  2.487491,  2.094551,  1.399436 },
+    {  2.575522,  2.109672,  1.354471 },
+    {  2.418647,  2.154795,  1.359050 },
+    {  1.382277,  0.933263,  2.057272 },
+    {  1.464198,  0.988093,  2.040457 },
+    {  1.331486,  0.922156,  1.971851 },
+    {  0.814603,  1.428325,  2.639752 },
+    {  0.800255,  1.459433,  2.545803 },
+    {  0.763166,  1.486824,  2.702459 },
+    {  1.261287,  0.211828,  2.224595 },
+    {  1.241577,  0.276306,  2.298447 },
+    {  1.224565,  0.121861,  2.248203 },
+    {  1.619485,  2.689898,  0.188250 },
+    {  1.588224,  2.651442,  0.275106 },
+    {  1.626511,  2.789316,  0.196419 },
+    {  0.418282,  2.348942,  1.783532 },
+    {  0.446726,  2.334551,  1.688749 },
+    {  0.340773,  2.412083,  1.785854 },
+    {  0.074372,  0.645818,  1.465995 },
+    {  0.111170,  0.656995,  1.373686 },
+    {  0.051180,  0.549745,  1.481229 },
+    {  3.103577,  0.430002,  1.792040 },
+    {  3.127296,  0.345212,  1.839453 },
+    {  3.185557,  0.486255,  1.781320 },
+    {  0.656926,  1.071854,  1.113254 },
+    {  0.740429,  1.082080,  1.059192 },
+    {  0.603347,  0.995283,  1.077673 },
+    {  1.082612,  2.167030,  1.119109 },
+    {  1.112438,  2.118508,  1.036914 },
+    {  1.121778,  2.122971,  1.199885 },
+    {  1.685950,  2.668299,  0.595540 },
+    {  1.654574,  2.595554,  0.656563 },
+    {  1.701733,  2.751685,  0.648433 },
+    {  1.877991,  1.451300,  0.501414 },
+    {  1.860443,  1.441725,  0.403432 },
+    {  1.791928,  1.469157,  0.549104 },
+    {  1.193680,  2.367192,  1.806688 },
+    {  1.230655,  2.274677,  1.798090 },
+    {  1.267246,  2.430350,  1.831166 },
+    {  1.262868,  3.023321,  2.111573 },
+    {  1.218133,  3.027728,  2.200900 },
+    {  1.198796,  2.986934,  2.043964 },
+    {  2.363530,  1.819884,  0.872829 },
+    {  2.421597,  1.755189,  0.823403 },
+    {  2.406757,  1.843780,  0.959779 },
+    {  2.828612,  2.346733,  0.601532 },
+    {  2.871731,  2.429490,  0.565585 },
+    {  2.896460,  2.273475,  0.606992 },
+    {  1.479757,  1.908335,  0.805231 },
+    {  1.432019,  1.821825,  0.820629 },
+    {  1.493505,  1.954847,  0.892682 },
+    {  2.447036,  2.469183,  1.388989 },
+    {  2.484687,  2.415866,  1.464750 },
+    {  2.421583,  2.560194,  1.421687 },
+    {  0.390387,  2.304647,  0.871009 },
+    {  0.343645,  2.374860,  0.924723 },
+    {  0.452494,  2.253251,  0.930179 },
+    {  1.331260,  0.646907,  0.168446 },
+    {  1.335624,  0.547157,  0.173994 },
+    {  1.421037,  0.685440,  0.189784 },
+    {  2.828654,  2.172696,  2.960263 },
+    {  2.739741,  2.218000,  2.953789 },
+    {  2.815353,  2.073702,  2.965085 },
+    {  1.031085,  0.986172,  0.843095 },
+    {  1.020895,  1.030502,  0.754039 },
+    {  0.995655,  1.046452,  0.914586 },
+    {  1.724838,  0.391131,  2.659596 },
+    {  1.768809,  0.480924,  2.657695 },
+    {  1.633320,  0.399657,  2.698991 },
+    {  2.588704,  2.692304,  1.035174 },
+    {  2.627025,  2.632110,  1.105232 },
+    {  2.527773,  2.758929,  1.078168 },
+    {  2.699075,  0.688808,  0.769271 },
+    {  2.672432,  0.666009,  0.862921 },
+    {  2.792721,  0.657848,  0.752781 },
+    {  0.703772,  1.603296,  2.794425 },
+    {  0.701323,  1.570932,  2.889011 },
+    {  0.695426,  1.702938,  2.793061 },
+    {  0.199272,  0.353715,  0.976004 },
+    {  0.232097,  0.405137,  0.896767 },
+    {  0.126936,  0.290899,  0.947342 },
+    {  2.546014,  0.024049,  2.369379 },
+    {  2.611304, -0.035563,  2.322648 },
+    {  2.454932,  0.010881,  2.330253 },
+    {  0.022823,  1.201578,  0.748523 },
+    {  0.089773,  1.186154,  0.821185 },
+    { -0.020197,  1.290949,  0.761256 },
+    {  0.132073,  0.862795,  0.586868 },
+    {  0.119996,  0.867413,  0.487708 },
+    {  0.214518,  0.810293,  0.607998 },
+    {  2.092458,  0.359644,  0.786490 },
+    {  2.040730,  0.360242,  0.872069 },
+    {  2.190376,  0.358194,  0.806735 },
+    {  0.421056,  2.015500,  1.793066 },
+    {  0.440920,  2.024396,  1.890669 },
+    {  0.503559,  2.035681,  1.740283 },
+    {  0.385087,  0.729295,  0.920073 },
+    {  0.370596,  0.804357,  0.855608 },
+    {  0.481900,  0.704266,  0.920879 },
+    {  0.660259,  0.556115,  1.874230 },
+    {  0.674878,  0.507989,  1.787800 },
+    {  0.637897,  0.651811,  1.855729 },
+    {  1.502447,  0.450094,  2.831928 },
+    {  1.420294,  0.484380,  2.786374 },
+    {  1.548974,  0.525641,  2.878058 },
+    {  0.029169,  0.014635,  1.731543 },
+    {  0.026633,  0.054837,  1.640016 },
+    {  0.060547,  0.083210,  1.797215 },
+    {  1.945071,  1.895363,  0.577451 },
+    {  1.862520,  1.917282,  0.629461 },
+    {  2.002888,  1.833848,  0.631051 },
+    {  2.310390,  0.609079,  0.805817 },
+    {  2.224057,  0.654864,  0.827042 },
+    {  2.298969,  0.510214,  0.815575 },
+    {  0.263679,  0.742484,  1.174274 },
+    {  0.318844,  0.741293,  1.090875 },
+    {  0.258625,  0.835913,  1.209567 },
+    {  2.214362,  2.795311,  3.028770 },
+    {  2.276577,  2.856483,  2.979910 },
+    {  2.193373,  2.833914,  3.118600 },
+    {  2.862483,  0.087396,  2.967400 },
+    {  2.775054,  0.134739,  2.956690 },
+    {  2.852752,  0.014295,  3.034940 },
+    {  1.911967,  1.618076,  2.687047 },
+    {  1.939990,  1.699615,  2.737705 },
+    {  1.934376,  1.629614,  2.590276 },
+    {  3.089770,  0.624647,  0.091657 },
+    {  3.155308,  0.685544,  0.046978 },
+    {  2.997098,  0.648104,  0.062301 },
+    {  0.073286,  1.189907,  2.156408 },
+    {  0.052831,  1.175998,  2.253300 },
+    {  0.036866,  1.278274,  2.127000 },
+    {  1.751887,  1.440179,  0.260930 },
+    {  1.798183,  1.408672,  0.178081 },
+    {  1.701865,  1.364040,  0.302169 },
+    {  0.173609,  2.179533,  0.758562 },
+    {  0.240866,  2.219671,  0.820734 },
+    {  0.176312,  2.227662,  0.670948 },
+    {  0.142457,  1.714121,  2.988510 },
+    {  0.117949,  1.619062,  3.007567 },
+    {  0.171225,  1.722647,  2.893118 },
+    {  1.307838,  1.001512,  1.411174 },
+    {  1.271228,  0.912830,  1.439374 },
+    {  1.232705,  1.066537,  1.399913 },
+    {  2.169500,  1.727567,  2.182432 },
+    {  2.214494,  1.641325,  2.205624 },
+    {  2.236708,  1.801605,  2.183625 },
+    {  1.262072,  0.462936,  1.175858 },
+    {  1.169844,  0.436656,  1.147514 },
+    {  1.323387,  0.459730,  1.096926 },
+    {  1.423067,  0.881474,  0.640908 },
+    {  1.410777,  0.897237,  0.738890 },
+    {  1.333599,  0.874747,  0.596747 },
+    {  1.354799,  1.797455,  1.110787 },
+    {  1.284755,  1.765934,  1.174821 },
+    {  1.443784,  1.760881,  1.138063 },
+    {  2.129596,  0.681632,  2.008767 },
+    {  2.164107,  0.608978,  2.068185 },
+    {  2.111495,  0.763493,  2.063275 },
+    {  2.448219,  0.769518,  0.357171 },
+    {  2.453654,  0.740682,  0.452769 },
+    {  2.364799,  0.732847,  0.315983 },
+    {  0.882298,  0.543308,  0.139417 },
+    {  0.841711,  0.611831,  0.078942 },
+    {  0.885374,  0.455061,  0.092482 },
+    {  0.800295,  1.861557,  2.511300 },
+    {  0.895248,  1.830847,  2.504910 },
+    {  0.776153,  1.875477,  2.607338 },
+    {  0.764847,  2.617533,  0.120170 },
+    {  0.750496,  2.712191,  0.091292 },
+    {  0.847962,  2.581897,  0.077486 },
+    {  2.224452,  2.284036,  0.208382 },
+    {  2.184583,  2.300793,  0.118217 },
+    {  2.231256,  2.185503,  0.224032 },
+    {  0.079359,  0.002159,  0.962802 },
+    {  0.088958,  0.015986,  0.864229 },
+    {  0.027587,  0.078089,  1.002228 },
+    {  2.203527,  0.302158,  2.750022 },
+    {  2.118676,  0.267117,  2.710368 },
+    {  2.181990,  0.363004,  2.826402 },
+    {  2.170179,  2.922779,  0.174290 },
+    {  2.139623,  2.835094,  0.211408 },
+    {  2.214502,  2.975912,  0.246487 },
+    {  0.890672,  0.080190,  2.804656 },
+    {  0.938414,  0.126680,  2.730094 },
+    {  0.956701,  0.052889,  2.874619 },
+    {  2.895087,  1.762880,  1.373604 },
+    {  2.900573,  1.663669,  1.362331 },
+    {  2.987003,  1.800097,  1.386500 },
+    {  1.853496,  2.074764,  1.508729 },
+    {  1.948479,  2.059296,  1.481547 },
+    {  1.801303,  2.107900,  1.430129 },
+    {  2.582175,  2.315870,  2.888700 },
+    {  2.529120,  2.231314,  2.882752 },
+    {  2.555198,  2.366456,  2.970634 },
+    {  2.750479,  0.538398,  1.610168 },
+    {  2.766143,  0.560952,  1.514012 },
+    {  2.664507,  0.579511,  1.640473 },
+    {  1.377553,  1.621616,  0.224361 },
+    {  1.362069,  1.531830,  0.183145 },
+    {  1.471939,  1.627547,  0.256858 },
+    {  0.701605,  1.997351,  0.173637 },
+    {  0.647573,  2.049848,  0.239400 },
+    {  0.768452,  2.057483,  0.129870 },
+    {  0.732393,  2.885926,  1.675034 },
+    {  0.681248,  2.960743,  1.717302 },
+    {  0.678998,  2.801575,  1.680869 },
+    {  1.333051,  1.944054,  2.636380 },
+    {  1.270422,  1.992525,  2.697439 },
+    {  1.304905,  1.848392,  2.628856 },
+    {  0.350047,  1.397444,  2.193652 },
+    {  0.381158,  1.302587,  2.187811 },
+    {  0.269866,  1.402622,  2.253185 },
+    {  2.655774,  2.801154,  1.477291 },
+    {  2.607340,  2.769915,  1.559012 },
+    {  2.612048,  2.883978,  1.442246 },
+    {  0.830586,  2.382898,  2.380660 },
+    {  0.751782,  2.323648,  2.363947 },
+    {  0.821711,  2.466316,  2.326230 },
+    {  0.386076,  2.773589,  2.748805 },
+    {  0.415232,  2.861381,  2.710824 },
+    {  0.309400,  2.737978,  2.695395 },
+    {  0.288028,  1.761089,  2.267276 },
+    {  0.195585,  1.734450,  2.294565 },
+    {  0.306586,  1.727296,  2.175006 },
+    {  2.845222,  3.049689,  0.710560 },
+    {  2.938507,  3.015530,  0.699111 },
+    {  2.796410,  2.992019,  0.776069 },
+    {  2.095486,  2.468157,  1.419021 },
+    {  2.014126,  2.429148,  1.462136 },
+    {  2.161124,  2.395254,  1.399606 },
+    {  0.990751,  0.380958,  1.088061 },
+    {  0.962957,  0.355990,  0.995302 },
+    {  1.050039,  0.309627,  1.125433 },
+    {  1.490762,  3.006773,  1.217981 },
+    {  1.443078,  3.092111,  1.239049 },
+    {  1.589527,  3.021852,  1.222217 },
+    {  1.054051,  1.680650,  2.482261 },
+    {  0.992890,  1.601710,  2.487543 },
+    {  1.097855,  1.694879,  2.571023 },
+    {  1.617761,  2.709729,  1.856625 },
+    {  1.685809,  2.664639,  1.798863 },
+    {  1.625149,  2.808851,  1.845661 },
+    {  0.831548,  0.104590,  1.240112 },
+    {  0.854610,  0.030748,  1.303480 },
+    {  0.870357,  0.084640,  1.150135 },
+    {  2.460575,  2.913002,  2.033870 },
+    {  2.387432,  2.978945,  2.016501 },
+    {  2.544679,  2.944073,  1.989585 },
+    {  0.968554,  1.072304,  0.587917 },
+    {  1.021416,  0.999670,  0.543986 },
+    {  0.886242,  1.090771,  0.534217 },
+    {  1.747197,  0.995358,  2.249228 },
+    {  1.834103,  1.034204,  2.279860 },
+    {  1.689613,  0.975781,  2.328606 },
+    {  2.113166,  1.198713,  2.946735 },
+    {  2.164920,  1.232009,  3.025557 },
+    {  2.082168,  1.276428,  2.891968 },
+    {  0.386328,  0.003613,  1.788966 },
+    {  0.370117, -0.024061,  1.694249 },
+    {  0.331931, -0.053732,  1.850224 },
+    {  1.113078,  2.990990,  0.400315 },
+    {  1.033021,  2.934960,  0.421561 },
+    {  1.196169,  2.937301,  0.414924 },
+    {  3.004892,  0.215602,  0.988293 },
+    {  2.941095,  0.159722,  1.041278 },
+    {  2.959599,  0.248333,  0.905364 },
+    {  1.180028,  0.462930,  3.027119 },
+    {  1.194383,  0.448931,  3.125088 },
+    {  1.205635,  0.556462,  3.002706 },
+    {  1.274036,  0.501724,  2.672057 },
+    {  1.301730,  0.596901,  2.685261 },
+    {  1.191003,  0.483553,  2.724738 },
+    {  2.947187,  2.426754,  0.273837 },
+    {  2.910177,  2.352895,  0.217490 },
+    {  2.962008,  2.507751,  0.217092 },
+    {  0.414034,  1.604272,  2.862308 },
+    {  0.369433,  1.665968,  2.797468 },
+    {  0.511529,  1.598227,  2.840903 },
+    {  0.857555,  1.198856,  1.337218 },
+    {  0.815665,  1.254240,  1.265260 },
+    {  0.790251,  1.181020,  1.408996 },
+    {  1.402725,  1.861893,  1.683336 },
+    {  1.478004,  1.884592,  1.621549 },
+    {  1.438488,  1.812987,  1.762893 },
+    {  1.143436,  2.070677,  2.177391 },
+    {  1.126093,  1.974251,  2.197423 },
+    {  1.140420,  2.085246,  2.078504 },
+    {  1.140117,  2.529814,  2.107822 },
+    {  1.195065,  2.512471,  2.026092 },
+    {  1.179853,  2.481181,  2.185642 },
+    {  1.977009,  0.352605,  0.334132 },
+    {  1.906708,  0.390859,  0.274179 },
+    {  1.962216,  0.384824,  0.427636 },
+    {  2.130115,  1.470625,  1.830714 },
+    {  2.130574,  1.426674,  1.920537 },
+    {  2.139711,  1.569528,  1.841947 },
+    {  0.730700,  0.203115,  1.799955 },
+    {  0.694439,  0.296295,  1.801601 },
+    {  0.830605,  0.206164,  1.803080 },
+    {  1.903507,  2.950766,  2.105392 },
+    {  1.961982,  2.880427,  2.145802 },
+    {  1.809765,  2.939068,  2.138189 },
+    {  1.362461,  0.776317,  2.440580 },
+    {  1.373552,  0.711877,  2.364919 },
+    {  1.401240,  0.864848,  2.414921 },
+    {  1.393736,  0.230352,  1.027233 },
+    {  1.474875,  0.215232,  1.083694 },
+    {  1.312059,  0.203810,  1.078462 },
+    {  0.883267,  2.290109,  0.853754 },
+    {  0.964497,  2.279289,  0.796442 },
+    {  0.862588,  2.203355,  0.898988 },
+    {  1.860047,  2.351311,  1.532016 },
+    {  1.892853,  2.257751,  1.518966 },
+    {  1.760116,  2.352393,  1.528474 },
+    {  0.907781,  1.468871,  0.302742 },
+    {  0.943288,  1.506453,  0.388339 },
+    {  0.808771,  1.482381,  0.298937 },
+    {  0.634389,  0.172523,  0.350440 },
+    {  0.731006,  0.157177,  0.329712 },
+    {  0.579360,  0.100624,  0.307988 },
+    {  0.948849,  0.786484,  1.870334 },
+    {  1.046390,  0.765851,  1.862583 },
+    {  0.902713,  0.711892,  1.918370 },
+    {  0.928507,  1.428757,  1.800533 },
+    {  0.964649,  1.337409,  1.819219 },
+    {  0.981629,  1.471275,  1.727250 },
+    {  0.520126,  0.449796,  0.329923 },
+    {  0.480298,  0.444788,  0.238333 },
+    {  0.545807,  0.358005,  0.360171 },
+    {  0.173019,  1.766946,  1.124286 },
+    {  0.119940,  1.845672,  1.155670 },
+    {  0.266447,  1.795893,  1.103473 },
+    {  0.294915,  2.483116,  1.059922 },
+    {  0.237058,  2.412428,  1.100614 },
+    {  0.279515,  2.569983,  1.107008 },
+    {  1.967528,  1.701598,  0.384068 },
+    {  1.937630,  1.618064,  0.430200 },
+    {  1.953844,  1.779905,  0.444737 },
+    {  2.602165,  1.306857,  2.049074 },
+    {  2.675314,  1.367643,  2.018182 },
+    {  2.530699,  1.302540,  1.979261 },
+    {  0.466325,  2.360293,  2.055629 },
+    {  0.431952,  2.347197,  1.962640 },
+    {  0.560285,  2.394324,  2.051953 },
+    {  2.050154,  1.584414,  0.148513 },
+    {  2.040061,  1.624411,  0.239608 },
+    {  2.068395,  1.656922,  0.082106 },
+    {  1.556378,  1.957320,  2.428697 },
+    {  1.476038,  1.941088,  2.485985 },
+    {  1.529396,  1.956406,  2.332410 },
+    {  0.682812,  1.205529,  2.526461 },
+    {  0.723788,  1.287438,  2.566610 },
+    {  0.754192,  1.137731,  2.508900 },
+    {  1.535311,  0.251227,  2.208550 },
+    {  1.556668,  0.315254,  2.282337 },
+    {  1.437096,  0.253450,  2.189872 },
+    {  2.668479,  2.280105,  0.800170 },
+    {  2.710946,  2.318387,  0.718127 },
+    {  2.739255,  2.259010,  0.867592 },
+    {  1.542641,  3.084046,  2.220568 },
+    {  1.544509,  3.183810,  2.213954 },
+    {  1.458575,  3.049445,  2.178907 },
+    {  1.457762,  1.374257,  2.244142 },
+    {  1.499569,  1.291727,  2.206182 },
+    {  1.369735,  1.390552,  2.199582 },
+    {  2.519020,  1.910788,  1.891775 },
+    {  2.505169,  1.980275,  1.821208 },
+    {  2.518774,  1.820060,  1.849722 },
+    {  1.153670,  2.497971,  0.920991 },
+    {  1.071685,  2.549851,  0.896764 },
+    {  1.150536,  2.474089,  1.018047 },
+    {  2.586281,  3.065417,  2.640789 },
+    {  2.568059,  3.047493,  2.544111 },
+    {  2.503036,  3.049598,  2.693891 },
+    {  2.306781,  1.384101,  0.311448 },
+    {  2.360460,  1.468263,  0.305517 },
+    {  2.263250,  1.378589,  0.401307 },
+    {  2.141848,  2.022213,  0.235023 },
+    {  2.188715,  1.934828,  0.222090 },
+    {  2.046005,  2.005531,  0.258168 },
+    {  0.201078,  1.356753,  0.228828 },
+    {  0.104294,  1.337330,  0.244812 },
+    {  0.255501,  1.318727,  0.303609 },
+    {  0.457343,  0.726277,  2.048767 },
+    {  0.460321,  0.628162,  2.067859 },
+    {  0.365421,  0.751595,  2.018612 },
+    {  2.860924,  1.577827,  1.715642 },
+    {  2.807984,  1.661584,  1.729132 },
+    {  2.834381,  1.510187,  1.784347 },
+    {  3.020626,  2.542969,  0.500236 },
+    {  2.999224,  2.640062,  0.489514 },
+    {  3.013950,  2.497365,  0.411491 },
+    {  2.449280,  0.880812,  2.387606 },
+    {  2.481825,  0.817972,  2.316952 },
+    {  2.399173,  0.956029,  2.344807 },
+    {  0.839472,  2.578596,  0.606320 },
+    {  0.789949,  2.578031,  0.519445 },
+    {  0.782640,  2.537078,  0.677358 },
+    {  1.243451,  2.095390,  1.335077 },
+    {  1.341417,  2.115228,  1.338089 },
+    {  1.228127,  1.999442,  1.358721 },
+    {  0.679730,  2.838689,  2.009180 },
+    {  0.764800,  2.786702,  2.001406 },
+    {  0.699085,  2.936157,  1.997983 },
+    {  0.738842,  1.537655,  0.650196 },
+    {  0.761227,  1.584947,  0.564976 },
+    {  0.790684,  1.578252,  0.725458 },
+    {  2.835650,  0.699534,  0.020790 },
+    {  2.777710,  0.692381,  0.101980 },
+    {  2.780032,  0.685783, -0.061170 },
+    {  1.845371,  0.433166,  1.258526 },
+    {  1.842422,  0.520378,  1.307367 },
+    {  1.791587,  0.365195,  1.308398 },
+    {  3.094758,  1.053543,  1.958825 },
+    {  3.137912,  1.085383,  2.043228 },
+    {  3.044658,  0.968902,  1.976876 },
+    {  1.893173,  3.056022,  0.347448 },
+    {  1.915403,  2.979650,  0.408054 },
+    {  1.943785,  3.137299,  0.376303 },
+    {  0.227549,  2.726489,  1.743416 },
+    {  0.256351,  2.780895,  1.822222 },
+    {  0.292572,  2.739273,  1.668526 },
+    {  1.149302,  2.387237,  0.343532 },
+    {  1.166208,  2.474303,  0.297339 },
+    {  1.104012,  2.404185,  0.431062 },
+    {  0.998224,  1.657693,  1.298714 },
+    {  1.056918,  1.616397,  1.229074 },
+    {  0.929567,  1.715405,  1.254493 },
+    {  1.580309,  1.703216,  2.655682 },
+    {  1.649980,  1.643679,  2.695698 },
+    {  1.618097,  1.794935,  2.643051 },
+    {  2.081265,  2.616518,  0.762181 },
+    {  2.163416,  2.561470,  0.777047 },
+    {  2.033529,  2.583809,  0.680625 },
+    {  1.576754,  0.079976,  2.599135 },
+    {  1.624151,  0.042940,  2.679022 },
+    {  1.635391,  0.071299,  2.518597 },
+    {  1.820339,  2.087323,  1.807897 },
+    {  1.862842,  2.081803,  1.717547 },
+    {  1.876202,  2.144950,  1.867550 },
+    {  1.288347,  2.784119,  0.352047 },
+    {  1.348111,  2.713677,  0.313756 },
+    {  1.267249,  2.761808,  0.447216 },
+    {  2.053319,  2.806163,  2.812877 },
+    {  2.012843,  2.896631,  2.799563 },
+    {  2.079198,  2.795015,  2.908825 },
+    {  3.103936,  1.939383,  3.010709 },
+    {  3.140987,  1.850879,  2.982526 },
+    {  3.004767,  1.932147,  3.021340 },
+    {  1.747635,  1.880408,  0.182510 },
+    {  1.711340,  1.800658,  0.230703 },
+    {  1.811848,  1.928874,  0.241905 },
+    {  0.357312,  1.249510,  0.396746 },
+    {  0.434813,  1.308092,  0.420447 },
+    {  0.370178,  1.159100,  0.437496 },
+    {  1.162175,  1.003437,  0.132788 },
+    {  1.128159,  0.910792,  0.148908 },
+    {  1.118065,  1.066691,  0.196452 },
+    {  1.720024,  2.350807,  2.796146 },
+    {  1.816624,  2.332488,  2.777905 },
+    {  1.666584,  2.268039,  2.779012 },
+    {  1.819804,  2.881982,  1.499877 },
+    {  1.801703,  2.787241,  1.473482 },
+    {  1.853012,  2.884553,  1.594167 },
+    {  1.641302,  0.985935,  1.700102 },
+    {  1.578200,  1.054423,  1.736539 },
+    {  1.590234,  0.903900,  1.674370 },
+    {  1.407558,  2.105852,  0.622137 },
+    {  1.439669,  2.037089,  0.687256 },
+    {  1.376226,  2.186770,  0.671844 },
+    {  0.742039,  2.449685,  1.807591 },
+    {  0.664816,  2.508741,  1.784159 },
+    {  0.750599,  2.443898,  1.907056 },
+    {  1.055383,  2.338027,  2.575278 },
+    {  0.980287,  2.357568,  2.512201 },
+    {  1.137644,  2.315308,  2.523153 },
+    {  0.383084,  1.881983,  0.997049 },
+    {  0.439661,  1.963523,  1.009305 },
+    {  0.342804,  1.882808,  0.905524 },
+    {  1.624121,  1.460397,  0.585692 },
+    {  1.610918,  1.374878,  0.635814 },
+    {  1.536897,  1.490047,  0.546797 },
+    {  3.073791,  2.284139,  1.733887 },
+    {  3.159350,  2.238214,  1.710000 },
+    {  3.006778,  2.216259,  1.763913 },
+    {  2.276815,  2.539086,  2.980504 },
+    {  2.243982,  2.631874,  2.998179 },
+    {  2.215148,  2.473147,  3.023507 },
+    {  0.287152,  0.812484,  2.829435 },
+    {  0.364868,  0.874562,  2.839761 },
+    {  0.320299,  0.721354,  2.805011 },
+    {  2.947925,  2.745224,  1.175244 },
+    {  2.937136,  2.657265,  1.221578 },
+    {  2.932797,  2.819397,  1.240584 },
+    {  2.432782,  0.445198,  2.008265 },
+    {  2.528164,  0.421749,  2.027040 },
+    {  2.426765,  0.541315,  1.981331 },
+    {  2.135631,  2.846586,  1.674159 },
+    {  2.112821,  2.924476,  1.615739 },
+    {  2.142838,  2.877115,  1.769111 },
+    {  1.992697,  1.542239,  1.123538 },
+    {  1.994674,  1.495622,  1.035090 },
+    {  2.085254,  1.571023,  1.148125 },
+    {  3.007302,  1.002020,  1.263169 },
+    {  3.005399,  1.045505,  1.173139 },
+    {  3.102123,  0.991726,  1.293219 },
+    {  3.042117,  1.830594,  2.657699 },
+    {  3.091667,  1.816789,  2.571943 },
+    {  2.974763,  1.757611,  2.669402 },
+    {  1.465297,  1.281842,  2.950841 },
+    {  1.411305,  1.229250,  3.016560 },
+    {  1.408774,  1.303931,  2.871359 },
+    {  2.612090,  0.891093,  1.547955 },
+    {  2.695821,  0.887163,  1.493423 },
+    {  2.616686,  0.823002,  1.621047 },
+    {  0.812006,  2.707695,  1.208838 },
+    {  0.735158,  2.770254,  1.195395 },
+    {  0.808964,  2.635761,  1.139439 },
+    {  0.318130,  2.780547,  0.516632 },
+    {  0.265551,  2.753112,  0.436116 },
+    {  0.291856,  2.723669,  0.594571 },
+    {  1.554664,  1.776211,  0.557025 },
+    {  1.585392,  1.801147,  0.648862 },
+    {  1.479411,  1.836105,  0.529645 },
+    {  1.313118,  1.325875,  1.106502 },
+    {  1.406876,  1.305721,  1.134843 },
+    {  1.255307,  1.336157,  1.187448 },
+    {  0.563695,  1.495837,  0.858004 },
+    {  0.647750,  1.477497,  0.807031 },
+    {  0.516021,  1.409745,  0.875762 },
+    {  0.189938,  2.083492,  2.220667 },
+    {  0.179488,  2.169607,  2.170918 },
+    {  0.228533,  2.014250,  2.159708 },
+    {  1.219512,  1.960655,  0.459886 },
+    {  1.126082,  1.995943,  0.454832 },
+    {  1.269108,  2.007934,  0.532721 },
+    {  2.373176,  2.965076,  2.821447 },
+    {  2.364244,  2.875424,  2.778057 },
+    {  2.284076,  3.010455,  2.822850 },
+    {  0.688102,  2.932363,  2.635048 },
+    {  0.749140,  3.002946,  2.599097 },
+    {  0.736401,  2.878551,  2.704123 },
+    {  3.043730,  1.315443,  0.326532 },
+    {  3.042042,  1.258753,  0.408893 },
+    {  2.996829,  1.267695,  0.252232 },
+    {  1.964500,  2.004276,  2.335286 },
+    {  1.904133,  1.953017,  2.274227 },
+    {  1.911536,  2.040095,  2.412175 },
+    {  0.450798,  1.904655,  2.606229 },
+    {  0.475742,  1.954537,  2.523226 },
+    {  0.376490,  1.952627,  2.652888 },
+    {  2.112788,  1.128108,  0.683552 },
+    {  2.130045,  1.121204,  0.781809 },
+    {  2.060726,  1.048319,  0.653164 },
+    {  0.770271,  0.564206,  0.707533 },
+    {  0.849217,  0.624301,  0.695042 },
+    {  0.701429,  0.584713,  0.637961 },
+    {  1.907848,  1.027415,  1.090399 },
+    {  1.926364,  1.073308,  1.177296 },
+    {  1.854230,  1.087899,  1.031520 },
+    {  2.006840,  0.879452,  0.615825 },
+    {  1.950347,  0.812869,  0.567089 },
+    {  2.048772,  0.835710,  0.695376 },
+    {  1.044237,  2.729692,  2.739900 },
+    {  0.957432,  2.739064,  2.788657 },
+    {  1.087096,  2.642769,  2.764545 },
+    {  2.024470,  0.868120,  2.448789 },
+    {  1.977539,  0.792888,  2.402554 },
+    {  2.038713,  0.844474,  2.544904 },
+    {  2.346306,  0.847486,  1.854141 },
+    {  2.428596,  0.887883,  1.894097 },
+    {  2.273015,  0.846975,  1.922172 },
+    {  2.451466,  1.066926,  0.052602 },
+    {  2.454208,  1.089762,  0.149921 },
+    {  2.461859,  1.150367, -0.001524 },
+    {  1.586928,  0.171622,  1.225782 },
+    {  1.643190,  0.092301,  1.249084 },
+    {  1.585595,  0.235339,  1.302842 },
+    {  2.158334,  2.595841,  2.438041 },
+    {  2.126742,  2.586688,  2.532477 },
+    {  2.120427,  2.521555,  2.382862 },
+    {  0.268769,  2.384647,  1.524956 },
+    {  0.178764,  2.396688,  1.483075 },
+    {  0.264809,  2.310261,  1.591672 },
+    {  2.964697,  0.609294,  2.578384 },
+    {  3.014589,  0.539796,  2.526607 },
+    {  2.991249,  0.604578,  2.674679 },
+    {  2.804129,  2.035185,  2.658896 },
+    {  2.831947,  2.130885,  2.667122 },
+    {  2.859608,  1.990245,  2.588878 },
+    {  2.269440,  0.004664,  2.015026 },
+    {  2.292795,  0.086003,  1.961748 },
+    {  2.266981,  0.028052,  2.112221 },
+    {  0.978350,  1.814540,  1.887908 },
+    {  1.016409,  1.901488,  1.919396 },
+    {  0.900506,  1.832099,  1.827642 },
+    {  1.043390,  1.175341,  1.906444 },
+    {  1.099585,  1.238650,  1.959679 },
+    {  0.975010,  1.133260,  1.966055 },
+    {  2.016893,  0.274093,  2.004319 },
+    {  2.071563,  0.340099,  2.055840 },
+    {  2.024768,  0.293409,  1.906518 },
+    {  0.200210,  1.231970,  1.834713 },
+    {  0.114839,  1.184264,  1.855594 },
+    {  0.188948,  1.285302,  1.750875 },
+    {  2.729975,  1.523368,  1.494243 },
+    {  2.786119,  1.553298,  1.571393 },
+    {  2.644035,  1.574497,  1.493741 },
+    {  0.654823,  2.344026,  0.041906 },
+    {  0.585582,  2.332462, -0.029311 },
+    {  0.740286,  2.375393,  0.000528 },
+    {  3.021982,  2.593565,  2.621302 },
+    {  2.989764,  2.499790,  2.634267 },
+    {  3.017212,  2.642770,  2.708228 },
+    {  2.487491,  2.587543,  0.588152 },
+    {  2.540926,  2.508060,  0.559391 },
+    {  2.491371,  2.596063,  0.687713 },
+    {  0.858188,  2.209867,  1.713786 },
+    {  0.822392,  2.294693,  1.752813 },
+    {  0.919970,  2.231431,  1.638169 },
+    {  2.596792,  1.253523,  0.653627 },
+    {  2.639966,  1.236539,  0.565041 },
+    {  2.592499,  1.168156,  0.705531 },
+    {  1.557444,  1.249902,  0.754581 },
+    {  1.590664,  1.171004,  0.702893 },
+    {  1.458703,  1.241710,  0.768116 },
+    {  0.474497,  2.224022,  0.619046 },
+    {  0.446543,  2.260459,  0.707877 },
+    {  0.480869,  2.124369,  0.624402 },
+    {  0.761041,  1.590794,  2.432924 },
+    {  0.791242,  1.685785,  2.440954 },
+    {  0.663172,  1.588543,  2.412513 },
+    {  0.836284,  1.482214,  2.190881 },
+    {  0.850232,  1.384275,  2.205489 },
+    {  0.787473,  1.520964,  2.269085 },
+    {  2.454650,  0.391488,  2.726185 },
+    {  2.367849,  0.341863,  2.724489 },
+    {  2.440428,  0.482185,  2.765830 },
+    {  2.354491,  0.123748,  1.086280 },
+    {  2.373650,  0.056337,  1.014945 },
+    {  2.440302,  0.152735,  1.128663 },
+    {  2.992918,  1.513766,  2.387696 },
+    {  2.906224,  1.543682,  2.347829 },
+    {  2.987283,  1.518885,  2.487406 },
+    {  1.227082,  2.282968,  2.976912 },
+    {  1.164560,  2.261041,  3.051813 },
+    {  1.316651,  2.307128,  3.014247 },
+    {  1.518608,  0.153309,  1.856854 },
+    {  1.447277,  0.199556,  1.909514 },
+    {  1.606102,  0.199449,  1.871548 },
+    {  2.587957,  0.288841,  2.468338 },
+    {  2.578525,  0.296796,  2.567574 },
+    {  2.606517,  0.193603,  2.444146 },
+    {  0.144688,  1.415405,  1.610001 },
+    {  0.207284,  1.450562,  1.540389 },
+    {  0.085255,  1.489291,  1.641759 },
+    {  2.748672,  1.594337,  2.271072 },
+    {  2.673511,  1.622680,  2.330631 },
+    {  2.718247,  1.596183,  2.175830 },
+    {  0.410163,  0.619010,  2.435827 },
+    {  0.345484,  0.681869,  2.392637 },
+    {  0.503603,  0.646896,  2.413665 },
+    {  0.534691,  0.343823,  1.325729 },
+    {  0.632028,  0.338918,  1.348121 },
+    {  0.500601,  0.435795,  1.345198 },
+    {  2.461049,  0.820135,  0.965838 },
+    {  2.536165,  0.820911,  1.031846 },
+    {  2.421632,  0.728344,  0.961273 },
+    {  0.531212,  2.220300,  0.236689 },
+    {  0.502904,  2.296693,  0.294679 },
+    {  0.574186,  2.255658,  0.153605 },
+    {  1.655506,  2.833838,  2.317040 },
+    {  1.668580,  2.830497,  2.416125 },
+    {  1.602969,  2.915483,  2.293083 },
+    {  1.288110,  2.656172,  2.952423 },
+    {  1.277223,  2.634069,  2.855505 },
+    {  1.368445,  2.608857,  2.988584 },
+    {  2.348524,  2.179906,  2.595979 },
+    {  2.372646,  2.102011,  2.653862 },
+    {  2.259984,  2.216541,  2.624589 },
+    {  1.695517,  0.551448,  0.805462 },
+    {  1.699774,  0.609314,  0.724017 },
+    {  1.704642,  0.455524,  0.778714 },
+    {  2.106596,  1.916632,  1.923212 },
+    {  2.155546,  1.961234,  1.998142 },
+    {  2.032239,  1.861051,  1.960386 },
+    {  2.447050,  2.038526,  1.664823 },
+    {  2.350761,  2.065299,  1.668234 },
+    {  2.484148,  2.058980,  1.574239 },
+    {  2.449344,  1.569436,  1.950703 },
+    {  2.437787,  1.493630,  1.886517 },
+    {  2.546473,  1.580996,  1.971496 },
+    {  2.112171,  0.408380,  1.794677 },
+    {  2.158942,  0.496119,  1.805372 },
+    {  2.078496,  0.399767,  1.700912 },
+    {  2.692511,  0.417154,  0.512240 },
+    {  2.679476,  0.365314,  0.427725 },
+    {  2.621964,  0.487674,  0.519306 },
+    {  0.435488,  2.780530,  1.586002 },
+    {  0.420283,  2.877527,  1.567019 },
+    {  0.435612,  2.729368,  1.500080 },
+    {  1.115003,  1.717126,  0.837236 },
+    {  1.203147,  1.677245,  0.811938 },
+    {  1.068973,  1.751023,  0.755185 },
+    {  1.856343,  0.616824,  2.343989 },
+    {  1.796548,  0.622851,  2.264063 },
+    {  1.904818,  0.529366,  2.342835 },
+    {  2.604397,  0.261200,  2.905175 },
+    {  2.528620,  0.244919,  2.968362 },
+    {  2.569499,  0.303156,  2.821379 },
+    {  2.983071,  1.836011,  0.408545 },
+    {  2.941255,  1.922312,  0.380198 },
+    {  2.911503,  1.771495,  0.435298 },
+    {  0.284846,  1.004775,  0.159867 },
+    {  0.340818,  1.016814,  0.241856 },
+    {  0.297717,  1.083015,  0.098934 },
+    {  0.192126,  0.793038,  0.011385 },
+    {  0.230558,  0.870973,  0.060874 },
+    {  0.241567,  0.780506, -0.074630 },
+    {  2.563812,  1.647993,  2.692657 },
+    {  2.622485,  1.725166,  2.717190 },
+    {  2.503455,  1.674583,  2.617490 },
+    {  2.529260,  2.046808,  0.776094 },
+    {  2.471748,  2.053308,  0.857642 },
+    {  2.544468,  2.138278,  0.738651 },
+    {  1.521366,  2.552599,  3.064763 },
+    {  1.526632,  2.463583,  3.110023 },
+    {  1.534993,  2.625151,  3.132221 },
+    {  0.511749,  0.923074,  2.208753 },
+    {  0.447660,  0.998092,  2.192473 },
+    {  0.496390,  0.850876,  2.141288 },
+    {  2.117688,  1.781807,  0.783134 },
+    {  2.208797,  1.813138,  0.809922 },
+    {  2.055770,  1.788578,  0.861366 },
+    {  1.652780,  2.093001,  2.754505 },
+    {  1.554431,  2.085575,  2.771006 },
+    {  1.698800,  2.011709,  2.790196 },
+    {  1.737177,  1.179170,  2.904903 },
+    {  1.737840,  1.107564,  2.974704 },
+    {  1.642971,  1.207781,  2.887392 },
+    {  2.608930,  0.790629,  1.194068 },
+    {  2.528547,  0.828235,  1.240158 },
+    {  2.684912,  0.785017,  1.258839 },
+    {  1.698150,  0.265894,  0.685113 },
+    {  1.679547,  0.256862,  0.782952 },
+    {  1.680976,  0.178467,  0.639707 },
+    {  1.062092,  1.101304,  1.495332 },
+    {  1.047507,  1.009579,  1.532398 },
+    {  0.976651,  1.135380,  1.456105 },
+    {  2.481560,  2.004994,  0.118148 },
+    {  2.554321,  1.938467,  0.101419 },
+    {  2.482028,  2.031356,  0.214610 },
+    {  1.923369,  2.539567,  0.556425 },
+    {  1.838167,  2.585092,  0.530578 },
+    {  1.973136,  2.512668,  0.473965 },
+    {  2.710513,  1.598229,  2.008108 },
+    {  2.724888,  1.696756,  2.017366 },
+    {  2.797808,  1.553485,  1.988678 },
+    {  2.942739,  0.227199,  0.186899 },
+    {  3.020717,  0.170557,  0.160232 },
+    {  2.975626,  0.309638,  0.232967 },
+    {  1.274750,  0.014932,  2.831151 },
+    {  1.277539, -0.019282,  2.737227 },
+    {  1.311231, -0.054613,  2.893059 },
+    {  0.138548,  2.393702,  0.543185 },
+    {  0.060579,  2.445383,  0.507829 },
+    {  0.146433,  2.307200,  0.493635 },
+    {  0.194759,  3.076992,  1.308021 },
+    {  0.227728,  3.149223,  1.247228 },
+    {  0.123684,  3.024177,  1.261557 },
+    {  1.133502,  0.030873,  0.173195 },
+    {  1.148695, -0.014224,  0.261146 },
+    {  1.211249,  0.090184,  0.152275 },
+    {  2.722824,  2.558867,  2.789907 },
+    {  2.702571,  2.600501,  2.701270 },
+    {  2.696187,  2.462493,  2.788332 },
+    {  1.307419,  2.352714,  2.242314 },
+    {  1.405996,  2.369378,  2.240105 },
+    {  1.287675,  2.277863,  2.305619 },
+    {  2.808640,  0.090952,  2.094578 },
+    {  2.837316,  0.064602,  2.002473 },
+    {  2.873024,  0.053768,  2.161452 },
+    {  2.610557,  2.119816,  2.296930 },
+    {  2.516683,  2.088381,  2.311053 },
+    {  2.673361,  2.042581,  2.306444 },
+    {  2.067765,  0.663952,  0.224417 },
+    {  2.149722,  0.619553,  0.188201 },
+    {  2.062731,  0.649171,  0.323191 },
+    {  2.410587,  1.939136,  0.539274 },
+    {  2.329640,  1.983980,  0.501371 },
+    {  2.433478,  1.980572,  0.627359 },
+    {  0.266830,  2.589002,  0.694311 },
+    {  0.229373,  2.506770,  0.651476 },
+    {  0.213318,  2.611497,  0.775739 },
+    {  2.665478,  0.247924,  0.257674 },
+    {  2.758689,  0.235464,  0.223669 },
+    {  2.619919,  0.159088,  0.263375 },
+    {  1.391624,  1.635214,  0.824559 },
+    {  1.443687,  1.587036,  0.895045 },
+    {  1.373363,  1.573131,  0.748321 },
+    {  0.915468,  0.823852,  0.413096 },
+    {  0.943532,  0.769916,  0.492490 },
+    {  0.954097,  0.783595,  0.330107 },
+    {  2.422248,  2.909883,  1.103557 },
+    {  2.418386,  2.919563,  1.203012 },
+    {  2.330025,  2.917723,  1.065696 },
+    {  1.408309,  2.936097,  0.154872 },
+    {  1.501433,  2.955528,  0.185701 },
+    {  1.357769,  2.890516,  0.228139 },
+    {  1.601230,  0.015841,  0.607280 },
+    {  1.583071,  0.049227,  0.514783 },
+    {  1.529356,  0.047873,  0.668990 },
+    {  2.387127,  2.249286,  0.604177 },
+    {  2.339117,  2.308859,  0.668568 },
+    {  2.320551,  2.194928,  0.553061 },
+    {  0.006317,  0.397187,  2.468096 },
+    {  0.086350,  0.369685,  2.521373 },
+    { -0.067122,  0.330651,  2.481501 },
+    {  2.414588,  0.649050,  2.818040 },
+    {  2.413447,  0.726390,  2.881421 },
+    {  2.379346,  0.678284,  2.729139 },
+    {  1.620984,  0.646636,  0.554546 },
+    {  1.555752,  0.571955,  0.541602 },
+    {  1.571288,  0.732489,  0.567183 },
+    {  1.388431,  1.496548,  2.555467 },
+    {  1.346007,  1.491565,  2.645885 },
+    {  1.459663,  1.566733,  2.555890 },
+    {  0.135346,  0.027221,  0.692454 },
+    {  0.110535,  0.085136,  0.614799 },
+    {  0.229755, -0.004019,  0.681917 },
+    {  0.356113,  1.759265,  2.006375 },
+    {  0.428524,  1.828103,  2.010617 },
+    {  0.357217,  1.715211,  1.916609 },
+    {  2.784840,  1.337893,  0.048133 },
+    {  2.833571,  1.258874,  0.085296 },
+    {  2.850191,  1.410781,  0.027721 },
+    {  2.732356,  2.248891,  1.483486 },
+    {  2.798089,  2.308929,  1.529034 },
+    {  2.645377,  2.251207,  1.532774 },
+    {  1.609259,  2.461869,  0.761605 },
+    {  1.515557,  2.495474,  0.771124 },
+    {  1.626281,  2.390800,  0.829865 },
+    {  3.034595,  2.376378,  1.030368 },
+    {  3.108631,  2.326860,  1.075828 },
+    {  3.072930,  2.450813,  0.975689 },
+    {  3.001063,  2.956280,  2.449605 },
+    {  2.932654,  2.883470,  2.445274 },
+    {  3.020729,  2.977897,  2.545239 },
+    {  0.973131,  1.398826,  3.027256 },
+    {  1.048479,  1.453925,  3.063128 },
+    {  0.886059,  1.441609,  3.051508 },
+    {  1.075531,  2.444457,  0.635589 },
+    {  1.139902,  2.479480,  0.703631 },
+    {  0.990821,  2.497460,  0.639456 },
+    {  1.866464,  1.096888,  1.554833 },
+    {  1.941039,  1.123887,  1.615740 },
+    {  1.789922,  1.062351,  1.609132 },
+    {  1.591678,  1.105215,  2.043568 },
+    {  1.653395,  1.145689,  1.976092 },
+    {  1.645280,  1.060640,  2.115260 },
+    {  2.619927,  0.227980,  1.174340 },
+    {  2.633047,  0.294780,  1.101090 },
+    {  2.665581,  0.142407,  1.149987 },
+    {  1.916667,  0.415190,  0.590627 },
+    {  1.825708,  0.378396,  0.609931 },
+    {  1.983344,  0.373288,  0.652258 },
+    {  1.200849,  1.841071,  1.389818 },
+    {  1.114525,  1.790768,  1.394038 },
+    {  1.256145,  1.819190,  1.470215 },
+    {  2.221784,  1.766977,  3.004150 },
+    {  2.225336,  1.794523,  3.100216 },
+    {  2.288916,  1.694712,  2.987690 },
+    {  1.120165,  3.008868,  2.322689 },
+    {  1.029789,  3.031427,  2.359063 },
+    {  1.133909,  2.909893,  2.326577 },
+    {  0.405986,  1.997015,  2.356493 },
+    {  0.366114,  1.907130,  2.338302 },
+    {  0.345189,  2.068190,  2.321310 },
+    {  2.326232,  0.162329,  0.556844 },
+    {  2.317494,  0.256924,  0.525610 },
+    {  2.412060,  0.151587,  0.607026 },
+    {  1.349474,  2.909042,  3.002070 },
+    {  1.354029,  2.915883,  3.101732 },
+    {  1.313151,  2.819469,  2.976431 },
+    {  1.677748,  2.890286,  2.981716 },
+    {  1.584536,  2.854118,  2.979874 },
+    {  1.739825,  2.820638,  3.017710 },
+    {  2.146479,  1.045232,  0.950271 },
+    {  2.062776,  1.035080,  1.004035 },
+    {  2.225747,  1.042585,  1.011178 },
+    {  0.038713,  0.203819,  0.461963 },
+    {  0.080467,  0.204316,  0.371099 },
+    {  0.022739,  0.297910,  0.491824 },
+    {  1.344154,  0.934719,  3.048288 },
+    {  1.298501,  0.975815,  3.127199 },
+    {  1.292224,  0.854988,  3.017525 },
+    {  1.876736,  0.670754,  0.506472 },
+    {  1.922832,  0.582605,  0.516712 },
+    {  1.777974,  0.657982,  0.515576 },
+    {  1.547024,  1.257100,  1.494394 },
+    {  1.462871,  1.279845,  1.445394 },
+    {  1.595454,  1.184510,  1.445555 },
+    {  0.837046,  1.662106,  0.882764 },
+    {  0.927946,  1.694579,  0.908893 },
+    {  0.770410,  1.690515,  0.951702 },
+    {  2.905724,  1.433934,  1.956678 },
+    {  2.901017,  1.350620,  1.901572 },
+    {  2.982411,  1.427385,  2.020522 },
+    {  1.082721,  1.574084,  1.538980 },
+    {  1.118780,  1.653944,  1.587168 },
+    {  1.041923,  1.603015,  1.452386 },
+    {  0.973517,  1.950813,  0.715403 },
+    {  0.983211,  2.013477,  0.638077 },
+    {  0.883009,  1.908370,  0.712770 },
+    {  2.047444,  1.846347,  2.788275 },
+    {  2.105859,  1.796484,  2.852317 },
+    {  2.098174,  1.864406,  2.704012 },
+    {  1.472286,  0.407694,  0.463299 },
+    {  1.403985,  0.383358,  0.532166 },
+    {  1.548848,  0.343549,  0.468160 },
+    {  1.523722,  2.012941,  1.058531 },
+    {  1.538378,  2.080087,  1.131171 },
+    {  1.463127,  1.940637,  1.091702 },
+    {  2.094622,  0.765399,  0.870291 },
+    {  2.123104,  0.847060,  0.920494 },
+    {  2.004127,  0.736782,  0.901781 },
+    {  1.360037,  1.461451,  1.615762 },
+    {  1.375715,  1.426828,  1.708258 },
+    {  1.267388,  1.498526,  1.609306 },
+    {  1.754323,  2.881247,  0.755875 },
+    {  1.740556,  2.861699,  0.852975 },
+    {  1.710649,  2.968212,  0.732860 },
+    {  2.597326,  2.339246,  0.463067 },
+    {  2.688913,  2.333021,  0.502729 },
+    {  2.530638,  2.300986,  0.527011 },
+    {  2.404012,  2.888762,  1.379749 },
+    {  2.377619,  2.981254,  1.407111 },
+    {  2.362718,  2.822465,  1.442195 },
+    {  2.682210,  0.752891,  0.246149 },
+    {  2.588032,  0.751670,  0.279748 },
+    {  2.719633,  0.845183,  0.255187 },
+    {  1.147989,  0.504369,  0.806579 },
+    {  1.188565,  0.445977,  0.736266 },
+    {  1.068069,  0.458769,  0.845737 },
+    {  0.882417,  2.859277,  0.450074 },
+    {  0.828696,  2.842740,  0.532782 },
+    {  0.820924,  2.879784,  0.373929 },
+    {  2.310841,  1.485608,  2.189112 },
+    {  2.390981,  1.454864,  2.240419 },
+    {  2.338739,  1.513314,  2.097166 },
+    {  0.048620,  1.439459,  2.985076 },
+    {  0.078551,  1.439376,  2.889661 },
+    {  0.058812,  1.347612,  3.023289 },
+    {  2.685128,  3.096664,  1.076209 },
+    {  2.634155,  3.017488,  1.109867 },
+    {  2.636042,  3.137695,  0.999352 },
+    {  2.955404,  1.555187,  2.648529 },
+    {  2.871594,  1.525579,  2.694345 },
+    {  3.034353,  1.532617,  2.705606 },
+    {  0.064303,  2.480490,  2.970512 },
+    {  0.081989,  2.494919,  3.067872 },
+    { -0.018484,  2.529915,  2.943987 },
+    {  2.482995,  0.044725,  0.867955 },
+    {  2.455494, -0.036642,  0.816739 },
+    {  2.538862,  0.103589,  0.809526 },
+    {  2.017835,  2.999311,  2.452181 },
+    {  2.056715,  2.908900,  2.434452 },
+    {  1.920387,  2.998675,  2.429744 },
+    {  0.869423,  2.167004,  3.082747 },
+    {  0.954671,  2.177259,  3.134008 },
+    {  0.864372,  2.237510,  3.012012 },
+    {  1.589117,  0.399666,  2.413510 },
+    {  1.674099,  0.378754,  2.461891 },
+    {  1.570287,  0.497660,  2.420041 },
+    {  0.440864,  0.611366,  1.385214 },
+    {  0.366708,  0.650546,  1.330755 },
+    {  0.527868,  0.625182,  1.337891 },
+    {  2.713192,  1.529373,  1.085268 },
+    {  2.693629,  1.627372,  1.088945 },
+    {  2.710758,  1.498439,  0.990204 },
+    {  2.066839,  1.149465,  2.402028 },
+    {  1.978751,  1.170214,  2.359483 },
+    {  2.063437,  1.058285,  2.442951 },
+    {  0.718140,  1.556839,  1.676953 },
+    {  0.794749,  1.522176,  1.731078 },
+    {  0.701074,  1.652454,  1.700755 },
+    {  1.851286,  1.748633,  1.205296 },
+    {  1.906319,  1.667628,  1.185058 },
+    {  1.903282,  1.810358,  1.264343 },
+    {  0.690798,  2.820113,  0.892873 },
+    {  0.624258,  2.764246,  0.843363 },
+    {  0.659978,  2.832952,  0.987135 },
+    {  0.700392,  2.971775,  0.643684 },
+    {  0.629248,  2.966450,  0.573611 },
+    {  0.667850,  2.928206,  0.727605 },
+    {  0.224944,  2.412756,  2.411288 },
+    {  0.179940,  2.480028,  2.352558 },
+    {  0.321229,  2.437351,  2.422438 },
+    {  0.931960,  1.088532,  1.085458 },
+    {  0.948257,  1.069581,  1.182284 },
+    {  0.943490,  1.186361,  1.068238 },
+    {  0.665315,  1.482798,  1.205282 },
+    {  0.623395,  1.392477,  1.196078 },
+    {  0.754802,  1.482720,  1.160649 },
+    {  2.090545,  2.389004,  2.282603 },
+    {  2.040173,  2.355573,  2.362259 },
+    {  2.025895,  2.417626,  2.211884 },
+    {  0.586392,  2.277950,  2.330457 },
+    {  0.544270,  2.318000,  2.249084 },
+    {  0.583852,  2.178214,  2.323650 },
+    {  0.397428,  2.598797,  1.378318 },
+    {  0.467494,  2.548450,  1.327762 },
+    {  0.332320,  2.534269,  1.418282 },
+    {  0.769337,  0.909264,  1.677104 },
+    {  0.851592,  0.904461,  1.733770 },
+    {  0.689510,  0.924296,  1.735428 },
+    {  2.809384,  0.362243,  1.792651 },
+    {  2.906450,  0.384960,  1.800543 },
+    {  2.770939,  0.407692,  1.712300 },
+    {  2.165909,  0.965344,  0.397730 },
+    {  2.089549,  0.933174,  0.453714 },
+    {  2.248087,  0.972319,  0.454283 },
+    {  3.029223,  1.963090,  2.255361 },
+    {  3.063521,  2.056860,  2.260912 },
+    {  3.032822,  1.931843,  2.160436 },
+    {  2.290786,  0.279773,  2.425314 },
+    {  2.272727,  0.248542,  2.518580 },
+    {  2.389205,  0.277242,  2.407783 },
+    {  2.887936,  0.900624,  2.678907 },
+    {  2.848443,  0.883810,  2.588588 },
+    {  2.939101,  0.986531,  2.677450 },
+    {  2.724532,  1.007735,  0.316482 },
+    {  2.638163,  1.056986,  0.305776 },
+    {  2.737244,  0.983237,  0.412598 },
+    {  2.046399,  1.071255,  1.952165 },
+    {  2.071263,  1.164937,  1.976772 },
+    {  2.077369,  1.008654,  2.023734 },
+    {  0.170790,  2.227231,  2.943018 },
+    {  0.126575,  2.314910,  2.961923 },
+    {  0.105750,  2.152970,  2.958991 },
+    {  1.361693,  2.771602,  1.982177 },
+    {  1.454761,  2.773405,  1.945637 },
+    {  1.342410,  2.858072,  2.028557 },
+    {  2.982726,  0.757058,  1.738590 },
+    {  3.078254,  0.782233,  1.723078 },
+    {  2.946703,  0.711262,  1.657319 },
+    {  2.418788,  0.252780,  1.386757 },
+    {  2.352642,  0.300740,  1.329098 },
+    {  2.499443,  0.229291,  1.332506 },
+    {  1.608286,  2.595250,  2.794006 },
+    {  1.645863,  2.503744,  2.779360 },
+    {  1.562406,  2.598627,  2.882796 },
+    {  1.508130,  0.999554,  2.425027 },
+    {  1.547857,  0.994937,  2.516681 },
+    {  1.431312,  1.063578,  2.425178 },
+    {  0.403062,  0.456581,  0.079987 },
+    {  0.443234,  0.406243,  0.003487 },
+    {  0.303384,  0.455265,  0.072083 },
+    {  2.772199,  1.911678,  2.353951 },
+    {  2.729955,  1.826940,  2.321781 },
+    {  2.870697,  1.908343,  2.337011 },
+    {  0.267947,  2.608428,  2.130318 },
+    {  0.325039,  2.689867,  2.140717 },
+    {  0.324975,  2.531033,  2.102786 },
+    {  0.271482,  2.897455,  1.935251 },
+    {  0.186640,  2.909345,  1.986831 },
+    {  0.341018,  2.856649,  1.994408 },
+    {  0.420612,  1.093519,  1.906373 },
+    {  0.340253,  1.144399,  1.875491 },
+    {  0.424876,  1.005758,  1.858624 },
+    {  0.317469,  2.961369,  0.908774 },
+    {  0.344220,  2.899485,  0.982631 },
+    {  0.236408,  3.013052,  0.936305 },
+    {  1.331593,  1.232370,  2.476098 },
+    {  1.246807,  1.247953,  2.425416 },
+    {  1.387810,  1.315023,  2.473236 },
+    {  1.653708,  2.990313,  0.221008 },
+    {  1.729954,  2.996775,  0.285388 },
+    {  1.680305,  3.031054,  0.133642 },
+    {  0.590628,  1.387522,  0.466964 },
+    {  0.630802,  1.407555,  0.556321 },
+    {  0.620713,  1.456152,  0.400747 },
+    {  2.905997,  0.221663,  2.459906 },
+    {  2.819336,  0.267701,  2.440662 },
+    {  2.896627,  0.166170,  2.542566 },
+    {  3.093628,  2.977978,  2.705256 },
+    {  3.167925,  3.044386,  2.696902 },
+    {  3.071771,  2.964390,  2.801887 },
+    {  2.165292,  1.291783,  2.041764 },
+    {  2.234435,  1.220242,  2.031709 },
+    {  2.185992,  1.347037,  2.122501 },
+    {  2.252015,  0.402395,  1.221932 },
+    {  2.285112,  0.496702,  1.225218 },
+    {  2.179675,  0.394827,  1.153306 },
+    {  2.104356,  0.137080,  1.189404 },
+    {  2.195319,  0.128762,  1.148705 },
+    {  2.079462,  0.050753,  1.233312 },
+    {  2.148437,  0.707200,  3.015197 },
+    {  2.198806,  0.754869,  3.087243 },
+    {  2.051558,  0.731376,  3.020663 },
+    {  1.850478,  1.598817,  3.013910 },
+    {  1.874091,  1.567314,  3.105834 },
+    {  1.850247,  1.521043,  2.951052 },
+    {  1.984243,  1.101537,  0.205597 },
+    {  2.056039,  1.050969,  0.253432 },
+    {  2.016996,  1.193515,  0.183984 },
+    {  0.819823,  2.184803,  2.627983 },
+    {  0.910067,  2.222214,  2.649346 },
+    {  0.818973,  2.151619,  2.533653 },
+    {  0.680880,  0.100328,  2.990090 },
+    {  0.748260,  0.091873,  2.916685 },
+    {  0.673872,  0.013431,  3.039078 },
+    {  2.347672,  1.066007,  2.070294 },
+    {  2.435627,  1.018893,  2.063654 },
+    {  2.327837,  1.086215,  2.166201 },
+    {  1.111822,  1.814359,  2.252410 },
+    {  1.077790,  1.776269,  2.338381 },
+    {  1.095407,  1.749261,  2.178296 },
+    {  2.873311,  1.875343,  0.918630 },
+    {  2.944104,  1.911954,  0.858231 },
+    {  2.784531,  1.880520,  0.872899 },
+    {  2.101428,  2.550539,  2.746625 },
+    {  2.078013,  2.646820,  2.760104 },
+    {  2.189270,  2.531164,  2.790308 },
+    {  2.827466,  0.083838,  2.684289 },
+    {  2.743385,  0.029836,  2.680525 },
+    {  2.855318,  0.095556,  2.779614 },
+    {  2.643409,  2.459431,  1.183392 },
+    {  2.631575,  2.376139,  1.129333 },
+    {  2.581379,  2.457376,  1.261802 },
+    {  0.210477,  1.616716,  0.215712 },
+    {  0.227327,  1.627602,  0.313679 },
+    {  0.191301,  1.520642,  0.195659 },
+    {  2.595851,  3.085082,  0.245145 },
+    {  2.533216,  3.108680,  0.170849 },
+    {  2.632559,  2.993318,  0.229920 },
+    {  0.948067,  1.831565,  0.021233 },
+    {  0.912134,  1.907261,  0.075814 },
+    {  0.938805,  1.746188,  0.072468 },
+    {  1.953344,  2.247947,  1.017599 },
+    {  1.909073,  2.312925,  0.955810 },
+    {  1.960324,  2.158811,  0.972811 },
+    {  1.222649,  2.766274,  0.625820 },
+    {  1.132619,  2.728772,  0.647918 },
+    {  1.292364,  2.720128,  0.680687 },
+    {  1.697084,  1.491664,  2.240765 },
+    {  1.608414,  1.453049,  2.215338 },
+    {  1.683516,  1.566071,  2.306182 },
+    {  1.267412,  1.311498,  2.741722 },
+    {  1.282870,  1.251771,  2.663022 },
+    {  1.169226,  1.326331,  2.753535 },
+    {  0.703434,  0.631065,  1.342521 },
+    {  0.757236,  0.648969,  1.424891 },
+    {  0.755720,  0.658720,  1.261889 },
+    {  0.536418,  0.871703,  1.821272 },
+    {  0.506921,  0.828597,  1.906547 },
+    {  0.501439,  0.819320,  1.743603 },
+    {  2.033586,  1.894688,  1.361921 },
+    {  2.053905,  1.813031,  1.415951 },
+    {  2.102318,  1.964908,  1.380502 },
+    {  1.353145,  0.749155,  2.700183 },
+    {  1.340584,  0.768015,  2.602784 },
+    {  1.423395,  0.809983,  2.737126 },
+    {  1.757646,  3.040187,  1.185496 },
+    {  1.805834,  2.953766,  1.199967 },
+    {  1.789142,  3.082058,  1.100321 },
+    {  2.692199,  2.835351,  0.825364 },
+    {  2.663609,  2.776601,  0.901068 },
+    {  2.611627,  2.876881,  0.783133 },
+    {  2.753498,  2.840923,  0.324355 },
+    {  2.736860,  2.782748,  0.244738 },
+    {  2.680602,  2.827267,  0.391435 },
+    {  0.196329,  2.621545,  2.569990 },
+    {  0.219355,  2.524588,  2.578307 },
+    {  0.108105,  2.638733,  2.613821 },
+    {  2.345007,  1.825788,  1.374116 },
+    {  2.272672,  1.793851,  1.435333 },
+    {  2.379912,  1.913637,  1.406738 },
+    {  0.596710,  0.509863,  2.871939 },
+    {  0.526640,  0.561688,  2.822905 },
+    {  0.556514,  0.426024,  2.908751 },
+    {  2.937274,  0.823236,  1.996167 },
+    {  2.937670,  0.813596,  1.896634 },
+    {  2.911096,  0.736251,  2.037979 },
+    {  0.579374,  1.320692,  0.011389 },
+    {  0.634136,  1.240102,  0.033891 },
+    {  0.484056,  1.293558, -0.001960 },
+    {  2.278243,  2.412097,  0.787639 },
+    {  2.368768,  2.449098,  0.808522 },
+    {  2.240378,  2.368551,  0.869309 },
+    {  0.391627,  1.711143,  0.025375 },
+    {  0.332230,  1.678111,  0.098730 },
+    {  0.390472,  1.645887, -0.050389 },
+    {  0.153753,  2.467941,  1.820145 },
+    {  0.065625,  2.429276,  1.792973 },
+    {  0.150971,  2.567416,  1.810297 },
+    {  2.843451,  0.422126,  2.906952 },
+    {  2.775335,  0.354829,  2.935786 },
+    {  2.799691,  0.511419,  2.896375 },
+    {  1.970457,  1.649264,  2.404565 },
+    {  2.013029,  1.699928,  2.329594 },
+    {  1.985128,  1.551262,  2.391131 },
+    {  1.342607,  1.643091,  2.334386 },
+    {  1.344545,  1.563513,  2.394914 },
+    {  1.248079,  1.673291,  2.322043 },
+    {  0.748739,  1.133236,  0.071356 },
+    {  0.842917,  1.127034,  0.038310 },
+    {  0.747734,  1.124634,  0.170981 },
+    {  1.378131,  1.410352,  1.877753 },
+    {  1.319542,  1.407747,  1.958750 },
+    {  1.424860,  1.322530,  1.867574 },
+    {  2.379939,  1.693036,  0.436722 },
+    {  2.413363,  1.778852,  0.475690 },
+    {  2.340060,  1.636823,  0.509177 },
+    {  0.560335,  1.301357,  2.831908 },
+    {  0.656147,  1.325504,  2.816512 },
+    {  0.537359,  1.315835,  2.928149 },
+    {  2.308699,  2.450235,  2.131759 },
+    {  2.320931,  2.549287,  2.125504 },
+    {  2.229118,  2.430013,  2.188837 },
+    {  1.398964,  0.129485,  0.101708 },
+    {  1.406581,  0.030972,  0.117107 },
+    {  1.430994,  0.151393,  0.009545 },
+    {  2.738661,  1.810796,  1.150217 },
+    {  2.785875,  1.826236,  1.063428 },
+    {  2.803245,  1.821952,  1.225745 },
+    {  1.834855,  1.243843,  2.347878 },
+    {  1.784425,  1.296402,  2.279364 },
+    {  1.812100,  1.277635,  2.439203 },
+    {  2.675870,  1.821318,  0.707845 },
+    {  2.624071,  1.899672,  0.742160 },
+    {  2.626939,  1.736877,  0.729653 },
+    {  2.769887,  2.202680,  2.007300 },
+    {  2.822160,  2.284730,  2.030436 },
+    {  2.675095,  2.214055,  2.037049 },
+    {  1.998308,  2.423041,  0.279446 },
+    {  1.928540,  2.367313,  0.234427 },
+    {  2.088992,  2.387066,  0.257485 },
+    {  2.612892,  0.331665,  0.870959 },
+    {  2.614312,  0.422865,  0.911954 },
+    {  2.693229,  0.320122,  0.812541 },
+    {  1.438447,  2.473494,  1.915666 },
+    {  1.459389,  2.449059,  2.010347 },
+    {  1.449352,  2.572151,  1.903508 },
+    {  0.869607,  0.994845,  2.380191 },
+    {  0.960289,  0.969060,  2.413537 },
+    {  0.816006,  0.912361,  2.362208 },
+    {  2.262026,  1.572083,  0.674023 },
+    {  2.207234,  1.647739,  0.709715 },
+    {  2.201615,  1.503071,  0.634175 },
+    {  0.029213,  2.539434,  2.193714 },
+    {  0.114704,  2.573874,  2.154917 },
+    { -0.041214,  2.610128,  2.187201 },
+    {  2.804363,  0.979878,  0.585511 },
+    {  2.878881,  1.037113,  0.551286 },
+    {  2.815526,  0.886603,  0.551230 },
+    {  1.145669,  0.191337,  1.809638 },
+    {  1.136214,  0.202391,  1.710702 },
+    {  1.055125,  0.181165,  1.850847 },
+    {  1.799933,  2.204886,  1.265283 },
+    {  1.721729,  2.267174,  1.263213 },
+    {  1.858550,  2.222334,  1.186166 },
+    {  2.768473,  1.887750,  2.008596 },
+    {  2.685808,  1.884735,  1.952404 },
+    {  2.781906,  1.980614,  2.043174 },
+    {  0.566042,  0.942291,  2.780672 },
+    {  0.542564,  1.003858,  2.705451 },
+    {  0.618895,  0.865111,  2.745320 },
+    {  1.440484,  2.308258,  0.440554 },
+    {  1.345608,  2.311138,  0.409085 },
+    {  1.451129,  2.234898,  0.507674 },
+    {  2.099174,  2.113051,  2.937382 },
+    {  2.064708,  2.019650,  2.927986 },
+    {  2.084658,  2.162707,  2.851804 },
+    {  0.640344,  1.990762,  1.382271 },
+    {  0.613247,  2.082472,  1.353029 },
+    {  0.567632,  1.925826,  1.359992 },
+    {  1.005877,  1.535225,  0.537525 },
+    {  1.087595,  1.584022,  0.506849 },
+    {  1.032672,  1.459432,  0.597003 },
+    {  1.001243,  2.787001,  1.696773 },
+    {  0.992437,  2.688644,  1.712534 },
+    {  0.910309,  2.828442,  1.693079 },
+    {  0.987802,  1.110389,  3.055721 },
+    {  1.065605,  1.081580,  3.111549 },
+    {  0.999141,  1.206273,  3.029689 },
+    {  0.559374,  1.591763,  1.450101 },
+    {  0.607457,  1.568462,  1.534631 },
+    {  0.618799,  1.573391,  1.371800 },
+    {  1.478474,  0.101704,  1.588815 },
+    {  1.486885,  0.115724,  1.687469 },
+    {  1.567854,  0.077935,  1.550783 },
+    {  1.197401,  2.030470,  2.891763 },
+    {  1.204490,  2.130070,  2.886325 },
+    {  1.101431,  2.004405,  2.902264 },
+    {  2.593369,  2.916082,  3.009380 },
+    {  2.501069,  2.936721,  2.976903 },
+    {  2.647562,  2.878580,  2.934170 },
+    {  1.874216,  0.910326,  1.799684 },
+    {  1.928068,  0.986814,  1.835033 },
+    {  1.784798,  0.943563,  1.769689 },
+    {  1.120926,  0.186051,  2.975514 },
+    {  1.169400,  0.130500,  2.907954 },
+    {  1.157365,  0.279169,  2.974435 },
+    {  1.743099,  0.329782,  2.034890 },
+    {  1.692066,  0.296574,  2.114217 },
+    {  1.836555,  0.294352,  2.038158 },
+    {  1.657390,  1.879589,  1.841187 },
+    {  1.717444,  1.958116,  1.826119 },
+    {  1.702586,  1.796398,  1.808989 },
+    {  1.300228,  2.270635,  0.841357 },
+    {  1.295869,  2.196579,  0.908414 },
+    {  1.228832,  2.337792,  0.861172 },
+    {  1.948942,  0.107632,  2.195505 },
+    {  1.962856,  0.009021,  2.186429 },
+    {  1.980313,  0.153514,  2.112374 },
+    {  0.592938,  2.832478,  1.152267 },
+    {  0.595325,  2.932350,  1.156722 },
+    {  0.497900,  2.801368,  1.152355 },
+    {  3.028118,  1.151776,  1.025723 },
+    {  3.094740,  1.221061,  1.053310 },
+    {  2.957975,  1.193980,  0.968288 },
+    {  1.833976,  0.982234,  0.013196 },
+    {  1.883561,  1.039306,  0.078648 },
+    {  1.885634,  0.976953, -0.072265 },
+    {  1.798332,  1.244152,  1.851843 },
+    {  1.884876,  1.234745,  1.802633 },
+    {  1.723244,  1.251207,  1.786177 },
+    {  2.873589,  1.201986,  1.817110 },
+    {  2.927328,  1.201648,  1.732778 },
+    {  2.906900,  1.130124,  1.878153 },
+    {  0.577414,  0.140788,  1.536999 },
+    {  0.611632,  0.171898,  1.625663 },
+    {  0.652564,  0.138931,  1.471052 },
+    {  0.479143,  3.039990,  0.297688 },
+    {  0.403226,  3.001126,  0.245475 },
+    {  0.521000,  2.968592,  0.353815 },
+    {  2.581915,  1.009475,  0.768424 },
+    {  2.672051,  0.990541,  0.729474 },
+    {  2.554187,  0.933238,  0.826898 },
+    {  2.285805,  1.798154,  0.177273 },
+    {  2.371693,  1.842169,  0.151083 },
+    {  2.293527,  1.762829,  0.270507 },
+    {  0.216147,  3.103959,  2.689932 },
+    {  0.206578,  3.176040,  2.621282 },
+    {  0.297853,  3.049780,  2.670213 },
+    {  0.686871,  1.890136,  2.775596 },
+    {  0.662080,  1.936036,  2.860911 },
+    {  0.605159,  1.878210,  2.719196 },
+    {  1.069007,  2.995313,  3.029030 },
+    {  1.073078,  3.066635,  3.099005 },
+    {  1.160823,  2.978560,  2.993125 },
+    {  2.694476,  1.837937,  0.085521 },
+    {  2.644472,  1.755175,  0.111019 },
+    {  2.791382,  1.826384,  0.107334 },
+    {  1.563852,  0.853418,  2.911395 },
+    {  1.602637,  0.770872,  2.952407 },
+    {  1.488071,  0.886218,  2.967798 },
+    {  0.460347,  2.801415,  2.155280 },
+    {  0.542405,  2.813267,  2.099369 },
+    {  0.486605,  2.790770,  2.251182 },
+    {  1.067116,  0.828584,  1.118327 },
+    {  1.017197,  0.895557,  1.063347 },
+    {  1.147577,  0.797335,  1.067835 },
+    {  2.248599,  1.379134,  0.873790 },
+    {  2.293116,  1.393911,  0.785473 },
+    {  2.293247,  1.303346,  0.921359 },
+    {  0.023727,  1.461944,  2.107485 },
+    {  0.039466,  1.452465,  2.205783 },
+    {  0.056943,  1.551156,  2.076858 },
+    {  0.890338,  1.285968,  0.873042 },
+    {  0.805316,  1.245775,  0.839044 },
+    {  0.933413,  1.339340,  0.800269 },
+    {  2.648945,  1.437668,  0.287452 },
+    {  2.699407,  1.401270,  0.209165 },
+    {  2.675734,  1.388361,  0.370224 },
+    {  0.390508,  3.056364,  2.334304 },
+    {  0.374435,  3.116324,  2.255905 },
+    {  0.317691,  2.988021,  2.339484 },
+    {  2.941599,  2.289971,  2.678662 },
+    {  3.039241,  2.269131,  2.673033 },
+    {  2.912219,  2.286466,  2.774185 },
+    {  1.199353,  2.918159,  1.497088 },
+    {  1.269711,  2.966859,  1.548839 },
+    {  1.118937,  2.904431,  1.554922 },
+    {  2.948856,  0.470312,  1.096935 },
+    {  2.985099,  0.380752,  1.071136 },
+    {  3.024561,  0.531828,  1.118947 },
+    {  2.489230,  1.274888,  2.457981 },
+    {  2.575071,  1.260972,  2.408608 },
+    {  2.489590,  1.220024,  2.541587 },
+    {  1.644334,  1.202727,  0.331251 },
+    {  1.631770,  1.123611,  0.271394 },
+    {  1.635932,  1.174006,  0.426668 },
+    {  0.669309,  2.003121,  2.315451 },
+    {  0.730467,  1.954706,  2.378027 },
+    {  0.574977,  1.974480,  2.332215 },
+    {  2.284317,  1.482399,  1.602583 },
+    {  2.203780,  1.434499,  1.567663 },
+    {  2.260654,  1.530045,  1.687259 },
+    {  0.527517,  2.701255,  2.395590 },
+    {  0.572355,  2.743476,  2.474374 },
+    {  0.501162,  2.607549,  2.418497 },
+    {  2.691990,  1.782137,  1.668582 },
+    {  2.622890,  1.751930,  1.602910 },
+    {  2.728574,  1.870738,  1.640094 },
+    {  1.221627,  1.403014,  2.134535 },
+    {  1.177639,  1.339731,  2.198256 },
+    {  1.151914,  1.458799,  2.089499 },
+    {  1.276239,  1.209683,  0.830184 },
+    {  1.274310,  1.109869,  0.824392 },
+    {  1.270617,  1.237626,  0.926036 },
+    {  0.816251,  2.909087,  3.046489 },
+    {  0.901923,  2.953749,  3.020687 },
+    {  0.771765,  2.961669,  3.118989 },
+    {  0.533906,  1.223529,  1.303916 },
+    {  0.569896,  1.156711,  1.238800 },
+    {  0.578958,  1.211478,  1.392376 },
+    {  1.683346,  2.144673,  2.139148 },
+    {  1.741238,  2.072530,  2.177146 },
+    {  1.613641,  2.103882,  2.080179 },
+    {  2.875850,  0.044009,  1.250278 },
+    {  2.911148, -0.036725,  1.297565 },
+    {  2.805482,  0.016229,  1.184882 },
+    {  1.784021,  0.926724,  0.326634 },
+    {  1.855064,  0.984494,  0.286440 },
+    {  1.826414,  0.857633,  0.385195 },
+    {  1.704426,  1.630143,  0.792940 },
+    {  1.672037,  1.613072,  0.699884 },
+    {  1.668404,  1.559794,  0.854205 },
+    {  0.766134,  2.421196,  2.059355 },
+    {  0.809315,  2.345348,  2.108166 },
+    {  0.752692,  2.497881,  2.122115 },
+    {  0.871077,  2.182524,  2.154052 },
+    {  0.810919,  2.153015,  2.228283 },
+    {  0.962738,  2.145297,  2.168630 },
+    {  1.865873,  1.349151,  0.032304 },
+    {  1.827492,  1.323421, -0.056380 },
+    {  1.964725,  1.334066,  0.031487 },
+    {  2.222735,  1.008374,  1.670202 },
+    {  2.286023,  1.057572,  1.610417 },
+    {  2.274593,  0.951644,  1.734173 },
+    {  1.293692,  2.083151,  1.808644 },
+    {  1.358039,  2.082571,  1.885189 },
+    {  1.324981,  2.019323,  1.738309 },
+    {  2.875127,  0.361920,  0.728630 },
+    {  2.927991,  0.446531,  0.735430 },
+    {  2.818555,  0.364492,  0.646210 },
+    {  0.560226,  1.918473,  2.025234 },
+    {  0.614082,  1.999690,  2.002796 },
+    {  0.606294,  1.866823,  2.097414 },
+    {  0.116601,  2.287058,  2.040205 },
+    {  0.135431,  2.341154,  1.958235 },
+    {  0.072215,  2.344766,  2.108759 },
+    {  1.731207,  1.627822,  1.774748 },
+    {  1.743176,  1.560404,  1.701867 },
+    {  1.758793,  1.587726,  1.862106 },
+    {  2.955634,  2.730964,  0.905002 },
+    {  2.874554,  2.771880,  0.863146 },
+    {  2.949333,  2.738789,  1.004496 },
+    {  1.501594,  2.091653,  1.371834 },
+    {  1.538751,  2.009640,  1.415345 },
+    {  1.538425,  2.172932,  1.416971 },
+    {  2.833318,  2.065374,  0.326849 },
+    {  2.735733,  2.046780,  0.338315 },
+    {  2.849821,  2.101427,  0.235046 },
+    {  1.050436,  1.606848,  2.061210 },
+    {  1.034856,  1.671504,  1.986532 },
+    {  0.963136,  1.567431,  2.089933 },
+    {  2.852918,  2.103729,  1.290104 },
+    {  2.826100,  2.168810,  1.361134 },
+    {  2.787516,  2.107990,  1.214576 },
+    {  2.693916,  0.326078,  2.033253 },
+    {  2.731292,  0.332854,  1.940748 },
+    {  2.723277,  0.240009,  2.074847 },
+    {  0.212220,  0.175849,  2.885870 },
+    {  0.212176,  0.100251,  2.820410 },
+    {  0.153710,  0.152683,  2.963587 },
+    {  1.629055,  0.636815,  1.189020 },
+    {  1.552820,  0.586142,  1.148765 },
+    {  1.622687,  0.632959,  1.288743 },
+    {  1.339579,  0.227037,  2.582705 },
+    {  1.429690,  0.183681,  2.583158 },
+    {  1.350244,  0.326169,  2.590398 },
+    {  0.877764,  3.073416,  2.428342 },
+    {  0.876731,  3.168795,  2.458370 },
+    {  0.830020,  3.065500,  2.340833 },
+    {  0.012970,  1.608793,  1.734893 },
+    { -0.086547,  1.600180,  1.730197 },
+    {  0.041121,  1.618498,  1.830357 },
+    {  2.089223,  2.356806,  3.093349 },
+    {  2.080570,  2.263474,  3.058502 },
+    {  2.007413,  2.409067,  3.069351 },
+    {  2.470659,  0.854329,  2.975580 },
+    {  2.544938,  0.892503,  2.920576 },
+    {  2.460200,  0.907998,  3.059307 },
+    {  2.511084,  0.660490,  1.700075 },
+    {  2.478100,  0.600190,  1.627439 },
+    {  2.435588,  0.717009,  1.733330 },
+    {  3.043270,  2.024359,  0.777765 },
+    {  3.006095,  2.041482,  0.686524 },
+    {  3.131200,  2.071035,  0.787233 },
+    {  2.406380,  2.833836,  2.437090 },
+    {  2.498902,  2.800394,  2.455016 },
+    {  2.410718,  2.912515,  2.375521 },
+    {  2.734020,  1.466940,  2.755877 },
+    {  2.700045,  1.377356,  2.784519 },
+    {  2.659075,  1.519847,  2.716075 },
+    {  0.855259,  2.409014,  2.948572 },
+    {  0.811121,  2.434356,  2.862493 },
+    {  0.919369,  2.480852,  2.975574 },
+    {  1.958775,  1.734897,  2.027947 },
+    {  1.918280,  1.644707,  2.012915 },
+    {  2.045688,  1.724766,  2.076356 },
+    {  2.982304,  2.766292,  2.104076 },
+    {  3.060064,  2.827760,  2.117309 },
+    {  2.923938,  2.801635,  2.030972 },
+    {  0.495257,  2.600207,  0.002865 },
+    {  0.574514,  2.584488,  0.061783 },
+    {  0.523212,  2.594076, -0.092952 },
+    {  0.620427,  1.316333,  1.773186 },
+    {  0.550082,  1.344964,  1.838239 },
+    {  0.654246,  1.396176,  1.723373 },
+    {  1.851595,  2.477959,  3.036031 },
+    {  1.794908,  2.470350,  2.954003 },
+    {  1.842133,  2.569694,  3.074699 },
+    {  2.162743,  1.730778,  1.542545 },
+    {  2.114802,  1.643183,  1.547900 },
+    {  2.217777,  1.743755,  1.625025 },
+    {  2.529501,  2.719916,  1.696654 },
+    {  2.503803,  2.782004,  1.770713 },
+    {  2.570790,  2.637380,  1.735165 },
+    {  2.307523,  3.038538,  0.375298 },
+    {  2.404434,  3.016431,  0.364365 },
+    {  2.297896,  3.116554,  0.437110 },
+    {  2.247696,  2.677393,  1.478840 },
+    {  2.181267,  2.606604,  1.454839 },
+    {  2.208496,  2.737719,  1.548296 },
+    {  2.405993,  0.100579,  0.117782 },
+    {  2.319176,  0.078530,  0.162242 },
+    {  2.399747,  0.190952,  0.075429 },
+    {  2.845756,  2.478670,  2.035563 },
+    {  2.813879,  2.492950,  2.129265 },
+    {  2.929733,  2.530863,  2.020603 },
+    {  2.412509,  2.437882,  2.677793 },
+    {  2.409318,  2.340578,  2.654949 },
+    {  2.447902,  2.449183,  2.770635 },
+    {  2.743492,  0.946496,  2.446978 },
+    {  2.763913,  0.946953,  2.349087 },
+    {  2.644497,  0.941931,  2.460358 },
+    {  0.252801,  2.064296,  2.729654 },
+    {  0.205969,  2.116614,  2.658453 },
+    {  0.233709,  2.105034,  2.818962 },
+    {  3.063191,  1.922158,  1.214172 },
+    {  2.986959,  1.986712,  1.218799 },
+    {  3.100113,  1.907543,  1.305950 },
+    {  2.880231,  3.025379,  0.083855 },
+    {  2.795332,  3.002985,  0.131716 },
+    {  2.945707,  3.064380,  0.148600 },
+    {  2.779395,  1.653453,  2.946437 },
+    {  2.784444,  1.581315,  2.877367 },
+    {  2.816726,  1.619581,  3.032803 },
+    {  2.054265,  0.038926,  0.074381 },
+    {  2.065626, -0.041658,  0.132494 },
+    {  2.100034,  0.023588, -0.013197 },
+    {  2.355414,  2.720144,  2.698744 },
+    {  2.344450,  2.753016,  2.604939 },
+    {  2.357313,  2.620162,  2.699021 },
+    {  0.361217,  2.018670,  0.301548 },
+    {  0.303415,  2.006261,  0.220894 },
+    {  0.429552,  2.089293,  0.283039 },
+    {  0.332342,  0.090876,  2.109455 },
+    {  0.263449,  0.156985,  2.139177 },
+    {  0.390810,  0.132649,  2.039909 },
+    {  3.034524,  0.068387,  2.292232 },
+    {  2.993148,  0.137518,  2.351469 },
+    {  3.043613, -0.017534,  2.342580 },
+    {  0.237543,  0.583210,  1.838098 },
+    {  0.311681,  0.597860,  1.772608 },
+    {  0.276038,  0.559019,  1.927165 },
+    {  2.503589,  2.263025,  2.095976 },
+    {  2.420729,  2.315682,  2.114991 },
+    {  2.540302,  2.226586,  2.181559 },
+    {  2.262877,  2.698771,  2.033787 },
+    {  2.333674,  2.768746,  2.024233 },
+    {  2.248342,  2.653808,  1.945656 },
+    {  0.964111,  2.685023,  2.452276 },
+    {  0.990834,  2.666914,  2.546923 },
+    {  1.040843,  2.726435,  2.403315 },
+    {  0.794322,  2.734946,  2.845067 },
+    {  0.803437,  2.799933,  2.920523 },
+    {  0.710474,  2.681741,  2.856841 },
+    {  2.896233,  2.435937,  1.571472 },
+    {  2.949992,  2.393141,  1.644124 },
+    {  2.879950,  2.531950,  1.594195 },
+    {  0.707918,  0.439981,  1.637015 },
+    {  0.805572,  0.456561,  1.650751 },
+    {  0.687875,  0.438135,  1.539061 },
+    {  2.429562,  2.935991,  0.705919 },
+    {  2.331154,  2.931808,  0.723196 },
+    {  2.451272,  2.883147,  0.623845 },
+    {  0.890410,  0.316803,  3.083332 },
+    {  0.973293,  0.305226,  3.028592 },
+    {  0.829674,  0.238704,  3.068783 },
+    {  0.544859,  2.440687,  1.202416 },
+    {  0.638042,  2.463712,  1.174367 },
+    {  0.480239,  2.473483,  1.133506 },
+    {  2.821353,  0.977632,  2.194345 },
+    {  2.890551,  1.047090,  2.214022 },
+    {  2.854392,  0.917286,  2.121772 },
+    {  0.710748,  1.170876,  2.004677 },
+    {  0.643095,  1.116736,  1.954758 },
+    {  0.730699,  1.254545,  1.953672 },
+    {  1.323921,  1.479145,  0.621735 },
+    {  1.286777,  1.537103,  0.549201 },
+    {  1.253285,  1.415737,  0.653197 },
+    {  2.698551,  2.717451,  0.063376 },
+    {  2.639217,  2.637232,  0.056723 },
+    {  2.661341,  2.791201,  0.007017 },
+    {  0.840228,  1.225083,  2.251827 },
+    {  0.854567,  1.147753,  2.313588 },
+    {  0.765601,  1.203942,  2.188709 },
+    {  1.592481,  1.743693,  1.226737 },
+    {  1.565173,  1.689101,  1.305946 },
+    {  1.691904,  1.754410,  1.226317 },
+    {  1.258602,  2.759789,  1.297767 },
+    {  1.231534,  2.833672,  1.359482 },
+    {  1.236972,  2.671656,  1.339776 },
+    {  1.283405,  3.025043,  1.772125 },
+    {  1.383297,  3.021171,  1.774669 },
+    {  1.252723,  3.114943,  1.803376 },
+    {  2.541767,  1.632310,  0.149237 },
+    {  2.449338,  1.608351,  0.119526 },
+    {  2.572917,  1.566396,  0.217683 },
+    {  1.328386,  0.424321,  1.433167 },
+    {  1.399835,  0.355967,  1.418246 },
+    {  1.300864,  0.463486,  1.345368 },
+    {  0.236768,  0.950959,  2.590976 },
+    {  0.330331,  0.962132,  2.557492 },
+    {  0.238410,  0.905038,  2.679794 },
+    {  0.313513,  2.796867,  3.012214 },
+    {  0.323708,  2.795983,  2.912740 },
+    {  0.375929,  2.730056,  3.052716 },
+    {  0.112414,  2.245971,  0.123348 },
+    {  0.177492,  2.170582,  0.114330 },
+    {  0.162248,  2.331534,  0.137334 },
+    {  2.701271,  2.514977,  2.263225 },
+    {  2.611569,  2.555932,  2.279852 },
+    {  2.714556,  2.437557,  2.325108 },
+    {  1.770655,  0.024603,  2.384955 },
+    {  1.699905,  0.005690,  2.316861 },
+    {  1.847949,  0.070276,  2.340914 },
+    {  0.009882,  1.194905,  1.519823 },
+    { -0.077604,  1.217861,  1.477170 },
+    {  0.058135,  1.279012,  1.544271 },
+    {  2.362329,  1.189368,  1.500885 },
+    {  2.448073,  1.222733,  1.461709 },
+    {  2.288210,  1.252204,  1.477265 },
+    {  1.943393,  1.163287,  1.318490 },
+    {  1.904684,  1.254202,  1.303121 },
+    {  1.923693,  1.134053,  1.412070 },
+    {  0.095808,  0.472131,  0.518367 },
+    {  0.157246,  0.463382,  0.596782 },
+    {  0.143525,  0.518364,  0.443630 },
+    {  0.157283,  0.392476,  2.732502 },
+    {  0.071212,  0.434916,  2.760620 },
+    {  0.167245,  0.303987,  2.778005 },
+    {  2.308432,  0.518593,  0.204206 },
+    {  2.407431,  0.531838,  0.199337 },
+    {  2.285893,  0.425193,  0.176483 },
+    {  0.944487,  0.067090,  1.962743 },
+    {  0.979830, -0.021319,  1.932171 },
+    {  0.921300,  0.061935,  2.059881 },
+    {  0.672079,  1.749103,  0.099972 },
+    {  0.679855,  1.844222,  0.129836 },
+    {  0.575510,  1.724947,  0.090434 },
+    {  1.825839,  0.707532,  0.059138 },
+    {  1.820204,  0.806882,  0.049239 },
+    {  1.897469,  0.684609,  0.125044 },
+    {  2.985048,  1.441246,  0.798920 },
+    {  3.015628,  1.520955,  0.850991 },
+    {  2.984317,  1.463406,  0.701409 },
+    {  2.308448,  2.258307,  1.299501 },
+    {  2.290653,  2.254337,  1.201177 },
+    {  2.344603,  2.348475,  1.323219 }
+};
diff --git a/src/gromacs/nbnxm/benchmark/bench_setup.cpp b/src/gromacs/nbnxm/benchmark/bench_setup.cpp
new file mode 100644 (file)
index 0000000..c3cb64d
--- /dev/null
@@ -0,0 +1,448 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \internal \file
+ * \brief
+ * This file defines functions for setting up kernel benchmarks
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \ingroup module_nbnxm
+ */
+
+#include "gmxpre.h"
+
+#include "bench_setup.h"
+
+#include "gromacs/compat/optional.h"
+#include "gromacs/gmxlib/nrnb.h"
+#include "gromacs/mdlib/dispersioncorrection.h"
+#include "gromacs/mdlib/force_flags.h"
+#include "gromacs/mdlib/forcerec.h"
+#include "gromacs/mdlib/gmx_omp_nthreads.h"
+#include "gromacs/mdtypes/enerdata.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/mdtypes/interaction_const.h"
+#include "gromacs/mdtypes/mdatom.h"
+#include "gromacs/nbnxm/atomdata.h"
+#include "gromacs/nbnxm/gridset.h"
+#include "gromacs/nbnxm/nbnxm.h"
+#include "gromacs/nbnxm/nbnxm_simd.h"
+#include "gromacs/nbnxm/pairlistset.h"
+#include "gromacs/nbnxm/pairlistsets.h"
+#include "gromacs/nbnxm/pairsearch.h"
+#include "gromacs/pbcutil/ishift.h"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/simd/simd.h"
+#include "gromacs/timing/cyclecounter.h"
+#include "gromacs/utility/enumerationhelpers.h"
+#include "gromacs/utility/fatalerror.h"
+#include "gromacs/utility/logger.h"
+
+#include "bench_system.h"
+
+namespace Nbnxm
+{
+
+/*! \brief Checks the kernel setup
+ *
+ * Returns an error string when the kernel is not available.
+ */
+static gmx::compat::optional<std::string> checkKernelSetup(const KernelBenchOptions &options)
+{
+    GMX_RELEASE_ASSERT(options.nbnxmSimd < BenchMarkKernels::Count &&
+                       options.nbnxmSimd != BenchMarkKernels::SimdAuto, "Need a valid kernel SIMD type");
+
+    // Check SIMD support
+    if ((options.nbnxmSimd != BenchMarkKernels::SimdNo && !GMX_SIMD)
+#ifndef GMX_NBNXN_SIMD_4XN
+        || options.nbnxmSimd == BenchMarkKernels::Simd4XM
+#endif
+#ifndef GMX_NBNXN_SIMD_2XNN
+        || options.nbnxmSimd == BenchMarkKernels::Simd2XMM
+#endif
+        )
+    {
+        return "the requested SIMD kernel was not set up at configuration time";
+    }
+
+    return {};
+}
+
+//! Helper to translate between the different enumeration values.
+static KernelType translateBenchmarkEnum(const BenchMarkKernels &kernel)
+{
+    int kernelInt = static_cast<int>(kernel);
+    return static_cast<KernelType>(kernelInt);
+}
+
+/*! \brief Returns the kernel setup
+ */
+static KernelSetup getKernelSetup(const KernelBenchOptions &options)
+{
+    auto messageWhenInvalid = checkKernelSetup(options);
+    GMX_RELEASE_ASSERT(!messageWhenInvalid, "Need valid options");
+
+    KernelSetup kernelSetup;
+
+    //The int enum options.nbnxnSimd is set up to match KernelType + 1
+    kernelSetup.kernelType         = translateBenchmarkEnum(options.nbnxmSimd);
+    // The plain-C kernel does not support analytical ewald correction
+    if (kernelSetup.kernelType == KernelType::Cpu4x4_PlainC)
+    {
+        kernelSetup.ewaldExclusionType = EwaldExclusionType::Table;
+    }
+    else
+    {
+        kernelSetup.ewaldExclusionType = options.useTabulatedEwaldCorr ? EwaldExclusionType::Table : EwaldExclusionType::Analytical;
+    }
+
+    return kernelSetup;
+}
+
+//! Return an interaction constants struct with members used in the benchmark set appropriately
+static interaction_const_t setupInteractionConst(const KernelBenchOptions &options)
+
+{
+    interaction_const_t ic;
+
+    ic.vdwtype          = evdwCUT;
+    ic.vdw_modifier     = eintmodPOTSHIFT;
+    ic.rvdw             = options.pairlistCutoff;
+
+    ic.eeltype          = (options.coulombType == BenchMarkCoulomb::Pme ? eelPME : eelRF);
+    ic.coulomb_modifier = eintmodPOTSHIFT;
+    ic.rcoulomb         = options.pairlistCutoff;
+
+    // Reaction-field with epsilon_rf=inf
+    // TODO: Replace by calc_rffac() after refactoring that
+    ic.k_rf             = 0.5*std::pow(ic.rcoulomb, -3);
+    ic.c_rf             = 1/ic.rcoulomb + ic.k_rf*ic.rcoulomb*ic.rcoulomb;
+
+    if (EEL_PME_EWALD(ic.eeltype))
+    {
+        // Ewald coefficients, we ignore the potential shift
+        GMX_RELEASE_ASSERT(options.ewaldcoeff_q > 0, "Ewald coefficient should be > 0");
+        ic.ewaldcoeff_q       = options.ewaldcoeff_q;
+        ic.coulombEwaldTables = std::make_unique<EwaldCorrectionTables>();
+        init_interaction_const_tables(nullptr, &ic);
+    }
+
+    return ic;
+}
+
+//! Sets up and returns a Nbnxm object for the given benchmark options and system
+static std::unique_ptr<nonbonded_verlet_t>
+setupNbnxmForBenchInstance(const KernelBenchOptions   &options,
+                           const gmx::BenchmarkSystem &system)
+{
+    const auto         pinPolicy       = (options.useGpu ? gmx::PinningPolicy::PinnedIfSupported : gmx::PinningPolicy::CannotBePinned);
+    const int          numThreads      = options.numThreads;
+    // Note: the options and Nbnxm combination rule enums values should match
+    const int          combinationRule = static_cast<int>(options.ljCombinationRule);
+
+    auto               messageWhenInvalid = checkKernelSetup(options);
+    if (messageWhenInvalid)
+    {
+        gmx_fatal(FARGS, "Requested kernel is unavailable because %s.",
+                  messageWhenInvalid->c_str());
+    }
+    Nbnxm::KernelSetup kernelSetup = getKernelSetup(options);
+
+    PairlistParams     pairlistParams(kernelSetup.kernelType, false, options.pairlistCutoff, false);
+
+    GridSet            gridSet(epbcXYZ, nullptr, nullptr, pairlistParams.pairlistType, false, numThreads, pinPolicy);
+
+    auto               pairlistSets = std::make_unique<PairlistSets>(pairlistParams, false, 0);
+
+    auto               pairSearch   = std::make_unique<PairSearch>(epbcXYZ, nullptr, nullptr,
+                                                                   pairlistParams.pairlistType,
+                                                                   false, numThreads, pinPolicy);
+
+    auto atomData     = std::make_unique<nbnxn_atomdata_t>(pinPolicy);
+
+    // Put everything together
+    auto nbv = std::make_unique<nonbonded_verlet_t>(std::move(pairlistSets),
+                                                    std::move(pairSearch),
+                                                    std::move(atomData),
+                                                    kernelSetup,
+                                                    nullptr,
+                                                    nullptr);
+
+    nbnxn_atomdata_init(gmx::MDLogger(),
+                        nbv->nbat.get(), kernelSetup.kernelType,
+                        combinationRule, system.numAtomTypes, system.nonbondedParameters.data(),
+                        1, numThreads);
+
+    t_nrnb nrnb;
+
+    GMX_RELEASE_ASSERT(!TRICLINIC(system.box), "Only rectangular unit-cells are supported here");
+    const rvec               lowerCorner = { 0, 0, 0 };
+    const rvec               upperCorner = {
+        system.box[XX][XX],
+        system.box[YY][YY],
+        system.box[ZZ][ZZ]
+    };
+
+    gmx::ArrayRef<const int> atomInfo;
+    if (options.useHalfLJOptimization)
+    {
+        atomInfo = system.atomInfoOxygenVdw;
+    }
+    else
+    {
+        atomInfo = system.atomInfoAllVdw;
+    }
+
+    const real atomDensity = system.coordinates.size()/det(system.box);
+
+    nbnxn_put_on_grid(nbv.get(),
+                      system.box, 0, lowerCorner, upperCorner,
+                      nullptr, 0, system.coordinates.size(), atomDensity,
+                      atomInfo, system.coordinates,
+                      0, nullptr);
+
+    nbv->constructPairlist(Nbnxm::InteractionLocality::Local,
+                           &system.excls, 0, &nrnb);
+
+    t_mdatoms mdatoms;
+    // We only use (read) the atom type and charge from mdatoms
+    mdatoms.typeA   = const_cast<int *>(system.atomTypes.data());
+    mdatoms.chargeA = const_cast<real *>(system.charges.data());
+    nbv->setAtomProperties(mdatoms, atomInfo);
+
+    return nbv;
+}
+
+//! Add the options instance to the list for all requested kernel SIMD types
+static void
+expandSimdOptionAndPushBack(const KernelBenchOptions        &options,
+                            std::vector<KernelBenchOptions> *optionsList)
+{
+    if (options.nbnxmSimd == BenchMarkKernels::SimdAuto)
+    {
+        bool addedInstance = false;
+#ifdef GMX_NBNXN_SIMD_4XN
+        optionsList->push_back(options);
+        optionsList->back().nbnxmSimd = BenchMarkKernels::Simd4XM;
+        addedInstance = true;
+#endif
+#ifdef GMX_NBNXN_SIMD_2XNN
+        optionsList->push_back(options);
+        optionsList->back().nbnxmSimd = BenchMarkKernels::Simd2XMM;
+        addedInstance = true;
+#endif
+        if (!addedInstance)
+        {
+            optionsList->push_back(options);
+            optionsList->back().nbnxmSimd = BenchMarkKernels::SimdNo;
+        }
+    }
+    else
+    {
+        optionsList->push_back(options);
+    }
+}
+
+//! Sets up and runs the requested benchmark instance and prints the results
+//
+// When \p doWarmup is true runs the warmup iterations instead
+// of the normal ones and does not print any results
+static void setupAndRunInstance(const gmx::BenchmarkSystem &system,
+                                const KernelBenchOptions   &options,
+                                const bool                  doWarmup)
+{
+    // Generate an, accurate, estimate of the number of non-zero pair interactions
+    const real                          atomDensity          = system.coordinates.size()/det(system.box);
+    const real                          numPairsWithinCutoff = atomDensity*4.0/3.0*M_PI*std::pow(options.pairlistCutoff, 3);
+    const real                          numUsefulPairs       = system.coordinates.size()*0.5*(numPairsWithinCutoff + 1);
+
+    std::unique_ptr<nonbonded_verlet_t> nbv = setupNbnxmForBenchInstance(options, system);
+
+    // We set the interaction cut-off to the pairlist cut-off
+    interaction_const_t   ic = setupInteractionConst(options);
+
+    t_nrnb                nrnb = { 0 };
+
+    gmx_enerdata_t        enerd(1, 0);
+
+    int                   forceFlags = GMX_FORCE_FORCES;
+    if (options.computeVirialAndEnergy)
+    {
+        forceFlags |= GMX_FORCE_VIRIAL | GMX_FORCE_ENERGY;
+    }
+
+    const gmx::EnumerationArray<BenchMarkKernels, std::string>  kernelNames = { "auto", "no", "4xM", "2xMM" };
+
+    const gmx::EnumerationArray<BenchMarkCombRule, std::string> combruleNames = { "geom.", "LB", "none" };
+
+    if (!doWarmup)
+    {
+        fprintf(stdout, "%-7s %-4s %-5s %-4s ",
+                options.coulombType == BenchMarkCoulomb::Pme ? "Ewald" : "RF",
+                options.useHalfLJOptimization ? "half" : "all",
+                combruleNames[options.ljCombinationRule].c_str(),
+                kernelNames[options.nbnxmSimd].c_str());
+    }
+
+    // Run pre-iteration to avoid cache misses
+    for (int iter = 0; iter < options.numPreIterations; iter++)
+    {
+        nbv->dispatchNonbondedKernel(InteractionLocality::Local,
+                                     ic, forceFlags, enbvClearFYes, system.forceRec,
+                                     &enerd,
+                                     &nrnb);
+    }
+
+    const int          numIterations = (doWarmup ? options.numWarmupIterations : options.numIterations);
+    const PairlistSet &pairlistSet   = nbv->pairlistSets().pairlistSet(InteractionLocality::Local);
+    const gmx::index   numPairs      = pairlistSet.natpair_ljq_ + pairlistSet.natpair_lj_ + pairlistSet.natpair_q_;
+    gmx_cycles_t       cycles        = gmx_cycles_read();
+    for (int iter = 0; iter < numIterations; iter++)
+    {
+        // Run the kernel without force clearing
+        nbv->dispatchNonbondedKernel(InteractionLocality::Local,
+                                     ic, forceFlags, enbvClearFNo, system.forceRec,
+                                     &enerd,
+                                     &nrnb);
+    }
+    cycles = gmx_cycles_read() - cycles;
+    if (!doWarmup)
+    {
+        const double dCycles = static_cast<double>(cycles);
+        if (options.cyclesPerPair)
+        {
+            fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n",
+                    cycles*1e-6,
+                    dCycles/options.numIterations*1e-6,
+                    dCycles/(options.numIterations*numPairs),
+                    dCycles/(options.numIterations*numUsefulPairs));
+        }
+        else
+        {
+            fprintf(stdout, "%10.3f %10.4f %8.4f %8.4f\n",
+                    dCycles*1e-6,
+                    dCycles/options.numIterations*1e-6,
+                    options.numIterations*numPairs/dCycles,
+                    options.numIterations*numUsefulPairs/dCycles);
+        }
+    }
+}
+
+void bench(const int                 sizeFactor,
+           const KernelBenchOptions &options)
+{
+    // We don't want to call gmx_omp_nthreads_init(), so we init what we need
+    gmx_omp_nthreads_set(emntPairsearch, options.numThreads);
+    gmx_omp_nthreads_set(emntNonbonded, options.numThreads);
+
+    const gmx::BenchmarkSystem system(sizeFactor);
+
+    real                       minBoxSize = norm(system.box[XX]);
+    for (int dim = YY; dim < DIM; dim++)
+    {
+        minBoxSize = std::min(minBoxSize, norm(system.box[dim]));
+    }
+    if (options.pairlistCutoff > 0.5*minBoxSize)
+    {
+        gmx_fatal(FARGS, "The cut-off should be shorter than half the box size");
+    }
+
+    std::vector<KernelBenchOptions> optionsList;
+    if (options.doAll)
+    {
+        KernelBenchOptions opt = options;
+        gmx::EnumerationWrapper<BenchMarkCoulomb> coulombIter;
+        for (auto coulombType : coulombIter)
+        {
+            opt.coulombType = coulombType;
+            for (int halfLJ = 0; halfLJ <= 1; halfLJ++)
+            {
+                opt.useHalfLJOptimization = (halfLJ == 1);
+
+                gmx::EnumerationWrapper<BenchMarkCombRule> combRuleIter;
+                for (auto combRule : combRuleIter)
+                {
+                    if (combRule == BenchMarkCombRule::RuleNone)
+                    {
+                        continue;
+                    }
+                    opt.ljCombinationRule = combRule;
+
+                    expandSimdOptionAndPushBack(opt, &optionsList);
+                }
+            }
+        }
+    }
+    else
+    {
+        expandSimdOptionAndPushBack(options, &optionsList);
+    }
+    GMX_RELEASE_ASSERT(!optionsList.empty(), "Expect at least on benchmark setup");
+
+#if GMX_SIMD
+    if (options.nbnxmSimd != BenchMarkKernels::SimdNo)
+    {
+        fprintf(stdout, "SIMD width:           %d\n", GMX_SIMD_REAL_WIDTH);
+    }
+#endif
+    fprintf(stdout, "System size:          %zu atoms\n", system.coordinates.size());
+    fprintf(stdout, "Cut-off radius:       %g nm\n", options.pairlistCutoff);
+    fprintf(stdout, "Number of threads:    %d\n", options.numThreads);
+    fprintf(stdout, "Number of iterations: %d\n", options.numIterations);
+    fprintf(stdout, "Compute energies:     %s\n",
+            options.computeVirialAndEnergy ? "yes" : "no");
+    if (options.coulombType != BenchMarkCoulomb::ReactionField)
+    {
+        fprintf(stdout, "Ewald excl. corr.:    %s\n",
+                options.nbnxmSimd == BenchMarkKernels::SimdNo || options.useTabulatedEwaldCorr ? "table" : "analytical");
+    }
+    printf("\n");
+
+    if (options.numWarmupIterations > 0)
+    {
+        setupAndRunInstance(system, optionsList[0], true);
+    }
+
+    fprintf(stdout, "Coulomb LJ   comb. SIMD    Mcycles  Mcycles/it.   %s\n",
+            options.cyclesPerPair ? "cycles/pair" : "pairs/cycle");
+    fprintf(stdout, "                                                total    useful\n");
+
+    for (const auto &optionsInstance : optionsList)
+    {
+        setupAndRunInstance(system, optionsInstance, false);
+    }
+}
+
+} // namespace Nbnxm
diff --git a/src/gromacs/nbnxm/benchmark/bench_setup.h b/src/gromacs/nbnxm/benchmark/bench_setup.h
new file mode 100644 (file)
index 0000000..f3355bf
--- /dev/null
@@ -0,0 +1,134 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \libinternal \file
+ * \brief
+ * This file declares functions for setting up kernel benchmarks
+ *
+ * \author Berk Hess <hess@kth.se>
+ *
+ * \inlibraryapi
+ * \ingroup module_nbnxm
+ */
+
+#ifndef GMX_NBNXN_BENCH_SETUP_H
+#define GMX_NBNXN_BENCH_SETUP_H
+
+#include "gromacs/utility/real.h"
+
+namespace Nbnxm
+{
+
+//! Enum for selecting the SIMD kernel type for benchmarks
+enum class BenchMarkKernels : int
+{
+    SimdAuto,
+    SimdNo,
+    Simd4XM,
+    Simd2XMM,
+    Count
+};
+
+//! Enum for selecting the combination rule for kernel benchmarks
+enum class BenchMarkCombRule : int
+{
+    RuleGeom,
+    RuleLB,
+    RuleNone,
+    Count
+};
+
+//! Enum for selecting coulomb type for kernel benchmarks
+enum class BenchMarkCoulomb : int
+{
+    Pme,
+    ReactionField,
+    Count
+};
+
+/*! \internal \brief
+ * The options for the kernel benchmarks
+ */
+struct KernelBenchOptions
+{
+    //! Whether to use a GPU, currently GPUs are not supported
+    bool              useGpu                 = false;
+    //! The number of OpenMP threads to use
+    int               numThreads             = 1;
+    //! The SIMD type for the kernel
+    BenchMarkKernels  nbnxmSimd  = BenchMarkKernels::SimdAuto;
+    //! The LJ combination rule
+    BenchMarkCombRule ljCombinationRule = BenchMarkCombRule::RuleGeom;
+    //! Use i-cluster half-LJ optimization for clusters with <= half LJ
+    bool              useHalfLJOptimization  = false;
+    //! The pairlist and interaction cut-off
+    real              pairlistCutoff         = 1.0;
+    //! The Coulomb Ewald coefficient
+    real              ewaldcoeff_q           = 0;
+    //! Whether to compute energies (shift forces for virial are always computed on CPU)
+    bool              computeVirialAndEnergy = false;
+    //! The Coulomb interaction function
+    BenchMarkCoulomb  coulombType = BenchMarkCoulomb::Pme;
+    //! Whether to use tabulated PME grid correction instead of analytical, not applicable with simd=no
+    bool              useTabulatedEwaldCorr  = false;
+    //! Whether to run all combinations of Coulomb type, combination rule and SIMD
+    bool              doAll                  = false;
+    //! Number of iterations to run before running each kernel benchmark, currently always 1
+    int               numPreIterations       = 1;
+    //! The number of iterations for each kernel
+    int               numIterations          = 100;
+    //! The number of (untimed) iterations to run at startup to warm up the CPU
+    int               numWarmupIterations    = 0;
+    //! Print cycles/pair instead of pairs/cycle
+    bool              cyclesPerPair          = false;
+};
+
+/*! \brief
+ * Sets up and runs one or more Nbnxm kernel benchmarks
+ *
+ * The simulated system is a box of 1000 SPC/E water molecules scaled
+ * by the factor \p sizeFactor, which has to be a power of 2.
+ * One or more benchmarks are run, as specified by \p options.
+ * Benchmark settings and timings are printed to stdout.
+ *
+ * \param[in] sizeFactor How much should the system size be increased.
+ * \param[in] options How the benchmark will be run.
+ */
+void bench(int                       sizeFactor,
+           const KernelBenchOptions &options);
+
+} // namespace Nbnxm
+
+#endif
diff --git a/src/gromacs/nbnxm/benchmark/bench_system.cpp b/src/gromacs/nbnxm/benchmark/bench_system.cpp
new file mode 100644 (file)
index 0000000..7eb9681
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*! \internal \file
+ * \brief
+ * This file defines functions for setting up a benchmark system
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \ingroup module_nbnxm
+ */
+
+#include "gmxpre.h"
+
+#include "bench_system.h"
+
+#include <vector>
+
+#include "gromacs/math/vec.h"
+#include "gromacs/mdlib/dispersioncorrection.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/nbnxm/nbnxm.h"
+#include "gromacs/pbcutil/ishift.h"
+#include "gromacs/pbcutil/pbc.h"
+#include "gromacs/utility/fatalerror.h"
+
+#include "bench_coords.h"
+
+namespace gmx
+{
+
+namespace
+{
+
+// A 3-site water model
+//! The number of atoms in a molecule
+constexpr int  numAtomsInMolecule = 3;
+//! The atom type of the oxygen atom
+constexpr int  typeOxygen         = 0;
+//! The atom type of the hydrogen atom
+constexpr int  typeHydrogen       = 1;
+//! The charge of the oxygen atom
+constexpr real chargeOxygen       = -0.8476;
+//! The charge of the hydrogen atom
+constexpr real chargeHydrogen     = 0.4238;
+//! The LJ C6 parameter of the Oxygen atom
+constexpr real c6Oxygen           = 0.0026173456;
+//! The LJ C12 parameter of the Oxygen atom
+constexpr real c12Oxygen          = 2.634129e-06;
+// Note that the hydrogen has LJ parameters all zero
+
+}   // namespace
+
+//! Generates coordinates and a box for the base system scaled by \p multiplicationFactor
+//
+// The parameter \p multiplicationFactor should be a power of 2.
+// A fatal error is generated when this is not the case.
+static void
+generateCoordinates(int                     multiplicationFactor,
+                    std::vector<gmx::RVec> *coordinates,
+                    matrix                  box)
+{
+    if (multiplicationFactor < 1 ||
+        (multiplicationFactor & (multiplicationFactor - 1)) != 0)
+    {
+        gmx_fatal(FARGS, "The size factor has to be a power of 2");
+    }
+
+    if (multiplicationFactor == 1)
+    {
+        *coordinates = coordinates1000;
+        copy_mat(box1000, box);
+
+        return;
+    }
+
+    ivec factors = { 1, 1, 1 };
+
+    int  dim = 0;
+    while (multiplicationFactor > 1)
+    {
+        factors[dim]         *= 2;
+        multiplicationFactor /= 2;
+        dim++;
+        if (dim == DIM)
+        {
+            dim = 0;
+        }
+    }
+    printf("Stacking a box of %zu atoms %d x %d x %d times\n",
+           coordinates1000.size(), factors[XX], factors[YY], factors[ZZ]);
+
+    coordinates->resize(factors[XX]*factors[YY]*factors[ZZ]*coordinates1000.size());
+
+    int       i = 0;
+    gmx::RVec shift;
+    for (int x = 0; x < factors[XX]; x++)
+    {
+        shift[XX] = x*box1000[XX][XX];
+        for (int y = 0; y < factors[YY]; y++)
+        {
+            shift[YY] = y*box1000[YY][YY];
+            for (int z = 0; z < factors[ZZ]; z++)
+            {
+                shift[ZZ] = z*box1000[ZZ][ZZ];
+
+                for (const gmx::RVec &coordOrig : coordinates1000)
+                {
+                    (*coordinates)[i] = coordOrig + shift;
+                    i++;
+                }
+            }
+        }
+    }
+
+    for (int d1 = 0; d1 < DIM; d1++)
+    {
+        for (int d2 = 0; d2 < DIM; d2++)
+        {
+            box[d1][d2] = factors[d1]*box1000[d1][d2];
+        }
+    }
+}
+
+BenchmarkSystem::BenchmarkSystem(const int multiplicationFactor)
+{
+    numAtomTypes = 2;
+    nonbondedParameters.resize(numAtomTypes*numAtomTypes*2, 0);
+    nonbondedParameters[0] = c6Oxygen;
+    nonbondedParameters[1] = c12Oxygen;
+
+    generateCoordinates(multiplicationFactor, &coordinates, box);
+    put_atoms_in_box(epbcXYZ, box, coordinates);
+
+    int numAtoms = coordinates.size();
+    GMX_RELEASE_ASSERT(numAtoms % numAtomsInMolecule == 0, "Coordinates should match whole molecules");
+
+    atomTypes.resize(numAtoms);
+    charges.resize(numAtoms);
+    atomInfoAllVdw.resize(numAtoms);
+    atomInfoOxygenVdw.resize(numAtoms);
+    snew(excls.index, numAtoms + 1);
+    snew(excls.a, numAtoms*numAtomsInMolecule);
+    excls.index[0] = 0;
+
+    for (int a = 0; a < numAtoms; a++)
+    {
+        if (a % numAtomsInMolecule == 0)
+        {
+            // Oxgygen
+            atomTypes[a] = typeOxygen;
+            charges[a]   = chargeOxygen;
+            SET_CGINFO_HAS_VDW(atomInfoAllVdw[a]);
+            SET_CGINFO_HAS_VDW(atomInfoOxygenVdw[a]);
+        }
+        else
+        {
+            // Hydrogen
+            atomTypes[a] = typeHydrogen;
+            charges[a]   = chargeHydrogen;
+            SET_CGINFO_HAS_VDW(atomInfoAllVdw[a]);
+        }
+        SET_CGINFO_HAS_Q(atomInfoAllVdw[a]);
+        SET_CGINFO_HAS_Q(atomInfoOxygenVdw[a]);
+
+        const int firstAtomInMolecule = a - (a % numAtomsInMolecule);
+        for (int aj = 0; aj < numAtomsInMolecule; aj++)
+        {
+            excls.a[a*numAtomsInMolecule + aj] = firstAtomInMolecule + aj;
+        }
+        excls.index[a + 1] = (a + 1)*numAtomsInMolecule;
+    }
+
+    forceRec.ntype = numAtomTypes;
+    forceRec.nbfp  = nonbondedParameters.data();
+    snew(forceRec.shift_vec, SHIFTS);
+    calc_shifts(box, forceRec.shift_vec);
+}
+
+} // namespace gmx
diff --git a/src/gromacs/nbnxm/benchmark/bench_system.h b/src/gromacs/nbnxm/benchmark/bench_system.h
new file mode 100644 (file)
index 0000000..1801f77
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+
+/*!\file
+ * \brief
+ * This file declares functions for setting up a benchmark system
+ *
+ * \author Berk Hess <hess@kth.se>
+ * \ingroup module_nbnxm
+ */
+
+#ifndef GMX_NBNXN_BENCH_SYSTEM_H
+#define GMX_NBNXN_BENCH_SYSTEM_H
+
+#include <vector>
+
+#include "gromacs/math/vectypes.h"
+#include "gromacs/mdtypes/forcerec.h"
+#include "gromacs/topology/block.h"
+#include "gromacs/utility/smalloc.h"
+
+namespace gmx
+{
+
+//! Description of the system used for benchmarking.
+struct BenchmarkSystem
+{
+    /*! \brief Constructor
+     *
+     * Generates a benchmark system of size \p multiplicationFactor
+     * times the base size by stacking cubic boxes of 1000 water molecules
+     * with 3000 atoms total.
+     *
+     * \param[in] multiplicationFactor  Should be a power of 2, is checked
+     */
+    BenchmarkSystem(int multiplicationFactor);
+
+    //! Number of different atom types in test system.
+    int                    numAtomTypes;
+    //! Storage for parameters for short range interactions.
+    std::vector<real>      nonbondedParameters;
+    //! Storage for atom type parameters.
+    std::vector<int>       atomTypes;
+    //! Storage for atom partial charges.
+    std::vector<real>      charges;
+    //! Atom info where all atoms are marked to have Van der Waals interactions
+    std::vector<int>       atomInfoAllVdw;
+    //! Atom info where only oxygen atoms are marked to have Van der Waals interactions
+    std::vector<int>       atomInfoOxygenVdw;
+    //! Information about exclusions.
+    t_blocka               excls;
+    //! Storage for atom positions.
+    std::vector<gmx::RVec> coordinates;
+    //! System simulation box.
+    matrix                 box;
+    //! Forcerec with only the entries used in the benchmark set
+    t_forcerec             forceRec;
+};
+
+} // namespace gmx
+
+#endif
index 28a88bbeb90f0560f76f09c850c872d686db8ab9..b73c03d0eea3ecc0f0f6c6c337e179ed399740aa 100644 (file)
@@ -212,6 +212,7 @@ void GridSet::putOnGrid(const matrix                    box,
     gridSetData_.cells.resize(atomEnd);
 
     const int nthread = gmx_omp_nthreads_get(emntPairsearch);
+    GMX_ASSERT(nthread > 0, "We expect the OpenMP thread count to be set");
 
 #pragma omp parallel for num_threads(nthread) schedule(static)
     for (int thread = 0; thread < nthread; thread++)
index b8ec65eaa0456609451f8c402aec2544e4a8f9ff..f8184fa2547269f9dab0f16042c0306f0a002d12 100644 (file)
@@ -69,6 +69,7 @@
 #include "gromacs/tools/tune_pme.h"
 
 #include "mdrun/mdrun_main.h"
+#include "mdrun/nonbonded_bench.h"
 #include "view/view.h"
 
 namespace
@@ -196,6 +197,11 @@ void registerLegacyModules(gmx::CommandLineModuleManager *manager)
     registerModuleNoNice(manager, &gmx::gmx_mdrun, "mdrun",
                          "Perform a simulation, do a normal mode analysis or an energy minimization");
 
+    gmx::ICommandLineOptionsModule::registerModuleFactory(
+            manager, gmx::NonbondedBenchmarkInfo::name,
+            gmx::NonbondedBenchmarkInfo::shortDescription,
+            &gmx::NonbondedBenchmarkInfo::create);
+
     gmx::ICommandLineOptionsModule::registerModuleFactory(
             manager, gmx::InsertMoleculesInfo::name(),
             gmx::InsertMoleculesInfo::shortDescription(),
diff --git a/src/programs/mdrun/nonbonded_bench.cpp b/src/programs/mdrun/nonbonded_bench.cpp
new file mode 100644 (file)
index 0000000..1adf0bd
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ *
+ * \brief This file contains the main function for the non-bonded kernel benchmark
+ *
+ * \author Berk Hess <hess@kth.se>
+ */
+
+#include "gmxpre.h"
+
+#include "nonbonded_bench.h"
+
+#include <vector>
+
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
+#include "gromacs/ewald/ewald_utils.h"
+#include "gromacs/nbnxm/benchmark/bench_setup.h"
+#include "gromacs/options/basicoptions.h"
+#include "gromacs/options/filenameoption.h"
+#include "gromacs/options/ioptionscontainer.h"
+#include "gromacs/selection/selectionoptionbehavior.h"
+#include "gromacs/utility/arraysize.h"
+#include "gromacs/utility/enumerationhelpers.h"
+
+namespace gmx
+{
+
+
+namespace
+{
+
+class NonbondedBenchmark : public ICommandLineOptionsModule
+{
+    public:
+        NonbondedBenchmark()
+        {}
+
+        // From ICommandLineOptionsModule
+        void init(CommandLineModuleSettings * /*settings*/) override
+        {
+        }
+        void initOptions(IOptionsContainer                 *options,
+                         ICommandLineOptionsModuleSettings *settings) override;
+        void optionsFinished() override;
+        int run() override;
+    private:
+        int                       sizeFactor_     = 1;
+        Nbnxm::KernelBenchOptions benchmarkOptions_;
+};
+
+void NonbondedBenchmark::initOptions(IOptionsContainer                 *options,
+                                     ICommandLineOptionsModuleSettings *settings)
+{
+    std::vector<const char *>        desc = {
+        "[THISMODULE] runs benchmarks for one or more so-called Nbnxm",
+        "non-bonded pair kernels. The non-bonded pair kernels are",
+        "the most compute intensive part of MD simulations",
+        "and usually comprise 60 to 90 percent of the runtime.",
+        "For this reason they are highly optimized and several different",
+        "setups are available to compute the same physical interactions.",
+        "In addition, there are different physical treatments of Coulomb",
+        "interactions and optimizations for atoms without Lennard-Jones",
+        "interactions. There are also different physical treatments of",
+        "Lennard-Jones interactions, but only a plain cut-off is supported",
+        "in this tool, as that is by far the most common treatment.",
+        "And finally, while force output is always necessary, energy output",
+        "is only required at certain steps. In total there are",
+        "12 relevant combinations of options. The combinations double to 24",
+        "when two different SIMD setups are supported. These combinations",
+        "can be run with a single invocation using the [TT]-all[tt] option.",
+        "The behavior of each kernel is affected by caching behavior,",
+        "which is determined by the hardware used together with the system size",
+        "and the cut-off radius. The larger the number of atoms per thread,",
+        "the more L1 cache is needed to avoid L1 cache misses.",
+        "The cut-off radius mainly affects the data reuse: a larger cut-off",
+        "results in more data reuse and makes the kernel less sensitive to cache",
+        "misses.[PAR]",
+        "OpenMP parallelization is used to utilize multiple hardware threads",
+        "within a compute node. In these benchmarks there is no interaction",
+        "between threads, apart from starting and closing a single OpenMP",
+        "parallel region per iteration. Additionally, threads interact",
+        "through sharing and evicting data from shared caches.",
+        "The number of threads to use is set with the [TT]-nt[tt] option.",
+        "Thread affinity is important, especially with SMT and shared",
+        "caches. Affinities can be set through the OpenMP library using",
+        "the GOMP_CPU_AFFINITY environment variable.[PAR]",
+        "The benchmark tool times one or more kernels by running them",
+        "repeatedly for a number of iterations set by the [TT]-iter[tt]",
+        "option. An initial kernel call is done to avoid additional initial",
+        "cache misses. Times are recording in cycles read from efficient,",
+        "high accuracy counters in the CPU. Note that these often do not",
+        "correspond to actual clock cycles. For each kernel, the tool",
+        "reports the total number of cycles, cycles per iteration,",
+        "and (total and useful) pair interactions per cycle.",
+        "Because a cluster pair list is used instead of an atom pair list,",
+        "interactions are also computed for some atom pairs that are beyond",
+        "the cut-off distance. These pairs are not useful (except for",
+        "additional buffering, but that is not of interest here),",
+        "only a side effect of the cluster-pair setup. The SIMD 2xMM kernel",
+        "has a higher useful pair ratio then the 4xM kernel due to a smaller",
+        "cluster size, but a lower total pair throughput.",
+        "It is best to run this, or for that matter any, benchmark",
+        "with locked CPU clocks, as thermal throttling can significantly",
+        "affect performance. If that is not an option, the [TT]-warmup[TT]",
+        "option can be used to run initial, untimed iterations to warm up",
+        "the processor.[PAR]",
+        "The most relevant regime is between 0.1 to 1 millisecond per",
+        "iteration. Thus it is useful to run with system sizes that cover",
+        "both ends of this regime.[PAR]",
+        "The [TT]-simd[tt] and [TT]-table[tt] options select different",
+        "implementations to compute the same physics. The choice of these",
+        "options should ideally be optimized for the target hardware.",
+        "Historically, we only found tabulated Ewald correction to be useful",
+        "on 2-wide SIMD or 4-wide SIMD without FMA support. As all modern",
+        "architectures are wider and support FMA, we do not use tables by",
+        "default. The only exceptions are kernels without SIMD, which only",
+        "support tables.",
+        "Options [TT]-coulomb[tt], [TT]-combrule[tt] and [TT]-halflj[tt]",
+        "depend on the force field and composition of the simulated system.",
+        "The optimization of computing Lennard-Jones interactions for only",
+        "half of the atoms in a cluster is useful for water, which does not",
+        "use Lennard-Jones on hydrogen atoms in most water models.",
+        "In the MD engine, any clusters where at most half of the atoms",
+        "have LJ interactions will automatically use this kernel.",
+        "And finally, the [TT]-energy[tt] option selects the computation",
+        "of energies, which are usually only needed infrequently."
+    };
+
+    settings->setHelpText(desc);
+
+    const char *const cNbnxmSimdStrings[] = {
+        "auto", "no", "4xm", "2xmm"
+    };
+    const char *const cCombRuleStrings[] = {
+        "geometric", "lb", "none"
+    };
+    const char *const cCoulombTypeStrings[] = {
+        "ewald", "reaction-field"
+    };
+
+    options->addOption(IntegerOption("size")
+                           .store(&sizeFactor_)
+                           .description("The system size is 3000 atoms times this value"));
+    options->addOption(IntegerOption("nt")
+                           .store(&benchmarkOptions_.numThreads)
+                           .description("The number of OpenMP threads to use"));
+    options->addOption(EnumOption<Nbnxm::BenchMarkKernels>("simd")
+                           .store(&benchmarkOptions_.nbnxmSimd)
+                           .enumValue(cNbnxmSimdStrings)
+                           .description("SIMD type, auto runs all supported SIMD setups or no SIMD when SIMD is not supported"));
+    options->addOption(EnumOption<Nbnxm::BenchMarkCoulomb>("coulomb")
+                           .store(&benchmarkOptions_.coulombType)
+                           .enumValue(cCoulombTypeStrings)
+                           .description("The functional form for the Coulomb interactions"));
+    options->addOption(BooleanOption("table")
+                           .store(&benchmarkOptions_.useTabulatedEwaldCorr)
+                           .description("Use lookup table for Ewald correction instead of analytical"));
+    options->addOption(EnumOption<Nbnxm::BenchMarkCombRule>("combrule")
+                           .store(&benchmarkOptions_.ljCombinationRule)
+                           .enumValue(cCombRuleStrings)
+                           .description("The LJ combination rule"));
+    options->addOption(BooleanOption("halflj")
+                           .store(&benchmarkOptions_.useHalfLJOptimization)
+                           .description("Use optimization for LJ on half of the atoms"));
+    options->addOption(BooleanOption("energy")
+                           .store(&benchmarkOptions_.computeVirialAndEnergy)
+                           .description("Compute energies in addition to forces"));
+    options->addOption(BooleanOption("all")
+                           .store(&benchmarkOptions_.doAll)
+                           .description("Run all 12 combinations of options for coulomb, halflj, combrule"));
+    options->addOption(RealOption("cutoff")
+                           .store(&benchmarkOptions_.pairlistCutoff)
+                           .description("Pair-list and interaction cut-off distance"));
+    options->addOption(IntegerOption("iter")
+                           .store(&benchmarkOptions_.numIterations)
+                           .description("The number of iterations for each kernel"));
+    options->addOption(IntegerOption("warmup")
+                           .store(&benchmarkOptions_.numWarmupIterations)
+                           .description("The number of iterations for initial warmup"));
+    options->addOption(BooleanOption("cycles")
+                           .store(&benchmarkOptions_.cyclesPerPair)
+                           .description("Report cycles/pair instead of pairs/cycle"));
+
+}
+
+void NonbondedBenchmark::optionsFinished()
+{
+    // We compute the Ewald coefficient here to avoid a dependency of the Nbnxm on the Ewald module
+    const real ewald_rtol     = 1e-5;
+    benchmarkOptions_.ewaldcoeff_q      = calc_ewaldcoeff_q(benchmarkOptions_.pairlistCutoff,
+                                                            ewald_rtol);
+}
+
+int NonbondedBenchmark::run()
+{
+    Nbnxm::bench(sizeFactor_, benchmarkOptions_);
+
+    return 0;
+}
+
+}   // namespace
+
+const char NonbondedBenchmarkInfo::name[]             = "nonbonded-benchmark";
+const char NonbondedBenchmarkInfo::shortDescription[] =
+    "Benchmarking tool for the non-bonded pair kernels.";
+
+ICommandLineOptionsModulePointer NonbondedBenchmarkInfo::create()
+{
+    return ICommandLineOptionsModulePointer(std::make_unique<NonbondedBenchmark>());
+}
+
+} //i namespace gmx
diff --git a/src/programs/mdrun/nonbonded_bench.h b/src/programs/mdrun/nonbonded_bench.h
new file mode 100644 (file)
index 0000000..5b42b81
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \file
+ * \brief
+ * Declares the nonbonded benchmarking tool.
+ *
+ * \author Berk Hess <hess@kth.se>
+ */
+
+#ifndef GMX_PROGRAMS_MDRUN_NOBONDED_BENCH_MAIN_H
+#define GMX_PROGRAMS_MDRUN_NOBONDED_BENCH_MAIN_H
+
+#include "gromacs/commandline/cmdlineoptionsmodule.h"
+
+namespace gmx
+{
+
+//! Declares gmx nonbonded-bench.
+class NonbondedBenchmarkInfo
+{
+    public:
+        //! Name of the module.
+        static const char name[];
+        //! Short module description.
+        static const char shortDescription[];
+        //! Build the actual gmx module to use.
+        static ICommandLineOptionsModulePointer create();
+};
+
+} // namespace gmx
+
+#endif
index da17cd990fe9944fc3c23812ca8e021199596bde..fd95db2de766aa8e659e2d783a674725df0c12a8 100644 (file)
@@ -80,6 +80,7 @@ gmx_add_gtest_executable(
     ${exename}
     # files with code for tests
     minimize.cpp
+    nonbonded_bench.cpp
     normalmodes.cpp
     rerun.cpp
     simple_mdrun.cpp
diff --git a/src/programs/mdrun/tests/nonbonded_bench.cpp b/src/programs/mdrun/tests/nonbonded_bench.cpp
new file mode 100644 (file)
index 0000000..300322f
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the GROMACS molecular simulation package.
+ *
+ * Copyright (c) 2018,2019, by the GROMACS development team, led by
+ * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
+ * and including many others, as listed in the AUTHORS file in the
+ * top-level source directory and at http://www.gromacs.org.
+ *
+ * GROMACS 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.
+ *
+ * GROMACS 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 GROMACS; if not, see
+ * http://www.gnu.org/licenses, or write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
+ *
+ * If you want to redistribute modifications to GROMACS, please
+ * consider that scientific software is very special. Version
+ * control is crucial - bugs must be traceable. We will be happy to
+ * consider code for inclusion in the official distribution, but
+ * derived work must not be called official GROMACS. Details are found
+ * in the README & COPYING files - if they are missing, get the
+ * official version at http://www.gromacs.org.
+ *
+ * To help us fund GROMACS development, we humbly ask that you cite
+ * the research papers on the package. Check out http://www.gromacs.org.
+ */
+/*! \internal \file
+ * \brief
+ * This implements basic Nonbonded bench tests.
+ *
+ * \author Paul Bauer <paul.bauer.q@gmail.com>
+ * \ingroup module_mdrun_integration_tests
+ */
+#include "gmxpre.h"
+
+#include "programs/mdrun/nonbonded_bench.h"
+
+#include "gromacs/utility/stringutil.h"
+#include "gromacs/utility/textreader.h"
+
+#include "testutils/refdata.h"
+#include "testutils/testasserts.h"
+
+#include "moduletest.h"
+
+namespace gmx
+{
+namespace test
+{
+namespace
+{
+
+TEST(NonbondedBenchTest, BasicEndToEndTest)
+{
+    const char *const command[] = {
+        "nonbonded-benchmark"
+    };
+    CommandLine       cmdline(command);
+    cmdline.addOption("-iter", 1);
+    EXPECT_EQ(0, gmx::test::CommandLineTestHelper::runModuleFactory(
+                      &gmx::NonbondedBenchmarkInfo::create, &cmdline));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace gmx