繁体   English   中英

R:foreach不适用于导出图,例如png或ggsave

[英]R: The foreach does not work with exporting figure out, such as png or ggsave

我正在尝试在本地计算机(具有12核的Mac Pro 2009或Macbook Pro 2017)中运行foreachdoParallel 一旦有绘图或设备输出,例如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)或带有%do% foreach的第二个循环均正常工作。 但第三圈, foreach%dopar%再次stucks。

因此,这表明1)并行工作在我的机器上正常运行,并且2)绘图函数( base::plotggsave )与并行函数之间可能存在兼容问题。

Mac上的活动监视器显示四个rsession正在运行,并且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)
}

没有错误,但是程序在foreach停止。

Test1:如果仅运行fxp()并关闭plot(1:10) ,则该程序可以运行。

Test2:如果仅运行fxg()并关闭ggsave ,则该程序可以运行。

Test3:一旦plotggsave打开,程序将在foreach中进入死锁状态。

使用相同代码的另一台Linux计算机(群集计算机)上的测试始终可以正常工作。 Linux集群的会话信息为:

R版本3.6.1(2019-07-05)平台:x86_64-pc-linux-gnu(64位)运行于: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 = zh_CN.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标度_1.0.0支柱_1.4.2 [9] rlang_0.4.0
lazyeval_0.2.2标签_0.3工具_3.6.1 [13] munsell_0.5.0编译器_3.6.1 pkgconfig_2.0.2 colorspace_1.4-1 [17] tibble_2.1.3


我期望在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

似乎“ quartz ”无法在fork模式下打开新的图形设备。
让我们尝试使用“ Xlibpng(type =“ Xlib”) ,这是一个可爱的消息:

“分叉的孩子不应该打开图形设备”

这证实了我们的怀疑……但是它“ 不应该 ”“不能”“ 不能

解决方案

使用1个核心

将%dopar%与1个核心工程一起使用,但这不是很有用。

cl <- 1
registerDoParallel(cl)

因此,让我们尝试使用“ cairo ”:

fxp<- function(x){
    png(paste0(x, '_p.png'), type = "cairo", bg = "white") ;
    plot(1:10);
    dev.off()
}

工作正常! (对于我在Mac OS上)

谢谢@jfrey,您说得对。 我必须用开罗。 另外,它需要X11。

这是我发现并解决我的问题的方法。 1.从r-project而不是homebrew安装R。 2.按照jfrey的建议键入='cairo'。

我的Mac上的R是通过自制程序安装的,因此capabilities()返回X11 = FALSE。 然后我从自制软件中卸载了R,然后从https://cran.r-project.org/bin/macosx/下载并安装了Mac版R。 然后, capabilities()返回X11=TRUE

然后,类型='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 

线程可能有用: 尝试使用fix()时,Mac OS X 10.13上的RStudio无法获得X11错误

我用代码打击确认了:

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)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM