2014-04-15 11 views
5

Ich bin mit einem Code, der sehr lange dauert, um zu berechnen. Ich habe meinen Code unter Verwendung von foreach()%dopar% parallel gemacht und bin auf dem Cluster gelaufen.Rückverfolgung seltenen Fehler

Es läuft in der Regel gut, aber manchmal stürzt ab und ich bekomme die folgende Fehlermeldung: Error in { : task 4 failed - "missing value where TRUE/FALSE needed" Calls: %dopar% -> <Anonymous> Execution halted

Jetzt heißt es Execution gestoppt, sondern nur für diesen speziellen Kern so die anderen weiterlaufen und am Ende scheitert es zur Ausgabe aber doesn Sag es mir nicht vorher. Ich denke, es ist ein Problem mit einer if Aussage. Ich habe versucht, den Code auf meinem Computer zu simulieren, aber es ist so selten, dass ich es nicht simulieren kann.

Der Code kann problemlos 100 Stunden lang ausgeführt werden, wobei 100 000 Schleifen ausgeführt werden und nur einer von ihnen fehlschlägt.

Meine Fragen sind: Kann ich zurückverfolgen, wo der Fehler war? (Ich lasse den Code auf einem Cluster laufen, so dass ich nicht all die netten Rstudio-Sachen habe)
Ist es auch möglich, immer noch von einer foreach()-Schleife auszugeben, selbst wenn eine der Aufgaben abgestürzt ist?
Oder vielleicht irgendeine Methode, die Leute benutzen, damit ich den Unfall auf meinem Computer geschehen lassen kann?

Ich kann den Code bei Bedarf schreiben, bitte fragen, ob es hilft.

+0

wickeln Sie Ihre Berechnung in einem try(). Dann werden Sie alle Ergebnisse haben und in der Lage sein, das Problem zu untersuchen –

+0

@KarlForner: Ich kann nicht scheinen, "Versuch" Arbeit zu machen. Es beschwert sich über "Unerwartete Symbole", wenn es nur mein Code ist ... Gibt es eine besondere Art, es zu benutzen? Ich bin überhaupt nicht damit vertraut. – TAllieri

+1

'try' oder' trycatch' ist ein guter Rat. Eine andere Möglichkeit besteht darin, die * Eingabe * (d. H. Die j-te Datenteilmenge) zu protokollieren, die bei jedem parallelen Aufruf verwendet wird, so dass Sie die Datenmenge eingrenzen können, die das Problem verursacht hat. Stellen Sie in der Zwischenzeit sicher, dass Sie in Ihrer Funktion einen Validierungscode haben, z. B. prüfen Sie, ob 'length (something)> 0' und'! Is.na (something) 'TRUE sind, bevor Sie' if (something) 'anwenden . –

Antwort

3

Das foreach Argument ".errorhandling" soll in dieser Situation helfen. Wenn Sie möchten, dass foreach Fehler durchgibt, verwenden Sie .errorhandling="pass". Wenn Sie möchten, dass Fehler herausgefiltert werden (was die Länge des Ergebnisses reduziert), verwenden Sie .errorhandling="remove". Der Standardwert ist "stop", was einen Fehler anzeigt, der angibt, welche Aufgabe fehlgeschlagen ist.

Leider unterstützen die meisten parallelen Backends keine Tracebacks, aber doMPI tut dies. Sie rufen einfach "startMPIcluster" mit verbose=TRUE auf, und das Traceback wird in die Protokolldatei des Worker, der den Fehler hatte, geschrieben. Hier ist ein Beispiel, das einen Fehler erzeugt auf Aufgabe 42:

suppressMessages(library(doMPI)) 
cl <- startMPIcluster(4, verbose=TRUE) 
registerDoMPI(cl) 
g <- function(i) { 
    if (i == 42) { 
    if (NULL) cat('hello, world\n') 
    } 
    7 
} 
f <- function(i) g(i) 
r <- foreach(i=1:50, .errorhandling='pass') %dopar% f(i) 
print(r) 
closeCluster(cl) 
mpi.quit() 

Da es .errorhandling="pass" verwendet, das Skript ausgeführt wird bis zur Fertigstellung, mit einem Fehlerobjekt in Elemente zurück 42 des Ergebnisliste. Darüber hinaus enthält eine der Protokolldateien die eine Rückverfolgung des Fehlers (zusammen mit vielen anderen Nachrichten):

waiting for a taskchunk... 
executing taskchunk 42 containing 1 tasks 
error executing task: argument is of length zero 
traceback (most recent call first): 
> g(i) 
> f(i) 
> eval(expr, envir, enclos) 
> eval(expr, envir) 
> executeTask(taskchunk$argslist[[1]]) 
> executeTaskChunk(cl$workerid, taskchunk, envir, err, cores) 
returning error results for taskchunk 42 

Leider ist doMPI meist auf Linux-Systemen verwendet wird, so ist dies nicht hilfreich für die meisten Mac und Windows Benutzer.

+0

Danke. Ich habe versucht, doMPI am Anfang anstelle von foreach zu verwenden, leider kann der Linux-Cluster es nicht installieren. Ich habe den Administrator gebeten, es vor ein paar Monaten zu tun, aber keine Antwort :-(Würde '.errorhandling =" pass "' NA anstelle der Antwort setzen und weitermachen? Ich werde es versuchen, aber der Fehler ist sehr zufällig und selten, so könnte es in ein paar Tagen kommen. – TAllieri

+0

Wenn ich nicht mit Rmpi ​​verwechselt werde? Das ist der Fehler, den ich bekomme, wenn ich versuche, es zu installieren https://stat.ethz.ch/pipermail/r-sig-hpc/2011-May/000977.html – TAllieri

+0

@Ttellieri Ich aktualisierte die Antwort zu sagen, dass ein Fehlerobjekt zurückgegeben wird in der Ergebnisliste bei Verwendung von .errorhandling = "pass". –