Eine mit implementierte Reduzierung MPI_Allreduce()
ist reproduzierbar, solange Sie dieselbe Anzahl von Prozessoren verwenden, sofern die Implementierung den folgenden Hinweis in Abschnitt 5.9.1 des MPI-2.2-Standards beachtet.
Ratschläge für Implementierer . Es wird dringend empfohlen, MPI_REDUCE
diese Methode so zu implementieren, dass dasselbe Ergebnis erhalten wird, wenn die Funktion auf dieselben Argumente angewendet wird, die in derselben Reihenfolge angezeigt werden. Beachten Sie, dass dies Optimierungen verhindern kann, die den physischen Standort der Prozessoren ausnutzen. ( Ende der Ratschläge für Implementierer .)
Wenn Sie die Reproduzierbarkeit unbedingt gewährleisten müssen, können Sie die Richtlinien im nächsten Absatz befolgen:
Hinweise für Benutzer . Einige Anwendungen können möglicherweise den nicht assoziativen Charakter von Gleitkommaoperationen nicht ignorieren oder benutzerdefinierte Operationen (siehe Abschnitt 5.9.5) verwenden, die eine spezielle Verkleinerungsreihenfolge erfordern und nicht als assoziativ behandelt werden können. Solche Anwendungen sollten die Reihenfolge der Bewertung ausdrücklich durchsetzen. Zum Beispiel könnte im Fall von Operationen, die eine strikte Auswertungsreihenfolge von links nach rechts (oder von rechts nach links) erfordern, dies durch Sammeln aller Operanden in einem einzigen Prozess (z. B. mit
MPI_GATHER
) unter Anwendung der Reduktionsoperation erfolgen MPI_REDUCE_LOCAL
Senden Sie das Ergebnis in der gewünschten Reihenfolge (z. B. mit
) und übertragen Sie es bei Bedarf auf die anderen Prozesse (z MPI_BCAST
. B. mit ). ( Ende der Beratung für Benutzer .)
Im weiteren Sinne nutzen effiziente Algorithmen für die meisten Anwendungen die Lokalität. Da der Algorithmus bei einer anderen Anzahl von Prozessen sehr unterschiedlich ist, ist es einfach nicht praktikabel, die Ergebnisse bei einer anderen Anzahl von Prozessen exakt zu reproduzieren. Eine mögliche Ausnahme ist Multigrid mit gedämpften Jacobi- oder Polynomglättern (z. B. Chebyshev), bei denen diese einfache Methode sehr gut funktioniert.
Bei der gleichen Anzahl von Prozessen ist es für die Leistung häufig vorteilhaft, Nachrichten in der Reihenfolge zu verarbeiten, in der sie empfangen werden (z. B. unter Verwendung von MPI_Waitany()
), was einen Nichtdeterminismus einführt. In solchen Fällen können Sie zwei Varianten implementieren, die schnelle, die in einer beliebigen Reihenfolge empfangen wird, und eine "Fehlerbehebung", die in einer statischen Reihenfolge empfangen wird. Dies setzt voraus, dass alle zugrunde liegenden Bibliotheken ebenfalls so geschrieben sind, dass sie dieses Verhalten bieten.
In einigen Fällen können Sie zum Debuggen einen Teil einer Berechnung, die dieses reproduzierbare Verhalten nicht bietet, isolieren und redundant ausführen. Je nachdem, wie die Komponenten entworfen wurden, kann diese Änderung eine geringe Menge an Code oder sehr aufdringlich sein.