【问题标题】:R function scope and parallelismR函数范围和并行性
【发布时间】:2018-03-18 02:34:33
【问题描述】:

考虑以下函数定义

library(doParallel)
f_print <- function(x)
{
  print(x)
}
f_foreach <- function(l)
{
  foreach (i=l) %do%
  {
    f_print(i)
  }
}

f_foreach_parallel <- function(l)
{
  doParallel::registerDoParallel(1)
  foreach (i=l) %dopar%
  {
    f_print(i)
  }
}

功能使用:

> f_foreach(c(1,2))
[1] 1
[1] 2
[[1]]
[1] 1

[[2]]
[1] 2

> f_foreach_parallel(c(1,2))
 Show Traceback

 Rerun with Debug
 Error in { : 
  task 1 failed - "impossible de trouver la fonction "f_print"" 
  [Error: could not find function f_print]
> 

您能否帮助解释为什么foreach 涉及并行性时f_print() 不可见?我们如何在这个平行的foreach 中使用f_print()?任何与此相关的文档?

【问题讨论】:

  • 第二个功能对我有用,没有错误。我在 R 3.4.2 上运行每个包中的最新版本(doParallel 1.0.11 和 foreach 1.4.3)。
  • 这令人费解。我使用的是 doParallel_1.0.10 和 foreach_1.4.3。我刚刚更新到与您相同的最新版本,问题仍然存在。有什么想法吗?
  • 这很奇怪。我只是用新版本的 R 重新运行了代码,并没有出现错误。您在 Windows 中工作吗?如果是这样,您可能必须像这样导出函数:foreach (i=l, .export=c("f_print")) %dopar%。如果这可行,那么问题与snowmcapply 之间的区别有关,其中第一个适用于所有操作系统,而第二个仅适用于 *nix。我正在运行 openSuse linux。
  • 你说的对。我使用 Windows,确实 export 解决了它。那里有些曲折。此外,foreach 与并行不会正常返回列表foreach

标签: r function parallel-processing scope


【解决方案1】:

除了在顶帖的 cmets 中已经说过的内容,尤其是关于指定 .export 的内容之外,当使用 doFuture 包时,您的代码确实可以工作,而不管并行后端、操作系统和 @ 987654323@。这是您的设置的改编版本:

f_print <- function(x) {
  print(x)
}

f_foreach <- function(l) {
  foreach(i=l) %do% {
    f_print(i)
  }
}

f_foreach_dopar <- function(l) {
  foreach(i=l) %dopar% {
    f_print(i)
  }
}

而不是做:

library("doParallel")

## Setup PSOCK workers (just as on Windows)
workers <- parallel::makeCluster(1L, outfile = "")
registerDoParallel(workers)

f_foreach_dopar(c(1,2))
## Error in { : task 1 failed - "could not find function "f_print""

你可以这样做:

library("doFuture")
registerDoFuture()

## As above
workers <- parallel::makeCluster(1L, outfile = "")
plan(cluster, workers = workers)

f_foreach_dopar(c(1,2))
## [1] 1
## [1] 2
## [[1]]
## [1] 1
## 
## [[2]]
## [1] 2

之所以可行,是因为 doFuture 进行了更彻底的搜索以识别全局变量(此处为 f_print())。

PS。 outfile = "" 的原因是实际上显示了 stdout/stderr 输出(例如来自 print())。我不推荐在并行处理中重定向 stdout/stderr,这是一个完全不同的讨论,但我假设您使用 print() 只是为了您的示例。

【讨论】:

    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2012-08-03
    • 1970-01-01
    相关资源
    最近更新 更多