diff --git a/mandelbrot_numba_fixed.ipynb b/mandelbrot_numba_fixed.ipynb new file mode 100644 index 0000000..4d9c018 --- /dev/null +++ b/mandelbrot_numba_fixed.ipynb @@ -0,0 +1,116 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# A Numba Mandelbrot Example (Fixed for Modern Python/Numba)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "from numba import cuda\n", + "from matplotlib.pyplot import imshow, show\n", + "from timeit import default_timer as timer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@cuda.jit(device=True)\n", + "def mandel(x, y, max_iters):\n", + " \"\"\"Device function that calculates if a point belongs to Mandelbrot set\"\"\"\n", + " c = complex(x, y)\n", + " z = 0.0j\n", + " for i in range(max_iters):\n", + " z = z*z + c\n", + " if (z.real*z.real + z.imag*z.imag) >= 4:\n", + " return i\n", + " return max_iters" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "@cuda.jit\n", + "def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):\n", + " \"\"\"CUDA kernel for Mandelbrot set calculation\"\"\"\n", + " height = image.shape[0]\n", + " width = image.shape[1]\n", + " \n", + " pixel_size_x = (max_x - min_x) / width\n", + " pixel_size_y = (max_y - min_y) / height\n", + " \n", + " # Get the 2D thread position within the grid\n", + " x, y = cuda.grid(2)\n", + " \n", + " # Make sure we stay within bounds\n", + " if x < width and y < height:\n", + " real = min_x + x * pixel_size_x\n", + " imag = min_y + y * pixel_size_y\n", + " image[y, x] = mandel(real, imag, iters)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Create a GPU array\n", + "gimage = np.zeros((1024, 1536), dtype=np.uint8)\n", + "\n", + "# Configure the blocks and grid\n", + "threadsperblock = (16, 16)\n", + "blockspergrid_x = (gimage.shape[1] + threadsperblock[0] - 1) // threadsperblock[0]\n", + "blockspergrid_y = (gimage.shape[0] + threadsperblock[1] - 1) // threadsperblock[1]\n", + "blockspergrid = (blockspergrid_x, blockspergrid_y)\n", + "\n", + "# Start the computation\n", + "start = timer()\n", + "d_image = cuda.to_device(gimage)\n", + "mandel_kernel[blockspergrid, threadsperblock](-2.0, 1.0, -1.0, 1.0, d_image, 20)\n", + "result_image = d_image.copy_to_host()\n", + "dt = timer() - start\n", + "\n", + "print(f\"Mandelbrot created on GPU in {dt:.6f} s\")\n", + "\n", + "# Display the result\n", + "imshow(result_image)\n", + "show()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.0" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file