Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make YaoToEinsum a component package #502

Merged
merged 2 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ jobs:
- YaoBlocks
- YaoSym
- YaoPlots
- YaoToEinsum
steps:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
Expand Down
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ JL = julia --project
default: init test

init:
$(JL) -e 'using Pkg; Pkg.develop([Pkg.PackageSpec(path = joinpath("lib", pkg)) for pkg in ["YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "YaoAPI"]]); Pkg.precompile()'
$(JL) -e 'using Pkg; Pkg.develop([Pkg.PackageSpec(path = joinpath("lib", pkg)) for pkg in ["YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "YaoAPI", "YaoToEinsum"]]); Pkg.precompile()'
init-docs:
$(JL) -e 'using Pkg; Pkg.activate("docs"); Pkg.develop([Pkg.PackageSpec(path = joinpath("lib", pkg)) for pkg in ["YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "YaoAPI"]]); Pkg.precompile()'
$(JL) -e 'using Pkg; Pkg.activate("docs"); Pkg.develop([Pkg.PackageSpec(path = joinpath("lib", pkg)) for pkg in ["YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "YaoAPI", "YaoToEinsum"]]); Pkg.precompile()'

update:
$(JL) -e 'using Pkg; Pkg.update(); Pkg.precompile()'
Expand All @@ -22,10 +22,10 @@ test-%:
$(JL) -e 'using Pkg; Pkg.test("$*")'

test:
$(JL) -e 'using Pkg; Pkg.test(["YaoAPI", "YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "Yao"])'
$(JL) -e 'using Pkg; Pkg.test(["YaoAPI", "YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "Yao", "YaoToEinsum"])'

coverage:
$(JL) -e 'using Pkg; Pkg.test(["YaoAPI", "YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "Yao"]; coverage=true)'
$(JL) -e 'using Pkg; Pkg.test(["YaoAPI", "YaoArrayRegister", "YaoBlocks", "YaoSym", "YaoPlots", "Yao", "YaoToEinsum"]; coverage=true)'

servedocs:
$(JL) -e 'using Pkg; Pkg.activate("docs"); using LiveServer; servedocs(;skip_dirs=["docs/src/assets", "docs/src/generated"])'
Expand Down
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ YaoArrayRegister = "e600142f-9330-5003-8abb-0ebd767abc51"
YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df"
YaoPlots = "32cfe2d9-419e-45f2-8191-2267705d8dbc"
YaoSym = "3b27209a-d3d6-11e9-3c0f-41eb92b2cb9d"
YaoToEinsum = "9b173c7b-dc24-4dc5-a0e1-adab2f7b6ba9"

[weakdeps]
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
Expand Down
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const PAGES = [
"man/cuda.md",
"man/plot.md",
"man/automatic_differentiation.md",
"man/yao2einsum.md",
"man/simplification.md",
"man/bitbasis.md",
],
Expand All @@ -71,7 +72,7 @@ const PAGES = [
indigo = DocThemeIndigo.install(Yao)

makedocs(
modules = [Yao, YaoAPI, YaoArrayRegister, YaoBlocks, BitBasis, YaoSym, YaoPlots, AD, Optimise],
modules = [Yao, YaoAPI, YaoArrayRegister, YaoBlocks, BitBasis, YaoSym, YaoPlots, YaoToEinsum, AD, Optimise],
format = Documenter.HTML(
prettyurls = ("deploy" in ARGS),
canonical = ("deploy" in ARGS) ? "https://docs.yaoquantum.org/" : nothing,
Expand Down
45 changes: 45 additions & 0 deletions docs/src/man/yao2einsum.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Tensor network backend

Simulating quantum circuits using tensor networks has been studied in the literature[^Markov2008][^Pan2022]. The `YaoToEinsum` package provides a convenient way to convert Yao circuits to tensor networks, which can be used for further analysis and optimization.

## Tutorial
The main function is
```julia
yao2einsum(circuit; initial_state=Dict(), final_state=Dict(), optimizer=TreeSA())
```
which transforms a [`Yao`](https://github.com/QuantumBFS/Yao.jl) circuit to a tensor network that generalizes the hyper-graph (einsum notation). The return value is a `TensorNetwork` object.

* `initial_state` and `final_state` are for specifying the initial state and final state. Left the qubits unspecified if you want to keep them as the open indices.
* `optimizer` is for specifying the contraction order optimizing algorithm of the tensor network. The default value is the `TreeSA()` algorithm that developed in [^Kalachev2021][^Liu2023]. Please check the README of [OMEinsumEinsumContractors.jl](https://github.com/TensorBFS/OMEinsumContractionOrders.jl) for more information.

In the following example, we show how to convert a quantum Fourier transform circuit to a tensor network and contract it to
- Get the matrix representation of the circuit.
- Get the probability of measuring the zero state after applying the circuit on the zero state.

```@repl
import Yao
using Yao.EasyBuild: qft_circuit
n = 10;
circuit = qft_circuit(n); # build a quantum Fourier transform circuit
network = Yao.yao2einsum(circuit) # convert this circuit to tensor network
reshape(Yao.contract(network), 1<<n, 1<<n) ≈ Yao.mat(circuit)
network = Yao.yao2einsum(circuit; # convert circuit sandwiched by zero states
initial_state=Dict([i=>0 for i=1:n]), final_state=Dict([i=>0 for i=1:n]),
optimizer=Yao.YaoToEinsum.TreeSA(; nslices=3)) # slicing technique
Yao.contract(network)[] ≈ Yao.zero_state(n)' * (Yao.zero_state(n) |> circuit)
```

## API
```@docs
yao2einsum
TensorNetwork
optimize_code
contraction_complexity
contract
```

## References
[^Pan2022]: Pan, Feng, and Pan Zhang. "Simulation of quantum circuits using the big-batch tensor network method." Physical Review Letters 128.3 (2022): 030501.
[^Kalachev2021]: Kalachev, Gleb, Pavel Panteleev, and Man-Hong Yung. "Recursive multi-tensor contraction for xeb verification of quantum circuits." arXiv preprint arXiv:2108.05665 (2021).
[^Markov2008]: Markov, Igor L., and Yaoyun Shi. "Simulating quantum computation by contracting tensor networks." SIAM Journal on Computing 38.3 (2008): 963-981.
[^Liu2023]: Liu, Jin-Guo, et al. "Computing solution space properties of combinatorial optimization problems via generic tensor networks." SIAM Journal on Scientific Computing 45.3 (2023): A1239-A1270.
61 changes: 61 additions & 0 deletions lib/YaoToEinsum/CITATION.bib
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
@article{Luo2020,
title = {Yao.jl: {Extensible}, {Efficient} {Framework} for {Quantum} {Algorithm} {Design}},
volume = {4},
shorttitle = {Yao.jl},
url = {https://quantum-journal.org/papers/q-2020-10-11-341/},
doi = {10.22331/q-2020-10-11-341},
abstract = {Xiu-Zhe Luo, Jin-Guo Liu, Pan Zhang, and Lei Wang,
Quantum 4, 341 (2020).
We introduce \${\textbackslash}texttt\{Yao\}\$, an extensible, efficient open-source framework for quantum algorithm design. \${\textbackslash}texttt\{Yao\}\$ features generic and differentiable programming of quantum circuits. It a…},
language = {en-GB},
urldate = {2023-03-23},
journal = {Quantum},
author = {Luo, Xiu-Zhe and Liu, Jin-Guo and Zhang, Pan and Wang, Lei},
month = oct,
year = {2020},
note = {Publisher: Verein zur Förderung des Open Access Publizierens in den Quantenwissenschaften},
pages = {341},
}

@article{Pan2022,
title = {Simulation of {Quantum} {Circuits} {Using} the {Big}-{Batch} {Tensor} {Network} {Method}},
volume = {128},
url = {https://link.aps.org/doi/10.1103/PhysRevLett.128.030501},
doi = {10.1103/PhysRevLett.128.030501},
abstract = {We propose a tensor network approach to compute amplitudes and probabilities for a large number of correlated bitstrings in the final state of a quantum circuit. As an application, we study Google’s Sycamore circuits, which are believed to be beyond the reach of classical supercomputers and have been used to demonstrate quantum supremacy. By employing a small computational cluster containing 60 graphical processing units (GPUs), we compute exact amplitudes and probabilities of 2×106 correlated bitstrings with some entries fixed (which span a subspace of the output probability distribution) for the Sycamore circuit with 53 qubits and 20 cycles. The obtained results verify the Porter-Thomas distribution of the large and deep quantum circuits of Google, provide datasets and benchmarks for developing approximate simulation methods, and can be used for spoofing the linear cross entropy benchmark of quantum supremacy. Then we extend the proposed big-batch method to a full-amplitude simulation approach that is more efficient than the existing Schrödinger method on shallow circuits and the Schrödinger-Feynman method in general, enabling us to obtain the state vector of Google’s simplifiable circuit with n=43 qubits and m=14 cycles using only one GPU. We also manage to obtain the state vector for Google’s simplifiable circuits with n=50 qubits and m=14 cycles using a small GPU cluster, breaking the previous record on the number of qubits in full-amplitude simulations. Our method is general in computing bitstring probabilities for a broad class of quantum circuits and can find applications in the verification of quantum computers. We anticipate that our method will pave the way for combining tensor network–based classical computations and near-term quantum computations for solving challenging problems in the real world.},
number = {3},
urldate = {2023-02-09},
journal = {Physical Review Letters},
author = {Pan, Feng and Zhang, Pan},
month = jan,
year = {2022},
note = {Publisher: American Physical Society},
pages = {030501},
}

@article{Kalachev2021,
title = {Recursive {Multi}-{Tensor} {Contraction} for {XEB} {Verification} of {Quantum} {Circuits}},
url = {http://arxiv.org/abs/2108.05665},
abstract = {The computational advantage of noisy quantum computers have been demonstrated by sampling the bitstrings of quantum random circuits. An important issue is how the performance of quantum devices could be quantified in the so-called "supremacy regime". The standard approach is through the linear cross entropy (XEB), where the theoretical value of the probability is required for each bitstring. However, the computational cost of XEB grows exponentially. So far, random circuits of the 53-qubit Sycamore chip was verified up to 10 cycles of gates only; the XEB fidelities of deeper circuits were approximated with simplified circuits instead. Here we present a multi-tensor contraction algorithm for speeding up the calculations of XEB of quantum circuits, where the computational cost can be significantly reduced through a recursive manner with some form of memoization. As a demonstration, we analyzed the experimental data of the 53-qubit Sycamore chip and obtained the exact values of the corresponding XEB fidelities up to 16 cycles using only moderate computing resources (few GPUs). If the algorithm was implemented on the Summit supercomputer, we estimate that for the 20-cycles supremacy circuits, it would only cost 7.5 days, which is several orders of magnitudes lower than previously estimated in the literature.},
author = {Kalachev, Gleb and Panteleev, Pavel and Yung, Man-Hong},
year = {2021},
note = {arXiv: 2108.05665},
pages = {1--9},
}

@article{Markov2008,
title = {Simulating {Quantum} {Computation} by {Contracting} {Tensor} {Networks}},
volume = {38},
issn = {0097-5397},
url = {https://epubs.siam.org/doi/abs/10.1137/050644756},
doi = {10.1137/050644756},
abstract = {Adiabatic quantum computation has recently attracted attention in the physics and computer science communities, but its computational power was unknown. We describe an efficient adiabatic simulation of any given quantum algorithm, which implies that the adiabatic computation model and the conventional quantum computation model are polynomially equivalent. Our result can be extended to the physically realistic setting of particles arranged on a two‐dimensional grid with nearest neighbor interactions. The equivalence between the models allows stating the main open problems in quantum computation using well‐studied mathematical objects such as eigenvectors and spectral gaps of sparse matrices.},
number = {3},
urldate = {2023-10-05},
journal = {SIAM Journal on Computing},
author = {Markov, Igor L. and Shi, Yaoyun},
month = jan,
year = {2008},
note = {Publisher: Society for Industrial and Applied Mathematics},
pages = {963--981},
}
21 changes: 21 additions & 0 deletions lib/YaoToEinsum/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 GiggleLiu <[email protected]> and contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
28 changes: 28 additions & 0 deletions lib/YaoToEinsum/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name = "YaoToEinsum"
uuid = "9b173c7b-dc24-4dc5-a0e1-adab2f7b6ba9"
authors = ["GiggleLiu <[email protected]> and contributors"]
version = "0.2.2"

[deps]
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
OMEinsum = "ebe7aa44-baf0-506c-a96f-8464559b3922"
YaoBlocks = "418bc28f-b43b-5e0b-a6e7-61bbc1a2c1df"

[weakdeps]
CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"

[extensions]
YaoToEinsumCUDAExt = "CUDA"

[compat]
CUDA = "4, 5"
OMEinsum = "0.8"
YaoBlocks = "0.13"
julia = "1.9"

[extras]
SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "SymEngine"]
14 changes: 14 additions & 0 deletions lib/YaoToEinsum/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# YaoToEinsum

Convert [Yao](https://github.com/QuantumBFS/Yao.jl) circuit to tensor networks (einsum).

## Installation

`YaoToEinsum` is a [Julia language](https://julialang.org/) package. To install `YaoToEinsum`, please [open Julia's interactive session (known as REPL)](https://docs.julialang.org/en/v1/manual/getting-started/) and press <kbd>]</kbd> key in the REPL to use the package mode, then type the following command

```julia
pkg> add YaoToEinsum
```

## Using
Please refer to the [documentation]().
7 changes: 7 additions & 0 deletions lib/YaoToEinsum/ext/YaoToEinsumCUDAExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module YaoToEinsumCUDAExt
using CUDA, YaoToEinsum

function CUDA.cu(tnet::TensorNetwork)
return TensorNetwork(tnet.code, tnet.tensors .|> CuArray)
end
end
62 changes: 62 additions & 0 deletions lib/YaoToEinsum/src/Core.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"""
TensorNetwork

A (generalized) tensor network representation of a quantum circuit.

### Fields
* `code::AbstractEinsum`: The einsum code.
* `tensors::Vector`: The tensors in the network.
"""
struct TensorNetwork
code::AbstractEinsum
tensors::Vector
end
function Base.show(io::IO, c::TensorNetwork)
print(io, "TensorNetwork")
print(io, "\n")
print(io, contraction_complexity(c))
end
function Base.show(io::IO, ::MIME"text/plain", c::TensorNetwork)
Base.show(io, c)
end
function Base.iterate(c::TensorNetwork, state=1)
if state > 2
return nothing
elseif state == 1
return (c.code, 2)
else
return (c.tensors, 3)
end
end

"""
contract(c::TensorNetwork)

Contract the tensor network, and return the result tensor.
"""
function contract(c::TensorNetwork)
return c.code(c.tensors...; size_info=uniformsize(c.code, 2))
end

"""
optimize_code(c::TensorNetwork, optimizer=TreeSA())

Optimize the code of the tensor network.

### Arguments
* `c::TensorNetwork`: The tensor network.
* `optimizer::Optimizer`: The optimizer to use, default is `TreeSA()`. Please check [OMEinsumContractors.jl](https://github.com/TensorBFS/OMEinsumContractionOrders.jl) for more information.
"""
function OMEinsum.optimize_code(c::TensorNetwork, args...)
optcode = optimize_code(c.code, uniformsize(c.code, 2), args...)
return TensorNetwork(optcode, c.tensors)
end

"""
contraction_complexity(c::TensorNetwork)

Return the contraction complexity of the tensor network.
"""
function OMEinsum.contraction_complexity(c::TensorNetwork)
return contraction_complexity(c.code, uniformsize(c.code, 2))
end
13 changes: 13 additions & 0 deletions lib/YaoToEinsum/src/YaoToEinsum.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module YaoToEinsum

using YaoBlocks, YaoBlocks.YaoArrayRegister, OMEinsum
using LinearAlgebra

export yao2einsum
export TensorNetwork, optimize_code, contraction_complexity, contract
export TreeSA

include("Core.jl")
include("circuitmap.jl")

end
Loading
Loading