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