From b9057925955f066c1c88719f6bbff29cfc5fe666 Mon Sep 17 00:00:00 2001 From: Erik Lindahl Date: Thu, 25 May 2017 20:01:57 +0200 Subject: [PATCH] Improved SIMD test data to use all bits The SIMD test data now uses all available bits in the current precision floating-point numbers, to catch errors where we lose precision or have mistakes in single/double conversions (e.g. return values). Since some operations now depend on the least significant bit, a few tests have been relaxed to allow a tolerance rather than require exact binary matching. The new tests caught a precision loss in a reduction function for the SIMD-mimicking scalar functions, but this has never been used apart from testing, and should be harmless. Fixes #2163. Change-Id: I6d8f19d2aafeee8f42a2034c6100fcb10f6d2e81 --- src/gromacs/simd/scalar/scalar_util.h | 4 +- src/gromacs/simd/tests/CMakeLists.txt | 3 +- .../{simd4_vector_operations.cpp => data.cpp} | 49 +++--- .../tests/{simd4_vector_operations.cpp => data.h} | 67 ++++---- src/gromacs/simd/tests/scalar.cpp | 72 ++++----- src/gromacs/simd/tests/scalar_math.cpp | 88 ++++++----- src/gromacs/simd/tests/scalar_util.cpp | 66 ++++---- src/gromacs/simd/tests/simd.cpp | 47 ++++-- src/gromacs/simd/tests/simd.h | 27 +++- src/gromacs/simd/tests/simd4.cpp | 44 ++++-- src/gromacs/simd/tests/simd4.h | 42 ++--- src/gromacs/simd/tests/simd4_floatingpoint.cpp | 152 +++++++++--------- src/gromacs/simd/tests/simd4_vector_operations.cpp | 13 +- src/gromacs/simd/tests/simd_floatingpoint.cpp | 176 +++++++++++---------- src/gromacs/simd/tests/simd_floatingpoint_util.cpp | 59 ++++--- src/gromacs/simd/tests/simd_integer.cpp | 6 +- src/gromacs/simd/tests/simd_math.cpp | 71 ++++++--- src/gromacs/simd/tests/simd_vector_operations.cpp | 47 +++--- 18 files changed, 557 insertions(+), 476 deletions(-) copy src/gromacs/simd/tests/{simd4_vector_operations.cpp => data.cpp} (68%) copy src/gromacs/simd/tests/{simd4_vector_operations.cpp => data.h} (50%) diff --git a/src/gromacs/simd/scalar/scalar_util.h b/src/gromacs/simd/scalar/scalar_util.h index 16818f49d5..66550477f0 100644 --- a/src/gromacs/simd/scalar/scalar_util.h +++ b/src/gromacs/simd/scalar/scalar_util.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2016, by the GROMACS development team, led by + * Copyright (c) 2016,2017, 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. @@ -629,7 +629,7 @@ gatherLoadBySimdIntTranspose(const double * base, * write templated SIMD/non-SIMD code. For clarity it should not be used * outside such code. */ -static inline float +static inline double reduceIncr4ReturnSum(double * m, double v0, double v1, diff --git a/src/gromacs/simd/tests/CMakeLists.txt b/src/gromacs/simd/tests/CMakeLists.txt index dd23216959..2f8b30a074 100644 --- a/src/gromacs/simd/tests/CMakeLists.txt +++ b/src/gromacs/simd/tests/CMakeLists.txt @@ -1,7 +1,7 @@ # # This file is part of the GROMACS molecular simulation package. # -# Copyright (c) 2014,2015,2016, by the GROMACS development team, led by +# Copyright (c) 2014,2015,2016,2017, 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. @@ -35,6 +35,7 @@ gmx_add_unit_test(SimdUnitTests simd-test bootstrap_loadstore.cpp base.cpp + data.cpp simd.cpp simd_floatingpoint.cpp simd_floatingpoint_util.cpp diff --git a/src/gromacs/simd/tests/simd4_vector_operations.cpp b/src/gromacs/simd/tests/data.cpp similarity index 68% copy from src/gromacs/simd/tests/simd4_vector_operations.cpp copy to src/gromacs/simd/tests/data.cpp index f32d4ff14b..1e3ab7ba07 100644 --- a/src/gromacs/simd/tests/simd4_vector_operations.cpp +++ b/src/gromacs/simd/tests/data.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -34,49 +34,38 @@ */ #include "gmxpre.h" -#include +#include "data.h" -#include "gromacs/simd/simd.h" -#include "gromacs/simd/vector_operations.h" +#include "gromacs/utility/real.h" -#include "simd4.h" - -#if GMX_SIMD namespace gmx { namespace test { -namespace -{ /*! \cond internal */ /*! \addtogroup module_simd */ /*! \{ */ -#if GMX_SIMD4_HAVE_REAL - -/*! \brief Test fixture for SIMD4 vector operations (identical to the SIMD4 \ref Simd4Test) */ -typedef Simd4Test Simd4VectorOperationsTest; - -TEST_F(Simd4VectorOperationsTest, norm2) -{ - Simd4Real simdX = setSimd4RealFrom3R(1, 2, 3); - Simd4Real simdY = setSimd4RealFrom3R(3, 0, 5); - Simd4Real simdZ = setSimd4RealFrom3R(4, 1, 8); - Simd4Real simdR2 = setSimd4RealFrom3R(26, 5, 98); - - setUlpTol(2); - GMX_EXPECT_SIMD4_REAL_NEAR(simdR2, norm2(simdX, simdY, simdZ)); -} - -#endif // GMX_SIMD4_HAVE_REAL +// Common test data constants used both for SIMD, SIMD4, and scalar tests. +// We both want numbers that are easy to identify with integer part from 0 to 9, +// and to fill all digits in the mantissa and avoid identical differences +// between adjacent numbers we add a fraction of primes. +const real czero = 0.0; +const real c0 = 0.0 + 1.0/3.0; +const real c1 = 1.0 + 5.0/7.0; +const real c2 = 2.0 + 9.0/13.0; +const real c3 = 3.0 + 17.0/19.0; +const real c4 = 4.0 + 23.0/29.0; +const real c5 = 5.0 + 31.0/37.0; +const real c6 = 6.0 + 41.0/43.0; +const real c7 = 7.0 + 47.0/53.0; +const real c8 = 8.0 + 59.0/61.0; /*! \} */ /*! \endcond */ -} // namespace -} // namespace -} // namespace +} // namespace test -#endif // GMX_SIMD +} // namespace gmx diff --git a/src/gromacs/simd/tests/simd4_vector_operations.cpp b/src/gromacs/simd/tests/data.h similarity index 50% copy from src/gromacs/simd/tests/simd4_vector_operations.cpp copy to src/gromacs/simd/tests/data.h index f32d4ff14b..b66abcece7 100644 --- a/src/gromacs/simd/tests/simd4_vector_operations.cpp +++ b/src/gromacs/simd/tests/data.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -32,51 +32,52 @@ * To help us fund GROMACS development, we humbly ask that you cite * the research papers on the package. Check out http://www.gromacs.org. */ -#include "gmxpre.h" +#ifndef GMX_SIMD_TESTS_DATA_H +#define GMX_SIMD_TESTS_DATA_H -#include - -#include "gromacs/simd/simd.h" -#include "gromacs/simd/vector_operations.h" - -#include "simd4.h" +/*! \internal \file + * \brief Common test data constants for SIMD, SIMD4 and scalar tests + * + * To avoid silent bugs due to double/float truncation if we ever use the + * wrong return type of routines, we want to use test data that fills all + * available bits in either single or double precision. The values themselves + * are meaningless. + * Note that the data is used to initialize the SIMD constants, which for + * technical (alignment) reasons in some compilers cannot be placed inside + * the text fixture classes. For that reason this data cannot go in the + * fixtures either. + * + * \author Erik Lindahl + * \ingroup module_simd + */ -#if GMX_SIMD +#include "gromacs/utility/real.h" namespace gmx { namespace test { -namespace -{ /*! \cond internal */ /*! \addtogroup module_simd */ /*! \{ */ - -#if GMX_SIMD4_HAVE_REAL - -/*! \brief Test fixture for SIMD4 vector operations (identical to the SIMD4 \ref Simd4Test) */ -typedef Simd4Test Simd4VectorOperationsTest; - -TEST_F(Simd4VectorOperationsTest, norm2) -{ - Simd4Real simdX = setSimd4RealFrom3R(1, 2, 3); - Simd4Real simdY = setSimd4RealFrom3R(3, 0, 5); - Simd4Real simdZ = setSimd4RealFrom3R(4, 1, 8); - Simd4Real simdR2 = setSimd4RealFrom3R(26, 5, 98); - - setUlpTol(2); - GMX_EXPECT_SIMD4_REAL_NEAR(simdR2, norm2(simdX, simdY, simdZ)); -} - -#endif // GMX_SIMD4_HAVE_REAL +extern const real czero; //!< Value 0.0 in real precision +extern const real c0; //!< Random fp value using entire mantissa +extern const real c1; //!< Random fp value using entire mantissa +extern const real c2; //!< Random fp value using entire mantissa +extern const real c3; //!< Random fp value using entire mantissa +extern const real c4; //!< Random fp value using entire mantissa +extern const real c5; //!< Random fp value using entire mantissa +extern const real c5; //!< Random fp value using entire mantissa +extern const real c6; //!< Random fp value using entire mantissa +extern const real c7; //!< Random fp value using entire mantissa +extern const real c8; //!< Random fp value using entire mantissa +extern const real c9; //!< Random fp value using entire mantissa /*! \} */ /*! \endcond */ -} // namespace -} // namespace -} // namespace +} // namespace test +} // namespace gmx -#endif // GMX_SIMD +#endif diff --git a/src/gromacs/simd/tests/scalar.cpp b/src/gromacs/simd/tests/scalar.cpp index 2d6418b1c2..540d3b1398 100644 --- a/src/gromacs/simd/tests/scalar.cpp +++ b/src/gromacs/simd/tests/scalar.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -42,6 +42,8 @@ #include "gromacs/utility/basedefinitions.h" #include "gromacs/utility/real.h" +#include "data.h" + namespace gmx { namespace test @@ -60,38 +62,34 @@ namespace TEST(SimdScalarTest, load) { - real ref = 1.234; - real val = load(&ref); + real val = load(&c1); - EXPECT_EQ(ref, val); + EXPECT_EQ(c1, val); } TEST(SimdScalarTest, loadU) { - real ref = 1.234; - real val = loadU(&ref); + real val = loadU(&c1); - EXPECT_EQ(ref, val); + EXPECT_EQ(c1, val); } TEST(SimdScalarTest, store) { - real ref = 1.234; real val; - store(&val, ref); + store(&val, c1); - EXPECT_EQ(ref, val); + EXPECT_EQ(c1, val); } TEST(SimdScalarTest, storeU) { - real ref = 1.234; real val; - store(&val, ref); + store(&val, c1); - EXPECT_EQ(ref, val); + EXPECT_EQ(c1, val); } TEST(SimdScalarTest, setZero) @@ -105,61 +103,61 @@ TEST(SimdScalarTest, andNot) { real signBit = GMX_REAL_NEGZERO; - EXPECT_EQ(real(1), andNot(signBit, real(-1))); - EXPECT_EQ(real(2), andNot(signBit, real(2))); + EXPECT_EQ(c1, andNot(signBit, -c1)); + EXPECT_EQ(c2, andNot(signBit, c2)); } TEST(SimdScalarTest, fma) { - EXPECT_EQ(real(27), fma(real(3), real(6), real(9))); // 3*6+9=27 + EXPECT_EQ(c1*c2+c3, fma(real(c1), real(c2), real(c3))); } TEST(SimdScalarTest, fms) { - EXPECT_EQ(real(9), fms(real(3), real(6), real(9))); // 3*6-9=9 + EXPECT_EQ(c1*c2-c3, fms(c1, c2, c3)); } TEST(SimdScalarTest, fnma) { - EXPECT_EQ(real(-9), fnma(real(3), real(6), real(9))); // -3*6+9=-9 + EXPECT_EQ(-c1*c2+c3, fnma(c1, c2, c3)); } TEST(SimdScalarTest, fnms) { - EXPECT_EQ(real(-27), fnms(real(3), real(6), real(9))); // -3*6-9=-27 + EXPECT_EQ(-c1*c2-c3, fnms(c1, c2, c3)); } TEST(SimdScalarTest, maskAdd) { - EXPECT_EQ(real(3), maskAdd(real(3), real(6), false)); - EXPECT_EQ(real(9), maskAdd(real(3), real(6), true)); + EXPECT_EQ(c1, maskAdd(c1, c2, false)); + EXPECT_EQ(c1+c2, maskAdd(c1, c2, true)); } TEST(SimdScalarTest, maskzMul) { - EXPECT_EQ(real(0), maskzMul(real(3), real(6), false)); - EXPECT_EQ(real(18), maskzMul(real(3), real(6), true)); + EXPECT_EQ(czero, maskzMul(c1, c2, false)); + EXPECT_EQ(c1*c2, maskzMul(c1, c2, true)); } TEST(SimdScalarTest, maskzFma) { - EXPECT_EQ(real(0), maskzFma(real(3), real(6), real(9), false)); - EXPECT_EQ(real(27), maskzFma(real(3), real(6), real(9), true)); + EXPECT_EQ(czero, maskzFma(c1, c2, c3, false)); + EXPECT_EQ(c1*c2+c3, maskzFma(c1, c2, c3, true)); } TEST(SimdScalarTest, abs) { - EXPECT_EQ(real(3), abs(real(-3))); + EXPECT_EQ(c1, abs(-c1)); } TEST(SimdScalarTest, max) { - EXPECT_EQ(real(3), max(real(1), real(3))); + EXPECT_EQ(c3, max(c1, c3)); } TEST(SimdScalarTest, min) { - EXPECT_EQ(real(1), min(real(1), real(3))); + EXPECT_EQ(c1, min(c1, c3)); } TEST(SimdScalarTest, round) @@ -180,14 +178,14 @@ TEST(SimdScalarTest, trunc) TEST(SimdScalarTest, reduce) { - EXPECT_EQ(real(5), reduce(real(5))); + EXPECT_EQ(c1, reduce(c1)); } TEST(SimdScalarTest, testBits) { - EXPECT_TRUE(testBits(real(1))); + EXPECT_TRUE(testBits(c1)); EXPECT_TRUE(testBits(GMX_REAL_NEGZERO)); - EXPECT_FALSE(testBits(real(0))); + EXPECT_FALSE(testBits(czero)); } TEST(SimdScalarTest, anyTrue) @@ -198,20 +196,20 @@ TEST(SimdScalarTest, anyTrue) TEST(SimdScalarTest, selectByMask) { - EXPECT_EQ(real(5.0), selectByMask(real(5.0), true)); - EXPECT_EQ(real(0.0), selectByMask(real(5.0), false)); + EXPECT_EQ(c1, selectByMask(c1, true)); + EXPECT_EQ(czero, selectByMask(c1, false)); } TEST(SimdScalarTest, selectByNotMask) { - EXPECT_EQ(real(0.0), selectByNotMask(real(5.0), true)); - EXPECT_EQ(real(5.0), selectByNotMask(real(5.0), false)); + EXPECT_EQ(czero, selectByNotMask(c1, true)); + EXPECT_EQ(c1, selectByNotMask(c1, false)); } TEST(SimdScalarTest, blend) { - EXPECT_EQ(real(5.0), blend(real(3.0), real(5.0), true)); - EXPECT_EQ(real(3.0), blend(real(3.0), real(5.0), false)); + EXPECT_EQ(c2, blend(c1, c2, true)); + EXPECT_EQ(c1, blend(c1, c2, false)); } TEST(SimdScalarTest, cvtR2I) diff --git a/src/gromacs/simd/tests/scalar_math.cpp b/src/gromacs/simd/tests/scalar_math.cpp index be92f24667..df297937b3 100644 --- a/src/gromacs/simd/tests/scalar_math.cpp +++ b/src/gromacs/simd/tests/scalar_math.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -44,6 +44,8 @@ #include "testutils/testasserts.h" +#include "data.h" + namespace gmx { namespace test @@ -66,14 +68,14 @@ namespace TEST(SimdScalarMathTest, copysign) { - EXPECT_EQ(real(-4), copysign(real(4), real(-5))); - EXPECT_EQ(real(5), copysign(real(5), real(2))); + EXPECT_EQ(real(-c1), copysign(real(c1), real(-c2))); + EXPECT_EQ(real(c2), copysign(real(c2), real(c3))); } TEST(SimdScalarMathTest, invsqrtPair) { - real x0 = 1.2345; - real x1 = 9.8765; + real x0 = c1; + real x1 = c2; real out0, out1; @@ -85,14 +87,14 @@ TEST(SimdScalarMathTest, invsqrtPair) TEST(SimdScalarMathTest, inv) { - real x0 = 1.2345; + real x0 = c0; EXPECT_EQ(real(1.0)/x0, inv(x0)); } TEST(SimdScalarMathTest, maskzInvsqrt) { - real x0 = 1.2345; + real x0 = c0; EXPECT_EQ(invsqrt(x0), maskzInvsqrt(x0, true)); EXPECT_EQ(real(0), maskzInvsqrt(x0, false)); @@ -100,42 +102,42 @@ TEST(SimdScalarMathTest, maskzInvsqrt) TEST(SimdScalarMathTest, log) { - real x0 = 1.2345; + real x0 = c0; EXPECT_EQ(std::log(x0), log(x0)); } TEST(SimdScalarMathTest, exp2) { - real x0 = 1.2345; + real x0 = c0; EXPECT_EQ(std::exp2(x0), exp2(x0)); } TEST(SimdScalarMathTest, exp) { - real x0 = 1.2345; + real x0 = c0; EXPECT_EQ(std::exp(x0), exp(x0)); } TEST(SimdScalarMathTest, erf) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::erf(x0), erf(x0)); } TEST(SimdScalarMathTest, erfc) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::erfc(x0), erfc(x0)); } TEST(SimdScalarMathTest, sincos) { - real x0 = 0.51256; + real x0 = c0; real s, c; sincos(x0, &s, &c); @@ -146,21 +148,21 @@ TEST(SimdScalarMathTest, sincos) TEST(SimdScalarMathTest, sin) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::sin(x0), sin(x0)); } TEST(SimdScalarMathTest, cos) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::cos(x0), cos(x0)); } TEST(SimdScalarMathTest, tan) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::tan(x0), tan(x0)); } @@ -168,29 +170,29 @@ TEST(SimdScalarMathTest, tan) TEST(SimdScalarMathTest, asin) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::asin(x0), asin(x0)); } TEST(SimdScalarMathTest, acos) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::acos(x0), acos(x0)); } TEST(SimdScalarMathTest, atan) { - real x0 = 0.51256; + real x0 = c0; EXPECT_EQ(std::atan(x0), atan(x0)); } TEST(SimdScalarMathTest, atan2) { - real x = 0.5; - real y = std::sqrt(0.75); + real x = c0; + real y = std::sqrt(c0); EXPECT_EQ(std::atan2(y, x), atan2(y, x)); @@ -198,7 +200,7 @@ TEST(SimdScalarMathTest, atan2) TEST(SimdScalarMathTest, pmeForceCorrection) { - real z2 = 0.51256; + real z2 = c0; // Calculate reference value for z2!=0 real z = std::sqrt(z2); @@ -216,7 +218,7 @@ TEST(SimdScalarMathTest, pmeForceCorrection) TEST(SimdScalarMathTest, pmePotentialCorrection) { - real z2 = 0.51256; + real z2 = c0; // Calculate reference value for z2!=0 real z = std::sqrt(z2); @@ -238,8 +240,8 @@ TEST(SimdScalarMathTest, pmePotentialCorrection) TEST(SimdScalarMathTest, invsqrtPairSingleAccuracy) { - double x0 = 1.2345; - double x1 = 9.8765; + double x0 = c1; + double x1 = c2; double out0, out1; @@ -251,7 +253,7 @@ TEST(SimdScalarMathTest, invsqrtPairSingleAccuracy) TEST(SimdScalarMathTest, invSingleAccuracy) { - double x0 = 1.2345; + double x0 = c1; EXPECT_EQ(1.0f/static_cast(x0), static_cast(invSingleAccuracy(x0))); @@ -259,7 +261,7 @@ TEST(SimdScalarMathTest, invSingleAccuracy) TEST(SimdScalarMathTest, maskzInvsqrtSingleAccuracy) { - double x0 = 1.2345; + double x0 = c1; EXPECT_EQ(invsqrt(static_cast(x0)), static_cast(maskzInvsqrtSingleAccuracy(x0, true))); @@ -269,7 +271,7 @@ TEST(SimdScalarMathTest, maskzInvsqrtSingleAccuracy) TEST(SimdScalarMathTest, logSingleAccuracy) { - double x0 = 1.2345; + double x0 = c1; EXPECT_EQ(std::log(static_cast(x0)), static_cast(logSingleAccuracy(x0))); @@ -277,7 +279,7 @@ TEST(SimdScalarMathTest, logSingleAccuracy) TEST(SimdScalarMathTest, exp2SingleAccuracy) { - double x0 = 1.2345; + double x0 = c1; EXPECT_EQ(std::exp2(static_cast(x0)), static_cast(exp2SingleAccuracy(x0))); @@ -285,7 +287,7 @@ TEST(SimdScalarMathTest, exp2SingleAccuracy) TEST(SimdScalarMathTest, expSingleAccuracy) { - double x0 = 1.2345; + double x0 = c1; EXPECT_EQ(std::exp(static_cast(x0)), static_cast(expSingleAccuracy(x0))); @@ -293,21 +295,21 @@ TEST(SimdScalarMathTest, expSingleAccuracy) TEST(SimdScalarMathTest, erfSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::erf(static_cast(x0)), static_cast(erfSingleAccuracy(x0))); } TEST(SimdScalarMathTest, erfcSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::erfc(static_cast(x0)), static_cast(erfcSingleAccuracy(x0))); } TEST(SimdScalarMathTest, sincosSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; double s, c; sincosSingleAccuracy(x0, &s, &c); @@ -318,7 +320,7 @@ TEST(SimdScalarMathTest, sincosSingleAccuracy) TEST(SimdScalarMathTest, sinSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::sin(static_cast(x0)), static_cast(sinSingleAccuracy(x0))); @@ -326,7 +328,7 @@ TEST(SimdScalarMathTest, sinSingleAccuracy) TEST(SimdScalarMathTest, cosSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::cos(static_cast(x0)), static_cast(cosSingleAccuracy(x0))); @@ -334,7 +336,7 @@ TEST(SimdScalarMathTest, cosSingleAccuracy) TEST(SimdScalarMathTest, tanSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::tan(static_cast(x0)), static_cast(tanSingleAccuracy(x0))); @@ -343,7 +345,7 @@ TEST(SimdScalarMathTest, tanSingleAccuracy) TEST(SimdScalarMathTest, asinSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::asin(static_cast(x0)), static_cast(asinSingleAccuracy(x0))); @@ -351,7 +353,7 @@ TEST(SimdScalarMathTest, asinSingleAccuracy) TEST(SimdScalarMathTest, acosSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::acos(static_cast(x0)), static_cast(acosSingleAccuracy(x0))); @@ -359,7 +361,7 @@ TEST(SimdScalarMathTest, acosSingleAccuracy) TEST(SimdScalarMathTest, atanSingleAccuracy) { - double x0 = 0.51256; + double x0 = c0; EXPECT_EQ(std::atan(static_cast(x0)), static_cast(atanSingleAccuracy(x0))); @@ -367,8 +369,8 @@ TEST(SimdScalarMathTest, atanSingleAccuracy) TEST(SimdScalarMathTest, atan2SingleAccuracy) { - double x = 0.5; - double y = std::sqrt(0.75); + double x = c0; + double y = std::sqrt(c0); EXPECT_EQ(std::atan2(static_cast(y), static_cast(x)), @@ -377,7 +379,7 @@ TEST(SimdScalarMathTest, atan2SingleAccuracy) TEST(SimdScalarMathTest, pmeForceCorrectionSingleAccuracy) { - double z2 = 0.51256; + double z2 = c0; // Calculate reference value for z2!=0 in single precision float z = std::sqrt(static_cast(z2)); @@ -391,7 +393,7 @@ TEST(SimdScalarMathTest, pmeForceCorrectionSingleAccuracy) TEST(SimdScalarMathTest, pmePotentialCorrectionSingleAccuracy) { - double z2 = 0.51256; + double z2 = c0; // Calculate reference value for z2!=0 in single precision float z = std::sqrt(static_cast(z2)); diff --git a/src/gromacs/simd/tests/scalar_util.cpp b/src/gromacs/simd/tests/scalar_util.cpp index daf1e87a3e..76e64c78a8 100644 --- a/src/gromacs/simd/tests/scalar_util.cpp +++ b/src/gromacs/simd/tests/scalar_util.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -41,6 +41,10 @@ #include "gromacs/simd/simd.h" #include "gromacs/utility/basedefinitions.h" +#include "testutils/testasserts.h" + +#include "data.h" + namespace gmx { namespace test @@ -55,7 +59,7 @@ namespace TEST(SimdScalarUtilTest, gatherLoadTranspose) { - real data[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; std::int32_t offset = 1; real v0, v1, v2, v3; @@ -74,7 +78,7 @@ TEST(SimdScalarUtilTest, gatherLoadTranspose) TEST(SimdScalarUtilTest, gatherLoadUTranspose) { - real data[6] = {1, 2, 3, 4, 5, 6}; + real data[6] = {c0, c1, c2, c3, c4, c5}; std::int32_t offset = 1; real v0, v1, v2; @@ -95,33 +99,33 @@ TEST(SimdScalarUtilTest, transposeScatterStoreU) transposeScatterStoreU<3>(data, &offset, v0, v1, v2); - EXPECT_EQ(real(0.0), data[0]); - EXPECT_EQ(real(0.0), data[1]); - EXPECT_EQ(real(0.0), data[2]); + EXPECT_EQ(czero, data[0]); + EXPECT_EQ(czero, data[1]); + EXPECT_EQ(czero, data[2]); EXPECT_EQ(v0, data[3]); EXPECT_EQ(v1, data[4]); EXPECT_EQ(v2, data[5]); - EXPECT_EQ(real(0.0), data[6]); - EXPECT_EQ(real(0.0), data[7]); - EXPECT_EQ(real(0.0), data[8]); + EXPECT_EQ(czero, data[6]); + EXPECT_EQ(czero, data[7]); + EXPECT_EQ(czero, data[8]); } TEST(SimdScalarUtilTest, transposeScatterIncrU) { real data[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; std::int32_t offset = 1; - real v0 = 1; - real v1 = 2; - real v2 = 3; + real v0 = c1; + real v1 = c2; + real v2 = c3; transposeScatterIncrU<3>(data, &offset, v0, v1, v2); EXPECT_EQ(real(10), data[0]); EXPECT_EQ(real(20), data[1]); EXPECT_EQ(real(30), data[2]); - EXPECT_EQ(real(41), data[3]); - EXPECT_EQ(real(52), data[4]); - EXPECT_EQ(real(63), data[5]); + EXPECT_EQ(real(40+c1), data[3]); + EXPECT_EQ(real(50+c2), data[4]); + EXPECT_EQ(real(60+c3), data[5]); EXPECT_EQ(real(70), data[6]); EXPECT_EQ(real(80), data[7]); EXPECT_EQ(real(90), data[8]); @@ -131,18 +135,18 @@ TEST(SimdScalarUtilTest, transposeScatterDecrU) { real data[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90}; std::int32_t offset = 1; - real v0 = 1; - real v1 = 2; - real v2 = 3; + real v0 = c1; + real v1 = c2; + real v2 = c3; transposeScatterDecrU<3>(data, &offset, v0, v1, v2); EXPECT_EQ(real(10), data[0]); EXPECT_EQ(real(20), data[1]); EXPECT_EQ(real(30), data[2]); - EXPECT_EQ(real(39), data[3]); - EXPECT_EQ(real(48), data[4]); - EXPECT_EQ(real(57), data[5]); + EXPECT_EQ(real(40-c1), data[3]); + EXPECT_EQ(real(50-c2), data[4]); + EXPECT_EQ(real(60-c3), data[5]); EXPECT_EQ(real(70), data[6]); EXPECT_EQ(real(80), data[7]); EXPECT_EQ(real(90), data[8]); @@ -151,7 +155,7 @@ TEST(SimdScalarUtilTest, transposeScatterDecrU) TEST(SimdScalarTest, expandScalarsToTriplets) { - real scalar = 1.234; + real scalar = c1; real t0, t1, t2; expandScalarsToTriplets(scalar, &t0, &t1, &t2); @@ -163,7 +167,7 @@ TEST(SimdScalarTest, expandScalarsToTriplets) TEST(SimdScalarUtilTest, gatherLoadBySimdIntTranspose) { - real data[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; std::int32_t offset = 1; real v0, v1, v2, v3; @@ -182,7 +186,7 @@ TEST(SimdScalarUtilTest, gatherLoadBySimdIntTranspose) TEST(SimdScalarUtilTest, gatherLoadUBySimdIntTranspose) { - real data[8] = {1, 2, 3, 4, 5, 6, 7, 8}; + real data[8] = {c0, c1, c2, c3, c4, c5, c6, c7}; std::int32_t offset = 1; real v0, v1; @@ -195,22 +199,22 @@ TEST(SimdScalarUtilTest, gatherLoadUBySimdIntTranspose) TEST(SimdScalarUtilTest, reduceIncr4ReturnSum) { real data[6] = {0, 0, 0, 0, 0, 0}; - real v0 = 1; - real v1 = 2; - real v2 = 3; - real v3 = 4; + real v0 = c1; + real v1 = c2; + real v2 = c3; + real v3 = c4; real sum; sum = reduceIncr4ReturnSum(data+1, v0, v1, v2, v3); - EXPECT_EQ(real(0.0), data[0]); + EXPECT_EQ(czero, data[0]); EXPECT_EQ(v0, data[1]); EXPECT_EQ(v1, data[2]); EXPECT_EQ(v2, data[3]); EXPECT_EQ(v3, data[4]); - EXPECT_EQ(real(0.0), data[5]); + EXPECT_EQ(czero, data[5]); - EXPECT_EQ(real(v0+v1+v2+v3), sum); + EXPECT_REAL_EQ_TOL(real(v0+v1+v2+v3), sum, defaultRealTolerance()); } /*! \} */ diff --git a/src/gromacs/simd/tests/simd.cpp b/src/gromacs/simd/tests/simd.cpp index dd56b0d425..6aa0fa04ff 100644 --- a/src/gromacs/simd/tests/simd.cpp +++ b/src/gromacs/simd/tests/simd.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -64,29 +64,48 @@ namespace test * them in a single place makes sure they are consistent. */ #if GMX_SIMD_HAVE_REAL -const SimdReal rSimd_1_2_3 = setSimdRealFrom3R(1, 2, 3); -const SimdReal rSimd_4_5_6 = setSimdRealFrom3R(4, 5, 6); -const SimdReal rSimd_7_8_9 = setSimdRealFrom3R(7, 8, 9); -const SimdReal rSimd_5_7_9 = setSimdRealFrom3R(5, 7, 9); -const SimdReal rSimd_m1_m2_m3 = setSimdRealFrom3R(-1, -2, -3); -const SimdReal rSimd_3_1_4 = setSimdRealFrom3R(3, 1, 4); -const SimdReal rSimd_m3_m1_m4 = setSimdRealFrom3R(-3, -1, -4); -const SimdReal rSimd_2p25 = setSimdRealFrom1R(2.25); -const SimdReal rSimd_3p25 = setSimdRealFrom1R(3.25); -const SimdReal rSimd_3p75 = setSimdRealFrom1R(3.75); +const SimdReal rSimd_c0c1c2 = setSimdRealFrom3R( c0, c1, c2); +const SimdReal rSimd_c3c4c5 = setSimdRealFrom3R( c3, c4, c5); +const SimdReal rSimd_c6c7c8 = setSimdRealFrom3R( c6, c7, c8); +const SimdReal rSimd_c3c0c4 = setSimdRealFrom3R( c3, c0, c4); +const SimdReal rSimd_c4c6c8 = setSimdRealFrom3R( c4, c6, c8); +const SimdReal rSimd_c7c2c3 = setSimdRealFrom3R( c7, c2, c3); +const SimdReal rSimd_m0m1m2 = setSimdRealFrom3R(-c0, -c1, -c2); +const SimdReal rSimd_m3m0m4 = setSimdRealFrom3R(-c3, -c0, -c4); + +const SimdReal rSimd_2p25 = setSimdRealFrom1R( 2.25); +const SimdReal rSimd_3p25 = setSimdRealFrom1R( 3.25); +const SimdReal rSimd_3p75 = setSimdRealFrom1R( 3.75); const SimdReal rSimd_m2p25 = setSimdRealFrom1R(-2.25); const SimdReal rSimd_m3p25 = setSimdRealFrom1R(-3.25); const SimdReal rSimd_m3p75 = setSimdRealFrom1R(-3.75); const SimdReal rSimd_Exp = setSimdRealFrom3R( 1.4055235171027452623914516e+18, 5.3057102734253445623914516e-13, -2.1057102745623934534514516e+16); -# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE +#if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE // Make sure we also test exponents outside single precision when we use double const SimdReal rSimd_ExpDouble = setSimdRealFrom3R( 6.287393598732017379054414e+176, 8.794495252903116023030553e-140, -3.637060701570496477655022e+202); -# endif -#endif // GMX_SIMD_HAVE_REAL +#endif // GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE + +#if GMX_SIMD_HAVE_LOGICAL +// The numbers below all have exponent (2^0), which will not change with AND/OR operations. +// We also leave the last part of the mantissa as zeros, to avoid rounding issues in the compiler +#if GMX_DOUBLE +const SimdReal rSimd_logicalA = setSimdRealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 +const SimdReal rSimd_logicalB = setSimdRealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 +const SimdReal rSimd_logicalResultAnd = setSimdRealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 +const SimdReal rSimd_logicalResultOr = setSimdRealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 +#else // GMX_DOUBLE +const SimdReal rSimd_logicalA = setSimdRealFrom1R(1.3333282470703125); // mantissa 0101010101010101 +const SimdReal rSimd_logicalB = setSimdRealFrom1R(1.79998779296875); // mantissa 1100110011001100 +const SimdReal rSimd_logicalResultAnd = setSimdRealFrom1R(1.26666259765625); // mantissa 0100010001000100 +const SimdReal rSimd_logicalResultOr = setSimdRealFrom1R(1.8666534423828125); // mantissa 1101110111011101 +#endif // GMX_DOUBLE +#endif // GMX_SIMD_HAVE_LOGICAL + +#endif // GMX_SIMD_HAVE_REAL #if GMX_SIMD_HAVE_INT32_ARITHMETICS const SimdInt32 iSimd_1_2_3 = setSimdIntFrom3I(1, 2, 3); const SimdInt32 iSimd_4_5_6 = setSimdIntFrom3I(4, 5, 6); diff --git a/src/gromacs/simd/tests/simd.h b/src/gromacs/simd/tests/simd.h index 978a3dfa2d..f4aac8d657 100644 --- a/src/gromacs/simd/tests/simd.h +++ b/src/gromacs/simd/tests/simd.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -81,6 +81,7 @@ #include "gromacs/simd/simd.h" #include "base.h" +#include "data.h" #if GMX_SIMD @@ -108,13 +109,15 @@ namespace test * them in a single place makes sure they are consistent. */ #if GMX_SIMD_HAVE_REAL -extern const SimdReal rSimd_1_2_3; //!< Generic (different) fp values. -extern const SimdReal rSimd_4_5_6; //!< Generic (different) fp values. -extern const SimdReal rSimd_7_8_9; //!< Generic (different) fp values. -extern const SimdReal rSimd_5_7_9; //!< rSimd_1_2_3 + rSimd_4_5_6. -extern const SimdReal rSimd_m1_m2_m3; //!< Generic negative floating-point values. -extern const SimdReal rSimd_3_1_4; //!< Used to test min/max. -extern const SimdReal rSimd_m3_m1_m4; //!< negative rSimd_3_1_4. +extern const SimdReal rSimd_c0c1c2; //!< c0,c1,c2 repeated +extern const SimdReal rSimd_c3c4c5; //!< c3,c4,c5 repeated +extern const SimdReal rSimd_c6c7c8; //!< c6,c7,c8 repeated +extern const SimdReal rSimd_c3c0c4; //!< c3,c0,c4 repeated +extern const SimdReal rSimd_c4c6c8; //!< c4,c6,c8 repeated +extern const SimdReal rSimd_c7c2c3; //!< c7,c2,c3 repeated +extern const SimdReal rSimd_m0m1m2; //!< -c0,-c1,-c2 repeated +extern const SimdReal rSimd_m3m0m4; //!< -c3,-c0,-c4 repeated + extern const SimdReal rSimd_2p25; //!< Value that rounds down. extern const SimdReal rSimd_3p25; //!< Value that rounds down. extern const SimdReal rSimd_3p75; //!< Value that rounds up. @@ -123,6 +126,14 @@ extern const SimdReal rSimd_m3p25; //!< Negative value that rounds up. extern const SimdReal rSimd_m3p75; //!< Negative value that rounds down. //! Three large floating-point values whose exponents are >32. extern const SimdReal rSimd_Exp; + +#if GMX_SIMD_HAVE_LOGICAL +extern const SimdReal rSimd_logicalA; //!< Bit pattern to test logical ops +extern const SimdReal rSimd_logicalB; //!< Bit pattern to test logical ops +extern const SimdReal rSimd_logicalResultOr; //!< Result or bitwise 'or' of A and B +extern const SimdReal rSimd_logicalResultAnd; //!< Result or bitwise 'and' of A and B +#endif // GMX_SIMD_HAVE_LOGICAL + # if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE // Make sure we also test exponents outside single precision when we use double extern const SimdReal rSimd_ExpDouble; diff --git a/src/gromacs/simd/tests/simd4.cpp b/src/gromacs/simd/tests/simd4.cpp index c50f8db6a2..edb66badf0 100644 --- a/src/gromacs/simd/tests/simd4.cpp +++ b/src/gromacs/simd/tests/simd4.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017, 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. @@ -39,6 +39,8 @@ #include "gromacs/simd/simd.h" #include "gromacs/utility/basedefinitions.h" +#include "data.h" + #if GMX_SIMD namespace gmx @@ -52,26 +54,34 @@ namespace test #if GMX_SIMD4_HAVE_REAL -const Simd4Real rSimd4_1_2_3 = setSimd4RealFrom3R(1, 2, 3); -const Simd4Real rSimd4_4_5_6 = setSimd4RealFrom3R(4, 5, 6); -const Simd4Real rSimd4_7_8_9 = setSimd4RealFrom3R(7, 8, 9); -const Simd4Real rSimd4_5_7_9 = setSimd4RealFrom3R(5, 7, 9); -const Simd4Real rSimd4_m1_m2_m3 = setSimd4RealFrom3R(-1, -2, -3); -const Simd4Real rSimd4_3_1_4 = setSimd4RealFrom3R(3, 1, 4); -const Simd4Real rSimd4_m3_m1_m4 = setSimd4RealFrom3R(-3, -1, -4); +const Simd4Real rSimd4_c0c1c2 = setSimd4RealFrom3R( c0, c1, c2); +const Simd4Real rSimd4_c3c4c5 = setSimd4RealFrom3R( c3, c4, c5); +const Simd4Real rSimd4_c6c7c8 = setSimd4RealFrom3R( c6, c7, c8); +const Simd4Real rSimd4_c3c0c4 = setSimd4RealFrom3R( c3, c0, c4); +const Simd4Real rSimd4_c4c6c8 = setSimd4RealFrom3R( c4, c6, c8); +const Simd4Real rSimd4_c7c2c3 = setSimd4RealFrom3R( c7, c2, c3); +const Simd4Real rSimd4_m0m1m2 = setSimd4RealFrom3R(-c0, -c1, -c2); +const Simd4Real rSimd4_m3m0m4 = setSimd4RealFrom3R(-c3, -c0, -c4); const Simd4Real rSimd4_2p25 = setSimd4RealFrom1R(2.25); const Simd4Real rSimd4_3p75 = setSimd4RealFrom1R(3.75); const Simd4Real rSimd4_m2p25 = setSimd4RealFrom1R(-2.25); const Simd4Real rSimd4_m3p75 = setSimd4RealFrom1R(-3.75); -const Simd4Real rSimd4_Exp = setSimd4RealFrom3R( 1.4055235171027452623914516e+18, - 5.3057102734253445623914516e-13, - -2.1057102745623934534514516e+16); -# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE -// Make sure we also test exponents outside single precision when we use double -const Simd4Real rSimd_ExpDouble = setSimd4RealFrom3R( 6.287393598732017379054414e+176, - 8.794495252903116023030553e-140, - -3.637060701570496477655022e+202); -# endif + +#if GMX_SIMD_HAVE_LOGICAL +// The numbers below all have exponent (2^0), which will not change with AND/OR operations. +// We also leave the last part of the mantissa as zeros, to avoid rounding issues in the compiler +#if GMX_DOUBLE +const Simd4Real rSimd4_logicalA = setSimd4RealFrom1R(1.3333333332557231188); // mantissa 01010101010101010101010101010101 +const Simd4Real rSimd4_logicalB = setSimd4RealFrom1R(1.7999999998137354851); // mantissa 11001100110011001100110011001100 +const Simd4Real rSimd4_logicalResultAnd = setSimd4RealFrom1R(1.266666666604578495); // mantissa 01000100010001000100010001000100 +const Simd4Real rSimd4_logicalResultOr = setSimd4RealFrom1R(1.8666666664648801088); // mantissa 11011101110111011101110111011101 +#else // GMX_DOUBLE +const Simd4Real rSimd4_logicalA = setSimd4RealFrom1R(1.3333282470703125); // mantissa 0101010101010101 +const Simd4Real rSimd4_logicalB = setSimd4RealFrom1R(1.79998779296875); // mantissa 1100110011001100 +const Simd4Real rSimd4_logicalResultAnd = setSimd4RealFrom1R(1.26666259765625); // mantissa 0100010001000100 +const Simd4Real rSimd4_logicalResultOr = setSimd4RealFrom1R(1.8666534423828125); // mantissa 1101110111011101 +#endif // GMX_DOUBLE +#endif // GMX_SIMD_HAVE_LOGICAL ::std::vector simd4Real2Vector(const Simd4Real simd4) diff --git a/src/gromacs/simd/tests/simd4.h b/src/gromacs/simd/tests/simd4.h index 4432227cf7..4d4eecde53 100644 --- a/src/gromacs/simd/tests/simd4.h +++ b/src/gromacs/simd/tests/simd4.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017, 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. @@ -54,6 +54,7 @@ #include "gromacs/simd/simd.h" #include "base.h" +#include "data.h" #if GMX_SIMD @@ -67,29 +68,34 @@ namespace test /*! \{ */ #if GMX_SIMD4_HAVE_REAL -extern const Simd4Real rSimd4_1_2_3; //!< Generic (different) fp values. -extern const Simd4Real rSimd4_4_5_6; //!< Generic (different) fp values. -extern const Simd4Real rSimd4_7_8_9; //!< Generic (different) fp values. -extern const Simd4Real rSimd4_5_7_9; //!< rSimd_1_2_3 + rSimd_4_5_6. -extern const Simd4Real rSimd4_m1_m2_m3; //!< Generic negative fp values. -extern const Simd4Real rSimd4_3_1_4; //!< Used to test min/max. -extern const Simd4Real rSimd4_m3_m1_m4; //!< negative rSimd_3_1_4. +extern const Simd4Real rSimd4_c0c1c2; //!< c0,c1,c2 repeated +extern const Simd4Real rSimd4_c3c4c5; //!< c3,c4,c5 repeated +extern const Simd4Real rSimd4_c6c7c8; //!< c6,c7,c8 repeated +extern const Simd4Real rSimd4_c3c0c4; //!< c3,c0,c4 repeated +extern const Simd4Real rSimd4_c4c6c8; //!< c4,c6,c8 repeated +extern const Simd4Real rSimd4_c7c2c3; //!< c7,c2,c3 repeated +extern const Simd4Real rSimd4_m0m1m2; //!< -c0,-c1,-c2 repeated +extern const Simd4Real rSimd4_m3m0m4; //!< -c3,-c0,-c4 repeated extern const Simd4Real rSimd4_2p25; //!< Value that rounds down. extern const Simd4Real rSimd4_3p75; //!< Value that rounds up. extern const Simd4Real rSimd4_m2p25; //!< Negative value that rounds up. extern const Simd4Real rSimd4_m3p75; //!< Negative value that rounds down. //! Three large floating-point values whose exponents are >32. extern const Simd4Real rSimd4_Exp; -# if GMX_SIMD_HAVE_DOUBLE && GMX_DOUBLE -// Make sure we also test exponents outside single precision when we use double -extern const Simd4Real rSimd4_ExpDouble; -# endif -extern const Simd4Real rSimd4_Bits1; //!< Pattern F0 repeated to fill single/double. -extern const Simd4Real rSimd4_Bits2; //!< Pattern CC repeated to fill single/double. -extern const Simd4Real rSimd4_Bits3; //!< Pattern C0 repeated to fill single/double. -extern const Simd4Real rSimd4_Bits4; //!< Pattern 0C repeated to fill single/double. -extern const Simd4Real rSimd4_Bits5; //!< Pattern FC repeated to fill single/double. -extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill single/double. + +#if GMX_SIMD_HAVE_LOGICAL +extern const Simd4Real rSimd4_logicalA; //!< Bit pattern to test logical ops +extern const Simd4Real rSimd4_logicalB; //!< Bit pattern to test logical ops +extern const Simd4Real rSimd4_logicalResultOr; //!< Result or bitwise 'or' of A and B +extern const Simd4Real rSimd4_logicalResultAnd; //!< Result or bitwise 'and' of A and B +#endif // GMX_SIMD_HAVE_LOGICAL + +extern const Simd4Real rSimd4_Bits1; //!< Pattern F0 repeated to fill single/double. +extern const Simd4Real rSimd4_Bits2; //!< Pattern CC repeated to fill single/double. +extern const Simd4Real rSimd4_Bits3; //!< Pattern C0 repeated to fill single/double. +extern const Simd4Real rSimd4_Bits4; //!< Pattern 0C repeated to fill single/double. +extern const Simd4Real rSimd4_Bits5; //!< Pattern FC repeated to fill single/double. +extern const Simd4Real rSimd4_Bits6; //!< Pattern 3C repeated to fill single/double. /*! \internal * \brief diff --git a/src/gromacs/simd/tests/simd4_floatingpoint.cpp b/src/gromacs/simd/tests/simd4_floatingpoint.cpp index 3705aab566..b2300ec8be 100644 --- a/src/gromacs/simd/tests/simd4_floatingpoint.cpp +++ b/src/gromacs/simd/tests/simd4_floatingpoint.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -40,6 +40,9 @@ #include "gromacs/simd/simd.h" #include "gromacs/utility/basedefinitions.h" +#include "testutils/testasserts.h" + +#include "data.h" #include "simd4.h" #if GMX_SIMD @@ -67,75 +70,79 @@ TEST_F(Simd4FloatingpointTest, setZero) TEST_F(Simd4FloatingpointTest, set) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom1R(1.0), Simd4Real(1.0)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom1R(c1), Simd4Real(c1)); } TEST_F(Simd4FloatingpointTest, add) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_5_7_9, rSimd4_1_2_3 + rSimd4_4_5_6); // 1+4=5, 2+5=7, 3+6=9 + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 + c3, c1 + c4, c2 + c5 ), + rSimd4_c0c1c2 + rSimd4_c3c4c5); + } TEST_F(Simd4FloatingpointTest, sub) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_4_5_6, rSimd4_5_7_9 - rSimd4_1_2_3); // 5-1=4, 7-2=5, 9-3=6 + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 - c3, c1 - c4, c2 - c5 ), + rSimd4_c0c1c2 - rSimd4_c3c4c5); } TEST_F(Simd4FloatingpointTest, mul) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(4, 10, 18), rSimd4_1_2_3 * rSimd4_4_5_6); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0 * c3, c1 * c4, c2 * c5 ), + rSimd4_c0c1c2 * rSimd4_c3c4c5); } TEST_F(Simd4FloatingpointTest, fma) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(11, 18, 27), fma(rSimd4_1_2_3, rSimd4_4_5_6, rSimd4_7_8_9)); // 1*4+7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(c0 * c3 + c6, c1 * c4 + c7, c2 * c5 + c8), + fma(rSimd4_c0c1c2, rSimd4_c3c4c5, rSimd4_c6c7c8)); } TEST_F(Simd4FloatingpointTest, fms) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-3, 2, 9), fms(rSimd4_1_2_3, rSimd4_4_5_6, rSimd4_7_8_9)); // 1*4-7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(c0 * c3 - c6, c1 * c4 - c7, c2 * c5 - c8), + fms(rSimd4_c0c1c2, rSimd4_c3c4c5, rSimd4_c6c7c8)); } TEST_F(Simd4FloatingpointTest, fnma) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(3, -2, -9), fnma(rSimd4_1_2_3, rSimd4_4_5_6, rSimd4_7_8_9)); // -1*4+7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(c6 - c0 * c3, c7 - c1 * c4, c8 - c2 * c5), + fnma(rSimd4_c0c1c2, rSimd4_c3c4c5, rSimd4_c6c7c8)); } TEST_F(Simd4FloatingpointTest, fnms) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-11, -18, -27), fnms(rSimd4_1_2_3, rSimd4_4_5_6, rSimd4_7_8_9)); // -1*4-7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD4_REAL_NEAR(setSimd4RealFrom3R(-c0 * c3 - c6, -c1 * c4 - c7, -c2 * c5 - c8), + fnms(rSimd4_c0c1c2, rSimd4_c3c4c5, rSimd4_c6c7c8)); } TEST_F(Simd4FloatingpointTest, abs) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_1_2_3, abs(rSimd4_1_2_3)); // fabs(x)=x - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_1_2_3, abs(rSimd4_m1_m2_m3)); // fabs(-x)=x + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, abs(rSimd4_c0c1c2)); // fabs(x)=x + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, abs(rSimd4_m0m1m2)); // fabs(-x)=x } TEST_F(Simd4FloatingpointTest, neg) { - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_m1_m2_m3, -rSimd4_1_2_3); // fneg(x)=-x - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_1_2_3, -rSimd4_m1_m2_m3); // fneg(-x)=x + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_m0m1m2, -(rSimd4_c0c1c2)); // fneg(x)=-x + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, -(rSimd4_m0m1m2)); // fneg(-x)=x } #if GMX_SIMD_HAVE_LOGICAL -/* 1.3333282470703125 has mantissa 0101010101010101 (followed by zeros) - * 1.79998779296875 has mantissa 1100110011001100 (followed by zeros) - * 1.26666259765625 has mantissa 0100010001000100 (followed by zeros) - * 1.8666534423828125 has mantissa 1101110111011101 (followed by zeros) - * - * Since all of them have the same exponent (2^0), the exponent will - * not change with AND or OR operations. - */ TEST_F(Simd4FloatingpointTest, and) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom1R(1.26666259765625), - Simd4Real(1.3333282470703125) & Simd4Real(1.79998779296875)); + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultAnd, + (rSimd4_logicalA & rSimd4_logicalB)); } TEST_F(Simd4FloatingpointTest, or) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom1R(1.8666534423828125), - Simd4Real(1.3333282470703125) | Simd4Real(1.79998779296875)); + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_logicalResultOr, + (rSimd4_logicalA | rSimd4_logicalB)); } TEST_F(Simd4FloatingpointTest, xor) @@ -144,8 +151,8 @@ TEST_F(Simd4FloatingpointTest, xor) * in only the sign bit being set. We then use this bit change the sign of * different numbers. */ - Simd4Real signbit = Simd4Real(1.5) ^ Simd4Real(-1.5); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-1, 2, -3), signbit ^ setSimd4RealFrom3R(1, -2, 3)); + Simd4Real signbit = Simd4Real(c1) ^ Simd4Real(-c1); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c2, c3, -c4), signbit ^ setSimd4RealFrom3R(c2, -c3, c4)); } TEST_F(Simd4FloatingpointTest, andNot) @@ -153,26 +160,26 @@ TEST_F(Simd4FloatingpointTest, andNot) /* Use xor (which we already tested, so fix that first if both tests fail) * to extract the sign bit, and then use andnot to take absolute values. */ - Simd4Real signbit = Simd4Real(1.5) ^ Simd4Real(-1.5); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 2, 3), andNot(signbit, setSimd4RealFrom3R(-1, 2, -3))); + Simd4Real signbit = Simd4Real(c1) ^ Simd4Real(-c1); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c2, c3, c4), andNot(signbit, setSimd4RealFrom3R(-c2, c3, -c4))); } #endif TEST_F(Simd4FloatingpointTest, max) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(3, 2, 4), max(rSimd4_1_2_3, rSimd4_3_1_4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(3, 2, 4), max(rSimd4_3_1_4, rSimd4_1_2_3)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-1, -1, -3), max(rSimd4_m1_m2_m3, rSimd4_m3_m1_m4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-1, -1, -3), max(rSimd4_m3_m1_m4, rSimd4_m1_m2_m3)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c3, c1, c4), max(rSimd4_c0c1c2, rSimd4_c3c0c4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c3, c1, c4), max(rSimd4_c3c0c4, rSimd4_c0c1c2)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c0, -c0, -c2), max(rSimd4_m0m1m2, rSimd4_m3m0m4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c0, -c0, -c2), max(rSimd4_m3m0m4, rSimd4_m0m1m2)); } TEST_F(Simd4FloatingpointTest, min) { - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 1, 3), min(rSimd4_1_2_3, rSimd4_3_1_4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 1, 3), min(rSimd4_3_1_4, rSimd4_1_2_3)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-3, -2, -4), min(rSimd4_m1_m2_m3, rSimd4_m3_m1_m4)); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-3, -2, -4), min(rSimd4_m3_m1_m4, rSimd4_m1_m2_m3)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c0, c0, c2), min(rSimd4_c0c1c2, rSimd4_c3c0c4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R( c0, c0, c2), min(rSimd4_c3c0c4, rSimd4_c0c1c2)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c3, -c1, -c4), min(rSimd4_m0m1m2, rSimd4_m3m0m4)); + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(-c3, -c1, -c4), min(rSimd4_m3m0m4, rSimd4_m0m1m2)); } TEST_F(Simd4FloatingpointTest, round) @@ -214,46 +221,46 @@ TEST_F(Simd4FloatingpointTest, gmxSimd4RsqrtR) TEST_F(Simd4FloatingpointTest, cmpEqAndSelectByMask) { - Simd4Bool eq = (rSimd4_5_7_9 == rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, 3), selectByMask(rSimd4_1_2_3, eq)); + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, c2), selectByMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, selectByNotMask) { - Simd4Bool eq = (rSimd4_5_7_9 == rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 2, 0), selectByNotMask(rSimd4_1_2_3, eq)); + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByNotMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, cmpNe) { - Simd4Bool eq = (rSimd4_5_7_9 != rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 2, 0), selectByMask(rSimd4_1_2_3, eq)); + Simd4Bool eq = rSimd4_c4c6c8 != rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByMask(rSimd4_c0c1c2, eq)); } TEST_F(Simd4FloatingpointTest, cmpLe) { - Simd4Bool le = (rSimd4_5_7_9 <= rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_1_2_3, selectByMask(rSimd4_1_2_3, le)); + Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, selectByMask(rSimd4_c0c1c2, le)); } TEST_F(Simd4FloatingpointTest, cmpLt) { - Simd4Bool lt = (rSimd4_5_7_9 < rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 2, 0), selectByMask(rSimd4_1_2_3, lt)); + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c0, c1, 0), selectByMask(rSimd4_c0c1c2, lt)); } TEST_F(Simd4FloatingpointTest, andB) { - Simd4Bool eq = (rSimd4_5_7_9 == rSimd4_7_8_9); - Simd4Bool le = (rSimd4_5_7_9 <= rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, 3), selectByMask(rSimd4_1_2_3, eq && le)); + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool le = rSimd4_c4c6c8 <= rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(0, 0, c2), selectByMask(rSimd4_c0c1c2, (eq && le))); } TEST_F(Simd4FloatingpointTest, orB) { - Simd4Bool eq = (rSimd4_5_7_9 == rSimd4_7_8_9); - Simd4Bool lt = (rSimd4_5_7_9 < rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(1, 2, 3), selectByMask(rSimd4_1_2_3, eq || lt)); + Simd4Bool eq = rSimd4_c4c6c8 == rSimd4_c6c7c8; + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(rSimd4_c0c1c2, selectByMask(rSimd4_c0c1c2, (eq || lt))); } TEST_F(Simd4FloatingpointTest, anyTrue) @@ -264,24 +271,24 @@ TEST_F(Simd4FloatingpointTest, anyTrue) * We cannot check for truth values for "any" element beyond the first, * since that part of the data will not be used if simd width is 1. */ - eq = (rSimd4_5_7_9 == setSimd4RealFrom3R(5, 0, 0)); + eq = (rSimd4_c4c6c8 == setSimd4RealFrom3R(c4, 0, 0)); EXPECT_TRUE(anyTrue(eq)); - eq = (rSimd4_1_2_3 == rSimd4_4_5_6); + eq = (rSimd4_c0c1c2 == rSimd4_c3c4c5); EXPECT_FALSE(anyTrue(eq)); } TEST_F(Simd4FloatingpointTest, blend) { - Simd4Bool lt = (rSimd4_5_7_9 < rSimd4_7_8_9); - GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(4, 5, 3), blend(rSimd4_1_2_3, rSimd4_4_5_6, lt)); + Simd4Bool lt = rSimd4_c4c6c8 < rSimd4_c6c7c8; + GMX_EXPECT_SIMD4_REAL_EQ(setSimd4RealFrom3R(c3, c4, c2), blend(rSimd4_c0c1c2, rSimd4_c3c4c5, lt)); } TEST_F(Simd4FloatingpointTest, reduce) { // The horizontal sum of the SIMD variable depends on the width, so // simply store it an extra time and calculate what the sum should be - std::vector v = simd4Real2Vector(rSimd4_1_2_3); + std::vector v = simd4Real2Vector(rSimd4_c3c4c5); real sum = 0.0; for (int i = 0; i < GMX_SIMD4_WIDTH; i++) @@ -289,19 +296,15 @@ TEST_F(Simd4FloatingpointTest, reduce) sum += v[i]; } - EXPECT_EQ(sum, reduce(rSimd4_1_2_3)); + EXPECT_REAL_EQ_TOL(sum, reduce(rSimd4_c3c4c5), defaultRealTolerance() ); } TEST_F(Simd4FloatingpointTest, dotProduct) { - Simd4Real v1 = setSimd4RealFrom3R(1, 4, 5); - Simd4Real v2 = setSimd4RealFrom3R(3, 8, 2); -# if GMX_DOUBLE - EXPECT_DOUBLE_EQ(45.0, dotProduct(v1, v2)); -# else - EXPECT_FLOAT_EQ(45.0, dotProduct(v1, v2)); -# endif + real res = c0*c3 + c1*c4 + c2*c5; + + EXPECT_REAL_EQ_TOL(res, dotProduct(rSimd4_c0c1c2, rSimd4_c3c4c5), defaultRealTolerance()); } TEST_F(Simd4FloatingpointTest, transpose) @@ -317,10 +320,11 @@ TEST_F(Simd4FloatingpointTest, transpose) // Assign data with tens as row, single-digit as column for (i = 0; i < 4; i++) { - p0[i] = 0*10 + i*1; - p1[i] = 1*10 + i*1; - p2[i] = 2*10 + i*1; - p3[i] = 3*10 + i*1; + // Scale by 1+100*eps to use low bits tii + p0[i] = (0*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); + p1[i] = (1*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); + p2[i] = (2*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); + p3[i] = (3*10 + i*1) * (1.0 + 100*GMX_REAL_EPS); } v0 = load4(p0); @@ -337,10 +341,10 @@ TEST_F(Simd4FloatingpointTest, transpose) for (i = 0; i < 4; i++) { - EXPECT_EQ(i*10+0, p0[i]); - EXPECT_EQ(i*10+1, p1[i]); - EXPECT_EQ(i*10+2, p2[i]); - EXPECT_EQ(i*10+3, p3[i]); + EXPECT_REAL_EQ_TOL( (i*10+0) * (1.0 + 100*GMX_REAL_EPS), p0[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL( (i*10+1) * (1.0 + 100*GMX_REAL_EPS), p1[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL( (i*10+2) * (1.0 + 100*GMX_REAL_EPS), p2[i], defaultRealTolerance()); + EXPECT_REAL_EQ_TOL( (i*10+3) * (1.0 + 100*GMX_REAL_EPS), p3[i], defaultRealTolerance()); } } diff --git a/src/gromacs/simd/tests/simd4_vector_operations.cpp b/src/gromacs/simd/tests/simd4_vector_operations.cpp index f32d4ff14b..97ae2d2d1f 100644 --- a/src/gromacs/simd/tests/simd4_vector_operations.cpp +++ b/src/gromacs/simd/tests/simd4_vector_operations.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017, 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. @@ -39,6 +39,7 @@ #include "gromacs/simd/simd.h" #include "gromacs/simd/vector_operations.h" +#include "data.h" #include "simd4.h" #if GMX_SIMD @@ -61,10 +62,12 @@ typedef Simd4Test Simd4VectorOperationsTest; TEST_F(Simd4VectorOperationsTest, norm2) { - Simd4Real simdX = setSimd4RealFrom3R(1, 2, 3); - Simd4Real simdY = setSimd4RealFrom3R(3, 0, 5); - Simd4Real simdZ = setSimd4RealFrom3R(4, 1, 8); - Simd4Real simdR2 = setSimd4RealFrom3R(26, 5, 98); + Simd4Real simdX = rSimd4_c0c1c2; + Simd4Real simdY = rSimd4_c3c4c5; + Simd4Real simdZ = rSimd4_c6c7c8; + Simd4Real simdR2 = setSimd4RealFrom3R(c0*c0 + c3*c3 + c6*c6, + c1*c1 + c4*c4 + c7*c7, + c2*c2 + c5*c5 + c8*c8); setUlpTol(2); GMX_EXPECT_SIMD4_REAL_NEAR(simdR2, norm2(simdX, simdY, simdZ)); diff --git a/src/gromacs/simd/tests/simd_floatingpoint.cpp b/src/gromacs/simd/tests/simd_floatingpoint.cpp index 4e41134378..ce994b6e3d 100644 --- a/src/gromacs/simd/tests/simd_floatingpoint.cpp +++ b/src/gromacs/simd/tests/simd_floatingpoint.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -42,6 +42,7 @@ #include "testutils/testasserts.h" +#include "data.h" #include "simd.h" #if GMX_SIMD @@ -70,106 +71,103 @@ TEST_F(SimdFloatingpointTest, setZero) TEST_F(SimdFloatingpointTest, set) { - real r = 2.0; - real *p = &r; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(1.0), SimdReal(1.0)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(r), SimdReal(*p)); + const real *p = &c0; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(c1), SimdReal(c1)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(c0), SimdReal(*p)); } TEST_F(SimdFloatingpointTest, add) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_5_7_9, - (rSimd_1_2_3 + rSimd_4_5_6)); // 1+4=5, 2+5=7, 3+6=9 + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + c4, c2 + c5 ), + rSimd_c0c1c2 + rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, maskAdd) { - SimdBool m = setSimdRealFrom3R(1, 0, 1) != setZero(); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(5, 2, 9), - maskAdd(rSimd_1_2_3, rSimd_4_5_6, m)); + SimdBool m = setSimdRealFrom3R(c6, 0, c7) != setZero(); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 + c3, c1 + 0.0, c2 + c5 ), + maskAdd(rSimd_c0c1c2, rSimd_c3c4c5, m)); } TEST_F(SimdFloatingpointTest, sub) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_4_5_6, - (rSimd_5_7_9 - rSimd_1_2_3)); // 5-1=4, 7-2=5, 9-3=6 + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 - c3, c1 - c4, c2 - c5 ), + rSimd_c0c1c2 - rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, mul) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(4, 10, 18), - (rSimd_1_2_3 * rSimd_4_5_6)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, c1 * c4, c2 * c5 ), + rSimd_c0c1c2 * rSimd_c3c4c5); } TEST_F(SimdFloatingpointTest, maskzMul) { - SimdBool m = setSimdRealFrom3R(1, 0, 1) != setZero(); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(4, 0, 18), - maskzMul(rSimd_1_2_3, rSimd_4_5_6, m)); + SimdBool m = setSimdRealFrom3R(c1, 0, c1) != setZero(); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3, 0.0, c2 * c5 ), + maskzMul(rSimd_c0c1c2, rSimd_c3c4c5, m)); } TEST_F(SimdFloatingpointTest, fma) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(11, 18, 27), - fma(rSimd_1_2_3, rSimd_4_5_6, rSimd_7_8_9)); // 1*4+7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3 + c6, c1 * c4 + c7, c2 * c5 + c8), + fma(rSimd_c0c1c2, rSimd_c3c4c5, rSimd_c6c7c8)); } + TEST_F(SimdFloatingpointTest, maskzFma) { - SimdBool m = setSimdRealFrom3R(1, 0, 1) != setZero(); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(11, 0, 27), - maskzFma(rSimd_1_2_3, rSimd_4_5_6, rSimd_7_8_9, m)); // 1*4+7, etc. + SimdBool m = setSimdRealFrom3R(c2, 0, c3) != setZero(); + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3 + c6, 0.0, c2 * c5 + c8), + maskzFma(rSimd_c0c1c2, rSimd_c3c4c5, rSimd_c6c7c8, m)); } TEST_F(SimdFloatingpointTest, fms) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-3, 2, 9), - fms(rSimd_1_2_3, rSimd_4_5_6, rSimd_7_8_9)); // 1*4-7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c0 * c3 - c6, c1 * c4 - c7, c2 * c5 - c8), + fms(rSimd_c0c1c2, rSimd_c3c4c5, rSimd_c6c7c8)); } TEST_F(SimdFloatingpointTest, fnma) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(3, -2, -9), - fnma(rSimd_1_2_3, rSimd_4_5_6, rSimd_7_8_9)); // -1*4+7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(c6 - c0 * c3, c7 - c1 * c4, c8 - c2 * c5), + fnma(rSimd_c0c1c2, rSimd_c3c4c5, rSimd_c6c7c8)); } TEST_F(SimdFloatingpointTest, fnms) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-11, -18, -27), - fnms(rSimd_1_2_3, rSimd_4_5_6, rSimd_7_8_9)); // -1*4-7, etc. + // The last bit of FMA operations depends on hardware, so we don't require exact match + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(-c0 * c3 - c6, -c1 * c4 - c7, -c2 * c5 - c8), + fnms(rSimd_c0c1c2, rSimd_c3c4c5, rSimd_c6c7c8)); } TEST_F(SimdFloatingpointTest, abs) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_1_2_3, abs(rSimd_1_2_3)); // fabs(x)=x - GMX_EXPECT_SIMD_REAL_EQ(rSimd_1_2_3, abs(rSimd_m1_m2_m3)); // fabs(-x)=x + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, abs(rSimd_c0c1c2)); // fabs(x)=x + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, abs(rSimd_m0m1m2)); // fabs(-x)=x } TEST_F(SimdFloatingpointTest, neg) { - GMX_EXPECT_SIMD_REAL_EQ(rSimd_m1_m2_m3, -(rSimd_1_2_3)); // fneg(x)=-x - GMX_EXPECT_SIMD_REAL_EQ(rSimd_1_2_3, -(rSimd_m1_m2_m3)); // fneg(-x)=x + GMX_EXPECT_SIMD_REAL_EQ(rSimd_m0m1m2, -(rSimd_c0c1c2)); // fneg(x)=-x + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, -(rSimd_m0m1m2)); // fneg(-x)=x } #if GMX_SIMD_HAVE_LOGICAL -/* 1.3333282470703125 has mantissa 0101010101010101 (followed by zeros) - * 1.79998779296875 has mantissa 1100110011001100 (followed by zeros) - * 1.26666259765625 has mantissa 0100010001000100 (followed by zeros) - * 1.8666534423828125 has mantissa 1101110111011101 (followed by zeros) - * - * Since all of them have the same exponent (2^0), the exponent will - * not change with AND or OR operations. - */ TEST_F(SimdFloatingpointTest, and) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(1.26666259765625), - (SimdReal(1.3333282470703125) & SimdReal(1.79998779296875))); + GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultAnd, + (rSimd_logicalA & rSimd_logicalB)); } TEST_F(SimdFloatingpointTest, or) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(1.8666534423828125), - (SimdReal(1.3333282470703125) | SimdReal(1.79998779296875))); + GMX_EXPECT_SIMD_REAL_EQ(rSimd_logicalResultOr, + (rSimd_logicalA | rSimd_logicalB)); } TEST_F(SimdFloatingpointTest, xor) @@ -178,8 +176,8 @@ TEST_F(SimdFloatingpointTest, xor) * in only the sign bit being set. We then use this bit change the sign of * different numbers. */ - SimdReal signbit = SimdReal(1.5) ^ SimdReal(-1.5); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-1, 2, -3), (signbit ^ setSimdRealFrom3R(1, -2, 3))); + SimdReal signbit = SimdReal(c1) ^ SimdReal(-c1); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c2, c3, -c4), (signbit ^ setSimdRealFrom3R(c2, -c3, c4))); } TEST_F(SimdFloatingpointTest, andNot) @@ -187,34 +185,34 @@ TEST_F(SimdFloatingpointTest, andNot) /* Use xor (which we already tested, so fix that first if both tests fail) * to extract the sign bit, and then use andnot to take absolute values. */ - SimdReal signbit = SimdReal(1.5) ^ SimdReal(-1.5); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 2, 3), andNot(signbit, setSimdRealFrom3R(-1, 2, -3))); + SimdReal signbit = SimdReal(c1) ^ SimdReal(-c1); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c2, c3, c4), andNot(signbit, setSimdRealFrom3R(-c2, c3, -c4))); } #endif TEST_F(SimdFloatingpointTest, max) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(3, 2, 4), max(rSimd_1_2_3, rSimd_3_1_4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(3, 2, 4), max(rSimd_3_1_4, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-1, -1, -3), max(rSimd_m1_m2_m3, rSimd_m3_m1_m4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-1, -1, -3), max(rSimd_m3_m1_m4, rSimd_m1_m2_m3)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c3, c1, c4), max(rSimd_c0c1c2, rSimd_c3c0c4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c3, c1, c4), max(rSimd_c3c0c4, rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, -c0, -c2), max(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, -c0, -c2), max(rSimd_m3m0m4, rSimd_m0m1m2)); } TEST_F(SimdFloatingpointTest, min) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 1, 3), min(rSimd_1_2_3, rSimd_3_1_4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 1, 3), min(rSimd_3_1_4, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-3, -2, -4), min(rSimd_m1_m2_m3, rSimd_m3_m1_m4)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-3, -2, -4), min(rSimd_m3_m1_m4, rSimd_m1_m2_m3)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, c0, c2), min(rSimd_c0c1c2, rSimd_c3c0c4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, c0, c2), min(rSimd_c3c0c4, rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c3, -c1, -c4), min(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c3, -c1, -c4), min(rSimd_m3m0m4, rSimd_m0m1m2)); } TEST_F(SimdFloatingpointTest, round) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(2), round(SimdReal(2.25))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(4), round(SimdReal(3.75))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(-2), round(SimdReal(-2.25))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(-4), round(SimdReal(-3.75))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(2), round(rSimd_2p25)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(4), round(rSimd_3p75)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(-2), round(rSimd_m2p25)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom1R(-4), round(rSimd_m3p75)); } TEST_F(SimdFloatingpointTest, trunc) @@ -353,58 +351,58 @@ TEST_F(SimdFloatingpointTest, maskzRcp) TEST_F(SimdFloatingpointTest, cmpEqAndSelectByMask) { - SimdBool eq = rSimd_5_7_9 == rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, 3), selectByMask(rSimd_1_2_3, eq)); + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, c2), selectByMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, selectByNotMask) { - SimdBool eq = rSimd_5_7_9 == rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 2, 0), selectByNotMask(rSimd_1_2_3, eq)); + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByNotMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, cmpNe) { - SimdBool eq = rSimd_5_7_9 != rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 2, 0), selectByMask(rSimd_1_2_3, eq)); + SimdBool eq = rSimd_c4c6c8 != rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByMask(rSimd_c0c1c2, eq)); } TEST_F(SimdFloatingpointTest, cmpLe) { - SimdBool le = rSimd_5_7_9 <= rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(rSimd_1_2_3, selectByMask(rSimd_1_2_3, le)); + SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, le)); } TEST_F(SimdFloatingpointTest, cmpLt) { - SimdBool lt = rSimd_5_7_9 < rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 2, 0), selectByMask(rSimd_1_2_3, lt)); + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, c1, 0), selectByMask(rSimd_c0c1c2, lt)); } #if GMX_SIMD_HAVE_INT32_LOGICAL || GMX_SIMD_HAVE_LOGICAL TEST_F(SimdFloatingpointTest, testBits) { - SimdBool eq = testBits(setSimdRealFrom3R(1, 0, 2)); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 0, 3), selectByMask(rSimd_1_2_3, eq)); + SimdBool eq = testBits(setSimdRealFrom3R(c1, 0, c1)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, 0, c2), selectByMask(rSimd_c0c1c2, eq)); // Test if we detect only the sign bit being set eq = testBits(setSimdRealFrom1R(GMX_REAL_NEGZERO)); - GMX_EXPECT_SIMD_REAL_EQ(rSimd_1_2_3, selectByMask(rSimd_1_2_3, eq)); + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, eq)); } #endif TEST_F(SimdFloatingpointTest, andB) { - SimdBool eq = rSimd_5_7_9 == rSimd_7_8_9; - SimdBool le = rSimd_5_7_9 <= rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, 3), selectByMask(rSimd_1_2_3, (eq && le))); + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool le = rSimd_c4c6c8 <= rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(0, 0, c2), selectByMask(rSimd_c0c1c2, (eq && le))); } TEST_F(SimdFloatingpointTest, orB) { - SimdBool eq = rSimd_5_7_9 == rSimd_7_8_9; - SimdBool lt = rSimd_5_7_9 < rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1, 2, 3), selectByMask(rSimd_1_2_3, (eq || lt))); + SimdBool eq = rSimd_c4c6c8 == rSimd_c6c7c8; + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(rSimd_c0c1c2, selectByMask(rSimd_c0c1c2, (eq || lt))); } TEST_F(SimdFloatingpointTest, anyTrueB) @@ -415,24 +413,24 @@ TEST_F(SimdFloatingpointTest, anyTrueB) * We cannot check for truth values for "any" element beyond the first, * since that part of the data will not be used if simd width is 1. */ - eq = rSimd_5_7_9 == setSimdRealFrom3R(5, 0, 0); + eq = rSimd_c4c6c8 == setSimdRealFrom3R(c4, 0, 0); EXPECT_TRUE(anyTrue(eq)); - eq = rSimd_1_2_3 == rSimd_4_5_6; + eq = rSimd_c0c1c2 == rSimd_c3c4c5; EXPECT_FALSE(anyTrue(eq)); } TEST_F(SimdFloatingpointTest, blend) { - SimdBool lt = rSimd_5_7_9 < rSimd_7_8_9; - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(4, 5, 3), blend(rSimd_1_2_3, rSimd_4_5_6, lt)); + SimdBool lt = rSimd_c4c6c8 < rSimd_c6c7c8; + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c3, c4, c2), blend(rSimd_c0c1c2, rSimd_c3c4c5, lt)); } TEST_F(SimdFloatingpointTest, reduce) { // The horizontal sum of the SIMD variable depends on the width, so // simply store it an extra time and calculate what the sum should be - std::vector v = simdReal2Vector(rSimd_4_5_6); + std::vector v = simdReal2Vector(rSimd_c3c4c5); real sum = 0.0; for (int i = 0; i < GMX_SIMD_REAL_WIDTH; i++) @@ -440,7 +438,7 @@ TEST_F(SimdFloatingpointTest, reduce) sum += v[i]; } - EXPECT_EQ(sum, reduce(rSimd_4_5_6)); + EXPECT_REAL_EQ_TOL(sum, reduce(rSimd_c3c4c5), defaultRealTolerance() ); } #endif // GMX_SIMD_HAVE_REAL @@ -458,7 +456,9 @@ TEST_F(SimdFloatingpointTest, cvtFloat2Double) for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { - f[i] = i; + // Scale by 1+100*eps to use low bits too. + // Due to the conversions we want to avoid being too sensitive to fluctuations in last bit + f[i] = i * (1.0 + 100*GMX_FLOAT_EPS); } vf = load(f); @@ -491,7 +491,9 @@ TEST_F(SimdFloatingpointTest, cvtDouble2Float) // This fills elements for pd1 too when double width is 2*single width for (i = 0; i < GMX_SIMD_FLOAT_WIDTH; i++) { - d[i] = i; + // Scale by 1+eps to use low bits too. + // Due to the conversions we want to avoid being too sensitive to fluctuations in last bit + d[i] = i * (1.0 + 100*GMX_FLOAT_EPS); } vd0 = load(d); diff --git a/src/gromacs/simd/tests/simd_floatingpoint_util.cpp b/src/gromacs/simd/tests/simd_floatingpoint_util.cpp index 6eef2e2a95..8d288f77c6 100644 --- a/src/gromacs/simd/tests/simd_floatingpoint_util.cpp +++ b/src/gromacs/simd/tests/simd_floatingpoint_util.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2015, by the GROMACS development team, led by + * Copyright (c) 2015,2017, 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. @@ -85,10 +85,12 @@ class SimdFloatingpointUtilTest : public SimdTest { // Use every third point to avoid a continguous access pattern offset_[i] = 3 * i; - val0_[i] = i; - val1_[i] = i + 0.1; - val2_[i] = i + 0.2; - val3_[i] = i + 0.3; + // Multiply numbers by 1+100*GMX_REAL_EPS ensures some low bits are + // set too, so the tests make sure we read all bits correctly. + val0_[i] = (i ) * (1.0 + 100*GMX_REAL_EPS); + val1_[i] = (i + 0.1) * (1.0 + 100*GMX_REAL_EPS); + val2_[i] = (i + 0.2) * (1.0 + 100*GMX_REAL_EPS); + val3_[i] = (i + 0.3) * (1.0 + 100*GMX_REAL_EPS); } } @@ -265,7 +267,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterStoreU3) // Set test and reference memory to background value for (std::size_t j = 0; j < s_workMemSize_; j++) { - mem0_[j] = refmem[j] = 1000.0 + j; + // Multiply by 1+100*eps to make sure low bits are also used + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -316,7 +319,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3) // Set test and reference memory to background value for (std::size_t j = 0; j < s_workMemSize_; j++) { - mem0_[j] = refmem[j] = 1000.0 + j; + // Multiply by 1+100*eps to make sure low bits are also used + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -366,7 +370,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterIncrU3Overlapping) // Set test and reference memory to background value for (std::size_t j = 0; j < s_workMemSize_; j++) { - mem0_[j] = refmem[j] = 1000.0 + j; + // Multiply by 1+100*eps to make sure low bits are also used + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -405,7 +410,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3) // Set test and reference memory to background value for (std::size_t j = 0; j < s_workMemSize_; j++) { - mem0_[j] = refmem[j] = 1000.0 + j; + // Multiply by 1+100*eps to make sure low bits are also used + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -455,7 +461,8 @@ TEST_F(SimdFloatingpointUtilTest, transposeScatterDecrU3Overlapping) // Set test and reference memory to background value for (std::size_t j = 0; j < s_workMemSize_; j++) { - mem0_[j] = refmem[j] = 1000.0 + j; + // Multiply by 1+100*eps to make sure low bits are also used + mem0_[j] = refmem[j] = (1000.0 + j) * (1.0 + 100*GMX_REAL_EPS); } for (std::size_t j = 0; j < GMX_SIMD_REAL_WIDTH; j++) @@ -668,17 +675,17 @@ TEST_F(SimdFloatingpointUtilTest, reduceIncr4Sum) } // Just put some numbers in memory so we check the addition is correct - mem0_[0] = 5.0; - mem0_[1] = 15.0; - mem0_[2] = 25.0; - mem0_[3] = 35.0; + mem0_[0] = c0; + mem0_[1] = c1; + mem0_[2] = c2; + mem0_[3] = c3; tstsum = reduceIncr4ReturnSum(mem0_, v0, v1, v2, v3); - EXPECT_REAL_EQ_TOL( 5.0 + sum0, mem0_[0], tolerance); - EXPECT_REAL_EQ_TOL(15.0 + sum1, mem0_[1], tolerance); - EXPECT_REAL_EQ_TOL(25.0 + sum2, mem0_[2], tolerance); - EXPECT_REAL_EQ_TOL(35.0 + sum3, mem0_[3], tolerance); + EXPECT_REAL_EQ_TOL(c0 + sum0, mem0_[0], tolerance); + EXPECT_REAL_EQ_TOL(c1 + sum1, mem0_[1], tolerance); + EXPECT_REAL_EQ_TOL(c2 + sum2, mem0_[2], tolerance); + EXPECT_REAL_EQ_TOL(c3 + sum3, mem0_[3], tolerance); EXPECT_REAL_EQ_TOL(sum0 + sum1 + sum2 + sum3, tstsum, tolerance); } @@ -893,17 +900,17 @@ TEST_F(SimdFloatingpointUtilTest, reduceIncr4SumHsimd) } // Just put some numbers in memory so we check the addition is correct - mem0_[0] = 5.0; - mem0_[1] = 15.0; - mem0_[2] = 25.0; - mem0_[3] = 35.0; + mem0_[0] = c0; + mem0_[1] = c1; + mem0_[2] = c2; + mem0_[3] = c3; tstsum = reduceIncr4ReturnSumHsimd(mem0_, v0, v1); - EXPECT_REAL_EQ_TOL( 5.0 + sum0, mem0_[0], tolerance); - EXPECT_REAL_EQ_TOL(15.0 + sum1, mem0_[1], tolerance); - EXPECT_REAL_EQ_TOL(25.0 + sum2, mem0_[2], tolerance); - EXPECT_REAL_EQ_TOL(35.0 + sum3, mem0_[3], tolerance); + EXPECT_REAL_EQ_TOL(c0 + sum0, mem0_[0], tolerance); + EXPECT_REAL_EQ_TOL(c1 + sum1, mem0_[1], tolerance); + EXPECT_REAL_EQ_TOL(c2 + sum2, mem0_[2], tolerance); + EXPECT_REAL_EQ_TOL(c3 + sum3, mem0_[3], tolerance); EXPECT_REAL_EQ_TOL(sum0 + sum1 + sum2 + sum3, tstsum, tolerance); } diff --git a/src/gromacs/simd/tests/simd_integer.cpp b/src/gromacs/simd/tests/simd_integer.cpp index 9ab6e87774..7dd555bbbd 100644 --- a/src/gromacs/simd/tests/simd_integer.cpp +++ b/src/gromacs/simd/tests/simd_integer.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015,2016, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2016,2017, 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. @@ -305,7 +305,7 @@ TEST_F(SimdIntegerTest, blend) #if GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS TEST_F(SimdIntegerTest, cvtB2IB) { - SimdBool eq = (rSimd_5_7_9 == setSimdRealFrom3R(5, 0, 0)); // eq should be T,F,F + SimdBool eq = (rSimd_c3c4c5 == rSimd_c3c0c4); // eq should be T,F,F SimdIBool eqi = cvtB2IB(eq); GMX_EXPECT_SIMD_INT_EQ(setSimdIntFrom3I(1, 0, 0), selectByMask(iSimd_1_2_3, eqi)); @@ -315,7 +315,7 @@ TEST_F(SimdIntegerTest, cvtIB2B) { SimdIBool eqi = (iSimd_5_7_9 == setSimdIntFrom3I(5, 0, 0)); // eq should be T,F,F SimdBool eq = cvtIB2B(eqi); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(1.0, 0, 0), selectByMask(rSimd_1_2_3, eq)); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(c0, 0, 0), selectByMask(rSimd_c0c1c2, eq)); } #endif // GMX_SIMD_HAVE_REAL && GMX_SIMD_HAVE_INT32_ARITHMETICS diff --git a/src/gromacs/simd/tests/simd_math.cpp b/src/gromacs/simd/tests/simd_math.cpp index 532ab3ec88..2f1f19ff67 100644 --- a/src/gromacs/simd/tests/simd_math.cpp +++ b/src/gromacs/simd/tests/simd_math.cpp @@ -68,6 +68,7 @@ class SimdMathTest : public SimdTest ::testing::AssertionResult compareSimdMathFunction(const char * refFuncExpr, const char *simdFuncExpr, real refFunc(real x), SimdReal gmx_simdcall simdFunc(SimdReal x)); + }; /*! \brief Test approximate equality of SIMD vs reference version of a function. @@ -198,10 +199,10 @@ namespace TEST_F(SimdMathTest, copysign) { - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-4, 5, 6), copysign(setSimdRealFrom3R(4, 5, 6), setSimdRealFrom3R(-5, 2, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-4, 5, 6), copysign(setSimdRealFrom3R(-4, -5, -6), setSimdRealFrom3R(-5, 2, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(4, -5, 6), copysign(setSimdRealFrom3R(4, 5, 6), setSimdRealFrom3R(5, -2, 0))); - GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(4, -5, 6), copysign(setSimdRealFrom3R(-4, -5, -6), setSimdRealFrom3R(5, -2, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), copysign(setSimdRealFrom3R( c0, c1, c2), setSimdRealFrom3R(-c3, c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R(-c0, c1, c2), copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R(-c3, c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, -c1, c2), copysign(setSimdRealFrom3R( c0, c1, c2), setSimdRealFrom3R( c3, -c4, 0))); + GMX_EXPECT_SIMD_REAL_EQ(setSimdRealFrom3R( c0, -c1, c2), copysign(setSimdRealFrom3R(-c0, -c1, -c2), setSimdRealFrom3R( c3, -c4, 0))); } /*! \brief Function wrapper to evaluate reference 1/sqrt(x) */ @@ -219,9 +220,9 @@ TEST_F(SimdMathTest, invsqrt) TEST_F(SimdMathTest, maskzInvsqrt) { - SimdReal x = setSimdRealFrom3R(1.0, 0.0, 3.0); + SimdReal x = setSimdRealFrom3R(c1, 0.0, c2); SimdBool m = (setZero() < x); - SimdReal ref = setSimdRealFrom3R(1.0/std::sqrt(1.0), 0.0, 1.0/std::sqrt(3.0)); + SimdReal ref = setSimdRealFrom3R(1.0/std::sqrt(c1), 0.0, 1.0/std::sqrt(c2)); GMX_EXPECT_SIMD_REAL_NEAR(ref, maskzInvsqrt(x, m)); } @@ -257,7 +258,7 @@ TEST_F(SimdMathTest, invsqrtPair) TEST_F(SimdMathTest, sqrt) { // Just make sure sqrt(0)=0 works and isn't evaluated as 0*1/sqrt(0)=NaN - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, 2, 3), sqrt(setSimdRealFrom3R(0, 4, 9))); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c1), std::sqrt(c2)), sqrt(setSimdRealFrom3R(0, c1, c2))); } /*! \brief Function wrapper to evaluate reference 1/x */ @@ -277,9 +278,9 @@ TEST_F(SimdMathTest, inv) TEST_F(SimdMathTest, maskzInv) { - SimdReal x = setSimdRealFrom3R(2.0, 0.0, 3.0); + SimdReal x = setSimdRealFrom3R(c1, 0.0, c2); SimdBool m = (setZero() < x); - SimdReal ref = setSimdRealFrom3R(0.5, 0.0, 1.0/3.0); + SimdReal ref = setSimdRealFrom3R(1.0/c1, 0.0, 1.0/c2); GMX_EXPECT_SIMD_REAL_NEAR(ref, maskzInv(x, m)); } @@ -429,16 +430,25 @@ TEST_F(SimdMathTest, atan) TEST_F(SimdMathTest, atan2) { // test each quadrant - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, 1.0)), atan2(rSimd_1_2_3, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, 1.0)), atan2(rSimd_m1_m2_m3, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, -1.0)), atan2(rSimd_m1_m2_m3, rSimd_m1_m2_m3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, -1.0)), atan2(rSimd_1_2_3, rSimd_m1_m2_m3)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), + atan2(rSimd_c0c1c2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), + atan2(rSimd_m0m1m2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), + atan2(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), + atan2(rSimd_c0c1c2, rSimd_m3m0m4)); + // cases important for calculating angles // values on coordinate axes - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(0.0, 1.0)), atan2(setZero(), rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, 0.0)), atan2(rSimd_1_2_3, setZero())); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(0.0, -1.0)), atan2(setZero(), rSimd_m1_m2_m3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, 0.0)), atan2(rSimd_m1_m2_m3, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, c0), std::atan2(0, c1), std::atan2(0, c2)), + atan2(setZero(), rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, 0), std::atan2(c1, 0), std::atan2(c2, 0)), + atan2(rSimd_c0c1c2, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), + atan2(setZero(), rSimd_m0m1m2)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), + atan2(rSimd_m0m1m2, setZero())); // degenerate value (origin) should return 0.0. At least IBM xlc 13.1.5 gets the reference // value wrong (-nan) at -O3 optimization, so we compare to the correct value (0.0) instead. GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(0.0), atan2(setSimdRealFrom3R(0.0, 0.0, 0.0), setZero())); @@ -541,7 +551,7 @@ TEST_F(SimdMathTest, sqrtSingleAccuracy) setUlpTol(ulpTol_ * (1LL << (std::numeric_limits::digits-std::numeric_limits::digits))); // Just make sure sqrt(0)=0 works and isn't evaluated as 0*1/sqrt(0)=NaN - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, 2, 3), sqrtSingleAccuracy(setSimdRealFrom3R(0, 4, 9))); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(0, std::sqrt(c0), std::sqrt(c1)), sqrtSingleAccuracy(setSimdRealFrom3R(0, c0, c1))); } TEST_F(SimdMathTest, invSingleAccuracy) @@ -682,16 +692,25 @@ TEST_F(SimdMathTest, atan2SingleAccuracy) setUlpTol(ulpTol_ * (1LL << (std::numeric_limits::digits-std::numeric_limits::digits))); // test each quadrant - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, 1.0)), atan2SingleAccuracy(rSimd_1_2_3, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, 1.0)), atan2SingleAccuracy(rSimd_m1_m2_m3, rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, -1.0)), atan2SingleAccuracy(rSimd_m1_m2_m3, rSimd_m1_m2_m3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, -1.0)), atan2SingleAccuracy(rSimd_1_2_3, rSimd_m1_m2_m3)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, c3), std::atan2(c1, c4), std::atan2(c2, c5)), + atan2SingleAccuracy(rSimd_c0c1c2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, c3), std::atan2(-c1, c4), std::atan2(-c2, c5)), + atan2SingleAccuracy(rSimd_m0m1m2, rSimd_c3c4c5)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, -c3), std::atan2(-c1, -c0), std::atan2(-c2, -c4)), + atan2SingleAccuracy(rSimd_m0m1m2, rSimd_m3m0m4)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, -c3), std::atan2(c1, -c0), std::atan2(c2, -c4)), + atan2SingleAccuracy(rSimd_c0c1c2, rSimd_m3m0m4)); // cases important for calculating angles // values on coordinate axes - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(0.0, 1.0)), atan2SingleAccuracy(setZero(), rSimd_1_2_3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(1.0, 0.0)), atan2SingleAccuracy(rSimd_1_2_3, setZero())); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(0.0, -1.0)), atan2SingleAccuracy(setZero(), rSimd_m1_m2_m3)); - GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(std::atan2(-1.0, 0.0)), atan2SingleAccuracy(rSimd_m1_m2_m3, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, c0), std::atan2(0, c1), std::atan2(0, c2)), + atan2SingleAccuracy(setZero(), rSimd_c0c1c2)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(c0, 0), std::atan2(c1, 0), std::atan2(c2, 0)), + atan2SingleAccuracy(rSimd_c0c1c2, setZero())); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(0, -c0), std::atan2(0, -c1), std::atan2(0, -c2)), + atan2SingleAccuracy(setZero(), rSimd_m0m1m2)); + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(std::atan2(-c0, 0), std::atan2(-c1, 0), std::atan2(-c2, 0)), + atan2SingleAccuracy(rSimd_m0m1m2, setZero())); + // degenerate value (origin) should return 0.0. At least IBM xlc 13.1.5 gets the reference // value wrong (-nan) at -O3 optimization, so we compare to the correct value (0.0) instead. GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom1R(0.0), atan2SingleAccuracy(setSimdRealFrom3R(0.0, 0.0, 0.0), setZero())); diff --git a/src/gromacs/simd/tests/simd_vector_operations.cpp b/src/gromacs/simd/tests/simd_vector_operations.cpp index fa1570ffa4..0795606104 100644 --- a/src/gromacs/simd/tests/simd_vector_operations.cpp +++ b/src/gromacs/simd/tests/simd_vector_operations.cpp @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2014,2015, by the GROMACS development team, led by + * Copyright (c) 2014,2015,2017, 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. @@ -39,6 +39,7 @@ #include "gromacs/simd/simd.h" #include "gromacs/simd/vector_operations.h" +#include "data.h" #include "simd.h" #if GMX_SIMD @@ -61,13 +62,15 @@ typedef SimdTest SimdVectorOperationsTest; TEST_F(SimdVectorOperationsTest, iprod) { - SimdReal aX = setSimdRealFrom3R(1, 2, 3); - SimdReal aY = setSimdRealFrom3R(3, 0, 5); - SimdReal aZ = setSimdRealFrom3R(4, 1, 8); - SimdReal bX = setSimdRealFrom3R(8, 3, 6); - SimdReal bY = setSimdRealFrom3R(2, 3, 1); - SimdReal bZ = setSimdRealFrom3R(5, 7, 9); - SimdReal iprodRef = setSimdRealFrom3R(34, 13, 95); + SimdReal aX = rSimd_c0c1c2; + SimdReal aY = rSimd_c3c4c5; + SimdReal aZ = rSimd_c6c7c8; + SimdReal bX = rSimd_c3c0c4; + SimdReal bY = rSimd_c4c6c8; + SimdReal bZ = rSimd_c7c2c3; + SimdReal iprodRef = setSimdRealFrom3R(c0*c3 + c3*c4 + c6*c7, + c1*c0 + c4*c6 + c7*c2, + c2*c4 + c5*c8 + c8*c3); setUlpTol(2); GMX_EXPECT_SIMD_REAL_NEAR(iprodRef, iprod(aX, aY, aZ, bX, bY, bZ)); @@ -75,10 +78,12 @@ TEST_F(SimdVectorOperationsTest, iprod) TEST_F(SimdVectorOperationsTest, norm2) { - SimdReal simdX = setSimdRealFrom3R(1, 2, 3); - SimdReal simdY = setSimdRealFrom3R(3, 0, 5); - SimdReal simdZ = setSimdRealFrom3R(4, 1, 8); - SimdReal norm2Ref = setSimdRealFrom3R(26, 5, 98); + SimdReal simdX = rSimd_c0c1c2; + SimdReal simdY = rSimd_c3c4c5; + SimdReal simdZ = rSimd_c6c7c8; + SimdReal norm2Ref = setSimdRealFrom3R(c0*c0 + c3*c3 + c6*c6, + c1*c1 + c4*c4 + c7*c7, + c2*c2 + c5*c5 + c8*c8); setUlpTol(2); GMX_EXPECT_SIMD_REAL_NEAR(norm2Ref, norm2(simdX, simdY, simdZ)); @@ -86,15 +91,15 @@ TEST_F(SimdVectorOperationsTest, norm2) TEST_F(SimdVectorOperationsTest, cprod) { - SimdReal aX = setSimdRealFrom3R(1, 2, 3); - SimdReal aY = setSimdRealFrom3R(3, 0, 5); - SimdReal aZ = setSimdRealFrom3R(4, 1, 8); - SimdReal bX = setSimdRealFrom3R(8, 3, 6); - SimdReal bY = setSimdRealFrom3R(2, 3, 1); - SimdReal bZ = setSimdRealFrom3R(5, 7, 9); - SimdReal refcX = setSimdRealFrom3R(7, -3, 37); - SimdReal refcY = setSimdRealFrom3R(27, -11, 21); - SimdReal refcZ = setSimdRealFrom3R(-22, 6, -27); + SimdReal aX = rSimd_c0c1c2; + SimdReal aY = rSimd_c3c4c5; + SimdReal aZ = rSimd_c6c7c8; + SimdReal bX = rSimd_c3c0c4; + SimdReal bY = rSimd_c4c6c8; + SimdReal bZ = rSimd_c7c2c3; + SimdReal refcX = setSimdRealFrom3R( c3*c7-c6*c4, c4*c2-c7*c6, c5*c3-c8*c8 ); + SimdReal refcY = setSimdRealFrom3R( c6*c3-c0*c7, c7*c0-c1*c2, c8*c4-c2*c3 ); + SimdReal refcZ = setSimdRealFrom3R( c0*c4-c3*c3, c1*c6-c4*c0, c2*c8-c5*c4 ); SimdReal cX, cY, cZ; cprod(aX, aY, aZ, bX, bY, bZ, &cX, &cY, &cZ); -- 2.11.4.GIT