R – C/C++ programming
This presentation is the property of its rightful owner.
Sponsored Links
1 / 31

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


  • 73 Views
  • Uploaded on
  • Presentation posted in: General

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

Download Presentation

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

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


R c c programming katia oleinik koleinik bu edu scientific computing and visualization boston university

R – C/C++ programmingKatia [email protected] Computing and VisualizationBoston University

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


R c c programming

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


R c c programming1

R-C/C++ programming

.C() interface

exC1.c

/* exC1.c – example C function to be called from R */

void exampleC1(int *iVec){

iVec[0] = 7;

return;

}

Important:

Function returns no values – it is VOID

All the values that need to be changed/returned by a function must be passed through its arguments.


R c c programming2

R-C/C++ programming

.C() interface

katana:~ % R CMD SHLIB exC1.c

gcc -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.o

gcc -std=gnu99 -shared -L/usr/local/lib64 -o exC1.so exC1.o

katana:~ %

Important:

In linux (and R) environment commands are case sensitive!


R c c programming3

R-C/C++ programming

.C() interface

># load C function to R workspace

> dyn.load("exC1.so")

>

Note:

In windows after the function is compiled it will be named exC1.dll


R c c programming4

R-C/C++ programming

.C() interface

># load C function to R workspace

> dyn.load("exC1.so")

> # create a vector

> iv <- 1:3


R c c programming5

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))


R c c programming6

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


R c c programming7

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.


R c c programming8

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 type

R copies its arguments prior to passing them to C and then creates a copy of the values passed back from C.


R c c programming9

R-C/C++ programming

exC2.c

/* 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 */

inti;

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;

}


R c c programming10

R-C/C++ programming

.C() interface

katana:~ % R CMD SHLIB exC2.c

gcc -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.o

gcc -std=gnu99 -shared -L/usr/local/lib64 -o exC2.so exC2.o


R c c programming11

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("")


R c c programming12

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))


R c c programming13

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


R c c programming14

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))


R c c programming15

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


R c c programming16

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


R c c programming17

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


R c c programming18

R-C/C++ programming

.Call() interface – passing a value

exC3.c

/* 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 ( SEXPiValue ){

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

}

  • Note:

  • All objects passed between R and C/C++ are of type SEXP – SimpleEXPression.

  • 2 standard includes needed for .Call interface

  • If function is void it should return R_NilValue object.


R c c programming19

R-C/C++ programming

.Call() interface – passing a value

exC3.c

/* 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 ( SEXPiValue ){

intlocal_iValue;

/* convert R object to c-accessible variable */

local_iValue= INTEGER_VALUE(iValue);

return (R_NilValue);

}


R c c programming20

R-C/C++ programming

.Call() interface – passing a value

exC3.c

/* 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 ( SEXPiValue ){

intlocal_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);

}


R c c programming21

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

> out

NULL


R c c programming22

R-C/C++ programming

.Call() interface – passing a vector

exC4.c

/* 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 */

}

  • 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!


R c c programming23

R-C/C++ programming

exC4.c

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 */

intlen; /* local variable – size of the input vector */

inti; /* local variable – loop index */

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

}


R c c programming24

R-C/C++ programming

exC4.c

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen;

double * pVector; double vLen = 0; intlen; inti;

/* get the pointer to the vector */

pVector=NUMERIC_POINTER(Vector);

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

}

Note:

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


R c c programming25

R-C/C++ programming

exC4.c

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen;

double * pVector; double vLen = 0; intlen; inti;

/* get the pointer to the vector */

pVector=NUMERIC_POINTER(Vector);

/* number of elements in the array */

len = length(Vector);

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

}

Note:

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


R c c programming26

R-C/C++ programming

exC4.c

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen;

double * pVector; double vLen = 0; intlen; inti;

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 */

}

  • Note:

  • To allocate integer and character arrays use NEW_INTEGER(len)and NEW_CHARACTER(len) functions respectfully

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


R c c programming27

R-C/C++ programming

exC4.c

SEXP exampleC4 ( SEXP Vector ){

SEXP rLen;

double * pVector; double vLen = 0; intlen; inti;

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 */

}


R c c programming28

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


R c c programming katia oleinik koleinik bu edu scientific computing and visualization boston university

This tutorial has been made possible by

Scientific Computing and Visualization

group

at Boston University.

Katia [email protected]


  • Login