Normalerweise schreibe ich seriellen Code, und wenn ich das tue, schreibe ich Komponententests mit einem Testframework im xUnit-Stil (MATLAB xUnit, PyUnit / nose oder Googles C ++ - Testframework).
Basierend auf einer flüchtigen Google-Suche habe ich nicht viel darüber gesehen, wie Praktiker Unit-Test-Code verwenden, der MPI verwendet. Gibt es dafür Best Practices?
Im Vergleich zu Strategien für Komponententests und testgetriebene Entwicklung suche ich nach Antworten, welche Software ich für ein Testframework verwenden sollte (falls vorhanden - die Antwort könnte durchaus "Roll your own Code" lauten, in dem Fallbeispiele für benutzerdefinierten Testcode wären hilfreich.
Das meiste, was ich testen möchte, sind Funktionsbewertungen auf der rechten Seite und Jacobi-Matrix-Assemblierungsroutinen für Zeitschrittmacher, die semi-diskretisierte PDEs integrieren. Ich werde PETSc verwenden. Wenn es also etwas PETSc-spezifisches gibt, wäre dies zusätzlich zu allgemeineren Test-Frameworks hilfreich.
Klarstellungsänderungen:
Ein Beispiel wäre in ${PETSC_DIR}/src/ts/examples/tutorials/ex2.c
, wo ich sowas testen möchte RHSFunction
(eine rechtsseitige Funktionsbewertung) undRHSJacobian
(eine Jacobi-Matrix-Auswertung). Ich würde gegen bekannte Werte für die zusammengebaute rechte Seite und die zusammengebaute Jacobi-Matrix testen; Ich kann diese Werte für einige einfache Problemfälle analytisch ermitteln. Diese Funktionen sind anwendungsspezifische Funktionen, die keine andere Funktion auf Anwendungsebene ausführen. Sie können jedoch MPI aufrufen, wenn die Vektor- oder Matrixassemblierung innerhalb der Funktion erfolgt (wie im oben aufgeführten verknüpften PETSc-Beispiel). Wenn ich Funktionen schreibe, die nur Teile von Vektoren oder Matrizen lokal für einen Prozessor berechnen, würde ich, wenn möglich, gegen die globale, zusammengesetzte Version testen wollen, da die parallele Programmierung neu für mich ist, ist es intuitiver, an globale Vektoren und globale zu denken Matrizen. Diese Tests würden auf kleinen Problemgrößen und einer kleinen Anzahl von Prozessoren ausgeführt.
Ich kann mir ein paar Strategien vorstellen, um dies zu tun:
- Eine Strategie, die wahrscheinlich nicht gut funktioniert, basierend auf den Google-Suchen, die ich zu diesem Thema durchgeführt habe, wäre, eine bekannte Ausgabe zu erstellen, den relativen / absoluten Fehler parallel zu finden und dann naive Vergleiche durchzuführen. Die Ausgabe wird wahrscheinlich verstümmelt sein - jeder, der ein "Hallo Welt" -Programm mit MPI geschrieben hat, weiß warum - was den Nutzen der Durchführung von Komponententests einschränkt. ( Dies war der Anstoß, die Frage zu stellen. ) Es scheint auch eine potenzielle Schwierigkeit zu geben, das Unit-Testing-Framework aufzurufen.
- Schreiben Sie die Ausgabe in eine Datei (z. B. in PETSc mit
VecView
undMatView
) und vergleichen Sie sie mit bekannten Ausgaben wiendiff
odernumdiff
. Mein Bauchgefühl bei dieser Methode aus früheren Erfahrungen mit Unit-Tests mit Dateivergleichen ist, dass sie heikel ist und eine gewisse Filterung erfordert. Diese Methode scheint sich jedoch hervorragend für Regressionstests zu eignen, da ich die oben genannten Dienstprogramme durch eine einfache ersetzen könntediff
und mich nicht um das Anpassen von Textformaten kümmern muss. Ich habe festgestellt, dass diese Strategie mehr oder weniger dem entspricht, was WolfgangBangerth und andybauer vorschlagen. PETSc scheint bei einigen Tests einen ähnlichen Ansatz zu verfolgen. - Verwenden Sie ein Unit-Test-Framework, erfassen Sie alles auf dem Prozessor mit MPI-Rang 0 und fordern Sie ihn auf, Unit-Tests nur dann auszuführen, wenn der Prozessor-Rang 0 ist. Ich könnte mit Normen etwas Ähnliches tun (dies ist wahrscheinlich sogar noch einfacher), obwohl der Kompromiss besteht ist, dass alle zurückgegebenen Fehler mich darauf hinweisen, dass ich ein Problem in meiner Berechnung habe, aber nicht, welche Elemente fehlerhaft sind. Dann brauche ich mir keine Sorgen zu machen, dass die Ausgabe von Unit-Tests verstümmelt wird. Ich muss mich nur darum kümmern, das Unit-Testing-Framework korrekt aufzurufen. PETSc scheint normgerechte Vergleiche in seinen Beispielprogrammen zu verwenden, wenn genaue Lösungen verfügbar sind, verwendet jedoch kein Unit-Testing-Framework, um diese Vergleiche durchzuführen (und sollte dies auch nicht unbedingt tun).
quelle
mpiexec
sie auszuführen und Aufrufe wiePETScInitialize
/PETScFinalize
in den Setup- / Teardown-Code aufzunehmen. (Vermutlich würde ich, wenn ich PETSc nicht verwenden würde, diese Aufrufe durch Analoga vonMPI_Init
/ ersetzenMPI_Finalize
, je nachdem, welche Bibliotheken ich verwende.) Das Testframework von Google ist eine quellbasierte Version und wird daher zusammen mit Code I kompiliert schreiben wäre auch kein problem.RHSFunction
undRHSJacobian
in${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) für sich ausüben .Antworten:
Ich bin ein zufriedener Nutzer von GoogleTest mit einem C ++ MPI-Code in einer CMake / CTest-Build-Umgebung:
So funktioniert es. Eine Reihe von Unit-Tests, die MPI erfordern, werden in eine
my_mpi_test.cpp
Datei geschrieben, die so aussieht:Die CMakeLists.txt, die diesen Test hinzufügt, ist:
Wo
add_mpi_test
hüllt sich CMakeadd_test
in meine root CMakeLists.txt:Dieser letzte Teil ist nicht erforderlich, ermöglicht jedoch das einfache Hinzufügen von MPI-Tests in einer Zeile. Anschließend können Sie entscheiden, ob Sie die Anzahl der MPI-Prozesse für jeden Test fest codieren oder über einen Befehlszeilenparameter an ctest auslesen möchten.
quelle
Es gibt mehrere MPI-fähige Softwarepakete, die CMake verwenden Tools zum Testen verwenden. Die, an die ich auf Anhieb denken kann, sind Trilinos, VTK und ParaView. Ich würde denken, dass Sie nicht davon ausgehen möchten, dass die ausführbare Datei mit mpirun und / oder mpiexec gestartet werden muss. CMake bietet Unterstützung für das Festlegen, wie die ausführbare Datei ordnungsgemäß gestartet werden soll, sowie verschiedene Optionen, z.
Möglicherweise möchten Sie sich den Abschnitt HPC-Sites des ParaView-Dashboards ansehen die Tests auf einer Vielzahl von NERSC- und Argonne-Supercomputern ausgeführt werden. Darin verborgen sind auch die meisten Einstellungen, die Sie vornehmen müssen, damit es auf diesen Computern funktioniert.
Als Referenz dient das Trilinos-Dashboard eine Vielzahl von Paketen aufgeführt, und für mich ist die Organisation ziemlich beeindruckend.
Vollständige Offenlegung: Ich bin ein Kitware-Mitarbeiter und CMake ist eines der Open Source-Projekte, an denen Kitware beteiligt ist.
quelle
Wir rollen einfach unseren eigenen Code in deal.II - im Wesentlichen weisen wir das Framework an, Tests mit auszuführen
mpirun -np ...
. Bisher haben wir nur ein Makefile-basiertes Testschema verwendet (kompilieren, verknüpfen, Test ausführen und dann die Ausgabe mit einer zuvor gespeicherten vergleichen). Dies finden Sie hier:und für den Kontext sind die Nicht-MPI-Ziele hier:
Wir schreiben Dinge mit CMake / CTest um, mit der aktuellen Entwicklung hier:
quelle
Das Teuchos Unit-Testgeschirr in Trilinos unterstützt von Haus aus Unit-Tests, die MPI verwenden. Dinge wie das Steuern der Ausgabe von mehreren Prozessen und das Aggregieren von Bestanden / Nicht Bestanden über alle Prozesse erfolgen automatisch. Schau mal:
http://trilinos.org/docs/dev/packages/teuchos/doc/html/group__Teuchos__UnitTest__grp.html
quelle