{ "metadata": { "name": "", "signature": "sha256:e58608ff09e4d334429f1517e7a9fa0629a8b5796af1bc579d07832f59f881ad" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "Basic Usage" ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.parallel import Client\n", "rc = Client()\n", "rc.ids" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 1, "text": [ "[0, 1, 2, 3]" ] } ], "prompt_number": 1 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use all engines by `DirectView`. By this view, it specifies engines to use" ] }, { "cell_type": "code", "collapsed": false, "input": [ "dview = rc[:]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we define the `is_prime` function as usual" ] }, { "cell_type": "code", "collapsed": false, "input": [ "with open('../builtin-cpuheavy/prime_list.txt') as f:\n", " PRIMES = [int(l) for l in f]\n", "\n", "def is_prime(n):\n", " import math # import until the function is called\n", " # make sure all engines import math\n", " if n % 2 == 0:\n", " return False\n", "\n", " sqrt_n = int(math.floor(math.sqrt(n)))\n", " for i in range(3, sqrt_n + 1, 2):\n", " if n % i == 0:\n", " return False\n", " return True" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Run in parallel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Use `map_async` or `map_sync` to map function to run in parallel" ] }, { "cell_type": "code", "collapsed": false, "input": [ "ar = dview.map_async(is_prime, PRIMES[:8])" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "ar.wait_interactive() # wait blocks, and wait_interactive provide working status" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ " 4/4 tasks finished after 12 s" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "done\n" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "ar.get()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 6, "text": [ "[True, True, True, True, True, False, True, True]" ] } ], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "speedup = ar.serial_time / ar.wall_time\n", "speedup" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 9, "text": [ "1.7723805092389953" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": true, "input": [ "ar.metadata[:1]" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 10, "text": [ "[{'follow': [],\n", " 'engine_id': 0,\n", " 'msg_id': 'c5c2c0dc-d560-4888-9d77-2cb6a565b8cf',\n", " 'submitted': datetime.datetime(2014, 4, 21, 14, 40, 12, 468317),\n", " 'started': datetime.datetime(2014, 4, 21, 14, 40, 12, 470405),\n", " 'stderr': '',\n", " 'completed': datetime.datetime(2014, 4, 21, 14, 40, 16, 244956),\n", " 'engine_uuid': '923ba113-2829-4f9d-8b67-ffe55c69a7e7',\n", " 'pyin': None,\n", " 'outputs': [],\n", " 'received': datetime.datetime(2014, 4, 21, 14, 40, 16, 248072),\n", " 'stdout': '',\n", " 'outputs_ready': True,\n", " 'pyout': None,\n", " 'after': [],\n", " 'pyerr': None,\n", " 'data': {},\n", " 'status': 'ok'}]" ] } ], "prompt_number": 10 }, { "cell_type": "markdown", "metadata": {}, "source": [ "More to checkout " ] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Import modules remotely" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If any modules imported, engines should import them as well. So here use a `dview.sync_import()` context_manager to help this issue. Note that `import numpy as np` will not actually intepreted as `np` module on engines but instead remaining `numpy`." ] }, { "cell_type": "code", "collapsed": false, "input": [ "with dview.sync_imports():\n", " import math\n", " import numpy as np" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "importing math on engine(s)\n", "importing numpy on engine(s)\n" ] } ], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "def find_np():\n", " np.random.randint(10)\n", "\n", "rc[:2].apply_sync(find_np)" ], "language": "python", "metadata": {}, "outputs": [ { "ename": "CompositeError", "evalue": "one or more exceptions from call to method: find_np\n[0:apply]: NameError: name 'np' is not defined\n[1:apply]: NameError: name 'np' is not defined", "output_type": "pyerr", "traceback": [ "[0:apply]: ", "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mfind_np\u001b[0;34m()\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined", "", "[1:apply]: ", "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m", "\u001b[0;32m\u001b[0m in \u001b[0;36mfind_np\u001b[0;34m()\u001b[0m", "\u001b[0;31mNameError\u001b[0m: name 'np' is not defined", "" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": [ "IPython Parallel Magic" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To do so, use `%%px` ipython magic. The `%%px` cell block executes its statements on all engines" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%px\n", "import numpy as np\n", "np.random.randint(6)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[0:2]: \u001b[0m1" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[1:2]: \u001b[0m2" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[2:2]: \u001b[0m3" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[3:2]: \u001b[0m4" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "%%px\n", "# try to run it multiple times, engines use same processes (like a remote Python intepreter)\n", "import os\n", "os.getpid()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[0:2]: \u001b[0m6952" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[1:2]: \u001b[0m6953" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[2:2]: \u001b[0m6954" ] }, { "metadata": {}, "output_type": "display_data", "text": [ "\u001b[0;31mOut[3:2]: \u001b[0m6955" ] } ], "prompt_number": 12 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": [ "Passing/Collecting Data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Pushing / pulling a variable to all engines" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# push\n", "dview['prog'] = 'val_prime'\n", "\n", "# pull\n", "dview['prog']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 13, "text": [ "['val_prime', 'val_prime', 'val_prime', 'val_prime']" ] } ], "prompt_number": 13 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": [ "Splitting a variable across engines" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# all engines get x but with differnt value\n", "ar = dview.scatter('x', list(range(13)))\n", "ar.wait()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "dview['x']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 15, "text": [ "[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]" ] } ], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "# get x from all engines and combined\n", "dview.gather('x', block=True)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 16, "text": [ "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]" ] } ], "prompt_number": 16 }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here is another example" ] }, { "cell_type": "code", "collapsed": false, "input": [ "%%px \n", "import numpy as np\n", "rand_n = np.random.randint(0, 10, 6)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "dview['rand_n']" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 19, "text": [ "[array([5, 8, 7, 7, 2, 9]),\n", " array([2, 9, 2, 2, 9, 4]),\n", " array([2, 5, 7, 7, 5, 1]),\n", " array([6, 4, 8, 5, 2, 5])]" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "dview.gather('rand_n', block=True)" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 20, "text": [ "array([5, 8, 7, 7, 2, 9, 2, 9, 2, 2, 9, 4, 2, 5, 7, 7, 5, 1, 6, 4, 8, 5, 2,\n", " 5])" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "# sum at each engine\n", "def rand_sum():\n", " return np.sum(rand_n)\n", "\n", "ar = dview.apply_sync(rand_sum)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "ar.get()" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 22, "text": [ "[38, 28, 27, 30]" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "# parallel sum shoud equal to serial sum\n", "sum(ar.get()) == sum(dview.gather('rand_n', block=True))" ], "language": "python", "metadata": {}, "outputs": [ { "metadata": {}, "output_type": "pyout", "prompt_number": 25, "text": [ "True" ] } ], "prompt_number": 25 } ], "metadata": {} } ] }