Ich habe ein MPI-Programm, das kompiliert und ausgeführt wird, aber ich möchte es durchgehen, um sicherzustellen, dass nichts Seltsames passiert. Im Idealfall möchte ich eine einfache Möglichkeit, GDB an einen bestimmten Prozess anzuhängen, bin mir jedoch nicht sicher, ob dies möglich ist oder wie dies zu tun ist. Eine Alternative wäre, dass jeder Prozess die Debug-Ausgabe in eine separate Protokolldatei schreibt. Dies bietet jedoch nicht die gleiche Freiheit wie ein Debugger.
Gibt es bessere Ansätze? Wie debuggen Sie MPI-Programme?
Ich habe gdb sehr nützlich gefunden. Ich benutze es als
Dies startet xterm Windows, in dem ich tun kann
funktioniert normalerweise gut
Sie können diese Befehle auch zusammen packen, indem Sie:
quelle
<file>
und-x <file>
an gdb übergeben.Viele der Beiträge hier befassen sich mit GDB, erwähnen jedoch nicht, wie Sie einen Prozess vom Start an anhängen können. Natürlich können Sie an alle Prozesse anhängen:
Dies ist jedoch äußerst ineffektiv, da Sie herumspringen müssen, um alle Ihre Prozesse zu starten. Wenn Sie nur einen (oder eine kleine Anzahl) MPI-Prozess debuggen möchten, können Sie diesen mithilfe des
:
Operators als separate ausführbare Datei in der Befehlszeile hinzufügen :Jetzt erhält nur einer Ihrer Prozesse GDB.
quelle
Wie andere erwähnt haben, sind , wenn Sie mit einem Arbeitshandvoll von MPI Prozesse , die Sie verwenden können versuchen , mehrere GDB - Sitzungen , die gefürchtete valgrind oder rollen Sie Ihre eigenen printf / Logging - Lösung.
Wenn Sie mehr Prozesse verwenden, benötigen Sie wirklich einen geeigneten Debugger. In den OpenMPI-FAQ werden sowohl Allinea DDT als auch TotalView empfohlen .
Ich arbeite an Allinea DDT . Es ist ein grafischer Quellcode-Debugger mit vollem Funktionsumfang. Ja, Sie können:
...und so weiter. Wenn Sie Eclipse oder Visual Studio verwendet haben, sind Sie hier genau richtig.
Wir haben einige interessante Funktionen speziell für das Debuggen von parallelem Code hinzugefügt (sei es MPI, Multithread oder CUDA):
Skalare Variablen werden automatisch über alle Prozesse hinweg verglichen: (Quelle: allinea.com )
Sie können auch die Werte von Variablen und Ausdrücken über Prozesse und Zeit verfolgen und filtern:
Es ist weit verbreitet unter Top500 HPC-Standorten wie ORNL , NCSA , LLNL , Jülich et. al.
Die Oberfläche ist ziemlich bissig; Im Rahmen der Abnahmetests für den Jaguar-Cluster von Oak Ridge haben wir die Stapel und Variablen von 220.000 Prozessen bei 0,1 Sekunden zeitlich festgelegt und zusammengeführt.
@tgamblin erwähnte den exzellenten STAT , der in Allinea DDT integriert ist , ebenso wie einige andere beliebte Open Source-Projekte.
quelle
http://valgrind.org/ nuf sagte
Spezifischerer Link: Debuggen von MPI-Parallelprogrammen mit Valgrind
quelle
Wenn Sie ein
tmux
Benutzer sind, werden Sie sich mit dem Skript von Benedikt Morbach sehr wohl fühlen :tmpi
Originalquelle:
https://github.com/moben/scripts/blob/master/tmpiGabel: https://github.com/Azrael3000/tmpi
Damit haben Sie mehrere Panels (Anzahl der Prozesse) synchronisiert (jeder Befehl wird gleichzeitig auf alle Panels oder Prozesse kopiert, sodass Sie im Vergleich zum
xterm -e
Ansatz viel Zeit sparen ). Darüber hinaus können Sie die Werte der Variablen in dem Prozess kennen, den Sie gerade ausführen möchten,print
ohne in ein anderes Fenster wechseln zu müssen. Dadurch werden auf jedem Feld die Werte der Variablen für jeden Prozess gedruckt.Wenn Sie kein
tmux
Benutzer sind, empfehle ich dringend, es zu versuchen und zu sehen.quelle
http://github.com/jimktrains/pgdb/tree/master ist ein Dienstprogramm, das ich geschrieben habe, um genau dies zu tun. Es gibt einige Dokumente und Sie können mich gerne bei Fragen kontaktieren.
Sie rufen im Grunde ein Perl-Programm auf, das GDB umschließt und dessen E / A an einen zentralen Server überträgt. Auf diese Weise kann GDB auf jedem Host ausgeführt werden und Sie können auf jedem Host am Terminal darauf zugreifen.
quelle
Die Verwendung
screen
zusammen mitgdb
zum Debuggen von MPI-Anwendungen funktioniert gut, insbesondere wenn diesexterm
nicht verfügbar sind oder Sie mit mehr als einigen Prozessoren arbeiten. Es gab viele Fallstricke auf dem Weg mit begleitenden Stackoverflow-Suchen, daher werde ich meine Lösung vollständig reproduzieren.Fügen Sie zunächst nach MPI_Init Code hinzu, um die PID auszudrucken, und halten Sie das Programm an, um auf das Anhängen zu warten. Die Standardlösung scheint eine Endlosschleife zu sein; Ich habe mich schließlich entschieden
raise(SIGSTOP);
, was einen zusätzlichen Anruf erfordertcontinue
, um innerhalb von GDB zu entkommen.Führen Sie nach dem Kompilieren die ausführbare Datei im Hintergrund aus und fangen Sie den stderr ab. Sie können dann
grep
die stderr-Datei für ein Schlüsselwort (hier wörtliche PID) verwenden, um die PID und den Rang jedes Prozesses zu erhalten.Mit jedem Prozess kann eine GDB-Sitzung verbunden werden
gdb $MDRUN_EXE $PID
. Dies innerhalb einer Bildschirmsitzung zu tun, ermöglicht den einfachen Zugriff auf jede GDB-Sitzung.-d -m
Startet den Bildschirm im getrennten Modus,-S "P$RANK"
ermöglicht es Ihnen, den Bildschirm für einen späteren einfachen Zugriff zu benennen, und die-l
Option zum Bash startet ihn im interaktiven Modus und verhindert, dass gdb sofort beendet wird.Sobald gdb in den Bildschirmen gestartet wurde, können Sie mit dem
-X stuff
Befehl des Bildschirms Skripteingaben in die Bildschirme schreiben (damit Sie nicht jeden Bildschirm eingeben und dasselbe eingeben müssen) . Am Ende des Befehls ist eine neue Zeile erforderlich. Hier wird auf die Bildschirme unter-S "P$i"
Verwendung der zuvor angegebenen Namen zugegriffen . Die-p 0
Option ist kritisch, andernfalls schlägt der Befehl zeitweise fehl (je nachdem, ob Sie zuvor eine Verbindung zum Bildschirm hergestellt haben oder nicht).An dieser Stelle können Sie mit jedem Bildschirm anhängen
screen -rS "P$i"
und mit entfernenCtrl+A+D
. Befehle können analog zum vorherigen Codeabschnitt an alle GDB-Sitzungen gesendet werden.quelle
Es gibt auch mein Open-Source-Tool padb, das bei der parallelen Programmierung helfen soll. Ich nenne es ein "Job Inspection Tool", da es nicht nur als Debugger fungiert, sondern auch als paralleles Top-ähnliches Programm. Im Modus "Vollständiger Bericht" werden die Spuren jedes Prozesses in Ihrer Anwendung sowie lokale Variablen für jede Funktion über jeden Rang gestapelt (vorausgesetzt, Sie haben mit -g kompiliert). Außerdem werden die "MPI-Nachrichtenwarteschlangen" angezeigt, dh die Liste der ausstehenden Sende- und Empfangsvorgänge für jeden Rang innerhalb des Jobs.
Neben der Anzeige des vollständigen Berichts ist es Padb auch möglich, einzelne Informationen innerhalb des Jobs zu vergrößern. Es gibt eine Vielzahl von Optionen und Konfigurationselementen, mit denen Sie steuern können, welche Informationen angezeigt werden. Weitere Informationen finden Sie auf der Webseite.
Padb
quelle
Die "Standard" -Methode zum Debuggen von MPI-Programmen ist die Verwendung eines Debuggers, der dieses Ausführungsmodell unterstützt.
Unter UNIX Totalview ist die gute suppoort für MPI haben.
quelle
Ich verwende diese kleine Homebrewn-Methode, um den Debugger an MPI-Prozesse anzuhängen. Rufen Sie die folgende Funktion, DebugWait (), direkt nach MPI_Init () in Ihrem Code auf. Während die Prozesse auf Tastatureingaben warten, haben Sie jederzeit Zeit, den Debugger an sie anzuhängen und Haltepunkte hinzuzufügen. Wenn Sie fertig sind, geben Sie eine einzelne Zeicheneingabe ein und Sie können loslegen.
Natürlich möchten Sie diese Funktion nur für Debug-Builds kompilieren.
quelle
gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);
. Anschließend fügen Sie den Vorgang durch Eingabe vonrsh <hostname_from_print_statement>
und schließlich hinzugdb --pid=<PID_from_print_statement>
.Der Befehl zum Anhängen von gdb an einen mpi-Prozess ist unvollständig
Eine kurze Diskussion über mpi und gdb finden Sie hier
quelle
Eine ganz einfache Möglichkeit, ein MPI-Programm zu debuggen.
In der Funktion main () addiere sleep (some_seconds)
Führen Sie das Programm wie gewohnt aus
Das Programm startet und geht in den Schlaf.
Sie haben also einige Sekunden Zeit, um Ihre Prozesse nach ps zu finden, gdb auszuführen und an sie anzuhängen.
Wenn Sie einen Editor wie QtCreator verwenden, können Sie diesen verwenden
Debug-> Debugging starten-> An laufende Anwendung anhängen
und finden Sie dort Prozesse.
quelle
Ich führe ein MPI-bezogenes Debugging mit Protokollspuren durch, aber Sie können gdb auch ausführen, wenn Sie mpich2: MPICH2 und gdb verwenden . Diese Technik ist im Allgemeinen eine gute Vorgehensweise, wenn Sie mit einem Prozess arbeiten, dessen Start über einen Debugger schwierig ist.
quelle
mpirun -gdb
Vielen Dank an http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/CommonDoc/mpich2_gdb.html ( Archivlink )
quelle
Eine andere Lösung besteht darin, Ihren Code in SMPI, dem simulierten MPI, auszuführen. Das ist ein Open Source Projekt, an dem ich beteiligt bin. Jeder MPI-Rang wird in Threads desselben UNIX-Prozesses konvertiert. Sie können dann einfach gdb verwenden, um die MPI-Ränge zu erhöhen.
SMPI bietet weitere Vorteile für die Untersuchung von MPI-Anwendungen: Hellsehen (Sie können alle Teile des Systems beobachten), Reproduzierbarkeit (mehrere Läufe führen zu genau demselben Verhalten, sofern Sie dies nicht angeben), Fehlen von Heisenbugs (da die simulierte Plattform unterschiedlich gehalten wird vom Gastgeber) usw.
Weitere Informationen finden Sie in dieser Präsentation oder in der entsprechenden Antwort .
quelle