Avez-vous des recommandations pour les frameworks de tests unitaires compatibles avec le code / les bibliothèques qui utilisent MPI?

13

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 VecViewet MatView), et comparez-la avec une sortie connue avec quelque chose comme ndiffou numdiff. 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 simple diff, 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).
Geoff Oxberry
la source
Je ne connais que les suites de tests internes, donc je ne peux rien recommander. Cela étant dit, aucune de ces suites de tests ne vous permet-elle de spécifier comment exécuter l'exécutable que vous créez? S'ils le font, il devrait être trivial de créer des tests qui fonctionnent pour les programmes MPI.
Bill Barth
Ils devraient. Dans n'importe quel langage compilé, c'est juste un exécutable, donc cela ne devrait pas poser de problème mpiexecpour l'exécuter, et inclure des appels comme PETScInitialize/ PETScFinalizedans le code setup / démontage. (Vraisemblablement, si je n'utilisais pas PETSc, je remplacerais ces appels par des analogues de MPI_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.
Geoff Oxberry
Votre description du problème me suggère que vous êtes intéressé à utiliser un framework de tests unitaires pour exécuter des tests d'intégration / de régression. Il n'y a rien de mal à cela en soi, mais vous voudrez peut-être clarifier un peu plus votre question. Je pense que si vous demandiez à un expert en tests unitaires comment écrire des tests unitaires pour votre code scientifique, il vous dirait d'écrire des tests de manière modulaire. Autrement dit, la plupart de vos tests ne contiendraient pas d'appels MPI appropriés.
Aron Ahmadia
Permettez-moi d'être plus concret. Quelque chose que je voudrais tester sur un petit problème avec un petit nombre de processeurs (disons, 1-4) serait de savoir si ma matrice jacobienne assemblée aboutit réellement au jacobien global approprié. Je voudrais également tester ma fonction côté droit par rapport à un côté droit mondial connu. Chacun de ces tests ne devrait toujours exercer qu'une seule fonction dans l'application (par exemple, dans PETSc, test RHSFunctionet RHSJacobiandans ${PETSC_DIR}/src/ts/examples/tutorials/ex.2) de manière isolée.
Geoff Oxberry
Je ne pense pas qu'il existe actuellement un cadre qui vous aidera à faire ce que vous voulez. Nous avons réussi à nous arranger le nez pour faire quelques choses pour nous dans PyClaw, (et Lisandro l'a utilisé dans mpi4py et petsc4py). Avez-vous regardé le cadre de test dans mpich?
Aron Ahmadia

Réponses:

8

Je suis un utilisateur heureux de GoogleTest avec un code MPI C ++ dans un environnement de construction CMake / CTest:

  • CMake installe automatiquement / liens googletest de svn!
  • l'ajout de tests est une ligne unique!
  • écrire les tests est facile! (et google mock est très puissant!)
  • CTest peut transmettre des paramètres de ligne de commande à vos tests et exporter des données vers CDash!

Voilà comment cela fonctionne. Un lot de tests unitaires qui nécessitent mpi sont écrits dans un my_mpi_test.cppfichier qui ressemble à ceci:

#include <gtest/gtest.h>
#include <boost/mpi.h>

/// Most testing libraries allow to define main yourself to override initialization.
int main(int argc, char* argv[]) {
    ::testing::InitGoogleTest(&argc, argv);  /// Set gtest environment
    mpi::environment env(argc, argv);  /// Set mpi environment
    return RUN_ALL_TESTS();  /// Execute all gtest tests
}

TEST(test_batch_name, test_name) {  /// Then you can create tests as usual,
  using namespace mpi;
  communicator world;  /// and use MPI inside your tests.
  /* ... test stuff here ... */
}

Le CMakeLists.txt qui ajoute ce test est:

add_mpi_test(my_mpi 2)  # Uses 2 MPI processes

add_mpi_testenveloppe CMake à l' add_testintérieur de ma racine CMakeLists.txt:

function(add_mpi_test name no_mpi_proc)
  include_directories(${MY_TESTING_INCLUDES})
      # My test are all called name_test.cpp
      add_executable(${name} ${name}_test.cpp)
      add_dependencies(${name} googletest)
  # Make sure to link MPI here too:
  target_link_libraries(${name} ${MY_TESTING_LIBS})
  set(test_parameters ${MPIEXEC_NUMPROC_FLAG} ${no_mpi_proc} "./${name}")
      add_test(NAME ${name} COMMAND ${MPIEXEC} ${test_parameters})
endfunction(add_mpi_test)

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.

gnzlbg
la source
4

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é.

andybauer
la source
Merci d'avoir répondu! J'ai regardé CTest, et je n'ai trouvé aucune documentation à part une description semblable à une page de manuel sur le site Web KitWare. Pouvez-vous recommander des tutoriels disponibles gratuitement?
Geoff Oxberry
Il y a un tas d'informations sur le wiki CMake . Il y a un tas de tutoriels pour CMake, CTest et CPack là-bas. Je trouve la plupart de mes réponses à ces applications sur Stack Overflow .
andybauer
andybauer - Merci pour la réponse. Cela vous dérange-t-il de modifier votre réponse et de divulguer votre affiliation avec KitWare?
Aron Ahmadia
3

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:

Wolfgang Bangerth
la source
Wolfgang, merci pour la réponse! PETSc semble faire quelque chose de similaire.
Geoff Oxberry