Work around compiler issue with random test
authorErik Lindahl <erik@kth.se>
Thu, 7 Jul 2016 23:05:17 +0000 (01:05 +0200)
committerErik Lindahl <erik@kth.se>
Fri, 8 Jul 2016 09:08:31 +0000 (11:08 +0200)
gcc-4.8.4 running on 32-bit Linux fails a few
tests for random distributions. This seems
to be caused by the compiler doing something
strange (that can lead to differences in the lsb)
when we do not use the result as floating-point
values, but rather do exact binary comparisions.
This is valid C++, and bad behaviour of the
compiler (IMHO), but technically it is not required
to produce bitwise identical results at high
optimization. However, by using floating-point
tests with zero ULP tolerance the problem
appears to go away.

Fixes #1986.

Change-Id: I252f37b46605424c02435af0fbf7a4f81b493eb8

src/gromacs/random/tests/exponentialdistribution.cpp
src/gromacs/random/tests/gammadistribution.cpp
src/gromacs/random/tests/normaldistribution.cpp
src/gromacs/random/tests/tabulatednormaldistribution.cpp
src/gromacs/random/tests/uniformrealdistribution.cpp

index c429e3ffd8edaccc0e785bf7bea5e0a44c418d1f..684242433c084060acd7a67b754312571e875a90 100644 (file)
@@ -106,7 +106,7 @@ TEST(ExponentialDistributionTest, Reset)
 
     valB = distB(rng);
 
-    EXPECT_EQ(valA, valB);
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 TEST(ExponentialDistributionTest, AltParam)
@@ -122,7 +122,7 @@ TEST(ExponentialDistributionTest, AltParam)
     rngB.restart();
     distA.reset();
     distB.reset();
-    EXPECT_EQ(distA(rngA), distB(rngB, paramA));
+    EXPECT_REAL_EQ_TOL(distA(rngA), distB(rngB, paramA), gmx::test::ulpTolerance(0));
 }
 
 }      // namespace anonymous
index b28bc083ec9018b7ff956219cf81b343fca6e988..2d3ce20c76cf716925df3b78f17b7c5958b9791b 100644 (file)
@@ -100,7 +100,7 @@ TEST(GammaDistributionTest, Reset)
 
     valB = distB(rng);
 
-    EXPECT_EQ(valA, valB);
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 TEST(GammaDistributionTest, AltParam)
@@ -116,7 +116,7 @@ TEST(GammaDistributionTest, AltParam)
     rngB.restart();
     distA.reset();
     distB.reset();
-    EXPECT_EQ(distA(rngA), distB(rngB, paramA));
+    EXPECT_REAL_EQ_TOL(distA(rngA), distB(rngB, paramA), gmx::test::ulpTolerance(0));
 }
 
 }      // namespace anonymous
index cfacf22017df1ea80f0412e6bf877dc78c4e8864..a6d5022ce1e5307844d919b14fe93d89b009c482 100644 (file)
@@ -91,7 +91,7 @@ TEST(NormalDistributionTest, Reset)
     gmx::ThreeFry2x64<8>                                rng(123456, gmx::RandomDomain::Other);
     gmx::NormalDistribution<real>                       distA(2.0, 5.0);
     gmx::NormalDistribution<real>                       distB(2.0, 5.0);
-    gmx::NormalDistribution<>::result_type              valA, valB;
+    gmx::NormalDistribution<real>::result_type          valA, valB;
 
     valA = distA(rng);
 
@@ -101,7 +101,10 @@ TEST(NormalDistributionTest, Reset)
 
     valB = distB(rng);
 
-    EXPECT_EQ(valA, valB);
+    // Use floating-point test with no tolerance rather than
+    // exact test, since the latter leads to failures with
+    // 32-bit gcc-4.8.4
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 TEST(NormalDistributionTest, AltParam)
@@ -111,13 +114,21 @@ TEST(NormalDistributionTest, AltParam)
     gmx::NormalDistribution<real>              distA(2.0, 5.0);
     gmx::NormalDistribution<real>              distB; // default parameters
     gmx::NormalDistribution<real>::param_type  paramA(2.0, 5.0);
+    gmx::NormalDistribution<real>::result_type valA, valB;
 
     EXPECT_NE(distA(rngA), distB(rngB));
     rngA.restart();
     rngB.restart();
     distA.reset();
     distB.reset();
-    EXPECT_EQ(distA(rngA), distB(rngB, paramA));
+
+    valA = distA(rngA);
+    valB = distB(rngB, paramA);
+
+    // Use floating-point test with no tolerance rather than
+    // exact test, since the latter leads to failures with
+    // 32-bit gcc-4.8.4
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 }      // namespace anonymous
index a4e8fc652de3e4c1449e838500bbcf2b234687bb..45fba634039ee54ba90321bd1ae24b358b8e814b 100644 (file)
@@ -132,7 +132,7 @@ TEST(TabulatedNormalDistributionTest, Reset)
 
     valB = distB(rng);
 
-    EXPECT_EQ(valA, valB);
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 TEST(TabulatedNormalDistributionTest, AltParam)
@@ -148,7 +148,7 @@ TEST(TabulatedNormalDistributionTest, AltParam)
     rngB.restart();
     distA.reset();
     distB.reset();
-    EXPECT_EQ(distA(rngA), distB(rngB, paramA));
+    EXPECT_REAL_EQ_TOL(distA(rngA), distB(rngB, paramA), gmx::test::ulpTolerance(0));
 }
 
 TEST(TabulatedNormalDistributionTableTest, HasValidProperties)
@@ -159,7 +159,9 @@ TEST(TabulatedNormalDistributionTableTest, HasValidProperties)
 
     size_t halfSize     = table.size() / 2;
     double sumOfSquares = 0.0;
-    auto   tolerance    = gmx::test::ulpTolerance(1);
+    // accept errors of a few ULP since the exact value of the summation
+    // below will depend on whether the compiler issues FMA instructions
+    auto   tolerance    = gmx::test::ulpTolerance(10);
     for (size_t i = 0, iFromEnd = table.size()-1; i < halfSize; ++i, --iFromEnd)
     {
         EXPECT_REAL_EQ_TOL(table.at(i), -table.at(iFromEnd), tolerance)
index f80f067cdf614c23ae23d9f9f9038d7109c51281..6121eb463e2235e0c3ccaa1d0be090c5fe44d490 100644 (file)
@@ -102,10 +102,10 @@ TEST(UniformRealDistributionTest, Logical)
 
 TEST(UniformRealDistributionTest, Reset)
 {
-    gmx::ThreeFry2x64<8>                           rng(123456, gmx::RandomDomain::Other);
-    gmx::UniformRealDistribution<real>             distA(2.0, 5.0);
-    gmx::UniformRealDistribution<real>             distB(2.0, 5.0);
-    gmx::UniformRealDistribution<>::result_type    valA, valB;
+    gmx::ThreeFry2x64<8>                             rng(123456, gmx::RandomDomain::Other);
+    gmx::UniformRealDistribution<real>               distA(2.0, 5.0);
+    gmx::UniformRealDistribution<real>               distB(2.0, 5.0);
+    gmx::UniformRealDistribution<real>::result_type  valA, valB;
 
     valA = distA(rng);
 
@@ -115,7 +115,9 @@ TEST(UniformRealDistributionTest, Reset)
 
     valB = distB(rng);
 
-    EXPECT_EQ(valA, valB);
+    // Use floating-point test with no tolerance rather than exact
+    // test, since the later fails with 32-bit gcc-4.8.4
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 TEST(UniformRealDistributionTest, AltParam)
@@ -125,13 +127,20 @@ TEST(UniformRealDistributionTest, AltParam)
     gmx::UniformRealDistribution<real>              distA(2.0, 5.0);
     gmx::UniformRealDistribution<real>              distB; // default parameters
     gmx::UniformRealDistribution<real>::param_type  paramA(2.0, 5.0);
+    gmx::UniformRealDistribution<real>::result_type valA, valB;
 
     EXPECT_NE(distA(rngA), distB(rngB));
     rngA.restart();
     rngB.restart();
     distA.reset();
     distB.reset();
-    EXPECT_EQ(distA(rngA), distB(rngB, paramA));
+
+    valA = distA(rngA);
+    valB = distB(rngB, paramA);
+
+    // Use floating-point test with no tolerance rather than exact test,
+    // since the latter fails with 32-bit gcc-4.8.4
+    EXPECT_REAL_EQ_TOL(valA, valB, gmx::test::ulpTolerance(0));
 }
 
 }      // namespace anonymous