Frequently Asked Questions About RCPP: Dirk Eddelbuettel Romain François
Frequently Asked Questions About RCPP: Dirk Eddelbuettel Romain François
Abstract
This document attempts to answer the most Frequently Asked Questions (FAQ) regarding the Rcpp (Eddelbuettel, Franois,
Allaire, Ushey, Kou, Russel, Chambers, and Bates, 2017; Eddelbuettel and Franois, 2011; Eddelbuettel, 2013) package.
Contents
1 Getting started 2
1.1 How do I get started ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 What do I need ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 What compiler can I use ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.4 What other packages are useful ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.5 What licenses can I choose for my code? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1
3 Examples 9
3.1 Can I use templates with Rcpp ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.1 Using inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
3.1.2 Using Rcpp Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2 Can I do matrix algebra with Rcpp ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2.1 Using inline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.2.2 Using Rcpp Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.3 Can I use code from the Rmath header and library with Rcpp ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.4 Can I use NA and Inf with Rcpp ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.5 Can I easily multiply matrices ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.6 How do I write a plugin for inline and/or Rcpp Attributes? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.7 How can I pass one additional flag to the compiler? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.8 How can I set matrix row and column names ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.9 Why can long long types not be cast correctly? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.10 What LaTeX packages do I need to typeset the vignettes ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.11 Why is there a limit of 20 on some constructors? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.12 Can I use default function parameters with Rcpp? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.13 Can I use C++11, C++14, C++17, ... with Rcpp? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4 Support 17
4.1 Is the API documented ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.2 Does it really work ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.3 Where can I ask further questions ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.4 Where can I read old questions and answers ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.5 I like it. How can I help ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.6 I dont like it. How can I help ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.7 Can I have commercial support for Rcpp ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.8 I want to learn quickly. Do you provide training courses ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.9 Where is the code repository ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1 Getting started
1.1 How do I get started ?
If you have Rcpp installed, please execute the following command in R to access the introductory vignette (which is a
variant of the Eddelbuettel and Franois (2011) paper) for a detailed introduction, ideally followed by at least the Rcpp
Attributes (Allaire, Eddelbuettel, and Franois, 2015) vignette:
> vignette("Rcpp-introduction")
> vignette("Rcpp-attributes")
If you do not have Rcpp installed, these documents should also be available whereever you found this document, i.e.,
on every mirror of CRAN site.
2
Also see the RStudio documentation on pre-requisites for R package development.
3
2 Compiling and Linking
2.1 How do I use Rcpp in my package ?
Rcpp has been specifically designed to be used by other packages. Making a package that uses Rcpp depends on the same
mechanics that are involved in making any R package that use compiled code so reading the Writing R Extensions
manual (R Core Team, 2015b) is a required first step.
Further steps, specific to Rcpp, are described in a separate vignette.
> vignette("Rcpp-package")
4
The cppFunction parses the supplied text, extracts the desired function names, creates the required scaffolding,
compiles, links and loads the supplied code and makes it available under the selected identifier.
Similarly, sourceCpp can read in a file and compile, link and load the code therein.
This first installs the packages, and then uses the command-line tool Rscript (which ships with R) to load the package,
and execute the R expression following the -e switch. Such an expression can contain multiple statements separated by
semicolons. Rscript is available on all three core operating systems.
On Linux, one can also use r from the littler package by Horner and Eddelbuettel which is an alternative front end
to R designed for both #! (hashbang) scripting and command-line use. It has slightly faster start-up times than Rscript;
and both give a guaranteed clean slate as a new session is created.
The example then becomes
The -l option calls suppressMessages(library(mypkg)) before executing the R expression. Several packages can be
listed, separated by a comma.
More choice are provide by the devtools package, and by using RStudio. See the respective documentation for details.
which first defines and exports two relevant environment variables which R CMD SHLIB then relies on. On other operating
systems, appropriate settings may have to be used to define the environment variables.
This approach corresponds to the very earliest ways of building programs and can still be found in some deprecated
documents (as e.g. some of Dirks older Intro to HPC with R tutorial slides). It is still not recommended as there are tools
and automation mechanisms that can do the work for you.
Rcpp versions 0.11.0 or later can do with the definition of PKG_LIBS as a user-facing library is no longer needed (and
hence no longer shipped with the package). One still needs to set PKG_CXXFLAGS to tell R where the Rcpp headers files are
located.
5
Once R CMD SHLIB has created the dyanmically-loadable file (with extension .so on Linux, .dylib on OS X or .dll
on Windows), it can be loaded in an R session via dyn.load, and the function can be executed via .Call. Needless to say,
we strongly recommend using a package, or at least Rcpp Attributes as either approach takes care of a lot of these tedious
and error-prone manual steps.
$ xcode-select --install
6
4. After the installation is complete, type the following in Terminal to ensure the installation was successful:
$ gcc --version
After major system updates, e.g. going from version 10.11 to 10.12, you may need to accept the terms and licenses
associated the the Xcode command line tools prior to being allowed to compile again.
To do so, open the Terminal found in /Applications/Utilities/ and type:
$ git
Press spacebar to move down to the end of the file. There, you should see a prompt asking whether or not you accept
the terms via either "Yes" or "No". Enter "Yes" if you agree to the terms to have the command line tools reactivated.
#ifdef _OPENMP
#include <omp.h>
#endif
#ifdef _OPENMP
// multithreaded OpenMP version of code
#else
// single-threaded version of code
#endif
Doing so will enable the parallelization of the process on Linux and Windows. In the event that Apple enables OpenMP
later on, this code will also allow for parallelization to occur.
The reason for the lack of OpenMP support is because under OS X, you are not using the gcc compiler. Instead, all the
requests are being redirected to llvm. As of LLVM 3.7, the community initiative to enable OpenMP has been merged into
the official branch. Thus, there is hope in the next release of Xcode (around WWDC in June 2016) that OpenMP will work
on OS X.
7
2.11 Does Rcpp work on solaris/suncc ?
Yes, it generally does. But as we do not have access to such systems, some issues persist on the CRAN test systems.
curl -O http://r.research.att.com/libs/gfortran-4.8.2-darwin13.tar.bz2
sudo tar fvxz gfortran-4.8.2-darwin13.tar.bz2 -C /
8
For more information on this error, please see TheCoatlessProfessors Rcpp, RcppArmadillo and OS X Mavericks
"-lgfortran" and "-lquadmath" error.
This invocation explicitly asks and constructs the library link paths from the gfortrans reported search paths, and
produces a set of paths suitable to be passed to FLIBS. Rwill then search these paths when attempting to locate e.g
libgfortran when compiling RcppArmadillo or other FORTRAN-dependent code.
Also see FAQ 2.10 above, and the links provided in that answer. In the event the above solution does not satisfy all the
OS X build problems.
3 Examples
The following questions were asked on the Rcpp-devel mailing list, which is our preferred place to ask questions as it
guarantees exposure to a number of advanced Rcpp users. The StackOverflow tag for rcpp is an alternative; that site is also
easily searchable.
Several dozen fully documented examples are provided at the Rcpp Gallery which is also open for new contributions.
9
inc <- template <typename T>
class square : public std::unary_function<T,T> {
public:
T operator()( T t) const { return t*t ;}
};
src <-
double x = Rcpp::as<double>(xs);
int i = Rcpp::as<int>(is);
square<double> sqdbl;
square<int> sqint;
return Rcpp::DataFrame::create(Rcpp::Named("x", sqdbl(x)),
Rcpp::Named("i", sqint(i)));
fun <- cxxfunction(signature(xs="numeric", is="integer"),
body=src, include=inc, plugin="Rcpp")
fun(2.2, 3L)
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::DataFrame fun(double x, int i) {
square<double> sqdbl;
square<int> sqint;
return Rcpp::DataFrame::create(Rcpp::Named("x", sqdbl(x)),
Rcpp::Named("i", sqint(i)));
}
/*** R
fun(2.2, 3L)
*/
10
would be a major project (if done right) involving advanced techniques such as expression templates. We currently do not
plan to go in this direction, but we would welcome external help. Please send us a design document.
However, we have developed the RcppArmadillo package (Eddelbuettel, Franois, and Bates, 2016; Eddelbuettel and
Sanderson, 2014) that provides a bridge between Rcpp and Armadillo (Sanderson, 2010). Armadillo supports binary
operators on its types in a way that takes full advantage of expression templates to remove temporaries and allow chaining
of operations. That is a mouthful of words meaning that it makes the code go faster by using fiendishly clever ways available
via the so-called template meta programming, an advanced C++ technique. Also, the RcppEigen package (Bates and
Eddelbuettel, 2013) provides an alternative using the Eigen template library.
// return it to R
return Rcpp::wrap( result );
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
double fx(arma::colvec x, arma::mat Y, arma::colvec z) {
// calculate the result
double result = arma::as_scalar(arma::trans(x) * arma::inv(Y) * z);
return result;
}
/*** R
fx(1:4, diag(4), 1:4)
*/
11
Here, the additional Rcpp::depends(RcppArmadillo) ensures that code can be compiled against the RcppArmadillo
header, and that the correct libraries are linked to the function built from the supplied code example.
Note how we do not have to concern ourselves with conversion; R object automatically become (Rcpp)Armadillo objects
and we can focus on the single computing a (scalar) result.
3.3 Can I use code from the Rmath header and library with Rcpp ?
Can I call functions defined in the Rmath header file and the standalone math library for Ras for example the
random number generators?
Yes, of course. This math library exports a subset of R, but Rcpp has access to much more. Here is another simple example.
Note how we have to use and instance of the RNGScope class to set and re-set the random-number generator. This also
illustrates Rcpp sugar as we are using a vectorised call to rnorm. Moreover, because the RNG is reset, the two calls result in
the same random draws. If we wanted to control the draws, we could explicitly set the seed after the RNGScope object has
been instantiated.
> fx <- cxxfunction(signature(),
+ 'RNGScope();
return rnorm(5, 0, 100);',
+ plugin="Rcpp")
> set.seed(42)
> fx()
[1] 137.09584 -56.46982 36.31284 63.28626 40.42683
> fx()
[1] -10.612452 151.152200 -9.465904 201.842371 -6.271410
Newer versions of Rcpp also provide the actual Rmath function in the R namespace, i.e. as R::rnorm(m,s) to obtain a
scalar random variable distributed as N (m, s).
Using Rcpp Attributes, this can be as simple as
12
> src <- 'Rcpp::NumericVector v(4);
v[0] = R_NegInf; // -Inf
v[1] = NA_REAL; // NA
v[2] = R_PosInf; // Inf
v[3] = 42; // see the Hitchhiker Guide
return Rcpp::wrap(v);'
> fun <- cxxfunction(signature(), src, plugin="Rcpp")
> fun()
[1] -Inf NA Inf 42
Similarly, for Rcpp Attributes:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::NumericVector fun(void) {
Rcpp::NumericVector v(4);
v[0] = R_NegInf; // -Inf
v[1] = NA_REAL; // NA
v[2] = R_PosInf; // Inf
v[3] = 42; // see the Hitchhiker Guide
return v;
}
13
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::mat mult(arma::mat A, arma::mat B) {
return A*B;
}
/*** R
A <- matrix(1:9, 3, 3)
B <- matrix(9:1, 3, 3)
mult(A,B)
*/
which can be built, and run, from R via a simple sourceCpp calland will also run the small R example at the end.
14
> myplugin <- getPlugin("Rcpp")
> myplugin$env$PKG_CXXFLAGS <- "-std=c++11"
> f <- cxxfunction(signature(), settings=myplugin, body='
+ std::vector<double> x = { 1.0, 2.0, 3.0 }; // fails without -std=c++0x
+ return Rcpp::wrap(x);
+ ')
> f()
For Rcpp Attributes, the attributes Rcpp::plugin() can be used. Currently supported plugins are for C++11 as well as
for OpenMP.
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List fun(void) {
Rcpp::NumericMatrix x(2,2);
x.fill(42); // or more interesting values
Rcpp::List dimnms = // two vec. with static names
Rcpp::List::create(Rcpp::CharacterVector::create("cc", "dd"),
Rcpp::CharacterVector::create("ee", "ff"));
// and assign it
x.attr("dimnames") = dimnms;
return(x);
}
15
> BigInts <- cxxfunction(signature(),
+ 'std::vector<long> bigints;
bigints.push_back(12345678901234567LL);
bigints.push_back(12345678901234568LL);
Rprintf("Difference of %ld\\n", 12345678901234568LL - 12345678901234567LL);
return wrap(bigints);', plugin="Rcpp", includes="#include <vector>")
> retval<-BigInts()
> stopifnot(length(unique(retval)) == 2)
While the difference of one is evident at the C++ level, it is no longer present once cast to R. The 64-bit integer values
get cast to a floating point types with a 53-bit mantissa. We do not have a good suggestion or fix for casting 64-bit integer
values: 32-bit integer values fit into integer types, up to 53 bit precision fits into numeric and beyond that truly large
integers may have to converted (rather crudely) to text and re-parsed. Using a different representation as for example from
the GNU Multiple Precision Arithmetic Library may be an alternative.
16
To illustrate, please consider the following example that provides a short how to:
#include <Rcpp.h>
// [[Rcpp::export]]
void sample_defaults(NumericVector x = NumericVector::create(), // Size 0 vector
bool bias = true, // Set to true
std::string method = "rcpp rules!"){ // Default string
Rcpp::Rcout << "x size: " << x.size() << ", ";
Rcpp::Rcout << "bias value: " << bias << ", ";
Rcpp::Rcout << "method value: " << method << std::endl;
}
/*** R
sample_defaults() # all defaults
sample_defaults(1:5) # supply x values
sample_defaults(bias = FALSE,
method = "rstats") # supply bool and string
*/
Note: In cpp, the default bool values are true and false whereas in R the valid types are TRUE or FALSE.
4 Support
4.1 Is the API documented ?
You bet. We use doxygen to generate html, latex and man page documentation from the source. The html documentation is
available for browsing, as a very large pdf file, and all three formats are also available a zip-archives: html, latex, and man.
17
4.3 Where can I ask further questions ?
The Rcpp-devel mailing list hosted at R-forge is by far the best place. You may also want to look at the list archives to see if
your question has been asked before.
You can also use Stack Overflow via its rcpp tag.
References
J. J. Allaire, Dirk Eddelbuettel, and Romain Franois. Rcpp Attributes, 2015. URL http://CRAN.R-Project.org/package=
Rcpp. Vignette included in R package Rcpp.
Douglas Bates and Dirk Eddelbuettel. Fast and elegant numerical linear algebra using the RcppEigen package. Journal of
Statistical Software, 52(5):124, 2013. URL http://www.jstatsoft.org/v52/i05/.
Dirk Eddelbuettel. Seamless R and C++ Integration with Rcpp. Use R! Springer, New York, 2013. ISBN 978-1-4614-6867-7.
Dirk Eddelbuettel and Romain Franois. Rcpp: Seamless R and C++ integration. Journal of Statistical Software, 40(8):
118, 2011. URL http://www.jstatsoft.org/v40/i08/.
18
Dirk Eddelbuettel and Conrad Sanderson. RcppArmadillo: Accelerating R with high-performance C++ linear algebra.
Computational Statistics and Data Analysis, 71:10541063, March 2014. doi: 10.1016/j.csda.2013.02.005. URL
http://dx.doi.org/10.1016/j.csda.2013.02.005.
Dirk Eddelbuettel, Romain Franois, and Douglas Bates. RcppArmadillo: Rcpp integration for Armadillo templated linear
algebra library, 2016. URL http://CRAN.R-Project.org/package=RcppArmadillo. R package version 0.7.400.2.0.
Dirk Eddelbuettel, Romain Franois, JJ Allaire, Kevin Ushey, Qiang Kou, Nathan Russel, John Chambers, and Douglas Bates.
Rcpp: Seamless R and C++ Integration, 2017. URL http://CRAN.R-Project.org/package=Rcpp. R package version
0.12.10.
R Core Team. R Installation and Administration. R Foundation for Statistical Computing, Vienna, Austria, 2015a. URL
http://CRAN.R-Project.org/doc/manuals/R-admin.html.
R Core Team. Writing R extensions. R Foundation for Statistical Computing, Vienna, Austria, 2015b. URL http://CRAN.
R-Project.org/doc/manuals/R-exts.html.
Conrad Sanderson. Armadillo: An open source C++ algebra library for fast prototyping and computationally intensive
experiments. Technical report, NICTA, 2010. URL http://arma.sf.net.
Oleg Sklyar, Duncan Murdoch, Mike Smith, Dirk Eddelbuettel, and Romain Franois. inline: Inline C, C++, Fortran function
calls from R, 2015. URL http://CRAN.R-Project.org/package=inline. R package version 0.3.14.
19