Die Verwendung screen
zusammen mit gdb
zum Debuggen von MPI-Anwendungen funktioniert gut, insbesondere wenn diese xterm
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 erfordert continue
, um innerhalb von GDB zu entkommen.
}
int i, id, nid;
MPI_Comm_rank(MPI_COMM_WORLD,&id);
MPI_Comm_size(MPI_COMM_WORLD,&nid);
for (i=0; i<nid; i++) {
MPI_Barrier(MPI_COMM_WORLD);
if (i==id) {
fprintf(stderr,"PID %d rank %d\n",getpid(),id);
}
MPI_Barrier(MPI_COMM_WORLD);
}
raise(SIGSTOP);
}
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.
MDRUN_EXE=../../Your/Path/To/bin/executable
MDRUN_ARG="-a arg1 -f file1 -e etc"
mpiexec -n 1 $MDRUN_EXE $MDRUN_ARG >> output 2>> error &
sleep 2
PIDFILE=pid.dat
grep PID error > $PIDFILE
PIDs=(`awk '{print $2}' $PIDFILE`)
RANKs=(`awk '{print $4}' $PIDFILE`)
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.
for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
PID=${PIDs[$i]}
RANK=${RANKs[$i]}
screen -d -m -S "P$RANK" bash -l -c "gdb $MDRUN_EXE $PID"
done
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).
for i in `awk 'BEGIN {for (i=0;i<'${#PIDs[@]}';i++) {print i}}'`
do
screen -S "P$i" -p 0 -X stuff "set logging file debug.$i.log
"
screen -S "P$i" -p 0 -X stuff "set logging overwrite on
"
screen -S "P$i" -p 0 -X stuff "set logging on
"
screen -S "P$i" -p 0 -X stuff "source debug.init
"
done
An dieser Stelle können Sie mit jedem Bildschirm anhängen screen -rS "P$i"
und mit entfernen Ctrl+A+D
. Befehle können analog zum vorherigen Codeabschnitt an alle GDB-Sitzungen gesendet werden.