R:foreach不能用于导出数字输出,例如png或ggsave
我正在本地机器上运行R:foreach不能用于导出数字输出,例如png或ggsave,r,ggplot2,foreach,parallel-processing,R,Ggplot2,Foreach,Parallel Processing,我正在本地机器上运行foreach和doParallel(Mac Pro 2009 12核或Macbook Pro 2017)。一旦出现绘图或设备输出,如png或ggsave,foreach就会死锁 2019年8月29日更新:我做了一个简单的测试: library(foreach) library(doParallel) library(ggplot2) registerDoParallel(cores = 4) ret.plot=foreach(i = 1:4) %dopar% { wri
foreach
和doParallel
(Mac Pro 2009 12核或Macbook Pro 2017)。一旦出现绘图或设备输出,如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(1:4中的i)
或foreach
与%do%
都能很好地工作。
但是,第三个循环,foreach
和%dopar%
再次阻塞
因此它表明1)并行在我的机器中正常工作,2)绘图函数(base::plot
或ggsave
)和并行之间可能存在兼容问题
Mac上的活动监视器显示四个会话运行在后台,CPU风扇工作更努力。终端或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)
}
会话信息:
>sessionInfo()R版本3.6.1(2019-07-05)平台:
>x86_64-apple-darwin17.7.0(64位)运行于:macOS High Sierra
> 10.13.6
>
>矩阵乘积:默认BLAS:
>/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
>LAPACK:/usr/local/ceral/openblas/0.3.7/lib/libopenblasp-r0.3.7.dylib
>
>地点:[1]
>en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
>
>附加的基本包:[1]并行设备
>utils数据集方法库
>
>其他随附文件包:[1]ggplot2_3.2.1 doParallel_1.0.15
>迭代器1.0.12 foreach_1.4.7
>
>通过命名空间加载(未附加):[1]Rcpp_1.0.1
>代码工具\u 0.2-16,其R\u 2.1.2资产为\u 0.2.1[5]dplyr\u 0.8.3
>蜡笔1.3.4 R6 2.4.0网格3.6.1[9]表格0.3.0
>magrittr_1.5比例尺_1.0.0支柱_1.4.2[13]rlang_0.4.0
>lazyeval_0.2.2 rstudioapi_0.10工具_3.6.1[17]胶水_1.3.1
>purrr_0.3.2蒙塞尔_0.5.0编译器_3.6.1[21]
>pkgconfig_2.0.2颜色空间_1.4-1 TIDY选择_0.2.5 TIBLE_2.1.3
图书馆(foreach)
图书馆(双平行)
图书馆(GG2)
fxp在Mac OS上使用%dopar%中的png()时,我预期会出现同样的问题(linux和Windows工作正常)
这是由于Mac Os上的分叉机制和图形设备(以及可能的png()实现)。
如果您这样做,您将看到png不会创建新的图形设备:
fxp<- function(x){
print(dev.cur())
png(paste0(x, '_p.png')) ;
print(dev.cur())
plot(1:10);
dev.off()
}
## quartz_off_screen
## 2
fxp谢谢@jfrey,你说得对。我必须使用开罗。而且,它需要X11
这是我发现并解决我的问题的东西。
1.从R-project而不是自制程序安装R。
2.type='cairo',正如jfrey所建议的那样
我的Mac电脑上的R是从自制软件安装的,因此capabilities()
返回X11=FALSE。
然后我从自制中卸载了R,然后从下载并安装R for Mac。然后capabilities()
返回X11=TRUE
然后,带有type='cairo'的并行代码在我的Mac上完美地工作
capabilities()
jpeg png tiff tcltk X11 aqua
TRUE TRUE TRUE TRUE TRUE TRUE
http/ftp sockets libxml fifo cledit iconv
TRUE TRUE TRUE TRUE TRUE TRUE
NLS profmem cairo ICU long.double libcurl
TRUE TRUE TRUE TRUE TRUE TRUE
线程可能很有用:
我用代码blow确认:
library(foreach)
library(doParallel)
library(ggplot2)
fxp<- function(x){
png(paste0(x, '_p.png'), type = "cairo") ;
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, type = "cairo")
}
fxp(0);fxg(0)
cl <- 4
registerDoParallel(cl)
x=foreach(i =1:4) %dopar% {
fxp(i);
fxg(i)
}
库(foreach)
图书馆(双平行)
图书馆(GG2)
fxpTry改为使用cl=detectCores()-1运行,并查看是否复制错误。如果您的机器在MAC中只有4核,您可能会耗尽所有资源。谢谢您的建议。这没什么区别。如果我使用一个核心(仅此一个),它就可以工作。如果我将%dopar%更改为%do%,它就可以工作。好的。我们消除了这一点。我认为另一个关键步骤是在每个集群内本地加载包。因此,请在foreach.x=foreach(I=1:4,.packages=c(“ggplot2”)中添加库(ggplot2)。x=foreach(I=1:4,.packages=c(“ggplot2”))%dopar%等。在此之后,请按原样运行代码。如果不成功,请按顺序重复测试1-3,以了解此更改的响应方式。由于您使用的是registerDoParallel(4)
,并且在macOS上(在Linux上也是如此),因此您将得到类似于parallel::McLappy()的分叉并行处理
。如果您可以单独使用parallel::mclappy()
来重现这一点,您可以排除foreach/doParallel是问题所在。谢谢。@HenrikB。经过更多测试,我知道并行代码在没有任何绘图函数的情况下运行良好。一旦有了plot()或ggsave(),并行永远不会结束。谢谢你,jfrey。是的,我应该使用type='cairo'。除了你的建议,我必须使用R-project.org上的R,而不是自制的。
capabilities()
jpeg png tiff tcltk X11 aqua
TRUE TRUE TRUE TRUE TRUE TRUE
http/ftp sockets libxml fifo cledit iconv
TRUE TRUE TRUE TRUE TRUE TRUE
NLS profmem cairo ICU long.double libcurl
TRUE TRUE TRUE TRUE TRUE TRUE
library(foreach)
library(doParallel)
library(ggplot2)
fxp<- function(x){
png(paste0(x, '_p.png'), type = "cairo") ;
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, type = "cairo")
}
fxp(0);fxg(0)
cl <- 4
registerDoParallel(cl)
x=foreach(i =1:4) %dopar% {
fxp(i);
fxg(i)
}