Как отладить программу MPI?

У меня есть программа MPI, которая компилируется и запускается, но я хотел бы пройти через нее, чтобы убедиться, что ничего странного не происходит. В идеале, я хотел бы просто подключить GDB к любому конкретному процессу, но я не уверен, что это возможно или как это сделать. Альтернативой будет каждый процесс записи отладки вывода в отдельный файл журнала, но на самом деле это не дает такой же свободы, как отладчик.

Есть ли лучшие подходы? Как вы отлаживаете программы MPI?

Как сказал кто-то другой, TotalView является стандартом для этого. Но это будет стоить вам руки и ноги.

На сайте OpenMPI есть большой FAQ по отладке MPI . В пункте № 6 раздела «Часто задаваемые вопросы» описывается, как подключать процессы GDB к MPI. Прочитайте все, есть отличные советы.

Если вы обнаружите, что у вас слишком много процессов для отслеживания, проверьте инструмент анализа стека (STAT) . Мы используем это в Ливерморе, чтобы собирать трассировки стека из потенциально сотен тысяч запущенных процессов и представлять их разумно для пользователей. Это не полнофункциональный отладчик (полнофункциональный отладчик никогда не масштабируется до 208k ядер), но он расскажет вам, какие группы процессов делают то же самое. Затем вы можете вывести представителя из каждой группы в стандартный отладчик.

Я нашел gdb весьма полезным. Я использую его как

mpirun -np  xterm -e gdb ./program 

Это запускает windows xterm, в которых я могу сделать

 run   ...  

обычно работает нормально

Вы также можете объединить эти команды, используя:

 mpirun -n  xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...] 

Многие из сообщений здесь относятся к GDB, но не упоминают, как подключиться к процессу с момента запуска. Очевидно, что вы можете подключаться ко всем процессам:

 mpiexec -n X gdb ./a.out 

Но это дико неэффективно, так как вам придется отскакивать, чтобы запустить все ваши процессы. Если вы просто хотите отладить один (или несколько) MPI-процесс, вы можете добавить это как отдельный исполняемый файл в командной строке с помощью оператора:

 mpiexec -n 1 gdb ./a.out : -n X-1 ./a.out 

Теперь только один из ваших процессов получит GDB.

Как уже упоминалось, если вы работаете только с несколькими процессами MPI, вы можете попытаться использовать несколько сеансов gdb , redoubtable valgrind или запустить собственное решение printf / logging.

Если вы используете больше процессов, чем это, вы действительно начинаете нуждаться в надлежащем отладчике. Часто задаваемые вопросы OpenMPI рекомендуют как Allinea DDT, так и TotalView .

Я работаю над Allinea DDT . Это полнофункциональный графический отладчик исходного кода, поэтому да, вы можете:

  • Отладка или подключение к процессам MPI (более 200 тыс.)
  • Шаг и приостановить их группами или индивидуально
  • Добавить контрольные точки, часы и контрольные точки
  • Поймать ошибки памяти и утечки

…и так далее. Если вы использовали Eclipse или Visual Studio, тогда вы будете дома.

Мы добавили некоторые интересные функции специально для отладки параллельного кода (будь то MPI, multithreading или CUDA):

  • Скалярные переменные автоматически сравниваются по всем процессам: Sparklines, показывающий значения в процессах

  • Вы также можете отслеживать и фильтровать значения переменных и выражений над процессами и временем: Значения журналов трассировки во времени

Он широко используется среди 500 сайтов HPC, таких как ORNL , NCSA , LLNL , Jülich et. и др.

Интерфейс довольно быстрый; мы приурочили постепенное и слияние стеков и переменных 220 000 процессов в 0,1 с в рамках приемочных испытаний на кластере Jaguar Oak Ridge.

@tgamblin упомянула отличную STAT , которая интегрируется с Allinea DDT , а также некоторые другие популярные проекты с открытым исходным кодом.

http://valgrind.org/ nuf сказал


Более конкретная ссылка: отладка параллельных программ MPI с Valgrind

http://github.com/jimktrains/pgdb/tree/master – это полезность, которую я написал для этого. Есть несколько документов и не стесняйтесь меня на вопросы.

Вы в основном называете Perl-программу, которая обертывает GDB и вставляет ее IO на центральный сервер. Это позволяет GDB запускаться на каждом хосте и получать доступ к нему на каждом хосте на терминале.

Использование 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 

После компиляции запустите исполняемый файл в фоновом режиме и поймайте 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 аналогично предыдущему разделу кода.

«Стандартный» способ отладки программ MPI – это использование отладчика, который поддерживает эту модель исполнения.

В UNIX TotalView, как говорят, имеет хороший Suppoort для MPI.

Я использую этот маленький метод homebrewn для присоединения отладчика к процессам MPI – вызовите следующую функцию DebugWait (), сразу после MPI_Init () в вашем коде. Теперь, пока процессы ждут ввода с клавиатуры, вы все время присоединяете к ним отладчик и добавляете контрольные точки. Когда вы закончите, укажите один ввод символов, и вы готовы к работе.

 static void DebugWait(int rank) { char a; if(rank == 0) { scanf("%c", &a); printf("%d: Starting now\n", rank); } MPI_Bcast(&a, 1, MPI_BYTE, 0, MPI_COMM_WORLD); printf("%d: Starting now\n", rank); } 

Конечно, вы захотите скомпилировать эту функцию только для отладочных compilationов.

Существует также мой инструмент с открытым исходным кодом, padb, который призван помочь в параллельном программировании. Я называю это «Инструментом осмотра работы», поскольку он функционирует не только потому, что отладчик также может функционировать, например, как параллельная программа, подобная вершине. Запустив режим «Полный отчет», он покажет вам стековые следы каждого процесса в вашем приложении вместе с локальными переменными для каждой функции над каждым рангом (при условии, что вы скомпилированы с -g). Он также покажет вам «очереди сообщений MPI», то есть список выдающихся отправлений и получения для каждого ранга в задании.

Помимо показа полного отчета, можно также указать padb для увеличения отдельных бит информации в задании, имеется множество опций и элементов конфигурации для контроля, какая информация отображается, см. Веб-страницу для более подробной информации.

PADB

Если вы являетесь пользователем tmux вам будет очень удобно пользоваться сценарием Бенедикта tmpi : tmpi

Исходный источник: https://github.com/moben/scripts/blob/master/tmpi

Вилка: https://github.com/Azrael3000/tmpi

При этом у вас есть несколько панелей (количество процессов), все синхронизированы (каждая команда копируется на все панели или процессы одновременно, поэтому вы сохраняете много времени по сравнению с подходом xterm -e ). Кроме того, вы можете знать значения переменных в процессе, который вы хотите просто выполнять print не переходя на другую панель, это будет печатать на каждой панели значения переменной для каждого процесса.

Если вы не являетесь пользователем tmux я настоятельно рекомендую его попробовать и посмотреть.

Команда для подключения gdb к процессу mpi является неполной, она должна быть

 mpirun -np  xterm -e gdb ./program 

Краткое описание mpi и gdb можно найти здесь

Я делаю некоторую отладку, связанную с MPI, с трассировкой журнала, но вы также можете запустить gdb, если вы используете mpich2: MPICH2 и gdb . Этот метод является хорошей практикой в ​​целом, когда вы имеете дело с процессом, который сложно запускать из отладчика.

Другим решением является запуск вашего кода в SMPI, моделируемый MPI. Это проект с открытым исходным кодом, в котором я участвую. Каждый ранг MPI будет преобразован в streamи одного и того же процесса UNIX. Затем вы можете легко использовать gdb для установки рангов MPI.

SMPI предлагает другие преимущества для изучения приложений MPI: clairevoyance (вы можете наблюдать за каждой частью системы), воспроизводимость (несколько прогонов приводят к точному поведению, если вы не указали это), отсутствие heisenbugs (так как имитируемая платформа поддерживается разными от хоста) и т. д.

Для получения дополнительной информации см. Эту презентацию или соответствующий ответ .

Достаточно простой способ отладки программы MPI.

В функции main () добавьте sleep (some_seconds)

Запускать программу как обычно

 $ mpirun -np    

Программа начнется и начнет спать.

Таким образом, у вас будет несколько секунд, чтобы найти процессы с помощью ps, запустить gdb и приложить к ним.

Если вы используете какой-то редактор, такой как QtCreator, вы можете использовать

Debug-> Начать отладку-> Приложить к запущенному приложению

и найти там процессы.

  • Что такое «Async Pinned Handle»?
  • Не удалось подключиться к серверу ASP.Net Development Server
  • Как мне работать с ClassNotLoadedException во время отладки?
  • Простой способ отладки службы Windows
  • Как читать и понимать трассировку стека java?
  • Печать коллекций Java Nicely (toString не возвращает довольно вывод)
  • Как добавить NSDebug.h и использовать NSZombie в iPhone SDK
  • NoSuchFieldError Java
  • Как вы отлаживаете хранимые процедуры MySQL?
  • Шаг в свойство / функцию (F11) не работает должным образом
  • ERROR 1066: невозможно открыть iterator для псевдонима в Pig, Generic solution
  • Давайте будем гением компьютера.