Skip to content

Commit

Permalink
use YaoHIR (#71)
Browse files Browse the repository at this point in the history
* ignore vscode

* use YaoHIR

* test on latest stable

* add compat

* mark whatever is broken

* fix HIR

* update to latest YaoHIR

* rm deprecated circuit

* fix test
  • Loading branch information
Roger-luo committed May 10, 2021
1 parent ec5eb03 commit 0ef28ea
Show file tree
Hide file tree
Showing 8 changed files with 236 additions and 342 deletions.
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

0 comments on commit 0ef28ea

Please sign in to comment.