-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature Parse qasm for BlockIR(qasm::String) (#8)
* prototype parser and converter for OpenQASM still a lot of gates to parse, currently support - S - X - Z - s - sDag - t - tDag * use explicit InstrinsicOperation * remove CompilerPluginTools * Create YaoHIRExt * create testsets * add qasm test --------- Co-authored-by: liam <[email protected]>
- Loading branch information
1 parent
e03925c
commit 59a5fd9
Showing
8 changed files
with
337 additions
and
63 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
module YaoHIRExt | ||
|
||
using YaoHIR, YaoLocations | ||
using YaoHIR.IntrinsicOperation | ||
using MLStyle | ||
using OpenQASM | ||
using OpenQASM.Types: Instruction, CXGate, Measure, Reset, MainProgram, Include, RegDecl, ASTNode | ||
using Core.Compiler: IRCode | ||
|
||
function YaoHIR.BlockIR(ast::MainProgram) | ||
convert_to_blockir(ast::MainProgram) | ||
end | ||
function YaoHIR.BlockIR(qasm::String) | ||
convert_to_blockir(OpenQASM.parse(qasm)::MainProgram) | ||
end | ||
|
||
qarg_address(i::Instruction) = Locations(parse(Int, i.qargs[1].address.str) + 1) | ||
qarg_address(i::CXGate) = Locations(parse(Int, i.qarg.address.str) + 1) | ||
#qarg_address(i::CZGate) = Locations(parse(Int, i.qarg.address.str) + 1) | ||
ctrl_address(i::ASTNode) = Locations(parse(Int, i.ctrl.address.str) + 1) | ||
|
||
|
||
push_prog!(circ::Chain, prog::Any) = prog !== nothing && push!(circ.args, prog) | ||
|
||
function convert_to_blockir(ast::MainProgram) | ||
qubits = sum([parse(Int, m.size.str) for m in ast.prog if m isa RegDecl && m.type.str == "qreg"]) | ||
ir = IRCode() | ||
chain = Chain() | ||
[push_prog!(chain, prog_to_gate(prog)) for prog in ast.prog] | ||
BlockIR(ir, qubits, chain) | ||
end | ||
|
||
|
||
function instruction_to_gate(i::Instruction) | ||
@switch i.name begin | ||
@case "z" | ||
Gate(Z, qarg_address(i)) | ||
@case "x" | ||
Gate(X, qarg_address(i)) | ||
@case "h" | ||
Gate(H, qarg_address(i)) | ||
@case "s" | ||
Gate(S, qarg_address(i)) | ||
@case "sdg" | ||
Gate(AdjointOperation(S), qarg_address(i)) | ||
@case "t" | ||
Gate(S, qarg_address(i)) | ||
@case "tdg" | ||
Gate(AdjointOperation(T), qarg_address(i)) | ||
@case "rx" | ||
error("Gate $i not yet implemented") | ||
@case "rx" | ||
error("Gate $i not yet implemented") | ||
@case "shift" | ||
error("Gate $i not yet implemented") | ||
@case "id" | ||
nothing | ||
@case _ | ||
error("Gate $i not supported") | ||
end | ||
end | ||
|
||
function prog_to_gate(a::Any) | ||
@match a begin | ||
i::Include => nothing | ||
r::RegDecl => nothing | ||
inst::Instruction => instruction_to_gate(inst) | ||
cx::CXGate => Ctrl(Gate(X, | ||
Locations(qarg_address(cx))), | ||
CtrlLocations(ctrl_address(cx))) | ||
|
||
# cz::CZGate => Ctrl(Gate(Z, | ||
# Locations(qarg_address(cz))), | ||
# CtrlLocations(ctrl_address(cz))) | ||
m::Measure => nothing | ||
r::Reset => error("only unitaries are supported, please use the function reconstruct_unitaries from the package QuantumCircuitEquivalence.jl") | ||
end | ||
end | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
|
||
@testset "types" begin | ||
@test YaoHIR.routine_name(TestIntrinsic.X) == :X | ||
@test YaoHIR.routine_name(TestIntrinsic.R(1.0)) == :R | ||
@test TestIntrinsic.R(1.0).theta == 1.0 | ||
|
||
display(X) | ||
display(Rx(1.0)) | ||
display(YaoHIR.Operation(X, 2.0)) | ||
|
||
circ = Chain( | ||
Gate(X, Locations(1)), | ||
Core.SSAValue(1), | ||
Ctrl(Gate(Core.SSAValue(1), Locations(3)), CtrlLocations(2)) | ||
) | ||
|
||
print(circ) | ||
|
||
@test YaoHIR.leaves(circ) == [Gate(X, Locations(1)), | ||
Core.SSAValue(1), | ||
Ctrl(Gate(Core.SSAValue(1), Locations(3)), CtrlLocations(2)) | ||
] | ||
|
||
end | ||
|
||
|
||
@testset "test match" begin | ||
gate = Gate(X, Locations(2)) | ||
|
||
@match gate begin | ||
Gate(op, locs) => begin | ||
@test op == X | ||
@test locs == Locations(2) | ||
end | ||
end | ||
|
||
ctrl = Ctrl(Gate(X, Locations(2)), CtrlLocations(3)) | ||
|
||
@match ctrl begin | ||
Ctrl(Gate(op, locs), ctrl) => begin | ||
@test op == X | ||
@test locs == Locations(2) | ||
@test ctrl == CtrlLocations(3) | ||
end | ||
end | ||
end | ||
|
||
@testset "isequal" begin | ||
circuit1 = Chain(Gate(H, Locations((1, ))), Gate(H, Locations((1, )))) | ||
circuit2 = Chain(Gate(H, Locations((1, ))), Gate(H, Locations((1, )))) | ||
@test circuit1 == circuit2 | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module TestIntrinsic | ||
using YaoHIR: @intrinsic | ||
|
||
@intrinsic X | ||
@intrinsic R(theta::T) where {T <: Real} | ||
@intrinsic SWAP | ||
|
||
end | ||
|
||
@testset "instrinic" begin | ||
|
||
@test YaoHIR.routine_name(TestIntrinsic.X) == :X | ||
@test YaoHIR.routine_name(TestIntrinsic.R(1.0)) == :R | ||
@test TestIntrinsic.R(1.0).theta == 1.0 | ||
|
||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
using YaoHIR | ||
using YaoHIR.IntrinsicOperation | ||
using OpenQASM | ||
|
||
@testset "convert qasm" begin | ||
|
||
bir = BlockIR(""" | ||
OPENQASM 2.0; | ||
include "qelib1.inc"; | ||
qreg q0[3]; | ||
creg c0[2]; | ||
h q0[0]; | ||
h q0[1]; | ||
x q0[2]; | ||
h q0[2]; | ||
CX q0[0], q0[2]; | ||
h q0[0]; | ||
measure q0[0] -> c0[0]; | ||
CX q0[1], q0[2]; | ||
h q0[1]; | ||
measure q0[1] -> c0[1]; | ||
""") | ||
|
||
@testset "correct parsing" begin | ||
bir !== nothing | ||
end | ||
|
||
chain = Chain( | ||
Gate(H, Locations(1)), | ||
Gate(H, Locations(2)), | ||
Gate(X, Locations(3)), | ||
Gate(H, Locations(3)), | ||
Ctrl(Gate(X, Locations(3)), CtrlLocations(1)), | ||
Gate(H, Locations(1)), | ||
Ctrl(Gate(X, Locations(3)), CtrlLocations(2)), | ||
Gate(H, Locations(2)) | ||
) | ||
|
||
@testset "conversion" begin | ||
@test chain == bir.circuit | ||
end | ||
|
||
|
||
@testset "parse DJ-NAND" begin | ||
bv = BlockIR(""" | ||
OPENQASM 2.0; | ||
include "qelib1.inc"; | ||
qreg q[3]; | ||
creg c[2]; | ||
h q[0]; | ||
h q[1]; | ||
x q[2]; | ||
h q[2]; | ||
x q[2]; | ||
h q[2]; | ||
cx q[1],q[2]; | ||
tdg q[2]; | ||
cx q[0],q[2]; | ||
t q[2]; | ||
cx q[1],q[2]; | ||
t q[1]; | ||
tdg q[2]; | ||
cx q[0],q[2]; | ||
cx q[0],q[1]; | ||
t q[0]; | ||
tdg q[1]; | ||
cx q[0],q[1]; | ||
h q[0]; | ||
h q[1]; | ||
t q[2]; | ||
h q[2]; | ||
measure q[0] -> c[0]; | ||
measure q[1] -> c[1]; | ||
""") | ||
|
||
|
||
bv_re = BlockIR(""" | ||
OPENQASM 2.0; | ||
include "qelib1.inc"; | ||
qreg q[3]; | ||
creg c1[1]; | ||
creg c2[1]; | ||
h q[1]; | ||
t q[1]; | ||
x q[2]; | ||
h q[2]; | ||
x q[2]; | ||
h q[2]; | ||
t q[2]; | ||
CX q[1], q[2]; | ||
tdg q[2]; | ||
CX q[1], q[2]; | ||
h q[1]; | ||
h q[2]; | ||
h q[2]; | ||
t q[2]; | ||
h q[0]; | ||
t q[0]; | ||
CX q[0], q[2]; | ||
tdg q[2]; | ||
CX q[0], q[2]; | ||
CX q[1], q[0]; | ||
tdg q[0]; | ||
tdg q[2]; | ||
CX q[0], q[2]; | ||
t q[2]; | ||
CX q[0], q[2]; | ||
CX q[1], q[0]; | ||
h q[0]; | ||
h q[2]; | ||
measure q[0] -> c2[0]; | ||
measure q[1] -> c1[0];""") | ||
|
||
@testset "correct parsing" begin | ||
@test bv !== nothing | ||
end | ||
|
||
@testset "convert into BlockIR" begin | ||
@test bv_re !== nothing | ||
|
||
end | ||
|
||
end | ||
|
||
@testset "dj 3" begin | ||
dj3 = BlockIR(""" | ||
OPENQASM 2.0; | ||
include "qelib1.inc"; | ||
qreg q[3]; | ||
creg c[2]; | ||
h q[0]; | ||
h q[1]; | ||
x q[2]; | ||
x q[0]; | ||
x q[1]; | ||
h q[2]; | ||
cx q[0],q[2]; | ||
x q[0]; | ||
cx q[1],q[2]; | ||
h q[0]; | ||
x q[1]; | ||
h q[1]; | ||
""") | ||
|
||
chain = Chain(Gate(H, Locations(1)), | ||
Gate(H, Locations(2)), | ||
Gate(X, Locations(3)), | ||
Gate(X, Locations(1)), | ||
Gate(X, Locations(2)), | ||
Gate(H, Locations(3)), | ||
Ctrl(Gate(X, Locations(3)), | ||
CtrlLocations(1)), | ||
Gate(X, Locations(1)), | ||
Ctrl(Gate(X, Locations(3)), | ||
CtrlLocations(2)), | ||
Gate(H, Locations(1)), | ||
Gate(X, Locations(2)), | ||
Gate(H, Locations(2))) | ||
|
||
@test dj3.circuit == chain | ||
# FIXME should an empty IR print '1 ─ return nothing' ? | ||
# print(dj3) | ||
|
||
end | ||
|
||
end |
Oops, something went wrong.