Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Communication between R and C++

I have a program written in C++ which calculates values for a likelihood function, which relies on lot of data. I want to be able to call the function from R to request function values (the calculations would take to much time in R, and the C++ program is already to long to change it, it's approximately 150K lines of code).

I can do this to request one value, but then the C++ application terminates and I have to restart it and load all the data again, (did this with .c()). The loading takes from 10-30 seconds, depending on the model for the likelihood function and the data, and I was thinking if there is a way to keep the C++ application alive, waiting for requests for function values, so I don't have to read all the data back into memory. Already calculating one function value in the C++ application takes around half a second, which is very long for C++.

I was thinking about using pipe() to do this, and ask you if that is a feasible option or should I use some other method? Is it possible to do this with rcpp?

I'm doing this to test minimizing algorithms for R on this function.

like image 320
Gumeo Avatar asked Feb 16 '23 00:02

Gumeo


1 Answers

Forget about .C. That is clunky. Perhaps using .C over .Call or .External made sense before Rcpp. But now with the work we've put in Rcpp, I really don't see the point of using .C anymore. Just use .Call.

Better still, with attributes (sourceCpp and compileAttributes), you don't even have to see the .Call anymore, it just feels like you are using a c++ function.

Now, if I wanted to do something that preserves states, I'd use a module. For example, your application is this Test class. It has methods do_something and do_something_else and it counts the number of times these methods are used:

#include <Rcpp.h>
using namespace Rcpp ;

class Test {
public:
    Test(): count(0){}

    void do_something(){
        // do whatever
        count++ ;
    }
    void do_something_else(){
        // do whatever
        count++ ;
    }

    int get_count(){
        return count ;
    }

private:
    int count ; 
} ;

This is pretty standard C++ so far. Now, to make this available to R, you create a module like this :

RCPP_MODULE(test){
    class_<Test>( "Test" )
        .constructor()
        .method( "do_something", &Test::do_something )
        .method( "do_something_else", &Test::do_something_else )

        .property( "count", &Test::get_count )
    ;
}

And then you can just use it :

app <- new( Test )
app$count
app$do_something()
app$do_something()
app$do_something_else()
app$count
like image 197
Romain Francois Avatar answered Mar 01 '23 00:03

Romain Francois