PantheonSim / GitHub Actions
CUDA tests in GitHub Actions, without a GPU
GitHub’s hosted runners have no GPU, so CUDA code usually goes untested until someone has a card free. The PantheonSim action gives a job simulated NVIDIA GPUs: CUDA code compiles, and its tests run, on every push and pull request.
Add it to a workflow
One step, after checkout. Everything after it in the job sees the GPUs you asked for.
# .github/workflows/cuda.yml name: CUDA tests on: [push, pull_request] jobs: cuda-tests: runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: pantheongpu/pantheonsim@main with: gpu: nvidia/h100 count: 2 - run: | nvidia-smi -L nvcc -arch=compute_90 my_test.cu -o my_test vgpu run ./my_test
What it does
- Installs CMake, Ninja and a C++ compiler and, unless
cuda-toolkit: none, Ubuntu’s CUDA toolkit (CUDA 12.0 onubuntu-24.04) with the GCC 12 its nvcc needs. - Builds the simulator at the ref the job named, and caches the build against a hash of its source and the toolkit version, so later runs skip it.
- Puts the simulator’s tools first on
PATHand setsVGPU_GPU,VGPU_DEVICE_COUNTandVGPU_SHIM_DIRfor the rest of the job (and, with the apt toolkit,NVCC_PREPEND_FLAGS=-ccbin g++-12).
After it, nvidia-smi reports the GPUs you asked for, nvcc is the real compiler
with -cudart shared added (so unmodified build systems link the runtime the simulator stands
in for), and vgpu run ./program runs a program on the simulated GPUs.
Inputs
| Input | Default | Meaning |
|---|---|---|
gpu | nvidia/t4 | The profile to simulate. vgpu list-gpus lists them; see the GPU table. |
count | 1 | How many GPUs. |
cuda-toolkit | apt | apt installs Ubuntu’s toolkit; none uses one the job already installed. |
Outputs
| Output | Meaning |
|---|---|
build-dir | Where the simulator was built. |
shim-dir | Its CUDA libraries, for LD_LIBRARY_PATH when not using vgpu run. |
Testing on every GPU
A result that depends on the card is the bug CI on one GPU never finds. vgpu test --matrix
runs the same binary on every measured profile and compares the outputs. Build it for the oldest
architecture you support:
- run: |
nvcc -arch=compute_75 vectoradd.cu -o vectoradd
vgpu test --matrix ./vectoradd | tee matrix.txt
grep -q ' 0 different' matrix.txt
Things to know
- Build kernels for an architecture the profile supports:
-arch=compute_75runs on a T4 and every newer card,compute_90needs Hopper. - Check CUDA return codes in your tests. A refused kernel or an unsupported call returns its CUDA error and prints why, but the program carries on, so a test that ignores the code can still exit 0.
- The simulator’s CUDA libraries are built against the job’s toolkit, so their version always
matches the
nvccthat compiled the program. - It checks behaviour, not performance: timings mean nothing here. Keep a run on physical GPUs before a release.
- Linux runners only. The first run builds the simulator; later runs restore it from the cache.
Want to try it before wiring up a workflow? The playground gives you the same tools in a browser terminal.