我正在使用 R 中的 snow
包在 SOCK
集群上执行一个函数,该集群具有在 Linux 操作系统上运行的多台机器 (3)。我尝试使用 parLapply
和 clusterApply
运行代码。
如果 worker 级别出现任何错误,worker 节点的结果不会正确返回给 master,这使得调试变得非常困难。我目前正在使用 futile.logger
独立记录工作节点的每个心跳。似乎结果计算得当。但是,当我尝试在主节点上打印结果时(在收到工作人员的输出后),我收到一个错误消息,内容为 Error in checkForRemoteErrors(val): 8 nodes produced errors; first error: missing value where TRUE/FALSE needed
。
有没有办法更深入地调试worker的结果?
最佳答案
checkForRemoteErrors
函数由 parLapply
和 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
语句。当然,它不会告诉您表达式的文件名和行号,但通常足以让您解决问题。关于 worker 未正确返回的结果 - 雪 - 调试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16895848/