SlideShare a Scribd company logo
Native Interfaces for R

           Seth Falcon

Fred Hutchinson Cancer Research Center


         20-21 May, 2010
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
which   as implemented in R prior to R-2.11




   which <- function(x) {
       seq_along(x)[x & !is.na(x)]
   }
which   as implemented in R prior to R-2.11



   which <- function(x) {
       seq_along(x)[x & !is.na(x)]
   }

        1. is.na
        2. !
        3. &
        4. seq_along
        5. [
which   in C


    1 SEXP nid_which(SEXP v) {
    2     SEXP ans;
    3     int i, j = 0, len = Rf_length(v), *buf, *tf;
    4     buf = (int *) R_alloc(len, sizeof(int));
    5     tf = LOGICAL(v);
    6     for (i = 0; i < len; i++) {
    7         if (tf[i] == TRUE) buf[j] = i + 1; j++;
    8     }
    9     ans = Rf_allocVector(INTSXP, j);
   10     memcpy(INTEGER(ans), buf, sizeof(int) * j);
   11     return ans;
   }
which   is now 10x faster



   system.time(which(v))



    R Version    System time    Elapsed time
    R-2.10       0.018          0.485
    R-2.11       0.001          0.052


   v is a logical vector with 10 million elements
Making use of existing code




 Access algorithms            Interface to other systems
     RBGL                         RSQLite
     RCurl                        netcdf
     Rsamtools                    SJava
Review of C

   #include <stdio.h>
   double _nid_avg(int *data, int len) {
       int i;
       double ans = 0.0;
       for (i = 0; i < len; i++) {
         ans += data[i];
       }
       return ans / len;
   }
   main() {
       int ex_data[5] = {1, 2, 3, 4, 5};
       double m = _nid_avg(ex_data, 5);
       printf("%fn", m);
   }
The .Call interface
Symbolic Expressions (SEXPs)




      The SEXP is R’s fundamental data type at the C-level
      SEXP is short for symbolic expression and is borrowed from
      Lisp
      History at http://en.wikipedia.org/wiki/S-expression
.Call Start to Finish Demo




   Demo
.Call Disection

   R
   # R/somefile.R
   avg <- function(x) .Call(.nid_avg, x)
   # NAMESPACE
   useDynLib("yourPackage", .nid_avg = nid_avg)


   C
   /* src/some.c */
   #include <Rinternals.h>
   SEXP nid_avg(SEXP data) { ... INTEGER(data) ... }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
.Call C function


   #include <Rinternals.h>

   SEXP nid_avg(SEXP data)
   {
       SEXP ans;
       double v = _nid_avg(INTEGER(data), Rf_length(data));
       PROTECT(ans = Rf_allocVector(REALSXP, 1));
       REAL(ans)[0] = v;
       UNPROTECT(1);
       return ans;
       /* shortcut: return Rf_ScalarReal(v); */
   }
Function Registration




      In NAMESPACE
      In C via R_CallMethodDef (See
      ShortRead/src/R_init_ShortRead.c for a nice example.
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
Just one thing to learn




       Everything is a SEXP
       But there are many different types of SEXPs
       INTSXP, REALSXP, STRSXP, LGLSXP, VECSXP, and more.
What’s a SEXP?
Common SEXP subtypes



   R function    SEXP subtype   Data accessor
   integer()     INTSXP         int *INTEGER(x)
   numeric()     REALSXP        double *REAL(x)
   logical()     LGLSXP         int *LOGICAL(x)
   character()   STRSXP         CHARSXP STRING ELT(x, i)
   list()        VECSXP         SEXP VECTOR ELT(x, i)
   NULL          NILSXP         R NilValue
   externalptr   EXTPTRSXP      SEXP (accessor funcs)
STRSXP/CHARSXP Exercise




  Try this:


       .Internal(inspect(c("abc", "abc", "xyz")))
STRSXP/CHARSXP Exercise




  > .Internal(inspect(c("abc", "abc", "xyz")))

   @101d3f280 16 STRSXP g0c3 []   (len=3, tl=1)
     @101cc6278 09 CHARSXP g0c1   [gp=0x20] "abc"
     @101cc6278 09 CHARSXP g0c1   [gp=0x20] "abc"
     @101cc6308 09 CHARSXP g0c1   [gp=0x20] "xyz"
character vectors == STRSXPs + CHARSXPs
CHARSXPs are special
STRSXP/CHARSXP API Example




  SEXP s = Rf_allocVector(STRSXP, 5);
  PROTECT(s);
  SET_STRING_ELT(s, 0, mkChar("hello"));
  SET_STRING_ELT(s, 1, mkChar("goodbye"));
  SEXP c = STRING_ELT(s, 0);
  const char *v = CHAR(c);
  UNPROTECT(1);
STRSXP/CHARSXP API Example




  SEXP s = Rf_allocVector(STRSXP, 5);
  PROTECT(s);
  SET_STRING_ELT(s, 0, mkChar("hello"));
  SET_STRING_ELT(s, 1, mkChar("goodbye"));
  SEXP c = STRING_ELT(s, 0);
  const char *v = CHAR(c);
  UNPROTECT(1);
STRSXP/CHARSXP API Example




  SEXP s = Rf_allocVector(STRSXP, 5);
  PROTECT(s);
  SET_STRING_ELT(s, 0, mkChar("hello"));
  SET_STRING_ELT(s, 1, mkChar("goodbye"));
  SEXP c = STRING_ELT(s, 0);
  const char *v = CHAR(c);
  UNPROTECT(1);
STRSXP/CHARSXP API Example




  SEXP s = Rf_allocVector(STRSXP, 5);
  PROTECT(s);
  SET_STRING_ELT(s, 0, mkChar("hello"));
  SET_STRING_ELT(s, 1, mkChar("goodbye"));
  SEXP c = STRING_ELT(s, 0);
  const char *v = CHAR(c);
  UNPROTECT(1);
STRSXP/CHARSXP API Example




  SEXP s = Rf_allocVector(STRSXP, 5);
  PROTECT(s);
  SET_STRING_ELT(s, 0, mkChar("hello"));
  SET_STRING_ELT(s, 1, mkChar("goodbye"));
  SEXP c = STRING_ELT(s, 0);
  const char *v = CHAR(c);
  UNPROTECT(1);
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
R’s memory model (dramatization)



                                 All SEXPs

     PROTECT                                 reachable
       stack



      Precious
         list




                 DRAMATIZATION
R’s memory model
      R allocates, tracks, and garbage collects SEXPs
      gc is triggered by R functions
      SEXPs that are not in-use are recycled.
      A SEXP is in-use if:
          it is on the protection stack (PROTECT/UNPROTECT)
          it is in the precious list (R PreserveObject/R ReleaseObject)
          it is reachable from a SEXP in the in-use list.

                                        All SEXPs

         PROTECT                                       reachable
           stack



          Precious
             list




                      DRAMATIZATION
Preventing gc of SEXPs with the protection stack




    PROTECT(s)     Push s onto the protection stack
    UNPROTECT(n)   Pop top n items off of the protection stack
Generic memory: When everything isn’t a SEXP




    Allocation Function   Lifecycle
    R_alloc               Memory is freed when returning from .Call
    Calloc/Free           Memory persists until Free is called
Case Study: C implementation of        which




   Code review of nidemo/src/which.c
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
Alphabet frequency of a text file

 Yeast Gene YDL143W                         English Dictionary


   a                                          e
    t                                          i
   g                                          a
   c                                          o
   d                                          r
    0.00   0.10               0.20   0.30     0.07   0.08     0.09      0.10
                  frequency                                 frequency
Self-Study in nidemo package



    1. Alphabet Frequency
           Explore R and C implementations
           Make C implementation robust
           Attach names attribute in C
           multiple file, matrix return enhancement
    2. External pointer example
    3. Calling R from C example and enhancement
    4. Debugging: a video how-to
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
Odds and Ends




    1. Debugging
    2. Public API
    3. Calling R from C
    4. Making sense of the remapped function names
    5. Finding C implementations of R functions
    6. Using a TAGS file
Debugging Native Code



  Rprintf("DEBUG: v => %d, x => %sn", v, x);

  $ R -d gdb
  (gdb) run
  > # now R is running

      There are two ways to write error-free programs; only the
      third one works.
      – Alan Perlis, Epigrams on Programming
R’s Public API



   mkdir R-devel-build; cd R-devel-build
   ~/src/R-devel-src/configure && make
   ## hint: configure --help

   ls include

     R.h      Rdefines.h    Rinterface.h   S.h
     R_ext/   Rembedded.h   Rinternals.h

   Details in WRE
Calling R functions from C




    1. Build a pairlist
    2. call Rf_eval(s, rho)
Remapped functions




      Source is unadorned
      Preprocessor adds Rf_
      Object code contains Rf_
Finding C implementations




   cd R-devel/src/main

   grep '"any"' names.c
   {"any", do_logic3, 2, ...}

   grep -l do_logic3 *.c
   logic.c
R CMD rtags




  cd R-devel/src
  R CMD rtags --no-Rd
  # creates index file TAGS
Outline


   The .Call Native Interface

   R types at the C-level

   Memory management in R

   Self-Study Exercises

   Odds and Ends

   Resources
Writing R Extensions




   RShowDoc("R-exts")
Book: The C Programming Language (K & R)




   Java in a Nutshell             1264 pages
   The C++ Programming Language   1030 pages
   The C Programming Language     274 pages
Resources
      Read WRE and “K & R”
      Use the sources for R and packages
      R-devel, bioc-devel mailing lists
      Patience

More Related Content

PDF
MeCC: Memory Comparison-based Code Clone Detector
PPTX
Exploit exercises.com stack-overflows
PDF
Apache PIG - User Defined Functions
PPT
STL ALGORITHMS
PPTX
PPTX
Idiomatic C++
PDF
C++20 the small things - Timur Doumler
PDF
Scala is java8.next()
MeCC: Memory Comparison-based Code Clone Detector
Exploit exercises.com stack-overflows
Apache PIG - User Defined Functions
STL ALGORITHMS
Idiomatic C++
C++20 the small things - Timur Doumler
Scala is java8.next()

What's hot (20)

PPTX
The Style of C++ 11
PPT
Paradigmas de Linguagens de Programacao - Aula #4
PDF
Java Keeps Throttling Up!
PDF
C++11 & C++14
PPTX
Summary of C++17 features
PPT
What's New in C++ 11?
PDF
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
PDF
C++aptitude questions and answers
PPTX
C++ 11 Features
ODP
OpenGurukul : Language : C++ Programming
PPTX
Fun with Lambdas: C++14 Style (part 2)
PDF
Javaz. Functional design in Java 8.
PPTX
Dynamic memory allocation in c++
PDF
Lazy java
PPTX
Meta Object Protocols
PPTX
PDF
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
PDF
Kamil witecki asynchronous, yet readable, code
PDF
Threads and Callbacks for Embedded Python
PDF
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
The Style of C++ 11
Paradigmas de Linguagens de Programacao - Aula #4
Java Keeps Throttling Up!
C++11 & C++14
Summary of C++17 features
What's New in C++ 11?
Beyond Java: 자바 8을 중심으로 본 자바의 혁신
C++aptitude questions and answers
C++ 11 Features
OpenGurukul : Language : C++ Programming
Fun with Lambdas: C++14 Style (part 2)
Javaz. Functional design in Java 8.
Dynamic memory allocation in c++
Lazy java
Meta Object Protocols
개발 과정 최적화 하기 내부툴로 더욱 강력한 개발하기 Stephen kennedy _(11시40분_103호)
Kamil witecki asynchronous, yet readable, code
Threads and Callbacks for Embedded Python
[C++] The Curiously Recurring Template Pattern: Static Polymorphsim and Expre...
Ad

Viewers also liked (17)

PPTX
Stock imagebank.com sibsa 2014
PDF
Dev ops of die (
PPS
RCRH - Candidats
PPS
Collage elsa en madrid
PPTX
Know how to cash in your Creativity ! Stock Photography Today
PPT
Ad slide show
PPTX
about me
PPTX
about me
PDF
你喜歡吃美國牛肉嗎(商業週刊內容)
PPT
Anàlisi
PPTX
Common wealth games 2010
PPT
Portfolio carstylistdk
PPT
Traditional Media Presentation
PPTX
Wiki Power point.
PPTX
Learn how to cash in your Creativity !! Stock Photography
PDF
While i was walking ___
PPT
Telephone english for secretaries 2014
Stock imagebank.com sibsa 2014
Dev ops of die (
RCRH - Candidats
Collage elsa en madrid
Know how to cash in your Creativity ! Stock Photography Today
Ad slide show
about me
about me
你喜歡吃美國牛肉嗎(商業週刊內容)
Anàlisi
Common wealth games 2010
Portfolio carstylistdk
Traditional Media Presentation
Wiki Power point.
Learn how to cash in your Creativity !! Stock Photography
While i was walking ___
Telephone english for secretaries 2014
Ad

Similar to Native interfaces for R (20)

PDF
Rcpp: Seemless R and C++
PDF
PDF
Rcpp: Seemless R and C++
PPTX
cp05.pptx
PPTX
C programming language tutorial
PDF
Pydiomatic
PDF
Python idiomatico
PDF
Pune Clojure Course Outline
PDF
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
PDF
Introduction to source{d} Engine and source{d} Lookout
PPTX
Advanced procedures in assembly language Full chapter ppt
PPT
Java Intro
PPT
r,rstats,r language,r packages
PDF
Rcpp: Seemless R and C++
PDF
Spark workshop
PDF
Xdp and ebpf_maps
ODP
Scala as a Declarative Language
PPTX
R language
PPT
Lex (lexical analyzer)
PDF
Introduction to Compiler Development
Rcpp: Seemless R and C++
Rcpp: Seemless R and C++
cp05.pptx
C programming language tutorial
Pydiomatic
Python idiomatico
Pune Clojure Course Outline
Oh Crap, I Forgot (Or Never Learned) C! [CodeMash 2010]
Introduction to source{d} Engine and source{d} Lookout
Advanced procedures in assembly language Full chapter ppt
Java Intro
r,rstats,r language,r packages
Rcpp: Seemless R and C++
Spark workshop
Xdp and ebpf_maps
Scala as a Declarative Language
R language
Lex (lexical analyzer)
Introduction to Compiler Development

Recently uploaded (20)

PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
Group 1 Presentation -Planning and Decision Making .pptx
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
cuic standard and advanced reporting.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Getting Started with Data Integration: FME Form 101
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPT
Teaching material agriculture food technology
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Spectroscopy.pptx food analysis technology
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
“AI and Expert System Decision Support & Business Intelligence Systems”
Group 1 Presentation -Planning and Decision Making .pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
cuic standard and advanced reporting.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Network Security Unit 5.pdf for BCA BBA.
Getting Started with Data Integration: FME Form 101
Digital-Transformation-Roadmap-for-Companies.pptx
MIND Revenue Release Quarter 2 2025 Press Release
Encapsulation_ Review paper, used for researhc scholars
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Teaching material agriculture food technology
Spectral efficient network and resource selection model in 5G networks
Spectroscopy.pptx food analysis technology
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Diabetes mellitus diagnosis method based random forest with bat algorithm
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf

Native interfaces for R

  • 1. Native Interfaces for R Seth Falcon Fred Hutchinson Cancer Research Center 20-21 May, 2010
  • 2. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 3. which as implemented in R prior to R-2.11 which <- function(x) { seq_along(x)[x & !is.na(x)] }
  • 4. which as implemented in R prior to R-2.11 which <- function(x) { seq_along(x)[x & !is.na(x)] } 1. is.na 2. ! 3. & 4. seq_along 5. [
  • 5. which in C 1 SEXP nid_which(SEXP v) { 2 SEXP ans; 3 int i, j = 0, len = Rf_length(v), *buf, *tf; 4 buf = (int *) R_alloc(len, sizeof(int)); 5 tf = LOGICAL(v); 6 for (i = 0; i < len; i++) { 7 if (tf[i] == TRUE) buf[j] = i + 1; j++; 8 } 9 ans = Rf_allocVector(INTSXP, j); 10 memcpy(INTEGER(ans), buf, sizeof(int) * j); 11 return ans; }
  • 6. which is now 10x faster system.time(which(v)) R Version System time Elapsed time R-2.10 0.018 0.485 R-2.11 0.001 0.052 v is a logical vector with 10 million elements
  • 7. Making use of existing code Access algorithms Interface to other systems RBGL RSQLite RCurl netcdf Rsamtools SJava
  • 8. Review of C #include <stdio.h> double _nid_avg(int *data, int len) { int i; double ans = 0.0; for (i = 0; i < len; i++) { ans += data[i]; } return ans / len; } main() { int ex_data[5] = {1, 2, 3, 4, 5}; double m = _nid_avg(ex_data, 5); printf("%fn", m); }
  • 10. Symbolic Expressions (SEXPs) The SEXP is R’s fundamental data type at the C-level SEXP is short for symbolic expression and is borrowed from Lisp History at http://en.wikipedia.org/wiki/S-expression
  • 11. .Call Start to Finish Demo Demo
  • 12. .Call Disection R # R/somefile.R avg <- function(x) .Call(.nid_avg, x) # NAMESPACE useDynLib("yourPackage", .nid_avg = nid_avg) C /* src/some.c */ #include <Rinternals.h> SEXP nid_avg(SEXP data) { ... INTEGER(data) ... }
  • 13. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 14. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 15. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 16. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 17. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 18. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 19. .Call C function #include <Rinternals.h> SEXP nid_avg(SEXP data) { SEXP ans; double v = _nid_avg(INTEGER(data), Rf_length(data)); PROTECT(ans = Rf_allocVector(REALSXP, 1)); REAL(ans)[0] = v; UNPROTECT(1); return ans; /* shortcut: return Rf_ScalarReal(v); */ }
  • 20. Function Registration In NAMESPACE In C via R_CallMethodDef (See ShortRead/src/R_init_ShortRead.c for a nice example.
  • 21. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 22. Just one thing to learn Everything is a SEXP But there are many different types of SEXPs INTSXP, REALSXP, STRSXP, LGLSXP, VECSXP, and more.
  • 24. Common SEXP subtypes R function SEXP subtype Data accessor integer() INTSXP int *INTEGER(x) numeric() REALSXP double *REAL(x) logical() LGLSXP int *LOGICAL(x) character() STRSXP CHARSXP STRING ELT(x, i) list() VECSXP SEXP VECTOR ELT(x, i) NULL NILSXP R NilValue externalptr EXTPTRSXP SEXP (accessor funcs)
  • 25. STRSXP/CHARSXP Exercise Try this: .Internal(inspect(c("abc", "abc", "xyz")))
  • 26. STRSXP/CHARSXP Exercise > .Internal(inspect(c("abc", "abc", "xyz"))) @101d3f280 16 STRSXP g0c3 [] (len=3, tl=1) @101cc6278 09 CHARSXP g0c1 [gp=0x20] "abc" @101cc6278 09 CHARSXP g0c1 [gp=0x20] "abc" @101cc6308 09 CHARSXP g0c1 [gp=0x20] "xyz"
  • 27. character vectors == STRSXPs + CHARSXPs
  • 29. STRSXP/CHARSXP API Example SEXP s = Rf_allocVector(STRSXP, 5); PROTECT(s); SET_STRING_ELT(s, 0, mkChar("hello")); SET_STRING_ELT(s, 1, mkChar("goodbye")); SEXP c = STRING_ELT(s, 0); const char *v = CHAR(c); UNPROTECT(1);
  • 30. STRSXP/CHARSXP API Example SEXP s = Rf_allocVector(STRSXP, 5); PROTECT(s); SET_STRING_ELT(s, 0, mkChar("hello")); SET_STRING_ELT(s, 1, mkChar("goodbye")); SEXP c = STRING_ELT(s, 0); const char *v = CHAR(c); UNPROTECT(1);
  • 31. STRSXP/CHARSXP API Example SEXP s = Rf_allocVector(STRSXP, 5); PROTECT(s); SET_STRING_ELT(s, 0, mkChar("hello")); SET_STRING_ELT(s, 1, mkChar("goodbye")); SEXP c = STRING_ELT(s, 0); const char *v = CHAR(c); UNPROTECT(1);
  • 32. STRSXP/CHARSXP API Example SEXP s = Rf_allocVector(STRSXP, 5); PROTECT(s); SET_STRING_ELT(s, 0, mkChar("hello")); SET_STRING_ELT(s, 1, mkChar("goodbye")); SEXP c = STRING_ELT(s, 0); const char *v = CHAR(c); UNPROTECT(1);
  • 33. STRSXP/CHARSXP API Example SEXP s = Rf_allocVector(STRSXP, 5); PROTECT(s); SET_STRING_ELT(s, 0, mkChar("hello")); SET_STRING_ELT(s, 1, mkChar("goodbye")); SEXP c = STRING_ELT(s, 0); const char *v = CHAR(c); UNPROTECT(1);
  • 34. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 35. R’s memory model (dramatization) All SEXPs PROTECT reachable stack Precious list DRAMATIZATION
  • 36. R’s memory model R allocates, tracks, and garbage collects SEXPs gc is triggered by R functions SEXPs that are not in-use are recycled. A SEXP is in-use if: it is on the protection stack (PROTECT/UNPROTECT) it is in the precious list (R PreserveObject/R ReleaseObject) it is reachable from a SEXP in the in-use list. All SEXPs PROTECT reachable stack Precious list DRAMATIZATION
  • 37. Preventing gc of SEXPs with the protection stack PROTECT(s) Push s onto the protection stack UNPROTECT(n) Pop top n items off of the protection stack
  • 38. Generic memory: When everything isn’t a SEXP Allocation Function Lifecycle R_alloc Memory is freed when returning from .Call Calloc/Free Memory persists until Free is called
  • 39. Case Study: C implementation of which Code review of nidemo/src/which.c
  • 40. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 41. Alphabet frequency of a text file Yeast Gene YDL143W English Dictionary a e t i g a c o d r 0.00 0.10 0.20 0.30 0.07 0.08 0.09 0.10 frequency frequency
  • 42. Self-Study in nidemo package 1. Alphabet Frequency Explore R and C implementations Make C implementation robust Attach names attribute in C multiple file, matrix return enhancement 2. External pointer example 3. Calling R from C example and enhancement 4. Debugging: a video how-to
  • 43. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 44. Odds and Ends 1. Debugging 2. Public API 3. Calling R from C 4. Making sense of the remapped function names 5. Finding C implementations of R functions 6. Using a TAGS file
  • 45. Debugging Native Code Rprintf("DEBUG: v => %d, x => %sn", v, x); $ R -d gdb (gdb) run > # now R is running There are two ways to write error-free programs; only the third one works. – Alan Perlis, Epigrams on Programming
  • 46. R’s Public API mkdir R-devel-build; cd R-devel-build ~/src/R-devel-src/configure && make ## hint: configure --help ls include R.h Rdefines.h Rinterface.h S.h R_ext/ Rembedded.h Rinternals.h Details in WRE
  • 47. Calling R functions from C 1. Build a pairlist 2. call Rf_eval(s, rho)
  • 48. Remapped functions Source is unadorned Preprocessor adds Rf_ Object code contains Rf_
  • 49. Finding C implementations cd R-devel/src/main grep '"any"' names.c {"any", do_logic3, 2, ...} grep -l do_logic3 *.c logic.c
  • 50. R CMD rtags cd R-devel/src R CMD rtags --no-Rd # creates index file TAGS
  • 51. Outline The .Call Native Interface R types at the C-level Memory management in R Self-Study Exercises Odds and Ends Resources
  • 52. Writing R Extensions RShowDoc("R-exts")
  • 53. Book: The C Programming Language (K & R) Java in a Nutshell 1264 pages The C++ Programming Language 1030 pages The C Programming Language 274 pages
  • 54. Resources Read WRE and “K & R” Use the sources for R and packages R-devel, bioc-devel mailing lists Patience