Як налагодити програму MPI?


129

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

Чи є кращі підходи? Як ви налагоджуєте програми MPI?

Відповіді:


62

Як хтось сказав, стандарт TotalView - це стандарт. Але це обійдеться вам за руку і ногу.

На сайті OpenMPI є чудовий FAQ щодо налагодження MPI . Пункт №6 у FAQ задає, як приєднати GDB до MPI-процесів. Прочитайте всю справу, є кілька чудових порад.

Якщо ви виявите, що у вас занадто багато процесів, щоб слідкувати за ними, перегляньте інструмент аналізу стеження стека (STAT) . Ми використовуємо це в Livermore, щоб збирати сліди стека з потенційно сотень тисяч запущених процесів та інтелектуально представляти їх користувачам. Це не повнофункціональний налагоджувач (повнофункціональний налагоджувач ніколи не буде масштабуватися до 208 кер), але він підкаже, які групи процесів роблять те саме. Потім ви можете перейти через представника кожної групи у стандартному відладчику.


14
Станом на 2010 рік Allinea DDT - це повнофункціональний відладчик, який набирає масштаби понад 208 кер
Марк

1
Тож я піду і надаю відповідь на відповідь @ Марка тут. DDT приємно. Спробуйте також. TotalView також інтегрується зі STAT зараз, тому якщо на вашому веб-сайті встановлено TotalView, ви можете також спробувати це. LLNL тримає TotalView та DDT навколо, і приємно, що TotalView нарешті має жорстку конкуренцію.
Тодд Гамблін

Мені хотілося б передати посилання на FAQ щодо налагодження MPI ( open-mpi.org/faq/?category=debugging#serial-debuggers ). Зокрема, куля 6 - це хороший, швидкий і простий (достатньо навіть мені!), Щоб зрозуміти спосіб принаймні налагодити окремий процес.
Джефф

Етапи №6 сторінки FAQ часто спрацювали для мене чудово і допомогли розібратися в моїй проблемі. Дуже дякую за це.
Джон Дітон

86

Я знайшов 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] [...]

Як я можу надіслати один і той же вхід до всіх NP gdb xterms? Наприклад, я хочу додати два точки проби до кожного процесу, і є 16 процесів. Чи є альтернатива xterm для цього? Чи можемо ми з'єднати сеанси в один екземпляр екрана, tmux або термінатора Кріса Джонса?
osgx

@osgx Ви можете це зробити, зберігаючи команди ("break xxx", "break yyy", "run") <file>і переходите -x <file>до gdb.
eush77

але я зустрічаюся з помилкою, повідомлення про помилку - "помилка execvp у файлі xterm (Немає такого файлу чи каталогу)"
hitwlh

коли я спробую це з jdb & OpenMPI, він не працює, тобто кожен jdb екземпляр бачить num_ranks з 1 замість того, що задано аргументу -np. будь-яка ідея чому?
Мішель Мюллер

26

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

mpiexec -n X gdb ./a.out

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

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

Тепер лише один із ваших процесів отримає GDB.


Я можу використовувати "mpiexec -n X gdb ./a.out", але чи можна використовувати режим gdb -tui?
hitwlh

16

Як уже згадували інші, якщо ви працюєте лише з декількома процесами MPI, ви можете спробувати скористатися декількома сеансами gdb , повторюваним valgrind або прокатати власне рішення printf / logging.

Якщо ви використовуєте більше процесів, ніж це, вам справді починає потрібен належний налагоджувач. OpenMPI FAQ рекомендує як Allinea DDT і TotalView .

Я працюю над Allinea DDT . Це повнофункціональний графічний налагоджувач вихідного коду, так що так, ви можете:

  • Налагоджувати або приєднувати до (понад 200 К) процесів MPI
  • Крок і пауза в групах або окремо
  • Додайте точки перерви, годинник та точки сліду
  • Ловіть помилки та витоки пам'яті

...і так далі. Якщо ви використовували Eclipse або Visual Studio, то ви будете прямо вдома.

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

  • Скалярні змінні автоматично порівнюються в усіх процесах: (джерело: allinea.com )Мережі, що показують значення для різних процесів

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

Він широко використовується серед top500 сайтів HPC, таких як ORNL , NCSA , LLNL , Jülich та ін. ін.

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

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



7

Якщо ви tmuxкористувач, вам буде дуже комфортно використовувати сценарій Benedikt Morbach :tmpi

Оригінальне джерело: https://github.com/moben/scripts/blob/master/tmpi

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

З ним у вас є декілька панелей (кількість процесів), всі синхронізовані (кожна команда копіюється на всі панелі або процеси одночасно, так що ви економите багато часу в порівнянні з xterm -eпідходом). Крім того, ви можете знати значення змінних у процесі, який ви хочете просто виконувати, printне переходячи на іншу панель, це надрукує на кожній панелі значення змінної для кожного процесу.

Якщо ви не tmuxкористувач, я настійно рекомендую спробувати його і подивитися.


2
Оскільки tmpi - це дійсно фантастично і саме те, що я шукав, я записав його на свій рахунок github: github.com/Azrael3000/tmpi, оскільки його автор видалив
Azrael3000

6

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

Ви в основному викликаєте програму perl, яка завершує GDB і виконує послідовність вводу-виводу на центральний сервер. Це дозволяє GDB працювати на кожному хості та отримувати доступ до нього на кожному хості в терміналі.


Дякую! Я обов'язково перевіряю це наступного разу, коли я працюю в MPI.
Джей Конрод

5

Використання screenразом із gdbналагодженням програм MPI прекрасно працює, особливо якщо xtermвін недоступний або ви маєте справу з декількома процесорами. Попутно було багато підводних каменів із супутніми пошуковими потоками, тому я відтворять своє рішення в повному обсязі.

По-перше, додайте код після 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 за аналогією з попереднім розділом коду.


3

Є також мій інструмент з відкритим кодом, padb, який спрямований на допомогу в паралельному програмуванні. Я називаю це "інструментом інспекції роботи", оскільки він функціонує не лише як відладчик, він також може функціонувати, наприклад, як паралельна верхня програма. Запустіть у режимі "Повний звіт", він покаже вам стеження слідів кожного процесу у вашій програмі, а також локальні змінні для кожної функції над кожним рангом (якщо вважати, що ви складені з -g). Він також покаже вам "черги повідомлень MPI", тобто список незавершених відправлень та отримань для кожного рангу в межах завдання.

Окрім показу повного звіту, можна також сказати padb для збільшення окремих бітів інформації в межах роботи, існує безліч опцій та елементів конфігурації, щоб контролювати інформацію, яка відображається, детальну інформацію див. На веб-сторінці.

Padb


3

"Стандартний" спосіб налагодження програм MPI полягає у використанні налагоджувача, який підтримує цю модель виконання.

У UNIX, як кажуть , TotalView є гарним прихильником MPI.


2

Я використовую цей маленький домашній метод, щоб приєднати налагоджувач до процесів 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);
}

Звичайно, ви хочете скомпілювати цю функцію лише для налагодження.


MPI вимагає найвищих заявок про налагодження, які я коли-небудь писав, навіть для простого коду. (LOL) Це може бути дуже корисно.
Troggy

3
Це рішення подібне до кулі 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>.
Джефф

2

Команда приєднати gdb до процесу mpi неповна, вона повинна бути

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

Коротке обговорення mpi та gdb можна знайти тут


2

Досить простий спосіб налагодження програми MPI.

Основна функція () додає сон (кілька_секунд)

Запускайте програму як завжди

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

Програма запуститься і засипить.

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

Якщо ви використовуєте такий редактор, як QtCreator, ви можете використовувати

Налагодження-> Почати налагодження-> Приєднати до запущеної програми

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


1

Я роблю налагодження, пов’язані з MPI, зі слідами журналу, але ви також можете запустити gdb, якщо ви використовуєте mpich2: MPICH2 та gdb . Ця методика є хорошою практикою загалом, коли ви маєте справу з процесом, який складно запустити з налагоджувача.


Змінено на інше посилання, яке не порушено, додали коментар.
Джим Ханзікер


0

Ще одне рішення - запустити свій код у SMPI, імітованому MPI. Це проект з відкритим кодом, в якому я беру участь. Кожен ранг MPI буде перетворений на нитки того ж процесу UNIX. Тоді ви можете легко використовувати gdb для визначення MPI-рангів.

SMPI пропонує інші переваги для вивчення MPI-додатків: ясновидіння (ви можете спостерігати за всіма частинами системи), відтворюваність (кілька запусків призводять до такої ж поведінки, якщо ви цього не вказали), відсутність heisenbugs (оскільки модельована платформа зберігається по-різному від господаря) тощо.

Для отримання додаткової інформації дивіться цю презентацію чи відповідну відповідь .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.