Rcpp11 genentech

48
R / C++ Romain François [email protected] @romain_francois

description

R/C++ talk at Genentech, San Francisco. The talk was given at the end of my holidays in California, so the initial slides are not that relevant ...

Transcript of Rcpp11 genentech

Page 1: Rcpp11 genentech

R / C++

Romain François

[email protected]@romain_francois

Page 2: Rcpp11 genentech
Page 3: Rcpp11 genentech
Page 4: Rcpp11 genentech
Page 5: Rcpp11 genentech
Page 6: Rcpp11 genentech
Page 7: Rcpp11 genentech
Page 8: Rcpp11 genentech
Page 9: Rcpp11 genentech

• Use R since 2002

• Consultant

• Rcpp since 2010

• Rcpp11 since last september

• C++ for performance

• Occasional comedy

Page 10: Rcpp11 genentech
Page 11: Rcpp11 genentech
Page 12: Rcpp11 genentech
Page 13: Rcpp11 genentech

Agenda

• R and C++ • Rcpp11

Page 14: Rcpp11 genentech
Page 15: Rcpp11 genentech
Page 16: Rcpp11 genentech
Page 17: Rcpp11 genentech

Success of Rcpp

• Thin wrapper around R/C api

• Users focus on what!

• Rcpp handles how

Page 18: Rcpp11 genentech

Example 1: Shiny

Page 19: Rcpp11 genentech

Example 2: dplyr

hflights %>% group_by(Year, Month, DayofMonth) %>% select(Year:DayofMonth, ArrDelay, DepDelay) %>% summarise( arr = mean(ArrDelay, na.rm = TRUE), dep = mean(DepDelay, na.rm = TRUE) ) %>% filter(arr > 30 | dep > 30)

Page 20: Rcpp11 genentech

int add( int a, int b){ return a + b ; }

Page 21: Rcpp11 genentech
Page 22: Rcpp11 genentech

#include <Rcpp.h> !

// [[Rcpp::export]] int add( int a, int b){ return a + b ; }

Page 23: Rcpp11 genentech

sourceCpp#include <Rcpp.h> !// [[Rcpp::export]] int add( int a, int b){ return a + b ; }

> sourceCpp( "add.cpp" ) > add( 2L, 3L) [1] 5

Page 24: Rcpp11 genentech

R data -> Rcpp classes

• vectors: NumericVector, IntegerVector, …

• lists: List

• functions: Function

• environments: Environment

• …

Page 25: Rcpp11 genentech

Rcpp objects are proxies to R data structures

No additional memory

Page 26: Rcpp11 genentech

Example: NumericVector// [[Rcpp::export]] double sum( NumericVector x){ int n = x.size() ; !

double res = 0.0 ; for( int i=0; i<n; i++){ res += x[i] ; } !

return res ; }

Page 27: Rcpp11 genentech

Example : listsList res = List::create( _["a"] = 1, _["b"] = "foo" );

res.attr( "class" ) = "myclass" ; !int a = res["a"] ;res["b"] = 42 ;

Page 28: Rcpp11 genentech

Example: R function

Function rnorm( "rnorm" ) ; !

NumericVector x = rnorm( 10, _["mean"] = 30, _["sd"] = 100 );

Page 29: Rcpp11 genentech

Rcpp11

Page 30: Rcpp11 genentech

Rcpp11

• C++ = C++11

• Smaller code base (than Rcpp)

• Header only

Page 31: Rcpp11 genentech
Page 32: Rcpp11 genentech

#include <Rcpp.h> !// [[Rcpp::export]] int foo(){ return 2 ; }

Rcpp

Rcpp11

0 1 2 3

Less code -> faster compiles

Page 33: Rcpp11 genentech

!

Interface simplification

Page 34: Rcpp11 genentech

NumericVector constructorsVector() { Vector( const Vector& other){ Vector( SEXP x ) { !Vector( const GenericProxy<Proxy>& proxy ){ explicit Vector( const no_init& obj) { Vector( const int& size, const stored_type& u ) { Vector( const std::string& st ){ Vector( const char* st ) { Vector( const int& siz, stored_type (*gen)(void) ) { Vector( const int& size ) { Vector( const Dimension& dims) { Vector( const Dimension& dims, const U& u) { Vector( const VectorBase<RTYPE,NA,VEC>& other ) { Vector( const int& size, const U& u) { Vector( const sugar::SingleLogicalResult<NA,T>& obj ) { Vector( const int& siz, stored_type (*gen)(U1), const U1& u1) { Vector( const int& siz, stored_type (*gen)(U1,U2), const U1& u1, const U2& u2) { Vector( const int& siz, stored_type (*gen)(U1,U2,U3), const U1& u1, const U2& u2, const U3& u3) { Vector( InputIterator first, InputIterator last){ Vector( InputIterator first, InputIterator last, int n) { Vector( InputIterator first, InputIterator last, Func func) { Vector( InputIterator first, InputIterator last, Func func, int n){ Vector( std::initializer_list<init_type> list ) {

23 constructors in Rcpp

Page 35: Rcpp11 genentech

NumericVector constructors

11 constructors in Rcpp

Vector(){ Vector( const Vector& other){ Vector( Vector&& other){ !explicit Vector(int n) { explicit Vector(R_xlen_t n) { !Vector( R_xlen_t n, value_type x ) { Vector( std::initializer_list<value_type> list ){ Vector( std::initializer_list<traits::named_object<value_type>> list ){ !Vector( const SugarVectorExpression<eT, Expr>& other ) { Vector( const LazyVector<RT,Expr>& other ) { Vector( const GenericProxy<Proxy>& proxy ){

Page 36: Rcpp11 genentech

NumericVector constructorsVector( const int& siz, stored_type (*gen)(U1), const U1& u1) -> replicate

double fun( int power ){ return pow(2.0, power) ; } !// Rcpp NumericVector x(10, fun, 10.0) ;

// Rcpp11 NumericVector x = replicate(10, fun, 10.0) ;

Page 37: Rcpp11 genentech

NumericVector constructors

std::vector<double> v = /* ... */ ; !// Rcpp NumericVector x(v.begin(), v.end()) ;

// Rcpp11 NumericVector x = import(begin(v), end(v)) ; NumericVector x = import(v) ;

Vector( InputIterator first, InputIterator last) -> import

Page 38: Rcpp11 genentech

Some examples

Page 39: Rcpp11 genentech

NumericVector ctors

// C++ uniform initialization NumericVector x = {1.0, 2.0, 3.0} ; !// init with given size NumericVector y( 2 ) ; // data is not initialized NumericVector y( 2, 3.0 ) ; // initialize all to 3.0 !// fuse several vectors (similar to c in R) NumericVector z = fuse(x, y) ; NumericVector z = fuse(x, y, 3.0) ;

Page 40: Rcpp11 genentech

create// old school NumericVector::create (Rcpp style). NumericVector x = NumericVector::create(1.0, 2.0, 3.0) ; NumericVector x = NumericVector::create( _["a"] = 1.0, _["b"] = 2.0, _["c"] = 3.0 ) ; !!// create as a free function. Rcpp11 style NumericVector x = create(1.0, 2.0, 3.0) ; NumericVector x = create( _["a"] = 1.0, _["b"] = 2.0, _["c"] = 3.0 ) ;

Page 41: Rcpp11 genentech

sapply + lambda

Page 42: Rcpp11 genentech

sapply + lambda

#include <Rcpp11> !// [[export]] NumericVector foo( NumericVector x ){ return sapply(x, [](double d){ return exp(d * 2) ; }); }

x <- 1:3 sapply( x, function(d){ exp(d*2) ; })

Page 43: Rcpp11 genentech

sapply + lambda + …

#include <Rcpp11> !// [[export]] NumericVector foo( NumericVector x ){ auto fun = [](double d, double y, double z){ return exp(d * y) + z ; } ; return sapply(x, fun, 3.0, 4.6); }

x <- 1:3 sapply( x, function(d, y, z){ exp(d*y) + z ; }, 3.0, 4.6 )

Page 44: Rcpp11 genentech

Rcpp11 release cycle• Available from CRAN:

!

• Evolves quickly. Get it from github

!

• Next Release: 3.1.1 (same time as R 3.1.1) in a few days (I've been travelling)

> install.packages( "Rcpp11" )

> install_github( "Rcpp11/Rcpp11" )

Page 45: Rcpp11 genentech

attributes companion package

• Standalone impl of Rcpp attributes [[Rcpp::export]], sourceCpp, compileAttributes

!

• Only available from github: > install_github( "Rcpp11/attributes" )

Page 46: Rcpp11 genentech

Use Rcpp11 in your package• Write your .cpp files

#include <Rcpp11> !// [[export]] void foo( … ) { … } // your code

SystemRequirements: C++11 LinkingTo: Rcpp11

library(attributes) compileAttributes( "mypkg" )

• Express dep on C++11 and Rcpp11 headers

• Generate the boiler plate

Page 47: Rcpp11 genentech

Header only

• No runtime dependency

!

• Snapshot the code base

!

• Better control for package authors

Page 48: Rcpp11 genentech

Romain Franç[email protected] @romain_francois

Questions ?