There are two things going on here: (1) I am just learning how to use Rcpp and friends to make my R code faster and (2) I have never built an R package before.
I've got the use of inline
down. Great package. Love it. However, I can't seem to use any code developed with inline
with package.skeleton
to make an R package.
Here is a minimal example:
#############################
# File : build-R-pacakge.R #
#############################
require(inline)
require(Rcpp)
require(RcppArmadillo)
# Define a simple cxxfunction
plus.two.cpp.src <- '
arma::mat U = Rcpp::as<arma::mat>(UmatrixR);
return(Rcpp::wrap(U+2));
'
plus.two.cpp <- cxxfunction(
signature(UmatrixR="numeric"),
body=plus.two.cpp.src,
plugin="RcppArmadillo")
# Define the analogous R function
plus.two.r <- function( x ) {
return( x + 2 )
}
In new R session run:
source('build-R-package.R')
RcppArmadillo.package.skeleton(name='inlineExample',
list=c('plus.two.cpp', 'plus.two.r'),
code_files='build-R-package.R')
Then delete the man/*.Rd
files since R doesn't put in defaults that 'just work'.
$ rm inlineExample/man/*.Rd
And run:
$ R CMD build inlineExample/
<< snip >>
$ R CMD check inlineExample_1.0.tar.gz
<< snip >>
$ R CMD INSTALL inlineExample_1.0.tar.gz
<< snip >>
Which all complete successfully, except for some complaining about the missing documentation.
And then try it out in a new R session:
> require(inlineExample)
Loading required package: inlineExample
Loading required package: Rcpp
Loading required package: RcppArmadillo
Loading required package: inline
>
> plus.two.cpp( matrix(1:12, ncol=3))
Error in .Primitive(".Call")(<pointer: (nil)>, UmatrixR) :
NULL value passed as symbol address
>
> plus.two.cpp
An object of class "CFunc"
function (UmatrixR)
.Primitive(".Call")(<pointer: (nil)>, UmatrixR)
<environment: 0x2f28370>
Slot "code":
[1] "\n// includes from the plugin\n#include <RcppArmadillo.h>\n#include <Rcpp.h>\n\n\n#ifndef BEGIN_RCPP\n#define BEGIN_RCPP\n#endif\n\n#ifndef END_RCPP\n#define END_RCPP\n#endif\n\nusing namespace Rcpp;\n\n\n// user includes\n\n\n// declarations\nextern \"C\" {\nSEXP file2f8c4cc10657( SEXP UmatrixR) ;\n}\n\n// definition\n\nSEXP file2f8c4cc10657( SEXP UmatrixR ){\nBEGIN_RCPP\n\n arma::mat U = Rcpp::as<arma::mat>(UmatrixR);\n return(Rcpp::wrap(U+2));\n\nEND_RCPP\n}\n\n\n"
It fails. To my untrained eyes it seems that:
inline
compiled never got copied by *.package.skeleton to the "right" part of the directory skeleton for later compilation by the R build process, and Thinking about this further, it seems like (2) would be a really bad idea because it would force the user to compile the code every time they loaded their package. That would both exclude all users who require binary only packages and just simply be really inefficient.
And (1) seems technically possible, but as discussed on the Rcpp mailing list, it is not worth implementing a set of auto-magic converter functions.
So, the question:
Can someone please give a walk-through of the correct way to take the provided example code and turn it into an R package?
There is just a bit too much newness for me to make sense of the existing documentation. FWIW, I'm sure it would be helpful for people in the future!
Step 1: Write a dummy package without Rcpp, just to get a feel for how things work.
Step 2: Read Dirk's explanation of how to make a package that uses Rcpp.
From what I've read inline
seems to make Rcpp in packages harder not easier.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With