【问题标题】:weird segfault in R when using mclapply in Linux在 Linux 中使用 mclapply 时,R 中出现奇怪的段错误
【发布时间】:2017-03-27 15:41:13
【问题描述】:

我遇到了这个奇怪的段错误并且零线索如何解决它。我正在运行一些马尔可夫链蒙特卡罗算法(一种近似分布的顺序算法)。我并行化了这个算法的每一次迭代。所以它就像

for (iter in 1:T){
  res[iter] = mclapply(fun)
}

现在奇怪的是,当我的数据集大小相对适中时,算法可以毫无问题地运行。然后我增加数据集大小(80,000 个观察值,不是超大),该算法适用于前一千次迭代,然后以 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))

我用谷歌搜索过,有些人确实在 R 中遇到了这个segfalut 问题,他们通常建议是一些版本冲突,应该重新安装 R。但就我而言,奇怪的是我的算法在前一千次迭代中运行良好。我也在没有并行化的情况下运行它,它也可以正常工作。

谁能提出一些可能的原因?现在我完全没有方向了。

谢谢!

【问题讨论】:

    标签: r linux parallel-processing segmentation-fault mclapply


    【解决方案1】:

    mclapply 函数的每次调用都可能会绕过僵尸进程。由于您反复调用它,因此可能会累积大量它们,最终导致问题。

    您可以使用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')
    

    如果您在mclapply 之后的for 循环中调用wait,它应该会消除任何僵尸并将其作为可能的问题消除:

    for (iter in 1:T) {
      res[iter] = mclapply(1:10, fun)
      wait()
    }
    

    【讨论】:

    • 对于它的价值,完全相同的事情发生在 foreach 和可能许多其他并行包包装器上......
    【解决方案2】:

    除了 Steve 关于检查僵尸进程的建议之外的评论:看起来您的代码正在产生递归 mclapply(..., 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”分叉进程。我不知道这两个ncores 是什么,但请确保检查这是否真的是您想要的。

    【讨论】:

    • 这是一个很好的收获!我确实有一个嵌套的 mclapply,我在当前的测试中连同史蒂夫的建议一起改变了它,问题得到了解决!该测试非常耗时,因此我无法进行控制测试来判断问题是否通过您的建议或史蒂夫的建议得到解决。绝对两者都有助于代码的稳定性。我选择了史蒂夫作为答案,因为它是较早发布的:)
    猜你喜欢
    • 2016-05-31
    • 2021-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多