0

I am trying to parallelize for cycle computing fitness value of individuals. For this whole algorithm I am using Rcpp, but fitness function is passed from R.

So I am trying to do something like this:

#pragma omp parallel for
  for (int i = 0; i < population.size(); i++)
  {
    population[i].computeFitness(FitnessFunction);
  }

Where FitnessFunction is Rcpp::Function and computeFitness is just class function essentially assigning computed value to member variable.

void computeFitness(Rcpp::Function optFunction)
  {
    this->_fitness = Rcpp::as<double>(optFunction(this->_coords));
  }

But this crashes, because, as I now know, R is single-threaded and I cannot use any underlying R instances in parallel sections.

So is there any way to convert Rcpp::Function to either std::function, functor or something similar? Is there any other way to pass a function from R to Rcpp, that would allow me to parallelize computation of this fitness value?

This whole work is for creating parallel optimization package of Moth Search Algoritm for CRAN.

Basically same code in c++ with std::function works well. Rcpp code works fine without it being parallel.

P. Soltes
  • 38
  • 7
  • Where does the `Rcpp::Function` come from? You can’t make it thread save if it is an R function. You might use `Xptr` if it is a C++ function you wrapped for transport. – Ralf Stubner Feb 23 '19 at 15:21
  • It is function, which my code is supposed to optimize. Supplied by user from R. But it seems that this problem will be impossible to solve in Rcpp. Unless I will force user to use c++. So it seems I will either rewrite it in R with parallel sections or keep it single-threaded in Rcpp and will see what runs faster. – P. Soltes Feb 23 '19 at 16:31
  • 1
    You can use Rcpp::Function if you parallelise at the R level, since you than have multiple R processes to interact with. – Ralf Stubner Feb 23 '19 at 16:56
  • 1
    Fair point, though it still runs at R speed ... – Dirk Eddelbuettel Feb 23 '19 at 19:30

1 Answers1

2

Are you aware that Rcpp::Function() just calls an R function, and hence

  1. violates the principle you state of using the underlying R instance in (OpenMP or pthread) parallel code and
  2. of course also only runs at R speed as an R function?

You can achieve the parallel calling of R code more easily at the R level.

And if you want C++ speed in parallel you need to write C++ code that can be called in parallel -- see for example the RcppParallel package and its vignettet for introductory examples.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • Yes i am aware, that is why i am looking for way to transform that function into c++ function. Problem is that i am writing optimization package where that optimization function is supplied by user of said package in R, so i can't just rewrite it in c++ as it will be different every time. Similiar approach is used in ABCOptim CRAN package, but that package is not parallel. – P. Soltes Feb 23 '19 at 16:28
  • I will either rewrite it parallelly in R or leave it single-threaded in Rcpp, see what is faster. Because it seems only other solution is to force user to write optimization function in c++. – P. Soltes Feb 23 '19 at 16:48
  • 1
    FWIW RcppDE is an optimization framework where I allow such an import of user-supplied C++ function. – Dirk Eddelbuettel Feb 23 '19 at 16:53
  • Do you mind if i take concept from your RcppDE, slightly alter it and use it in my package? I would, of course, cite your help in both code and documentation. – P. Soltes Feb 24 '19 at 18:56
  • Of course not -- it's all GPL for a reason. I had been meaningto get back to RcppDE to add the OpenMP angle but somehow it never happened -- I got hung up on trying to get the same RNG stream in serial and parallel mode, and that may be a bit too much to ask. – Dirk Eddelbuettel Feb 24 '19 at 19:06