gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-05 03:58:50 27 4
gpt4 key购买 nike

我正在尝试在我的本地计算机(12 核 Mac Pro 2009 或 Macbook Pro 2017)中运行 foreachdoParallel。一旦出现 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 with %do% 都能正常工作。但是,第三个循环,foreach%dopar% 再次卡住了。

所以它表明 1) 并行在我的机器上工作正常,以及 2) 绘图函数(base::plotggsave)之间可能存在兼容问题和并行。

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中停止了。

测试 1:如果我只运行 fxp() 并关闭 plot(1:10),程序可以运行。

测试 2:如果我只运行 fxg() 并关闭 ggsave,程序可以运行。

测试 3:一旦 plotggsave 为 ON,程序在 foreach 中进入死锁。

在另一台具有相同代码的 Linux 机器(集群机器)上的测试总是正确的。Linux集群的session信息为:

R version 3.6.1 (2019-07-05) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Ubuntu 18.04.3 LTS

Matrix products: default BLAS:
/usr/lib/x86_64-linux-gnu/openblas/libblas.so.3 LAPACK: /usr/lib/x86_64-linux-gnu/libopenblasp-r0.2.20.so

locale: [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

attached base packages: [1] parallel stats graphics grDevices utils datasets methods [8] 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.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.0 pillar_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


最佳答案

我预计在 Mac OS(linux 和 Windows 工作正常)的 %dopar% 中使用 png() 会出现同样的问题。

这是由于 Mac Os 上的 fork 机制和图形设备(可能还有 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"),多么可爱的消息:

"a forked child should not open a graphics device"

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

解决方案

使用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()
}

It's working ! (for me on Mac OS)

关于R:foreach 不适用于导出图形,例如 png 或 ggsave,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57682250/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com