[Rd] names in optim()
Dear both, I have just found that names are treated in the same way in optim() depending on the optimization method. The example below shows the difference between the Brent method and the L-BFGS-B method. f <- function(x){ y <- x^2;names(y) <-"f(x)";y} optim(10, f, method="Brent", lower=-1, upper=10)$value optim(10, f, method="L-BFGS-B", lower=-1, upper=10)$value z <- 10 names(z) <- "x" z optim(z, f, method="Brent", lower=-1, upper=10)$par optim(z, f, method="L-BFGS-B", lower=-1, upper=10)$par Do you obtain the same behavior? I’m using R version 3.2.1 (2015-06-18) Platform: x86_64-apple-darwin13.4.0 (64-bit) Running under: OS X 10.9.5 (Mavericks) locale: [1] fr_FR.UTF-8/fr_FR.UTF-8/fr_FR.UTF-8/C/fr_FR.UTF-8/fr_FR.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] tools_3.2.1 Kind regards, CD --- Christophe Dutang LMM, UdM, Le Mans, France web: http://dutangc.free.fr __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] OpenMP problem with 64-bit Rtools
I've been getting pqR to work on windows systems, and in the process have discovered various problems with R core versions of R and with Rtools. One is with the implementation of OpenMP in 64-bit Rtools. This problem is in Rtools215 and Rtools33, and presumably all the ones in between. You can see the problem with the following test program: #include #include static struct { omp_lock_t lock; char pad[20]; } s; void show_pad(void) { int i; for (i = 0; i<20; i++) printf(" %02x",s.pad[i]); printf("\n"); } int main(void) { int i; printf("size: %d\n",(int)sizeof s); for (i = 0; i<20; i++) s.pad[i] = 7; show_pad(); omp_init_lock (&s.lock); show_pad(); omp_set_lock (&s.lock); show_pad(); return 0; } When compiled using the Rtools compiler with "gcc -m32 -fopenmp", it works fine, printing three lines of output with all numbers being 7. But when compiled with "gcc -m64 -fopenmp", the last two lines have four zeros at the beginning. What's happended is that omp_init_lock has written zeros to four bytes after the end of the omp_lock_t structure. The reason for this appears to be that the omp.h file included is appropriate only for the 32-bit version of the openMP library. As far as I can see, there is no 64-bit version of this include file in the stuff installed with Rtools. This problem obviously has the potential to affect many packages that use OpenMP, though simple OpenMP applications may not do anything for which the incorrect omp.h include file makes a difference. Radford Neal __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Problem with psignal.c for Windows builds
Continuing with problems that I've uncovered while getting pqR to work on Windows... The file src/ghuwin32/psignal.c (used only in Windows builds) fails to use the sigset_t type in all places where it should, using "int" some places instead. Here is a diff of the needed corrections: @@ -253,7 +253,7 @@ sighandler_t signal(int signal_Number, sighandler_t signal_Handler) int sigaddset(sigset_t* sigset_Info,int signal_Number) { if (IS_SIGNAL(signal_Number)) { - (*sigset_Info) |= (1 << (signal_Number - 1)); + (*sigset_Info) |= ((sigset_t)1 << (signal_Number - 1)); return 0; } else { @@ -267,7 +267,7 @@ int sigaddset(sigset_t* sigset_Info,int signal_Number) int sigdelset(sigset_t* sigset_Info,int signal_Number) { if (IS_SIGNAL(signal_Number)) { - *sigset_Info &= ~(1<< (signal_Number - 1)); + *sigset_Info &= ~((sigset_t)1<< (signal_Number-1)); return 0; } else { @@ -295,7 +295,7 @@ int sigfillset(sigset_t* sigset_Info) int sigismember(sigset_t* sigset_Info,int signal_Number) { if (IS_SIGNAL(signal_Number)) { - if ( *sigset_Info & (1 << (signal_Number-1))) + if ( *sigset_Info & ((sigset_t)1 << (signal_Number-1))) return 1; else return 0; @@ -380,9 +380,9 @@ int sigprocmask(int mask_Function,sigset_t* sigset_Info, } /* Set signal mask = */ -int sigsetmask(int signal_MaskNew) +sigset_t sigsetmask(sigset_t signal_MaskNew) { -int signal_MaskOld = downhill_Sigset_Mask; +sigset_t signal_MaskOld = downhill_Sigset_Mask; if (sigprocmask(SIG_SETMASK, &signal_MaskNew, NULL) == -1) return (int)-1; @@ -391,7 +391,7 @@ int sigsetmask(int signal_MaskNew) } /* Add signals to mask = */ -int sigblock(int signal_MaskNew) +sigset_t sigblock(sigset_t signal_MaskNew) { /* Block a specific group of signals */ return sigsetmask(downhill_Sigset_Mask|signal_MaskNew); Now, you may wonder how it's been working with these errors. The file src/gnuwin32/fixed/h/psignal.h has the following code: /* mingw-w64's sys/types.h also defines this and we want this defn */ #ifndef _SIGSET_T_ #define _SIGSET_T_ typedef int sigset_t; #endif /* Not _SIGSET_T_ */ The comment is unclear as to whether the mingw definition is or is not the one that is desired (what does "this" refer to?). Anyway, the mingw sys/types.h file contains the following code: #ifndef _SIGSET_T_ #define _SIGSET_T_ #ifdef _WIN64 __MINGW_EXTENSION typedef unsigned long long _sigset_t; #else typedef unsigned long _sigset_t; #endif #ifdef _POSIX typedef _sigset_t sigset_t; #endif #endif /* Not _SIGSET_T_ */ So if the R psignal.h file is included before sys/types, sigset_t will be defined as "int", not as "unsigned long" or "unsigned long long". And in fact it seems that R (though not pqR) always includes psignal.h before sys/types.h (if the latter is included as well). There's even this code snippet in src/unix/Rscript.c: #ifdef WIN32 #include /* on some systems needs to be included before */ #endif And indeed, with Rtools, you do have to include psignal.h first, since the mingw sys/types.h defines _SIGSET_T_, preventing psignal.h from defining sigset_t but does not define sigset_t itself (rather only _sigset_t), since _POSIX isn't defined. So current R Core releases (accidentally?) avoid the problem by not actually using mingw's sigset_t type, but instead always using int. But it's possible that there is some reason to want to use the type defined in sys/types.h. Radford Neal __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Getting SSE2 instructions to work in 32-bit builds on Windows
When getting pqR to work on Windows, I've wanted for it to be able to use SSE2 instructions with 32-bit builds, for those 32-bit processors that have SS2 instructions (all of them from the Pentium 4 onwards). It seems that R Core 32-bit versions do not attempt this, instead using the 387 FPU for all floating-point arithmetic. This is sometimes slower than using SSE2 instructions, and also produces results that are not compliant with the IEEE floating point standard, and that are not reproducible - possibly changing after trivial, unrelated changes to R or to the C compiler used. Once can get the gcc used in Rtools to use SSE2 instructions by including the following compiler options: -m32 -msse2 -mfpmath=sse Unfortunately, the result is that some things then crash. The problem is that by default gcc assumes that the stack is aligned to a 16-byte boundary on entry to a procedure, which allows it to easily ensure the 16-byte alignment needed for SSE2 instructions. Unfortunately, Windows does not ensure that a 32-bit application's stack is 16-byte aligned, so this doesn't work. (There's no problem for 64-bit builds, however.) A solution is to add one more option: -m32 -msse2 -mfpmath=sse -mstackrealign The -mstackrealign option forces gcc to generate code to align the stack on procedure entry, rather than assuming it is already aligned. It would probably be enough to compile only a few modules with this option (ones that are directly called from outside R), and hence avoid most of the extra procedure call overhead, but I haven't attempted this. Radford Neal __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] Problems with embedded R, ReplDLL
Along with getting pqR to work on Windows, I've also been testing it in the context of embedded R, and in the process have found some problems with the examples given of embedded R use. One problem can be seen in R_ReplDLLinit, in src/main/main.c: void R_ReplDLLinit(void) { SETJMP(R_Toplevel.cjmpbuf); R_GlobalContext = R_ToplevelContext = R_SessionContext = &R_Toplevel; R_IoBufferWriteReset(&R_ConsoleIob); prompt_type = 1; DLLbuf[0] = DLLbuf[CONSOLE_BUFFER_SIZE] = '\0'; DLLbufp = DLLbuf; } The call of SETJMP makes no sense. Nothing that follows in this function can possibly cause a long jump. The use of R_ReplDLLinit is illustrated in the R Extensions manual (doc/manual/R-exts.texi): R_ReplDLLinit(); while(R_ReplDLLdo1() > 0) { /* add user actions here if desired */ } Note that the R_ReplDLLdo1 function does not call SETJMP. Amazingly, however, the combination sometimes seems to work! When a long jump is taken during evaluation of an expression initiated by R_ReplDLLdo1, the stack is restored to the value suitable for the now-non-existent stack frame for R_ReplDLLinit, and execution of the statements in R_ReplDLLinit then continues after the SETJMP. Likely, none of these statements actually refers to the non-existent stack frame (seeing as this function has no parameters and no local variables), so nothing disastrous occurs, and in the end the procedure return code at the end of R_ReplDLLinit has the effect of doing a return from R_ReplDLLdo1, which is more-or-less the desired result. Obviously, one does not want a program to "work" for such reasons, which may cease to apply with any change to how the C compiler generates code. The current development version of pqR has a different version of R_ReplDLLdo1, which calls SETJMP itself, but this version is tied to other rationalizations of the Repl functions in the development version of pqR. The embedded R examples and tests have various other problems that are fixed in the current development branch of pqR (branch 44 at the moment). R Core might want to take a look there, or at the next version of pqR, which will be released soon. Radford Neal __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] unset() function?
Does R have a function like the S/S++ unset() function? unset(name) would remove 'name' from the current evaluation frame and return its value. It allowed you to safely avoid some memory copying when calling .C or .Call. E.g., suppose you had C code like #include #include SEXP add1(SEXP pX) { int nProtected = 0; int n = Rf_length(pX); int i; double* x; Rprintf("NAMED(pX)=%d: ", NAMED(pX)); if (NAMED(pX)) { Rprintf("Copying pX before adding 1\n"); PROTECT(pX = duplicate(pX)); nProtected++; } else { Rprintf("Changing pX in place\n"); } x = REAL(pX); for(i=0 ; i add1(c(1.2, 3.4)) NAMED(pX)=2: Copying pX before adding 1 [1] 2.2 4.4 If I make the .Call directly, without a nice R function around it then I can avoid the copy > .Call("add1", c(1.2, 3.4)) NAMED(pX)=0: Changing pX in place [1] 2.2 4.4 If something like S's unset() were available I could avoid the copy, when safe to do so, by making the .Call in add1 .Call("add1", unset(x)) If you called this new add1 with a named variable from another function the copying would be done, since NAMED(x) would be 2 even after the local binding was removed. It actually requires some care to to eliminate the copying, as all the functions in the call chain would have to use unset() when possible. I ask this because I ran across a function in the 'bit' package that does not have its C code call duplicate but instead assumes the x[1] <- x[1] will force x to be copied: "!.bit" <- function(x){ if (length(x)){ ret <- x ret[1] <- ret[1] # force duplication .Call("R_bit_not", ret, PACKAGE="bit") }else{ x } } If you optimize things so that 'ret[1] <- ret[1]' does not copy 'ret', then this function alters its input. It a function like unset() were there then the .Call could be .Call("R_bit_not", unset(x)) I suppose the compiler could analyze the code and see that x was not used after the .Call and thus feel free to avoid the copy. In any case bit's maintainer should add something like if(NAMED(x) { PROTECT(x=duplicate(x)); nProtect++; } ... UNPROTECT(nProtect); in the C code, but unset() would help avoid unneeded duplications. Bill Dunlap TIBCO Software wdunlap tibco.com [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] unset() function?
> Does R have a function like the S/S++ unset() function? That should be 'S+' or 'S-Plus', not the typo 'S++'. Bill Dunlap TIBCO Software wdunlap tibco.com On Fri, Aug 21, 2015 at 1:43 PM, William Dunlap wrote: > Does R have a function like the S/S++ unset() function? > unset(name) would remove 'name' from the current evaluation > frame and return its value. It allowed you to safely avoid > some memory copying when calling .C or .Call. > > E.g., suppose you had C code like > #include > #include > SEXP add1(SEXP pX) > { > int nProtected = 0; > int n = Rf_length(pX); > int i; > double* x; > Rprintf("NAMED(pX)=%d: ", NAMED(pX)); > if (NAMED(pX)) { > Rprintf("Copying pX before adding 1\n"); > PROTECT(pX = duplicate(pX)); nProtected++; > } else { > Rprintf("Changing pX in place\n"); > } > x = REAL(pX); > for(i=0 ; i x[i] = x[i] + 1.0; > } > UNPROTECT(nProtected); > return pX; > } > > If I call this from an R function > add1 <- function(x) { > stopifnot(inherits(x, "numeric")) > .Call("add1", x) > } > it will will always copy 'x', even though not copying would > be safe (since add1 doesn't use 'x' after calling .Call()). > > add1(c(1.2, 3.4)) > NAMED(pX)=2: Copying pX before adding 1 > [1] 2.2 4.4 > If I make the .Call directly, without a nice R function around it > then I can avoid the copy > > .Call("add1", c(1.2, 3.4)) > NAMED(pX)=0: Changing pX in place > [1] 2.2 4.4 > > If something like S's unset() were available I could avoid the copy, > when safe to do so, by making the .Call in add1 >.Call("add1", unset(x)) > > If you called this new add1 with a named variable from another > function the copying would be done, since NAMED(x) would be > 2 even after the local binding was removed. It actually requires some > care to to eliminate the copying, as all the functions in the call > chain would have to use unset() when possible. > > I ask this because I ran across a function in the 'bit' package that > does not have its C code call duplicate but instead assumes the > x[1] <- x[1] will force x to be copied: > "!.bit" <- function(x){ > if (length(x)){ > ret <- x > ret[1] <- ret[1] # force duplication > .Call("R_bit_not", ret, PACKAGE="bit") > }else{ > x > } > } > If you optimize things so that 'ret[1] <- ret[1]' does not copy 'ret', > then this function alters its input. It a function like unset() > were there then the .Call could be > .Call("R_bit_not", unset(x)) > > I suppose the compiler could analyze the code and see that > x was not used after the .Call and thus feel free to avoid the > copy. > > In any case bit's maintainer should add something like > if(NAMED(x) { > PROTECT(x=duplicate(x)); > nProtect++; > } > ... > UNPROTECT(nProtect); > in the C code, but unset() would help avoid unneeded duplications. > > > Bill Dunlap > TIBCO Software > wdunlap tibco.com > [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] RFC: deprecating some complexity in key methods package functions
Dear R community, I have been working on speeding up a few parts of the methods package and related environment/namespace functionality. I would like to get some community input on a few proposed changes that are rather small, but do involve deprecations. These changes would simplify and speed-up some functions that are called with extreme frequency. I have made a few suggestions in the following R bug tracker submissions: https://bugs.r-project.org/bugzilla3/attachment.cgi?id=1896 https://bugs.r-project.org/bugzilla3/attachment.cgi?id=1897 In summary, the function 'is' can be called with a single argument, which gives the same result as calling 'extends' directly. The second argument to 'is' can be one of two types (a class name or a class definition), but it seems that only one of those options is ever used in methods or in base. I'd like to deprecate using a classDef as the second argument as we can now go quite fast without doing so. .getGeneric has an unnecessary swap of as.double for as.numeric and also what looks like it might be a bit of vestigial debug code ( a check for package == "" and detailed stack trace). The subsequent C code also checks for this situation, so I think we can omit the first check. If anyone feels strongly about deprecating these code paths, please let me know. As a community, we are very careful about backwards compatibility so I want to be sure no one needs these things. Regards, Pete Peter M. Haverty, Ph.D. Genentech, Inc. phave...@gene.com [[alternative HTML version deleted]] __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] OpenMP problem with 64-bit Rtools
Hi Radford On Fri, Aug 21, 2015 at 8:38 PM, Radford Neal wrote: > > I've been getting pqR to work on windows systems, and in the process > have discovered various problems with R core versions of R and with > Rtools. We happen to be working on a new version of the windows tool chain, perhaps you are interested to test if problems still exist in the latest versions. Find a copy of gcc-4.9.2 as well as an installer with the latest r-devel built with this compiler here: http://www.stat.ucla.edu/~jeroen/mingw-w64/. Note that this R installer contains a copy of the tool chain (hence requires no seperate 'rtools' installation). > The reason for this appears to be that the omp.h file included is > appropriate only for the 32-bit version of the openMP library. As > far as I can see, there is no 64-bit version of this include file > in the stuff installed with Rtools. This particular behavior exists in all builds of mingw-w64, not rtools per se. We might get a better answer in the mingw-w64-public mailing list. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] OpenMP problem with 64-bit Rtools
> On Fri, Aug 21, 2015 at 8:38 PM, Radford Neal wrote: > > > The reason for this appears to be that the omp.h file included is > > appropriate only for the 32-bit version of the openMP library. As > > far as I can see, there is no 64-bit version of this include file > > in the stuff installed with Rtools. On Sat, Aug 22, 2015 at 01:30:51AM +0200, Jeroen Ooms wrote: > This particular behavior exists in all builds of mingw-w64, not rtools > per se. We might get a better answer in the mingw-w64-public mailing > list. A comment near the front of omp.h says "These two structures get edited by the libgomp build process to reflect the shape of the two types". So presumably it is possible to generate the 64-bit version, and presumably this must have been done in order to compile the 64-bit version of the OpenMP library that is supplied with Rtools. Maybe there's no provision in the build process for having two omp.h files at once, though... Radford __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel