r语言 - 为什么并行作业不在 RStudio 中打印?



为什么与mclapply并行的脚本在集群上打印,而不是在RStudio中打印?只是出于好奇而问。

mclapply(1:10, function(x) {
print("Hello!")
return(TRUE)
}, mc.cores = 2)
# Hello prints in slurm but not RStudio

"并行"包中的任何函数都不保证正确显示发送到标准输出(stdout(的输出或工作线程上的标准错误(stderr(。 这适用于所有类型的并行化方法,例如分叉处理(mclapply()(或PSOCK集群(parLapply()(。 这样做的原因是因为它从未被设计为以一致的方式中继输出。

一个好的测试是查看您是否可以通过capture.output()捕获输出。 例如,我得到:

bfr <- utils::capture.output({
y <- lapply(1:3, FUN = print)
})
print(bfr)
## [1] "[1] 1" "[1] 2" "[1] 3"

正如预期的那样,但是当我尝试时:

bfr <- utils::capture.output({
y <- parallel::mclapply(1:3, FUN = print)
})
print(bfr)
## character(0)

没有捕获任何输出。 有趣的是,如果我在终端中没有捕获 Linux 上的 R 4.0.1 中的输出来调用它,我会得到:

y <- parallel::mclapply(1:3, FUN = print)
[1] 1
[1] 3
[1] 2

有趣吧?

使用本地 PSOCK 群集时可能会得到的另一个建议是在创建群集时设置参数outfile = ""。 事实上,当你在终端的Linux上尝试这个时,它看起来肯定是有效的:

cl <- parallel::makeCluster(2L, outfile = "")
## starting worker pid=25259 on localhost:11167 at 17:50:03.974
## starting worker pid=25258 on localhost:11167 at 17:50:03.974
y <- parallel::parLapply(cl, 1:3, fun = print)
## [1] 1
## [1] 2
## [1] 3

但这也给人带来了虚假的希望。 事实证明,您看到的输出只是因为终端碰巧显示它。 这在 RStudio 控制台中可能有效,也可能不起作用。 您可能会在 Linux、macOS 和 MS Windows 上看到不同的行为。 理解的最重要部分是 R 会话根本看不到此输出。 如果我们尝试捕获它,我们会得到:

bfr <- utils::capture.output({
y <- parallel::parLapply(cl, 1:3, fun = print)
})
## [1] 1
## [1] 2
## [1] 3
print(bfr)
## character(0)

有趣吧? 但实际上,如果您了解"并行"包的内部细节,这并不奇怪。

(

免责声明:我是作者(我知道的唯一一个正确中继标准输出的并行框架(例如cat()print(), ...和消息条件(例如message()(到主R会话是未来的框架。 您可以在其"文本和消息输出"小插图中阅读详细信息,但这里有一个示例显示它有效:

future::plan("multicore", workers = 2) ## forked processing
bfr <- utils::capture.output({
y <- future.apply::future_lapply(1:3, FUN = print)
})
print(bfr)
[1] "[1] 1" "[1] 2" "[1] 3"

无论底层并行化框架如何,它的工作方式都相同,例如与本地 PSOCK 工作线程:

future::plan("multisession", workers = 2) ## PSOCK cluster
bfr <- utils::capture.output({
y <- future.apply::future_lapply(1:3, FUN = print)
})
print(bfr)
[1] "[1] 1" "[1] 2" "[1] 3"

这在运行 R 的所有操作系统和环境(包括 RStudio 控制台(上的工作方式相同。 无论您使用哪种未来的map-reduce框架,例如(这里(future.apply,furrrforeachdoFuture,它的行为也是一样的。

最新更新