Skip to content

Clifford circuits, graph states, and other quantum Stabilizer formalism tools.

License

Notifications You must be signed in to change notification settings

liangcg/QuantumClifford.jl

 
 

Repository files navigation

QuantumClifford.jl

Documentation of latest stable version Documentation of dev version GitHub Workflow Status Test coverage from codecov

A Julia package for working with quantum stabilizer states and Clifford circuits that act on them. Graphs states are also supported. The package is already very fast for the majority of common operations, but there are still many low-hanging fruits performance-wise. See the detailed suggested readings & references page for background on the various algorithms.

To install it use:

] add QuantumClifford

Works efficiently with pure and mixed stabilizer states of thousands of qubits as well as sparse or dense Clifford operations acting upon them.

Provides canonicalization, projection, and generation operations, as well as partial traces.

julia> P"X" * P"Z"
-iY

julia> P"X" ⊗ P"Z"
+ XZ

julia> S"-XX
         +ZZ"
- XX
+ ZZ

julia> CNOT * S"-XX
                +ZZ"
- X_
+ _Z

The code is vectorized and multithreaded.

Quick Benchmarks

Fast, in-place, allocation free implementations.

Comparison against other Clifford simulators

The only other simulator of similar performance I know of is Stim. In particular, Stim implements convenient tracking of Pauli frames, that makes simulating the performance of error correcting codes blazingly fast (which are possible in QuantumClifford.jl, but no convenient interface is provided for that yet).

The "low level" functionality is of similar performance in Stim and QuantumClifford but different tradeoffs are made at the higher levels: to multiply in-place 1M-qubit Pauli operators Stim needs 16us while QuantumClifford.jl needs 20us.

Of note is that Stim achieved this performance through high-quality C++ SIMD code of significant sophistication, while QuantumClifford.jl is implemented in pure Julia.

Multiplying two 1 gigaqubit Paulis in 32 ms

julia> a = random_pauli(1_000_000_000);
julia> b = random_pauli(1_000_000_000);
julia> @benchmark QuantumClifford.mul_left!(a,b)
BenchmarkTools.Trial: 155 samples with 1 evaluation.
 Range (min … max):  32.074 ms … 32.425 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     32.246 ms              ┊ GC (median):    0.00%
 Time  (mean ± σ):   32.247 ms ± 63.427 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

                  ▃  ▃▃ ▄ ▆▄▄▄██▃ ▃▄▁▆█▃▃ ▃      ▁             
  ▄▁▁▄▁▁▄▆▁▁▄▆▄▆▇▇█▄▄██▄█▆███████▇███████▆█▆▄▄▄▁▄█▁▄▄▁▄▁▁▁▁▁▄ ▄
  32.1 ms         Histogram: frequency by time        32.4 ms <

 Memory estimate: 0 bytes, allocs estimate: 0.

Canonicalization of a random 1000-qubit stabilizer in 22 ms

julia> @benchmark canonicalize!(s) setup=(s=random_stabilizer(1000))
BenchmarkTools.Trial: 226 samples with 1 evaluation.
 Range (min … max):  21.938 ms …  22.680 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     22.025 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   22.057 ms ± 115.247 μs  ┊ GC (mean ± σ):  0.00% ± 0.00%

    ▂▂ █▃▃▂                                                     
  ▄▇███████▆▇▆█▆▄▄▄▄▄▅▄▃▃▁▄▃▃▃▃▃▃▁▁▁▁▁▃▁▁▁▁▁▃▁▃▁▁▁▁▃▁▁▁▁▁▁▁▁▃▃ ▃
  21.9 ms         Histogram: frequency by time         22.6 ms <

 Memory estimate: 32 bytes, allocs estimate: 1.

Gate application (500 CNOT gates on 1000 qubits) in 7 ms

julia> @benchmark apply!(s, gate) setup=(s=random_stabilizer(1000); gate=tensor_pow(CNOT,500))
BenchmarkTools.Trial: 564 samples with 1 evaluation.
 Range (min … max):  6.602 ms … 17.719 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     8.411 ms              ┊ GC (median):    0.00%
 Time  (mean ± σ):   8.865 ms ±  1.836 ms  ┊ GC (mean ± σ):  0.00% ± 0.00%

  ▂             ▁                    █                        
  ██▆▆▆▄▅▃▄▄▄▄▅▇█▇▆▄▅▃▄▃▃▃▃▃▃▁▂▂▃▁▃▃██▃▂▃▂▂▂▂▂▂▂▂▁▃▃▃▁▂▂▂▂▂▂ ▃
  6.6 ms         Histogram: frequency by time        13.7 ms <

 Memory estimate: 13.84 KiB, allocs estimate: 111.

Sparse gate application to only specified qubits in a 1000 qubit tableau in 4 microseconds

julia> @benchmark apply!(s, sCNOT(32,504)) setup=(s=random_stabilizer(1000))
BenchmarkTools.Trial: 10000 samples with 9 evaluations.
 Range (min … max):  3.373 μs … 252.630 μs  ┊ GC (min … max): 0.00% … 53.27%
 Time  (median):     3.766 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   3.892 μs ±   2.525 μs  ┊ GC (mean ± σ):  0.35% ±  0.53%

        ▃▆█▅▁                                                  
  ▁▁▁▂▃▇█████▅▃▂▂▃▃▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
  3.37 μs         Histogram: frequency by time        6.07 μs <

 Memory estimate: 96 bytes, allocs estimate: 2.

Benchmarks executed on a Ryzen Zen1 8-core CPU.

About

Clifford circuits, graph states, and other quantum Stabilizer formalism tools.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Julia 100.0%