Skip to content
Home/Blog/Multi-GPU Quantum Simulation with CUDA-Q: A Practical Guide
SimulatorsPerformanceGPU

Multi-GPU Quantum Simulation with CUDA-Q: A Practical Guide

How CUDA-Q splits a state vector across multiple GPUs to simulate more qubits than one GPU's memory allows, and the real distinction between multi-GPU state simulation and NVIDIA's separate multi-QPU (mqpu) execution platform.

FreeQuantumComputing
·· 8 min read

The code in this guide reflects NVIDIA's documented CUDA-Q API pattern, checked against NVIDIA's own developer documentation. Unlike the Qiskit tutorials elsewhere on this site, it wasn't executed here: CUDA-Q ships Linux-only wheels and needs real NVIDIA GPU hardware, neither of which this environment has. Verify exact target names and flags against NVIDIA's current docs before relying on them.

Why one GPU runs out of room

A full state-vector simulation stores one complex amplitude per basis state, and the basis state count doubles with every added qubit. At single precision, a 30-qubit state vector needs roughly 8 GB. Add three more qubits and it's 64 GB, past what a single consumer or even most datacenter GPUs hold. This is the same wall covered in our free simulators comparison: a laptop CPU tops out around 30 qubits, and a single GPU pushes that further but still hits a hard memory ceiling.

The fix: split the state vector, not the circuit

CUDA-Q's multi-GPU target distributes the state vector itself across multiple GPUs, each holding a slice of the total amplitude array. A single-qubit gate that only touches amplitudes within one GPU's slice runs locally. A gate acting on a qubit whose index crosses the partition boundary needs data from another GPU's slice, which is where NVLink or NVSwitch interconnect bandwidth between GPUs becomes the practical bottleneck rather than any single GPU's compute throughput.

This is a fundamentally different kind of parallelism than running many independent circuits at once. CUDA-Q also ships a separate mqpu (multi-QPU) platform for that case: distributing a batch of independent circuit executions, a parameter sweep for a variational algorithm, for instance, across multiple simulated or real QPUs in parallel. Multi-GPU state splitting makes one larger circuit simulable. Multi-QPU distribution makes many independent circuits run faster together. Mixing these two up is an easy way to misread a CUDA-Q benchmark.

What the code pattern looks like

CUDA-Q's design keeps the kernel itself untouched when the target changes, only the execution backend selection differs:

import cudaq

@cudaq.kernel
def ghz_state(n: int):
    qubits = cudaq.qvector(n)
    h(qubits[0])
    for i in range(n - 1):
        x.ctrl(qubits[i], qubits[i + 1])
    mz(qubits)

# Single GPU
cudaq.set_target("nvidia")
result_single = cudaq.sample(ghz_state, 30, shots_count=1000)

# Multi-GPU, state vector split across all visible GPUs
cudaq.set_target("nvidia", option="mgpu")
result_multi = cudaq.sample(ghz_state, 34, shots_count=1000)

The ghz_state kernel is identical in both cases. Only the target line changes, which is the actual value proposition: the same program that runs on a laptop CPU target during development runs unmodified on a multi-GPU cluster once the circuit outgrows single-GPU memory, without a rewrite.

What needs verification before you trust a claim here

Because this guide wasn't run against real hardware, treat every specific number in NVIDIA's own multi-GPU documentation (scaling efficiency, maximum qubit counts at a given GPU count, interconnect bandwidth requirements) as a vendor claim to check rather than a fact to repeat, the same standard this site applies to any hardware vendor's own benchmark. What's verifiable without a cluster: that the kernel code above is syntactically valid CUDA-Q, and that the nvidia and mgpu targets are real, documented options rather than something invented for this guide. Beyond that, run it on real multi-GPU hardware, or read NVIDIA's own published multi-GPU benchmarks, before citing a specific scaling number.

Multi-GPU state simulation and NVQLink solve two different problems that happen to share the same underlying GPU infrastructure. Multi-GPU simulation is about classically simulating a bigger circuit than one GPU holds. NVQLink is about connecting that same GPU infrastructure to a real QPU's control electronics fast enough to do real-time error correction decoding. Read together, they describe NVIDIA's strategy: own the classical compute layer on both sides of the quantum-classical boundary, regardless of whether the workload is simulating a circuit or decoding one from real hardware.

Try this next

  • If you have access to a multi-GPU machine, install CUDA-Q following NVIDIA's own Linux installation guide and reproduce the target-switching pattern above on a circuit sized to outgrow one GPU's memory.
  • Compare the CUDA-Q multi-GPU approach against PennyLane's lightning.gpu device and Qiskit Aer's GPU backend, both covered in our simulator comparison, to see how three different SDKs handle the same underlying memory-scaling problem.
  • Read NVIDIA's own CUDA-Q documentation directly for the current target names and flags, which change between releases faster than a static guide tracks.