Fatal Error while using Rcpp in RStudio on Windows - r

I'm trying to use Rcpp on Windows in RStudio. I have R version 3.2.3 and I have installed the Rcpp package. The problem is that I am unable to call any functions defined through the CPP code. I tried the following (picked up from an example online).
body <- '
NumericVector xx(x);
return wrap( std::accumulate( xx.begin(), xx.end(), 0.0));'
add <- cxxfunction(signature(x = "numeric"), body, plugin = "Rcpp")
This gives the following warning, but completes execution successfully.
cygwin warning:
MS-DOS style path detected: C:/R/R-32~1.3/etc/x64/Makeconf
Preferred POSIX equivalent is: /cygdrive/c/R/R-32~1.3/etc/x64/Makeconf
CYGWIN environment variable option "nodosfilewarning" turns off this warning.
Consult the user's guide for more details about POSIX paths:
http://cygwin.com/cygwin-ug-net/using.html#using-pathnames
When I try to use the above function,
x <- 1
y <- 2
res <- add(c(x, y))
I get the following error :
R Session Aborted
R encountered a fatal error.
The session was terminated.
Any suggestions? This same 'Fatal Error' happens for any code that I run with Rcpp.

Try rebuilding locally, starting with Rcpp. This is valid code and will work (and the hundreds of unit tests stress may more than this). Sometimes the compiler or something else changes under you and this sort of thing happens. It is then useful to have an alternative build system -- eg via Travis at GitHub you get Linux for free.
Also, learning about Rcpp Attributes. Your example can be written as
R> library(Rcpp)
R> cppFunction("double adder(std::vector<double> x) { return std::accumulate(x.begin(), x.end(), 0.0); }")
R> adder(c(1,2))
[1] 3
R>
which is simpler. Works of course the same way with Rcpp::NumericVector.

Related

How can I switch virtualenv from reticulate in R?

In R package reticulate there is a function use_virtualenv but it does not look like I can call it twice with different virtualenvs, second call is always ignored.
Is there a way to deactivate first virtualenv so I can call use_virtualenv("venv2") with the expected behavior?
#initialize
require(reticulate)
virtualenv_create("venv1")
virtualenv_create("venv2")
#call first virtualenv
use_virtualenv("venv1")
py_config() #show venv1 specs
#call second vrtualenv
use_virtualenv("venv2")
py_config() # still show venv1 specs, I want venv2 here
I think unloadNamespace("reticulate") could work but in my case first call is made by another package...
In short: By restarting the R session! You can't switch virtualenv in reticulate once chosen!
I tried it (but chose "venv2" first).
> use_python("venv1", T)
Error in use_python("venv1", T) :
Specified version of python 'venv1' does not exist.
> use_python("~/.virtualenvs/venv1", T)
ERROR: The requested version of Python ('~/.virtualenvs/venv1') cannot
be used, as another version of Python
('/home/josephus/.virtualenvs/venv2/bin/python') has already been
initialized. Please restart the R session if you need to attach
reticulate to a different version of Python.
Error in use_python("~/.virtualenvs/venv1", T) :
failed to initialize requested version of Python
So reticulate messages, that one has to start a new session to choose new virtual environment.
This must apply to use_virtualenv(<xxx>, T) too, though it is not as verbose as use_python(<xxx>, T).

How to ensure english error messages in testthat unit tests

I have a lot of unit tests using the testthat package that expect english error messages.
If other developer run the tests on a computer configured for a non-english locale the error message are emitted in a different language and my tests fail.
How can I initialize testthat to change the language settings only during the test run-time without manually or permanently changing the language or test environment from outside of R (like e. g. proposed here: in R how to get error messages in english)?
library(testthat)
# works only in english locales...
expect_error(log("a"), "non-numeric argument to mathematical function", fixed = TRUE)
Edit 1: Changing the locale during run-time does not change the language of the error messages (using Ubuntu and OSX High Sierra):
Sys.setlocale( locale = "en_US.UTF-8")
Sys.getlocale() # en_US is active now but messages are still in another language
Edit 2: It seems that Sys.setenv("LANGUAGE"="EN") seems to change the error message language immediately (tested using OSX). Where should I put this command for testthat? In the testthat.R file?
The R console is in German language, how can I set R to English?
Edit 3: As a first work-around I have put
Sys.setenv("LANGUAGE"="EN") # work-around to always create english R (error) messages
into my testthat.R file under the tests folder (it seems to work but I am not sure whether this is the right or best way...
Setting Sys.setenv("LANGUAGE" = "EN") works for me as well.
However, when testing with devtools::test() - as ctrl + shift + T in Rstudio will do - I had to call Sys.setenv() in the test scripts inside the tests/testthat/ directory. The reason being that devtools::test() will call testthat::test_dir() circumventing the tests/testthat.R file.
So far, this did not have undesirable side-effects. The environment variable will only be set for that particular R process as described in the help page:
Sys.setenv sets environment variables (for other processes called from within R or future calls to Sys.getenv from this R process).
For completeness, you can also unset the variable again on Windows (see comments).
Sys.setenv("LANGUAGE" = "DE")
expect_error(log("a"), "Nicht-numerisches Argument")
Sys.setenv("LANGUAGE" = "FR")
expect_error(log("a"), "argument non numérique ")
Sys.unsetenv("LANGUAGE")
RStudio might also give trouble (I was not able to change the language there interactively), but when executing with devtools::test() it works.
Finally, wrapping it in a helper function.
expect_error_lang <- function(..., lang = "EN") {
Sys.setenv("LANGUAGE" = lang)
expect_error(...)
Sys.unsetenv("LANGUAGE")
}
#...
expect_error_lang(log("a"), "non-numeric")
expect_error_lang(log("a"), "Nicht-numerisches", lang = "DE")
expect_error_lang(log("a"), "argument non", lang = "FR")

R: Patching a package function and reloading base libraries

Occasionally one wants to patch a function in a package, without recompiling the whole package.
For example, in Emacs ESS, the function install.packages() might get stuck if tcltk is not loaded. One might want to patch install.packages() in order to require tcltk before installation and unload it after the package setup.
A temp() patched version of install.packages() might be:
## Get original args without ending NULL
temp=rev(rev(deparse(args(install.packages)))[-1])
temp=paste(paste(temp, collapse="\n"),
## Add code to load tcltk
"{",
" wasloaded= 'package:tcltk' %in% search()",
" require(tcltk)",
## Add orginal body without braces
paste(rev(rev(deparse(body(install.packages))[-1])[-1]), collapse="\n"),
## Unload tcltk if it was not loaded before by user
" if(!wasloaded) detach('package:tcltk', unload=TRUE)",
"}\n",
sep="\n")
## Eval patched function
temp=eval(parse(text=temp))
# temp
Now we want to replace the original install.packages() and perhaps insert the code in Rprofile.
To this end it is worth nothing that:
getAnywhere("install.packages")
# A single object matching 'install.packages' was found
# It was found in the following places
# package:utils
# namespace:utils
# with value
#
# ... install.packages() source follows (quite lengthy)
That is, the function is stored inside the package/namespace of utils. This environment is sealed and therefore install.packages() should be unlocked before being replaced:
## Override original function
unlockBinding("install.packages", as.environment("package:utils"))
assign("install.packages", temp, envir=as.environment("package:utils"))
unlockBinding("install.packages", asNamespace("utils"))
assign("install.packages", temp, envir=asNamespace("utils"))
rm(temp)
Using getAnywhere() again, we get:
getAnywhere("install.packages")
# A single object matching 'install.packages' was found
# It was found in the following places
# package:utils
# namespace:utils
# with value
#
# ... the *new* install.packages() source follows
It seems that the patched function is placed in the right place.
Unfortunately, running it gives:
Error in install.packages(xxxxx) :
could not find function "getDependencies"
getDependencies() is a function inside the same utils package, but not exported; therefore it is not accessible outside its namespace.
Despite the output of getAnywhere("install.packages"), the patched install.packages() is still misplaced.
The problem is that we need to reload the utils library to obtain the desired effect, which also requires unloading other libraries importing it.
detach("package:stats", unload=TRUE)
detach("package:graphics", unload=TRUE)
detach("package:grDevices", unload=TRUE)
detach("package:utils", unload=TRUE)
library(utils)
install.packages() works now.
Of course, we need to reload the other libraries too. Given the dependencies, using
library(stats)
should reload everything. But there is a problem when reloading the graphics library, at least on Windows:
library(graphics)
# Error in FUN(X[[i]], ...) :
# no such symbol C_contour in package path/to/library/graphics/libs/x64/graphics.dll
Which is the correct way of (re)loading the graphics library?
Patching functions in packages is a low-level operation that should be avoided, because it may break internal assumptions of the execution environment and lead to unpredictable behavior/crashes. If there is a problem with tck/ESS (I didn't try to repeat that) perhaps it should be fixed or there may be a workaround. Particularly changing locked bindings is something to avoid.
If you really wanted to run some code at the start/end of say install.packages, you can use trace. It will do some of the low-level operations mentioned in the question, but the good part is you don't have to worry about fixing this whenever some new internals of R change.
trace(install.packages,
tracer=quote(cat("Starting install.packages\n")),
exit=quote(cat("Ending install packages.\n"))
)
Replace tracer and exit accordingly - maybe exit is not needed anyway, maybe you don't need to unload the package. Still, trace is a very useful tool for debugging.
I am not sure if that will solve your problem - if it would work with ESS - but in general you can also wrap install.packages in a function you define say in your workspace:
install.packages <- function(...) {
cat("Entry.\n")
on.exit(cat("Exit.\n"))
utils::install.packages(...)
}
This is the cleanest option indeed.

Source build of Rquantlib fails

I'm building Rquantlib from source and I recently have been encountering this issue:
Error in .Call("RQuantLib_setEvaluationDate", PACKAGE = "RQuantLib", evalDate) :
"RQuantLib_setEvaluationDate" not available for .Call() for package "RQuantLib"
Error : unable to load R code in package ‘RQuantLib’
R version 3.2.3 (2015-12-10)
Rcpp version 0.12.4
I have checked and setEvaluationDate() is there with appropriate rcpp tags, so not sure what's changed. I have not edited the file. It seems to be an inline version, wheras the github version is an actual call:
My rcpp generated inlcude verion for the function:
inline bool setEvaluationDate(QuantLib::Date evalDate) {
typedef SEXP(*Ptr_setEvaluationDate)(SEXP);
static Ptr_setEvaluationDate p_setEvaluationDate = NULL;
}
From github:
bool setEvaluationDate(QuantLib::Date evalDate);
static SEXP RQuantLib_setEvaluationDate_try(SEXP evalDateSEXP) {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::traits::input_parameter< QuantLib::Date >::type evalDate(evalDateSEXP);
__result = Rcpp::wrap(setEvaluationDate(evalDate));
return __result;
END_RCPP_RETURN_ERROR
}
You need to recompile all dependents of Rcpp after major upgrades.
Eg when we went from Ubuntu 15.04 to 15.10 which changed the compiler to g++-5 with its new ABI, ran this this script to rebuild everything from the local repo:
#!/usr/bin/env r
## installed packages
IP <- installed.packages()
## all local packages
AP <- available.packages(contrib.url(getOption("repos")[["local"]]))
## all packages known to us
allAP <- available.packages()
pkgs <- "Rcpp"
deps <- tools::package_dependencies(packages=pkgs, db=IP, reverse=TRUE)
## set of dependencies
alldeps <- unique(sort(do.call(c, deps)))
cat("Installing these:\n")
print(alldeps)
## this makes sense on Debian where no packages touch /usr/local
libloc <- Sys.getenv("LIBLOC", unset="/usr/local/lib/R/site-library")
install.packages(alldeps, lib=libloc)
It is similar when something in Rcpp changes, though we've been pretty good about not changing interfaces. But when in doubt, rebuild. Also re-run compileAttributes() if in doubt but little changed there.
Edit: I just (re-)installed without a glitch on two systems too.
Edit 2: It also works directly at the R prompt:
## what follows was one line in R and just broken up for display
R> cppFunction("bool mySetEvalDate(QuantLib::Date d) "
"{ QuantLib::Settings::instance().evaluationDate() = d;"
" return true; }", depends="RQuantLib")
R> mySetEvalDate( Sys.Date() )
[1] TRUE
R>
Now, if your intent was to call setEvaluationDate() from C++ then you need to look at the discussion about exporting to R and C++ in the Rcpp Attributes vignettes. The code in src/daycounter.cpp is meant for R.

What is the cause of "Error in .C("unlock solver")" Error in deSolve Package?

I have been using the deSolve package in a MCMC algorithm to estimate parameters in an ODE and wrote the functions used in the solver in C to speed up the algorithm. Sometimes, but not always I get the error Error in .C("unlock solver") when running the ode function. I am able to successfully compile and link the C files using the commands
system("R CMD SHLIB [insert-file-path]")
dyn.load("[dll-file-path]")
but when I try to solve the ODE using the dll file, the error is thrown. Then, even when running a simple script like the one below, I get the same error. I think the issue is related to using the compiled code, but I don't know how and cannot find any references on this error.
> require(deSolve)
> initVal <- c(y=1)
> times <- seq(0, 1, 0.001)
> parms <- c(k=1)
> model1 <- function(t, y, parms){
+ with(as.list(c(y, parms)),{
+ dy <- -k*y;
+ list(c(dy))
+ })
+ }
> out <- ode(y=initVal, times=times, parms=parms, func=model1)
Error in .C("unlock_solver") :
"unlock_solver" not resolved from current namespace (deSolve)
Partial Solution
If I restart R and only load the DLL using the dyn.load function, but don't compile the code, the ode function runs without an error. This fixes my problem, but I still have no idea why.
Edit:
REAL solution from Thomas Petzoldt on the R help list:
[The error] occurs, if package deSolve is loaded after the compiled model... The solution is to load deSolve before [before loading DLL's], ideally at the very beginning of your script, and at least before loading/unloading the DLL/.so
If that doesn't work, the below might as well (old answer):
I have found a somewhat inelegant solution.
The problem seems to be that the "unlock_solver" function within deSolve is somehow not being accessed correctly. You can unload and reload the entire deSolve.so file, rather than restarting R.
To do this you can use something like:
require(deSolve)
# encounter error
library.dynam.unload("deSolve", libpath=paste(.libPaths()[1], "//deSolve", sep=""))
library.dynam("deSolve", package="deSolve", lib.loc=.libPaths()[1])
You'll need to replace ".libPaths()[1]" with wherever you have installed deSolve, if it isn't in the first element of your .libPaths variable.
This is something of a sledge hammer, though. I've sent out a request to the r-help list asking if there is some way to either change where R looks for "unlock_solver", or to just unload/reload a portion of deSolve.
Make sure you have the following packages installed (at the beginning of your script) to compile the .dll file.
packages <- c("deSolve","coda", "adaptMCMC")
if(require(packages)){
install.packages(packages,dependencies = T)
}
ppp <- lapply(packages,require,character.only=T)
First remove the current .dll file in your wdir
c_compile <- "your_c_file"
dyn.unload(paste0(c_compile,".dll")) # unload dll (Windows only)
Then compile the C file and the .dll
system(paste0("R CMD SHLIB ",c_compile,".c"))
dyn.load(paste0(c_compile,".dll"))# Load dll (Windows only)

Resources