RCPP - Seamless R and C++ Integration - Matt P. Dziubinski - CppCon 2015
RCPP - Seamless R and C++ Integration - Matt P. Dziubinski - CppCon 2015
Matt P. Dziubinski
CppCon 2015
[email protected] // @matt_dz
Department of Mathematical Sciences, Aalborg University
CREATES (Center for Research in Econometric Analysis of Time Series)
Outline
Setup
Data Structures
Resources
2
Intro
3
Intro
4
Intro
5
Intro
6
Intro
7
Intro
8
Intro
9
Intro
10
Intro
11
Intro
12
Intro
13
Intro
14
Intro
15
Intro
16
Intro: Speedup
17
Intro: Takeaways
• http://c2.com/cgi/wiki?AlternateHardAndSoftLayers
• http://c2.com/cgi/wiki?ForeignFunctionInterface
18
Intro: The Times They Are a-Changin'
19
Intro: The Times They Are a-Changin'?
20
R
R
https://www.r-project.org/
22
What is R?
https://www.r-project.org/about.html
23
CRAN: The Comprehensive R Archive Network
• https://cran.r-project.org/web/packages/
• https://cran.r-project.org/web/views/
24
CRAN Task Views
25
CRAN: Machine Learning
• https://cran.r-project.org/web/views/MachineLearning.html
• https://cran.r-project.org/web/packages/caret/
• https://topepo.github.io/caret/modelList.html
• https://topepo.github.io/caret/bytag.html
• https://topepo.github.io/caret/training.html
• https://cran.r-project.org/web/packages/elasticnet/
• https://cran.r-project.org/web/packages/glmnet/
• Authors: Jerome Friedman, Trevor Hastie, Noah Simon, Rob Tibshirani
• https://cran.r-
project.org/web/packages/glmnet/vignettes/glmnet_beta.html
26
Introduction to Statistical Learning (ISL)
http://www.statlearning.com/
27
Elements of Statistical Learning (ESL)
http://www-stat.stanford.edu/ElemStatLearn
28
ggplot2
http://docs.ggplot2.org/current/
http://docs.ggplot2.org/current/aes_group_order.html
https://stat.ethz.ch/R-manual/R-
devel/library/datasets/html/mtcars.html 29
RStudio
https://www.rstudio.com/
https://github.com/rstudio/rstudio/
30
RStudio IDE
https://www.rstudio.com/products/RStudio/
31
R & RStudio IDE: Demo
install.packages("ggplot2")
library("ggplot2")
https://ateucher.github.io/rcourse_site/03-plotting.html
http://www.ats.ucla.edu/stat/r/faq/packages.htm
32
R & RStudio IDE: Demo - Package Not Installed
33
R & RStudio IDE: Demo - Installing Package
34
R & RStudio IDE: Demo - Loading/Attaching & Using Package
35
RStudio - Shiny
http://shiny.rstudio.com/
36
R Markdown
http://rmarkdown.rstudio.com/
37
R Markdown - PDF
http://rmarkdown.rstudio.com/
38
R Markdown - Slides
http://rmarkdown.rstudio.com/
39
Pandoc
http://pandoc.org/
40
R - Books
https://www.r-project.org/doc/bib/R-books.html
41
Rcpp Book
http://rcpp.org/book/
42
R - loops vs. vectorized code
43
R - loops & byte code compiler vs. vectorized code
45
C++ - loops, x86
https://gcc.godbolt.org/ https://goo.gl/DAKTUA
https://github.com/mattgodbolt/gcc-explorer
46
C++ - loops, Rcpp, x86
47
C++ - loops, Rcpp, RStudio
48
R - loops, random Normal numbers
49
R - loops, random Normal numbers
50
C++ - loops, Rcpp, OpenMP - result
51
C++ - loops, Rcpp, OpenMP - code
52
Utilizing the other 80%...
http://applicative.acm.org/speaker-UlrichDrepper.html
53
Utilizing the other 80%... - parallelism
54
Utilizing the other 80%... - vectorization
55
Utilizing the other 80%... - vector registers
56
Rcpp: R & C++
Rcpp History
http://dirk.eddelbuettel.com/code/rcpp.html
58
Rcpp Timeline
https://twitter.com/eddelbuettel/status/
613235012939464704
59
Rcpp September 2015
http://dirk.eddelbuettel.com/blog/2015/09/10/
#rcpp_0.12.1
60
C++ Timeline
https://isocpp.org/std/status
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v(5);
int element = 0;
for (std::vector<int>::size_type i = 0; i < v.size(); ++i)
v[i] = element++;
int sum = 0;
for (std::vector<int>::size_type i = 0; i < v.size(); ++i)
sum += v[i];
std::cout << "sum = " << sum;
}
#include <iostream>
#include <vector>
int main()
{
const std::vector<int> v {0, 1, 2, 3, 4};
auto sum = 0;
for (auto element : v) sum += element;
std::cout << "sum = " << sum;
}
63
Before Rcpp
#include <R.h>
#include <Rinternals.h>
SEXP fibonacci_c(SEXP n)
{
SEXP result = PROTECT(allocVector(INTSXP, 1));
INTEGER(result)[0] = fibonacci_c_impl(asInteger(n));
UNPROTECT(1);
return result;
}
64
With Rcpp
65
Setup
Simple Example #0
67
Simple Example #0
68
Simple Example #0
69
Simple Example #1
70
Simple Example #2
71
Simple Example #3
72
Simple Example #4
73
Linux Setup Example #0
74
Linux Setup Example #1
75
Linux Setup Example #2
76
Linux Setup Example #3
77
Linux Setup Example #4
78
Setup - OSes and Compilers
• R language — C API
• Writing R Extensions:
https://cran.r-project.org/doc/manuals/r-release/R-exts.html
• Rcpp — C++ API — ABI implications
• https://isocpp.org/wiki/faq/compiler-dependencies#binary-
compat
• Most platforms: GNU Compiler Collection
• Windows: Rtools, https://cran.r-project.org/bin/windows/Rtools/
• R-SIG-windows, https://stat.ethz.ch/mailman/listinfo/r-sig-windows
• Frequently Asked Questions about Rcpp - What compiler can I use?
http://dirk.eddelbuettel.com/code/rcpp/Rcpp-FAQ.pdf
• https://cran.r-project.org/doc/manuals/R-admin.html#Platform-
notes
79
R language — C API — SEXP
https://cran.r-project.org/doc/manuals/r-release/R-
exts.html#Calling-_002eCall
80
R language — C API — SEXPREC
https://cran.r-project.org/doc/manuals/r-release/R-
exts.html#Garbage-Collection
http://adv-r.had.co.nz/C-interface.html
81
Compilation, inline — example — Rcpp::as & Rcpp::wrap
fibonacci_impl = '
int fibonacci(int n)
{
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
'
fibonacci_body = '
int n = Rcpp::as<int>(in_n);
return Rcpp::wrap(fibonacci(n));
'
# install.packages("inline")
fibonacci_function = inline::cxxfunction(signature(in_n = "integer"),
body = fibonacci_body,
inc = fibonacci_impl,
plugin = "Rcpp")
fibonacci_function(10) # returns 55
82
Compilation, inline — verbose output I
1 :
2 : // includes from the plugin
3 :
4 : #include <Rcpp.h>
5 :
6 :
7 : #ifndef BEGIN_RCPP
8 : #define BEGIN_RCPP
9 : #endif
10 :
11 : #ifndef END_RCPP
12 : #define END_RCPP
13 : #endif
14 :
83
Compilation, inline — verbose output II
84
Compilation, inline — verbose output III
85
Compilation, Rcpp cppFunction — example
fibonacci_source = '
int fibonacci(int n)
{
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}'
fibonacci_cpp(10) # returns 55
86
Compilation, Rcpp cppFunction — verbose output I
#include <Rcpp.h>
// [[Rcpp::export]]
int fibonacci(int n)
{
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
87
Compilation, Rcpp cppFunction — verbose output II
--------------------------------------------------------
#include <Rcpp.h>
// fibonacci
int fibonacci(int n);
RcppExport SEXP sourceCpp_2_fibonacci(SEXP nSEXP) {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
Rcpp::traits::input_parameter< int >::type n(nSEXP);
__result = Rcpp::wrap(fibonacci(n));
return __result;
END_RCPP
}
Generated R functions
-------------------------------------------------------
88
Compilation, Rcpp cppFunction — verbose output III
rm(`.sourceCpp_2_DLLInfo`)
DIR: ...
89
Compilation, Rcpp Attributes — example
// fibonacci_example.cpp
// [[Rcpp::export]]
int fibonacci(int n)
{
if (n < 2) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
/*** R
fibonacci(10)
*/
Rcpp::sourceCpp('fibonacci_example.cpp') # returns 55
90
Compilation, Rcpp cppFunction — verbose output I
#include <Rcpp.h>
// fibonacci
int fibonacci(int n);
RcppExport SEXP sourceCpp_4_fibonacci(SEXP nSEXP) {
BEGIN_RCPP
Rcpp::RObject __result;
Rcpp::RNGScope __rngScope;
Rcpp::traits::input_parameter< int >::type n(nSEXP);
__result = Rcpp::wrap(fibonacci(n));
91
Compilation, Rcpp cppFunction — verbose output II
return __result;
END_RCPP
}
Generated R functions
-------------------------------------------------------
rm(`.sourceCpp_4_DLLInfo`)
DIR: .../sourcecpp_ce857c352c1
92
Compilation, Rcpp cppFunction — verbose output III
> fibonacci(10)
[1] 55
93
Exception Handling
::Rf_error
throw std::range_error
http://gallery.rcpp.org/articles/intro-to-exceptions/
94
Data Structures
RObject
• RObject
• NumericVector
• IntegerVector
96
IntegerVector
#include <algorithm>
#include <Rcpp.h>
// [[Rcpp::export]]
int accumulate(Rcpp::IntegerVector v)
{
return std::accumulate(v.begin(), v.end(), 0);
}
/*** R
accumulate(1:5) # returns 15
*/
97
IntegerVector - Lightweight Proxy Object
Not call-by-value
https://en.wikipedia.org/wiki/Evaluation_strategy
#include <Rcpp.h>
// [[Rcpp::export]]
void tweak(Rcpp::IntegerVector v)
{
if (v.size() > 0) v[0] = 42;
}
/*** R
v = 1:5 # 1 2 3 4 5
stopifnot(v == 1:5)
tweak(v) # 42 2 3 4 5
stopifnot(v == c(42, 2:5))
*/
98
NumericVector, reference semantics
99
NumericVector, deep copy: Rcpp::clone
100
Other Homogeneous Data Structures
• Rcpp::NumericMatrix
• Rcpp::LogicalVector
• Rcpp::CharacterVector
• Rcpp::RawVector
101
Other Data Structures
• List / GenericVector
• Dynamically Heterogeneous
• DataFrame
• Function, Environment
• Rcpp::Named
102
Rcpp::Named
103
Rcpp::List
104
Rcpp::Function
105
R Math Library
• Rmath.h
• PRNGs, Statistical Distributions
• http://gallery.rcpp.org/articles/using-rmath-functions/
• http://gallery.rcpp.org/articles/random-number-generation/
• http://dirk.eddelbuettel.com/blog/2012/11/14/
106
Packaging
• https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-
package.pdf
• Rcpp.package.skeleton
• Makevars
• Makevars.win
107
Extending
• http://dirk.eddelbuettel.com/code/rcpp/Rcpp-extending.pdf
• http://gallery.rcpp.org/articles/custom-as-and-wrap-example/
108
Extending - Rcpp::wrap - from C++ to R
// [[Rcpp::plugins(cpp11)]]
#include <RcppCommon.h>
// [[Rcpp::export]]
point wrapped(double x, double y)
{
return point{x, y};
}
#include <Rcpp.h>
109
Extending - Rcpp::wrap - from C++ to R
namespace Rcpp
{
template <> SEXP wrap(const point & p)
{
return Rcpp::NumericVector::create(
Rcpp::Named("x") = p.x,
Rcpp::Named("y") = p.y);
}
}
/*** R
wrapped(1., 2.)
*/
110
Extending - Rcpp::wrap - from C++ to R
111
Extending - Rcpp::as - from R to C++
// [[Rcpp::plugins(cpp11)]]
#include <RcppCommon.h>
// [[Rcpp::export]]
double squared_norm(point p)
{
return p.x * p.x + p.y * p.y;
}
#include <Rcpp.h>
112
Extending - Rcpp::as - from R to C++
namespace Rcpp
{
template <> point as(SEXP coords_in)
{
Rcpp::NumericVector coords(coords_in);
auto x = coords[0];
auto y = coords[1];
return point{x, y};
}
}
/*** R
squared_norm(c(1., 2.))
*/
113
Extending - Rcpp::as - from R to C++
114
Exposing Classes, Modules
• Rcpp::Xptr
• http://www.r-bloggers.com/external-pointers-with-rcpp/
• http://gallery.rcpp.org/articles/passing-cpp-function-pointers/
• RCPP_MODULE
• inspiration: Boost.Python, http://boost.org/libs/python
• in particular: BOOST_PYTHON_MODULE,
http://www.boost.org/doc/libs/release/libs/python/doc/tutorial/doc/h
• http://dirk.eddelbuettel.com/code/rcpp/Rcpp-modules.pdf
RCPP_MODULE(point_module) {
Rcpp::class_<point>("point")
.field( "x", &point::x )
.field( "y", &point::y )
;
}
115
Rcpp & Python
http://gallery.rcpp.org/articles/rcpp-python/
116
Sugar
• Syntactic Sugar
• http://dirk.eddelbuettel.com/code/rcpp/Rcpp-sugar.pdf
117
Sugar Example
118
Sugar
119
RInside
120
RInside
121
RInside
122
More
• https://cran.r-project.org/web/packages/BH/
• http://dirk.eddelbuettel.com/code/bh.html
• https://github.com/eddelbuettel/bh
• http://gallery.rcpp.org/articles/using-boost-with-bh/
RcppArmadillo: Rcpp Integration for the Armadillo Linear Algebra
Library
• http://dirk.eddelbuettel.com/code/rcpp.armadillo.html
• https://github.com/RcppCore/RcppArmadillo
123
More
• https://cran.r-project.org/web/packages/RcppEigen/
• https://github.com/RcppCore/RcppEigen
RcppGSL
• http://dirk.eddelbuettel.com/code/rcpp.gsl.html
• https://github.com/eddelbuettel/rcppgsl
124
More
RcppParallel
• https://github.com/RcppCore/RcppParallel
• https://cran.r-project.org/web/packages/RcppParallel/
• http://rcppcore.github.io/RcppParallel/
• http://gallery.rcpp.org/articles/parallel-vector-sum/
CRAN Users
• http://dirk.eddelbuettel.com/code/rcpp.cranusers.html
125
RcppEigen
• Eigen::Map
• http://eigen.tuxfamily.org/dox/group__TutorialMapClass.html
• http://eigen.tuxfamily.org/dox/classEigen_1_1Map.html
126
RcppEigen Example - Not Available
127
RcppEigen Example - Setup
128
RcppEigen Example - Use
129
Resources
Resources: Where to learn more
• https://cran.r-project.org/web/packages/Rcpp/vignettes/
• http://dirk.eddelbuettel.com/code/rcpp/Rcpp-quickref.pdf
• http://gallery.rcpp.org/
• http://www.rcpp.org/book/
• http://dirk.eddelbuettel.com/presentations/
• http://adv-r.had.co.nz/Rcpp.html
• https://cran.r-project.org/doc/manuals/r-release/R-exts.html
131
Resources: Help
• https://cran.r-project.org/web/packages/Rcpp/vignettes/
• http://news.gmane.org/gmane.comp.lang.r.rcpp
• http://stackoverflow.com/tags/rcpp/
132
Resources: Libraries
• http://dirk.eddelbuettel.com/code/
• http://gallery.rcpp.org/articles/using-boost-with-bh/
• http://dirk.eddelbuettel.com/code/rquantlib.html
• https://rcppcore.github.io/RcppParallel/
• http://bit.ly/1Ltycxk
133
Resources: How to stay up to date
News
• http://www.r-bloggers.com/
• http://dirk.eddelbuettel.com/blog/
• https://github.com/RcppCore/Rcpp
134
Resources: How to stay up to date
Conferences
• https://www.r-project.org/conferences.html
• http://www.rinfinance.com/
• http://www.earl-conference.com/
135
Resources: Slides
https://speakerdeck.com/mattpd
136
Thank You!
Questions?
137