feat: multi-GPU belief propagation backend - #87
Conversation
Squashed from 27 WIP commits for a clean rebase onto upstream main. --------- Co-authored-by: Matteo AC Rossi <9745862+matteoacrossi@users.noreply.github.com>
c31ec64 to
de7f7b3
Compare
|
Thanks! This is very impressive and useful. As this relies on CUDA.jl which I don't want as a fixed dependency, this will probably need to be written as a package extension (which then only loads if CUDA.jl is loaded), see: https://discourse.julialang.org/t/quick-tutorial-on-package-extensions/130923. In the short term we could have this as a branch off of main which I can then accept as a PR and people can load into easily / use for the time being and I can even have the README point too |
The GitHub merge of main into feat/multigpu left two [extras] and two [targets] tables, which is invalid TOML (key already defined) and broke CI.
Thanks! Makes sense to make it an |
The CUDA/KaHyPar device backend now lives in ext/TensorNetworkQuantumSimulatorCUDAExt.jl and loads only when both CUDA.jl and KaHyPar.jl are present, so neither is a hard dependency of the package. Co-authored-by: Matteo AC Rossi <9745862+matteoacrossi@users.noreply.github.com>
|
Hi @JoeyT1994, the refactoring to extension is done, so this may not need the interim branch Everything CUDA/KaHyPar-specific now lives in a single I validated it with the new tests and the 56-qubit heavy-hex benchmark from the description over BD 50–400 vs single GPU, same errors as before. So the refactor is behaviour-neutral and adds no dependencies for non-GPU users. Would you be happy to retarget this at |
Summary
Adds a
MultiGPUBeliefPropagationCachethat distributes a single BP instance across multiple CUDA devices. The implementation is not an embarrassingly parallel fan-out of independent jobs: all devices jointly maintain one shared BP fixed point and one evolving quantum state. Gate application is unchanged and still runs sequentially; only the BP sweep is parallelised.Algorithm
Partitioning
The tensor network graph$\mathcal{G}=(\mathcal{V},\mathcal{E})$ is partitioned with KaHyPar into $N_\text{dev}$ device-local subsets $\mathcal{V}^{(p)}$ . Two objectives are exposed:
Each device holds in VRAM the tensors${T_v : v\in\mathcal{V}^{(p)}}$ and every directed message incident to $\mathcal{V}^{(p)}$ . Cut edges are recorded as the messages that device must produce and ship.
Distributed sweep
The undirected edges are partitioned into proper color classes so that no two edges in a class share a vertex. One BP iteration then:
Threads.@spawn; no write conflicts because the local environments are vertex-disjoint.Gate application
Gates are applied sequentially on a chosen home device. For a two-site gate spanning a partition boundary, the partner tensor and surrounding environment messages are staged onto the home device, the gate is absorbed, a truncated QR/SVD is performed, the resulting singular-value spectrum is written as the new seed message on the gate edge and broadcast to all devices tracking it. At large bond dimension, where a single QR/SVD can transiently exceed device memory, the factorization falls back transparently to host RAM and the result is moved back to the GPU.
Validation and performance
Validated against the single-GPU reference on a 56-qubit heavy-hex circuit with 10675 gates. In double precision the two implementations reach the same BP fixed point to within$10^{-8}$ in message fidelity; in the single-precision production regime observables agree to $10^{-5}$ – $10^{-4}$ across $\chi=50$ – $500$ , consistent with the BP convergence floor rather than any algorithmic bias.
Strong-scaling speedup (4× A100-64 GB vs. single A100, same circuit):
The single-GPU run exhausts memory at$\chi\approx550$ ; the four-GPU run continues, reaching $\chi=700$ in roughly one hour of wall time. At eight H200 GPUs (140 GB each) the same circuit has been run at $\chi=980$ .
New public interface
The partitioning objective is selected via the
partition_algkeyword ("memory_balanced"or"min_cut").__
CC @fpietra @davidemateria feel free to jump into the discussion, review, and answer questions.