MPI#
Often, a parallel algorithm requires moving data between the engines. One way is to push and pull over the DirectView
. However, this is slow because all of the data has to get through the controller to the client and then back to the final destination.
A much better option is to use the Message Passing Interface (MPI). IPython’s parallel computing architecture was designed from the ground up to integrate with MPI. This notebook gives a brief introduction to using MPI with IPython.
Requirements#
Starting the engines with activated MPI#
Automatic start with mpiexec
and ipcluster
#
This can be done with, e.g.
$ pipenv run ipcluster start -n 4 --profile=mpi
For this, however, a corresponding profile must first be created; see configuration.
Automatic start with PBS and ipcluster
#
The ipcluster
command also offers integration in PBS. You can find more information about this in Using ipcluster in PBS mode.
Example#
The following notebook cell calls psum.py
with the following content:
from mpi4py import MPI
import numpy as np
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]