我正在尝试将Rcpp module
与doParallel
一起使用。但是,似乎它们不兼容。这是一个会产生段错误的例子。我已尝试使用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
答案 0 :(得分:3)
没有'Rcpp引用类'这样的东西。
您正在通过内联编译本地扩展,然后将其(及其内存位置)发送给工作人员。这是行不通的,并且已知无法工作 - 他们将访问一些随机内存内容。
对于这种方式的并行工作,您需要由每个工作者构建扩展 - 这就是为什么一般建议总是是使用包,并让每个工作者加载包。