【问题标题】:parallel connection issue in RR中的并行连接问题
【发布时间】:2017-06-30 02:30:41
【问题描述】:

我正在尝试使用 foreach 从目录中读取数据文件。但这给了我一个错误。它可以在我的办公室机器上工作,但不能在家里工作。两台机器都有4核,检查底部的输出。这是代码

rm(list=ls())
setwd("D:/Test")
library(foreach)
library(doParallel)

c1<-makeCluster(4, outfile = "debug.txt")
CE<-clusterEvalQ(c1, .libPaths(""))
registerDoParallel(c1)

print(paste0("Cores = ",detectCores()))
file.names <- dir(pattern ="h00|B00")
output<-list()

output<-foreach (i=1:4) %dopar% {
       read.table(file=file.names[i])
}

stopCluster(c1)

我收到错误:

{ 中的错误:任务 1 失败 - “无法打开连接”

【问题讨论】:

  • 您是否尝试过用for 循环替换foreach 调用?如果您怀疑集群会导致问题,那么以这种方式进行调试总是一个好主意。
  • 它适用于 for 循环,但不适用于 foreach。我在调试文件中发现它在目录中找不到文件。但我检查了包含从目录加载的正确文件名的 file.names。
  • 我不确定foreach 后端,但最好将绝对文件路径发送到每个节点,而不是相对路径。您可以通过在您的dir 调用中包含full.names=TRUE 来做到这一点...相对路径(您在此处使用)依赖于所有节点保留的工作目录,这可能不会发生(再次,我不是当然)。
  • 我找到了解决方案但不明白,为什么前面的代码在我的办公室机器上工作,但在家里的机器上却不行。除了 rosscova 建议的,我还需要包含目录路径。应该是 dir("D:/Test",pattern ="h00|b00",full.names=TRUE)

标签: r foreach parallel-processing


【解决方案1】:

我不是 R 并行操作方面的专家,我不知道为什么您在不同的机器上会有不同的行为(它们是相同的操作系统,具有相同版本的 R 和 R 包吗?) .我的理解是,像foreach 这样的函数会在后台启动多个 R 会话,每个会话都充当“节点”来计算操作的子集。在您的情况下,这些节点中的每一个都需要找到文件以提供 read.table,因此我个人认为,在使用并行进程时传递完整文件路径是一种很好的做法。

dir 与默认参数一起使用会返回相对文件路径(即:相对于您当前的工作目录),这意味着您需要留在当前工作目录中才能正确引用它们。我将首先将我的工作目录设置为我的桌面来解释:

desktop.path <- "~/Desktop"
setwd( desktop.path )
getwd()
# [1] "/Users/ross/Desktop"

现在我们可以通过几种方式获取位于我桌面上的“.txt”文件的路径。首先,使用默认参数。

file.default <- dir( pattern = "txt" )
file.default
# [1] "CW_denseCloud_LowestQual_withGCPs.txt"

请注意,该链接中没有任何内容可以显示文件的位置,我们依靠当前的工作目录来查找它,这目前很好。

file.exists( file.default )
[1] TRUE

但如果我们最终进入另一个工作目录,我们将丢失文件:

setwd( "~" )
file.exists( file.default )
# [1] FALSE

如果我们传递参数full.names = TRUE,我们得到的不仅仅是文件名本身,但它仍然是一个相对路径,没有帮助:

setwd( desktop.path )
dir( pattern = "txt", full.names = TRUE )
# [1] "./CW_denseCloud_LowestQual_withGCPs.txt"

将完整路径传递给dir 也会有所帮助,这样dir 就可以有效地查看相对于根目录的文件,而不是当前工作目录:

file.full <- dir( path = desktop.path, pattern = "txt", full.names = TRUE )
file.full
# [1] "/Users/ross/Desktop/CW_denseCloud_LowestQual_withGCPs.txt"

现在我们有了文件的完整路径,而不是相对路径,这意味着无论我们坐在哪里(工作目录),我们都会找到这个文件:

file.exists( file.full )
# [1] TRUE

setwd( "~" )
file.exists( file.full )
# [1] TRUE

现在,即使工作目录没有正确传递给每个处理节点,它们仍然可以找到所需的文件。

【讨论】:

  • 感谢您的解释并且说得通。我在具有相同 R 版本的两台机器上使用相同的设置,唯一的区别在于操作系统(Win7 Vs win10)。
【解决方案2】:
rm(list=ls())
setwd("D:/Test")
library(foreach)
library(doParallel)

c1<-makeCluster(4, outfile = "debug.txt")
CE<-clusterEvalQ(c1, .libPaths(""))
registerDoParallel(c1)

print(paste0("Cores = ",detectCores()))
file.names <- dir("D:/Test",pattern ="h00|b00",full.names=TRUE)
output<-list()

output<-foreach (i=1:4) %dopar% {
      read.table(file=file.names[i])
}

stopCluster(c1)

【讨论】:

  • 您应该在此答案中添加解释,以便其他人可以看到您学到了什么,以及哪些帮助您解决了问题。
  • 正如您在上面评论的,它需要添加上述cmets中提到的绝对文件路径。解决方案有效,但我无法解释为什么它在一台机器上有效,但在另一台机器上无效。
  • 看看output &lt;- foreach (i=1:4) %dopar% { list(pwd = getwd(), files = dir(), info = file.info(file.names[i])) } 是否返回你认为应该的结果。
猜你喜欢
  • 2021-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 2014-05-29
相关资源
最近更新 更多