R foreach问题(某些进程返回NULL)

jfl*_*int 6 memory foreach r

我遇到foreach了我在R中使用的程序部分的问题.该程序用于运行不同参数的模拟,然后将结果返回到单个列表,然后用于生成报告.如果并非所有分配的模拟运行在报表上实际可见,则会出现此问题.从各方面来看,似乎只分配了一部分已分配的运行.

这更可能发生在更大的数据集(例如,更长的模拟时间段).新程序运行的可能性较小,如果某些东西占用RAM,则更有可能发生.系统监视器的内存使用图有时达到100%RAM和100%交换峰值,然后急剧下降,此后四个子R会话中的一个已经消失.使用.verboseforeach(),日志文件显示报告中未显示的模拟运行将返回NULL,而报告中显示的模拟运行将正常返回(数据框和字符变量列表).同一组参数可以产生这种效果或者可以产生完整的图形; 也就是说,参数集不是诊断参数.

foreach()用于大约十二个参数..combinecbind,.inorder是假,所有其他内部参数,如.errorhandling默认值.

这当然是非常令人恼火的,因为模拟可能需要花费超过20分钟才能运行,结果由于缺少数据而变得无用.有没有办法确保这些"丢弃"的会话不被删除,或者如果它们是,那么这在某种程度上被抓住了?

(如果重要的话,正在使用的计算机有八个处理器,因此运行四个子进程,并且注册的并行运算符来自DoMC包)

代码的结构大致如下:

test.results <- foreach(parameter.one = parameter.one.space, .combine=cbind) %:%
foreach(parameter.two = parameter.two.space, .combine=cbind) %:%
...
foreach(parameter.last = parameter.last.space, .combine=cbind, .inorder=FALSE) %dopar%
{

run.result <- simulationRun(parameter.one,
            parameter.two,
            ...
            parameter.last)

 list(list(parameters=list(parameter.one,
            parameter.two,
            ...
            parameter.last),
  runResult <- run.result))
}

return(test.results)
Run Code Online (Sandbox Code Playgroud)

Ste*_*ton 2

我猜你正在 Linux 上运行,因为从你的描述来看,听起来子 R 会话正在被 Linux“内存不足杀手”杀死。巧合的是,我最近研究了直接使用 mclapply 的相同基本问题。

doMC 包使用 mclapply 函数并行执行 foreach 循环,不幸的是,当工作进程意外终止时,mclapply 不会发出错误信号。相反,mclapply 会为分配给该工作线程的所有任务返回 NULL。我认为 mclapply 中没有任何选项可以改变这种行为。

我能想到的唯一解决方法是:

  1. 使用 foreach 后端,例如 doParallel 或 doSNOW 而不是 doMC。
  2. 将结果列表中的 NULL 视为错误,并使用更少的工作程序重新运行。

如果使用 doParallel,请确保创建并注册集群对象,否则将在 Linux 系统上使用 mclapply。使用 doParallel 和 doSNOW,如果一个worker异常死亡,master从死亡的worker获取任务结果时会得到一个错误:

Error in unserialize(node$con) : error reading from connection
Run Code Online (Sandbox Code Playgroud)

在这种情况下,并行后端将捕获错误并使用指定的错误处理。

请记住,使用 doParallel 或 doSNOW 可能比 doMC 使用更多内存,因此您可能必须使用它们指定更少的工作进程以避免内存不足。