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).
mpiexec
sie auszuführen und Aufrufe wie PETScInitialize
/ PETScFinalize
in den Setup- / Teardown-Code aufzunehmen. (Vermutlich würde ich, wenn ich PETSc nicht verwenden würde, diese Aufrufe durch Analoga von MPI_Init
/ ersetzen MPI_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
und RHSJacobian
in ${PETSC_DIR}/src/ts/examples/tutorials/ex.2
) für sich ausüben .