Reputation: 3184
I am trying to use Rcpp module
with doParallel
. However, it seems that they are not compatible. This is a example would produce segfault. I have tried similar thing with the R built-in reference class
and it works fine.
require(doParallel)
require(Rcpp)
require(inline)
inc = '
using namespace Rcpp; class Uniform { public:
Uniform(double min_, double max_) : min(min_), max(max_) {}
NumericVector draw(int n) const {
RNGScope scope;
return runif( n, min, max ); }
double min, max;
};
double uniformRange( Uniform* w) { return w->max - w->min;
}
RCPP_MODULE(unif_module) {
class_<Uniform>( "Uniform" )
.constructor<double,double>()
.field( "min", &Uniform::min )
.field( "max", &Uniform::max )
.method( "draw", &Uniform::draw )
.method( "range", &uniformRange )
;
}
'
fx <- cxxfunction(signature(), plugin="Rcpp", include=inc)
unif_module <- Module("unif_module", getDynLib(fx))
Uniform <- unif_module$Uniform
registerDoParallel(2)
myObjs = foreach(i=1:2) %dopar% {
u <- new( Uniform, 0, 10 )
u$draw( 10L )
u
}
myObjs
Followed by the comment of Dirk, I tried to use Package with doParallel, but I still get segfault.
library(Rcpp)
require(doParallel)
Rcpp.package.skeleton( "MyPackage", module = TRUE )
install.packages("MyPackage", repos=NULL)
library(MyPackage)
NumEx = Module("NumEx", PACKAGE="MyPackage")
Num = NumEx$Num
registerDoParallel(2)
foreach(i=1:2) %dopar% {
obj = new(Num)
obj
}
FYI, the ordinary Reference class works flewlessly with doParallel.
require(doParallel)
myClass = setRefClass("myClass",
fields = c("a"),
methods = list(
show = function(){cat("hello\n")}
)
)
registerDoParallel(2)
objs = foreach(i=1:2) %dopar% {
obj = new("myClass")
obj$a=i
obj
}
objs[[1]]$a
Upvotes: 0
Views: 627
Reputation: 368261
There is no such thing as a 'Rcpp reference class'.
You are compiling a local extension via inline, and then shipping that (with its memory location) to the workers. That can't work and is known not to work -- they will access some random memory content.
For parallel work in this fashion, you need to build the extension by each worker --- which is why the general recommendation always is to use a package, and have each worker load the package.
Upvotes: 3