GPU state vector backend based on cuQuantum (cuStateVec) - #4
Closed
GrovyleX wants to merge 5 commits into
Closed
Conversation
Add the graphix_statevec_cuquantum package: a Statevec (DenseState) backed by a flat CuPy buffer of size 2**max_space, and a StatevectorBackend. Gates and CZ entanglement use cuStateVec apply_matrix, single-qubit expectation values use compute_expectation, and qubit removal/swap/tensor use CuPy. Graphix MSB indices are converted to cuStateVec LSB index bits. The cuStateVec handle and device gate constants are created lazily so the module imports without a GPU. Replaces the template package.
Add the cuquantum optional dependency (cupy-cuda12x, cuquantum-python-cu12), treat cupy and cuquantum as untyped for mypy, drop the unused console script, and regenerate the lock file.
Compare every operation and full pattern simulation against graphix.sim.statevec. The suite is skipped automatically when no CUDA device is available.
Time end-to-end QFT pattern simulation on the CPU and GPU backends with explicit CPU-GPU synchronization, and update the template micro-benchmarks for the new backend.
Owner
|
Thank you for your contribution and the interest in the project! As you may have noticed, PR #1 already address the same issue. The overall approach of your PR is very similar to theirs, and most differences consist of applying the feedback given in that PR. Could you clarify how your contribution differs from or improves upon the other PR and the discussion therein? |
Author
|
Thanks - yeah, fair, #1 is clearly ahead and has had the deeper review. No need for two near-identical PRs; happy to defer to it. I'll close this. Thanks for looking. Or just leave it open and quiet. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements a GPU-accelerated state vector backend for Graphix pattern simulation, built on NVIDIA cuQuantum (cuStateVec) and CuPy, following the template in this repository. Addresses TeamGraphix/graphix#496 (unitaryHACK 2026).
Design
2**max_space(complex128); only the first2**nqubitentries are meaningful, so the active register can grow (N) and shrink (M) without reallocating GPU memory.flatten()copies the active slice back to the host.custatevec.apply_matrix; single-qubit expectation values usecustatevec.compute_expectation(divided by the squared norm to match the reference backend); qubit removal, swap and tensor use CuPy.add_nodeshas a device-only fast path for the common single-|+>case (anNcommand), andStatevectorBackend.with_capacity(max_qubits)preallocates the buffer for pattern simulation.evolve(multi-qubit, circuit-only) is intentionally left unimplemented, as in the template.Tests
Every operation and full pattern simulation are compared against the reference
graphix.sim.statevecbackend. The suite is skipped automatically when no CUDA device is available (@pytest.mark.skipif(not _gpu_available())), as suggested in the issue. Passesruff,ruff format,mypy(strict),pyright, andpytest(49 tests on an NVIDIA GTX 1650).Benchmark results
End-to-end QFT pattern simulation (with the
min_spacepass), CPU vs GPU, on a GTX 1650 (4 GB). GPU timings use explicitcupy.cuda.Device().synchronize(); each point is the fastest of three runs (benchmarks/compare_cpu_gpu.py).For small patterns the CPU backend wins — each MBQC command is a tiny operation and the GPU's fixed per-call overhead dominates. The crossover is around 14 qubits; beyond it the CPU cost grows steeply (at 16 qubits the CPU backend did not finish a single QFT simulation within 15 minutes), whereas the GPU backend reaches 20 qubits in ~14 s. The value of the GPU backend is therefor reaching pattern sizes that are impractical on the CPU. Timings are noisy and
hardware-dependent; the GTX 1650 is an entry-level card.
AI disclosure (unitaryHACK policy)
I used an LLM (Claude) to help work through the cuStateVec API and to speed up boilerplate. The work is mine: I set up the GPU environment, ran and debugged the backend on my own hardware, reviewed every line against the reference implementation, wrote and ran the tests, and produced the benchmarks. I can explain and defend the whole change.