{ "metadata": { "name": "9932_05_03" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Chapter 5, example 3\n", "====================\n", "\n", "In this example we show how to use MPI from IPython." ] }, { "cell_type": "code", "collapsed": false, "input": [ "from IPython.parallel import Client" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We first need to create a MPI profile with:\n", "\n", " ipython profile create --parallel --profile=mpi\n", "\n", "Then specify the following in the cluster configuration file:\n", "\n", " c.IPClusterEngines.engine_launcher_class = 'MPIEngineSetLauncher'\n", "\n", "and run the engines with:\n", "\n", " ipcluster start -n 4 --profile=mpi\n", "\n", "Now, we can create a MPI client." ] }, { "cell_type": "code", "collapsed": false, "input": [ "c = Client(profile='mpi')" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "view = c[:]" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "view.activate() # enable magics" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will compute the sum of all integers between 1 and 16 in parallel over four cores. The script `psum.py` contains the following code:\n", "\n", " from mpi4py import MPI\n", " import numpy as np\n", " \n", " # This function will be executed on all processes.\n", " def psum(a):\n", " # \"a\" only contains a subset of all integers.\n", " # They are summed locally on this process. \n", " locsum = np.sum(a)\n", " \n", " # We allocate a variable that will contain the final result, that is,\n", " # the sum of all our integers.\n", " rcvBuf = np.array(0.0,'d')\n", " \n", " # We use a MPI reduce operation:\n", " # * locsum is combined from all processes\n", " # * these local sums are summed with the MPI.SUM operation\n", " # * the result (total sum) is distributed back to all processes in\n", " # the rcvBuf variable\n", " MPI.COMM_WORLD.Allreduce([locsum, MPI.DOUBLE],\n", " [rcvBuf, MPI.DOUBLE],\n", " op=MPI.SUM)\n", " return rcvBuf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We execute this script on all engines so that the function is available everywhere." ] }, { "cell_type": "code", "collapsed": false, "input": [ "view.run('psum.py') # the script runs on all processes" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we distribute the array with the 16 values across the engines (each engine gets a subarray)." ] }, { "cell_type": "code", "collapsed": false, "input": [ "view.scatter('a', np.arange(16)) # this array is scattered across processes" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We compute the total sum in parallel using MPI." ] }, { "cell_type": "code", "collapsed": false, "input": [ "%px totalsum = psum(a) # psum is executed on all processes" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, the result is available on all engines thanks to the MPI `Allreduce` function." ] }, { "cell_type": "code", "collapsed": false, "input": [ "view['totalsum']" ], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }