[Rcpp-devel] Passing an exposed function to another C++ function as a parameter
Dirk Eddelbuettel
edd at debian.org
Wed Aug 3 13:55:39 CEST 2011
Hi Manuel,
On 3 August 2011 at 08:22, Manuel Castejón Limas wrote:
|
| Dear all,
|
| I'm rewriting the AMORE package using Rcpp --- in fact it's more like I'm
| having a lot of fun while rewriting the AMORE package thanks to Rcpp.
| Nevertheless, I'm facing this little problem that I hope it would be pretty
| easy for you to solve.
|
|
| Let's consider the C++ function Tanh_f0
|
| double
|
| Tanh_f0(double inducedLocalField)
|
| {
|
| return tanh(inducedLocalField);
|
| }
|
|
| After compilation using inline, Tanh_f0 is exposed to R using Module and
| accessible through actMod$Tanh_f0
|
|
| actMod$Tanh_f0(0.1)
|
| # [1] 0.09966799
|
|
| Now, I want to pass actMod$Tanh_f0 as a parameter of a function in order
| to use the original C++ function Tanh_f0.
|
|
|
| testCode <- ' Rcpp::Function fx (myfun);
|
| double result = as<double>(fx(x));
|
| return wrap( result );
|
| '
|
| usingTanhf0 <- cfunction(sig=signature(myfun="function", x="numeric"), body
| =testCode,…)
|
|
| And that indeed works, but when compared to using a simple tanh function it
| shows quite a bad performance.
|
|
|
| testCode <- ' double value = as<double>(x);
|
| double result = tanh(value);
|
| return wrap( result );
|
| '
|
|
| usingTanh <- cfunction(sig=signature(x="numeric"), body=testCode, … )
|
| benchmark(usingTanhf0(myfun=actMod$Tanh_f0, x=0.1) , usingTanh( x=0.1),
| columns=c("test", "replications", "elapsed", "relative"), order="relative",
| replications=1000)
|
| # test
| replications elapsed relative
|
| # 2 usingTanh(x = 0.1)
| 1000 0.004 1
|
| # 1 usingTanhf0(myfun = actMod$Tanh_f0, x = 0.1) 1000 0.080
| 20
( I have a hard time with the formatting of your email. That table was
essentially unreadable. I even looked at Gmane's rendering at
http://article.gmane.org/gmane.comp.lang.r.rcpp/2301 which is also
broken. Can you work on your email setup? )
Profiling is a good idea. What we see here is that the ease of use comes at
some overhead for the wrapping and unwrapping it implies. Such is life --
Modules has some cost.
We do of course try to eliminate any obvious source of underperformance so
there is always scope for profiling and debugging. Help is always appreciated.
| Looks like having to go the R way to get access to Tanh_f0 has a high cost.
| In order to be faster, it would be great if I could have access to the
| original Tanh_f0 which I guess is pointed to by actMod$Tanh_f0, may be at
| the address 0x100153d30 ?
Why don't you just access double tanh(double) itself? If Tanh_f0 a
mockup for the real function you want to use this way?
| actMod$Tanh_f0
|
| # internal C++ function <0x100153d30>
|
| # signature : double Tanh_f0(double)
|
|
| After having had a look at RppDE sources, I guess the solution would be to
| pass the function as an external pointer; something like :
|
|
| testCode <- '
|
| typedef double (*funPtr)(double) ;
|
| Rcpp::XPtr< funPtr > fx (myfun);
|
| double result = (*fx)(0.1);
|
| return wrap( result );
|
| '
|
| testCodefun <- cfunction(sig=signature(myfun="C++Function"), body=
| testCode,…)
|
| result <- testCodefun(myfun=actMod$Tanh_f0)
|
|
| But this does NOT work and crashes R.
|
| Any hints?
No sorry, I don't have time to look through this now but XPtr per se is well
tested and reliable. It is meant to be used with external objects -- not
necessarily function pointers.
| Thank you for your patience in reading such long message!
Pleasure, and sorry I have no immediate fix for you.
Dirk
| Manuel
|
|
|
|
|
|
| ----------------------------------------------------------------------
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
--
Gauss once played himself in a zero-sum game and won $50.
-- #11 at http://www.gaussfacts.com
More information about the Rcpp-devel
mailing list