Summary and Schedule
Introduction
This is an advanced course in GPU programming using Python. You will learn about the types of problems that are suitable for parallelisation on the GPU and how to reformulate a problem using data parallelism. We will show you how to use the high-level GPU API provided by CuPy and then how to write your own, highly optimised kernels.
This course can be separated into two days:
Where: The workshop will be held at Swinburne university in the Engineering building.
When: The workshop will run on the 21st-22nd of July, 10am - 4pm each day. Arrive as early as 9am if you need help setting up your computer/environment.
Why use GPU acceleration?
It is increasingly common for science to make use of massive datasets—such as high-resolution sky surveys, complex N-body simulations, or signal processing over terabytes of data. Processing these vast datasets can be computationally prohibitive on standard CPUs. However, it is our good fortune that many of these tasks are trivially parallelisable, meaning that the work can be progressed by many processing cores at once.
GPU acceleration is the next step beyond CPU parallelisation, and allows you to leverage literally thousands of parallel cores to accelerate these tasks. GPUs are built specifically with high multi-threaded workloads in mind, and are efficient at these kinds of tasks in a way that CPUs are simply not. GPU programming is not easy, but with a little care (and experimentation) it is possible to achieve speedups of several orders of magnitude in processing time.
Or, let Mythbusters convince you:
Source: Nvidia on Youtube
Why Python?
This course is taught using Python and a number of libraries that allow writing CUDA kernels directly using Python. Python has been chosen to make this course as accessible as possible, which allows us to focus on the underlying concepts without getting snagged on unfamiliar syntax. Under the hood, the Python kernels are compiled to CUDA kernels and run just as fast as if we had written them in C.
And rest assured: the concepts learned here can be applied wholesale to CUDA programming in C or C++ (or Julia, Rust, …).
| Setup Instructions | Download files required for the lesson | |
| Duration: 00h 00m | 1. An introduction to parallelism |
Why does adding more cores not always make a program faster? What distinguishes data parallelism from task parallelism, and why do GPUs rely on the former? Why does a parallel program sometimes give a different answer each time you run it? |
| Duration: 00h 40m | 2. A GPU Deep Dive |
How is a GPU organised internally, and how does that differ from a
CPU? Why does the GPU have multiple types of memory with very different speeds and sizes? How does a GPU avoid sitting idle while waiting for slow memory operations? |
| Duration: 00h 50m | 3. CuPy: A Numpy-like GPU experience |
If NumPy arrays live in CPU memory, where do CuPy arrays live and what
does that mean for your code? Why does benchmarking GPU code give misleadingly fast results if you aren’t careful? How can you overlap independent computations and data transfers on the GPU? |
| Duration: 01h 00m | 4. Writing your first GPU kernels |
How does a single function body know which piece of data to process when
launched thousands of times? How do you configure a kernel launch so every element of an array is covered, regardless of its size? How can threads safely combine their results into a single value? |
| Duration: 01h 10m | 5. Optimisation |
Why is accessing global memory in a kernel’s hot loop a performance
bottleneck? How can threads within a block cooperate to share the cost of reading data from global memory? When does using lower-precision floating point numbers make your kernel faster? |
| Duration: 01h 20m | Finish |
The actual schedule may vary slightly depending on the topics and exercises chosen by the instructor.
Expected background
This course sets a reasonably high bar for what you are expected to already know, including:
- Python
- Primitive data types: integers, floats, doubles, etc. and their machine representation
- numpy, including broadcasting rules
- Some experience with
numbaand its parallelisation functions
Additionally, the examples given here are aimed towards people coming from a physics, astronomy, or engineering background. It will help if you are familiar with:
- Basic mathematical sum notation, e.g. for discrete Fourier transform
- Complex numbers (and, for example, Euler’s formula)
Setup
It is expected that you will be working on OzStar for this workshop, but if you have a CUDA based GPU you can work on your local machine (not recommended).
To work on ozstar you will need an account,
and you will need to have joined the group oz983.
Making an account and joining the group takes time as there is a human approval process required for each, so please make sure that you do this before attending the workshop.
Connecting to Ozstar
Log into ozstar using ssh via:
This should connect you to either farnarkle1 or
farnarkle2 as these are the login nodes.
See the documentation here for tips on how to setup easy access via ssh.
Installing the environment on HPC
Installing the environment on a HPC like OzStar
will require loading the gcc and CUDA modules
and installing uv.
Installing uv should require no change to the Linux
installation instructions as the bash script that runs should install
uv to your home directory on the login node of the HPC.
Using uv to install the environment on OzStar:
BASH
# Work in your home directory
cd ~
# Load the required software modules
module load gcc/13.3.0 cuda/12.8.0 python/3.12.3
# Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Now make a new directory and environment for us to work in
uv init gpu-tutorial
cd gpu-tutorial
# Note that the following may take up to 1/2 hour to complete (thanks cupy!)
uv add numpy \
numba \
numba-cuda \
cupy \
matplotlib \
pytest
# Activate this new environment
source .venv/bin/activate
# Test that everything is working
python -c 'import numpy, numba, numba.cuda, cupy, pytest, matplotlib'
If you can run all of the above without generating errors then you are ready to go. If you find errors then either email the organisers of the workshop, or be sure to arrive early on the first day to get in-person help.
Imports
We will frequently omit imports from the code snippets listed throughout this tutorial. The following imports should be assumed:
AI Declaration
With the exception of the following, no AI or LLM tools were used to prepare these notes in any capacity (including planning, writing, or otherwise):
- The shared memory optimisation animation (using Gemini 3).
- Final proof and code checking (using Qwen 3.6)
