Using -ffast-math and fixing tests



Hey all,

recent master on Github enables AVX, FMA, SSE4, etc instruction sets for modern CPUs and also turns on -ffast-math. Now that "can result in incorrect output for programs that depend on an exact implementation of IEEE or ISO rules/specifications for math functions" - as the GCC docs put it.

For the Beast code base, *most* DSP arithmetic should be fine, especially since
we also use -fno-finite-math-only -fno-cx-limited-range, which tell clang/gcc
that Inf and NaN *may* occour in arithmetic and despite fast-math shouldn't be ignored. For the most part, the rest of the fast-math stuff disables Math traps and signalling-NaNs and may cause *some* precision loss due to e.g. associative reordering.

In fact, our tests pass, except for the resampler, which needs further
investigation.


Stefan, please take a look at this commit:

commit 516df8fed83df1e4cf4b330023f8bf649a9a8438
Author: Tim Janik <timj gnu org>
Date:   Fri Jan 17 00:59:54 2020 +0100

    TESTS: testresampler.cc: disable resampler tests that need fast-math fixes

    Disable the test assertion for now, its current form is not helpful
    in finding the actual cause.

The resampler tests should be re-enabled, but I couldn't pin point the exact problem. In fact, when I tried to reproduce the failing test via the command lines, running the accuracy tests manually (which is very tedious, compared to just calling the test suite with the failing test name), everything looked fine and passed.

The resampler test code really needs to be reworked like the rest of the tests, so we have:

static void
fast_math_test()
{ ... }
TEST_ADD (fast_math_test);

That way, the test output shows:
  RUN…     fast_math_test
           [possible failures occour here]
  PASS     fast_math_test

It's easy to pin point the failing test that way and also easy to reproduce with:
$ out/tests/suite1 fast_math_test

The resampler test code looks a bit messy, because I had to merge it with all the other tests, it definitely needs your caring hand ;-)

Also, please move all moderately slow tests into TEST_SLOW() functions, where
moderately means something like:
- is noticably slow (50+ms), or
- has significant loop iterations/recursions, i.e. anything larger than 1000-
  10_000 iterations must use TEST_SLOW()

If that's hard to implement, you can use TEST_ADD() and special case the slowness like e.g. so:

const size_t step = Bse::Test::slow() ? 1 : 1000;
for (size_t i = 0; i < 1000000; i += step) ...;



--
Yours sincerely,
Tim Janik

https://testbit.eu/timj
Free software author.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]