Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+ runtime check of rounding mode support #8

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

AndreyG
Copy link

@AndreyG AndreyG commented Jun 12, 2015

For example, following program

#include <boost/numeric/interval.hpp>

int main()
{
    boost::numeric::interval<double>::traits_type::rounding _;
}

will work fine if is built with gcc using '-frounding-math', but will fail otherwise.
Running on Valgrind is another practical case when this program will crash (even if it was correctly built).

I am not sure about using assert for check, may be exception or some other mechanism should be used.

@mclow
Copy link
Contributor

mclow commented Jun 12, 2015

Ok, I'm confused. I tried your program using gcc 5.1 on Mac OS X, and it did nothing with both -frounding-math on the command line and without.

What is the behavior that you expect from this program (and what is the behavior that you observe)?

@AndreyG
Copy link
Author

AndreyG commented Jun 13, 2015

I expect (and I observe with gcc 5.1.0, clang 3.6.0 on ArchLinux) that after applying my patch for Boost.Interval program built without -frounding-math aborted with error

... /boost/numeric/interval/hw_rounding.hpp:68: boost::numeric::interval_lib::detail::runtime_checker<T>::helper::helper() [with T = double]: Assertion `a != b' failed.

Possibly, absence of crash on MAC OS X can be explained by another set of predefined command line options for gcc. Could you try to pass -fno-rounding-math explicitly?
Thanks.

@mcquay239
Copy link

👍

@jeking3
Copy link
Contributor

jeking3 commented May 17, 2018

Couldn't this be a compile-time check?

@AndreyG
Copy link
Author

AndreyG commented May 17, 2018

I'm afraid no. Firstly constexpr evaluation doesn't support rounding mode. Secondly correctly built program will crash if run it on Valgrind.

@jeking3
Copy link
Contributor

jeking3 commented May 17, 2018

Using the docker ubuntu bionic image (clang 6, gcc 7.3, valgrind 3.13, found in boostorg/boost#184) I am able to reproduce this issue on the "pi" test in release mode:

gcc with -fno-rounding-math:

boost@10c3dbfa93be:/boost/libs/numeric/interval/test$ ../../../../b2 toolset=gcc variant=release cxxflags=-fno-rounding-math pi                     /boost/libs/predef/check/../tools/check/predef.jam:46: Unescaped special character in argument $(language)::$(expression)
Performing configuration checks

    - default address-model    : 64-bit (cached)
    - default architecture     : x86 (cached)
    - symlinks supported       : yes (cached)
...patience...
...found 2012 targets...
...updating 2 targets...
testing.capture-output ../../../../bin.v2/libs/numeric/interval/test/pi.test/gcc-7.3/release/pi.run
====== BEGIN OUTPUT ======
/boost/libs/numeric/interval/test/pi.cpp(37): test subset(pi_f, widen(I_f((float) PI), (std::numeric_limits<float> ::min)())) failed in function: 'int test_main(int, char**)'
/boost/libs/numeric/interval/test/pi.cpp(38): test subset(pi_d, widen(I_d((double)PI), (std::numeric_limits<double>::min)())) failed in function: 'int test_main(int, char**)'

**** 2 errors detected

EXIT STATUS: 201

gcc with -frounding-math:

boost@10c3dbfa93be:/boost/libs/numeric/interval/test$ ../../../../b2 toolset=gcc variant=release cxxflags=-frounding-math pi
/boost/libs/predef/check/../tools/check/predef.jam:46: Unescaped special character in argument $(language)::$(expression)
Performing configuration checks

    - default address-model    : 64-bit (cached)
    - default architecture     : x86 (cached)
    - symlinks supported       : yes (cached)
...patience...
...found 2012 targets...
...updating 4 targets...
gcc.compile.c++ ../../../../bin.v2/libs/numeric/interval/test/pi.test/gcc-7.3/release/libs/numeric/interval/test/pi.o
gcc.link ../../../../bin.v2/libs/numeric/interval/test/pi.test/gcc-7.3/release/pi
testing.capture-output ../../../../bin.v2/libs/numeric/interval/test/pi.test/gcc-7.3/release/pi.run
**passed** ../../../../bin.v2/libs/numeric/interval/test/pi.test/gcc-7.3/release/pi.test
...updated 4 targets...

clang 6:

boost@10c3dbfa93be:/boost/libs/numeric/interval/test$ ../../../../b2 toolset=clang variant=release pi
/boost/libs/predef/check/../tools/check/predef.jam:46: Unescaped special character in argument $(language)::$(expression)
Performing configuration checks

    - default address-model    : 64-bit (cached)
    - default architecture     : x86 (cached)
    - symlinks supported       : yes (cached)
...patience...
...found 2012 targets...
...updating 9 targets...
clang-linux.compile.c++.without-pth ../../../../bin.v2/libs/numeric/interval/test/pi.test/clang-linux-6.0/release/libs/numeric/interval/test/pi.o
clang-linux.link ../../../../bin.v2/libs/numeric/interval/test/pi.test/clang-linux-6.0/release/pi
testing.capture-output ../../../../bin.v2/libs/numeric/interval/test/pi.test/clang-linux-6.0/release/pi.run
====== BEGIN OUTPUT ======
/boost/libs/numeric/interval/test/pi.cpp(37): test subset(pi_f, widen(I_f((float) PI), (std::numeric_limits<float> ::min)())) failed in function: 'int test_main(int, char **)'
/boost/libs/numeric/interval/test/pi.cpp(38): test subset(pi_d, widen(I_d((double)PI), (std::numeric_limits<double>::min)())) failed in function: 'int test_main(int, char **)'

**** 2 errors detected

EXIT STATUS: 201

Unable to use clang with -fno-rounding-math:

clang: warning: optimization flag '-fno-rounding-math' is not supported [-Wignored-optimization-argument]
c

As it stands you can't use clang at all, and you can only use gcc in one mode. I'm thinking it's the library or the test that's at fault here and not the compiler(s)...

include/boost/numeric/interval/hw_rounding.hpp Outdated Show resolved Hide resolved
{};

template<>
struct rounded_math<double>
: save_state<rounded_arith_opp<double> >
, private detail::runtime_checker<double>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't this increase the runtime performance significantly if these are used in hot code paths?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't because it is invoking only once (static helper _, line 59). There is still some performance penalty due to the check that singleton of the type helper is initialized, but I believe that it's insignificant in comparison to the cost of switch of rounding mode.

Copy link
Contributor

@jeking3 jeking3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rebase on develop.

For example, following program

<code>
    #include <boost/numeric/interval.hpp>

    int main()
    {
        boost::numeric::interval<double>::traits_type::rounding _;
    }
</code>

will work fine if is built with gcc using '-frounding-math', but will fail otherwise.
Running on Valgrind is another practical case when this program will crash (even if it was correctly built).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants