foreach 循环中 mclapply 的 R 错误
R error with mclapply in a foreach loop
基于,我试着写了一个脚本,看到这里:
library(parallel)
library(doParallel)
cl<-makeCluster(2,outfile='')
registerDoParallel(cl)
foreach(i=1:5, .packages='parallel') %dopar% {
system.time(mclapply(1:10, function(x){rnorm(1e5)},mc.cores=2))
}
stopCluster(cl)
它最初有效,但现在抛出错误代码:
Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted
Error in unserialize(socklist[[n]]) : error reading from connection
Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted
知道发生了什么事吗?甚至可以将 mclapply 放入 foreach 循环中吗?
编辑:我还想说这是在单个 8 核机器上,而不是集群。
我仅使用 R 3.2.3 中的 "parallel" 包就可以在我的 Linux 机器上重现您的问题:
library(parallel)
cl <- makeCluster(2)
clusterEvalQ(cl, library(parallel))
fun <- function(i) {
mclapply(1:10, function(x) rnorm(1e5), mc.cores=2)
0
}
clusterApplyLB(cl, 1:5, fun)
从我的调试会话来看,master 和 worker 之间的套接字连接似乎已损坏,这可能导致 worker 在尝试从损坏的套接字 "unserialize" 获取数据时出错时死亡连接。
有趣的是,我可以通过使用 "multicore" 包而不是 "parallel" 来使这个示例工作。我使用以下命令从 RForge.net 安装了多核 0.1-8:
> install.packages('multicore',,'http://www.rforge.net/')
然后,我在 workers 上加载了 "multicore" 而不是 "parallel":
clusterEvalQ(cl, library(multicore))
然后这个例子运行良好。您可以更改 foreach 循环以使用 .packages='multicore'
选项。
我查到的就这些。我的猜测是由 "mclapply" 在 "parallel" 中分叉的子进程以某种方式破坏了它们继承的套接字连接,但我没有查看代码以查看该理论是否合理。
我猜你的选择是:
- 不要在 "doParallel" foreach 循环中使用 "mclapply"
- 使用 "multicore 0.1-8" 中的 "mclapply" 而不是 "parallel"
- 向 R-Core 报告此问题
您需要做额外的工作才能将此报告给 R-Core,但希望我的示例会有所帮助。
我在使用mclapply进行并行计算时也遇到过类似的错误。它偶尔以非常随机的方式发生。您可以按照其他答案的建议进行操作,但我所做的一个快速修复是简单地让算法捕获此错误 re-运行 命令。大多数情况下,如果您再次 运行 它就会起作用。
基于
library(parallel)
library(doParallel)
cl<-makeCluster(2,outfile='')
registerDoParallel(cl)
foreach(i=1:5, .packages='parallel') %dopar% {
system.time(mclapply(1:10, function(x){rnorm(1e5)},mc.cores=2))
}
stopCluster(cl)
它最初有效,但现在抛出错误代码:
Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted
Error in unserialize(socklist[[n]]) : error reading from connection
Error in unserialize(node$con) : error reading from connection
Calls: <Anonymous> ... doTryCatch -> recvData -> recvData.SOCKnode -> unserialize
Execution halted
知道发生了什么事吗?甚至可以将 mclapply 放入 foreach 循环中吗?
编辑:我还想说这是在单个 8 核机器上,而不是集群。
我仅使用 R 3.2.3 中的 "parallel" 包就可以在我的 Linux 机器上重现您的问题:
library(parallel)
cl <- makeCluster(2)
clusterEvalQ(cl, library(parallel))
fun <- function(i) {
mclapply(1:10, function(x) rnorm(1e5), mc.cores=2)
0
}
clusterApplyLB(cl, 1:5, fun)
从我的调试会话来看,master 和 worker 之间的套接字连接似乎已损坏,这可能导致 worker 在尝试从损坏的套接字 "unserialize" 获取数据时出错时死亡连接。
有趣的是,我可以通过使用 "multicore" 包而不是 "parallel" 来使这个示例工作。我使用以下命令从 RForge.net 安装了多核 0.1-8:
> install.packages('multicore',,'http://www.rforge.net/')
然后,我在 workers 上加载了 "multicore" 而不是 "parallel":
clusterEvalQ(cl, library(multicore))
然后这个例子运行良好。您可以更改 foreach 循环以使用 .packages='multicore'
选项。
我查到的就这些。我的猜测是由 "mclapply" 在 "parallel" 中分叉的子进程以某种方式破坏了它们继承的套接字连接,但我没有查看代码以查看该理论是否合理。
我猜你的选择是:
- 不要在 "doParallel" foreach 循环中使用 "mclapply"
- 使用 "multicore 0.1-8" 中的 "mclapply" 而不是 "parallel"
- 向 R-Core 报告此问题
您需要做额外的工作才能将此报告给 R-Core,但希望我的示例会有所帮助。
我在使用mclapply进行并行计算时也遇到过类似的错误。它偶尔以非常随机的方式发生。您可以按照其他答案的建议进行操作,但我所做的一个快速修复是简单地让算法捕获此错误 re-运行 命令。大多数情况下,如果您再次 运行 它就会起作用。