4

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.

Gumeo
  • 891
  • 1
  • 13
  • 26
  • 6
    Maybe take a look at Rcpp ? http://cran.r-project.org/web/packages/Rcpp/index.html – juba Oct 10 '13 at 11:12
  • Can't just system("R Stuff"); from c++? It's similar to this one : [C call cmd command](http://stackoverflow.com/questions/5007268/call-linux-command-from-c-program) [R example](http://stackoverflow.com/questions/18306362/run-r-script-from-command-line) – alap Oct 10 '13 at 11:17
  • pipes looks as probable solution, or maybe tcp server ? – 4pie0 Oct 10 '13 at 11:21
  • Do you know of any examples where this is done with Rcpp? Or just any short examples of cimmunication between R and C++ processes? Found [this](http://dirk.eddelbuettel.com/code/rcpp.examples.html), might help! – Gumeo Oct 10 '13 at 11:36
  • Would it be possible to load the data into R and just pass a pointer to the data to the C++ function, or would that require too much reworking of the code? – mrip Oct 10 '13 at 11:54
  • 2
    I find the question confused, and editing may help. *Either* you have a main C++ function in which you need some R functionality---which [RInside](http://dirk.eddelbuettel.com/code/rinside.html) is made for---*or* you have C++ code you want to call from R---which [Rcpp](http://dirk.eddelbuettel.com/code/rcpp.html) makes easy. Either way, the Rcpp code is used to make data transfer easy. And in either case, it *is the same process* so `pipe()` et al are not appropriate. Unless you do something more complicated than you would want to. – Dirk Eddelbuettel Oct 10 '13 at 12:06
  • Also, it would be helpful if you could post the R code you are using to make the external `.C()` call. – mrip Oct 10 '13 at 12:11
  • I have a main C++ function but the main function is really simple, I think I can use modules from Rcpp to figure this out. – Gumeo Oct 11 '13 at 09:18
  • You don't have to use modules. You can also write a simple class, and use Rcpp attributes to access a few members init, get, set, ... etc. Modules automates this, but if you're new to Rcpp it adds another layer which may find confusing. There are in fact different options. – Dirk Eddelbuettel Oct 11 '13 at 14:47

2 Answers2

7

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
Romain Francois
  • 17,432
  • 3
  • 51
  • 77
  • Thank you very much for your response, I think I can definitely work this out by creating a module like this! – Gumeo Oct 11 '13 at 09:12
1

There are several questions here.

What is the best way to call C++ code from R?

As other commenters have pointed out, the Rcpp package provides the nicest interface. Using the .Call function from base R is also possible, but not recommended as nice as Rcpp.

How do I stop repeatedly passing data back and forth between R and C++?

You'll just just to restructure your code a little bit. Rewrite a wrapper routine in C++ that calls all the existing C++ routines, and call that from R.

Richie Cotton
  • 118,240
  • 47
  • 247
  • 360
  • 1
    The `.Call()` function *is required* as the `.C()` interface is limited, error-prone and should not be be used -- see eg Simon Urbanek on r-devel a few months back. – Dirk Eddelbuettel Oct 10 '13 at 12:05
  • @DirkEddelbuettel Can you elaborate on why `.C()` is error-prone, or post a link to the r-devel message from Simon Urbanek? – mrip Oct 10 '13 at 12:08
  • 2
    @mrip: Here you go. [R Core member Simon Urbanek on r-devel](http://article.gmane.org/gmane.comp.lang.r.devel/31175): _"As usual, I can only say don't use .C()"_ I got the date wrong: this was already in 2012 -- time flies, but some people still think they should use `.C()`. Which is bad enough, but sadly it gets worse when they inflict such bad ideas on others. – Dirk Eddelbuettel Oct 10 '13 at 13:51
  • Thanks. The reason I ask is that I have some C code that I call with `.C()`, and I haven't noticed any problems. I don't think it's all that bad -- it's a very simple C interface. – mrip Oct 10 '13 at 15:07