{
 "metadata": {
  "name": "parallel python_10.12.12"
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Parallel Python - Interactive parallel programming"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#IPython\n",
      "\n",
      "##Supports different styles of parallelism\n",
      "\n",
      "    Single program, multiple data (SPMD) parallelism\n",
      "    \n",
      "    Multiple program, multiple data (MPMD) parallelism\n",
      "    \n",
      "    Message passing using MPI\n",
      "    \n",
      "    Task farming\n",
      "    \n",
      "    Combinations of above approaches\n",
      "    \n",
      "    Custom user de\ufb01ned approaches\n",
      "\n",
      "##Interactive approach to\n",
      "\n",
      "    Development\n",
      "    \n",
      "    Execution\n",
      "    \n",
      "    Debugging\n",
      "    \n",
      "    Monitoring"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#ARCITECTURE\n",
      "IPython is a tool for interactive and exploratory computing.\n",
      "We have seen that IPython's kernel provides a mechanism for interactive\n",
      "*remote* computation, and we have extended this same mechanism for\n",
      "interactive remote *parallel* computation, simply by having multiple\n",
      "kernels.\n",
      "<img src=\"files\\wideView400.png\">\n",
      "\n",
      "\n",
      "##Engine\n",
      "    *Takes Python commands over a network connection\n",
      "    *One engine per core\n",
      "    *Blocks code: controller has an asynchronous API\n",
      "##Controller client \n",
      "    *Interface for working with a set of engines\n",
      "    *Hub\n",
      "    *Collection of schedulers\n",
      "    *View objects represent a subset of engines\n",
      "    *A Direct interface, where engines are addressed explicitly.\n",
      "    *A LoadBalanced interface, where the Scheduler is trusted \n",
      "        with assigning work to appropriate engines.\n",
      "##Hub\n",
      "\n",
      "    keeps track of engine\n",
      "    connections, schedulers,\n",
      "    clients\n",
      "    \n",
      "##Cluster state Scheduler\n",
      "\n",
      "    All actions that can be\n",
      "    performed on the engine go\n",
      "    through a scheduler"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q1: How to start your Engines or a cluster?\n",
      "\n",
      "     *Simplest method - run the following from command line window\n",
      "        ipcluster start --n=4\n",
      "     *Specify cluster of engines from ipython notebook\n",
      "<img src=\"files\\startengine.png\">"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q2: How to define a client for interfacing with the defined cluster?\n",
      "###The client: lightweight handle on all engines of a cluster\n",
      "            from IPython.parallel import Client\n",
      "            rc = Client(profile='default')\n",
      "                    OR\n",
      "            rc = Client(profile='MPI')"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython import parallel\n",
      "rc = parallel.Client()\n",
      "rc.block = True # let's start synchronous"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 3
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q3: How to view the engines of the defined cluster?"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "rc.ids # the ids of cluster engines"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 4,
       "text": [
        "[0, 1, 2, 3]"
       ]
      }
     ],
     "prompt_number": 4
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q4: How to view and access different  \u201cslices\u201d the cluster?\n",
      "\n",
      "The most basic function of the Client is to create the View objects\n",
      "which are the interfaces for actual communication with the engines.\n",
      "\n",
      "There are two basic models for working with engines: \n",
      "\n",
      "            *DirectView: dview = rc.direct_view()*  \n",
      "       and \n",
      "            *LoadBalanced: lview = rc.load_balanced_view()* \n",
      "\n",
      "Let's start with the DirectView.\n",
      "\n"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# index-access of a client gives us a DirectView\n",
      "e0 = rc[0] # 0 engine\n",
      "eall = rc[:] # all engines\n",
      "even = rc[::2] # engines with even ids\n",
      "odd = rc[1::2] # engines with odd ids\n",
      "\n",
      "# this is the one we are going to use the most:\n",
      "dview = eall\n",
      "map(display, [e0, eall, even, odd]); "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "display_data",
       "text": [
        "<DirectView 0>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "<DirectView [0, 1, 2, 3]>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "<DirectView [0, 2]>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "<DirectView [1, 3]>"
       ]
      }
     ],
     "prompt_number": 6
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q5: What is the MAP function (Very important!)\n",
      "* Applies a a function to sequence of arguments element-by-element\n",
      "\n",
      "       "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "help(map) "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Help on built-in function map in module __builtin__:\n",
        "\n",
        "map(...)\n",
        "    map(function, sequence[, sequence, ...]) -> list\n",
        "    \n",
        "    Return a list of the results of applying the function to the items of\n",
        "    the argument sequence(s).  If more than one sequence is given, the\n",
        "    function is called with an argument list consisting of the corresponding\n",
        "    item of each sequence, substituting None for missing values when not all\n",
        "    sequences have the same length.  If the function is None, return a list of\n",
        "    the items of the sequence (or a list of tuples if more than one sequence).\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 7
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Import OS functionality"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import os\n",
      "pid = os.getpid()\n",
      "print pid"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "11608\n"
       ]
      }
     ],
     "prompt_number": 1
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "help(os)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "Help on module os:\n",
        "\n",
        "NAME\n",
        "    os - OS routines for Mac, NT, or Posix depending on what system we're on.\n",
        "\n",
        "FILE\n",
        "    c:\\python27\\lib\\os.py\n",
        "\n",
        "DESCRIPTION\n",
        "    This exports:\n",
        "      - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.\n",
        "      - os.path is one of the modules posixpath, or ntpath\n",
        "      - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'\n",
        "      - os.curdir is a string representing the current directory ('.' or ':')\n",
        "      - os.pardir is a string representing the parent directory ('..' or '::')\n",
        "      - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\\\')\n",
        "      - os.extsep is the extension separator ('.' or '/')\n",
        "      - os.altsep is the alternate pathname separator (None or '/')\n",
        "      - os.pathsep is the component separator used in $PATH etc\n",
        "      - os.linesep is the line separator in text files ('\\r' or '\\n' or '\\r\\n')\n",
        "      - os.defpath is the default search path for executables\n",
        "      - os.devnull is the file path of the null device ('/dev/null', etc.)\n",
        "    \n",
        "    Programs that import and use 'os' stand a better chance of being\n",
        "    portable between different platforms.  Of course, they must then\n",
        "    only use functions that are defined by all platforms (e.g., unlink\n",
        "    and opendir), and leave all pathname manipulation to os.path\n",
        "    (e.g., split and join).\n",
        "\n",
        "CLASSES\n",
        "    __builtin__.object\n",
        "        nt.stat_result\n",
        "        nt.statvfs_result\n",
        "    exceptions.EnvironmentError(exceptions.StandardError)\n",
        "        exceptions.OSError\n",
        "    \n",
        "    error = class OSError(EnvironmentError)\n",
        "     |  OS system call failed.\n",
        "     |  \n",
        "     |  Method resolution order:\n",
        "     |      OSError\n",
        "     |      EnvironmentError\n",
        "     |      StandardError\n",
        "     |      Exception\n",
        "     |      BaseException\n",
        "     |      __builtin__.object\n",
        "     |  \n",
        "     |  Methods defined here:\n",
        "     |  \n",
        "     |  __init__(...)\n",
        "     |      x.__init__(...) initializes x; see help(type(x)) for signature\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data and other attributes defined here:\n",
        "     |  \n",
        "     |  __new__ = <built-in method __new__ of type object>\n",
        "     |      T.__new__(S, ...) -> a new object with type S, a subtype of T\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Methods inherited from EnvironmentError:\n",
        "     |  \n",
        "     |  __reduce__(...)\n",
        "     |  \n",
        "     |  __str__(...)\n",
        "     |      x.__str__() <==> str(x)\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data descriptors inherited from EnvironmentError:\n",
        "     |  \n",
        "     |  errno\n",
        "     |      exception errno\n",
        "     |  \n",
        "     |  filename\n",
        "     |      exception filename\n",
        "     |  \n",
        "     |  strerror\n",
        "     |      exception strerror\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Methods inherited from BaseException:\n",
        "     |  \n",
        "     |  __delattr__(...)\n",
        "     |      x.__delattr__('name') <==> del x.name\n",
        "     |  \n",
        "     |  __getattribute__(...)\n",
        "     |      x.__getattribute__('name') <==> x.name\n",
        "     |  \n",
        "     |  __getitem__(...)\n",
        "     |      x.__getitem__(y) <==> x[y]\n",
        "     |  \n",
        "     |  __getslice__(...)\n",
        "     |      x.__getslice__(i, j) <==> x[i:j]\n",
        "     |      \n",
        "     |      Use of negative indices is not supported.\n",
        "     |  \n",
        "     |  __repr__(...)\n",
        "     |      x.__repr__() <==> repr(x)\n",
        "     |  \n",
        "     |  __setattr__(...)\n",
        "     |      x.__setattr__('name', value) <==> x.name = value\n",
        "     |  \n",
        "     |  __setstate__(...)\n",
        "     |  \n",
        "     |  __unicode__(...)\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data descriptors inherited from BaseException:\n",
        "     |  \n",
        "     |  __dict__\n",
        "     |  \n",
        "     |  args\n",
        "     |  \n",
        "     |  message\n",
        "    \n",
        "    class stat_result(__builtin__.object)\n",
        "     |  stat_result: Result from stat or lstat.\n",
        "     |  \n",
        "     |  This object may be accessed either as a tuple of\n",
        "     |    (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n",
        "     |  or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n",
        "     |  \n",
        "     |  Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n",
        "     |  or st_flags, they are available as attributes only.\n",
        "     |  \n",
        "     |  See os.stat for more information.\n",
        "     |  \n",
        "     |  Methods defined here:\n",
        "     |  \n",
        "     |  __add__(...)\n",
        "     |      x.__add__(y) <==> x+y\n",
        "     |  \n",
        "     |  __contains__(...)\n",
        "     |      x.__contains__(y) <==> y in x\n",
        "     |  \n",
        "     |  __eq__(...)\n",
        "     |      x.__eq__(y) <==> x==y\n",
        "     |  \n",
        "     |  __ge__(...)\n",
        "     |      x.__ge__(y) <==> x>=y\n",
        "     |  \n",
        "     |  __getitem__(...)\n",
        "     |      x.__getitem__(y) <==> x[y]\n",
        "     |  \n",
        "     |  __getslice__(...)\n",
        "     |      x.__getslice__(i, j) <==> x[i:j]\n",
        "     |      \n",
        "     |      Use of negative indices is not supported.\n",
        "     |  \n",
        "     |  __gt__(...)\n",
        "     |      x.__gt__(y) <==> x>y\n",
        "     |  \n",
        "     |  __hash__(...)\n",
        "     |      x.__hash__() <==> hash(x)\n",
        "     |  \n",
        "     |  __le__(...)\n",
        "     |      x.__le__(y) <==> x<=y\n",
        "     |  \n",
        "     |  __len__(...)\n",
        "     |      x.__len__() <==> len(x)\n",
        "     |  \n",
        "     |  __lt__(...)\n",
        "     |      x.__lt__(y) <==> x<y\n",
        "     |  \n",
        "     |  __mul__(...)\n",
        "     |      x.__mul__(n) <==> x*n\n",
        "     |  \n",
        "     |  __ne__(...)\n",
        "     |      x.__ne__(y) <==> x!=y\n",
        "     |  \n",
        "     |  __reduce__(...)\n",
        "     |  \n",
        "     |  __repr__(...)\n",
        "     |      x.__repr__() <==> repr(x)\n",
        "     |  \n",
        "     |  __rmul__(...)\n",
        "     |      x.__rmul__(n) <==> n*x\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data descriptors defined here:\n",
        "     |  \n",
        "     |  st_atime\n",
        "     |      time of last access\n",
        "     |  \n",
        "     |  st_ctime\n",
        "     |      time of last change\n",
        "     |  \n",
        "     |  st_dev\n",
        "     |      device\n",
        "     |  \n",
        "     |  st_gid\n",
        "     |      group ID of owner\n",
        "     |  \n",
        "     |  st_ino\n",
        "     |      inode\n",
        "     |  \n",
        "     |  st_mode\n",
        "     |      protection bits\n",
        "     |  \n",
        "     |  st_mtime\n",
        "     |      time of last modification\n",
        "     |  \n",
        "     |  st_nlink\n",
        "     |      number of hard links\n",
        "     |  \n",
        "     |  st_size\n",
        "     |      total size, in bytes\n",
        "     |  \n",
        "     |  st_uid\n",
        "     |      user ID of owner\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data and other attributes defined here:\n",
        "     |  \n",
        "     |  __new__ = <built-in method __new__ of type object>\n",
        "     |      T.__new__(S, ...) -> a new object with type S, a subtype of T\n",
        "     |  \n",
        "     |  n_fields = 13\n",
        "     |  \n",
        "     |  n_sequence_fields = 10\n",
        "     |  \n",
        "     |  n_unnamed_fields = 3\n",
        "    \n",
        "    class statvfs_result(__builtin__.object)\n",
        "     |  statvfs_result: Result from statvfs or fstatvfs.\n",
        "     |  \n",
        "     |  This object may be accessed either as a tuple of\n",
        "     |    (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n",
        "     |  or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n",
        "     |  \n",
        "     |  See os.statvfs for more information.\n",
        "     |  \n",
        "     |  Methods defined here:\n",
        "     |  \n",
        "     |  __add__(...)\n",
        "     |      x.__add__(y) <==> x+y\n",
        "     |  \n",
        "     |  __contains__(...)\n",
        "     |      x.__contains__(y) <==> y in x\n",
        "     |  \n",
        "     |  __eq__(...)\n",
        "     |      x.__eq__(y) <==> x==y\n",
        "     |  \n",
        "     |  __ge__(...)\n",
        "     |      x.__ge__(y) <==> x>=y\n",
        "     |  \n",
        "     |  __getitem__(...)\n",
        "     |      x.__getitem__(y) <==> x[y]\n",
        "     |  \n",
        "     |  __getslice__(...)\n",
        "     |      x.__getslice__(i, j) <==> x[i:j]\n",
        "     |      \n",
        "     |      Use of negative indices is not supported.\n",
        "     |  \n",
        "     |  __gt__(...)\n",
        "     |      x.__gt__(y) <==> x>y\n",
        "     |  \n",
        "     |  __hash__(...)\n",
        "     |      x.__hash__() <==> hash(x)\n",
        "     |  \n",
        "     |  __le__(...)\n",
        "     |      x.__le__(y) <==> x<=y\n",
        "     |  \n",
        "     |  __len__(...)\n",
        "     |      x.__len__() <==> len(x)\n",
        "     |  \n",
        "     |  __lt__(...)\n",
        "     |      x.__lt__(y) <==> x<y\n",
        "     |  \n",
        "     |  __mul__(...)\n",
        "     |      x.__mul__(n) <==> x*n\n",
        "     |  \n",
        "     |  __ne__(...)\n",
        "     |      x.__ne__(y) <==> x!=y\n",
        "     |  \n",
        "     |  __reduce__(...)\n",
        "     |  \n",
        "     |  __repr__(...)\n",
        "     |      x.__repr__() <==> repr(x)\n",
        "     |  \n",
        "     |  __rmul__(...)\n",
        "     |      x.__rmul__(n) <==> n*x\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data descriptors defined here:\n",
        "     |  \n",
        "     |  f_bavail\n",
        "     |  \n",
        "     |  f_bfree\n",
        "     |  \n",
        "     |  f_blocks\n",
        "     |  \n",
        "     |  f_bsize\n",
        "     |  \n",
        "     |  f_favail\n",
        "     |  \n",
        "     |  f_ffree\n",
        "     |  \n",
        "     |  f_files\n",
        "     |  \n",
        "     |  f_flag\n",
        "     |  \n",
        "     |  f_frsize\n",
        "     |  \n",
        "     |  f_namemax\n",
        "     |  \n",
        "     |  ----------------------------------------------------------------------\n",
        "     |  Data and other attributes defined here:\n",
        "     |  \n",
        "     |  __new__ = <built-in method __new__ of type object>\n",
        "     |      T.__new__(S, ...) -> a new object with type S, a subtype of T\n",
        "     |  \n",
        "     |  n_fields = 10\n",
        "     |  \n",
        "     |  n_sequence_fields = 10\n",
        "     |  \n",
        "     |  n_unnamed_fields = 0\n",
        "\n",
        "FUNCTIONS\n",
        "    abort(...)\n",
        "        abort() -> does not return!\n",
        "        \n",
        "        Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n",
        "        in the hardest way possible on the hosting operating system.\n",
        "    \n",
        "    access(...)\n",
        "        access(path, mode) -> True if granted, False otherwise\n",
        "        \n",
        "        Use the real uid/gid to test for access to a path.  Note that most\n",
        "        operations will use the effective uid/gid, therefore this routine can\n",
        "        be used in a suid/sgid environment to test if the invoking user has the\n",
        "        specified access to the path.  The mode argument can be F_OK to test\n",
        "        existence, or the inclusive-OR of R_OK, W_OK, and X_OK.\n",
        "    \n",
        "    chdir(...)\n",
        "        chdir(path)\n",
        "        \n",
        "        Change the current working directory to the specified path.\n",
        "    \n",
        "    chmod(...)\n",
        "        chmod(path, mode)\n",
        "        \n",
        "        Change the access permissions of a file.\n",
        "    \n",
        "    close(...)\n",
        "        close(fd)\n",
        "        \n",
        "        Close a file descriptor (for low level IO).\n",
        "    \n",
        "    closerange(...)\n",
        "        closerange(fd_low, fd_high)\n",
        "        \n",
        "        Closes all file descriptors in [fd_low, fd_high), ignoring errors.\n",
        "    \n",
        "    dup(...)\n",
        "        dup(fd) -> fd2\n",
        "        \n",
        "        Return a duplicate of a file descriptor.\n",
        "    \n",
        "    dup2(...)\n",
        "        dup2(old_fd, new_fd)\n",
        "        \n",
        "        Duplicate file descriptor.\n",
        "    \n",
        "    execl(file, *args)\n",
        "        execl(file, *args)\n",
        "        \n",
        "        Execute the executable file with argument list args, replacing the\n",
        "        current process.\n",
        "    \n",
        "    execle(file, *args)\n",
        "        execle(file, *args, env)\n",
        "        \n",
        "        Execute the executable file with argument list args and\n",
        "        environment env, replacing the current process.\n",
        "    \n",
        "    execlp(file, *args)\n",
        "        execlp(file, *args)\n",
        "        \n",
        "        Execute the executable file (which is searched for along $PATH)\n",
        "        with argument list args, replacing the current process.\n",
        "    \n",
        "    execlpe(file, *args)\n",
        "        execlpe(file, *args, env)\n",
        "        \n",
        "        Execute the executable file (which is searched for along $PATH)\n",
        "        with argument list args and environment env, replacing the current\n",
        "        process.\n",
        "    \n",
        "    execv(...)\n",
        "        execv(path, args)\n",
        "        \n",
        "        Execute an executable path with arguments, replacing current process.\n",
        "        \n",
        "            path: path of executable file\n",
        "            args: tuple or list of strings\n",
        "    \n",
        "    execve(...)\n",
        "        execve(path, args, env)\n",
        "        \n",
        "        Execute a path with arguments and environment, replacing current process.\n",
        "        \n",
        "            path: path of executable file\n",
        "            args: tuple or list of arguments\n",
        "            env: dictionary of strings mapping to strings\n",
        "    \n",
        "    execvp(file, args)\n",
        "        execvp(file, args)\n",
        "        \n",
        "        Execute the executable file (which is searched for along $PATH)\n",
        "        with argument list args, replacing the current process.\n",
        "        args may be a list or tuple of strings.\n",
        "    \n",
        "    execvpe(file, args, env)\n",
        "        execvpe(file, args, env)\n",
        "        \n",
        "        Execute the executable file (which is searched for along $PATH)\n",
        "        with argument list args and environment env , replacing the\n",
        "        current process.\n",
        "        args may be a list or tuple of strings.\n",
        "    \n",
        "    fdopen(...)\n",
        "        fdopen(fd [, mode='r' [, bufsize]]) -> file_object\n",
        "        \n",
        "        Return an open file object connected to a file descriptor.\n",
        "    \n",
        "    fstat(...)\n",
        "        fstat(fd) -> stat result\n",
        "        \n",
        "        Like stat(), but for an open file descriptor.\n",
        "    \n",
        "    fsync(...)\n",
        "        fsync(fildes)\n",
        "        \n",
        "        force write of file with filedescriptor to disk.\n",
        "    \n",
        "    getcwd(...)\n",
        "        getcwd() -> path\n",
        "        \n",
        "        Return a string representing the current working directory.\n",
        "    \n",
        "    getcwdu(...)\n",
        "        getcwdu() -> path\n",
        "        \n",
        "        Return a unicode string representing the current working directory.\n",
        "    \n",
        "    getenv(key, default=None)\n",
        "        Get an environment variable, return None if it doesn't exist.\n",
        "        The optional second argument can specify an alternate default.\n",
        "    \n",
        "    getpid(...)\n",
        "        getpid() -> pid\n",
        "        \n",
        "        Return the current process id\n",
        "    \n",
        "    isatty(...)\n",
        "        isatty(fd) -> bool\n",
        "        \n",
        "        Return True if the file descriptor 'fd' is an open file descriptor\n",
        "        connected to the slave end of a terminal.\n",
        "    \n",
        "    kill(...)\n",
        "        kill(pid, sig)\n",
        "        \n",
        "        Kill a process with a signal.\n",
        "    \n",
        "    listdir(...)\n",
        "        listdir(path) -> list_of_strings\n",
        "        \n",
        "        Return a list containing the names of the entries in the directory.\n",
        "        \n",
        "            path: path of directory to list\n",
        "        \n",
        "        The list is in arbitrary order.  It does not include the special\n",
        "        entries '.' and '..' even if they are present in the directory.\n",
        "    \n",
        "    lseek(...)\n",
        "        lseek(fd, pos, how) -> newpos\n",
        "        \n",
        "        Set the current position of a file descriptor.\n",
        "    \n",
        "    lstat(...)\n",
        "        lstat(path) -> stat result\n",
        "        \n",
        "        Like stat(path), but do not follow symbolic links.\n",
        "    \n",
        "    makedirs(name, mode=511)\n",
        "        makedirs(path [, mode=0777])\n",
        "        \n",
        "        Super-mkdir; create a leaf directory and all intermediate ones.\n",
        "        Works like mkdir, except that any intermediate path segment (not\n",
        "        just the rightmost) will be created if it does not exist.  This is\n",
        "        recursive.\n",
        "    \n",
        "    mkdir(...)\n",
        "        mkdir(path [, mode=0777])\n",
        "        \n",
        "        Create a directory.\n",
        "    \n",
        "    open(...)\n",
        "        open(filename, flag [, mode=0777]) -> fd\n",
        "        \n",
        "        Open a file (for low level IO).\n",
        "    \n",
        "    pipe(...)\n",
        "        pipe() -> (read_end, write_end)\n",
        "        \n",
        "        Create a pipe.\n",
        "    \n",
        "    popen(...)\n",
        "        popen(command [, mode='r' [, bufsize]]) -> pipe\n",
        "        \n",
        "        Open a pipe to/from a command returning a file object.\n",
        "    \n",
        "    popen2(...)\n",
        "    \n",
        "    popen3(...)\n",
        "    \n",
        "    popen4(...)\n",
        "    \n",
        "    putenv(...)\n",
        "        putenv(key, value)\n",
        "        \n",
        "        Change or add an environment variable.\n",
        "    \n",
        "    read(...)\n",
        "        read(fd, buffersize) -> string\n",
        "        \n",
        "        Read a file descriptor.\n",
        "    \n",
        "    remove(...)\n",
        "        remove(path)\n",
        "        \n",
        "        Remove a file (same as unlink(path)).\n",
        "    \n",
        "    removedirs(name)\n",
        "        removedirs(path)\n",
        "        \n",
        "        Super-rmdir; remove a leaf directory and all empty intermediate\n",
        "        ones.  Works like rmdir except that, if the leaf directory is\n",
        "        successfully removed, directories corresponding to rightmost path\n",
        "        segments will be pruned away until either the whole path is\n",
        "        consumed or an error occurs.  Errors during this latter phase are\n",
        "        ignored -- they generally mean that a directory was not empty.\n",
        "    \n",
        "    rename(...)\n",
        "        rename(old, new)\n",
        "        \n",
        "        Rename a file or directory.\n",
        "    \n",
        "    renames(old, new)\n",
        "        renames(old, new)\n",
        "        \n",
        "        Super-rename; create directories as necessary and delete any left\n",
        "        empty.  Works like rename, except creation of any intermediate\n",
        "        directories needed to make the new pathname good is attempted\n",
        "        first.  After the rename, directories corresponding to rightmost\n",
        "        path segments of the old name will be pruned way until either the\n",
        "        whole path is consumed or a nonempty directory is found.\n",
        "        \n",
        "        Note: this function can fail with the new directory structure made\n",
        "        if you lack permissions needed to unlink the leaf directory or\n",
        "        file.\n",
        "    \n",
        "    rmdir(...)\n",
        "        rmdir(path)\n",
        "        \n",
        "        Remove a directory.\n",
        "    \n",
        "    spawnl(mode, file, *args)\n",
        "        spawnl(mode, file, *args) -> integer\n",
        "        \n",
        "        Execute file with arguments from args in a subprocess.\n",
        "        If mode == P_NOWAIT return the pid of the process.\n",
        "        If mode == P_WAIT return the process's exit code if it exits normally;\n",
        "        otherwise return -SIG, where SIG is the signal that killed it.\n",
        "    \n",
        "    spawnle(mode, file, *args)\n",
        "        spawnle(mode, file, *args, env) -> integer\n",
        "        \n",
        "        Execute file with arguments from args in a subprocess with the\n",
        "        supplied environment.\n",
        "        If mode == P_NOWAIT return the pid of the process.\n",
        "        If mode == P_WAIT return the process's exit code if it exits normally;\n",
        "        otherwise return -SIG, where SIG is the signal that killed it.\n",
        "    \n",
        "    spawnv(...)\n",
        "        spawnv(mode, path, args)\n",
        "        \n",
        "        Execute the program 'path' in a new process.\n",
        "        \n",
        "            mode: mode of process creation\n",
        "            path: path of executable file\n",
        "            args: tuple or list of strings\n",
        "    \n",
        "    spawnve(...)\n",
        "        spawnve(mode, path, args, env)\n",
        "        \n",
        "        Execute the program 'path' in a new process.\n",
        "        \n",
        "            mode: mode of process creation\n",
        "            path: path of executable file\n",
        "            args: tuple or list of arguments\n",
        "            env: dictionary of strings mapping to strings\n",
        "    \n",
        "    startfile(...)\n",
        "        startfile(filepath [, operation]) - Start a file with its associated\n",
        "        application.\n",
        "        \n",
        "        When \"operation\" is not specified or \"open\", this acts like\n",
        "        double-clicking the file in Explorer, or giving the file name as an\n",
        "        argument to the DOS \"start\" command: the file is opened with whatever\n",
        "        application (if any) its extension is associated.\n",
        "        When another \"operation\" is given, it specifies what should be done with\n",
        "        the file.  A typical operation is \"print\".\n",
        "        \n",
        "        startfile returns as soon as the associated application is launched.\n",
        "        There is no option to wait for the application to close, and no way\n",
        "        to retrieve the application's exit status.\n",
        "        \n",
        "        The filepath is relative to the current directory.  If you want to use\n",
        "        an absolute path, make sure the first character is not a slash (\"/\");\n",
        "        the underlying Win32 ShellExecute function doesn't work if it is.\n",
        "    \n",
        "    stat(...)\n",
        "        stat(path) -> stat result\n",
        "        \n",
        "        Perform a stat system call on the given path.\n",
        "    \n",
        "    stat_float_times(...)\n",
        "        stat_float_times([newval]) -> oldval\n",
        "        \n",
        "        Determine whether os.[lf]stat represents time stamps as float objects.\n",
        "        If newval is True, future calls to stat() return floats, if it is False,\n",
        "        future calls return ints. \n",
        "        If newval is omitted, return the current setting.\n",
        "    \n",
        "    strerror(...)\n",
        "        strerror(code) -> string\n",
        "        \n",
        "        Translate an error code to a message string.\n",
        "    \n",
        "    system(...)\n",
        "        system(command) -> exit_status\n",
        "        \n",
        "        Execute the command (a string) in a subshell.\n",
        "    \n",
        "    tempnam(...)\n",
        "        tempnam([dir[, prefix]]) -> string\n",
        "        \n",
        "        Return a unique name for a temporary file.\n",
        "        The directory and a prefix may be specified as strings; they may be omitted\n",
        "        or None if not needed.\n",
        "    \n",
        "    times(...)\n",
        "        times() -> (utime, stime, cutime, cstime, elapsed_time)\n",
        "        \n",
        "        Return a tuple of floating point numbers indicating process times.\n",
        "    \n",
        "    tmpfile(...)\n",
        "        tmpfile() -> file object\n",
        "        \n",
        "        Create a temporary file with no directory entries.\n",
        "    \n",
        "    tmpnam(...)\n",
        "        tmpnam() -> string\n",
        "        \n",
        "        Return a unique name for a temporary file.\n",
        "    \n",
        "    umask(...)\n",
        "        umask(new_mask) -> old_mask\n",
        "        \n",
        "        Set the current numeric umask and return the previous umask.\n",
        "    \n",
        "    unlink(...)\n",
        "        unlink(path)\n",
        "        \n",
        "        Remove a file (same as remove(path)).\n",
        "    \n",
        "    urandom(...)\n",
        "        urandom(n) -> str\n",
        "        \n",
        "        Return n random bytes suitable for cryptographic use.\n",
        "    \n",
        "    utime(...)\n",
        "        utime(path, (atime, mtime))\n",
        "        utime(path, None)\n",
        "        \n",
        "        Set the access and modified time of the file to the given values.  If the\n",
        "        second form is used, set the access and modified times to the current time.\n",
        "    \n",
        "    waitpid(...)\n",
        "        waitpid(pid, options) -> (pid, status << 8)\n",
        "        \n",
        "        Wait for completion of a given process.  options is ignored on Windows.\n",
        "    \n",
        "    walk(top, topdown=True, onerror=None, followlinks=False)\n",
        "        Directory tree generator.\n",
        "        \n",
        "        For each directory in the directory tree rooted at top (including top\n",
        "        itself, but excluding '.' and '..'), yields a 3-tuple\n",
        "        \n",
        "            dirpath, dirnames, filenames\n",
        "        \n",
        "        dirpath is a string, the path to the directory.  dirnames is a list of\n",
        "        the names of the subdirectories in dirpath (excluding '.' and '..').\n",
        "        filenames is a list of the names of the non-directory files in dirpath.\n",
        "        Note that the names in the lists are just names, with no path components.\n",
        "        To get a full path (which begins with top) to a file or directory in\n",
        "        dirpath, do os.path.join(dirpath, name).\n",
        "        \n",
        "        If optional arg 'topdown' is true or not specified, the triple for a\n",
        "        directory is generated before the triples for any of its subdirectories\n",
        "        (directories are generated top down).  If topdown is false, the triple\n",
        "        for a directory is generated after the triples for all of its\n",
        "        subdirectories (directories are generated bottom up).\n",
        "        \n",
        "        When topdown is true, the caller can modify the dirnames list in-place\n",
        "        (e.g., via del or slice assignment), and walk will only recurse into the\n",
        "        subdirectories whose names remain in dirnames; this can be used to prune\n",
        "        the search, or to impose a specific order of visiting.  Modifying\n",
        "        dirnames when topdown is false is ineffective, since the directories in\n",
        "        dirnames have already been generated by the time dirnames itself is\n",
        "        generated.\n",
        "        \n",
        "        By default errors from the os.listdir() call are ignored.  If\n",
        "        optional arg 'onerror' is specified, it should be a function; it\n",
        "        will be called with one argument, an os.error instance.  It can\n",
        "        report the error to continue with the walk, or raise the exception\n",
        "        to abort the walk.  Note that the filename is available as the\n",
        "        filename attribute of the exception object.\n",
        "        \n",
        "        By default, os.walk does not follow symbolic links to subdirectories on\n",
        "        systems that support them.  In order to get this functionality, set the\n",
        "        optional argument 'followlinks' to true.\n",
        "        \n",
        "        Caution:  if you pass a relative pathname for top, don't change the\n",
        "        current working directory between resumptions of walk.  walk never\n",
        "        changes the current directory, and assumes that the client doesn't\n",
        "        either.\n",
        "        \n",
        "        Example:\n",
        "        \n",
        "        import os\n",
        "        from os.path import join, getsize\n",
        "        for root, dirs, files in os.walk('python/Lib/email'):\n",
        "            print root, \"consumes\",\n",
        "            print sum([getsize(join(root, name)) for name in files]),\n",
        "            print \"bytes in\", len(files), \"non-directory files\"\n",
        "            if 'CVS' in dirs:\n",
        "                dirs.remove('CVS')  # don't visit CVS directories\n",
        "    \n",
        "    write(...)\n",
        "        write(fd, string) -> byteswritten\n",
        "        \n",
        "        Write a string to a file descriptor.\n",
        "\n",
        "DATA\n",
        "    F_OK = 0\n",
        "    O_APPEND = 8\n",
        "    O_BINARY = 32768\n",
        "    O_CREAT = 256\n",
        "    O_EXCL = 1024\n",
        "    O_NOINHERIT = 128\n",
        "    O_RANDOM = 16\n",
        "    O_RDONLY = 0\n",
        "    O_RDWR = 2\n",
        "    O_SEQUENTIAL = 32\n",
        "    O_SHORT_LIVED = 4096\n",
        "    O_TEMPORARY = 64\n",
        "    O_TEXT = 16384\n",
        "    O_TRUNC = 512\n",
        "    O_WRONLY = 1\n",
        "    P_DETACH = 4\n",
        "    P_NOWAIT = 1\n",
        "    P_NOWAITO = 3\n",
        "    P_OVERLAY = 2\n",
        "    P_WAIT = 0\n",
        "    R_OK = 4\n",
        "    SEEK_CUR = 1\n",
        "    SEEK_END = 2\n",
        "    SEEK_SET = 0\n",
        "    TMP_MAX = 32767\n",
        "    W_OK = 2\n",
        "    X_OK = 1\n",
        "    __all__ = ['altsep', 'curdir', 'pardir', 'sep', 'extsep', 'pathsep', '...\n",
        "    altsep = '/'\n",
        "    curdir = '.'\n",
        "    defpath = r'.;C:\\bin'\n",
        "    devnull = 'nul'\n",
        "    environ = {'TMP': 'C:\\\\Users\\\\elias\\\\AppData\\\\Local\\\\Temp'...sers\\\\Pub...\n",
        "    extsep = '.'\n",
        "    linesep = '\\r\\n'\n",
        "    name = 'nt'\n",
        "    pardir = '..'\n",
        "    pathsep = ';'\n",
        "    sep = r'\\'\n",
        "\n",
        "\n"
       ]
      }
     ],
     "prompt_number": 2
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q6: How to manage data in the cluster?\n",
      "\n",
      "    * push, pull\n",
      "    "
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Push and Pull\n",
      "\n",
      "###Limited to dictionary types"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.block=True #waits until all engines are done executing the command\n",
      "values = dict(a=1.03234,b=3453)\n",
      "dview.push(values) # push the same data to all engines.\n",
      "a_values = dview.pull('a')#pull returns a list of the same length as the number of engines\n",
      "b_values = dview.pull('b')\n",
      "print a_values,b_values\n",
      "dview.push(dict(c='speed'))\n",
      "print dview.pull('c')\n",
      "dview['c'] = 'nospeed'\n",
      "print dview.pull('c')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[1.03234, 1.03234, 1.03234, 1.03234] [3453, 3453, 3453, 3453]\n",
        "['speed', 'speed', 'speed', 'speed']\n",
        "['nospeed', 'nospeed', 'nospeed', 'nospeed']\n"
       ]
      }
     ],
     "prompt_number": 10
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "e0.pull('a') #push data in engine 0"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 11,
       "text": [
        "1.03234"
       ]
      }
     ],
     "prompt_number": 11
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Blocking vs. Non-blocking\n",
      "\n",
      "###Blocking\n",
      "\n",
      "waits until all engines are done executing the command\n",
      "             *  dview.block=True\n",
      "###Non-blocking\n",
      "\n",
      "returns an AsyncResult immediate\n",
      "Get data later with get method\n",
      "Check the status with ready\n",
      "Wait\n",
      "           * dview.block=False"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q7: How to manage data in the cluster?\n",
      "\n",
      "      *Scatter and Gather\n",
      "\n",
      "        Partition a sequence and push/pull"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "DirectViews have scatter() and gather() methods, to help with this. Pass any container or numpy array, and IPython will partition the object onto the engines wih scatter, or reconstruct the full object in the Client with gather()."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.scatter('a', range(16))\n",
      "dview['a']"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 12,
       "text": [
        "[[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.gather('a')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 13,
       "text": [
        "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"
       ]
      }
     ],
     "prompt_number": 13
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.execute(\"asum = sum(a)\")\n",
      "dview.gather('asum')"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 14,
       "text": [
        "[6, 22, 38, 54]"
       ]
      }
     ],
     "prompt_number": 14
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "We can pass a 'flatten' keyword, to instruct engines that will only get one item of the list to get the actual item, rather than a one-element sublist."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.scatter('rank', rc.ids)\n",
      "dview['rank']"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 15,
       "text": [
        "[[0], [1], [2], [3]]"
       ]
      }
     ],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "This particular call is very common when you want MPI-style switching for the behavior of code depending on then engine.\n",
      "A simple scatter/gather of numpy arrays:"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.core.display import display, Math\n",
      "\n",
      "A = np.random.randint(1,10,(16,4))\n",
      "B = np.random.randint(1,10,(4,16))\n",
      "display(Math('A ='))\n",
      "display(A)\n",
      "display(Math('B ='))\n",
      "display(B)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$A =$$"
       ],
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0x53581f0>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "array([[7, 5, 3, 2],\n",
        "       [2, 4, 9, 5],\n",
        "       [9, 2, 9, 1],\n",
        "       [6, 9, 7, 7],\n",
        "       [3, 7, 5, 7],\n",
        "       [1, 6, 3, 8],\n",
        "       [8, 4, 8, 5],\n",
        "       [1, 3, 9, 1],\n",
        "       [4, 9, 4, 5],\n",
        "       [4, 5, 9, 4],\n",
        "       [9, 7, 6, 4],\n",
        "       [1, 2, 7, 3],\n",
        "       [1, 3, 4, 3],\n",
        "       [5, 2, 8, 9],\n",
        "       [8, 7, 8, 1],\n",
        "       [5, 1, 7, 5]])"
       ]
      },
      {
       "latex": [
        "$$B =$$"
       ],
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0x522eb70>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "array([[4, 9, 5, 4, 6, 6, 5, 2, 4, 5, 9, 9, 3, 8, 8, 7],\n",
        "       [6, 5, 9, 7, 7, 4, 1, 9, 6, 6, 7, 2, 3, 5, 8, 4],\n",
        "       [9, 3, 5, 2, 6, 2, 2, 5, 8, 7, 9, 4, 9, 7, 7, 9],\n",
        "       [8, 1, 1, 6, 3, 9, 9, 7, 7, 6, 2, 7, 9, 1, 9, 4]])"
       ]
      }
     ],
     "prompt_number": 17
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.scatter('A', A)\n",
      "dview.scatter('B', B)\n",
      "display(Math('A_0 ='))\n",
      "display(e0['A'])\n",
      "display(Math('B_0 ='))\n",
      "display(e0['B'])\n"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "latex": [
        "$$A_0 =$$"
       ],
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0x5216a50>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "array([[7, 5, 3, 2],\n",
        "       [2, 4, 9, 5],\n",
        "       [9, 2, 9, 1],\n",
        "       [6, 9, 7, 7]])"
       ]
      },
      {
       "latex": [
        "$$B_0 =$$"
       ],
       "output_type": "display_data",
       "text": [
        "<IPython.core.display.Math at 0x5216a50>"
       ]
      },
      {
       "output_type": "display_data",
       "text": [
        "array([[4, 9, 5, 4, 6, 6, 5, 2, 4, 5, 9, 9, 3, 8, 8, 7]])"
       ]
      }
     ],
     "prompt_number": 18
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Q8: How to distribute and execute code remotely (in the cluster of engines)?\n",
      "   * apply\n",
      "   * execute\n",
      "   * map\n",
      "   * Remote function decorators"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Apply\n",
      "\n",
      "We want the interface for remote and parallel execution to be as natural as possible. And what's the most natural unit of execution? Code! Simply define a function, just as you would use locally, and instead of calling it, pass it to view.apply(), with the remaining arguments just as you would have passed them to the function.\n",
      "\n",
      "dview.apply(f, *args, **kwargs)"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Sequential Computation"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def get_norms(A, levels=[2]):\n",
      "    \"\"\"get all the requested norms for an array\"\"\"\n",
      "    norms = []\n",
      "    for level in levels:\n",
      "        norms.append(numpy.linalg.norm(A, level))\n",
      "    return norms\n",
      "\n",
      "A = numpy.linspace(0, numpy.pi, 1024)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 20
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "get_norms( A, levels=[1,2,3,numpy.inf])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 21,
       "text": [
        "[1608.4954386379741,\n",
        " 58.055762082012201,\n",
        " 19.954367610618046,\n",
        " 3.1415926535897931]"
       ]
      }
     ],
     "prompt_number": 21
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "**To call this remotely above function and execute it, simply replace 'get_norms(' with 'view.apply(get_norms,':**"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "e0.apply(get_norms, A, levels=[1,2,3,numpy.inf])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "ename": "RemoteError",
       "evalue": "NameError(global name 'numpy' is not defined)",
       "output_type": "pyerr",
       "traceback": [
        "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
        "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)\u001b[1;32m<string>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m",
        "\u001b[1;32m<ipython-input-20-c22516ec5624>\u001b[0m in \u001b[0;36mget_norms\u001b[1;34m(A, levels)\u001b[0m",
        "\u001b[1;31mNameError\u001b[0m: global name 'numpy' is not defined"
       ]
      }
     ],
     "prompt_number": 24
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "%px import numpy # import on all active engines the numpy"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 25
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "e0.apply(get_norms, A, levels=[1,2,3,numpy.inf]) #executes the function on engine 0"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 26,
       "text": [
        "[1608.4954386379741,\n",
        " 58.055762082012201,\n",
        " 19.954367610618046,\n",
        " 3.1415926535897931]"
       ]
      }
     ],
     "prompt_number": 26
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "###Synchronous Parallel Execution"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.block=True #waits until all engines are done executing the command\n",
      "dview.apply(get_norms, A, levels=[1,2,3,numpy.inf]) #executes the function on all engines"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "pyout",
       "prompt_number": 28,
       "text": [
        "[[1608.4954386379741,\n",
        "  58.055762082012201,\n",
        "  19.954367610618046,\n",
        "  3.1415926535897931],\n",
        " [1608.4954386379741,\n",
        "  58.055762082012201,\n",
        "  19.954367610618046,\n",
        "  3.1415926535897931],\n",
        " [1608.4954386379741,\n",
        "  58.055762082012201,\n",
        "  19.954367610618046,\n",
        "  3.1415926535897931],\n",
        " [1608.4954386379741,\n",
        "  58.055762082012201,\n",
        "  19.954367610618046,\n",
        "  3.1415926535897931]]"
       ]
      }
     ],
     "prompt_number": 28
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "###Aychronous Parallel Computation"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.block=False #waits until all engines are done executing the command\n",
      "ar=dview.apply(get_norms, A, levels=[1,2,3,numpy.inf]) #executes the function on all engines\n",
      "print ar"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "<AsyncResult: get_norms>\n"
       ]
      }
     ],
     "prompt_number": 34
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "result=ar.get()\n",
      "print result"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[[1608.4954386379741, 58.055762082012201, 19.954367610618046, 3.1415926535897931], [1608.4954386379741, 58.055762082012201, 19.954367610618046, 3.1415926535897931], [1608.4954386379741, 58.055762082012201, 19.954367610618046, 3.1415926535897931], [1608.4954386379741, 58.055762082012201, 19.954367610618046, 3.1415926535897931]]\n"
       ]
      }
     ],
     "prompt_number": 35
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "*Remote functions* are just like normal functions, but when they are called, they execute on one or more engines, rather than locally. \n",
      "\n",
      "IPython provides two decorators:\n",
      "\n",
      "    In [10]: @dview.remote(block=True)\n",
      "       ....: def getpid():\n",
      "       ....:     import os\n",
      "       ....:     return os.getpid()\n",
      "       ....:\n",
      "\n",
      "    In [11]: getpid()\n",
      "    Out[11]: [12345, 12346, 12347, 12348]'"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Blocking vs. Non-blocking\n",
      "\n",
      "##Blocking\n",
      "waits until all engines are done executing the command\n",
      "\n",
      "                 *  dview.block=True\n",
      "\n",
      "##Non-blocking\n",
      "\n",
      "   * returns an AsyncResult immediate\n",
      "   * Get data later with get method\n",
      "   * Check the status with ready\n",
      "   * Wait\n",
      "\n",
      "                   * dview.block=False"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.parallel import Client\n",
      "rc = Client(profile='default')\n",
      "dview = rc.direct_view()\n",
      "with dview.sync_imports():\n",
      "    import os\n",
      "dview.block=True\n",
      "pids = dview.apply(os.getpid)\n",
      "   \n",
      "dview.block=False\n",
      "ar = dview.apply(os.getpid)  \n",
      "dview.wait(ar)\n",
      "pids = ar.get()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Apply\n",
      "\n",
      "   * apply_sync (block=True)\n",
      "   *  apply_async (block=False)"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def wait(t):\n",
      "    import time\n",
      "    tic = time.time()\n",
      "    time.sleep(t)\n",
      "    return time.time()-tic\n",
      "ar = dview.apply_async(wait,1)   \n",
      "if ar.ready() == True:\n",
      "    print \"ready\"\n",
      "else:\n",
      "    print \"not-ready\"\n",
      "   \n",
      "dview.wait(ar)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "not-ready\n"
       ]
      },
      {
       "output_type": "pyout",
       "prompt_number": 36,
       "text": [
        "True"
       ]
      }
     ],
     "prompt_number": 36
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Execute\n",
      "Commands can be executed as strings on speci\ufb01c\n",
      "engines"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview['a'] = 10\n",
      "dview['b'] = 20\n",
      "dview.execute('c=a*b')\n",
      "rc[1].execute('c=a+b')\n",
      "print dview['c']"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[200, 30, 200, 200]\n"
       ]
      }
     ],
     "prompt_number": 37
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.scatter('a',range(24))   \n",
      "print dview['a']\n",
      "all_a = dview.gather('a')\n",
      "print all_a\n",
      "# Use\n",
      "dview.scatter('x',range(64))\n",
      "dview.execute('y=map(fsquare, x)')\n",
      "y = dview.gather('y')\n",
      "print y"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10, 11], [12, 13, 14, 15, 16, 17], [18, 19, 20, 21, 22, 23]]\n",
        "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]\n",
        "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969]"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n"
       ]
      }
     ],
     "prompt_number": 42
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "##Map\n",
      "\n",
      "       * Applies a sequence of to a function element-by-element\n",
      "\n",
      "       * Does not do dynamic load balancing\n",
      "\n",
      "                    map_sync, map_async\n",
      "## Important Note\n",
      "       **Parallel Map = dview.map_sync = scatter, apply, gather**\n",
      "                        dview.map_async = scatter, apply**"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def fsquare(x):\n",
      "    return x**2\n",
      "xvals = range(32)    \n",
      "s_result = map(fsquare, xvals)\n",
      "print s_result\n",
      "dview.block=True\n",
      "p_result = dview.map(fsquare, xvals)\n",
      "print p_result"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961]\n",
        "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961]\n"
       ]
      }
     ],
     "prompt_number": 38
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def fsquare(x):\n",
      "    return x**2\n",
      "xvals = range(32)   \n",
      "s_result = dview.map_sync(fsquare, xvals)\n",
      "print s_result\n",
      "a_result = dview.map_async(fsquare, xvals)\n",
      "print a_result"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961]\n",
        "<AsyncMapResult: fsquare>\n"
       ]
      }
     ],
     "prompt_number": 39
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "result=a_result.get()\n",
      "print result"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961]\n"
       ]
      }
     ],
     "prompt_number": 40
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "dview.scatter('a',range(24))   \n",
      "print dview['a']\n",
      "all_a = dview.gather('a')\n",
      "print all_a\n",
      "# Use\n",
      "dview.scatter('x',range(64))\n",
      "dview.execute('y=map(fsquare, x)')\n",
      "y = dview.gather('y')\n",
      "print y"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "###Remote functions are just like normal functions, but when they are called, they execute on one or more engines, rather than locally.\n",
      "\n",
      "            IPython provides two decorators:\n",
      "            In [10]: @dview.remote(block=True)\n",
      "               ....: def getpid():\n",
      "               ....:     import os\n",
      "               ....:     return os.getpid()\n",
      "               ....:\n",
      "            \n",
      "            In [11]: getpid()\n",
      "            Out[11]: [12345, 12346, 12347, 12348]'"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from __future__ import print_function\n",
      "\n",
      "from IPython.parallel import *\n",
      "\n",
      "client = Client()\n",
      "view = client.load_balanced_view() # asynchronous execution controlled by the scheduler\n",
      "\n",
      "@view.remote(block=True)\n",
      "def square(a):\n",
      "    \"\"\"return square of a number\"\"\"\n",
      "    return a*a\n",
      "\n",
      "squares = map(square, range(42))\n",
      "\n",
      "# but that blocked between each result; not exactly useful\n",
      "\n",
      "square.block = False\n",
      "\n",
      "arlist = map(square, range(42))\n",
      "# submitted very fast\n",
      "\n",
      "# wait for the results:\n",
      "squares2 = [ r.get() for r in arlist ]\n",
      "\n",
      "# now the more convenient @parallel decorator, which has a map method:\n",
      "view2 = client[:]\n",
      "@view2.parallel(block=False)\n",
      "def psquare(a):\n",
      "    \"\"\"return square of a number\"\"\"\n",
      "    return a*a\n",
      "\n",
      "# this chunks the data into n-engines jobs, not 42 jobs:\n",
      "ar = psquare.map(range(42))\n",
      "\n",
      "# wait for the results to be done:\n",
      "squares3 = ar.get()\n",
      "print(squares == squares2, squares3==squares)\n",
      "# True"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "True True\n"
       ]
      }
     ],
     "prompt_number": 43
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#Task interface\n",
      "\n",
      "    *Presents the engines as a fault tolerant, dynamic loadbalanced\n",
      "            system of workers\n",
      "\n",
      "    *No direct access to individual engines\n",
      "\n",
      "    *Simple and powerful\n",
      "\n",
      "            lview = rc.load_balanced_view()\n",
      "\n",
      "##Components:\n",
      "\n",
      "        map\n",
      "\n",
      "        Parallel function decoders\n",
      "\n",
      "        Dependencies\n",
      "                functional \n",
      "                graph"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "\n",
      "def simulator(x):\n",
      "    import subprocess\n",
      "    cmd = \"./simulator \" + str(x) + \" 2 4 > trial.\" + str(x)\n",
      "    p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)\n",
      "    (err,out)=p.communicate()\n",
      "    status = p.returncode\n",
      "    return \"%s, %s\" % (out,err)  "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "   \n",
      "print simulator(1)    "
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "from IPython.parallel import Client\n",
      "rc = Client(profile='default')\n",
      "lview = rc.load_balanced_view()\n",
      "r = lview.map_async(simulator, range(100))\n",
      "print r.get()"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": "*"
    }
   ],
   "metadata": {}
  }
 ]
}