【发布时间】:2019-08-27 21:04:04
【问题描述】:
我正在尝试在我的本地机器上运行 foreach 和 doParallel(Mac Pro 2009 有 12 核或 Macbook Pro 2017)。一旦出现 plot 或 device-out,例如 png 或 ggsave,foreach 就会卡住 --- 死锁。
2019 年 8 月 29 日更新:我做了一个简单的测试:
library(foreach)
library(doParallel)
library(ggplot2)
registerDoParallel(cores = 4)
ret.plot=foreach(i = 1:4) %dopar% {
write(1:1, paste0(i, '_p.txt'))
md=data.frame(x=1:10, y=1:10);
p=ggplot(md, aes(x=x, y=y))+geom_point();
}
# for(i in 1:4){
ret.save1=foreach(i = 1:4) %do% {
ggsave(filename = paste0(i, '_do.png'), ret.plot[[i]])
}
ret.save2=foreach(i = 1:4) %dopar% {
ggsave(filename = paste0(i, '_dopar.png'), ret.plot[[i]])
}
# ret.save2=foreach(i = 1:4, .packages = c("ggplot2")) %dopar% {
# ggsave(filename = paste0(i, '_dopar.png'), ret.plot[[i]])
# }
第一个并行循环 ret.plot=... 有效,它导出四个 .txt 文件,并返回 ggplot 结果列表。
第二个循环,for(i in 1:4) 或 foreach 和 %do% 都能正常工作。
但是,第三个循环,foreach 和 %dopar% 再次卡住。
所以它表明 1)并行在我的机器上工作正常,2)绘图函数(base::plot 或 ggsave)和并行之间可能存在兼容问题。
Mac 上的活动监视器显示四个 rsession 正在后台运行,并且 CPU 风扇工作得更加努力。 Terminal 或 RStudio 中的 R 没有区别。
原问题描述:
Session information:
> sessionInfo() R version 3.6.1 (2019-07-05) Platform:
> x86_64-apple-darwin17.7.0 (64-bit) Running under: macOS High Sierra
> 10.13.6
>
> Matrix products: default BLAS:
> /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
> LAPACK: /usr/local/Cellar/openblas/0.3.7/lib/libopenblasp-r0.3.7.dylib
>
> locale: [1]
> en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
>
> attached base packages: [1] parallel stats graphics grDevices
> utils datasets methods base
>
> other attached packages: [1] ggplot2_3.2.1 doParallel_1.0.15
> iterators_1.0.12 foreach_1.4.7
>
> loaded via a namespace (and not attached): [1] Rcpp_1.0.1
> codetools_0.2-16 withr_2.1.2 assertthat_0.2.1 [5] dplyr_0.8.3
> crayon_1.3.4 R6_2.4.0 grid_3.6.1 [9] gtable_0.3.0
> magrittr_1.5 scales_1.0.0 pillar_1.4.2 [13] rlang_0.4.0
> lazyeval_0.2.2 rstudioapi_0.10 tools_3.6.1 [17] glue_1.3.1
> purrr_0.3.2 munsell_0.5.0 compiler_3.6.1 [21]
> pkgconfig_2.0.2 colorspace_1.4-1 tidyselect_0.2.5 tibble_2.1.3
library(foreach)
library(doParallel)
library(ggplot2)
fxp<- function(x){
png(paste0(x, '_p.png')) ;
plot(1:10);
dev.off()
}
fxg <-function(x){
md=data.frame(x=1:10, y=1:10);
p=ggplot(md, aes(x=x, y=y))+geom_point();
ggsave(filename = paste0(x, '_g.png'), p)
}
fxp(0);fxg(0)
cl <- 4
registerDoParallel(cl)
x=foreach(i =1:4) %dopar% {
# for( i in 1:2){
fxp(i);
fxg(i)
}
没有错误,但程序在foreach处停止。
Test1:如果我只运行fxp() 并关闭plot(1:10),程序就可以工作。
Test2:如果我只运行fxg() 并关闭ggsave,程序就可以工作。
Test3:一旦plot或ggsave为ON,程序在foreach中进入死锁。
在另一台具有相同代码的 Linux 机器(集群机器)上进行的测试始终可以正常工作。 Linux集群的会话信息为:
R 版本 3.6.1 (2019-07-05) 平台:x86_64-pc-linux-gnu (64-bit) 运行于:Ubuntu 18.04.3 LTS
矩阵产品:默认 BLAS:
/usr/lib/x86_64-linux-gnu/openblas/libblas.so.3 LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so语言环境:[1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
[3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8 [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8 [7] LC_PAPER=en_US.UTF-8 LC_NAME=C [9] LC_ADDRESS=C LC_TELEPHONE=C [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C附加的基础包:[1] 并行统计图形 grDevices utils 数据集方法 [8] 基础
其他附加包:[1] ggplot2_3.2.1 doParallel_1.0.15 iterators_1.0.12 foreach_1.4.7
通过命名空间加载(未附加):[1] Rcpp_1.0.2
codetools_0.2-16 withr_2.1.2 crayon_1.3.4 [5] grid_3.6.1
gtable_0.3.0 scales_1.0.0pillar_1.4.2 [9] rlang_0.4.0
lazyeval_0.2.2 labeling_0.3 tools_3.6.1 [13] munsell_0.5.0 compiler_3.6.1 pkgconfig_2.0.2 colorspace_1.4-1 [17] tibble_2.1.3
【问题讨论】:
-
尝试使用 cl = detectCores() -1 运行,看看是否复制了错误。如果您的机器在 MAC 中只有 4 核,您可能会耗尽所有资源。
-
感谢您的建议。没有什么不同的。如果我使用一个核心(仅,它可以工作。如果我将 %dopar% 更改为 %do%,它可以工作。
-
好的。我们消除了这一点。我认为另一个关键步骤是在每个集群内本地加载包。所以请在 foreach 中添加库(ggplot2)。 x=foreach(i =1:4, .packages = c("ggplot2")) %dopar% 等。之后请按原样运行代码。如果不成功,请依次重复测试 1-3 以了解此更改如何响应。
-
由于您使用的是
registerDoParallel(4)并且在 macOS 上(在 Linux 上也是如此),因此您最终会得到类似于parallel::mclapply()的 forked 并行处理。如果您可以单独使用parallel::mclapply()重现此问题,则可以排除 foreach/doParallel 是问题所在。 -
谢谢。 @HenrikB。经过更多测试,我知道并行代码在没有任何绘图功能的情况下运行良好。一旦有 plot() 或 ggsave(),并行永远不会结束。
标签: r ggplot2 foreach parallel-processing