From 3c78eb7e5287622e704007e89503bb4e5a6145fc Mon Sep 17 00:00:00 2001 From: Erik Lindahl Date: Thu, 31 Jul 2014 16:32:30 +0200 Subject: [PATCH] Added tests for denormal and underflow for simd exp() The SIMD math functions are not expected to handle the denormal range correctly, but it should at least be clamped to zero rather than producing garbage values. No changes required to the math function, so it appears to pass these tests as-is. Change-Id: I841c2948c81f6b62f42e60ff30ffd5e4f77926fa --- src/gromacs/simd/tests/simd_math.cpp | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/gromacs/simd/tests/simd_math.cpp b/src/gromacs/simd/tests/simd_math.cpp index a064ae1fae..b892070c45 100644 --- a/src/gromacs/simd/tests/simd_math.cpp +++ b/src/gromacs/simd/tests/simd_math.cpp @@ -281,6 +281,23 @@ TEST_F(SimdMathTest, gmxSimdExp2R) { setRange(-100, 100); GMX_EXPECT_SIMD_FUNC_NEAR(ref_exp2, gmx_simd_exp2_r); + + // We do not care about the SIMD implementation getting denormal values right, + // but they must be clamped to zero rather than producing garbage. + // Check by setting the absolute tolerance to machine precision. + setAbsTol(GMX_REAL_EPS); + + // First two values will have denormal results in single, third value in double too. + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp2(-150.0), ref_exp2(-300.0), ref_exp2(-1050.0)), + gmx_simd_exp2_r(setSimdRealFrom3R(-150.0, -300.0, -1050.0))); + + // Reset absolute tolerance to enforce ULP checking + setAbsTol(0.0); + + // Make sure that underflowing values are set to zero. + // First two values underflow in single, third value in double too. + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp2(-200.0), ref_exp2(-600.0), ref_exp2(-1500.0)), + gmx_simd_exp2_r(setSimdRealFrom3R(-200.0, -600.0, -1500.0))); } #endif @@ -294,6 +311,22 @@ TEST_F(SimdMathTest, gmxSimdExpR) { setRange(-75, 75); GMX_EXPECT_SIMD_FUNC_NEAR(ref_exp, gmx_simd_exp_r); + + // We do not care about the SIMD implementation getting denormal values right, + // but they must be clamped to zero rather than producing garbage. + // Check by setting the absolute tolerance to machine precision. + setAbsTol(GMX_REAL_EPS); + // First two values will have denormal results in single, third value in double too. + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp(-90.0), ref_exp(-100.0), ref_exp(-725.0)), + gmx_simd_exp_r(setSimdRealFrom3R(-90.0, -100.0, -725.0))); + + // Reset absolute tolerance to enforce ULP checking + setAbsTol(0.0); + + // Make sure that underflowing values are set to zero. + // First two values underflow in single, third value in double too. + GMX_EXPECT_SIMD_REAL_NEAR(setSimdRealFrom3R(ref_exp(-150.0), ref_exp(-300.0), ref_exp(-800.0)), + gmx_simd_exp_r(setSimdRealFrom3R(-150.0, -300.0, -800.0))); } /*! \brief Function wrapper for erf(x), with argument/return in default Gromacs precision. -- 2.22.0