<div dir="ltr">Thanks for the quick reply! What kind of errors are we talking about? I a new run I explicitly caused an error by passing a character vector, and had no memory leak (using Valgrind):<div><br></div><div>cppFuncall(letters, fun)</div><div>Error in cos(x[1]) : non-numeric argument to mathematical function<br></div><div><br></div><div>If its not too much to ask, could you give an explicit example in which that happens (memory leak)? Just trying to learn here!</div><div><br></div><div>Thanks,</div><div><br></div></div><div class="gmail_extra"><br clear="all"><div><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>George G. Vega Yon<br>+1 (626) 381 8171<br><a href="http://www.its.caltech.edu/~gvegayon/" target="_blank">http://www.its.caltech.edu/~gvegayon/</a></div></div></div></div>
<br><div class="gmail_quote">On Wed, Aug 3, 2016 at 11:29 AM, Kevin Ushey <span dir="ltr"><<a href="mailto:kevinushey@gmail.com" target="_blank">kevinushey@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Also note that you definitely don't want to call `Rf_error` from a C++<br>
context in general, as it will bypass any active C++ try-catch blocks,<br>
bypass destructors, and so on. You should call `Rcpp::stop` explicitly<br>
and use Rcpp attributes to ensure the try-catch block is automagically<br>
set up for you.<br>
<div class="HOEnZb"><div class="h5"><br>
On Wed, Aug 3, 2016 at 11:28 AM, Kevin Ushey <<a href="mailto:kevinushey@gmail.com">kevinushey@gmail.com</a>> wrote:<br>
> The problem with your implementation is what happens if R throws an<br>
> error. The R longjmp will cause any C++ objects on the stack to leak,<br>
> their destructors not to run, and you'll essentially be in a bad place<br>
> if you evaluate any R code that might return an error. (For example,<br>
> suppose you had a file handle open, and then evaluated your R function<br>
> using 'eval', but an R error was produced. That file handle would<br>
> 'leak' and you wouldn't be able to recover it)<br>
><br>
> You can instead use the `Rf_tryEval` or `Rf_tryEvalSilent` routines,<br>
> but those don't respect active handlers (e.g. warning, message<br>
> handlers) and so aren't sufficient for general use.<br>
><br>
> Rcpp basically handles this by enclosing any expression to be<br>
> evaluated in an R 'tryCatch' call, with error + interrupt handlers<br>
> attached. This is, of course, slower since a lot more R code is being<br>
> evaluated, but right now it's the only way to safely execute an R<br>
> function in a C++ context while respecting all other active handlers.<br>
><br>
> In short, the Rcpp::Function implementation is designed to be as safe<br>
> + correct as possible, with the downside being that it's slower.<br>
> However, we generally advise that you shouldn't call back to R too<br>
> frequently from a C++ context, so that overhead should in most cases<br>
> be not too bad.<br>
><br>
> Best,<br>
> Kevin<br>
><br>
> On Wed, Aug 3, 2016 at 10:50 AM, George Vega Yon <<a href="mailto:g.vegayon@gmail.com">g.vegayon@gmail.com</a>> wrote:<br>
>> Hey there,<br>
>><br>
>> Looking at some old R code that I have I found this C++ function that allows<br>
>> evaluating R-written functions within C++ using Rcpp. While this is no news,<br>
>> the neat thing of it is that it seems to be faster than Rcpp::Function.<br>
>> Using microbenchmark I compared using Rcpp::function vs my implementation vs<br>
>> calling the function from R itself and this is what I got<br>
>><br>
>> Unit: relative<br>
>>                 expr min  lq     mean median  uq max neval<br>
>>   cppFuncall(x, fun) 1.3 1.3 1.39    1.3 1.4  83 10000<br>
>>  RcppFuncall(x, fun) 7.2 7.1 7.13    6.9 6.8  89 10000<br>
>>               fun(x) 1.0 1.0 1.00    1.0 1.0   1 10000<br>
>><br>
>> So, on average, while Rcpp::Function took ~7 times the R call took, my<br>
>> implementation took ~1.3 times. To be sure I was not breaking anything I ran<br>
>> the example using valgrind and there is no memory leak. The source code for<br>
>> the test follows:<br>
>><br>
>> -------- example_calling_r_functions.cpp ----<br>
>><br>
>> #include <Rinternals.h><br>
>> #include <Rcpp.h><br>
>><br>
>> // [[Rcpp::export]]<br>
>> SEXP cppFuncall(SEXP par, SEXP fn)<br>
>> {<br>
>>   SEXP R_fcall, ans;<br>
>><br>
>>   if(!isFunction(fn)) error("'fn' must be a function");<br>
>>   R_fcall = PROTECT(lang2(fn, R_NilValue));<br>
>><br>
>>   SETCADR(R_fcall, par);<br>
>>   ans=eval(R_fcall, R_GlobalEnv);<br>
>>   UNPROTECT(1);<br>
>>   return ans;<br>
>> }<br>
>><br>
>> using namespace Rcpp;<br>
>><br>
>> // [[Rcpp::export]]<br>
>> SEXP RcppFuncall(NumericVector par, Function fn)<br>
>> {<br>
>>   return fn(par);<br>
>> }<br>
>><br>
>><br>
>><br>
>> /*** R<br>
>> # R function to be called<br>
>> fun <- function(x) {<br>
>>   -cos(x[1])*cos(x[2])*exp(-((x[1] - pi)^2 + (x[2] - pi)^2))<br>
>> }<br>
>><br>
>> # Input data<br>
>> set.seed(3331)<br>
>> x <- runif(1e3)<br>
>><br>
>> # Benchmarking<br>
>> library(microbenchmark)<br>
>> microbenchmark(<br>
>>   cppFuncall(x, fun), RcppFuncall(x,fun), fun(x), times=1e4,<br>
>>   unit="relative", control = list(warmup=100)<br>
>> )<br>
>> */<br>
>><br>
>> -------- example_calling_r_functions.cpp ----<br>
>><br>
>> I've asked around about how to make things faster for function calls in Rcpp<br>
>> but, from what I've been told it is difficult since the implementation of<br>
>> Rcpp::Function actually has to go back to R to work (or something like that<br>
>> :P). Now, this implementation, -cppFuncall-, has no problem when it comes to<br>
>> passing wrong arguments, e.g. if you pass a character vector to it R will<br>
>> complain but there won't be any system crash. One big difference is that<br>
>> here I'm relying on passing all the function's arguments in a single object<br>
>> while Rcpp::Function does not. Either way, if this is OK this could be a<br>
>> nice extra feature for Rcpp, I'm thinking of optimization routines (or other<br>
>> kinds of algorithms) that rely on calling R functions multiple times.<br>
>><br>
>> The thing is that I'm still learning C++  and  I'm not Rinternals expert at<br>
>> all! So I would love to get some feedback from you guys. Does this function,<br>
>> -cppFuncall-, looks OK? in other words, am I doing/getting something wrong<br>
>> here?<br>
>><br>
>> Thanks,<br>
>><br>
>> George G. Vega Yon<br>
>> +1 (626) 381 8171<br>
>> <a href="http://www.its.caltech.edu/~gvegayon/" rel="noreferrer" target="_blank">http://www.its.caltech.edu/~gvegayon/</a><br>
>><br>
>> _______________________________________________<br>
>> Rcpp-devel mailing list<br>
>> <a href="mailto:Rcpp-devel@lists.r-forge.r-project.org">Rcpp-devel@lists.r-forge.r-project.org</a><br>
>> <a href="https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel" rel="noreferrer" target="_blank">https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel</a><br>
</div></div></blockquote></div><br></div>