Distributing tasks on several cores with IPython.parallel

In [1]:
import numpy as np
from ipyparallel import Client  # IPython.parallel before IPython 4.0
In [2]:
rc = Client()

Direct interface

In [3]:
rc.ids
Out[3]:
[0, 1, 2, 3]
In [4]:
%px import os, time
In [5]:
%px print(os.getpid())
Out[5]:
[stdout:0] 11173
[stdout:1] 11174
[stdout:2] 11175
[stdout:3] 11176
In [6]:
%%px --targets :-1
print(os.getpid())
Out[6]:
[stdout:0] 11173
[stdout:1] 11174
[stdout:2] 11175
In [7]:
view = rc[:-1]
view
Out[7]:
<DirectView [0, 1, 2]>

Load-balanced interface

In [8]:
v = rc.load_balanced_view()
In [9]:
def sample(n):
    import numpy as np
    # Random coordinates.
    x, y = np.random.rand(2, n)
    # Square distances to the origin.
    r_square = x ** 2 + y ** 2
    # Number of points in the quarter disc.
    return (r_square <= 1).sum()
In [10]:
def pi(n_in, n):
    return 4. * float(n_in) / n
In [11]:
n = 100000000
In [12]:
pi(sample(n), n)
Out[12]:
3.14174968
In [13]:
%timeit pi(sample(n), n)
Out[13]:
1 loops, best of 3: 2.65 s per loop
In [14]:
args = [n // 100] * 100
In [15]:
ar = v.map(sample, args)
In [16]:
ar.ready(), ar.progress
Out[16]:
(False, 12)
In [17]:
ar.elapsed, ar.serial_time
Out[17]:
(1.428284, 4.042367000000002)
In [18]:
pi(np.sum(ar.result), n)
Out[18]:
3.141666