PantheonSim / PyTorch on a simulated GPU

Run PyTorch on a simulated GPU, with no GPU

PantheonSim, the GPU simulator for CUDA and ROCm, runs PyTorch's official CUDA 13 build unmodified on a simulated NVIDIA GPU, so torch.cuda.is_available() is True on a machine that has no GPU. This guide shows the two commands that matter, what has been checked, what is not supported, and why you should treat it as a way to test code, not to train anything large.

Run it

You need PantheonSim built from its source (see how to run CUDA without a GPU), in a build that carries CUDA 13 libraries, and PyTorch's CUDA 13 wheel. Then:

pip install torch --index-url https://download.pytorch.org/whl/cu130
build/vgpu run --gpu nvidia/h100 --preload python train.py

The --gpu value picks the card, and --count gives you several. Here is a small script to try first. It runs the same computation on the simulated GPU and on the CPU and compares them:

import torch

print(torch.cuda.is_available(), torch.cuda.get_device_name(0))

torch.manual_seed(0)
x = torch.randn(64, 128)
w = torch.randn(128, 10)

def step(device):
    xd, wd = x.to(device), w.to(device).requires_grad_()
    loss = (xd @ wd).relu().sum()
    loss.backward()
    return loss.item(), wd.grad.cpu()

gpu_loss, gpu_grad = step("cuda")
cpu_loss, cpu_grad = step("cpu")
print("match" if torch.allclose(gpu_grad, cpu_grad, atol=1e-4) else "MISMATCH", gpu_loss, cpu_loss)

Why --preload

PyTorch finds NVIDIA's libraries through an RPATH into its own nvidia-* packages, and the python program itself names no CUDA library, so the simulator's usual way of getting in front of the real libraries does not apply. --preload loads every CUDA library the simulator carries first, and a library already loaded under a name is the one every later request for that name gets. Without it, NVIDIA's real runtime loads, finds no NVIDIA driver, and PyTorch reports that its integrity checks failed (error 103).

What has been checked

The repository's PyTorch test file, models.py, holds twelve whole-model checks, each compared against the CPU. They all pass on the simulated T4, A100, L4, RTX 3060, H100, B200 and RTX 5090. They cover:

Underneath, PyTorch's own kernels run as the machine code (SASS) its wheel carries for the simulated card's architecture, as on a real driver. Convolutions, batch norm, RNNs and scaled-dot-product attention go through the simulator's cuDNN, and linear layers through its cuBLAS and cuBLASLt. CUDA graphs capture and replay, and torch.compile works because Triton does: its generated kernels pass through the simulator's stand-in for ptxas. torch.distributed runs across processes, each with its own simulated GPU, over the simulator's NCCL, and a small network trained with DistributedDataParallel, tensor parallelism, pipeline parallelism and FullyShardedDataParallel ends where one process on the whole batch ends.

PyTorch built for ROCm also runs on the simulated AMD GPUs. The ROCm page has the AMD side, including the gfx target rule.

What this is good for

Limits

Questions

Can PyTorch run without a GPU, with torch.cuda.is_available() True?

Yes, on a simulated GPU. Run vgpu run --gpu nvidia/h100 --preload python your_script.py with PyTorch's CUDA 13 build installed. It is for testing behaviour, not for training at speed.

Why does PyTorch say its integrity checks failed?

PyTorch loaded NVIDIA's real CUDA runtime, which found no NVIDIA driver. Add --preload to vgpu run so the simulator's libraries load first.

Next steps

See why torch.cuda.is_available() is False on a real machine, run these tests in CI, browse the GPU index, or read the PyTorch notes in the repository, which are the source for this page.