在Linux中使用McLappy时R中出现奇怪的错误
我遇到了这个奇怪的segfault错误,对如何解决它一无所知。我在运行一些马尔可夫链蒙特卡罗算法(一种近似分布的顺序算法)。我将这个算法的每一次迭代并行化。所以有点像在Linux中使用McLappy时R中出现奇怪的错误,r,linux,parallel-processing,segmentation-fault,mclapply,R,Linux,Parallel Processing,Segmentation Fault,Mclapply,我遇到了这个奇怪的segfault错误,对如何解决它一无所知。我在运行一些马尔可夫链蒙特卡罗算法(一种近似分布的顺序算法)。我将这个算法的每一次迭代并行化。所以有点像 for (iter in 1:T){ res[iter] = mclapply(fun) } 现在奇怪的是,当我的数据集的大小相对适中时,算法可以毫无问题地运行。然后我增加数据集的大小(80000个观察值,不是超大),算法在前1000次迭代中有效,然后在出现segfault错误时停止。我已将错误粘贴到下面: *** caug
for (iter in 1:T){
res[iter] = mclapply(fun)
}
现在奇怪的是,当我的数据集的大小相对适中时,算法可以毫无问题地运行。然后我增加数据集的大小(80000个观察值,不是超大),算法在前1000次迭代中有效,然后在出现segfault
错误时停止。我已将错误粘贴到下面:
*** caught segfault ***
address 0x20, cause 'memory not mapped'
Traceback:
1: mcfork()
2: FUN(X[[i]], ...)
3: lapply(seq_len(cores), inner.do)
4: mclapply(1:n, FUN = function(k) { return(OptimRE(dataSummaries[[k]], mu + beta, v, vre))}, mc.cores = ncores)
5: getMargLikelihood0(dataSummaries_layer1[[k]], mu, v, vre, beta[k], logarithm = TRUE)
6: FUN(X[[i]], ...)
7: lapply(X = S, FUN = FUN, ...)
8: doTryCatch(return(expr), name, parentenv, handler)
9: tryCatchOne(expr, names, parentenv, handlers[[1L]])
10: tryCatchList(expr, classes, parentenv, handlers)
11: tryCatch(expr, error = function(e) { call <- conditionCall(e) if (!is.null(call)) { if (identical(call[[1L]], quote(doTryCatch))) call <- sys.call(-4L) dcall <- deparse(call)[1L] prefix <- paste("Error in", dcall, ": ") LONG <- 75L msg <- conditionMessage(e) sm <- strsplit(msg, "\n")[[1L]] w <- 14L + nchar(dcall, type = "w") + nchar(sm[1L], type = "w") if (is.na(w)) w <- 14L + nchar(dcall, type = "b") + nchar(sm[1L], type = "b") if (w > LONG) prefix <- paste0(prefix, "\n ") } else prefix <- "Error : " msg <- paste0(prefix, conditionMessage(e), "\n") .Internal(seterrmessage(msg[1L])) if (!silent && identical(getOption("show.error.messages"), TRUE)) { cat(msg, file = stderr()) .Internal(printDeferredWarnings()) } invisible(structure(msg, class = "try-error", condition = e))})
12: try(lapply(X = S, FUN = FUN, ...), silent = TRUE)
13: sendMaster(try(lapply(X = S, FUN = FUN, ...), silent = TRUE))
14: FUN(X[[i]], ...)
15: lapply(seq_len(cores), inner.do)
16: mclapply(1:length(beta), FUN = function(k) { return(getMargLikelihood0(dataSummaries_layer1[[k]], mu, v, vre, beta[k], logarithm = TRUE))}, mc.cores = ncores)
17: getMargLikelihood(dataSummaries_layer1, newm, news, newv, beta1)
18: FitPoissRegNRE(my[j, ], groupid, id1, id2, nb = nb, nc = nc, sig = sig, a = a, b = b, a2 = a2[j], b2 = b2[j], ps_m = ps_m, ps_s = ps_s, njump = njump)
19: ApplyFitPoissRegNRE(y, hashABC, hashAB, hashA, nb = 200, nc = 800, sig = 1000, a = 2, b = 2, a2 = rep(100, 3), b2 = rep(5, 3), ps_m = 0.01, ps_s = 0.03, njump = 4)
20: eval(expr, envir, enclos)
21: eval(ei, envir)
22: withVisible(eval(ei, envir))
***捕捉到故障***
地址0x20,导致“内存未映射”
回溯:
1:mcfork()
2:乐趣(X[[i]],…)
3:lappy(序列长度(芯),内部do)
4:mclapply(1:n,FUN=function(k){return(OptimRE(dataSummaries[[k]],mu+beta,v,vre))},mc.cores=ncores)
5:getMargLikelihood0(数据摘要_layer1[[k]],μ,v,vre,β[k],对数=TRUE)
6:乐趣(X[[i]],…)
7:lappy(X=S,FUN=FUN,…)
8:doTryCatch(返回(expr)、名称、parentenv、处理程序)
9:tryCatchOne(expr、name、parentenv、handlers[[1L]])
10:tryCatchList(expr、类、parentenv、处理程序)
11:tryCatch(expr,error=function(e){call对mclappy
函数的每次调用可能都会在僵尸进程周围留下。由于您反复调用它,可能会积累大量的僵尸进程,最终导致问题
您可以使用inline
包创建一个函数,该函数等待所有子进程以摆脱僵尸进程:
library(inline)
includes <- '#include <sys/wait.h>'
code <- 'int wstat; while (waitpid(-1, &wstat, WNOHANG) > 0) {};'
wait <- cfunction(body=code, includes=includes, convention='.C')
除了Steve关于检查僵尸进程的建议之外,还有一条评论:看起来您的代码是通过递归调用生成的mclappy(…,mc.cores=ncores)
4: mclapply(1:n, FUN = function(k) { return(OptimRE(dataSummaries[[k]], mu + beta, v, vre))}, mc.cores = ncores)
[...]
16: mclapply(1:length(beta), FUN = function(k) { return(getMargLikelihood0(dataSummaries_layer1[[k]], mu, v, vre, beta[k], logarithm = TRUE))}, mc.cores = ncores)
换句话说,你可能会以“ncores*ncores”结束每次迭代中都会出现分叉进程。我不知道这两个ncore
是什么,但一定要检查这是否是您真正想要的。这是一个很好的发现!我确实有一个嵌套的McLappy,我在当前的测试中与Steve的建议一起更改了它,问题得到了解决!该测试非常耗时,因此我无法进行测试控制测试,以判断问题是由您的建议解决还是由Steve的解决。这两种方法肯定都有助于代码的稳定性。我选择Steve的方法作为答案,因为它已在前面发布:)对于它的价值,foreach和许多其他并行包包装器也会发生同样的情况。。。
4: mclapply(1:n, FUN = function(k) { return(OptimRE(dataSummaries[[k]], mu + beta, v, vre))}, mc.cores = ncores)
[...]
16: mclapply(1:length(beta), FUN = function(k) { return(getMargLikelihood0(dataSummaries_layer1[[k]], mu, v, vre, beta[k], logarithm = TRUE))}, mc.cores = ncores)