MPI uygulamalarında hata ayıklamak için screenbirlikte kullanmak gdb, özellikle xtermkullanı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);, continuegdb 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 grepher 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 -mekranı bağımsız modda başlatır, ekranı -S "P$RANK"daha sonra kolay erişim için adlandırmanıza izin verir ve -lbash 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 stuffkomutunu 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 0Seç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.