MPI¶
Oft erfordert ein paralleler Algorithmus das Verschieben von Daten zwischen den Engines. Eine Möglichkeit besteht darin, Push und Pull über die DirectView
. Dies ist jedoch langsam, da alle Daten über den Controller zum Client und dann wieder zurück zum endgültigen Ziel gelangen müssen.
Eine viel bessere Möglichkeit ist die Verwendung des Message Passing Interface (MPI). Die Parallel-Computing-Architektur von IPython wurde von Grund auf für die Integration mit MPI entwickelt. Dieses Notebook gibt eine kurze Einführung in die Verwendung von MPI mit IPython.
Anforderungen¶
Starten der Engines bei aktiviertem MPI¶
Automatisches Starten mit mpiexec
und ipcluster
¶
Dies kann z.B. erfolgen mit
$ uv run ipcluster start -n 4 --profile=mpi
Hierfür muss jedoch zuvor ein entsprechendes Profil angelegt werden; siehe hierfür Konfiguration.
Automatisches Starten mit PBS und ipcluster
¶
Der ipcluster
-Befehl bietet auch eine Integration in PBS. Weitere Informationen hierzu erhaltet ihr in Starting IPython Parallel on a traditional cluster.
Beispiel¶
Die folgende Notebook-Zelle ruft psum.py
mit folgendem Inhalt auf:
import numpy as np
from mpi4py import MPI
def psum(a):
locsum = np.sum(a)
rcvBuf = np.array(0.0, "d")
MPI.COMM_WORLD.Allreduce(
[locsum, MPI.DOUBLE], [rcvBuf, MPI.DOUBLE], op=MPI.SUM
)
return rcvBuf
[1]:
import ipyparallel as ipp
c = ipp.Client(profile="mpi")
view = c[:]
view.activate()
view.run("psum.py")
view.scatter("a", np.arange(16, dtype="float"))
view["a"]
[1]:
[array([0., 1., 2., 3.]),
array([4., 5., 6., 7.]),
array([ 8., 9., 10., 11.]),
array([12., 13., 14., 15.])]
[2]:
%px totalsum = psum(a)
[2]:
Parallel execution on engines: [0,1,2,3]
[3]:
view["totalsum"]
[3]:
[120.0, 120.0, 120.0, 120.0]