2017-03-27 4 views
1

Ich habe diesen seltsamen segfault Fehler festgestellt und habe keine Ahnung, wie man es löst. Ich habe einen Markov-Chain-Monte-Carlo-Algorithmus (einen sequentiellen Algorithmus, der eine Verteilung approximiert) ausgeführt. Ich parallelisiere jede einzelne Iteration dieses Algorithmus. Es ist also so etwas wieseltsame segfault in R bei Verwendung von mclapply in Linux

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

Nun ist die seltsame Sache ist, wenn die Größe meines Datensatzes relativ moderat ist, kann der Algorithmus ohne Probleme laufen. Dann vergrößere ich die Datensatzgröße (80.000 Beobachtungen, nicht super groß), der Algorithmus arbeitet für die ersten eintausend Iterationen und stoppt dann mit einem segfault Fehler. Ich habe den Fehler unten eingefügt:

*** 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)) 

Ich habe gegoogelt und einige Leute haben dieses Problem segfalut in R begegnen und was sie in der Regel einige Versionskonflikt vorgeschlagen ist und R neu installiert werden soll. Aber das Seltsame in meinem Fall ist, dass mein Algorithmus in den ersten tausend Iterationen richtig funktioniert. Ich lief es auch ohne Parallelisierung und es funktioniert auch gut.

Kann jemand vorschlagen, was mögliche Ursachen dafür ist? Jetzt habe ich komplett keine Richtung mehr.

Danke!

Antwort

1

Jeder Aufruf der mclapply Funktion kann um Zombie-Prozesse verlassen. Da du es immer wieder anrufst, könntest du eine große Anzahl von ihnen ansammeln und schließlich Probleme verursachen.

Sie können das inline Paket um eine Funktion erstellen, die von Zombie-Prozesse, um loszuwerden, für alle untergeordneten Prozesse wartet:

library(inline) 
includes <- '#include <sys/wait.h>' 
code <- 'int wstat; while (waitpid(-1, &wstat, WNOHANG) > 0) {};' 
wait <- cfunction(body=code, includes=includes, convention='.C') 

Wenn Sie wait im for Schleife nach mclapply nennen, sollte es loswerden alle Zombies und beseitigen diese als mögliches Problem:

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

ein Kommentar neben Steve Vorschlag für Zombie-Prozesse zu überprüfen: Es sieht aus wie Ihr Code ist Laichen wiederkehrt ive mclapply(..., mc.cores = ncores) Anrufe;

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) 

Mit anderen Worten, können Sie mit "ncores * ncores" gegabelt Prozesse in jeder Iteration enden. Ich weiß nicht, was die beiden ncores hier sind, aber stellen Sie sicher, dass dies wirklich das ist, was Sie wollen.

+0

Das ist ein guter Fang! Ich hatte ein verschachteltes Mclappli und ich änderte das in meinem aktuellen Test zusammen mit Steves Vorschlag und die Probleme wurden gelöst! Der Test ist zeitaufwendig, daher kann ich keinen Kontrolltest durchführen, um festzustellen, ob das Problem durch Ihren Vorschlag oder von Steve gelöst wurde. Auf jeden Fall hilft beides in Bezug auf die Stabilität des Codes. Ich wählte Steve als Antwort, da es früher gepostet wurde :) – Bayesric

Verwandte Themen