当我使用mclapply时,不时(实际上是随机的)它会给出不正确的结果。这个问题在互联网上的其他帖子中得到了充分的描述,例如: (http://r.789695.n4.nabble.com/Bug-in-mclapply-td4652743.html)。但是,没有提供解决方案。有谁知道如何解决这个问题?谢谢!
答案 0 :(得分:8)
你引用的Winston Chang报告的问题似乎已在R 2.15.3中修复。在将结果列表分配给结果列表时,mccollect
中出现了一个错误:
if (is.raw(r)) res[[which(pid == pids)]] <- unserialize(r)
如果unserialize(r)
返回NULL,则失败,因为以这种方式将NULL分配给列表会删除列表的相应元素。这在R 2.15.3中改为:
if (is.raw(r)) # unserialize(r) might be null
res[which(pid == pids)] <- list(unserialize(r))
这是一种将未知值分配给列表的安全方法。
因此,如果您使用R&lt; = 2.15.2,则解决方案是升级到R&gt; = 2.15.3。如果你在使用R&gt; = 2.15.3时遇到问题,那么可能与Winston Chang报告的问题不同。
我还阅读了Elizabeth Purdom发起的R-help线程中讨论的问题。如果没有特定的测试用例,我的猜测是由于mclapply中的错误导致问题不,因为我可以使用以下函数重现相同的症状:
work <- function(i, poison) {
if (i == poison) quit(save='no')
i
}
如果mclapply因为任何原因(接收信号,seg faulting,退出)执行任务而mclapply开始工作,mclapply将为分配给该worker的所有任务返回NULL:
> library(parallel)
> mclapply(1:4, work, 3, mc.cores=2)
[[1]]
NULL
[[2]]
[1] 2
[[3]]
NULL
[[4]]
[1] 4
在这种情况下,由于预先安排,任务1和3返回NULL,即使只有任务3实际上失败了。
如果工作人员在使用parLapply或clusterApply等功能时死亡,则会报告错误:
> cl <- makePSOCKcluster(3)
> parLapply(cl, 1:4, work, 3)
Error in unserialize(node$con) : error reading from connection
我见过很多这样的报告,我认为它们往往发生在大型程序中,这些程序使用了很多难以转化为可重现的测试用例的软件包。
当然,在这个例子中,使用lapply时也会出错,尽管错误不会像mclapply一样隐藏。如果在使用lapply时似乎没有出现问题,可能是因为问题很少发生,所以它只发生在使用mclapply并行执行的非常大的运行中。但是也可能发生错误,不是因为任务是并行执行的,而是因为它们是由分叉进程执行的。例如,在分叉进程中执行时,各种图形操作将失败。
答案 1 :(得分:4)
我正在添加这个答案,所以其他人点击这个问题就不必趟过评论的长线程(我是赏金的人,但不是OP)。
mclapply
最初使用NULLS填充它创建的列表。当工作程序处理返回值时,这些值将覆盖NULLS。如果进程在没有返回值的情况下死亡,mclapply
将返回NULL。
当内存变低时,Linux内存杀手(oom killer)
https://lwn.net/Articles/317814/
将开始以静默方式终止进程。虽然oom杀手活动出现在系统日志中,但它不会向控制台打印任何内容以让您知道它正在做什么。在这种情况下,mclapply
的输出似乎被NULLS随机污染。