[Rcpp-devel] Passing an exposed function to another C++ function as a parameter

Manuel Castejón Limas manuel.castejon at gmail.com
Wed Aug 3 18:59:46 CEST 2011


Great! I'm eager to see the example. Thank you very much indeed!

I'm sorry about the formatting of the table, I'm used to write on a very
wide setting so it looked ok on my computer. I'll be more careful the next
time.

Though I did not mention it in the first message, the problem posed has
paramount importance for the new version of the AMORE package and may be
for many others to come.

The thing is that, in the case of AMORE ---a neural network simulator---,
the user of the package is provided the capability to write their own
neuron activation functions and training cost functions. In the stable
version on CRAN this is done by letting the user write those functions in
R language at the cost of a lower performance. Those users that are ok
with the functions provided in the package enjoy the benefits of compiled
code; those writing their own functions have to cope with a lower speed
unless they want to sink into the code of the package, but those are the
less I guess.

Now, thanks to Rcpp, a see a new possibility which is to let the user
write their own functions in C++ and use them along the provided ones in
the package following the scheme I was trying to get to work, and all that
without having to compromise performance.

The point is that the Tanh_f0 function, shown as an example, or many
others will be written by the user if need be, while the rest of the code
involved in training the network will be provided by the package.

There's beauty indeed in being able to merge those two worlds.

Similarly, the same thing might be done with classes. A package could then
provide a framework and the users could extend the existing classes
customizing the behavior of the package with the ease of using inline. Now
I'm thinking about training algorithms in the case of AMORE.

But that's another story. For now, I'm dreaming on the example that Romain
is cooking.

PS: Did I mention you guys did a great job with Rcpp! I love it. It's a
revolutionary package in the R arena, IMHO.



El 03/08/11 15:29, "Dirk Eddelbuettel" <edd at debian.org> escribió:

>
>On 3 August 2011 at 14:42, Romain Francois wrote:
>| Hi,
>| 
>| This looks very similar to a problem Dirk faced in rewriting the
>DEOptim 
>| package to use Rcpp (the RcppDE package is on the Rcpp svn repo).
>
>(and on CRAN)
> 
>| Essentially the problem is that the Rcpp::Function is a C++ object that
>| calls back to R, with additional protection, which eventually calls C++.
>| 
>| You should be able to bypass this entirely and access directly the
>| pointer to the C++ function from the R variable. This way, you stay in
>| the C++ world. This would allow you to branch your code depending on
>| whether you loop over a pure R function or a C++ function.
>| 
>| I'll cook an example.
>
>Cool, thanks. Maybe add it to the Rcpp-FAQ vignette too?
>
>Dirk
>
>| 
>| Romain
>| 
>| Le 03/08/11 08:22, Manuel Castejón Limas a écrit :
>| >
>| >> 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
>| >>
>| >>
>| >> 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 ?
>| >>
>| >>
>| >> 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?
>| >>
>| >> Thank you for your patience in reading such long message!
>| >> 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
>| 
>| 
>| -- 
>| Romain Francois
>| Professional R Enthusiast
>| +33(0) 6 28 91 30 30
>| http://romainfrancois.blog.free.fr
>| http://romain-francois.com
>| |- http://bit.ly/lJoWbH : Montpellier Comédie Club - Juin 2011
>| |- http://bit.ly/kaSV6U : Stand up set at Up The Creek
>| `- http://bit.ly/hdKhCy : Rcpp article in JSS
>| 
>| 
>| _______________________________________________
>| 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