Introduction to Calling C and Fortran from R In UNIX.

Slides:



Advertisements
Similar presentations
Introduction to C Programming
Advertisements

Calling C code from R an introduction Sigal Blay Dept. of Statistics and Actuarial Science Simon Fraser University October 2004.
C Programming lecture 2 Beautiful programs Greek algorithms
C++ crash course Class 10 practice problems. Pointers The following function is trying to swap the contents of two variables. Why isnt it working? void.
Overview of programming in C C is a fast, efficient, flexible programming language Paradigm: C is procedural (like Fortran, Pascal), not object oriented.
An introduction to pointers in c
R – C/C++ programming Katia Oleinik Scientific Computing and Visualization Boston University
The C ++ Language BY Shery khan. The C++ Language Bjarne Stroupstrup, the language’s creator C++ was designed to provide Simula’s facilities for program.
CSCI 6962: Server-side Design and Programming Input Validation and Error Handling.
What is a pointer? First of all, it is a variable, just like other variables you studied So it has type, storage etc. Difference: it can only store the.
Chapter 7: User-Defined Functions II
Chapter 7:: Data Types Programming Language Pragmatics
C Programming - Lecture 5
Kernighan/Ritchie: Kelley/Pohl:
1 1 Lecture 4 Structure – Array, Records and Alignment Memory- How to allocate memory to speed up operation Structure – Array, Records and Alignment Memory-
Starting out with C++1 Chapter 9 – Pointers Getting the address of a Variable Why do we have pointers? Indirection – difference between –Will you go out.
1 Chapter 2 Introductory Programs. 2 Getting started To create and run a Java program –Create a text file with a.java extension for the source code. For.
CS 61C L03 C Arrays (1) A Carle, Summer 2005 © UCB inst.eecs.berkeley.edu/~cs61c/su05 CS61C : Machine Structures Lecture #3: C Pointers & Arrays
Structured Data Types and Encapsulation Mechanisms to create new data types: –Structured data Homogeneous: arrays, lists, sets, Non-homogeneous: records.
Arrays. A problem with simple variables One variable holds one value –The value may change over time, but at any given time, a variable holds a single.
C++ / G4MICE Course Session 3 Introduction to Classes Pointers and References Makefiles Standard Template Library.
C++ Programming: Program Design Including Data Structures, Fourth Edition Chapter 13: Pointers, Classes, Virtual Functions, and Abstract Classes.
Pointer Data Type and Pointer Variables
C++ Programming: From Problem Analysis to Program Design, Fourth Edition Chapter 14: Pointers, Classes, Virtual Functions, and Abstract Classes.
Presented by: Mojtaba Khezrian. Agenda Object Creation Object Storage More on Arrays Parameter Passing For Each VarArgs Spring 2014Sharif University of.
1 Further C  Multiple source code file projects  Structs  The preprocessor  Pointers.
C Programming Tutorial – Part I CS Introduction to Operating Systems.
CNG 140 C Programming (Lecture set 9) Spring Chapter 9 Character Strings.
COMP 116: Introduction to Scientific Programming Lecture 28: Data types.
17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.
Introduction to Java Applications Part II. In this chapter you will learn:  Different data types( Primitive data types).  How to declare variables?
CMPSC 16 Problem Solving with Computers I Spring 2014 Instructor: Tevfik Bultan Lecture 12: Pointers continued, C strings.
C++ Programming: From Problem Analysis to Program Design, Second Edition1 Objectives In this chapter you will: Learn about the pointer data type and pointer.
Spring 2005, Gülcihan Özdemir Dağ Lecture 7, Page 1 BIL104E: Introduction to Scientific and Engineering Computing, Spring Lecture 7 Outline 7. 1.
Peyman Dodangeh Sharif University of Technology Fall 2013.
What does C store? >>A = [1 2 3] >>B = [1 1] >>[C,D]=meshgrid(A,B) c) a) d) b)
Dynamic memory allocation and Pointers Lecture 4.
Chapter 12: Pointers, Classes, Virtual Functions, and Abstract Classes.
Pointers: Basics. 2 What is a pointer? First of all, it is a variable, just like other variables you studied  So it has type, storage etc. Difference:
Lecture 6 C++ Programming Arne Kutzner Hanyang University / Seoul Korea.
(6-3) Modular Programming H&K Chapter 6 Instructor - Andrew S. O’Fallon CptS 121 (October 2, 2015) Washington State University.
School of Computer Science & Information Technology G6DICP - Lecture 4 Variables, data types & decision making.
Pointers *, &, array similarities, functions, sizeof.
Computer Organization and Design Pointers, Arrays and Strings in C Montek Singh Sep 18, 2015 Lab 5 supplement.
CSI 3125, Preliminaries, page 1 Data Type, Variables.
 2008 Pearson Education, Inc. All rights reserved. 1 Arrays and Vectors.
Chapter 8 Arrays. A First Book of ANSI C, Fourth Edition2 Introduction Atomic variable: variable whose value cannot be further subdivided into a built-in.
Pointers in C++. Topics Covered  Introduction to Pointers  Pointers and arrays  Character Pointers, Arrays and Strings  Examples.
Announcements Assignment 1 due Wednesday at 11:59PM Quiz 1 on Thursday 1.
C++ Programming Lecture 14 Arrays – Part I The Hashemite University Computer Engineering Department (Adapted from the textbook slides)
C Tutorial - Pointers CS 537 – Introduction to Operating Systems.
Pointers: Basics. 2 Address vs. Value Each memory cell has an address associated with it
You learned how to declare pointer variables how to store the address of a variable into a pointer variable of the same type as the variable how to manipulate.
Data Structures & Algorithms CHAPTER 2 Arrays Ms. Manal Al-Asmari.
Lecture 11: Pointers B Burlingame 13 Apr Announcements Rest of semester  Homework Remaining homework can be done in pairs, turn in one paper with.
Computer Organization and Design Pointers, Arrays and Strings in C
Chapter 2 Overview of C.
Quiz 11/15/16 – C functions, arrays and strings
C Basics.
Arrays in C.
Subroutines Idea: useful code can be saved and re-used, with different data values Example: Our function to find the largest element of an array might.
Your questions from last session
C++ Pointers and Strings
Java Programming Language
Chapter 9: Pointers and String
Chapter 9: Pointers and String
C++ Pointers and Strings
ENERGY 211 / CME 211 Lecture 29 December 3, 2008.
SPL – PS2 C++ Memory Handling.
Presentation transcript:

Introduction to Calling C and Fortran from R In UNIX

Why Call C or Fortran from R? R is rotten at iterative algorithms that require loops iterated many times (especially Markov chain Monte Carlo), not as bad as S-PLUS, but still bad. A way to get all the speed advantages of C or Fortran with most of the convenience of R is to write the inner loop in C and call it from R.

C functions and Fortran subroutines callable from R C functions: void foo(long *nin, double *x) { int n = nin[0]; int i; for (i=0; i<n; i++) x[i] = x[i] * x[i]; }

two properties that are required for a function callable from R The function does not return a value. All work is accomplished as a "side effect" (changing the values of arguments). All the arguments are pointers. Even scalars are vectors (of length one) in R.

Fortran subroutines subroutine bar(n, x) integer n double precision x(n) integer I do 100 i = 1, n x(i) = x(i) ** continue end

Compiling and Dynamic Loading compile it to a shared library. The command R CMD SHLIB foo.c Now the code can be dynamically loaded into R by doing (in R) dyn.load("foo.so")

The Call to C The actual call to C from R is made by the R function.C like this.C("foo", n=as.integer(5),x=as.double(rnorm(5)))

The function.C takes nargs + 1 arguments if the C function being called takes nargs arguments. The first argument is the name of the C function to be called. the rest are the arguments to the function call. The arguments generally have to be coerced to the proper type using as.integer, as.double, and similar functions. The function.C returns a list whose elements are the arguments to the function call (in this case n and x). The values are the values after the call (as changed by the function foo).

The Fortran is similar. In UNIX do R CMD SHLIB bar.f and in R do dyn.load("bar.so").Fortran("bar", n=as.integer(5), x=as.double(rnorm(5))) We just change the call from.C to.Fortran

R Wrapper Functions foo <- function(x) { if (!is.numeric(x)) stop("argument x must be numeric") out <-.C("foo", n=as.integer(length(x)), x=as.double(x)) return(out$x) }

R Wrapper Functions has three benefits It allows some error checking in R, where it is easier than in C. It allows some arguments (like n here) to be calculated so they don't have to be supplied by the user. It allows you to return only what the user needs. Now the call is much simpler, just foo(x)

Using R Random Number Generators The R random number generators and also all the other functions for probability distributions (not only rnorm but also dnorm, pnorm, and qnorm and so forth for other distributions) are callable from C (but not Fortran).

example #include void baz(int *nin, double *sin, double *tin, double *x) { int n = nin[0]; double s = sin[0]; double t = tin[0]; int i; GetRNGstate(); for (i = 0; i < n; i++) x[i] = rbeta(s, t); PutRNGstate(); } GetRNGstate(); PutRNGstate(); must be done before and after (respectively) all calls to random number functions (in this example rbeta).

set.seed(42) rbeta(5, 1.5, 2.5) dyn.load("baz.so") baz <- function(n, s, t) {.C("baz", n = as.integer(n), s = as.double(s), t = as.double(t), x = double(n))$x } set.seed(42) baz(5, 1.5, 2.5)

Error Messages from C Use the R error or warning function. They work just like printf but produce an R error or warning as the case may be. Here is an example. #include void qux(int *nin, double *x) { int n = nin[0]; int i; if (n < 1) error("arg n was %d, must be positive\n", n); for (i = 0; i < n; i++) x[i] = x[i] * x[i]; } And try it out. dyn.load("qux.so").C("qux", n = as.integer(0), x = as.double(1:4))

Motivation: Speed Efficient memory management Using existing C libraries

The following functions provide a standard interface to compiled code that has been linked into R:.C.Call

We will explore using.C and.Call with several code examples: Using.C I. Calling C with an integer vector II. Calling C with different vector types Using.Call III. Sending R integer vectors to C IV. Sending R character vectors to C V. Getting an integer vector from C VI. Getting a character vector from C VII. Getting a list from C

I. Calling C with an integer vector using.C

/* useC1.c */ void useC(int *i) { i[0] = 11; } The C function should be of type void. The compiled code should not return anything except through its arguments.

To compile the c code, type at the command prompt: R CMD SHLIB useC1.c The compiled code file name is useC1.so

In R: > dyn.load("useC1.so") > a <- 1:10 # integer vector > a [1] > out <-.C("useC", b = as.integer(a)) > a [1] > out$b [1]

You have to 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.C argument is given the name b. This name is used for the respective component in the returned list object (but not passed to the compiled code).

II. Calling C with different vector types using.C

/* useC2.c */ void useC(int *i, double *d, char **c, int *l) { i[0] = 11; d[0] = 2.333; c[1] = "g"; l[0] = 0; }

To compile the c code, type at the command prompt: R CMD SHLIB useC2.c to get useC2.so To compile more than one c file: R CMD SHLIB file1.c file2.c file3.c to get file1.so

In R: > dyn.load("useC2.so") > i <- 1:10 # integer vector > d <- seq(length=3,from=1,to=2) # real number vector > c <- c("a", "b", "c") # string vector > l <- c("TRUE", "FALSE") # logical vector > i [1] > d [1] > c [1] "a" "b" "c" > l [1] "TRUE" "FALSE"

> out <-.C("useC", i1 = as.integer(a), d1 = as.numeric(d), c1 = as.character(c), l1 = as.logical(l)) > out $i1 [1] $d1 [1] $c1 [1] "a" "g" "c“ $l1 [1] FALSE FALSE

III. Sending R integer vectors to C using.Call

/* useCall1.c */ #include SEXP getInt(SEXP myint, SEXP myintVar) { int Imyint, n; // declare an integer variable int *Pmyint; // pointer to an integer vector PROTECT(myint = AS_INTEGER(myint));

Rdefines.h is somewhat more higher level then Rinternal.h, and is preferred if the code might be shared with S at any stage. SEXP stands for Simple EXPression myint is of type SEXP, which is a general type, hence coercion is needed to the right type. R objects created in the C code have to be reported using the PROTECT macro on a pointer to the object. This tells R that the object is in use so it is not destroyed.

Imyint = INTEGER_POINTER(myint)[0]; Pmyint = INTEGER_POINTER(myint); n = INTEGER_VALUE(myintVar); printf(“ Printed from C: \n“); printf(“ Imyint: %d \n", Imyint); printf(“ n: %d \n", n); printf(“ Pmyint[0], Pmyint[1]: %d %d \n", Pmyint[0], Pmyint[1]); UNPROTECT(1); return(R_NilValue); }

The protection mechanism is stack- based, so UNPROTECT(n) unprotects the last n objects which were protected. The calls to PROTECT and UNPROTECT must balance when the user's code returns. to work with real numbers, replace int with double and INTEGER with NUMERIC

In R: > dyn.load("useCall1.so") > myint<- c(1,2,3) > out<-.Call("getInt", myint, 5) Printed from C: Imyint: 1 n: 5 Pmyint[0], Pmyint[1]: 1 2 > out NULL

IV. Reading an R character vector from C using.Call

/* useCall2.c */ #include SEXP getChar(SEXP mychar) { char *Pmychar[5]; // array of 5 pointers // to character strings PROTECT(mychar = AS_CHARACTER(mychar));

// allocate memory: Pmychar[0] = R_alloc(strlen(CHAR(STRING_ELT(mychar, 0))), sizeof(char)); Pmychar[1] = R_alloc(strlen(CHAR(STRING_ELT(mychar, 1))), sizeof(char)); //... and copy mychar to Pmychar: strcpy(Pmychar[0], CHAR(STRING_ELT(mychar, 0))); strcpy(Pmychar[1], CHAR(STRING_ELT(mychar, 1))); printf(“ Printed from C:”); printf(“ %s %s \n",Pmychar[0],Pmychar[1]); UNPROTECT(1); return(R_NilValue); }

In R: > dyn.load("useCall2.so") > mychar <- c("do","re","mi", "fa", "so") > out <-.Call("getChar", mychar) Printed from C: do re

V. Getting an integer vector from C using.Call

/* useCall3.c */ #include SEXP setInt() { SEXP myint; int *p_myint; int len = 5; // Allocating storage space: PROTECT(myint = NEW_INTEGER(len));

p_myint = INTEGER_POINTER(myint); p_myint[0] = 7; UNPROTECT(1); return myint; } // to work with real numbers, replace // int with double and INTEGER with NUMERIC

In R: > dyn.load("useCall3.so") > out<-.Call("setInt") > out [1]

VI. Getting a character vector from C using.Call

/* useCall4.c */ #include SEXP setChar() { SEXP mychar; PROTECT(mychar = allocVector(STRSXP, 5)); SET_STRING_ELT(mychar, 0, mkChar("A")); UNPROTECT(1); return mychar; }

In R: > dyn.load("useCall4.so") > out <-.Call("setChar") > out [1] "A" "" "" "" ""

VII. Getting a list from C using.Call

/* useCall5.c */ #include SEXP setList() { int *p_myint, i; double *p_double; SEXP mydouble, myint, list, list_names; char *names[2] = {"integer", "numeric"};

// creating an integer vector: PROTECT(myint = NEW_INTEGER(5)); p_myint = INTEGER_POINTER(myint); //... and a vector of real numbers: PROTECT(mydouble = NEW_NUMERIC(5)); p_double = NUMERIC_POINTER(mydouble); for(i = 0; i < 5; i++) { p_double[i] = 1/(double)(i + 1); p_myint[i] = i + 1; }

// Creating a character string vector // of the "names" attribute of the // objects in out list: PROTECT(list_names = allocVector(STRSXP,2)); for(i = 0; i < 2; i++) SET_STRING_ELT(list_names,i,mkChar(names[i]));

// Creating a list with 2 vector elements: PROTECT(list = allocVector(VECSXP, 2)); // attaching myint vector to list: SET_VECTOR_ELT(list, 0, myint); // attaching mydouble vector to list: SET_VECTOR_ELT(list, 1, mydouble); // and attaching the vector names: setAttrib(list, R_NamesSymbol, list_names); UNPROTECT(4); return list; } SET_VECTOR_ELT stands for Set Vector Element

In R: > dyn.load("useCall5.so") > out <-.Call("setList") > out $integer [1] $numeric [1]