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