我正在使用R中的snow
包在SOCK
集群上执行一个函数,其中多台机器(3)在Linux OS上运行。我尝试使用parLapply
和clusterApply
运行代码。
如果在工作级别出现任何错误,则工作节点的结果不会正确返回到master,这使得调试非常困难。我目前正在使用futile.logger
独立记录工作节点的每个心跳。似乎结果是正确计算的。但是当我尝试在主节点上打印结果时(在收到工作人员的输出后),我得到一个错误,上面写着Error in checkForRemoteErrors(val): 8 nodes produced errors; first error: missing value where TRUE/FALSE needed
。
有没有办法更深入地调试工人的结果?
答案 0 :(得分:11)
由checkForRemoteErrors
和parLapply
调用clusterApply
函数来检查任务错误,如果任何任务失败,它将抛出错误。不幸的是,虽然它显示错误消息,但它不提供有关哪些工作程序代码导致错误的任何信息。但是,如果您修改工作者/任务函数以捕获错误,则可以保留一些可能有助于确定错误发生位置的额外信息。
例如,这是一个失败的简单雪程序。请注意,它在创建集群时使用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
语句。当然,它不会告诉您表达式的文件名和行号,但通常足以让您解决问题。
答案 1 :(得分:0)
检查观察范围。观察结果如何变化。我注意到当有很多小数位4,5,6时,它会抛出glm.nb。要解决这个问题,我只需将观察结果舍入到小数点后两位。