当我使用mclapply时,有时(实际上是随机的)它会给出不正确的结果。这个问题在互联网上的其他帖子中有相当详细的描述,例如(http://r.789695.n4.nabble.com/Bug-in-mclapply-td4652743.html)。但是,没有提供任何解决方案。有人知道如何解决这个问题吗?谢谢!
发布于 2014-01-07 00:31:53
您引用的Winston Chang报告的问题似乎已经在R 2.15.3中得到解决。将worker结果分配给结果列表时,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 <= 2.15.2,则解决方案是升级到R >= 2.15.3。如果您在使用R >= 2.15.3时遇到问题,那么可能是与Winston Chang报告的问题不同的问题。
我还阅读了伊丽莎白·珀多姆发起的R-help线程中讨论的问题。如果没有特定的测试用例,我的猜测是问题不是由于mclapply中的错误造成的,因为我可以使用以下函数重现相同的症状:
work <- function(i, poison) {
if (i == poison) quit(save='no')
i
}如果由mclapply启动的一个worker在执行任务时由于任何原因(接收信号、seg出错、退出)而死亡,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失败。
如果worker在使用parLapply或clusterApply等函数时死亡,则会报告错误:
> cl <- makePSOCKcluster(3)
> parLapply(cl, 1:4, work, 3)
Error in unserialize(node$con) : error reading from connection我看过很多这样的报告,我认为它们往往发生在使用了大量包的大型程序中,这些包很难转化为可重现的测试用例。
当然,在本例中,使用lapply时也会出现错误,尽管错误不会像使用mclapply时那样被隐藏。如果在使用lapply时似乎没有出现这个问题,可能是因为这个问题很少发生,所以它只在使用mclapply并行执行的非常大的运行中发生。但也有可能出现错误,不是因为任务是并行执行的,而是因为它们是由forked进程执行的。例如,当在分支进程中执行时,各种图形操作将失败。
发布于 2014-05-02 09:20:26
我添加了这个答案,这样其他遇到这个问题的人就不必费力地通过长长的评论(我是赏金授予者,而不是OP)。
mclapply最初使用空值填充它创建的列表。当工作进程返回值时,这些值将覆盖NULLS。如果进程在没有返回值的情况下终止,mclapply将返回NULL。
当内存不足时,Linux内存不足杀手(oom杀手)
https://lwn.net/Articles/317814/
将开始静默地杀死进程。它不会将任何内容打印到控制台,让您知道它正在做什么,尽管oom杀手活动显示在系统日志中。在这种情况下,mclapply的输出将随机地被NULLS污染。
https://stackoverflow.com/questions/20674538
复制相似问题