Open source GPU simulator

Run CUDA and ROCm on a rack of GPUs you don’t have.

PantheonSim, the GPU simulator for CUDA and ROCm, simulates NVIDIA and AMD GPUs on an ordinary CPU: the CUDA driver, runtime and libraries, the HIP runtime, and the tools that read them, from nvidia-smi to rocm-smi. Unmodified programs compile, run, and fail exactly where they would on a card.

  • No GPU, no sign-up
  • CUDA 12 and 13, ROCm 6 and 7
  • 16 NVIDIA and 5 AMD GPU profiles
  • Apache-2.0
8 × H100, on a CPU
(vgpu 8xNVIDIA H100 80GB HBM3) ~$ nvidia-smi
+-----------------------------------------------------------------------------------------+
| NVIDIA-SMI 580.126.20             Driver Version: 580.126.20     CUDA Version: 13.0     |
+-----------------------------------------+------------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id          Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |           Memory-Usage | GPU-Util  Compute M. |
|                                         |                        |               MIG M. |
|=========================================+========================+======================|
|   0  NVIDIA H100 80GB HBM3          On  |   00000000:01:00.0 Off |                  N/A |
|  0%   32C    P8             56W /  700W |       0MiB /  81559MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
|   ...                                                                                   |
+-----------------------------------------+------------------------+----------------------+
|   7  NVIDIA H100 80GB HBM3          On  |   00000000:08:00.0 Off |                  N/A |
|  0%   32C    P8             56W /  700W |       0MiB /  81559MiB |      0%      Default |
|                                         |                        |                  N/A |
+-----------------------------------------+------------------------+----------------------+
~$ nvidia-smi --query-gpu=index,name,memory.total --format=csv
index, name, memory.total [MiB]
0, NVIDIA H100 80GB HBM3, 81559 MiB
1, NVIDIA H100 80GB HBM3, 81559 MiB
2, NVIDIA H100 80GB HBM3, 81559 MiB
3, NVIDIA H100 80GB HBM3, 81559 MiB
4, NVIDIA H100 80GB HBM3, 81559 MiB
5, NVIDIA H100 80GB HBM3, 81559 MiB
6, NVIDIA H100 80GB HBM3, 81559 MiB
7, NVIDIA H100 80GB HBM3, 81559 MiB
Real output from a simulated machine. There is no GPU in it.

Runs against it

  • nvcc
  • cuBLAS
  • cuDNN
  • NCCL
  • cuFFT
  • cuSPARSE
  • NVRTC
  • Numba
  • Triton
  • nvidia-smi
  • pynvml
  • nvitop
  • hipcc
  • rocm-smi
  • amd-smi
  • rocprofv3

How it works

Your program doesn’t know the difference

Build with the real CUDA or ROCm toolkit and run the binary unchanged. The simulator answers every call it makes, under the same library names a GPU driver installs.

  1. Build it as you always do

    The real nvcc or hipcc, your own build system. Link the CUDA runtime shared.

    nvcc -cudart shared app.cu -o app
    hipcc --offload-arch=gfx942 app.hip -o app
  2. Pick the machine

    Any card, up to sixteen of them. nvidia-smi, NVML and rocm-smi agree.

    vgpu run --gpu nvidia/h100 ./app
    vgpu run --gpu amd/mi300x ./app
  3. See what hardware hides

    For CUDA programs: races named to the line, exact counters, and the same binary on every profile at once.

    vgpu test --matrix ./app

Coverage

The whole stack a GPU program touches

Not a mock of a few calls: the driver API, the CUDA and HIP runtimes, the CUDA libraries checked against NVIDIA’s own on a physical GPU, and the tools that read them all.

Unmodified CUDA and ROCm programs

Binaries built with CUDA 12 or 13, or by hipcc from ROCm 6 or 7, run as they are, their kernels interpreted on the CPU.

The libraries programs link

cuBLAS, cuBLASLt, cuDNN, cuFFT, cuRAND, cuSPARSE, cuSOLVER, NCCL, NVRTC, NPP and nvJPEG. The ROCm libraries, rocBLAS among them, run in the repository’s current source.

The tools people run

nvidia-smi, NVML, pynvml, gpustat and nvitop on NVIDIA; rocm-smi, amd-smi and rocprofv3 on AMD. Numba and Triton kernels run too.

Cards measured, not guessed

Seventeen GPU profiles were read off physical cards and checked against them. The rest say they are not.

Debugging

What a real GPU won’t tell you

A simulator sees every lane of every warp. These come straight from it, and run on CUDA programs today; on AMD, out-of-bounds and use-after-free accesses are caught, and the rest is still to come.

Find the race

Two warps wrote the same word with no barrier. Hardware usually hides it; this names the kernel, the PTX line and the instruction.

$ VGPU_SASS=0 VGPU_SCHEDULER=adversarial vgpu run --race ./race
[vgpu] cudaLaunchKernel: VirtualGPU error [data-race]: read-write race on shared memory at byte offset 0: warp 2 and warp 0 both reach it with no bar.sync between them, so which one wins is not something the program decided. Hardware usually hides this because warps advance together; it is a real race either way
  in kernel '_Z5tallyPi', PTX line 38
  instruction: st.shared.u32[_ZZ5tallyPiE5local], %r4
  GPU profile: nvidia/h100

Run on every card at once

The same binary on each profile, outputs compared. A result that depends on the card shows up here, not in production.

$ vgpu test --matrix ./vectoradd
profile                    exit  output
nvidia/a10                    0  baseline
nvidia/a100                   0  identical
nvidia/h100                   0  identical
nvidia/rtx3060                0  identical
nvidia/a100-sxm4-40gb         0  identical
...
14 profiles: 13 identical to nvidia/a10, 0 different

Count, don’t sample

Exact instruction, memory and sector counts for every launch. They do not move between runs.

$ VGPU_COUNTERS=1 vgpu run ./vectoradd
[vgpu][counters] _Z3addPfPKfS1_i  grid=4x1x1 block=256x1x1
    blocks=4 warps=32
    inst_executed=704  thread_inst_executed=22528  lanes_active_avg=32.00/32
    divergent_branches=0  barriers=0  atomics=0 (0 B)
    global  ld=2048 st=1024  read=8192 B write=4096 B
    shared  ld=0 st=0  read=0 B write=0 B
    local   ld=0 st=0  read=0 B write=0 B
    sectors global=384 over 96 requests (4.00 per request, 100% of ideal)
    shared  bank_conflicts=0 over 0 requests
    mix     fp16=0 fp32=1024 fp64=0 int=5120 cvt=3072
            ctrl=2048 mem=7168 tensor=0 misc=4096  (tensor issues=0)
    ...

AMD

HIP programs on an Instinct you don’t have

The same idea for ROCm. Build with the real hipcc, and the simulator is the ROCm the program finds: its HIP runtime, its GPUs and the tools that read them.

  • Built by hipcc, run unmodified. Programs for ROCm 6 or 7 load their CDNA kernels, and 64-lane wavefronts run them on the CPU.
  • MI300X, MI325X, MI350X, RX 6800 and RX 6700 XT. rocm-smi, amd-smi and rocm_agent_enumerator report the machine, and rocprofv3 profiles it unmodified.
  • Newer than the NVIDIA side. What isn’t implemented yet is refused by name. Try one in the playground with ROCm 7.1 and hipcc, or run it under vgpu run on a machine with ROCm installed.
Run a ROCm program
$ vgpu shell -y --gpu amd/mi300x --count 8 --rocm 7.1.0
$ rocm-smi
========================= ROCm System Management Interface =========================
=================================== Concise Info ===================================
GPU  Temp   AvgPwr  SCLK     MCLK     Fan   Perf  PwrCap  VRAM%  GPU%
0    32c    60W     350Mhz   1300Mhz  0%    auto  750W    0      0
1    32c    60W     350Mhz   1300Mhz  0%    auto  750W    0      0
...
7    32c    60W     350Mhz   1300Mhz  0%    auto  750W    0      0
====================================================================================
$ hipcc --offload-arch=gfx942 vectoradd.hip -o vectoradd
$ ./vectoradd
AMD Instinct MI300X (gfx942), 304 CUs, wavefront 64
ok: c[7] = 21

Continuous integration

CUDA and HIP tests on every pull request, no GPU runners

Hosted runners have no GPU, so GPU code usually goes untested until someone has a card free. One step gives the job simulated ones, NVIDIA or AMD.

  • Works on standard runners. ubuntu-24.04, nothing to provision.
  • Cached build. The simulator builds once and is restored on later runs.
  • Real tools. nvcc or ROCm’s hipcc, nvidia-smi or rocm-smi, and vgpu are on the path.
Set it up
jobs:
  cuda-tests:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v4
      - uses: pantheongpu/pantheonsim@main
        with:
          gpu: nvidia/h100
          count: 2
      - run: |
          nvcc -arch=compute_90 test.cu -o test
          vgpu run ./test

Playground

Try it without installing anything

Pick up to eight cards and an operating system and you get a Linux machine in the browser.

  • A real toolchain. nvcc for CUDA 12.6 or 13.0, Numba, Ollama, git and CMake.
  • An editor and a terminal. Compile a kernel, run it, point the race detector at it.
  • Up to an hour per session. Ten idle minutes end it. The network reaches GitHub, GitLab, PyPI, PyTorch, NVIDIA, Hugging Face and Ollama.
Open the playground
The PantheonSim playground: a CUDA editor beside a terminal that has just compiled and run a kernel on a simulated H100

GPUs

Twenty-one cards, NVIDIA and AMD

The cards the playground offers. “Measured” means a profile’s values were read off a physical card and diffed against it. The simulator’s source carries more profiles: see the GPU index.

NVIDIA, Turing to Blackwell

CardArchitectureMemoryComputeProfile
NVIDIA H100 SXM5 80GBHopper80 GB9.0measured
NVIDIA H100 PCIe 80GBHopper80 GB9.0measured
NVIDIA A100 80GBAmpere80 GB8.0measured
NVIDIA A100 SXM4 40GBAmpere40 GB8.0measured
NVIDIA A10Ampere24 GB8.6measured
NVIDIA A10GAmpere24 GB8.6measured
NVIDIA L4Ada Lovelace24 GB8.9measured
NVIDIA L40SAda Lovelace48 GB8.9measured
NVIDIA Tesla T4Turing16 GB7.5measured
NVIDIA RTX 3060Ampere12 GB8.6measured
NVIDIA RTX 3080 TiAmpere12 GB8.6measured
NVIDIA GH200 480GBHopper/Grace96 GB9.0measured
NVIDIA RTX PRO 6000 Blackwell ServerBlackwell96 GB12.0measured
NVIDIA RTX PRO 4500 Blackwell ServerBlackwell32 GB12.0measured
NVIDIA H200Hopper141 GB9.0not yet measured
NVIDIA B200Blackwell192 GB10.0not yet measured

AMD Instinct and Radeon

CardArchitectureMemoryTargetProfile
AMD Instinct MI300XCDNA 3192 GBgfx942not yet measured
AMD Instinct MI325XCDNA 3256 GBgfx942measured
AMD Instinct MI350XCDNA 4288 GBgfx950not yet measured
AMD Radeon RX 6800RDNA 216 GBgfx1030measured
AMD Radeon RX 6700 XTRDNA 212 GBgfx1031measured

Tenstorrent, on Tenstorrent’s own simulator

Blackhole and Wormhole machines with tt-metal installed. They run on ttsim, Tenstorrent’s open source simulator, not on PantheonSim’s: a functional simulation with no performance data. See the Tenstorrent guide.

MachineArchitectureChipsSimulator
Tenstorrent BlackholeBlackhole1ttsim, functional only
Tenstorrent Blackhole, two chipsBlackhole2ttsim, functional only
Tenstorrent WormholeWormhole1ttsim, functional only
Tenstorrent Wormhole, two chipsWormhole2ttsim, functional only

AWS Trainium and Inferentia, on AWS’s own simulator

Trainium and Inferentia machines with AWS’s NKI package installed. They run nki.simulate, AWS’s CPU simulator for NKI kernels, not PantheonSim’s: a functional simulation with no performance data. See the AWS Trainium and Inferentia guide.

MachineArchitectureTargetSimulator
AWS Trainium (trn1)NeuronCore gen2trn1nki.simulate, functional only
AWS Inferentia2 (inf2)NeuronCore gen2inf2nki.simulate, functional only
AWS Trainium2 (trn2)NeuronCore gen3trn2nki.simulate, functional only
AWS Trainium3 (trn3)NeuronCore gen4trn3nki.simulate, functional only

Guides

Run, test and debug GPU code without a GPU

Step-by-step pages for the things people search for, each with commands you can copy and the limits stated plainly.

Run CUDA without a GPU

Build with nvcc -cudart shared, run with vgpu run, and what to expect.

Run ROCm and HIP without an AMD GPU

The gfx target rule, and the HSA_OVERRIDE_GFX_VERSION note for gfx1031.

A simulated nvidia-smi

Test monitoring tools and scripts against nvidia-smi, rocm-smi and amd-smi.

No CUDA-capable device

Why CUDA or torch.cuda.is_available() finds no GPU, and how to fix it.

PyTorch on a simulated GPU

Run PyTorch’s CUDA 13 build on a machine with no GPU.

Ollama on a simulated GPU

A model on a simulated GPU in the playground, with Ollama preinstalled.

Tenstorrent simulator

Blackhole and Wormhole machines on Tenstorrent’s own ttsim in the playground. Functional only.

AWS Trainium and Inferentia simulator

Trainium and Inferentia machines on AWS’s own NKI simulator in the playground. Functional only.

Compared with other tools

GPGPU-Sim, Accel-Sim, Mokka, compute-sanitizer and ZLUDA: what each is for.

Every simulated GPU

Names, memory, targets and measured status for each profile.

Questions

Honest about what it is

Run it on every commit; keep a run on physical GPUs before a release.

Can I run CUDA code without an NVIDIA GPU?

Yes. PantheonSim implements the CUDA driver API, the runtime and the common CUDA libraries on the CPU, so a program built with the real nvcc runs unmodified under vgpu run. It checks what a program does, not how fast it does it.

Can I run ROCm code without an AMD GPU?

Yes. A HIP program built by ROCm’s hipcc for an Instinct MI300X, MI325X or MI350X runs unmodified under vgpu run: the simulator is its libamdhip64, for ROCm 6 or 7, and runs its CDNA kernels on the CPU. rocm-smi, amd-smi and rocprofv3 report the simulated machine. The AMD side is newer than the NVIDIA one: the ROCm math libraries such as rocBLAS run on the simulator in the repository’s current source, and what is not implemented is refused by name. The playground offers all five AMD cards with ROCm 7.1 and hipcc.

Does it predict GPU performance?

No. There is no timing, cache or thermal model, so timings mean nothing. What it gives instead is exact: instruction, memory and sector counts that do not change between runs.

Do PyTorch and CuPy work?

PyTorch’s official CUDA 13 build runs on the simulated NVIDIA GPUs when the simulator is built from its current source and started with vgpu run --preload, but the playground does not support it yet. CuPy does not work, because it links the CUDA runtime statically. Numba runs unmodified, and so does Triton under vgpu run.

Can I run CUDA tests in CI without GPU runners?

Yes. PantheonSim is also a GitHub Action: one step gives a job simulated NVIDIA or AMD GPUs on a standard hosted runner, so CUDA and HIP code can be compiled and tested on every pull request. Keep a run on physical GPUs before a release. How to set it up.

Which GPUs can it simulate?

The playground offers sixteen NVIDIA cards from Turing to Blackwell, including the T4, A10, A100, L4, L40S, H100, GH200, H200 and B200, three AMD Instinct cards (the MI300X, MI325X and MI350X) and two Radeon RDNA 2 cards (the RX 6800 and RX 6700 XT). Seventeen were measured on physical cards; the rest are marked as not yet measured. The simulator’s source carries more profiles, listed on the GPU index.

What happens when a program uses something that is not implemented?

On NVIDIA, the call returns the documented CUDA error and the simulator prints where: the instruction, the PTX line, the kernel and the GPU profile. On AMD, the unimplemented instruction or call is refused by name. A gap is never silent, but the program carries on, so check return codes.

Is PantheonSim affiliated with NVIDIA or AMD?

No. It is an independent project, open source under Apache-2.0, built from documented public interfaces. It contains no NVIDIA code.

A GPU machine in a minute.

Open one in the browser, or build it on any Linux machine with CMake and a C++20 compiler. No GPU needed; the CUDA libraries build when a CUDA toolkit is installed, and ROCm programs compile with ROCm’s own hipcc.

$ git clone https://github.com/pantheongpu/pantheonsim
$ cd pantheonsim && ./scripts/build.sh
$ ./build/vgpu shell --gpu nvidia/h100 --count 8 --cuda 13.0 --driver 580.126.20
$ ./build/vgpu shell --gpu amd/mi300x --count 8 --rocm 7.1.0