What is a thread safe way to throw an error while using Rcpp

Viewed 136

I am using RcppThread for parallelism in an Rcpp function. What is the preferred way to throw an error in the middle of a parallel loop? R's API is single threaded, so I assume Rcpp::stop() is not thread safe. RcppThread provides means for thread safe cout and CheckUserInterrupt but not, so far as I can tell, a thread safe stop.

An example of what I'm trying to do:

#include <RcppThread.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(RcppThread)]]

void myfun() {

  // parallel loop
  RcppThread::parallelFor(0, 100, [](int j){
    // do something that causes an error
    Rcpp::stop("Is this error unsafe?");
  });

}
2 Answers

Probably not -- The simple and often repeated rule stated eg in the RcppParallel documentation is that no contact whatsoever should be made from multithreaded code back into to R, or with R-created/owned memory.

From the top of my head, I would just

  • break from the parallel loop
  • assign the error condition or text to a string
  • once back in single-threaded code call Rcpp::stop(thattext)

The answer from Thomas Nagler from RcppThread's GitHub:

You can use the native C++ throw std::runtime_error() and it will be cached until the threads sync back with the main pool. Then the error is pushed to the main thread where it's handled by Rcpp as a standard runtime error and pushed to R.

So:

#include <RcppThread.h>
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::depends(RcppThread)]]

void myfun() {

  // parallel loop
  RcppThread::parallelFor(0, 100, [](int j){
    // do something that causes an error
    throw std::runtime_error("You did a bad thing");
  });

}
Related