rcpp11 genentech

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

Upload: romain-francois

Post on 10-May-2015

530 views

Category:

Technology


0 download

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

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 ?