Skip to content

Commit

Permalink
General corrections (#10)
Browse files Browse the repository at this point in the history
* Formatting

* yaotoqasm -> convert_to_qasm
  • Loading branch information
Sov-trotter authored May 20, 2021
1 parent 259839a commit 6854da5
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 53 deletions.
24 changes: 10 additions & 14 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ using Documenter
indigo = DocThemeIndigo.install(YaoBlocksQASM)

makedocs(;
modules=[YaoBlocksQASM],
authors="Arsh Sharma",
repo="https://github.com/QuantumBFS/YaoBlocksQASM.jl/blob/{commit}{path}#{line}",
sitename="YaoBlocksQASM.jl",
format=Documenter.HTML(;
prettyurls=get(ENV, "CI", "false") == "true",
canonical="https://QuantumBFS.github.io/YaoBlocksQASM.jl",
assets=String[],
modules = [YaoBlocksQASM],
authors = "Arsh Sharma",
repo = "https://github.com/QuantumBFS/YaoBlocksQASM.jl/blob/{commit}{path}#{line}",
sitename = "YaoBlocksQASM.jl",
format = Documenter.HTML(;
prettyurls = get(ENV, "CI", "false") == "true",
canonical = "https://QuantumBFS.github.io/YaoBlocksQASM.jl",
assets = String[],
),
pages=[
"Quickstart" => "index.md",
],
pages = ["Quickstart" => "index.md"],
)

deploydocs(;
repo="github.com/QuantumBFS/YaoBlocksQASM.jl",devbranch = "main",
)
deploydocs(; repo = "github.com/QuantumBFS/YaoBlocksQASM.jl", devbranch = "main")
2 changes: 1 addition & 1 deletion docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ qc = chain(3, put(1=>X), put(2=>Y) ,put(3=>Z),
2) Convert it to OpenQASM compatible program

```julia
ast = yaotoqasm(qc, 1)
ast = convert_to_qasm(qc, 1)
```

## API References
Expand Down
2 changes: 1 addition & 1 deletion src/YaoBlocksQASM.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module YaoBlocksQASM

export yaotoqasm
export convert_to_qasm

using YaoBlocks

Expand Down
82 changes: 50 additions & 32 deletions src/qasm.jl
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
using OpenQASM.Types
using OpenQASM.Types
using OpenQASM.RBNF: Token

#todo support custom yao gates to qasm

"""
yaotoqasm(qc, ncreg)
convert_to_qasm(qc, ncreg)
Parses an `AbstractBlock` into code based on `OpenQASM`
Parses an `AbstractBlock` into code based on the `OpenQASM` spec
- `qc`: A `ChainBlock`(circuit that is to be run).
- `ncreg` (optional) : Number of classical registers
While performing operations like measuring, one can input desired number of classical regs(each size equal to number of qubits). Defaults to 1.
- `qc`: A `ChainBlock`(circuit that is to be run).
- `ncreg` (optional) : Number of classical registers
While performing operations like measuring, one can input desired number of classical regs(each size equal to number of qubits). Defaults to 1.
"""
function yaotoqasm(qc::AbstractBlock{N}, ncreg::Int = 1) where N
function convert_to_qasm(qc::AbstractBlock{N}, ncreg::Int = 1) where {N}
prog = generate_prog(qc, ncreg)
MainProgram(v"2", prog)
end

"""
generate_prog(qc)
Parses the YaoIR into a list of `QASM` instructions
Parses the YaoIR into a list of `QASM` instructions
- `qc`: A `ChainBlock`(circuit that is to be run).
- `qc`: A `ChainBlock`(circuit that is to be run).
"""
function generate_prog(qc::AbstractBlock{N}, ncreg::Int) where N
function generate_prog(qc::AbstractBlock{N}, ncreg::Int) where {N}
prog = []
generate_defs(prog, N, ncreg)
generate_prog!(prog, basicstyle(qc), [0:N-1...], Int[])
return prog
end

function generate_defs(prog, nq::Int, ncreg::Int)
function generate_defs(prog, nq::Int, ncreg::Int)
qregs = RegDecl(Token{:reserved}("qreg"), Token{:type}("q"), Token{:int}("$nq"))
cregs = collect(RegDecl(Token{:reserved}("creg"), Token{:type}("c$i"), Token{:int}("$nq")) for i in 1:ncreg)
cregs = collect(
RegDecl(Token{:reserved}("creg"), Token{:type}("c$i"), Token{:int}("$nq")) for
i = 1:ncreg
)
push!(prog, Include(Bit("\"qelib1.inc\"")), qregs, cregs...)
end

Expand All @@ -49,41 +51,54 @@ function generate_prog!(prog, blk::PutBlock{N,M}, locs, controls) where {N,M}
end

function generate_prog!(prog, blk::ControlBlock{N,GT,C}, locs, controls) where {N,GT,C}
any(==(0),blk.ctrl_config) && error("Inverse Control used in Control gate context")
generate_prog!(prog, blk.content, sublocs(blk.locs, locs), [controls..., sublocs(blk.ctrl_locs, locs)...])
any(==(0), blk.ctrl_config) && error("Inverse Control used in Control gate context")
generate_prog!(
prog,
blk.content,
sublocs(blk.locs, locs),
[controls..., sublocs(blk.ctrl_locs, locs)...],
)
end

function generate_prog!(prog, m::YaoBlocks.Measure{N}, locs, controls) where N
function generate_prog!(prog, m::YaoBlocks.Measure{N}, locs, controls) where {N}
# memory: List of memory slots in which to store the measurement results (mustbe the same length as qubits).
mlocs = sublocs(m.locations isa AllLocs ? [1:N...] : [m.locations...], locs)
(m.operator isa ComputationalBasis) || error("measuring an operator is not supported")
# (m.postprocess isa NoPostProcess) || error("postprocessing is not supported")
(length(controls) == 0) || error("controlled measure is not supported")

# can be improved
for i in mlocs
cargs = Bit("c1", i)
qargs = Bit("q", i)
qargs = Bit("q", i)
inst = Types.Measure(qargs, cargs)
push!(prog, inst)
end
end

# IBMQ Chip only supports ["id", "u1", "u2", "u3", "cx"]
# x, y, z and control x, y, z, id, t, swap and other primitive gates
for (GT, NAME, MAXC) in [(:XGate, "x", 2), (:YGate, "y", 2), (:ZGate, "z", 2),
(:I2Gate, "id", 0), (:TGate, "t", 0), (:SWAPGate, "swap", 0)]
for (GT, NAME, MAXC) in [
(:XGate, "x", 2),
(:YGate, "y", 2),
(:ZGate, "z", 2),
(:I2Gate, "id", 0),
(:TGate, "t", 0),
(:SWAPGate, "swap", 0),
]
@eval function generate_prog!(prog, ::$GT, locs, controls)
if length(controls) <= $MAXC
# push!(prog, )
name = "c"^(length(controls))*$NAME
name = "c"^(length(controls)) * $NAME
if name != "cx" && name != "swap"
cargs = [] #empty for now
qargs = isempty(controls) ? [Bit("q", locs...)] : [Bit("q", controls...), Bit("q", locs...)]
qargs =
isempty(controls) ? [Bit("q", locs...)] :
[Bit("q", controls...), Bit("q", locs...)]
inst = Instruction(name, cargs, qargs)
elseif name == "swap"
cargs = [] #empty for now
qargs = [Bit("q", i) for i in locs]
qargs = [Bit("q", i) for i in locs]
inst = Instruction(name, cargs, qargs)
else
inst = CXGate(Bit("q", controls...), Bit("q", locs...))
Expand All @@ -96,22 +111,25 @@ for (GT, NAME, MAXC) in [(:XGate, "x", 2), (:YGate, "y", 2), (:ZGate, "z", 2),
end

# rotation gates
for (GT, NAME, PARAMS, MAXC) in [(:(RotationGate{1, T, XGate} where T), "rx", :(b.theta), 0),
(:(RotationGate{1, T, YGate} where T), "ry", :(b.theta), 0),
(:(RotationGate{1, T, ZGate} where T), "rz", :(b.theta), 0),
(:(ShiftGate), "p", :(b.theta), 1),
(:(HGate), "h", :(nothing), 0),
]
for (GT, NAME, PARAMS, MAXC) in [
(:(RotationGate{1,T,XGate} where {T}), "rx", :(b.theta), 0),
(:(RotationGate{1,T,YGate} where {T}), "ry", :(b.theta), 0),
(:(RotationGate{1,T,ZGate} where {T}), "rz", :(b.theta), 0),
(:(ShiftGate), "p", :(b.theta), 1),
(:(HGate), "h", :(nothing), 0),
]
@eval function generate_prog!(prog, b::$GT, locs, controls)
if length(controls) <= $MAXC
name = "c"^(length(controls))*$NAME
name = "c"^(length(controls)) * $NAME
if $PARAMS === nothing
cargs = []
qargs = [Bit("q", locs...)]
else
params = $PARAMS
cargs = [Token{:float64}("$params")]
qargs = isempty(controls) ? [Bit("q", locs...)] : [Bit("q", controls...), Bit("q", locs...)]
qargs =
isempty(controls) ? [Bit("q", locs...)] :
[Bit("q", controls...), Bit("q", locs...)]
end
push!(prog, Instruction(name, cargs, qargs))
else
Expand All @@ -123,5 +141,5 @@ end
sublocs(subs, locs) = [locs[i] for i in subs]

function basicstyle(blk::AbstractBlock)
YaoBlocks.Optimise.simplify(blk, rules=[YaoBlocks.Optimise.to_basictypes])
YaoBlocks.Optimise.simplify(blk, rules = [YaoBlocks.Optimise.to_basictypes])
end
25 changes: 20 additions & 5 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,29 @@ using Test
"""

ast = OpenQASM.parse(qasm)
qc = chain(3, put(1=>H), control(2, 3=>X),control(2, 1=>Y),control(1, 3=>Z),
put(1=>X) ,swap(2,3),put(1=>I2),put(2=>T), put(3=>Rz(0.7)), put(1=>Z), put(2=>shift(0.7)),
put(3=>Ry(0.7)), put(1=>Y),put(2=>Rx(0.7)),Yao.Measure(3))
ast1 = yaotoqasm(qc, 1)
qc = chain(
3,
put(1 => H),
control(2, 3 => X),
control(2, 1 => Y),
control(1, 3 => Z),
put(1 => X),
swap(2, 3),
put(1 => I2),
put(2 => T),
put(3 => Rz(0.7)),
put(1 => Z),
put(2 => shift(0.7)),
put(3 => Ry(0.7)),
put(1 => Y),
put(2 => Rx(0.7)),
Yao.Measure(3),
)
ast1 = convert_to_qasm(qc, 1)

@test ast.version == ast1.version

for i in 1:length(ast.prog)
for i = 1:length(ast.prog)
@test "$(ast.prog[i])" == "$(ast1.prog[i])"
end
end

0 comments on commit 6854da5

Please sign in to comment.