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

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

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


person Jay Conrod    schedule 30.11.2008    source источник


Ответы (17)


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

На сайте OpenMPI есть отличный FAQ по отладке MPI. Пункт № 6 в FAQ описывает, как присоединить GDB к процессам MPI. Прочтите все, есть несколько отличных советов.

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

person Todd Gamblin    schedule 12.12.2008
comment
По состоянию на 2010 г. Allinea DDT это полнофункциональный отладчик, масштабируемый до более чем 208 тыс. ядер. - person Mark; 31.05.2012
comment
Так что я продолжу и проголосую за ответ @Mark здесь. ДДТ - это хорошо. Попробуйте тоже. TotalView теперь также интегрируется со STAT, поэтому, если на вашем сайте есть установка TotalView, вы также можете попробовать это. LLNL поддерживает TotalView и DDT, и приятно, что у TotalView наконец-то появилась жесткая конкуренция. - person Todd Gamblin; 07.06.2012
comment
Я хотел бы добавить ссылку на FAQ по отладке MPI (open -mpi.org/faq/?category=debugging#serial-debuggers). В частности, пункт 6 - хороший, быстрый и простой (достаточно даже для меня!) Способ хотя бы отладки отдельного процесса. - person Jeff; 19.08.2012
comment
Шаги в №6 на странице часто задаваемых вопросов отлично сработали для меня и помогли разобраться в моей проблеме. Большое спасибо за это. - person Jon Deaton; 07.11.2017

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

mpirun -np <NP> xterm -e gdb ./program 

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

run <arg1> <arg2> ... <argN>

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

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

mpirun -n <NP> xterm -hold -e gdb -ex run --args ./program [arg1] [arg2] [...]
person messenjah    schedule 02.03.2010
comment
Как я могу отправить один и тот же ввод для всех NP gdb xterms? Например, я хочу добавить по две точки останова к каждому процессу, а есть 16 процессов. Есть ли альтернатива xterm для этого? Можем ли мы объединить сеансы в один экземпляр screen, tmux или Terminator Криса Джонса? - person osgx; 24.09.2015
comment
@osgx Вы можете сделать это, сохранив команды (break xxx, break yyy, run) в <file> и передав -x <file> в gdb. - person eush77; 22.05.2016
comment
но я обнаружил ошибку, сообщение об ошибке - ошибка execvp в файле xterm (такого файла или каталога нет) - person hitwlh; 28.12.2016
comment
когда я пробую это с jdb и OpenMPI, это не работает, т.е. каждый экземпляр jdb видит num_ranks из 1 вместо того, что задано аргументу -np. есть идеи почему? - person Michel Müller; 02.10.2018

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

mpiexec -n X gdb ./a.out

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

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

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

person Wesley Bland    schedule 26.07.2013
comment
Я могу использовать mpiexec -n X gdb ./a.out, но есть ли способ использовать режим gdb -tui? - person hitwlh; 28.12.2016

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

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

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

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

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

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

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

  • Вы также можете отслеживать и фильтровать значения переменных и выражений по процессам и времени: Tracepoints log values ​​over time

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

Интерфейс довольно шустрый; мы рассчитали пошаговое выполнение и объединение стеков и переменных 220 000 процессов за 0,1 с в рамках приемочного тестирования кластера Jaguar в Ок-Ридже.

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

person Mark    schedule 31.05.2012

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


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

person Chad Brewbaker    schedule 09.03.2010
comment
Valgrind - это не то же самое, что интерактивный отладчик, но приятно знать, что он работает с MPI. - person Jay Conrod; 09.03.2010

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

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

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

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

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

person gagiuntoli    schedule 23.06.2017
comment
Поскольку tmpi действительно фантастический и именно то, что я искал, я форкнул его в своей учетной записи github: github.com/Azrael3000 / tmpi, так как первоначальный автор удалил его - person Azrael3000; 26.04.2018

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

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

person Jim Keener    schedule 08.04.2009
comment
Спасибо! Я обязательно проверю это в следующий раз, когда буду работать в MPI. - person Jay Conrod; 09.04.2009

Использование 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 запустился на экранах, вы можете ввести сценарий ввода на экраны (чтобы вам не приходилось вводить каждый экран и вводить одно и то же) с помощью команды screen -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 по аналогии с предыдущим разделом кода.

person user3788566    schedule 29.06.2014

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

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

Padb

person Community    schedule 03.12.2009

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

В UNIX считается, что TotalView хорошо поддерживает MPI.

person Community    schedule 04.12.2008

Я использую этот небольшой доморощенный метод для присоединения отладчика к процессам 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);
}

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

person Community    schedule 09.05.2009
comment
MPI требовало большинства отладочных операторов, которые я когда-либо писал, даже для простого кода. (смеется) Это может быть очень полезно. - person Troggy; 02.07.2009
comment
Это решение аналогично пункту 6 здесь (open-mpi.org/ faq /? category = debugging # serial-debuggers). Вы можете немного улучшить свой код, добавив gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);. Затем вы присоединяетесь к процессу, набрав rsh <hostname_from_print_statement> и, наконец, gdb --pid=<PID_from_print_statement>. - person Jeff; 19.08.2012

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

mpirun -np <NP> xterm -e gdb ./program 

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

person akintayo    schedule 28.02.2011

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

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

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

$ mpirun -np <num_of_proc> <prog> <prog_args>

Программа запустится и перейдет в режим сна.

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

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

Отладка-> Начать отладку-> Присоединиться к работающему приложению

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

person stranger    schedule 04.09.2018

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

person Jim Hunziker    schedule 03.06.2009
comment
Изменена на другую ссылку, которая не работает, добавлены комментарии. - person Jim Hunziker; 23.11.2015


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

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

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

person Martin Quinson    schedule 31.10.2015

Вы можете использовать бесплатный код Visual Studio, с которым гораздо проще работать, чем с xterm. Вы дублируете окно VS Code и вручную присоединяете отладчик к каждому процессу. Смотрите инструкцию в видео ниже:

YouTube

person Sorush    schedule 02.12.2020