J'ai un programme MPI qui se compile et s'exécute, mais j'aimerais le parcourir pour m'assurer que rien de bizarre ne se passe. Idéalement, j'aimerais un moyen simple d'attacher GDB à un processus particulier, mais je ne sais pas vraiment si c'est possible ou comment le faire. Une alternative serait que chaque processus écrive la sortie de débogage dans un fichier journal séparé, mais cela ne donne pas vraiment la même liberté qu'un débogueur.
Existe-t-il de meilleures approches? Comment déboguez-vous les programmes MPI?
J'ai trouvé gdb très utile. Je l'utilise comme
Ceci lance les fenêtres xterm dans lesquelles je peux faire
fonctionne généralement bien
Vous pouvez également regrouper ces commandes en utilisant:
la source
<file>
et en les passant-x <file>
à gdb.De nombreux articles ici concernent GDB, mais ne mentionnez pas comment s'attacher à un processus depuis le démarrage. Évidemment, vous pouvez vous attacher à tous les processus:
Mais c'est extrêmement inefficace car vous devrez rebondir pour démarrer tous vos processus. Si vous souhaitez simplement déboguer un (ou un petit nombre de) processus MPI, vous pouvez l'ajouter en tant qu'exécutable séparé sur la ligne de commande à l'aide de l'
:
opérateur:Désormais, un seul de vos processus obtiendra GDB.
la source
Comme d'autres l'ont mentionné, si vous ne travaillez qu'avec une poignée de processus MPI, vous pouvez essayer d'utiliser plusieurs sessions gdb , le redoutable valgrind ou lancer votre propre solution printf / logging.
Si vous utilisez plus de processus que cela, vous commencez vraiment à avoir besoin d'un débogueur approprié. La FAQ OpenMPI recommande Allinea DDT et TotalView .
Je travaille sur Allinea DDT . C'est un débogueur de code source graphique complet, donc oui, vous pouvez:
...etc. Si vous avez utilisé Eclipse ou Visual Studio, vous serez chez vous.
Nous avons ajouté quelques fonctionnalités intéressantes spécifiquement pour le débogage de code parallèle (que ce soit MPI, multi-thread ou CUDA):
Les variables scalaires sont automatiquement comparées à travers tous les processus: (source: allinea.com )
Vous pouvez également suivre et filtrer les valeurs des variables et des expressions au fil des processus et du temps:
Il est largement utilisé parmi les 500 meilleurs sites HPC, tels que ORNL , NCSA , LLNL , Jülich et. Al.
L'interface est assez vive; nous avons chronométré l'étape et la fusion des piles et des variables de 220 000 processus à 0,1 s dans le cadre des tests d'acceptation sur le cluster Jaguar d'Oak Ridge.
@tgamblin a mentionné l'excellent STAT , qui s'intègre à Allinea DDT , tout comme plusieurs autres projets open source populaires.
la source
http://valgrind.org/ nuf a dit
Lien plus spécifique: Débogage des programmes parallèles MPI avec Valgrind
la source
Si vous êtes un
tmux
utilisateur, vous vous sentirez très à l'aise avec le script de Benedikt Morbach :tmpi
Source primaire:
https://github.com/moben/scripts/blob/master/tmpiFourche: https://github.com/Azrael3000/tmpi
Avec lui, vous avez plusieurs panneaux (nombre de processus) tous synchronisés (chaque commande est copiée sur tous les panneaux ou processus en même temps, ce qui vous permet de gagner beaucoup de temps par rapport à l'
xterm -e
approche). De plus, vous pouvez connaître les valeurs des variables dans le processus que vous voulez simplement faireprint
sans avoir à passer à un autre panneau, cela imprimera sur chaque panneau les valeurs de la variable pour chaque processus.Si vous n'êtes pas un
tmux
utilisateur, je vous recommande fortement de l'essayer et de le voir.la source
http://github.com/jimktrains/pgdb/tree/master est un utilitaire que j'ai écrit pour faire exactement cela. Il y a quelques documents et n'hésitez pas à m'envoyer un message pour des questions.
Vous appelez essentiellement un programme perl qui encapsule GDB et achemine ses E / S vers un serveur central. Cela permet à GDB de fonctionner sur chaque hôte et pour vous d'y accéder sur chaque hôte du terminal.
la source
L'utilisation
screen
avecgdb
pour déboguer les applications MPI fonctionne bien, surtout si ellexterm
n'est pas disponible ou si vous avez affaire à plus de quelques processeurs. Il y avait de nombreux pièges en cours de route avec les recherches d'accompagnement de stackoverflow, je vais donc reproduire ma solution dans son intégralité.Tout d'abord, ajoutez du code après MPI_Init pour imprimer le PID et arrêtez le programme pour attendre que vous l'attachiez. La solution standard semble être une boucle infinie; J'ai finalement opté pour
raise(SIGSTOP);
, ce qui nécessite un appel supplémentairecontinue
pour s'échapper dans gdb.Après la compilation, exécutez l'exécutable en arrière-plan et récupérez le fichier stderr. Vous pouvez ensuite
grep
le fichier stderr pour un mot-clé (ici PID littéral) pour obtenir le PID et le rang de chaque processus.Une session gdb peut être attachée à chaque processus avec
gdb $MDRUN_EXE $PID
. Le faire dans une session d'écran permet un accès facile à n'importe quelle session gdb.-d -m
démarre l'écran en mode détaché,-S "P$RANK"
vous permet de nommer l'écran pour un accès facile plus tard, et l'-l
option de bash le démarre en mode interactif et empêche gdb de quitter immédiatement.Une fois que gdb a démarré dans les écrans, vous pouvez écrire une entrée dans les écrans (afin de ne pas avoir à entrer dans chaque écran et à taper la même chose) en utilisant la
-X stuff
commande screen . Une nouvelle ligne est requise à la fin de la commande. Ici, les écrans sont accessibles en-S "P$i"
utilisant les noms donnés précédemment. L'-p 0
option est critique, sinon la commande échoue par intermittence (selon que vous vous êtes déjà connecté ou non à l'écran).À ce stade, vous pouvez vous attacher à n'importe quel écran en utilisant
screen -rS "P$i"
et détacher en utilisantCtrl+A+D
. Les commandes peuvent être envoyées à toutes les sessions gdb par analogie avec la section de code précédente.la source
Il y a aussi mon outil open-source, padb, qui vise à aider à la programmation parallèle. Je l'appelle un "Job Inspection Tool" car il fonctionne non seulement comme un débogueur peut également fonctionner, par exemple, comme un programme de type top parallèle. Exécutez en mode "Rapport complet", il vous montrera les traces de la pile de chaque processus au sein de votre application ainsi que les variables locales pour chaque fonction sur chaque rang (en supposant que vous avez compilé avec -g). Il vous montrera également les «files d'attente de messages MPI», c'est-à-dire la liste des envois et des réceptions en attente pour chaque rang dans le travail.
En plus d'afficher le rapport complet, il est également possible de dire à padb de zoomer sur des bits d'information individuels dans le travail, il existe une myriade d'options et d'éléments de configuration pour contrôler les informations affichées, voir la page Web pour plus de détails.
Padb
la source
La manière «standard» de déboguer les programmes MPI consiste à utiliser un débogueur qui prend en charge ce modèle d'exécution.
Sous UNIX, on dit que TotalView prend en charge MPI.
la source
J'utilise cette petite méthode homebrewn pour attacher le débogueur aux processus MPI - appelez la fonction suivante, DebugWait (), juste après MPI_Init () dans votre code. Maintenant, pendant que les processus attendent une entrée au clavier, vous avez tout le temps de leur attacher le débogueur et d'ajouter des points d'arrêt. Lorsque vous avez terminé, fournissez une entrée de caractère unique et vous êtes prêt à partir.
Bien sûr, vous voudrez compiler cette fonction uniquement pour les versions de débogage.
la source
gethostname(hostname, sizeof(hostname)); printf("PID %d on host %s ready for attach\n", getpid(), hostname);
. Ensuite, vous vous attachez au processus en tapantrsh <hostname_from_print_statement>
, et enfingdb --pid=<PID_from_print_statement>
.La commande pour attacher gdb à un processus mpi est incomplète, elle devrait être
Une brève discussion de mpi et gdb peut être trouvée ici
la source
Un moyen assez simple de déboguer un programme MPI.
Dans la fonction main (), ajoutez sleep (some_seconds)
Exécutez le programme comme d'habitude
Le programme démarre et s'endort.
Vous aurez donc quelques secondes pour trouver vos processus par ps, exécuter gdb et vous y attacher.
Si vous utilisez un éditeur comme QtCreator, vous pouvez utiliser
Déboguer-> Démarrer le débogage-> Attacher à l'application en cours d'exécution
et trouvez vos processus là-bas.
la source
Je fais du débogage lié à MPI avec des traces de journal, mais vous pouvez également exécuter gdb si vous utilisez mpich2: MPICH2 et gdb . Cette technique est une bonne pratique en général lorsque vous avez affaire à un processus difficile à lancer à partir d'un débogueur.
la source
mpirun -gdb
Merci à http://www.ncsa.illinois.edu/UserInfo/Resources/Hardware/CommonDoc/mpich2_gdb.html ( lien d'archive )
la source
Une autre solution consiste à exécuter votre code dans SMPI, le MPI simulé. C'est un projet open source dans lequel je suis impliqué. Chaque rang MPI sera converti en threads du même processus UNIX. Vous pouvez ensuite facilement utiliser gdb pour remonter les rangs MPI.
SMPI propose d'autres avantages à l'étude des applications MPI: clairevoyance (vous pouvez observer toutes les parties du système), reproductibilité (plusieurs exécutions conduisent exactement au même comportement sauf si vous le spécifiez), absence de heisenbugs (car la plateforme simulée est maintenue différente de l'hôte), etc.
Pour plus d'informations, consultez cette présentation ou cette réponse connexe .
la source