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).
mpiexec
pour l'exécuter, et inclure des appels comme PETScInitialize
/ PETScFinalize
dans 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.
RHSFunction
et RHSJacobian
dans ${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) de manière isolée.