使用doParallel与Rcpp模块时的Segfault

时间:2014-03-08 04:49:17

标签: r rcpp

我正在尝试将Rcpp moduledoParallel一起使用。但是,似乎它们不兼容。这是一个会产生段错误的例子。我已尝试使用R built-in reference class进行类似的操作,但效果很好。

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

在Dirk的评论之后,我尝试使用带有doParallel的Package,但我仍然遇到了段错误。

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
}

仅供参考,普通的Reference类与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

1 个答案:

答案 0 :(得分:3)

没有'Rcpp引用类'这样的东西。

您正在通过内联编译本地扩展,然后将其(及其内存位置)发送给工作人员。这是行不通的,并且已知无法工作 - 他们将访问一些随机内存内容。

对于这种方式的并行工作,您需要由每个工作者构建扩展 - 这就是为什么一般建议总是是使用包,并让每个工作者加载包。