├── README.md ├── .gitignore └── mandelbrot_numba.ipynb /README.md: -------------------------------------------------------------------------------- 1 | numba_examples 2 | ================= 3 | 4 | Examples using Numba from Continuum Analytics 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | 3 | # C extensions 4 | *.so 5 | 6 | # Packages 7 | *.egg 8 | *.egg-info 9 | dist 10 | build 11 | eggs 12 | parts 13 | bin 14 | var 15 | sdist 16 | develop-eggs 17 | .installed.cfg 18 | lib 19 | lib64 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | nosetests.xml 28 | 29 | # Translations 30 | *.mo 31 | 32 | # Mr Developer 33 | .mr.developer.cfg 34 | .project 35 | .pydevproject 36 | -------------------------------------------------------------------------------- /mandelbrot_numba.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# A Numba Mandelbrot Example" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This is an example that demonstrates accelerating a Mandelbrot fractal computation using \"CUDA Python\" with Numba.\n", 15 | "\n", 16 | "Let's start with a basic Python Mandelbrot set. We use a numpy array for the image and display it using pylab imshow." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": 1, 22 | "metadata": { 23 | "collapsed": false 24 | }, 25 | "outputs": [], 26 | "source": [ 27 | "import numpy as np\n", 28 | "from pylab import imshow, show\n", 29 | "from timeit import default_timer as timer" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "The `mandel` function performs the Mandelbrot set calculation for a given (x,y) position on the imaginary plane. It returns the number of iterations before the computation \"escapes\"." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": 2, 42 | "metadata": { 43 | "collapsed": false 44 | }, 45 | "outputs": [], 46 | "source": [ 47 | "def mandel(x, y, max_iters):\n", 48 | " \"\"\"\n", 49 | " Given the real and imaginary parts of a complex number,\n", 50 | " determine if it is a candidate for membership in the Mandelbrot\n", 51 | " set given a fixed number of iterations.\n", 52 | " \"\"\"\n", 53 | " c = complex(x, y)\n", 54 | " z = 0.0j\n", 55 | " for i in range(max_iters):\n", 56 | " z = z*z + c\n", 57 | " if (z.real*z.real + z.imag*z.imag) >= 4:\n", 58 | " return i\n", 59 | "\n", 60 | " return max_iters" 61 | ] 62 | }, 63 | { 64 | "cell_type": "markdown", 65 | "metadata": {}, 66 | "source": [ 67 | "`create_fractal` iterates over all the pixels in the image, computing the complex coordinates from the pixel coordinates, and calls the `mandel` function at each pixel. The return value of `mandel` is used to color the pixel." 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": 3, 73 | "metadata": { 74 | "collapsed": false 75 | }, 76 | "outputs": [], 77 | "source": [ 78 | "def create_fractal(min_x, max_x, min_y, max_y, image, iters):\n", 79 | " height = image.shape[0]\n", 80 | " width = image.shape[1]\n", 81 | "\n", 82 | " pixel_size_x = (max_x - min_x) / width\n", 83 | " pixel_size_y = (max_y - min_y) / height\n", 84 | " \n", 85 | " for x in range(width):\n", 86 | " real = min_x + x * pixel_size_x\n", 87 | " for y in range(height):\n", 88 | " imag = min_y + y * pixel_size_y\n", 89 | " color = mandel(real, imag, iters)\n", 90 | " image[y, x] = color" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "Next we create a 1536x1024 pixel image as a numpy array of bytes. We then call `create_fractal` with appropriate coordinates to fit the whole mandelbrot set." 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "execution_count": 5, 103 | "metadata": { 104 | "collapsed": false 105 | }, 106 | "outputs": [ 107 | { 108 | "name": "stdout", 109 | "output_type": "stream", 110 | "text": [ 111 | "Mandelbrot created in 4.967389 s\n" 112 | ] 113 | }, 114 | { 115 | "data": { 116 | "image/png": "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\n", 117 | "text/plain": [ 118 | "" 119 | ] 120 | }, 121 | "metadata": {}, 122 | "output_type": "display_data" 123 | } 124 | ], 125 | "source": [ 126 | "image = np.zeros((1024, 1536), dtype = np.uint8)\n", 127 | "start = timer()\n", 128 | "create_fractal(-2.0, 1.0, -1.0, 1.0, image, 20) \n", 129 | "dt = timer() - start\n", 130 | "\n", 131 | "print \"Mandelbrot created in %f s\" % dt\n", 132 | "imshow(image)\n", 133 | "show()" 134 | ] 135 | }, 136 | { 137 | "cell_type": "markdown", 138 | "metadata": {}, 139 | "source": [ 140 | "You can play with the coordinates to zoom in on different regions in the fractal." 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "execution_count": 6, 146 | "metadata": { 147 | "collapsed": false 148 | }, 149 | "outputs": [ 150 | { 151 | "data": { 152 | "image/png": "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\nXd4c8JxPAZ9q9JhJInLPBiL1eElC7lGi6OWCplzsg8IiB2cnqh6DxiQvWGSyfFvcI2hE7ulHUjDx\n0qo8exh6Sr3MT41w7YZpesbOA9bQSbAkvzxUWdYgDJKqsej6b4zIPd2I1OMlLVKHamkfnJ2wovn8\nChSr/+9Rh04KGY3g40Lknl4kYo+XVkXsjUTOJlo/M7OOkfFzVY+7O1yjRPISxXe54IX0IWKPnzRF\n7QavqHNFRa6wzLUbpn0l731u1JRNt5K+/3wd4sq/S/SeLkTs8ZOmPLsbI2fvUMihwiIAC8XBUJOd\nwki+26P4rvxGidzTg0g9ftIodUMtKZ+ZWcdB+/ZqQB7eb3+Slw8mvZ+EhBC5pweRe/ykWe5e+orV\n0fVCcdCJ5N1RfK2JT/Ui+W6O4rPzaYgBkXs6kHRM/KQhHVNPpLVEbMoVgFU62H1/GCQn70/XCF7k\n3n5E7MnQbrGHIYqAT55fT66wnOgxuoX0fzJiQOTefkTs8ZOGqD1uVk8P8Ojm5500Dayt1xqGIMl3\na5pGvnVCoojYkyFLYq8VWfcVVUV+fTW/wuS+jzi3Tdom6vGk49UiO58SGhsiKdF7+xC5J0OW5B4G\nv+h819YpgIZLB/udVLoxiu+sT4oHkXv7ELnHTyemZAw5H8mbBUBW8ysNlw/udjrz0yK0DelITYas\nij1Kx6eJ1svFPqZLw9w5cYDd7/gux27/k9iO3W1RfDY/NSGQ6L31iNiTIatyb4SR8XO8fdspnrn6\nKfbPT3JwdoItT32UckE3FMV3+8iajvxGitxbj8g9GbpJ7rvf8V3uHv0qW/vO8cj8VUyXhjkzs67d\nzco08q0UmkLEngydIPao0fO+b/8o+wvb+ND2bwAwV6ocVGEmPYUdMuluh3tUTTet+JT6T5HqjTZM\nSqL31iFyT4ZOkHtUjLzLxT6eOHS9c793wpNJ1URN13hPNt2Si++oT5LIvXWI3JOhU+QeJXo3snaP\neX/prSudRbhrPU9G19SmMz5NQsuQUTLJ0Slyj0KQoI+evoyJ/LzvY976NGFF341RfGY+UfUmOUn0\nnjwi9mTohPHtccmyp9RrLdsHVSUL6iGSrybbnyqhZYjckyHrYm8GI2RvRN5T6mWosMgDs9fw0I7P\n+z43qMrkcoM5+k6lI761Er0ni8g9GTpV7mHy7/UE/M2dTwDwzgMfIldYZrWRmjQBRcqyPKrGXHHo\n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\nlRdp3KyaAAAAAElFTkSuQmCC\n", 153 | "text/plain": [ 154 | "" 155 | ] 156 | }, 157 | "metadata": {}, 158 | "output_type": "display_data" 159 | } 160 | ], 161 | "source": [ 162 | "create_fractal(-2.0, -1.7, -0.1, 0.1, image, 20) \n", 163 | "imshow(image)\n", 164 | "show()" 165 | ] 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "## Faster Execution with Numba" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "[Numba](https://github.com/numba/numba) is a Numpy-aware dynamic Python compiler based on the popular LLVM compiler infrastructure. \n", 179 | "\n", 180 | "Numba is an Open Source NumPy-aware optimizing compiler for Python sponsored by Anaconda. It uses the LLVM compiler infrastructure to compile Python syntax to machine code. It is aware of NumPy arrays as typed memory regions and so can speed-up code using NumPy arrays, such as our Mandelbrot functions.\n", 181 | "\n", 182 | "The simplest way to use Numba is to decorate the functions you want to compile with @autojit. Numba will compile them for the CPU (if it can resolve the types used)." 183 | ] 184 | }, 185 | { 186 | "cell_type": "code", 187 | "execution_count": 7, 188 | "metadata": { 189 | "collapsed": false 190 | }, 191 | "outputs": [], 192 | "source": [ 193 | "from numba import jit\n", 194 | "\n", 195 | "@jit\n", 196 | "def mandel(x, y, max_iters):\n", 197 | " \"\"\"\n", 198 | " Given the real and imaginary parts of a complex number,\n", 199 | " determine if it is a candidate for membership in the Mandelbrot\n", 200 | " set given a fixed number of iterations.\n", 201 | " \"\"\"\n", 202 | " c = complex(x, y)\n", 203 | " z = 0.0j\n", 204 | " for i in range(max_iters):\n", 205 | " z = z*z + c\n", 206 | " if (z.real*z.real + z.imag*z.imag) >= 4:\n", 207 | " return i\n", 208 | "\n", 209 | " return max_iters\n", 210 | "\n", 211 | "@jit\n", 212 | "def create_fractal(min_x, max_x, min_y, max_y, image, iters):\n", 213 | " height = image.shape[0]\n", 214 | " width = image.shape[1]\n", 215 | "\n", 216 | " pixel_size_x = (max_x - min_x) / width\n", 217 | " pixel_size_y = (max_y - min_y) / height\n", 218 | " \n", 219 | " for x in range(width):\n", 220 | " real = min_x + x * pixel_size_x\n", 221 | " for y in range(height):\n", 222 | " imag = min_y + y * pixel_size_y\n", 223 | " color = mandel(real, imag, iters)\n", 224 | " image[y, x] = color" 225 | ] 226 | }, 227 | { 228 | "cell_type": "markdown", 229 | "metadata": {}, 230 | "source": [ 231 | "Let's run the `@jit` code and see if it is faster." 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 8, 237 | "metadata": { 238 | "collapsed": false 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "Mandelbrot created in 0.667907 s\n" 246 | ] 247 | }, 248 | { 249 | "data": { 250 | "image/png": "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\n", 251 | "text/plain": [ 252 | "" 253 | ] 254 | }, 255 | "metadata": {}, 256 | "output_type": "display_data" 257 | } 258 | ], 259 | "source": [ 260 | "image = np.zeros((1024, 1536), dtype = np.uint8)\n", 261 | "start = timer()\n", 262 | "create_fractal(-2.0, 1.0, -1.0, 1.0, image, 20) \n", 263 | "dt = timer() - start\n", 264 | "\n", 265 | "print \"Mandelbrot created in %f s\" % dt\n", 266 | "imshow(image)\n", 267 | "show()" 268 | ] 269 | }, 270 | { 271 | "cell_type": "markdown", 272 | "metadata": {}, 273 | "source": [ 274 | "On a server with a Xeon (Haswell) CPU, the time to compute the 1536x1024 mandelbrot set dropped from 4.94s down to 46.6ms. That's a speedup of 106x! The reason this is so much faster is that Numba uses Numpy type information to convert the dynamic Python code into statically compiled machine code, which is many times faster to execute than dynamically typed, interpreted Python code. " 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "## Even Bigger Speedups with CUDA Python" 282 | ] 283 | }, 284 | { 285 | "cell_type": "markdown", 286 | "metadata": {}, 287 | "source": [ 288 | "In addition to various types of automatic vectorization and generalized Numpy Ufuncs, Numba also enables developers to access the CUDA parallel programming model using Python syntax. With CUDA Python, you use parallelism explicitly, just as in other CUDA languages such as CUDA C++ and CUDA Fortran. \n", 289 | "\n", 290 | "Let's write a CUDA version of our Python Mandelbrot set. We need to import `cuda` from the `numba` module. Then, we need to create a version of the mandel function compiled for the GPU. We can do this without any code duplication by calling `cuda.jit` on the function, specifying `device=True` to indicate that this is a function that will run on the GPU *device*." 291 | ] 292 | }, 293 | { 294 | "cell_type": "code", 295 | "execution_count": 9, 296 | "metadata": { 297 | "collapsed": false 298 | }, 299 | "outputs": [], 300 | "source": [ 301 | "from numba import cuda\n", 302 | "from numba import *\n", 303 | "\n", 304 | "mandel_gpu = cuda.jit(device=True)(mandel)" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "metadata": {}, 310 | "source": [ 311 | "In CUDA, a *kernel* is a function that runs in parallel using many threads on the device. We can write a kernel version of our mandelbrot function by simply assuming that it will be run by a *grid* of threads. NumbaPro provides the familiar CUDA `threadIdx`, `blockIdx`, `blockDim` and `gridDim` intrinsics, as well as a `grid()` convenience function which evaluates to `blockDim * blockIdx + threadIdx`.\n", 312 | "\n", 313 | "Our example juse needs a minor modification to compute a grid-size stride for the x and y ranges, since we will have many threads running in parallel. We just add these three lines:\n", 314 | "\n", 315 | " startX, startY = cuda.grid(2)\n", 316 | " gridX = cuda.gridDim.x * cuda.blockDim.x;\n", 317 | " gridY = cuda.gridDim.y * cuda.blockDim.y;\n", 318 | "\n", 319 | "And we modify the range in the `x` loop to use `range(startX, width, gridX)` (and likewise for the `y` loop).\n", 320 | "\n", 321 | "We decorate the function with @cuda.jit. Numba will infer the type signature from the invocation of the function." 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 10, 327 | "metadata": { 328 | "collapsed": false 329 | }, 330 | "outputs": [], 331 | "source": [ 332 | "@cuda.jit\n", 333 | "def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):\n", 334 | " height = image.shape[0]\n", 335 | " width = image.shape[1]\n", 336 | "\n", 337 | " pixel_size_x = (max_x - min_x) / width\n", 338 | " pixel_size_y = (max_y - min_y) / height\n", 339 | "\n", 340 | " startX, startY = cuda.grid(2)\n", 341 | " gridX = cuda.gridDim.x * cuda.blockDim.x;\n", 342 | " gridY = cuda.gridDim.y * cuda.blockDim.y;\n", 343 | "\n", 344 | " for x in range(startX, width, gridX):\n", 345 | " real = min_x + x * pixel_size_x\n", 346 | " for y in range(startY, height, gridY):\n", 347 | " imag = min_y + y * pixel_size_y \n", 348 | " image[y, x] = mandel_gpu(real, imag, iters)" 349 | ] 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "metadata": {}, 354 | "source": [ 355 | "#### Device Memory" 356 | ] 357 | }, 358 | { 359 | "cell_type": "markdown", 360 | "metadata": {}, 361 | "source": [ 362 | "CUDA kernels must operate on data allocated on the device. NumbaPro provides the cuda.to_device() function to copy a Numpy array to the GPU. \n", 363 | "\n", 364 | " d_image = cuda.to_device(image)\n", 365 | "\n", 366 | "The return value (`d_image`) is of type DeviceNDArray, which is a subclass of numpy.ndarray, and provides the `to_host()` function to copy the array back from GPU to CPU memory\n", 367 | "\n", 368 | " d_image.to_host()" 369 | ] 370 | }, 371 | { 372 | "cell_type": "markdown", 373 | "metadata": {}, 374 | "source": [ 375 | "#### Launching Kernels" 376 | ] 377 | }, 378 | { 379 | "cell_type": "markdown", 380 | "metadata": {}, 381 | "source": [ 382 | "To launch a kernel on the GPU, we must configure it, specifying the size of the grid in blocks, and the size of each thread block. For a 2D image calculation like the Mandelbrot set, we use a 2D grid of 2D blocks. We'll use blocks of 32x8 threads, and launch 32x16 of them in a 2D grid so that we have plenty of blocks to occupy all of the multiprocessors on the GPU.\n", 383 | "\n", 384 | "Putting this all together, we launch the kernel like this." 385 | ] 386 | }, 387 | { 388 | "cell_type": "code", 389 | "execution_count": 13, 390 | "metadata": { 391 | "collapsed": false 392 | }, 393 | "outputs": [ 394 | { 395 | "name": "stdout", 396 | "output_type": "stream", 397 | "text": [ 398 | "Mandelbrot created on GPU in 0.002815 s\n" 399 | ] 400 | }, 401 | { 402 | "data": { 403 | "image/png": "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\n", 404 | "text/plain": [ 405 | "" 406 | ] 407 | }, 408 | "metadata": {}, 409 | "output_type": "display_data" 410 | } 411 | ], 412 | "source": [ 413 | "gimage = np.zeros((1024, 1536), dtype = np.uint8)\n", 414 | "blockdim = (32, 8)\n", 415 | "griddim = (32,16)\n", 416 | "\n", 417 | "start = timer()\n", 418 | "d_image = cuda.to_device(gimage)\n", 419 | "mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20) \n", 420 | "d_image.copy_to_host()\n", 421 | "dt = timer() - start\n", 422 | "\n", 423 | "print \"Mandelbrot created on GPU in %f s\" % dt\n", 424 | "\n", 425 | "imshow(d_image)\n", 426 | "show()" 427 | ] 428 | }, 429 | { 430 | "cell_type": "markdown", 431 | "metadata": {}, 432 | "source": [ 433 | "You may need to run this last code block twice to see the best performance, because of the JIT and kernel loading overhead the first time you run it. The second time you run it, you may notice that the image was generated almost instantly. On the NVIDIA Tesla P100 GPU installed in my server, it ran in 2.9 milliseconds, which is an additional 16x speedup over the `@autojit` (compiled CPU) code, or a total of nearly 1700x faster than interpreted Python code.\n", 434 | "\n", 435 | "Productivity *and* Performance!\n", 436 | "\n", 437 | "Numba is free and open source software." 438 | ] 439 | }, 440 | { 441 | "cell_type": "code", 442 | "execution_count": null, 443 | "metadata": { 444 | "collapsed": true 445 | }, 446 | "outputs": [], 447 | "source": [] 448 | } 449 | ], 450 | "metadata": { 451 | "anaconda-cloud": {}, 452 | "kernelspec": { 453 | "display_name": "Python 2", 454 | "language": "python", 455 | "name": "python2" 456 | }, 457 | "language_info": { 458 | "codemirror_mode": { 459 | "name": "ipython", 460 | "version": 2 461 | }, 462 | "file_extension": ".py", 463 | "mimetype": "text/x-python", 464 | "name": "python", 465 | "nbconvert_exporter": "python", 466 | "pygments_lexer": "ipython2", 467 | "version": "2.7.13" 468 | } 469 | }, 470 | "nbformat": 4, 471 | "nbformat_minor": 0 472 | } 473 | --------------------------------------------------------------------------------