Jeroen Ooms
2015-Sep-14 12:49 UTC
[Rd] Optimization bug when byte compiling with gcc 5.2.0 on windows
When building R-devel with gcc 5.2.0 (mingw-w64 v4) on Windows, make check fails reg-tests-1b.R at the following check: x <- c(1:2, NA) sx <- sd(x) !is.nan(sx) Here 'sx' should be 'NA' but it is 'NaN'. It turns out this problem only appears when the function is byte compiled with optimization level 3: mysd <- function (x, na.rm = FALSE) sqrt(var(if (is.vector(x)) x else as.double(x), na.rm = na.rm)) mysd(x) # [1] NA compiler::cmpfun(mysd, list(optimize = 1L))(x) # [1] NA compiler::cmpfun(mysd, list(optimize = 2L))(x) # [1] NA compiler::cmpfun(mysd, list(optimize = 3L))(x) # [1] NaN The problem does not appear with gcc 5.2.0 on Debian, and also not with gcc 4.9.3 on Windows. Where do I start debugging this? The disassembled output from the compiled functions is here: https://gist.github.com/jeroenooms/3206945a6db6680a9c5c
Simon Urbanek
2015-Sep-14 13:27 UTC
[Rd] Optimization bug when byte compiling with gcc 5.2.0 on windows
Jeroen, the difference is that level 3 is using the internal implementation of sqrt in the compiler instead of calling the sqrt function. The internal path goes to R_sqrt which is defined as # define R_sqrt(x) (ISNAN(x) ? x : sqrt(x)) so you could check if that is where the problem happens. It theory NA should yield itself, but perhaps the compiler thinks all NANs are equal and will return a constant one. If that's not it, then something else in the direct FastMath1(R_sqrt, R_SqrtSym) path... Cheers, Simon> On Sep 14, 2015, at 8:49 AM, Jeroen Ooms <jeroen.ooms at stat.ucla.edu> wrote: > > When building R-devel with gcc 5.2.0 (mingw-w64 v4) on Windows, make > check fails reg-tests-1b.R at the following check: > > x <- c(1:2, NA) > sx <- sd(x) > !is.nan(sx) > > Here 'sx' should be 'NA' but it is 'NaN'. It turns out this problem > only appears when the function is byte compiled with optimization > level 3: > > mysd <- function (x, na.rm = FALSE) > sqrt(var(if (is.vector(x)) x else as.double(x), na.rm = na.rm)) > > mysd(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 1L))(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 2L))(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 3L))(x) > # [1] NaN > > The problem does not appear with gcc 5.2.0 on Debian, and also not > with gcc 4.9.3 on Windows. Where do I start debugging this? The > disassembled output from the compiled functions is here: > https://gist.github.com/jeroenooms/3206945a6db6680a9c5c > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >
luke-tierney at uiowa.edu
2015-Sep-14 13:36 UTC
[Rd] Optimization bug when byte compiling with gcc 5.2.0 on windows
I believe the issue is that on Windows the sqrt function when called with a NaN does not return the same NaN, as it does on other platforms. We have #if (defined(_WIN32) || defined(_WIN64)) && defined(__GNUC__) && \ __GNUC__ <= 4 # define R_sqrt(x) (ISNAN(x) ? x : sqrt(x)) #else # define R_sqrt sqrt #endif for implementing the SQRT opcode. I suspect this came from Duncan Murdoch; I don't know the reason for restricting to __GNUC__ <= 4. I seem to recall that there are other places in the code where we have similar workarounds but I can't find them at the moment. The builtin sqrt always pretests with ISNAN. Best, luke On Mon, 14 Sep 2015, Jeroen Ooms wrote:> When building R-devel with gcc 5.2.0 (mingw-w64 v4) on Windows, make > check fails reg-tests-1b.R at the following check: > > x <- c(1:2, NA) > sx <- sd(x) > !is.nan(sx) > > Here 'sx' should be 'NA' but it is 'NaN'. It turns out this problem > only appears when the function is byte compiled with optimization > level 3: > > mysd <- function (x, na.rm = FALSE) > sqrt(var(if (is.vector(x)) x else as.double(x), na.rm = na.rm)) > > mysd(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 1L))(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 2L))(x) > # [1] NA > compiler::cmpfun(mysd, list(optimize = 3L))(x) > # [1] NaN > > The problem does not appear with gcc 5.2.0 on Debian, and also not > with gcc 4.9.3 on Windows. Where do I start debugging this? The > disassembled output from the compiled functions is here: > https://gist.github.com/jeroenooms/3206945a6db6680a9c5c > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Luke Tierney Ralph E. Wareham Professor of Mathematical Sciences University of Iowa Phone: 319-335-3386 Department of Statistics and Fax: 319-335-3017 Actuarial Science 241 Schaeffer Hall email: luke-tierney at uiowa.edu Iowa City, IA 52242 WWW: http://www.stat.uiowa.edu
Duncan Murdoch
2015-Sep-14 14:16 UTC
[Rd] Optimization bug when byte compiling with gcc 5.2.0 on windows
On 14/09/2015 9:36 AM, luke-tierney at uiowa.edu wrote:> I believe the issue is that on Windows the sqrt function when called > with a NaN does not return the same NaN, as it does on other platforms. > We have > > #if (defined(_WIN32) || defined(_WIN64)) && defined(__GNUC__) && \ > __GNUC__ <= 4 > # define R_sqrt(x) (ISNAN(x) ? x : sqrt(x)) > #else > # define R_sqrt sqrt > #endif > > for implementing the SQRT opcode. I suspect this came from Duncan > Murdoch; I don't know the reason for restricting to __GNUC__ <= 4.That was an update to keep the workaround for gcc 4.9.2. The previous code restricted the change to 4.6.x or earlier. I think the reason for the earlier restriction is the assumption that eventually gcc will be fixed and this workaround won't be necessary, but apparently 5.2.0 still has the same problem. Duncan Murdoch> I > seem to recall that there are other places in the code where we have > similar workarounds but I can't find them at the moment. > > The builtin sqrt always pretests with ISNAN. > > Best, > > luke > > > > On Mon, 14 Sep 2015, Jeroen Ooms wrote: > > > When building R-devel with gcc 5.2.0 (mingw-w64 v4) on Windows, make > > check fails reg-tests-1b.R at the following check: > > > > x <- c(1:2, NA) > > sx <- sd(x) > > !is.nan(sx) > > > > Here 'sx' should be 'NA' but it is 'NaN'. It turns out this problem > > only appears when the function is byte compiled with optimization > > level 3: > > > > mysd <- function (x, na.rm = FALSE) > > sqrt(var(if (is.vector(x)) x else as.double(x), na.rm = na.rm)) > > > > mysd(x) > > # [1] NA > > compiler::cmpfun(mysd, list(optimize = 1L))(x) > > # [1] NA > > compiler::cmpfun(mysd, list(optimize = 2L))(x) > > # [1] NA > > compiler::cmpfun(mysd, list(optimize = 3L))(x) > > # [1] NaN > > > > The problem does not appear with gcc 5.2.0 on Debian, and also not > > with gcc 4.9.3 on Windows. Where do I start debugging this? The > > disassembled output from the compiled functions is here: > > https://gist.github.com/jeroenooms/3206945a6db6680a9c5c > > > > ______________________________________________ > > R-devel at r-project.org mailing list > > https://stat.ethz.ch/mailman/listinfo/r-devel > > >
Reasonably Related Threads
- Optimization bug when byte compiling with gcc 5.2.0 on windows
- Optimization bug when byte compiling with gcc 5.2.0 on windows
- Optimization bug when byte compiling with gcc 5.2.0 on windows
- Optimization bug when byte compiling with gcc 5.3.0 on windows
- Optimization bug when byte compiling with gcc 5.3.0 on windows