MPI uygulamalarında hata ayıklamak için screen
birlikte kullanmak gdb
, özellikle xterm
kullanılamıyorsa veya birkaç işlemciyle uğraşıyorsanız, iyi çalışır. Eşlik eden yığın akışı aramalarında birçok tuzak vardı, bu yüzden çözümümü tam olarak yeniden üreteceğim.
İlk olarak, PID'yi yazdırmak için MPI_Init'ten sonra kod ekleyin ve eklemenizi beklemesi için programı durdurun. Standart çözüm sonsuz bir döngü gibi görünüyor; Sonunda raise(SIGSTOP);
, continue
gdb içinde kaçmak için fazladan bir çağrı gerektiren bir karar verdim .
}
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);
}
Derledikten sonra, yürütülebilir dosyayı arka planda çalıştırın ve stderr'i yakalayın. Daha sonra grep
her işlemin PID'sini ve sırasını almak için bazı anahtar sözcükler için (burada gerçek PID) stderr dosyasını kullanabilirsiniz .
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`)
İle her işleme bir gdb oturumu eklenebilir gdb $MDRUN_EXE $PID
. Bunu bir ekran oturumu içinde yapmak, herhangi bir gdb oturumuna kolay erişim sağlar. -d -m
ekranı bağımsız modda başlatır, ekranı -S "P$RANK"
daha sonra kolay erişim için adlandırmanıza izin verir ve -l
bash seçeneği onu etkileşimli modda başlatır ve gdb'nin hemen çıkmasını engeller.
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
Ekranlarda gdb başladığında, ekran -X stuff
komutunu kullanarak ekranlara giriş komut dosyası oluşturabilirsiniz (böylece her ekrana girip aynı şeyi yazmanıza gerek kalmaz) . Komutun sonunda yeni bir satır gereklidir. Burada ekranlara daha -S "P$i"
önce verilen isimler kullanılarak ulaşılır . -p 0
Seçenek aksi komut aralıklı (Daha önce ekrana bağlı olsun veya olmasın göre) başarısız kritiktir.
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
Bu noktada kullanarak herhangi bir ekrana takabilir ve kullanarak screen -rS "P$i"
ayırabilirsiniz Ctrl+A+D
. Komutlar, kodun önceki bölümüyle benzer şekilde tüm gdb oturumlarına gönderilebilir.