让我先说一下,我已经阅读了写R扩展,Rcpp包的小介绍,并且我已经从Rcpp.package.skeleton()
构建了一个包。
自从构建我的包以来,我添加了一个函数multiGenerateCSVrow()
,然后在R CMD build/R CMD install之前在包目录上运行compileAttributes()
。在我加载我的包之后,我可以直接或通过%do%
方法的foreach()
运行我的函数。
当我尝试并行运行,然而,我得到一个错误:
cl <- makePSOCKcluster(8)
registerDoParallel(cl)
rows <- foreach(i=1:8,.combine=rbind,.packages="myPackage") %dopar% multiGenerateCSVrow(scoreMatrix=NIsample,
validMatrix = matrix(1,nrow=10,ncol=10),
cutoffVector = rep(0,10),
factorVector = randomsCutPlus1[i,],
actualVector = rep(1,10),
scaleSample = 1)
stopCluster(cl)
~
Error in multiGenerateCSVrow(scoreMatrix = NIsample, validMatrix = matrix(1, :
task 1 failed - "NULL value passed as symbol address"
这是包的命名空间:
# Generated by roxygen2 (4.0.1): do not edit by hand
useDynLib(myPackage)
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
以下是RcppExports.cpp的相关代码块:
// multiGenerateCSVrow
SEXP multiGenerateCSVrow(SEXP scoreMatrix, SEXP validMatrix, SEXP cutoffVector, SEXP factorVector, SEXP actualVector, SEXP scaleSample);
RcppExport SEXP myPackage_multiGenerateCSVrow(SEXP scoreMatrixSEXP, SEXP validMatrixSEXP, SEXP cutoffVectorSEXP, SEXP factorVectorSEXP, SEXP actualVectorSEXP, SEXP scaleSampleSEXP) {
BEGIN_RCPP
SEXP __sexp_result;
{
Rcpp::RNGScope __rngScope;
Rcpp::traits::input_parameter< SEXP >::type scoreMatrix(scoreMatrixSEXP );
Rcpp::traits::input_parameter< SEXP >::type validMatrix(validMatrixSEXP );
Rcpp::traits::input_parameter< SEXP >::type cutoffVector(cutoffVectorSEXP );
Rcpp::traits::input_parameter< SEXP >::type factorVector(factorVectorSEXP );
Rcpp::traits::input_parameter< SEXP >::type actualVector(actualVectorSEXP );
Rcpp::traits::input_parameter< SEXP >::type scaleSample(scaleSampleSEXP );
SEXP __result = multiGenerateCSVrow(scoreMatrix, validMatrix, cutoffVector, factorVector, actualVector, scaleSample);
PROTECT(__sexp_result = Rcpp::wrap(__result));
}
UNPROTECT(1);
return __sexp_result;
END_RCPP
}
和RcppExports。R:
multiGenerateCSVrow <- function(scoreMatrix, validMatrix, cutoffVector, factorVector, actualVector, scaleSample) {
.Call('myPackage_multiGenerateCSVrow', PACKAGE = 'myPackage', scoreMatrix, validMatrix, cutoffVector, factorVector, actualVector, scaleSample)
}
它可能在寻找什么?
我有一个类似的问题,我通过将.noexport = c(<Functions that were implemented in C++>)
添加到foreach
来解决它。
我猜这些函数从全局环境导入到并行上下文,但是,由于它们不是普通函数,它们实际上不起作用。这确实意味着函数必须在每个节点上单独加载;在我的例子中,这是一个SNOW clusterCall()
调用,它来源于各种文件,包括c++代码。
我还有一个问题,使用Rcpp的函数在foreach中不能工作。正如Patrick McCarthy所建议的那样,我将函数放在一个包中,安装&加载该包,并使用.packages=("…")将其传递给forearch。
我仍然得到一些错误,但这是解决后更新所有涉及的软件包。
(我本来会评论的,但我没有足够的声誉,我认为这可能对一些人有帮助)
灵感来自@henine &@jmb,我尝试了"反向"选项,这是我实际上用我的foreach循环中的Rccp函数源我的R文件,并确保在foreach的.packages选项中包含"Rccp"。可能不是最有效的,但可以完成工作& &;很简单。
类似:
cl = makeCluster(n_cores, outfile="")
registerDoParallel(cl)
foreach(n = 1:N,.packages = "Rcpp",.noexport = "<name of Rccp function>")%dopar%{
source("Scripts/Rccp_functions.R")
### do stuff with functions scripted in Rccp_functions.R
}
stopImplicitCluster()
与@jmb类似,我也会评论,但没有足够的声誉:D
我以前遇到过这个问题,我的解决方案是:
在函数内(用于运行循环),写入
library(Rcpp)
sourceRcpp('<the path to your cpp file>')
,然后调用该函数。