SlideShare uma empresa Scribd logo
1 de 31
Baixar para ler offline
Rcpp: Seamless R and C++
                   Romain François
        romain@r-enthusiasts.com
            Joint work with Dirk Eddelbuettel




                RMetrics, June 2010, Meielsalp.
Fine for Indiana Jones
Le viaduc de Millau
Background API Sugar Modules




                                       Plat du jour


  1    Appetizers : Some background on R and C++


  2    Main course : The Rcpp API


  3    Desert : Rcpp sugar


  4    Coffee : Rcpp modules




Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

R support for C/C++


          R is a C program
          R supports C++ out of the box, just use a .cpp file extension
          R exposes a API based on low level C functions and MACROS.
          R provides several calling conventions to invoke compiled code.


   SEXP foo( SEXP x1, SEXP x2 ){
      ...
   }

   > .Call( "foo", 1:10, rnorm(10) )



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP convolve2(SEXP a, SEXP b){
     int i, j, na, nb, nab;
     double *xa, *xb, *xab; SEXP ab;
     PROTECT(a = AS_NUMERIC(a));
     PROTECT(b = AS_NUMERIC(b));
     na=LENGTH(a); nb=LENGTH(b); nab=na+nb-1;
     PROTECT(ab = NEW_NUMERIC(nab));
     xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b);
     xab=NUMERIC_POINTER(ab);
     for(i=0; i<nab; i++) xab[i] = 0.0;
     for(i=0; i<na; i++) for(j=0; j<nb; j++)
        xab[i+j] += xa[i]*xb[j];
     UNPROTECT(3);
     return(ab);
   }
 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example: character vectors


   > c( "foo", "bar" )

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP foobar(){
     SEXP res = PROTECT(allocVector(STRSXP, 2));
     SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ;
     SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ;
     UNPROTECT(1) ;
     return res ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

.Call example: calling an R function

   > eval( call( "rnorm", 3L, 10.0, 20.0 ) )

   #include <R.h>
   #include <Rdefines.h>
   extern "C" SEXP callback(){
     SEXP call = PROTECT( LCONS( install("rnorm"),
         CONS( ScalarInteger( 3 ),
           CONS( ScalarReal( 10.0 ),
            CONS( ScalarReal( 20.0 ), R_NilValue )
          )
       )
     ) );
     SEXP res = PROTECT(eval(call, R_GlobalEnv)) ;
     UNPROTECT(2) ;
     return res ;
   }

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
The Rcpp API
Background API Sugar Modules

The Rcpp API



          Encapsulation of R objects (SEXP) into C++ classes:
          NumericVector, IntegerVector, ..., Function,
          Environment, Language, ...

          Conversion from R to C++ : as

          Conversion from C++ to R : wrap

          Interoperability with the Standard Template Library (STL)




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : classes


             Rcpp class                                      R typeof
      Integer(Vector|Matrix)                        integer vectors and matrices
      Numeric(Vector|Matrix)                                numeric ...
      Logical(Vector|Matrix)                                logical ...
     Character(Vector|Matrix)                              character ...
        Raw(Vector|Matrix)                                    raw ...
      Complex(Vector|Matrix)                                complex ...
                List                                list (aka generic vectors) ...
    Expression(Vector|Matrix)                             expression ...
            Environment                                   environment
             Function                                       function
                XPtr                                      externalptr
             Language                                       language
                 S4                                             S4
                 ...                                            ...

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example

   SEXP foo( SEXP x, SEXP y ){
       Rcpp::NumericVector xx(x), yy(y) ;
       int n = xx.size() ;
       Rcpp::NumericVector res( n ) ;
       double x_ = 0.0, y_ = 0.0 ;
       for( int i=0; i<n; i++){
            x_ = xx[i] ; y_ = yy[i] ;
            if( x_ < y_ ){
                 res[i] = x_ * x_ ;
            } else {
                 res[i] = -( y_ * y_) ;
                    }
           }
           return res ;
   }


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example


   using namespace Rcpp ;
   SEXP bar(){
        std::vector<double> z(10) ;
        List res = List::create(
           _["foo"] = NumericVector::create(1,2),
           _["bar"] = 3,
           _["bla"] = "yada yada",
           _["blo"] = z
           ) ;
        res.attr("class") = "myclass" ;
        return res ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : example



   using namespace Rcpp ;
   SEXP bar(){
        Language call( "rnorm",
             _["n"] = 100, _["mean"] = 10 ) ;
        NumericVector res = call.eval() ;
        double sum = std::accumulate(
             res.begin(), res.end(),
             0.0 ) ;
        return wrap( sum ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion from R to C++

  Rcpp::as<T> handles conversion from SEXP to T.

   template <typename T> T as( SEXP m_sexp)
       throw(not_compatible) ;

  T can be:
          primitive type : int, double, bool, long, std::string
          any type that has a constructor taking a SEXP
          ... that specializes the as template
          ... that specializes the Exporter class template
          containers from the STL
  more details in the Rcpp-extending vignette.


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion from C++ to R

  Rcpp::wrap<T> handles conversion from T to SEXP.

   template <typename T>
   SEXP wrap( const T& object ) ;

  T can be:
          primitive type : int, double, bool, long, std::string
          any type that has a an operator SEXP
          ... that specializes the wrap template
          ... that has a nested type called iterator and member
          functions begin and end
          containers from the STL vector<T>, list<T>,
          map<string,T>, etc ... (where T is itself wrappable)
  more details in the Rcpp-extending vignette.

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : conversion examples

   typedef std::vector<double> Vec ;
   int x_ = as<int>( x ) ;
   double y_ = as<double>( y_ ) ;
   VEC z_ = as<VEC>( z_ ) ;

   wrap( 1 ) ; // INTSXP
   wrap( "foo" ) ; // STRSXP

   typedef std::map<std::string,Vec> Map ;
   Map foo( 10 ) ;
   Vec f1(4) ;
   Vec f2(10) ;
   foo.insert( "x", f1 ) ;
   foo.insert( "y", f2 ) ;
   wrap( foo ) ; // named list of numeric vectors


 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

The Rcpp API : implicit conversion examples


   Environment env = ... ;
   List list = ... ;
   Function rnorm( "rnorm") ;

   // implicit calls to as
   int x = env["x"] ;
   double y = list["y"];

   // implicit calls to wrap
   rnorm( 100, _["mean"] = 10 ) ;
   env["x"] = 3;
   env["y"] = "foo" ;
   List::create( 1, "foo", 10.0, false ) ;




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Rcpp sugar
Background API Sugar Modules

Sugar : motivation


     int n = x.size() ;
     NumericVector res1( n ) ;
     double x_ = 0.0, y_ = 0.0 ;
     for( int i=0; i<n; i++){
             x_ = x[i] ;y_ = y[i] ;
             if( R_IsNA(x_) || R_IsNA(y_) ){
                  res1[i] = NA_REAL;
             } else if( x_ < y_ ){
                  res1[i] = x_ * x_ ;
             } else {
                  res1[i] = -( y_ * y_) ;
                    }
           }



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : motivation


  We missed the R syntax :
   > ifelse( x < y, x*x, -(y*y) )




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : motivation


  We missed the R syntax :
   > ifelse( x < y, x*x, -(y*y) )


  sugar brings it into C++

   SEXP foo( SEXP xx, SEXP yy){
       NumericVector x(xx), y(yy) ;
       return ifelse( x < y, x*x, -(y*y) ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : another example



   double square( double x){
     return x*x ;
   }

   SEXP foo( SEXP xx ){
     NumericVector x(xx) ;
     return sapply( x, square ) ;
   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : contents


          logical operators: <, >, <=, >=, ==, !=
          arithmetic operators: +, -, *, /
          functions: abs, all, any, ceiling, diff, exp, ifelse,
          is_na, lapply, pmin, pmax, pow, sapply, seq_along,
          seq_len, sign


  Sugar uses Expression Templates (Blitz++, Armadillo, ...) to
  achieve lazy evaluation of expressions.

  More information in the Rcpp-sugar vignette.



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Sugar : benchmarks




                      expression                                   sugar                R         R / sugar
            any(x*y<0)                                         0.0008771             29.58            33721
    ifelse(x<y, x*x, -(y*y) )                                    5.217               35.88            6.879
        sapply(x,square)                                         0.6322              259.4            410.2

  Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop.




 Romain François      romain@r-enthusiasts.com               Seamless R anc C++ integrations, RMetrics 2010
Rcpp modules
Background API Sugar Modules

Modules: expose C++ to R


   const char* hello( const std::string& who ){
       std::string result( "hello " ) ;
       result += who ;
       return result.c_str() ;
   }

   RCPP_MODULE(yada){
       using namespace Rcpp ;
       function( "hello", &hello ) ;
   }

   > yada <- Module( "yada" )
   > yada$hello( "world" )



 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: expose C++ classes to R

   class World {
   public:
        World() : msg("hello"){}
        void set(std::string msg) {
            this->msg = msg;
           }
           std::string greet() {
               return msg;
           }
   private:
        std::string msg;
   };

   void clearWorld( World* w){
       w->set( "" ) ;
   }

 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: expose C++ classes to R



   RCPP_MODULE(yada){
       using namespace Rcpp ;

           class_<World>( "World" )
               .method( "greet", &World::greet )
               .method( "set", &World::set )
               .method( "clear", &clearWorld )
           ;

   }




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Background API Sugar Modules

Modules: on the R side


   > w <- new( yada$World )
   > w$greet()
   [1] "hello"

   > w$set( "hello world")
   > w$greet()
   [1] "hello world"

   > w$clear()
   > w$greet()
   [1] ""




 Romain François     romain@r-enthusiasts.com     Seamless R anc C++ integrations, RMetrics 2010
Want to learn more ?

  Check the vignettes

  Questions on the Rcpp-devel mailing list

  Hands-on training courses

  Commercial support



Romain François               romain@r-enthusiasts.com
Dirk Eddelbuettel                       edd@debian.org

Mais conteúdo relacionado

Mais procurados

개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
changehee lee
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
xu liwei
 

Mais procurados (20)

C++20 the small things - Timur Doumler
C++20 the small things - Timur DoumlerC++20 the small things - Timur Doumler
C++20 the small things - Timur Doumler
 
Contravariant functors in scala
Contravariant functors in scalaContravariant functors in scala
Contravariant functors in scala
 
Introduction To Lisp
Introduction To LispIntroduction To Lisp
Introduction To Lisp
 
Class 11: Deeper List Procedures
Class 11: Deeper List ProceduresClass 11: Deeper List Procedures
Class 11: Deeper List Procedures
 
Macro
MacroMacro
Macro
 
R/C++ talk at earl 2014
R/C++ talk at earl 2014R/C++ talk at earl 2014
R/C++ talk at earl 2014
 
Summary of C++17 features
Summary of C++17 featuresSummary of C++17 features
Summary of C++17 features
 
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
 
C++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabsC++17 introduction - Meetup @EtixLabs
C++17 introduction - Meetup @EtixLabs
 
Intro to Pig UDF
Intro to Pig UDFIntro to Pig UDF
Intro to Pig UDF
 
Apache PIG - User Defined Functions
Apache PIG - User Defined FunctionsApache PIG - User Defined Functions
Apache PIG - User Defined Functions
 
C++11
C++11C++11
C++11
 
Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence) Advance LISP (Artificial Intelligence)
Advance LISP (Artificial Intelligence)
 
C++11 concurrency
C++11 concurrencyC++11 concurrency
C++11 concurrency
 
Native interfaces for R
Native interfaces for RNative interfaces for R
Native interfaces for R
 
Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4Paradigmas de Linguagens de Programacao - Aula #4
Paradigmas de Linguagens de Programacao - Aula #4
 
Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。Tiramisu をちょっと、味見してみました。
Tiramisu をちょっと、味見してみました。
 
Pydiomatic
PydiomaticPydiomatic
Pydiomatic
 
25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах25 лет истории C++, пролетевшей на моих глазах
25 лет истории C++, пролетевшей на моих глазах
 
Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)Fun with Lambdas: C++14 Style (part 1)
Fun with Lambdas: C++14 Style (part 1)
 

Semelhante a Rcpp: Seemless R and C++

Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!
mickey24
 
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdfImplement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
meerobertsonheyde608
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 

Semelhante a Rcpp: Seemless R and C++ (20)

Integrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBufIntegrating R with C++: Rcpp, RInside and RProtoBuf
Integrating R with C++: Rcpp, RInside and RProtoBuf
 
Rcpp
RcppRcpp
Rcpp
 
Rcpp11 genentech
Rcpp11 genentechRcpp11 genentech
Rcpp11 genentech
 
R and C++
R and C++R and C++
R and C++
 
Extend R with Rcpp!!!
Extend R with Rcpp!!!Extend R with Rcpp!!!
Extend R with Rcpp!!!
 
Lesson 24. Phantom errors
Lesson 24. Phantom errorsLesson 24. Phantom errors
Lesson 24. Phantom errors
 
Rcpp11
Rcpp11Rcpp11
Rcpp11
 
R Language Introduction
R Language IntroductionR Language Introduction
R Language Introduction
 
R and cpp
R and cppR and cpp
R and cpp
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
 
What's new in Apache SystemML - Declarative Machine Learning
What's new in Apache SystemML  - Declarative Machine LearningWhat's new in Apache SystemML  - Declarative Machine Learning
What's new in Apache SystemML - Declarative Machine Learning
 
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
Leveraging R in Big Data of Mobile Ads (R在行動廣告大數據的應用)
 
Qemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System EmulationQemu JIT Code Generator and System Emulation
Qemu JIT Code Generator and System Emulation
 
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdfImplement an MPI program to perform matrix-matrix multiplication AB .pdf
Implement an MPI program to perform matrix-matrix multiplication AB .pdf
 
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data EcosystemWprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
Wprowadzenie do technologii Big Data / Intro to Big Data Ecosystem
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Ch9a
Ch9aCh9a
Ch9a
 

Mais de Romain Francois (13)

R/C++
R/C++R/C++
R/C++
 
dplyr and torrents from cpasbien
dplyr and torrents from cpasbiendplyr and torrents from cpasbien
dplyr and torrents from cpasbien
 
dplyr use case
dplyr use casedplyr use case
dplyr use case
 
dplyr
dplyrdplyr
dplyr
 
user2015 keynote talk
user2015 keynote talkuser2015 keynote talk
user2015 keynote talk
 
SevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittrSevillaR meetup: dplyr and magrittr
SevillaR meetup: dplyr and magrittr
 
dplyr
dplyrdplyr
dplyr
 
Data manipulation with dplyr
Data manipulation with dplyrData manipulation with dplyr
Data manipulation with dplyr
 
Rcpp attributes
Rcpp attributesRcpp attributes
Rcpp attributes
 
Rcpp is-ready
Rcpp is-readyRcpp is-ready
Rcpp is-ready
 
Rcpp
RcppRcpp
Rcpp
 
Object Oriented Design(s) in R
Object Oriented Design(s) in RObject Oriented Design(s) in R
Object Oriented Design(s) in R
 
RProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for RRProtoBuf: protocol buffers for R
RProtoBuf: protocol buffers for R
 

Último

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Rcpp: Seemless R and C++

  • 1. Rcpp: Seamless R and C++ Romain François romain@r-enthusiasts.com Joint work with Dirk Eddelbuettel RMetrics, June 2010, Meielsalp.
  • 3. Le viaduc de Millau
  • 4. Background API Sugar Modules Plat du jour 1 Appetizers : Some background on R and C++ 2 Main course : The Rcpp API 3 Desert : Rcpp sugar 4 Coffee : Rcpp modules Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 5. Background API Sugar Modules R support for C/C++ R is a C program R supports C++ out of the box, just use a .cpp file extension R exposes a API based on low level C functions and MACROS. R provides several calling conventions to invoke compiled code. SEXP foo( SEXP x1, SEXP x2 ){ ... } > .Call( "foo", 1:10, rnorm(10) ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 6. Background API Sugar Modules .Call example #include <R.h> #include <Rdefines.h> extern "C" SEXP convolve2(SEXP a, SEXP b){ int i, j, na, nb, nab; double *xa, *xb, *xab; SEXP ab; PROTECT(a = AS_NUMERIC(a)); PROTECT(b = AS_NUMERIC(b)); na=LENGTH(a); nb=LENGTH(b); nab=na+nb-1; PROTECT(ab = NEW_NUMERIC(nab)); xa=NUMERIC_POINTER(a); xb=NUMERIC_POINTER(b); xab=NUMERIC_POINTER(ab); for(i=0; i<nab; i++) xab[i] = 0.0; for(i=0; i<na; i++) for(j=0; j<nb; j++) xab[i+j] += xa[i]*xb[j]; UNPROTECT(3); return(ab); } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 7. Background API Sugar Modules .Call example: character vectors > c( "foo", "bar" ) #include <R.h> #include <Rdefines.h> extern "C" SEXP foobar(){ SEXP res = PROTECT(allocVector(STRSXP, 2)); SET_STRING_ELT( res, 0, mkChar( "foo" ) ) ; SET_STRING_ELT( res, 1, mkChar( "bar" ) ) ; UNPROTECT(1) ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 8. Background API Sugar Modules .Call example: calling an R function > eval( call( "rnorm", 3L, 10.0, 20.0 ) ) #include <R.h> #include <Rdefines.h> extern "C" SEXP callback(){ SEXP call = PROTECT( LCONS( install("rnorm"), CONS( ScalarInteger( 3 ), CONS( ScalarReal( 10.0 ), CONS( ScalarReal( 20.0 ), R_NilValue ) ) ) ) ); SEXP res = PROTECT(eval(call, R_GlobalEnv)) ; UNPROTECT(2) ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 10. Background API Sugar Modules The Rcpp API Encapsulation of R objects (SEXP) into C++ classes: NumericVector, IntegerVector, ..., Function, Environment, Language, ... Conversion from R to C++ : as Conversion from C++ to R : wrap Interoperability with the Standard Template Library (STL) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 11. Background API Sugar Modules The Rcpp API : classes Rcpp class R typeof Integer(Vector|Matrix) integer vectors and matrices Numeric(Vector|Matrix) numeric ... Logical(Vector|Matrix) logical ... Character(Vector|Matrix) character ... Raw(Vector|Matrix) raw ... Complex(Vector|Matrix) complex ... List list (aka generic vectors) ... Expression(Vector|Matrix) expression ... Environment environment Function function XPtr externalptr Language language S4 S4 ... ... Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 12. Background API Sugar Modules The Rcpp API : example SEXP foo( SEXP x, SEXP y ){ Rcpp::NumericVector xx(x), yy(y) ; int n = xx.size() ; Rcpp::NumericVector res( n ) ; double x_ = 0.0, y_ = 0.0 ; for( int i=0; i<n; i++){ x_ = xx[i] ; y_ = yy[i] ; if( x_ < y_ ){ res[i] = x_ * x_ ; } else { res[i] = -( y_ * y_) ; } } return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 13. Background API Sugar Modules The Rcpp API : example using namespace Rcpp ; SEXP bar(){ std::vector<double> z(10) ; List res = List::create( _["foo"] = NumericVector::create(1,2), _["bar"] = 3, _["bla"] = "yada yada", _["blo"] = z ) ; res.attr("class") = "myclass" ; return res ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 14. Background API Sugar Modules The Rcpp API : example using namespace Rcpp ; SEXP bar(){ Language call( "rnorm", _["n"] = 100, _["mean"] = 10 ) ; NumericVector res = call.eval() ; double sum = std::accumulate( res.begin(), res.end(), 0.0 ) ; return wrap( sum ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 15. Background API Sugar Modules The Rcpp API : conversion from R to C++ Rcpp::as<T> handles conversion from SEXP to T. template <typename T> T as( SEXP m_sexp) throw(not_compatible) ; T can be: primitive type : int, double, bool, long, std::string any type that has a constructor taking a SEXP ... that specializes the as template ... that specializes the Exporter class template containers from the STL more details in the Rcpp-extending vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 16. Background API Sugar Modules The Rcpp API : conversion from C++ to R Rcpp::wrap<T> handles conversion from T to SEXP. template <typename T> SEXP wrap( const T& object ) ; T can be: primitive type : int, double, bool, long, std::string any type that has a an operator SEXP ... that specializes the wrap template ... that has a nested type called iterator and member functions begin and end containers from the STL vector<T>, list<T>, map<string,T>, etc ... (where T is itself wrappable) more details in the Rcpp-extending vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 17. Background API Sugar Modules The Rcpp API : conversion examples typedef std::vector<double> Vec ; int x_ = as<int>( x ) ; double y_ = as<double>( y_ ) ; VEC z_ = as<VEC>( z_ ) ; wrap( 1 ) ; // INTSXP wrap( "foo" ) ; // STRSXP typedef std::map<std::string,Vec> Map ; Map foo( 10 ) ; Vec f1(4) ; Vec f2(10) ; foo.insert( "x", f1 ) ; foo.insert( "y", f2 ) ; wrap( foo ) ; // named list of numeric vectors Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 18. Background API Sugar Modules The Rcpp API : implicit conversion examples Environment env = ... ; List list = ... ; Function rnorm( "rnorm") ; // implicit calls to as int x = env["x"] ; double y = list["y"]; // implicit calls to wrap rnorm( 100, _["mean"] = 10 ) ; env["x"] = 3; env["y"] = "foo" ; List::create( 1, "foo", 10.0, false ) ; Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 20. Background API Sugar Modules Sugar : motivation int n = x.size() ; NumericVector res1( n ) ; double x_ = 0.0, y_ = 0.0 ; for( int i=0; i<n; i++){ x_ = x[i] ;y_ = y[i] ; if( R_IsNA(x_) || R_IsNA(y_) ){ res1[i] = NA_REAL; } else if( x_ < y_ ){ res1[i] = x_ * x_ ; } else { res1[i] = -( y_ * y_) ; } } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 21. Background API Sugar Modules Sugar : motivation We missed the R syntax : > ifelse( x < y, x*x, -(y*y) ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 22. Background API Sugar Modules Sugar : motivation We missed the R syntax : > ifelse( x < y, x*x, -(y*y) ) sugar brings it into C++ SEXP foo( SEXP xx, SEXP yy){ NumericVector x(xx), y(yy) ; return ifelse( x < y, x*x, -(y*y) ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 23. Background API Sugar Modules Sugar : another example double square( double x){ return x*x ; } SEXP foo( SEXP xx ){ NumericVector x(xx) ; return sapply( x, square ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 24. Background API Sugar Modules Sugar : contents logical operators: <, >, <=, >=, ==, != arithmetic operators: +, -, *, / functions: abs, all, any, ceiling, diff, exp, ifelse, is_na, lapply, pmin, pmax, pow, sapply, seq_along, seq_len, sign Sugar uses Expression Templates (Blitz++, Armadillo, ...) to achieve lazy evaluation of expressions. More information in the Rcpp-sugar vignette. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 25. Background API Sugar Modules Sugar : benchmarks expression sugar R R / sugar any(x*y<0) 0.0008771 29.58 33721 ifelse(x<y, x*x, -(y*y) ) 5.217 35.88 6.879 sapply(x,square) 0.6322 259.4 410.2 Benchmarks performed on fedora 12 / R 2.12.0 (under development) on a 2 years old dell inspiron 1525 laptop. Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 27. Background API Sugar Modules Modules: expose C++ to R const char* hello( const std::string& who ){ std::string result( "hello " ) ; result += who ; return result.c_str() ; } RCPP_MODULE(yada){ using namespace Rcpp ; function( "hello", &hello ) ; } > yada <- Module( "yada" ) > yada$hello( "world" ) Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 28. Background API Sugar Modules Modules: expose C++ classes to R class World { public: World() : msg("hello"){} void set(std::string msg) { this->msg = msg; } std::string greet() { return msg; } private: std::string msg; }; void clearWorld( World* w){ w->set( "" ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 29. Background API Sugar Modules Modules: expose C++ classes to R RCPP_MODULE(yada){ using namespace Rcpp ; class_<World>( "World" ) .method( "greet", &World::greet ) .method( "set", &World::set ) .method( "clear", &clearWorld ) ; } Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 30. Background API Sugar Modules Modules: on the R side > w <- new( yada$World ) > w$greet() [1] "hello" > w$set( "hello world") > w$greet() [1] "hello world" > w$clear() > w$greet() [1] "" Romain François romain@r-enthusiasts.com Seamless R anc C++ integrations, RMetrics 2010
  • 31. Want to learn more ? Check the vignettes Questions on the Rcpp-devel mailing list Hands-on training courses Commercial support Romain François romain@r-enthusiasts.com Dirk Eddelbuettel edd@debian.org