Windows 7上的内联函数的doParallel问题(适用于Linux)
我在
Windows 7和
Linux(SUSE Server 11(x86_64))上都使用R 3.0.1.以下示例代码在Windows上产生错误,但在Linux上不产生错误.列出的所有工具箱在两台机器中都是最新的.
Windows错误是: Error in { : task 1 failed - "NULL value passed as symbol address" 如果我将%dopar%更改为%do%,则Windows代码运行时不会出现任何错误.我最初的猜测是,这与Windows中的一些配置问题有关,我尝试重新安装Rcpp和R,但这没有帮助.该错误似乎与作用域有关 – 如果我在f1中定义并编译函数cFunc,那么%dopar%可以工作,但是,正如预期的那样,它非常慢,因为我们为每个任务调用一次编译器. 有没有人对错误发生的原因或如何解决它的建议有一些见解? library(inline) sigFunc <- signature(x="numeric",size_x="numeric") code <- ' double tot =0; for(int k = 0; k < INTEGER(size_x)[0]; k++){ tot += REAL(x)[k]; }; return ScalarReal(tot); ' cFunc <- cxxfunction(sigFunc,code) f1 <- function(){ x <- rnorm(100) a <- cFunc(x=x,size_x=as.integer(length(x))) return(a) } library(foreach) library(doParallel) registerDoParallel() # this produces an error in Windows but not in Linux res <- foreach(counter=(1:100)) %dopar% {f1()} # this works for both Windows and Linux res <- foreach(counter=(1:100)) %do% {f1()} # The following is not a practical solution,but I can compile cFunc inside f1 and then this works in Windows but it is very slow f1 <- function(){ library(inline) sigFunc <- signature(x="numeric",size_x="numeric") code <- ' double tot =0; for(int k = 0; k < INTEGER(size_x)[0]; k++){ tot += REAL(x)[k]; }; return ScalarReal(tot); ' cFunc <- cxxfunction(sigFunc,code) x <- rnorm(100) a <- cFunc(x=x,size_x=as.integer(length(x))) return(a) } # this now works in Windows but is very slow res <- foreach(counter=(1:100)) %dopar% {f1()} 谢谢! 解决方法
错误消息“作为符号地址传递的NULL值”是不常见的,并不是由于函数未导出到worker. cFunc函数在序列化,发送给worker和反序列化后不起作用.当它从已保存的工作空间加载时也不起作用,这会导致相同的错误消息.这并不会让我感到惊讶,它可能是内联包的记录行为.
正如您所演示的那样,您可以通过在worker上创建cFunc来解决问题.为了有效地做到这一点,您只需要对每个工作人员执行一次.要使用doParallel后端执行此操作,我将定义一个worker初始化函数,并使用clusterCall函数在每个worker上执行它: worker.init <- function() { library(inline) sigFunc <- signature(x="numeric",size_x="numeric") code <- ' double tot =0; for(int k = 0; k < INTEGER(size_x)[0]; k++){ tot += REAL(x)[k]; }; return ScalarReal(tot); ' assign('cFunc',cxxfunction(sigFunc,code),.GlobalEnv) NULL } f1 <- function(){ x <- rnorm(100) a <- cFunc(x=x,size_x=as.integer(length(x))) return(a) } library(foreach) library(doParallel) cl <- makePSOCKcluster(3) clusterCall(cl,worker.init) registerDoParallel(cl) res <- foreach(counter=1:100) %dopar% f1() 请注意,必须显式创建PSOCK群集对象才能调用clusterCall. 您的示例在Linux上运行的原因是,在不使用参数调用registerDoParallel时使用mclapply函数,而在Windows上创建集群对象并使用clusterApplyLB函数.使用mclapply时,函数和变量不会被序列化并发送给worker,因此没有错误. 如果doParallel包含对初始化工作者的支持而不需要使用clusterCall会很好,但它还没有. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- unity3d – 如何从构建中排除不必要的DLL?
- windows-server-2003 – 排除Windows 2003中网络
- Powershell命令可以将断开连接的用户从服务器上移
- cygwin – cygpath无法将Windows路径转换为Linux
- 利用python搭建Powersploit powershell脚本站点
- windows-server-2003 – 无法RDP到Win 2003框或启
- 在Windows上更改位置_viminfo文件
- windows – 通过cmd打开文件并在特定编辑器中显示
- windows – 使用Powershell,如果最近的事件日志事
- 什么是Microsoft Exchange?它为何如此受欢迎?