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

use YaoHIR #71

Merged
merged 9 commits into from
May 10, 2021
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
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.5'
- '1'
- 'nightly'
os:
- ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/Manifest.toml
/dev/
/docs/build/
.vscode
11 changes: 9 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,24 @@ version = "0.4.0"
[deps]
LightGraphs = "093fc24a-ae57-5d10-9952-331d41423f4d"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
Multigraphs = "7ebac608-6c66-46e6-9856-b5f43e107bac"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
YaoHIR = "6769671a-fce8-4286-b3f7-6099e1b1298a"
YaoLocations = "66df03fb-d475-48f7-b449-3d9064bf085b"

[compat]
julia = "1"
LightGraphs = "1.3"
MLStyle = "0.4"
Multigraphs = "0.2"
YaoHIR = "0.1"
YaoLocations = "0.1"
julia = "1"

[extras]
CompilerPluginTools = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3638"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Test", "Documenter"]
test = ["Test", "Documenter", "CompilerPluginTools"]
12 changes: 10 additions & 2 deletions src/ZXCalculus.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
module ZXCalculus

using YaoHIR
using MLStyle
using YaoLocations
using YaoHIR: X, Y, Z, H, S, T, Rx, Ry, Rz, UGate, shift
using YaoLocations: plain

export convert_to_block_ir, convert_to_zxd

include("phase.jl")
include("scalar.jl")
include("abstract_zx_diagram.jl")
include("zx_layout.jl")
include("zx_diagram.jl")
include("qcircuit.jl")
include("zx_graph.jl")
include("rules.jl")

include("simplify.jl")

include("ir.jl")

include("circuit_extraction.jl")
include("phase_teleportation.jl")

Expand Down
192 changes: 192 additions & 0 deletions src/ir.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
function unwrap_ssa_phase(theta, ir::Core.Compiler.IRCode)
if theta isa Core.SSAValue
return Phase(theta, ir.stmts[theta.id][:type])
elseif theta isa QuoteNode
return theta.value
elseif theta isa Core.Const
return theta.val
elseif theta isa Number
return theta
else
error("expect SSAValue or Number")
end
end

function convert_to_zxd(root::YaoHIR.BlockIR)
circ = ZXDiagram(root.nqubits)

for gate in YaoHIR.leaves(root.circuit)
@switch gate begin
@case Gate(&Z, loc::Locations{Int})
push_gate!(circ, Val(:Z), plain(loc), 1//1)
@case Gate(&X, loc::Locations{Int})
push_gate!(circ, Val(:X), plain(loc), 1//1)
@case Gate(&H, loc::Locations{Int})
push_gate!(circ, Val(:H), loc)
@case Gate(&S, loc::Locations{Int})
push_gate!(circ, Val(:Z), plain(loc), 1//2)
@case Gate(&T, loc::Locations{Int})
push_gate!(circ, Val(:Z), plain(loc), 1//4)
@case Gate(shift(theta), loc::Locations{Int})
theta = unwrap_ssa_phase(theta, root.parent)
push_gate!(circ, Val(:Z), plain(loc), (1/π)*theta)
@case Gate(Rx(theta), loc::Locations{Int})
theta = unwrap_ssa_phase(theta, root.parent)
push_gate!(circ, Val(:X), plain(loc), (1/π)*theta)
@case Gate(Ry(theta), loc::Locations{Int})
theta = unwrap_ssa_phase(theta, root.parent)
push_gate!(circ, Val(:X), plain(loc), 1//2)
push_gate!(circ, Val(:Z), plain(loc), (1/π) * theta)
push_gate!(circ, Val(:X), plain(loc), -1//2)
@case Gate(Rz(theta), loc::Locations{Int})
theta = unwrap_ssa_phase(theta, root.parent)
push_gate!(circ, Val(:Z), plain(loc), (1/π)*theta)
@case Gate(AdjointOperation(&S), loc::Locations{Int})
push_gate!(circ, Val(:Z), plain(loc), 3//2)
@case Gate(AdjointOperation(&T), loc::Locations{Int})
push_gate!(circ, Val(:Z), plain(loc), 7//4)
@case Ctrl(Gate(&X, loc::Locations{Int}), ctrl::CtrlLocations{Int}) # CNOT
push_gate!(circ, Val(:CNOT), plain(loc), plain(ctrl))
@case Ctrl(Gate(&Z, loc::Locations{Int}), ctrl::CtrlLocations{Int}) # CZ
push_gate!(circ, Val(:CZ), plain(loc), plain(ctrl))
@case _
error("$gate is not supported")
end
end
return circ
end

function convert_to_block_ir(circ::ZXDiagram{T, P}) where {T, P}
spider_seq = spider_sequence(circ)
vs = spiders(circ)
locs = Dict()
nqubit = nqubits(circ)
qc = []
frontier_v = ones(T, nqubit)

while sum([frontier_v[i] <= length(spider_seq[i]) for i = 1:nqubit]) > 0
for q = 1:nqubit
if frontier_v[q] <= length(spider_seq[q])
v = spider_seq[q][frontier_v[q]]
nb = ZXCalculus.neighbors(circ, v)
if length(nb) <= 2
θ = phase(circ, v) * π
if spider_type(circ, v) == ZXCalculus.SpiderType.Z
if phase(circ, v) == 1
push!(qc, Gate(Z, Locations(q)))
elseif phase(circ, v) == 1//2
push!(qc, Gate(S, Locations(q)))
elseif phase(circ, v) == 3//2
push!(qc, Gate(AdjointOperation(S), Locations(q)))
elseif phase(circ, v) == 1//4
push!(qc, Gate(T, Locations(q)))
elseif phase(circ, v) == 7//4
push!(qc, Gate(AdjointOperation(T), Locations(q)))
elseif phase(circ, v) != 0
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(shift(θ), Locations(q)))
end
elseif spider_type(circ, v) == ZXCalculus.SpiderType.X
if phase(circ, v) == 1
push!(qc, Gate(X, Locations(q)))
else phase(circ, v) != 0
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(Rx(θ), Locations(q)))
end
elseif spider_type(circ, v) == ZXCalculus.SpiderType.H
push!(qc, Gate(H, Locations(q)))
end

frontier_v[q] += 1
elseif length(nb) == 3
v1 = nb[[qubit_loc(circ, u) != q for u in nb]][1]
if spider_type(circ, v1) == SpiderType.H
v1 = setdiff(ZXCalculus.neighbors(circ, v1), [v])[1]
end
if sum([findfirst(isequal(u), spider_seq[qubit_loc(circ, u)]) != frontier_v[qubit_loc(circ, u)] for u in [v, v1]]) == 0
if phase(circ, v) != 0
if spider_type(circ, v) == ZXCalculus.SpiderType.Z
if phase(circ, v) == 1
push!(qc, Gate(Z, Locations(qubit_loc(circ, v))))
elseif phase(circ, v) == 1//2
push!(qc, Gate(S, Locations(qubit_loc(circ, v))))
elseif phase(circ, v) == 3//2
push!(qc, Gate(S', Locations(qubit_loc(circ, v))))
elseif phase(circ, v) == 1//4
push!(qc, Gate(T, Locations(qubit_loc(circ, v))))
elseif phase(circ, v) == 7//4
push!(qc, GatE(T', Locations(qubit_loc(circ, v))))
else
θ = phase(circ, v)*π
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(shift(θ), Locations(qubit_loc(circ, v))))
end
else
if phase(circ, v) == 1
push!(qc, Gate(X, Locations(qubit_loc(circ, v))))
else
θ = phase(circ, v)*π
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(Rx(θ), Locations(qubit_loc(circ, v))))
end
end
end
if phase(circ, v1) != 0
if spider_type(circ, v1) == ZXCalculus.SpiderType.Z
if phase(circ, v1) == 1
push!(qc, Gate(Z, Locations(qubit_loc(circ, v1))))
elseif phase(circ, v1) == 1//2
push!(qc, Gate(S, Locations(qubit_loc(circ, v1))))
elseif phase(circ, v1) == 3//2
push!(qc, Gate(S', Locations(qubit_loc(circ, v1))))
elseif phase(circ, v1) == 1//4
push!(qc, Gate(T, Locations(qubit_loc(circ, v1))))
elseif phase(circ, v1) == 7//4
push!(qc, Gate(T', Locations(qubit_loc(circ, v1))))
else
θ = phase(circ, v1)*π
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(shift(θ), Locations(qubit_loc(circ, v1))))
end
else
if phase(circ, v1) == 1
push!(qc, Gate(X, Locations(qubit_loc(circ, v1))))
else
θ = phase(circ, v1)*π
if θ isa Phase
θ = θ.ex
end
push!(qc, Gate(Rx(θ), Locations(qubit_loc(circ, v1))))
end
end
end

if spider_type(circ, v) == spider_type(circ, v1) == ZXCalculus.SpiderType.Z
push!(qc, Ctrl(Gate(Z, Locations(qubit_loc(circ, v))), CtrlLocations(qubit_loc(circ, v1))))
elseif spider_type(circ, v) == ZXCalculus.SpiderType.Z
push!(qc, Ctrl(Gate(X, Locations(qubit_loc(circ, v1))), CtrlLocations(qubit_loc(circ, v))))
elseif spider_type(circ, v) == ZXCalculus.SpiderType.X
push!(qc, Ctrl(Gate(X, Locations(qubit_loc(circ, v))), CtrlLocations(qubit_loc(circ, v1))))
end
for u in [v, v1]
frontier_v[qubit_loc(circ, u)] += 1
end
end
else
error("ZX-diagram without a circuit structure is not supported!")
end
end
end
end
return qc
end
Loading