Une réduction implémentée à l'aide MPI_Allreduce()
est reproductible tant que vous utilisez le même nombre de processeurs, à condition que l'implémentation respecte la note suivante figurant à la section 5.9.1 de la norme MPI-2.2.
Conseils aux exécutants . Il est fortement recommandé de MPI_REDUCE
l'implémenter afin que le même résultat soit obtenu chaque fois que la fonction est appliquée sur les mêmes arguments, apparaissant dans le même ordre. Notez que cela peut empêcher les optimisations qui tirent parti de l'emplacement physique des processeurs. ( Fin des conseils aux exécutants .)
Si vous devez garantir la reproductibilité à tout prix, vous pouvez suivre les instructions du paragraphe suivant:
Conseils aux utilisateurs . Certaines applications peuvent ne pas être en mesure d'ignorer la nature non associative des opérations en virgule flottante ou peuvent utiliser des opérations définies par l'utilisateur (voir la section 5.9.5) qui nécessitent un ordre de réduction spécial et ne peuvent pas être traitées comme associatives. Ces demandes devraient faire respecter l'ordre d'évaluation de manière explicite. Par exemple, dans le cas d'opérations qui nécessitent un ordre d'évaluation strict de gauche à droite (ou de droite à gauche), cela pourrait être fait en rassemblant tous les opérandes en un seul processus (par exemple, avec
MPI_GATHER
), en appliquant l'opération de réduction dans l'ordre souhaité (par exemple, avec
MPI_REDUCE_LOCAL
) et, si nécessaire, diffusez ou diffusez le résultat aux autres processus (par exemple, avec MPI_BCAST
). ( Fin des conseils aux utilisateurs .)
Dans le schéma plus large des choses, des algorithmes efficaces pour la plupart des applications tirent parti de la localité. Étant donné que l'algorithme est vraiment différent lorsqu'il est exécuté sur un nombre différent de processus, il n'est tout simplement pas pratique de reproduire exactement les résultats lorsqu'il est exécuté sur un nombre différent de processus. Une exception possible est multigrille avec Jacobi amorti ou lisseurs polynomiaux (par exemple Chebyshev), où il est possible que cette méthode simple fonctionne très bien.
Avec le même nombre de processus, il est souvent avantageux pour la performance de traiter les messages dans l'ordre de leur réception (par exemple en utilisant MPI_Waitany()
), ce qui introduit le non-déterminisme. Dans de tels cas, vous pouvez implémenter deux variantes, la plus rapide qui reçoit dans n'importe quel ordre et une "débogage" qui reçoit dans un ordre statique. Cela nécessite que toutes les bibliothèques sous-jacentes soient également écrites pour offrir ce comportement.
Pour le débogage dans certains cas, vous pouvez isoler une partie d'un calcul qui n'offre pas ce comportement reproductible et l'exécuter de manière redondante. Selon la façon dont les composants ont été conçus, ce changement peut être une petite quantité de code ou très intrusif.