Mam program MPI, który się kompiluje i działa, ale chciałbym przejść przez niego, aby upewnić się, że nie dzieje się nic dziwnego. Idealnie chciałbym w prosty sposób dołączyć GDB do dowolnego konkretnego procesu, ale nie jestem do końca pewien, czy to możliwe i jak to zrobić. Alternatywą byłoby zapisanie danych debugowania przez każdy proces do oddzielnego pliku dziennika, ale tak naprawdę nie daje to takiej samej swobody jak debuger.
Czy są lepsze podejścia? Jak debuguje się programy MPI?
Uważam, że gdb jest całkiem przydatne. Używam go jako
To uruchamia okna xterm, w których mogę to zrobić
zwykle działa dobrze
Możesz również spakować te polecenia razem, używając:
źródło
<file>
i przekazując-x <file>
do gdb.Wiele postów tutaj dotyczy GDB, ale nie wspomina się, jak dołączyć do procesu od uruchomienia. Oczywiście możesz dołączyć do wszystkich procesów:
Ale to jest szalenie nieskuteczne, ponieważ będziesz musiał podskakiwać, aby uruchomić wszystkie swoje procesy. Jeśli chcesz tylko debugować jeden (lub niewielką liczbę) procesu MPI, możesz dodać go jako oddzielny plik wykonywalny w wierszu poleceń za pomocą
:
operatora:Teraz tylko jeden z Twoich procesów otrzyma GDB.
źródło
Jak wspominali inni, jeśli pracujesz tylko z kilkoma procesami MPI, możesz spróbować użyć wielu sesji gdb , niewątpliwego valgrind lub uruchomić własne rozwiązanie printf / logging.
Jeśli używasz więcej procesów, naprawdę zaczynasz potrzebować odpowiedniego debuggera. OpenMPI FAQ zaleca zarówno Allinea DDT i TotalView .
Pracuję na Allinea DDT . Jest to w pełni funkcjonalny, graficzny debugger kodu źródłowego, więc tak, możesz:
...i tak dalej. Jeśli korzystałeś z Eclipse lub Visual Studio, będziesz w domu.
Dodaliśmy kilka interesujących funkcji specjalnie do debugowania kodu równoległego (czy to MPI, wielowątkowość czy CUDA):
Zmienne skalarne są automatycznie porównywane we wszystkich procesach: (źródło: allinea.com )
Możesz także śledzić i filtrować wartości zmiennych i wyrażeń w zależności od procesów i czasu:
Jest szeroko stosowany wśród 500 najlepszych witryn HPC, takich jak ORNL , NCSA , LLNL , Jülich et. glin.
Interfejs jest dość zgryźliwy; w ramach testów akceptacyjnych na klastrze Jaguar firmy Oak Ridge wyznaczyliśmy czas na stopniowanie i łączenie stosów i zmiennych 220 000 procesów z dokładnością do 0,1 sekundy.
@tgamblin wspomniał o znakomitym STAT , który integruje się z Allinea DDT , podobnie jak kilka innych popularnych projektów open source.
źródło
http://valgrind.org/ nuf powiedział
Bardziej szczegółowy link: Debugowanie programów równoległych MPI z Valgrind
źródło
Jeśli jesteś
tmux
użytkownikiem, poczujesz się bardzo komfortowo korzystając ze skryptu Benedikta Morbacha :tmpi
Pierwotnym źródłem:
https://github.com/moben/scripts/blob/master/tmpiWidelec: https://github.com/Azrael3000/tmpi
Dzięki niemu masz wiele paneli (liczbę procesów), wszystkie zsynchronizowane (każde polecenie jest kopiowane na wszystkie panele lub procesy w tym samym czasie, dzięki czemu oszczędzasz dużo czasu w porównaniu z
xterm -e
podejściem). Co więcej, możesz znać wartości zmiennych w procesie, który chcesz wykonać,print
bez konieczności przechodzenia do innego panelu, spowoduje to wydrukowanie na każdym panelu wartości zmiennej dla każdego procesu.Jeśli nie jesteś
tmux
użytkownikiem, zdecydowanie polecam spróbować i zobaczyć.źródło
http://github.com/jimktrains/pgdb/tree/master to narzędzie, które napisałem właśnie w tym celu. Jest kilku doktorów i zapraszam do wysyłania mi pytań.
Zasadniczo wywołujesz program w Perlu, który opakowuje GDB i kieruje jego IO do centralnego serwera. Dzięki temu GDB może działać na każdym hoście i mieć do niego dostęp na każdym hoście w terminalu.
źródło
Używanie
screen
razem zgdb
do debugowania aplikacji MPI działa dobrze, zwłaszcza jeślixterm
jest niedostępny lub masz do czynienia z więcej niż kilkoma procesorami. Po drodze było wiele pułapek związanych z wyszukiwaniem stosów, więc odtworzę moje rozwiązanie w całości.Najpierw dodaj kod po MPI_Init, aby wydrukować PID i zatrzymaj program, aby czekał na dołączenie. Standardowe rozwiązanie wydaje się być nieskończoną pętlą; Ostatecznie zdecydowałem się na to
raise(SIGSTOP);
, co wymaga dodatkowego wezwaniacontinue
do ucieczki w gdb.Po kompilacji uruchom plik wykonywalny w tle i przechwyć stderr. Możesz następnie
grep
plik stderr dla jakiegoś słowa kluczowego (tutaj dosłowny PID), aby uzyskać PID i pozycję każdego procesu.Sesję gdb można dołączyć do każdego procesu z
gdb $MDRUN_EXE $PID
. Wykonanie tego w ramach sesji screen umożliwia łatwy dostęp do dowolnej sesji gdb.-d -m
uruchamia ekran w trybie odłączonym,-S "P$RANK"
umożliwia nazwanie ekranu w celu późniejszego uzyskania łatwego dostępu, a-l
opcja bash uruchamia go w trybie interaktywnym i zapobiega natychmiastowemu wyjściu gdb.Gdy gdb uruchomi się na ekranach, możesz skryptować wejście na ekrany (aby nie trzeba było wchodzić na każdy ekran i wpisywać tego samego) za pomocą
-X stuff
polecenia screen . Na końcu polecenia wymagany jest znak nowej linii. Tutaj dostęp do ekranów odbywa się za-S "P$i"
pomocą podanych wcześniej nazw. Ta-p 0
opcja jest krytyczna, w przeciwnym razie polecenie sporadycznie kończy się niepowodzeniem (w zależności od tego, czy wcześniej byłeś podłączony do ekranu).W tym momencie możesz dołączyć do dowolnego ekranu za pomocą
screen -rS "P$i"
i odłączyć za pomocąCtrl+A+D
. Polecenia mogą być wysyłane do wszystkich sesji gdb analogicznie do poprzedniej sekcji kodu.źródło
Jest też moje narzędzie open source, padb, które ma na celu pomóc w programowaniu równoległym. Nazywam to „narzędziem inspekcji pracy”, ponieważ działa nie tylko jako debugger, ale może również funkcjonować na przykład jako równoległy program typu top. Uruchom w trybie "pełnego raportu", pokaże ci ślady każdego procesu w twojej aplikacji wraz ze zmiennymi lokalnymi dla każdej funkcji w każdej pozycji (zakładając, że skompilowałeś z -g). Pokazuje również "kolejki komunikatów MPI", czyli listę oczekujących wysyłek i odbiorów dla każdej pozycji w zadaniu.
Oprócz pokazania pełnego raportu, można również powiedzieć padb, aby przybliżył poszczególne fragmenty informacji w zadaniu, istnieje niezliczona liczba opcji i elementów konfiguracji, które kontrolują, jakie informacje są wyświetlane, więcej szczegółów można znaleźć na stronie internetowej.
Padb
źródło
„Standardowym” sposobem debugowania programów MPI jest użycie debugera, który obsługuje ten model wykonywania.
Mówi się, że w systemie UNIX TotalView zapewnia dobre wsparcie dla MPI.
źródło
Używam tej małej metody homebrewn do dołączania debuggera do procesów MPI - wywołaj następującą funkcję, DebugWait (), zaraz po MPI_Init () w twoim kodzie. Teraz, gdy procesy czekają na dane wejściowe z klawiatury, masz cały czas, aby dołączyć do nich debugger i dodać punkty przerwania. Kiedy skończysz, wprowadź pojedynczy znak i jesteś gotowy do pracy.
Oczywiście chciałbyś skompilować tę funkcję tylko dla kompilacji debugowania.
źródło
gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);
. Następnie dołączasz do procesu, wpisującrsh <hostname_from_print_statement>
i na koniecgdb --pid=<PID_from_print_statement>
.Polecenie dołączenia gdb do procesu mpi jest niekompletne, a powinno
Krótkie omówienie mpi i gdb można znaleźć tutaj
źródło
Całkiem prosty sposób na debugowanie programu MPI.
W funkcji main () dodaj usypianie (some_seconds)
Uruchom program jak zwykle
Program uruchomi się i wejdzie w sen.
Będziesz miał więc kilka sekund na znalezienie procesów przez ps, uruchomienie gdb i dołączenie do nich.
Jeśli używasz jakiegoś edytora, takiego jak QtCreator, możesz użyć
Debuguj-> Rozpocznij debugowanie-> Dołącz do uruchomionej aplikacji
i znajdź tam swoje procesy.
źródło
Robię debugowanie związane z MPI ze śladami dziennika, ale możesz również uruchomić gdb, jeśli używasz mpich2: MPICH2 i gdb . Ta technika jest ogólnie dobrą praktyką, gdy masz do czynienia z procesem, którego uruchomienie z debuggera jest trudne.
źródło
mpirun -gdb
Podziękowania dla http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/CommonDoc/mpich2_gdb.html ( link do archiwum )
źródło
Innym rozwiązaniem jest uruchomienie kodu w ramach SMPI, symulowanego MPI. To projekt open source, w który jestem zaangażowany. Każda ranga MPI zostanie przekonwertowana na wątki tego samego procesu UNIX. Następnie możesz łatwo użyć gdb do zmiany rang MPI.
SMPI proponuje inne zalety badania aplikacji MPI: jasnowidzenie (można obserwować każdą część systemu), odtwarzalność (kilka przebiegów prowadzi do dokładnie tego samego zachowania, chyba że tak określono), brak heisenbugs (ponieważ symulowana platforma jest inna od hosta) itp.
Aby uzyskać więcej informacji, zobacz tę prezentację lub odpowiednią odpowiedź .
źródło