Habituellement, j'écris du code série, et quand je le fais, j'écris des tests unitaires avec un cadre de test de style xUnit (MATLAB xUnit, PyUnit / nose, ou le cadre de test C ++ de Google).
Sur la base d'une recherche rapide sur Google, je n'ai pas beaucoup vu comment les praticiens testent le code unitaire qui utilise MPI. Y a-t-il des meilleures pratiques pour cela?
Par rapport aux stratégies de test unitaire et de développement piloté par les tests , je recherche des réponses concernant le logiciel que je devrais utiliser pour un framework de test (le cas échéant - la réponse pourrait très bien être "roll your own code", dans laquelle des exemples de cas de code de test personnalisé seraient utiles).
La plupart de ce que je cherche à tester sont des évaluations de fonctions du côté droit et des routines d'assemblage de matrice jacobienne pour les steppers temporels qui intégreront des PDE semi-discrétisés. J'utiliserai PETSc, donc s'il y a quelque chose de spécifique à PETSc, cela serait utile en plus des cadres de test plus généraux.
Modifications de clarification:
Un exemple serait dans ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, où je voudrais tester quelque chose comme RHSFunction
(une évaluation de la fonction de droite) etRHSJacobian
(une évaluation matricielle jacobienne). Je testerais contre des valeurs connues pour le côté droit assemblé et la matrice jacobienne assemblée; Je peux obtenir ces valeurs analytiquement pour certaines instances de problème simples. Ces fonctions sont des fonctions spécifiques à l'application qui n'exerceront aucune autre fonction au niveau de l'application, mais elles pourraient appeler MPI si l'assemblage de vecteur ou de matrice est effectué dans la fonction (comme dans l'exemple PETSc lié ci-dessus). Si j'écris des fonctions qui ne calculent que des portions de vecteurs ou de matrices locales à un processeur, je voudrais tester la version globale assemblée si possible car, étant nouveau dans la programmation parallèle, il est plus intuitif pour moi de penser aux vecteurs globaux et globaux matrices. Ces tests seraient exécutés sur de petites tailles de problème et un petit nombre de processeurs.
Je peux penser à quelques stratégies pour ce faire:
- Une stratégie qui ne fonctionnera probablement pas bien, basée sur les recherches Google que j'ai faites sur ce sujet, serait de construire une sortie connue, de trouver l'erreur relative / absolue en parallèle, puis de faire des comparaisons naïves. La sortie sera probablement tronquée - quiconque a écrit un programme "Hello, world" avec MPI sait pourquoi - ce qui limite l'utilité de faire les tests unitaires. ( Ce fut l'impulsion pour poser la question. ) Il semble également y avoir un certain potentiel délicat à appeler le cadre de tests unitaires.
- Écrivez la sortie dans un fichier (dans PETSc, par exemple, en utilisant
VecView
etMatView
), et comparez-la avec une sortie connue avec quelque chose commendiff
ounumdiff
. Mon intuition avec cette méthode de l'expérience précédente en faisant des tests unitaires avec des comparaisons de fichiers est qu'elle sera difficile et nécessitera un certain filtrage. Cette méthode semble cependant être excellente pour les tests de régression, car je pourrais remplacer les utilitaires ci-dessus par un simplediff
, et ne pas avoir à me soucier de faire correspondre les formats de texte. J'ai compris que cette stratégie est plus ou moins ce que WolfgangBangerth et andybauer suggèrent. PETSc semble également utiliser une approche similaire pour certains de ses tests. - Utilisez un framework de tests unitaires, rassemblez tout sur le processeur avec le rang MPI 0 et demandez-lui d'exécuter des tests unitaires uniquement si le rang du processeur est 0. Je pourrais faire quelque chose de similaire avec les normes (c'est probablement encore plus facile de cette façon), bien que le compromis est que toute erreur retournée me dira que j'ai un problème dans mon calcul, mais pas quels éléments sont en erreur. Ensuite, je n'ai pas besoin de m'inquiéter de la sortie des tests unitaires; Je dois seulement m'inquiéter d'appeler correctement le framework de tests unitaires. PETSc semble utiliser des comparaisons normatives dans ses programmes d'exemple lorsque des solutions exactes sont disponibles, mais il n'utilise pas de cadre de test unitaire lors de ces comparaisons (et ne devrait pas nécessairement).
la source
mpiexec
pour l'exécuter, et inclure des appels commePETScInitialize
/PETScFinalize
dans le code setup / démontage. (Vraisemblablement, si je n'utilisais pas PETSc, je remplacerais ces appels par des analogues deMPI_Init
/MPI_Finalize
, selon les bibliothèques que j'utilise.) Le framework de test de Google est une version basée sur la source, donc le compiler avec le code I écrire ne serait pas non plus un problème.RHSFunction
etRHSJacobian
dans${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) de manière isolée.Réponses:
Je suis un utilisateur heureux de GoogleTest avec un code MPI C ++ dans un environnement de construction CMake / CTest:
Voilà comment cela fonctionne. Un lot de tests unitaires qui nécessitent mpi sont écrits dans un
my_mpi_test.cpp
fichier qui ressemble à ceci:Le CMakeLists.txt qui ajoute ce test est:
où
add_mpi_test
enveloppe CMake à l'add_test
intérieur de ma racine CMakeLists.txt:Cette dernière partie n'est pas nécessaire mais vous permet d'ajouter facilement des tests mpi sur une seule ligne. Ensuite, vous pouvez décider si vous souhaitez coder en dur le nombre de processus MPI pour chaque test ou le lire via un paramètre de ligne de commande pour ctest.
la source
Il existe plusieurs packages logiciels compatibles MPI qui utilisent l' ensemble d'outils CMake pour les tests. Ceux que je peux penser du haut de ma tête sont Trilinos, VTK et ParaView. Je pense que vous ne voulez pas supposer que l'exécutable doit être lancé avec mpirun et / ou mpiexec. CMake prend en charge la spécification de la façon de lancer correctement l'exécutable ainsi que différentes options telles que le nombre maximal de processus à utiliser et des pré-et post-drapeaux, si nécessaire.
Vous voudrez peut-être consulter la section Sites HPC du tableau de bord ParaView où les tests sont exécutés sur une variété de superordinateurs NERSC et Argonne. Enterré il y a aussi la plupart des paramètres que vous devez spécifier pour le faire fonctionner sur ces machines.
Pour référence, le tableau de bord Trilinos a une grande variété de packages répertoriés et pour moi est plutôt impressionnant dans son organisation.
Divulgation complète: je suis un employé de Kitware et CMake est l'un des projets open source avec lesquels Kitware est impliqué.
la source
Nous roulons simplement notre propre code dans deal.II - en gros, nous demandons au framework d'exécuter des tests en utilisant
mpirun -np ...
. Nous venions précédemment d'utiliser un schéma de test basé sur Makefile (compiler, lier, exécuter le test, puis comparer le résultat avec celui qui avait été précédemment enregistré) et vous pouvez le trouver ici:et pour le contexte, les cibles non MPI sont ici:
Nous réécrivons des choses en utilisant CMake / CTest, avec le développement actuel ici:
la source
Le faisceau de tests unitaires Teuchos de Trilinos prend en charge nativement les tests unitaires utilisant MPI. Des choses comme le contrôle de la sortie de plusieurs processus et l'agrégation de réussite / échec sur tous les processus sont automatiques. Regarde:
http://trilinos.org/docs/dev/packages/teuchos/doc/html/group__Teuchos__UnitTest__grp.html
la source