Использование screen
вместе с gdb
для отладки приложений MPI прекрасно работает, особенно если xterm
недоступен или вы имеете дело с несколькими процессорами. Было много подводных камней на пути с сопровождением поиска stackoverflow, поэтому я полностью воспроизведу свое решение.
Сначала добавьте код после MPI_Init, чтобы распечатать PID и остановить программу, чтобы дождаться, когда вы ее подключите. Стандартное решение кажется бесконечным циклом; В конце концов я остановился на raise(SIGSTOP);
, что требует дополнительного звонка continue
, чтобы сбежать внутри gdb.
}
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);
}
После компиляции запустите исполняемый файл в фоновом режиме и поймайте stderr. Затем вы можете указать grep
файл stderr для некоторого ключевого слова (здесь буквальный PID), чтобы получить PID и ранг каждого процесса.
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`)
сеанса GDB может быть присоединен к каждому процессу с gdb $MDRUN_EXE $PID
. Выполнение этого в сеансе экрана позволяет легко получить доступ к любому сеансу gdb.-d -m
запускает экран в отдельном режиме, -S "P$RANK"
позволяет вам назвать экран для легкого доступа позже, а опция -l
для bash запускает его в интерактивном режиме и немедленно отключает gdb.
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
После того, как GDB начал в экранах, вы можете ввести скрипт на экраны (так что вам не придется вводить каждый экран и введите то же самое), используя команду -X stuff
экрана. В конце команды требуется новая строка. Здесь к экранам обращаются -S "P$i"
с использованием названий, ранее указанных. Опция -p 0
имеет решающее значение, иначе команда прерывается с ошибкой (в зависимости от того, была ли вы ранее прикреплена к экрану).
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
На данный момент вы можете прикрепить к любому экрану с помощью screen -rS "P$i"
и отделяться с помощью Ctrl+A+D
. Команды могут быть отправлены на все сеансы gdb аналогично предыдущему разделу кода.
Начиная с 2010 года [Allinea DDT] (http://www.olcf.ornl.gov/2010/07/12/upgrade-adds-muscle-to-debugger/) - полнофункциональный отладчик, который масштабируется до 208k ядер – Mark 2012-05-31 12:00:10
Итак, я продолжу и поддержу @ ответ Марка. ДДТ хорош. Попробуйте тоже. TotalView теперь также интегрируется с STAT, поэтому, если ваш сайт имеет установку TotalView, вы также можете попробовать это. LLNL поддерживает TotalView и DDT, и хорошо, что TotalView, наконец, имеет жесткую конкуренцию. – tgamblin 2012-06-07 00:13:27
Я хотел бы добавить ссылку на FAQ по отладке MPI (http://www.open-mpi.org/faq/?category=debugging#serial-debuggers). В частности, bullet 6 является хорошим, быстрым и легким (достаточно даже для меня!), Чтобы понять способ, по крайней мере, отладить отдельный процесс. – Jeff 2012-08-19 18:30:26