31
R – C/C++ programming Katia Oleinik [email protected] Scientific Computing and Visualization Boston University http://www.bu.edu/tech/research/training/tutorials/list /

R – C/C++ programming Katia Oleinik [email protected] Scientific Computing and Visualization Boston University

  • Upload
    michel

  • View
    33

  • Download
    2

Embed Size (px)

DESCRIPTION

R – C/C++ programming Katia Oleinik [email protected] Scientific Computing and Visualization Boston University. http://www.bu.edu/tech/research/training/tutorials/list /. R-C/C++ programming. Goal – performance enhancement. Benefits – use of existing C/C++ libraries and memory management - PowerPoint PPT Presentation

Citation preview

Page 1: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

R – C/C++ programming

Katia [email protected]

Scientific Computing and Visualization

Boston University

http://www.bu.edu/tech/research/training/tutorials/list/

Page 2: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

2

R-C/C++ programming

Goal – performance enhancement.Benefits – use of existing C/C++ libraries and memory management

Base R package provides 3 types of interfaces between R and C/C++

.C()

.Call()

.External() – used to create R packages

There are other R packages that provide interface between R and C/C++ (and other languages such as FORTRAN and Python):

Rcpp

Page 3: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

3

R-C/C++ programming

.C() interface

/* exC1.c – example C function to be called from R */void exampleC1(int *iVec){

iVec[0] = 7; return;}

exC1.c

Important:Function returns no values – it is VOIDAll the values that need to be

changed/returned by a function must be passed through its arguments.

Page 4: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

4

R-C/C++ programming

.C() interface

katana:~ % R CMD SHLIB exC1.cgcc -std=gnu99 -I/usr/local/IT/R-2.13.2/lib64/R/include -I/usr/local/include -fpic -g -O2 -c exC1.c -o exC1.ogcc -std=gnu99 -shared -L/usr/local/lib64 -o exC1.so exC1.okatana:~ %

Important:In linux (and R) environment commands are case

sensitive!

Page 5: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

5

R-C/C++ programming

.C() interface

Note:In windows after the function is compiled it

will be named exC1.dll

> # load C function to R workspace> dyn.load("exC1.so")>

Page 6: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

6

R-C/C++ programming

.C() interface

> # load C function to R workspace> dyn.load("exC1.so")

> # create a vector> iv <- 1:3

Page 7: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

7

R-C/C++ programming

.C() interface

> # load C function to R workspace> dyn.load("exC1.so")

> # create a vector> iv <- 1:3

> # call c-function> out <- .C("exampleC1", newVec = as.integer(iv))

Page 8: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

8

R-C/C++ programming

.C() interface

> # load C function to R workspace> dyn.load("exC1.so")

> # create a vector> iv <- 1:3

> # call c-function> out <- .C("exampleC1", newVec = as.integer(iv))

> out$newVec [1] 7 2 3

Page 9: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

9

R-C/C++ programming

.C() interface

Note:• Allocate memory to the vectors passed to .C in R by

creating vectors of the right length• The first argument to .C is a character string of the C

function name• The rest of the arguments are R objects to be passed to

the C function.• All arguments should be coerced to the correct R storage

mode to prevent mismatching of types that can lead to errors

• C returns a list object• The second argument in this example is given a name

newVec. This name is used to access the component in the returned list object.

Page 10: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

10

R-C/C++ programming

.C() interface

Note:R has to allocate memory for the arrays passed to and

from C.R has to pass objects of correct typeR copies its arguments prior to passing them to C and

then creates a copy of the values passed back from C.

Page 11: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

11

R-C/C++ programming

/* exC2.c – example C function to be called from R *//* normalize the vector */include <math.h>include <string.h> void exampleC2(char **c, double *A, double *B, int *ierr){

double len = 0; /*local variable – vector length */ int i;

for (i=0; i<3; i++) len += pow( A[i]), 2);

/* check if the vector is degenerate */ if ( len < 0.000001){ ierr[0] = -1; /*error – null vector */ stncpy(c, “Error”, 5); return; }

/* calculate output vector len = pow(len, 0.5); for (i=0; i<3; i++) B[i] = A[i] / len ; ierr[0] = 0; strncpy(c, “OK”, 2); return; }

exC2.c

Page 12: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

12

R-C/C++ programming

.C() interface

katana:~ % R CMD SHLIB exC2.cgcc -std=gnu99 -I/usr/local/IT/R-2.13.2/lib64/R/include -I/usr/local/include -fpic -g -O2 -c exC2.c -o exC2.ogcc -std=gnu99 -shared -L/usr/local/lib64 -o exC2.so exC2.o

Page 13: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

13

R-C/C++ programming

.C() interface

> # load C function to R workspace> dyn.load("exC2.so")

> # create error vector> ierr_in <- 0

> # create input vector> A_in <- c(2, 3, 6)

> # create output vector> B_in <- c(0, 0, 0)

> # create message vector (make sure it is long enough!)> C_in <- c(" ")

Page 14: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

14

R-C/C++ programming

.C() interface

> # execute C function> out <- .C("exampleC2", + C_out = as.character(C_in), + A_out = as.numeric(A_in), + B_out = as.numeric(B_in), + ierr_out = as.integer(ierr_in))

Page 15: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

15

R-C/C++ programming

.C() interface

> out$C_out[1] "OK "

$A_out[1] 2 3 6

$B_out[1] 0.2857143 0.4285714 0.8571429

$ierr_out[1] 0

Page 16: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

16

R-C/C++ programming

.C() interface

> # create input vector> A_in <- c(0, 0, 0)

> # execute C function> out <- .C("exampleC2", "exampleC2", + C_out = as.character(C_in), + A_out = as.numeric(A_in), + B_out = as.numeric(B_in), + ierr_out = as.integer(ierr_in))

Page 17: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

17

R-C/C++ programming

.C() interface

> out$C_out[1] "error "

$A_out[1] 0 0 0

$B_out[1] 0 0 0

$ierr_out[1] -1

Page 18: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

18

R-C/C++ programming

.C() interface

Note:To compile more than one C file:

R CMD SHLIB file1.c file2.c file3.c

The resulting file will be named file1.so

Page 19: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

19

R-C/C++ programming

.Call() interface

does not copy arguments before and after calling c-

function

it is possible to find the length of the input vector inside c-

function

an easier access to wide-range of R – objects

NA (missing values) handling

Access to vectors’ attributes

Page 20: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

20

R-C/C++ programming

.Call() interface – passing a value/* exC3.c – example C function to be called from R with .Call interface*//* access R object (scalar value) inside c-function */include <R.h> /* 2 standard includes for .Call interface) */include <Rdefines.h> SEXP exampleC3 ( SEXP iValue ){

return (R_NilValue); /* “void” function must return “NULL” value */}

exC3.c

Note:• All objects passed between R and C/C++ are of type SEXP – Simple

EXPression.• 2 standard includes needed for .Call interface• If function is void it should return R_NilValue object.

Page 21: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

21

R-C/C++ programming

.Call() interface – passing a value/* exC3.c – example C function to be called from R with .Call interface*//* access R object (scalar value) inside c-function */include <R.h>include <Rdefines.h> SEXP exampleC3 ( SEXP iValue ){

int local_iValue;

/* convert R object to c-accessible variable */ local_iValue = INTEGER_VALUE(iValue);

return (R_NilValue); }

exC3.c

Page 22: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

22

R-C/C++ programming

.Call() interface – passing a value/* exC3.c – example C function to be called from R with .Call interface*//* access R object (scalar value) inside c-function */include <R.h>include <Rdefines.h> SEXP exampleC3 ( SEXP iValue ){

int local_iValue;

/* convert R object to c-accessible variable */ local_iValue = INTEGER_VALUE(iValue);

/* print value of the local variable*/ printf(" In exampleC3 iValue = %d\n", local_iValue);

return (R_NilValue); }

exC3.c

Page 23: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

23

R-C/C++ programming

.Call() interface – passing a value

> # load C function to R workspace – same as before> dyn.load("exC3.so")

> # call C function> out <-.Call("exampleC3", 7)In exampleC3 iValue = 7

> # explore output> outNULL

Page 24: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

24

R-C/C++ programming

.Call() interface – passing a vector/* exC4.c - example C function to be called from R *//* normalize the vector and return its length */include <R.h> include <Rdefines.h>include <Rmath.h> SEXP exampleC4 ( SEXP Vector ){

SEXP rLen;

return (rLen); /* return a value */}

exC4.c

Note:• Rmath.h include provides access to many R-functions include

rnorm(),rgamma(), etc.• Function should return SEXP object.• .Call() interface allows for changing the function arguments – be careful!

Page 25: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

25

R-C/C++ programming

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen; /* output value – length of a vector */ double * pVector; /* local variable - pointer to the input vector */ double vLen = 0; /* local variable to calculate intermediate values */ int len; /* local variable – size of the input vector */ int i; /* local variable – loop index */

return (rLen); /* return a value */}

exC4.c

Page 26: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

26

R-C/C++ programming

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen; double * pVector; double vLen = 0; int len; int i;

/* get the pointer to the vector */ pVector = NUMERIC_POINTER(Vector);

return (rLen); /* return a value */}

exC4.c

Note: Use INTEGER_POINTER()and CHARACTER_POINTER() to get pointer to integer and character arrays respectfully

Page 27: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

27

R-C/C++ programming

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen; double * pVector; double vLen = 0; int len; int i;

/* get the pointer to the vector */ pVector = NUMERIC_POINTER(Vector);

/* number of elements in the array */ len = length(Vector);

return (rLen); /* return a value */}

exC4.c

Note: We can get the size of the input R-vector !

Page 28: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

28

R-C/C++ programming

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen; double * pVector; double vLen = 0; int len; int i;

pVector = NUMERIC_POINTER(Vector); len = length(Vector);

/* allocate storage for integer variable (array works also!) */ PROTECT(rLen = NEW_NUMERIC(1));

UNPROTECT(1); return (rLen); /* return a value */}

exC4.c

Note: To allocate integer and character arrays use NEW_INTEGER(len)and

NEW_CHARACTER(len) functions respectfully

PROTECT() and UNPROTECT() command must be balanced!

Page 29: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

29

R-C/C++ programming

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen; double * pVector; double vLen = 0; int len; int i;

pVector = NUMERIC_POINTER(Vector); len = length(Vector); PROTECT(rLen = NEW_NUMERIC(1));

/* calculate the length */ for( i=0; i < len; i++)vLen += pow(pVector[i], 2); if ( vLen > 0.000001){ vLen = pow( vLen,0.5 );

/* Here we are working with a pointer - it WILL change R vector */ for( i=0; i < len; i++ )pVector[i] /= vLen; }

/* copy the value of local variable into R-object */ REAL(rLen)[0] = vLen;

UNPROTECT(1); return (rLen); /* return a value */}

exC4.c

Page 30: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

30

R-C/C++ programming

.Call() interface – passing an array

> # load C function to R workspace – same as before> dyn.load("exC4.so")

> # define and input array> A_in <- c( 2, 3, 6)

> # call C function> out <-.Call("exampleC4", A_in)

> # input array changed !!!> A_in[1] 0.2857143 0.4285714 0.8571429

> out[1] 7

Page 31: R – C/C++ programming Katia Oleinik koleinik@bu.edu Scientific  Computing and  Visualization Boston  University

31

This tutorial has been made possible by Scientific Computing and Visualization

groupat Boston University.

Katia [email protected]