Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 116 additions & 0 deletions mandelbrot_numba_fixed.ipynb
Original file line number Diff line number Diff line change
@@ -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
}