How to generate a R wrapper for a C function that returns an int*? - c

I would like to generate a R (programming language) wrapper for the following C function:
int *test(void)
{
int i;
i = 1024;
return (int *) i;
}
To create this wrapper I am using SWIG with the following interface:
%module X
%{
extern int *test(void);
%}
extern int *test(void);
I can successfully create and compile this wrapper. However, when I run the following R code (the wrapper was loaded beforehand):
print(test())
It will give the following error:
Error in getClass(Class, where = topenv(parent.frame())) :
“_p_int” is not a defined class
Calls: print -> test -> new -> getClass
My question is the following: how can I wrap the C test function (more precisely the int * returned by this function)?

SWIG is not so widely used around R. But the inline package can help you.
R> library(inline)
R> foo <- cfunction(signature(i="int"), body="*i = 1024;",
+ language="C", convention=".C")
R> foo(12)$i
[1] 1024
R>
That said, you probably want .Call() instead of .C(), and you should probably look into Rcpp even if you want to use plain C -- the tooling is pretty rich and useful.

Related

Use C functions in Idris

Idris can compile .idr to C-code (JS, NodeJS). Is it possible to do so in reverse direction - compile C-code to Idris format? Or, maybe, to use C functions direct in Idris code?
Sure! Take a look at the foreign function interface (FFI). Based on your compilation target (f.e. C, JavaScript, …) you can use the native functions like this example call of void *fileOpen(char *path, char *mode) inside the IO monad:
do_fopen : String -> String -> IO Ptr
do_fopen f m
= foreign FFI_C "fileOpen" (String -> String -> IO Ptr) f m

useDynLib() error and compileAttributes returns nothing: embedding a C library into an R package

I have a C package which builds a executable with several argument flags. One compiles the code with a Makefile (I know, this needs to change for the R package) and an executable is created to be run via
$ ./codeName -f path/inputfile -o path/outputfile -p ## -s "type"
My goal is to integrate several of the functions used in this C package to be used with an R library. I take a look at some examples on github.com/cran of R packages using C. In Writing R Extensions, it explains how I could use .Call() and Makevars to call the C functions from R. I would like to avoid that like the plague. However, it looks like this would require significant re-writing with SEXP object--so I turn to Rcpp (yeah!)
I create the package Rcpp.package.skeleton("packageName")
Great. Within R, I do the following:
$ R
> library(devtools)
> build() # works!
> install() # works!
> library(packageName)
> rcpp_hello_world()
## expected output
Everything works. Then I add my C package into /src. I then execute Rcpp::compileAttributes() in the package root directory via R--nothing happens and nothing is output, which is expected, as I haven't changed the C code at all yet.
I try installing with the commands above: devtools::build() and devtools::install(). Via the Makefile, it looks like the C code compiles perfectly! But then there's this issue:
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error in library.dynam(lib, package, package.lib) :
shared object ‘packageName.so’ not found
Error: loading failed
Execution halted'
ERROR: loading failed
Well, that's somewhat confusing, and I don't know why that has occurred, but the snag is the useDynLib("packageName") in the NAMESPACE. If I remove this, the C code appears to compile and the package installs via the build/install commands above. rcpp_hello_world() still works.
(1) Why does this error ‘packageName.so’ not found appear now, and can I get around it?
(This question has nothing to do with Rcpp.)
Then, I go to a .c file. I add
#include <Rcpp.h>
using namespace Rcpp;
to a *.c file and //[[Rcpp::export]] before a function I would like to import. (I'm not sure that's going to work in *.c, or in a C header file.)
Next, I go to the package root directory, open R and try this:
$ R
> library(Rcpp)
> compileAttributes()
That runs without error. However, no RcppExports.R and RcppExports.cpp were generated. Compiling the C code also results in the error that it cannot find #include <Rcpp.h>.
(2) Why would compileAttributes() not function in this environment? I must be incorrectly using Rcpp and //[[Rcpp::export]] in order to wrap these C functions into R-usable format.
What would you call this function? C code?
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
It passes as both C and C++ code. So let's call it C code.
You can clearly interface this from R via Rcpp with the following caller:
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
Stick them all together into a C++ file so that Rcpp can operate on them (see comments) and you are all set.
R> library(Rcpp)
R> sourceCpp("/tmp/ex.cpp")
R> callFib(10)
[1] 55
R>
The complete file is below.
#include <Rcpp.h>
int fib(int n) {
if (n < 2) return n;
return fib(n-1) + fib(n-2);
}
// [[Rcpp::export]]
int callFib(int n) {
return fib(n);
}
/*** R
callFib(10)
*/

What does the "install" function mean in C syntax?

I'm trying to understand the C code called by the R package ucminf. The following code is from the file interface.c found at https://cran.r-project.org/src/contrib/ucminf_1.1-4.tar.gz:
#include <R.h>
#include <Rinternals.h> //R internal structures
#include <R_ext/RS.h> //F77_CALL etc.
// Declare FORTRAN routine for use in C
extern void F77_NAME(ucminf)(int*, double[], double*, double[],
int*,double[],int*,int*,int*,double[],SEXP);
/*-------------------------------------------------------------------------------
Define C functions that calls user defined function in R
*/
void installPar(int nn, double x[], SEXP rho) {
int i;
SEXP PAR = findVarInFrame(rho, install(".x"));
double *xpt = REAL(PAR);
if (LENGTH(PAR) != nn)
error("Dimension mismatch, length(.x) = %d != n = $d", LENGTH(PAR), nn);
for (i = 0; i < nn; i++) xpt[i] = x[i] ;
}
rho is an environment created in R, and it contains the vector .x. My best guess is that the line SEXP PAR = findVarInFrame(rho, install(".x")); is setting PAR equal to .x, but what does the install() command do?
This is such a simple question that I was surprised I couldn't find the answer online - searching for "install c syntax" turned up lots of information about how to install compilers, but I couldn't find anything about the command. Any suggestions for keywords to make my searches more effective would be appreciated.
This code is part of an R extension I think, and therefore the use of install here is a function call to the R C API for Writing Extension. What this does is create the symbol .x in the current symbol table (or return a reference to the existing .x symbol). The linked document does indicate that using install is harmless if the symbol already exists, and is a good way of looking up the symbol if that's what you actually want to do.

Mixed language CUDA programming

What is the way to incorporate CUDA code with Fortran and C code (Mixed language programming). The Fortran code calls a C function which in turn calls the CUDA kernel. For example.
Fortran function:
if(flag.eq.1) call c_func
C function:
void c_func()
{
/* copy data to device
....
cuda_kernel<<< kernel parameters>>>();
/* copy data from device to Host
........
}
What is the way to compile this type of code?
I'm sure there are many possible approaches to this. But following the example you've given, it should be fairly straightforward.
The task can be separated into two pieces:
How to call a C function from Fortran
How to call a CUDA function from C
I think your question probably revolves around the first piece, and as such it is not really CUDA-specific. For the second piece of course there are many examples here on the cuda tag, as well as cuda sample codes and a programming guide.
One method that may help to streamline the first piece is to use the ISO_C_BINDING builtin module which is built into many current fortran distributions. This module defines a number of types which are useful for passing data between C and Fortran.
You can then create an INTERFACE block to define the parameters of your C function that you wish to call from fortran. Here is a worked example:
$ cat cuda_test.f90
!=======================================================================================================================
!Interface to cuda C functions
!=======================================================================================================================
module cuda_test
use iso_c_binding
interface
!
integer(c_int) function cudatestfunc(idata, isize) bind(C, name="cudatestfunc")
use iso_c_binding
implicit none
type(c_ptr),value :: idata
integer(c_int),value :: isize
end function cudatestfunc
!
end interface
end module cuda_test
!=======================================================================================================================
program main
!=======================================================================================================================
use iso_c_binding
use cuda_test
type(c_ptr) :: mydata
integer*4, target :: mysize,myresult
integer*4,dimension(:),allocatable,target :: darray
mysize = 100
allocate(darray(mysize))
darray = (/ (1, I = 1, mysize) /)
mydata = c_loc(darray)
myresult = cudatestfunc(mydata, mysize)
write (*, '(A, I10)') " result: ", myresult
write (*,*)
end program main
$ cat cuda_test.cu
#include <stdio.h>
#define cudaCheckErrors(msg) \
do { \
cudaError_t __err = cudaGetLastError(); \
if (__err != cudaSuccess) { \
fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
msg, cudaGetErrorString(__err), \
__FILE__, __LINE__); \
fprintf(stderr, "*** FAILED - ABORTING\n"); \
exit(1); \
} \
} while (0)
__global__ void testkernel(int *data, int size){
for (int i = 1; i < size; i++) data[0] += data[i];
}
extern "C" {
int cudatestfunc(int *data, int size){
int *d_data;
cudaMalloc(&d_data, size*sizeof(int));
cudaMemcpy(d_data, data, size*sizeof(int), cudaMemcpyHostToDevice);
testkernel<<<1,1>>>(d_data, size);
int result;
cudaMemcpy(&result, d_data, sizeof(int), cudaMemcpyDeviceToHost);
cudaCheckErrors("cuda error");
return result;
}
}
$ gfortran -c cuda_test.f90 -o cuda_testf.o
$ nvcc -c cuda_test.cu -o cuda_testc.o
$ gfortran cuda_testc.o cuda_testf.o -o cuda_test -L/usr/local/cuda/lib64 -lcudart -lstdc++
$ ./cuda_test
result: 100
$
(tested on RHEL 6.2, GNU 4.4.7, CUDA 7.0)
Notes/Other options:
If you only need to call CUDA runtime API functions, you can call those directly from fortran without needing any C/C++ files (if you create your own bindings). Example here.
If you only need to call CUSPARSE or CUBLAS library functions, there are some bindings created for you, that are included with the CUDA distribution. Those bindings by default on linux are installed at /usr/local/cuda/src. A worked example for the cublas bindings is contained in the cublas documentation.
If you need to call other CUDA library functions directly from fortran, it's not terribly difficult to create your own bindings. A worked example is here for a simple set of operations in CUSOLVER.
You can also write CUDA Fortran code directly. (Here is an example.) This requires the CUDA Fortran compiler from PGI.
You can also write OpenACC Fortran code. This requires one of the available OpenACC compilers, such as that from PGI. A PGI free-for-academic use or trial version is available here

R from C -- Simplest Possible Helloworld

What is the simplest possible C function for starting the R interpreter, passing in a small expression (eg, 2+2), and getting out the result? I'm trying to compile with MingW on Windows.
You want to call R from C?
Look at section 8.1 in the Writing R Extensions manual. You should also look into the "tests" directory (download the source package extract it and you'll have the tests directory). A similar question was previously asked on R-Help and here was the example:
#include <Rinternals.h>
#include <Rembedded.h>
SEXP hello() {
return mkString("Hello, world!\n");
}
int main(int argc, char **argv) {
SEXP x;
Rf_initEmbeddedR(argc, argv);
x = hello();
return x == NULL; /* i.e. 0 on success */
}
The simple example from the R manual is like so:
#include <Rembedded.h>
int main(int ac, char **av)
{
/* do some setup */
Rf_initEmbeddedR(argc, argv);
/* do some more setup */
/* submit some code to R, which is done interactively via
run_Rmainloop();
A possible substitute for a pseudo-console is
R_ReplDLLinit();
while(R_ReplDLLdo1() > 0) {
add user actions here if desired
}
*/
Rf_endEmbeddedR(0);
/* final tidying up after R is shutdown */
return 0;
}
Incidentally, you might want to consider using Rinside instead: Dirk provides a nice "hello world" example on the project homepage.
In you're interested in calling C from R, here's my original answer:
This isn't exactly "hello world", but here are some good resources:
Jay Emerson recently gave a talk on R package development at the New York useR group, and he provided some very nice examples of using C from within R. Have a look at the paper from this discussion on his website, starting on page 9. All the related source code is here: http://www.stat.yale.edu/~jay/Rmeetup/MyToolkitWithC/.
The course taught at Harvard by Gopi Goswami in 2005: C-C++-R (in Statistics). This includes extensive examples and source code.
Here you go. It's the main function, but you should be able to adapt it to a more general purpose function. This example builds an R expression from C calls and also from a C string. You're on your own for the compiling on windows, but I've provided compile steps on linux:
/* simple.c */
#include <Rinternals.h>
#include <Rembedded.h>
#include <R_ext/Parse.h>
int
main(int argc, char *argv[])
{
char *localArgs[] = {"R", "--no-save","--silent"};
SEXP e, tmp, ret;
ParseStatus status;
int i;
Rf_initEmbeddedR(3, localArgs);
/* EXAMPLE #1 */
/* Create the R expressions "rnorm(10)" with the R API.*/
PROTECT(e = allocVector(LANGSXP, 2));
tmp = findFun(install("rnorm"), R_GlobalEnv);
SETCAR(e, tmp);
SETCADR(e, ScalarInteger(10));
/* Call it, and store the result in ret */
PROTECT(ret = R_tryEval(e, R_GlobalEnv, NULL));
/* Print out ret */
printf("EXAMPLE #1 Output: ");
for (i=0; i<length(ret); i++){
printf("%f ",REAL(ret)[i]);
}
printf("\n");
UNPROTECT(2);
/* EXAMPLE 2*/
/* Parse and eval the R expression "rnorm(10)" from a string */
PROTECT(tmp = mkString("rnorm(10)"));
PROTECT(e = R_ParseVector(tmp, -1, &status, R_NilValue));
PROTECT(ret = R_tryEval(VECTOR_ELT(e,0), R_GlobalEnv, NULL));
/* And print. */
printf("EXAMPLE #2 Output: ");
for (i=0; i<length(ret); i++){
printf("%f ",REAL(ret)[i]);
}
printf("\n");
UNPROTECT(3);
Rf_endEmbeddedR(0);
return(0);
}
Compile steps:
$ gcc -I/usr/share/R/include/ -c -ggdb simple.c
$ gcc -o simple simple.o -L/usr/lib/R/lib -lR
$ LD_LIBRARY_PATH=/usr/lib/R/lib R_HOME=/usr/lib/R ./simple
EXAMPLE #1 Output: 0.164351 -0.052308 -1.102335 -0.924609 -0.649887 0.605908 0.130604 0.243198 -2.489826 1.353731
EXAMPLE #2 Output: -1.532387 -1.126142 -0.330926 0.672688 -1.150783 -0.848974 1.617413 -0.086969 -1.334659 -0.313699
I don't think any of the above has answered the question - which was to evaluate 2 + 2 ;). To use a string expression would be something like:
#include <Rinternals.h>
#include <R_ext/Parse.h>
#include <Rembedded.h>
int main(int argc, char **argv) {
SEXP x;
ParseStatus status;
const char* expr = "2 + 2";
Rf_initEmbeddedR(argc, argv);
x = R_ParseVector(mkString(expr), 1, &status, R_NilValue);
if (TYPEOF(x) == EXPRSXP) { /* parse returns an expr vector, you want the first */
x = eval(VECTOR_ELT(x, 0), R_GlobalEnv);
PrintValue(x);
}
Rf_endEmbeddedR(0);
return 0;
}
This lacks error checking, obviously, but works:
Z:\>gcc -o e.exe e.c -IC:/PROGRA~1/R/R-213~1.0/include -LC:/PROGRA~1/R/R-213~1.0/bin/i386 -lR
Z:\>R CMD e.exe
[1] 4
(To get the proper commands for your R use R CMD SHLIB e.c which gives you the relevant compiler flags)
You can also construct the expression by hand if it's simple enough - e.g., for rnorm(10) you would use
SEXP rnorm = install("rnorm");
SEXP x = eval(lang2(rnorm, ScalarInteger(10)), R_GlobalEnv);
I think you can't do much better than the inline package (which supports C, C++ and Fortran):
library(inline)
fun <- cfunction(signature(x="ANY"),
body='printf("Hello, world\\n"); return R_NilValue;')
res <- fun(NULL)
which will print 'Hello, World' for you. And you don't even know where / how / when the compiler and linker are invoked. [ The R_NilValue is R's NULL version of a SEXP and the .Call() signature used here requires that you return a SEXP -- see the 'Writing R Extensions' manual which you can't really avoid here. ]
You will then take such code and wrap it in a package. We had great success with using
inline for the
Rcpp unit tests (over 200 and counting now) and some of the examples.
Oh, and this inline example will work on any OS. Even Windoze provided you have the R package building tool chain installed, in the PATH etc pp.
Edit: I misread the question. What you want is essentially what the littler front-end does (using pure C) and what the RInside classes factored-out for C++.
Jeff and I never bothered with porting littler to Windoze, but RInside did work there in most-recent release. So you should be able to poke around the build recipes and create a C-only variant of RInside so that you can feed expression to an embedded R process. I suspect that you still want something like Rcpp for the clue as it gets tedious otherwise.
Edit 2: And as Shane mentions, there are indeed a few examples in the R sources in tests/Embedding/ along with a Makefile.win. Maybe that is the simplest start if you're willing to learn about R internals.

Resources