Skip to content

Commit

Permalink
Use std::isnan() and isinf() with C++11 (Trilinos #239)
Browse files Browse the repository at this point in the history
The ATTB machine 'white' which is a POWER8 with GCC 4.9.2 and CUDA 7.5 fails
the unit tests for ST::isnaninf() which uses the genetic inequality test for
NaNs.  This may be due to heavy compiler optimizations.  Therefore, we are
going to try to C++11 functions std::isnan() and std::isinf().  I have ifdefed
this based on C++11.  Without C++11, it just uses the old generic
implementaion.

I have tested this with and without C++11 enabled and they both passed on the
machine hansen using the GCC 4.8.4 compiler.

Build/Test Cases Summary
Enabled Packages: TeuchosCore
Disabled Packages: PyTrilinos,Pliris,Claps,STK,TriKota
Enabled all Forward Packages
0) MPI_DEBUG => passed: passed=1403,notpassed=0 (54.55 min)
1) SERIAL_RELEASE => passed: passed=1323,notpassed=0 (40.93 min)
  • Loading branch information
bartlettroscoe committed Mar 23, 2016
1 parent 9b9b8c0 commit 7363684
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 31 deletions.
6 changes: 6 additions & 0 deletions packages/teuchos/core/src/Teuchos_ScalarTraits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,11 @@ void throwScalarTraitsNanInfError( const std::string &errMsg );
template<class Scalar>
bool generic_real_isnaninf(const Scalar &x)
{
#ifdef HAVE_TEUCHOSCORE_CXX11
if (std::isnan(x)) return true;
if (std::isinf(x)) return true;
return false;
#else
typedef std::numeric_limits<Scalar> STD_NL;
// IEEE says this should fail for NaN (not all compilers do not obey IEEE)
const Scalar tol = 1.0; // Any (bounded) number should do!
Expand All @@ -133,6 +138,7 @@ bool generic_real_isnaninf(const Scalar &x)
if (x == STD_NL::infinity() || x == -STD_NL::infinity()) return true;
// We give up and assume the number is finite
return false;
#endif
}


Expand Down
44 changes: 13 additions & 31 deletions packages/teuchos/core/test/ScalarTraits/ScalarTraits_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@
#include "Teuchos_TypeTraits.hpp"
#include "Teuchos_Version.hpp"

#include "Teuchos_TestingHelpers.hpp"

namespace {

//
Expand Down Expand Up @@ -122,7 +124,6 @@ bool testScalarTraits(
typedef Teuchos::ScalarTraits<Scalar> ST;

bool success = true;
bool result;

out << "\nTesting: " << Teuchos::TypeNameTraits<ST>::name() << " ...\n";

Expand All @@ -133,25 +134,21 @@ bool testScalarTraits(
out << "Type chain (ascending) : "; TYPE_CHAIN_A<Scalar>(out); out << "\n";
out << "Type chain (descending): "; TYPE_CHAIN_D<Scalar>(out); out << "\n";

TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(1.0), false, out, success);

out << "\nTesting that squareroot(NaN) == NaN! ...\n";
{
const Scalar sqrtNan = ST::squareroot(nan);
result = (ST::isnaninf(sqrtNan));
if (!result) success = false;
out
<< "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
<< passfail(result) << "\n";
out << "squareroot("<<nan<<") = " << sqrtNan << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
}

out << "\nTesting that squareroot(-NaN) == NaN! ...\n";
{
const Scalar negNan = -nan;
const Scalar sqrtNegNan = ST::squareroot(negNan);
result = (ST::isnaninf(sqrtNegNan));
if (!result) success = false;
out
<< "squareroot("<<negNan<<") = " << sqrtNegNan << " == " << nan << " : "
<< passfail(result) << "\n";
out << "squareroot("<<negNan<<") = " << sqrtNegNan << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegNan), true, out, success);
}

if (ST::isComplex == false)
Expand All @@ -160,11 +157,8 @@ bool testScalarTraits(
{
const Scalar negOne = -ST::one();
const Scalar sqrtNegOne = ST::squareroot(negOne);
result = (ST::isnaninf(sqrtNegOne));
if (!result) success = false;
out
<< "squareroot("<<negOne<<") = " << sqrtNegOne << " == " << nan << " : "
<< passfail(result) << "\n";
out << "squareroot("<<negOne<<") = " << sqrtNegOne << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNegOne), true, out, success);
}
}

Expand All @@ -174,33 +168,21 @@ bool testScalarTraits(
{
const Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();
const Scalar sqrtNan = ST::squareroot(nan);
result = (ST::isnaninf(sqrtNan));
if (!result) success = false;
out
<< "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
<< passfail(result) << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
}

out << "\nTesting that squareroot(signaling_NaN) == NaN! ...\n";
{
const Scalar nan = std::numeric_limits<Scalar>::signaling_NaN();
const Scalar sqrtNan = ST::squareroot(nan);
result = (ST::isnaninf(sqrtNan));
if (!result) success = false;
out
<< "squareroot("<<nan<<") = " << sqrtNan << " == " << nan << " : "
<< passfail(result) << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtNan), true, out, success);
}

out << "\nTesting that squareroot(inf) == NaN! ...\n";
{
const Scalar inf = std::numeric_limits<Scalar>::infinity();
const Scalar sqrtInf = ST::squareroot(inf);
result = (ST::isnaninf(sqrtInf));
if (!result) success = false;
out
<< "squareroot("<<inf<<") = " << sqrtInf << " == " << nan << " : "
<< passfail(result) << "\n";
TEUCHOS_TEST_EQUALITY_CONST(ST::isnaninf(sqrtInf), true, out, success);
}

#endif // HAVE_NUMERIC_LIMITS
Expand Down

0 comments on commit 7363684

Please sign in to comment.