{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Using `ipyparallel`\n", "====\n", "\n", "Parallel execution is tightly integrated with Jupyter in the `ipyparallel` package. Install with\n", "\n", "```bash\n", "conda install ipyparallel\n", "ipcluster nbextension enable\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Official documentation](https://ipyparallel.readthedocs.org/en/latest/)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%matplotlib inline\n", "import numpy as np\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Starting engines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will only use engines on local cores which does not require any setup - see [docs](https://ipyparallel.readthedocs.org/en/latest/process.html) for detailed instructions on how to set up a remote cluster, including setting up to use Amazon EC2 clusters.\n", "\n", "You can start a cluster on the `IPython Clusters` tab in the main Jupyter browser window or via the command line with\n", "\n", "```\n", "ipcluster start -n \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The main advantage of developing parallel applications using `ipyparallel` is that it can be done interactively within Jupyter." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Basic concepts of `ipyparallel`" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from ipyparallel import Client" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The client connects to the cluster of \"remote\" engines that perfrom the actual computation. These engines may be on the same machine or on a cluster. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "rc = Client()" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 1, 2, 3, 4, 5, 6, 7]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rc.ids" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A view provides access to a subset of the engines available to the client. Jobs are submitted to the engines via the view. A direct view allows the user to explicitly send work specific engines. The load balanced view is like the `Pool` object in `multiprocessing`, and manages the scheduling and distribution of jobs for you." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Direct view**" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "dv = rc[:]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add 10 sets of 3 numbers in parallel using all engines." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map_sync(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add 10 sets of 3 numbers in parallel using only alternate engines." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rc[::2].map_sync(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add 10 sets of 3 numbers using a specific engine." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rc[2].map_sync(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Load balanced view**\n", "\n", "Use this when you have many jobs that take different amounts of time to complete." ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "lv = rc.load_balanced_view()" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[49943.055545684554,\n", " 49958.361259726298,\n", " 49864.353608090729,\n", " 50138.070719165735,\n", " 49948.175168188893,\n", " 49988.083010381451,\n", " 50019.95202007662,\n", " 49935.980196889475,\n", " 50126.055843775182,\n", " 50015.903549302966]" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lv.map_sync(lambda x: sum(x), np.random.random((10, 100000)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Calling functions with apply" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In contrast to `map`, `apply` is just a simple function call run on all remote engines, and has the usual function signature `apply(f, *args, **kwargs)`. It is a primitive on which other more useful functions (such as `map`) are built upon." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[25, 25]" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rc[1:3].apply_sync(lambda x, y: x**2 + y**2, 3, 4)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[25, 25]" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "rc[1:3].apply_sync(lambda x, y: x**2 + y**2, x=3, y=4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Synchronous and asynchronous jobs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have used the `map_sync` and `apply_sync` methods. The `sync` suffix indicate that we want to run a synchronous job. Synchronous jobs `block` until all the computation is done and return the result." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "res = dv.map_sync(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In contrast, asynchronous jobs return immediately so that you can do other work, but returns a `AsyncMapResult` object, similar to the `future` object returned by the `concurrent.futures` package. You can query its status, cancel running jobs and retrieve results once they have been computed." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "res = dv.map_async(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ ">" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.done()" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There is also a `map` method that by default uses asynchronous mode, but you can change this by setting the `block` attribute or function argument." ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "res = dv.map(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res.get()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Change blocking mode for just one job." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "res = dv.map(lambda x, y, z: x + y + z, range(10), range(10), range(10), block=True)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Change blocking mode for this view so that all jobs are synchronous." ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [], "source": [ "dv.block = True" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [], "source": [ "res = dv.map(lambda x, y, z: x + y + z, range(10), range(10), range(10))" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 3, 6, 9, 12, 15, 18, 21, 24, 27]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "res" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "### Remote function decorators " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `@remote` decorator results in functions that will execute simultaneously on all engines in a view. For example, you can use this decorator if you always want to run $n$ independent parallel MCMC chains." ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "importing numpy on engine(s)\n" ] } ], "source": [ "with dv.sync_imports():\n", " import numpy" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "@dv.remote(block = True)\n", "def f1(n):\n", " return numpy.random.rand(n)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[array([ 0.33832753, 0.23342134, 0.09817073, 0.51060264]),\n", " array([ 0.24919434, 0.61226489, 0.1709979 , 0.92716651]),\n", " array([ 0.19053364, 0.35857299, 0.09015628, 0.32347737]),\n", " array([ 0.7697255 , 0.57345448, 0.10060588, 0.3875056 ]),\n", " array([ 0.89363384, 0.70684507, 0.27046639, 0.12688668]),\n", " array([ 0.75036068, 0.2489435 , 0.3555557 , 0.52555086]),\n", " array([ 0.94484292, 0.12537997, 0.94156442, 0.10110875]),\n", " array([ 0.49883145, 0.76342079, 0.51813558, 0.54732924])]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f1(4)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The @parallel decorator breaks up elementwise operations and distributes them." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "@dv.parallel(block = True)\n", "def f2(x):\n", " return x" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[range(0, 2),\n", " range(2, 4),\n", " range(4, 6),\n", " range(6, 8),\n", " range(8, 10),\n", " range(10, 12),\n", " range(12, 14),\n", " range(14, 15)]" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f2(range(15))" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "@dv.parallel(block = True)\n", "def f3(x):\n", " return sum(x)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1, 5, 9, 13, 17, 21, 25, 14]" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f3(range(15))" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [], "source": [ "@dv.parallel(block = True)\n", "def f4(x, y):\n", " return x + y" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 2, 4, 6, 8, 10, 12, 14, 16, 18])" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "f4(np.arange(10), np.arange(10))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Example: Use the `@parallel` decorator to speed up Mandelbrot calculations" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [], "source": [ "def mandel1(x, y, max_iters=80):\n", " c = complex(x, y)\n", " z = 0.0j\n", " for i in range(max_iters):\n", " z = z*z + c\n", " if z.real*z.real + z.imag*z.imag >= 4:\n", " return i\n", " return max_iters" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [], "source": [ "@dv.parallel(block = True)\n", "def mandel2(x, y, max_iters=80):\n", " c = complex(x, y)\n", " z = 0.0j\n", " for i in range(max_iters):\n", " z = z*z + c\n", " if z.real*z.real + z.imag*z.imag >= 4:\n", " return i\n", " return max_iters" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "x = np.arange(-2, 1, 0.01)\n", "y = np.arange(-1, 1, 0.01)\n", "X, Y = np.meshgrid(x, y)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 536 ms, sys: 4 ms, total: 540 ms\n", "Wall time: 547 ms\n" ] } ], "source": [ "%%time\n", "im1 = np.reshape(list(map(mandel1, X.ravel(), Y.ravel())), (len(y), len(x)))" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CPU times: user 40 ms, sys: 0 ns, total: 40 ms\n", "Wall time: 156 ms\n" ] } ], "source": [ "%%time\n", "im2 = np.reshape(mandel2.map(X.ravel(), Y.ravel()), (len(y), len(x)))" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, axes = plt.subplots(1, 2, figsize=(12, 4))\n", "axes[0].grid(False)\n", "axes[0].imshow(im1, cmap='jet')\n", "axes[1].grid(False)\n", "axes[1].imshow(im2, cmap='jet')\n", "pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Functions with dependencies" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Modules imported locally are NOT available in the remote engines." ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [], "source": [ "import time\n", "import datetime" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [], "source": [ "def g1(x):\n", " time.sleep(0.1)\n", " now = datetime.datetime.now()\n", " return (now, x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This fails with an Exception because the `time` and `datetime` modules are not imported in the remote engines.\n", "\n", "```python\n", "dv.map_sync(g1, range(10))\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The simplest fix is to import the module(s) *within* the function" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [], "source": [ "def g2(x):\n", " import time, datetime\n", " time.sleep(0.1)\n", " now = datetime.datetime.now()\n", " return (now, x)" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(datetime.datetime(2018, 4, 3, 20, 33, 10, 207910), 0),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 209498), 1),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 209653), 2),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 209659), 3),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 209884), 4)]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map_sync(g2, range(5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Alternatively, you can simultaneously import both locally and in the remote engines with the `sync_import` context manager." ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "importing time on engine(s)\n", "importing datetime on engine(s)\n" ] } ], "source": [ "with dv.sync_imports():\n", " import time\n", " import datetime" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now the `g1` function will work." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[(datetime.datetime(2018, 4, 3, 20, 33, 10, 396045), 0),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 395993), 1),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 396044), 2),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 397792), 3),\n", " (datetime.datetime(2018, 4, 3, 20, 33, 10, 398626), 4)]" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map_sync(g1, range(5))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, there is also a `require` decorator that can be used. This will force the remote engine to import all packages given." ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [], "source": [ "from ipyparallel import require" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [], "source": [ "@require('scipy.stats')\n", "def g3(x):\n", " return scipy.stats.norm(0,1).pdf(x)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0.0044318484119380075,\n", " 0.053990966513188063,\n", " 0.24197072451914337,\n", " 0.3989422804014327,\n", " 0.24197072451914337,\n", " 0.053990966513188063,\n", " 0.0044318484119380075]" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map(g3, np.arange(-3, 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Moving data around" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can send data to remote engines with `push` and retrieve them with `pull`, or using the dictionary interface. For example, you can use this to distribute a large lookup table to all engines once instead of repeatedly as a function argument." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[None, None, None, None, None, None, None, None]" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.push(dict(a=3, b=2))" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [], "source": [ "def f(x):\n", " global a, b\n", " return a*x + b" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[2, 5, 8, 11, 14]" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map_sync(f, range(5))" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2]]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.pull(('a', 'b'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### You can also use the dictionary interface as an alternative to push and pull" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [], "source": [ "dv['c'] = 5" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[3, 3, 3, 3, 3, 3, 3, 3]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv['a']" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[5, 5, 5, 5, 5, 5, 5, 5]" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv['c']" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Working with compiled code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Numba" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using `numba.jit` is straightforward. See [example](https://github.com/barbagroup/numba_tutorial_scipy2016/blob/master/notebooks/10.optional.Numba.and.ipyparallel.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Cython" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We need to do some extra work to make sure the shared libary compiled with cython is available to the remote engines:\n", "\n", "- Compile a `named` shared module with the `-n` flag\n", "- Use `np.ndarray[dtype, ndim]` in place of memroy views\n", " - for example, double[:] becomes np.ndarray[np.float64_t, ndim=1]\n", "- Move the shared library to the `site-packages` directory\n", " - Cython magic moules can be found in `~/.cache/ipython/cython`\n", "- Import the modules remtoely in the usual ways" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [], "source": [ "%load_ext cython" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "%%cython -n cylib\n", "\n", "import cython\n", "import numpy as np\n", "cimport numpy as np\n", "\n", "@cython.boundscheck(False)\n", "@cython.wraparound(False)\n", "def f(np.ndarray[np.float64_t, ndim=1] x):\n", " x.setflags(write=True)\n", " cdef int i\n", " cdef int n = x.shape[0]\n", " cdef double s = 0\n", "\n", " for i in range(n):\n", " s += x[i]\n", " return s" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Copy the compiled module in `site-packages` so that the remote engines can import it" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'/opt/conda/lib/python3.6/site-packages/cylib.cpython-36m-x86_64-linux-gnu.so'" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import os\n", "import glob\n", "import site\n", "import shutil\n", "src = glob.glob(os.path.join(os.path.expanduser('~/'), '.cache', 'ipython', 'cython', 'cylib*so'))[0]\n", "dst = site.getsitepackages()[0]\n", "shutil.copy(src, dst)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "importing cylib on engine(s)\n" ] } ], "source": [ "with dv.sync_imports():\n", " import cylib" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Using parallel magic commands\n", "----\n", "\n", "In practice, most users will simply use the `%px` magic to execute code in parallel from within the notebook. This is the simplest way to use `ipyparallel`." ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[1.8825694893878855,\n", " 1.3291781855139693,\n", " 1.5788796473521334,\n", " 2.8365779834827047,\n", " 1.7491894709462499,\n", " 0.8538153083687106]" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.map(cylib.f, np.random.random((6, 4)))" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "### %px" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This sends the command to all targeted engines." ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "\u001b[0;31mOut[0:3]: \u001b[0m1.4108615162007481" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.754069", "data": {}, "engine_id": 0, "engine_uuid": "7fda7dc8-aafc798d1c0be69a39892f40", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "1.4108615162007481" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "33e7b590-4519f0cfa55be4d85065ebc5", "outputs": [], "received": "2018-04-03T20:33:11.759928", "started": "2018-04-03T20:33:11.738724", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.726558" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[1:3]: \u001b[0m2.307313190289948" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.744295", "data": {}, "engine_id": 1, "engine_uuid": "5264b541-68faf9b8454e02a33f068256", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "2.307313190289948" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "1966f3aa-71cc5ca8e87d733dc4a34ba7", "outputs": [], "received": "2018-04-03T20:33:11.749715", "started": "2018-04-03T20:33:11.731344", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.726809" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[2:3]: \u001b[0m2.7734346738281523" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.753579", "data": {}, "engine_id": 2, "engine_uuid": "bdb17e61-69b2a701e1c202e2155d680e", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "2.7734346738281523" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "cb1b47d7-816d81ae0393f734969a3271", "outputs": [], "received": "2018-04-03T20:33:11.756543", "started": "2018-04-03T20:33:11.732184", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.727023" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[3:3]: \u001b[0m1.2018443672156747" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.758204", "data": {}, "engine_id": 3, "engine_uuid": "7d7cd320-6d4fcedab0409ef4a8cdf4ae", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "1.2018443672156747" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "2b69696a-73ffbe38c76fa9bf5d306172", "outputs": [], "received": "2018-04-03T20:33:11.761406", "started": "2018-04-03T20:33:11.743408", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.727229" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[4:3]: \u001b[0m1.4850212778476148" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.754590", "data": {}, "engine_id": 4, "engine_uuid": "a2afa04c-e365c12979c5494d6d6befe2", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "1.4850212778476148" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "180298ce-2c4e905026a4625d14cbf981", "outputs": [], "received": "2018-04-03T20:33:11.758507", "started": "2018-04-03T20:33:11.732457", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.727469" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[5:3]: \u001b[0m1.7126681481007608" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.748814", "data": {}, "engine_id": 5, "engine_uuid": "7d4787e7-872b2199b5d717db0d36dba1", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "1.7126681481007608" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "4eab5bc3-0f19bb22f576d91536fb3683", "outputs": [], "received": "2018-04-03T20:33:11.752834", "started": "2018-04-03T20:33:11.731606", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.727783" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[6:3]: \u001b[0m2.1182406999813619" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.743050", "data": {}, "engine_id": 6, "engine_uuid": "85ec0125-09e8acd16999a30ed9ccb669", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "2.1182406999813619" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "43732350-de4a4820f5e38710018a831a", "outputs": [], "received": "2018-04-03T20:33:11.747013", "started": "2018-04-03T20:33:11.731677", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.727980" }, "output_type": "display_data" }, { "data": { "text/plain": [ "\u001b[0;31mOut[7:3]: \u001b[0m1.5880181901926447" ] }, "metadata": { "after": [], "completed": "2018-04-03T20:33:11.743889", "data": {}, "engine_id": 7, "engine_uuid": "9d8db3b0-639a304fc01c05536f07d005", "error": null, "execute_input": "a.sum()", "execute_result": { "data": { "text/plain": "1.5880181901926447" }, "execution_count": 3, "metadata": {} }, "follow": [], "msg_id": "5c7b2bd6-0e5cfc187c745824fadd846f", "outputs": [], "received": "2018-04-03T20:33:11.748393", "started": "2018-04-03T20:33:11.731860", "status": "ok", "stderr": "", "stdout": "", "submitted": "2018-04-03T20:33:11.728190" }, "output_type": "display_data" } ], "source": [ "%px import numpy as np\n", "%px a = np.random.random(4)\n", "%px a.sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### List comprehensions in parallel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `scatter` method partitions and distributes data to all engines. The `gather` method does the reverse. Together with `%px`, we can simulate parallel list comprehensions." ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[stdout:0] [0 9]\n", "[stdout:1] [6 9]\n", "[stdout:2] [9]\n", "[stdout:3] [5]\n", "[stdout:4] [7]\n", "[stdout:5] [9]\n", "[stdout:6] [1]\n", "[stdout:7] [5]\n" ] } ], "source": [ "dv.scatter('a', np.random.randint(0, 10, 10))\n", "%px print(a)" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([0, 9, 6, 9, 9, 5, 7, 9, 1, 5])" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.gather('a')" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144,\n", " 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529])" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "dv.scatter('xs', range(24))\n", "%px y = [x**2 for x in xs]\n", "np.array(dv.gather('y'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Running magic functions in parallel" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[output:1]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "engine": 1 }, "output_type": "display_data" }, { "data": { "text/plain": [ "[output:3]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "engine": 3 }, "output_type": "display_data" } ], "source": [ "%%px --target [1,3]\n", "%matplotlib inline\n", "import seaborn as sns\n", "x = np.random.normal(np.random.randint(-10, 10), 1, 100)\n", "sns.kdeplot(x);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Running in non-blocking mode" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%px --target [1,3] --noblock\n", "%matplotlib inline\n", "import seaborn as sns\n", "x = np.random.normal(np.random.randint(-10, 10), 1, 100)\n", "sns.kdeplot(x);" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[output:1]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "engine": 1 }, "output_type": "display_data" }, { "data": { "text/plain": [ "[output:3]" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "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\n", "text/plain": [ "" ] }, "metadata": { "engine": 3 }, "output_type": "display_data" } ], "source": [ "%pxresult" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interacting with individual engines" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can interact with individual engines by calling the %qtconsole on each engine." ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [], "source": [ "%px %qtconsole" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "Try looking at some of the variables defined in earlier cells - e..g `a`, `x`, `y` etc. Change the values directly in the console, then pull back into the notebook interface. Are the changes made preserved?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 1 }