我正在使用 R 中的 snow 包在 SOCK 集群上执行一个函数,该集群具有在 Linux 操作系统上运行的多台机器 (3)。我尝试使用 parLapplyclusterApply 运行代码。

如果 worker 级别出现任何错误,worker 节点的结果不会正确返回给 master,这使得调试变得非常困难。我目前正在使用 futile.logger 独立记录工作节点的每个心跳。似乎结果计算得当。但是,当我尝试在主节点上打印结果时(在收到工作人员的输出后),我收到一个错误消息,内容为 Error in checkForRemoteErrors(val): 8 nodes produced errors; first error: missing value where TRUE/FALSE needed

有没有办法更深入地调试worker的结果?

最佳答案

checkForRemoteErrors 函数由 parLapplyclusterApply 调用以检查任务错误,如果任何任务失败,它将抛出错误。不幸的是,虽然它显示了错误消息,但它没有提供任何有关导致错误的工作代码的信息。但是如果你修改你的 worker/task 函数来捕获错误,你可以保留一些额外的信息,这些信息可能有助于确定错误发生的位置。

例如,这里有一个失败的简单雪程序。请注意,它在创建集群时使用 outfile='' 以便显示程序的输出,这本身就是一种非常有用的调试技术:

library(snow)
cl <- makeSOCKcluster(2, outfile='')
problem <- function(i) {
  if (NA)
    j <- 999
  else
    j <- i
  2 * j
}
r <- parLapply(cl, 1:2, problem)

当您执行此操作时,您会看到来自 checkForRemoteErrors 的错误消息和一些其他消息,但没有任何内容告诉您 if 语句导致了错误。为了在调用 problem 时捕获错误,我们定义 workerfun :
workerfun <- function(i) {
  tryCatch({
    problem(i)
  },
  error=function(e) {
    print(e)
    stop(e)
  })
}

现在我们使用 workerfun 而不是 parLapply 执行 problem ,首先将 problem 导出到工作人员:
clusterExport(cl, c('problem'))
r <- parLapply(cl, 1:2, workerfun)

在其他消息中,我们现在看到
<simpleError in if (NA) j <- 999 else j <- i: missing value where TRUE/FALSE needed>

其中包括生成错误的实际 if 语句。当然,它不会告诉您表达式的文件名和行号,但通常足以让您解决问题。

关于 worker 未正确返回的结果 - 雪 - 调试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16895848/

10-11 22:25
查看更多