4

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

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

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

4

2 回答 2

11

checkForRemoteErrors函数由parLapplyand调用clusterApply以检查任务错误,如果任何任务失败,它将抛出错误。不幸的是,尽管它显示了错误消息,但它没有提供任何关于是什么工作代码导致错误的信息。但是如果你修改你的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其中包括产生错误的实际语句。当然,它不会告诉你表达式的文件名和行号,但通常足以让你解决问题。

于 2013-06-05T15:56:00.363 回答
0

检查你的观察范围。观察结果如何变化。我注意到当有很多小数位 4, 5,6 时,它会抛出 glm.nb 。为了解决这个问题,我只是将观察结果四舍五入到小数点后 2 位。

于 2014-09-05T20:31:52.227 回答