[Rd] Development version of R fails tests and is not installed

Jeroen Ooms jeroen @end|ng |rom berke|ey@edu
Sun Feb 9 01:04:24 CET 2020

On Sat, Feb 8, 2020 at 9:27 AM Berwin A Turlach
<berwin.turlach using gmail.com> wrote:
> G'day all,
> I have daily scripts running to install the patched version of the
> current R version and the development version of R on my linux box
> (Ubuntu 18.04.4 LTS).
> The last development version that was successfully compiled and
> installed was "R Under development (unstable) (2020-01-25 r77715)" on
> 27 January.  Since then the script always fails as a regression test
> seems to fail.  Specifically, in the tests/ subdirectory of my build
> directory I have a file reg-tests-1d.Rout.fail which ends with:
> > ## more than half of the above were rounded *down* in R <= 3.6.x
> > ## Some "wrong" test cases from CRAN packages (partly relying on wrong R <= 3.6.x behavior)
> > stopifnot(exprs = {
> +     all.equal(round(10.7775, digits=3), 10.778, tolerance = 1e-12) # even tol=0, was 10.777
> +     all.equal(round(12345 / 1000,   2), 12.35 , tolerance = 1e-12) # even tol=0, was 12.34 in Rd
> +     all.equal(round(9.18665, 4),        9.1866, tolerance = 1e-12) # even tol=0, was  9.1867
> + })
> Error: round(10.7775, digits = 3) and 10.778 are not equal:
>   Mean relative difference: 9.27902e-05
> Execution halted
> This happens while the 32bit architecture is installed,  which is a bit
> surprising as I get the following results for the last installed
> version of R's development version

There are two independent, but slightly related issues here:

First, as Martin already explained, the round() function was recently
improved, and some very strict tests were added to confirm the new
behavior. That explains why you see different round() results in R 4.0
from R 3.6.2. The bugzilla thread explains why:

The second issue has to do with numeric precision on 32-bit systems,
which is why I think you are getting this error. We ran into the same
problem on Windows where results on 32-bit are slightly off, including
(but not limited to) edge-cases in rounding. This has always been the
case, but the 32-bit inaccuracies have increased for recent versions
of GCC.

In general, the main difference in float precision between i686 and
x86_64 could come from whether it uses x87 (with 80 bit floats as
intermediates, as long as all intermediates are stored in registers)
or sse2 for general math. Depending on what the tests do, you can get
test failures (i.e. different results) if intermediates use different
precision, if the test reference is calculated assuming rounding all
intermediates to a certain length between each step.

The solution: to get the same results on 32-bit as on 64-bit, you need
to build R with these extra gcc flags: -mfpmath=sse -msse2. As
explained in https://gcc.gnu.org/onlinedocs/gcc-8.3.0/gcc/x86-Options.html#x86-Options
the -mfpmath=sse is the default for x86-64 but not for i686. As of
r77719 we have made sse the default on Windows and now we get
consistent results on 32-bit and 64-bit, including the round() edge

I think the intention was to add something similar in R's autoconf
script to enable sse on 32-bit unix systems, but seemingly this hasn't
happened. For now I think you should be able to make your 32-bit
checks succeed if you build R with CFLAGS=-mfpmath=sse -msse2.

More information about the R-devel mailing list