QuantumBFS / YaoBlocksQASM.jl

YaoBlocks interface for OpenQASM
MIT License
2 stars 3 forks source link

qasm to blocks implementation #13

Open Sov-trotter opened 3 years ago

Sov-trotter commented 3 years ago

@Roger-luo I have written the initial macro. Thanks for you help in the issue I finally have some clarity. For now I have kept the generated function names to be same as that in the QASM spec(https://github.com/QuantumBFS/YaoTargetQASM.jl/blob/master/test/qelib1.inc).

Also for the single qubit unitary gates I have used the implementation here YaoBlocksQobj(https://github.com/QuantumBFS/YaoBlocksQobj.jl/pull/16)

Roger-luo commented 3 years ago

So this implementation is quite brute-force, it generates the right code, but not the correct implementation, and it doesn't support user defined gate statement in QASM, what I'm expecting is a transform between QASM AST (parsed by OpenQASM.jl) and a Julia Expr which is a function returns YaoBlocks. This is because YaoBlocks itself cannot define functions it relys on Julia's semantic.

To be more detailed, I'm expecting the following code to work

for toplevel QASM code

OPENQASM 2.0;
qreg qreg_1[1];
rz(0) qreg_1;
ry(0) qreg_1;
rz(1.5707963267948966) qreg_1;

should generate

function main(n)
    circuit = chain(n)
    push!(circuit, put(1=>rz(0)))
    push!(circuit, put(1=>ry(0)))
    push!(circuit, put(1=>rz(1.5707963267948966)))
    return circuit
end

and for gate routine

gate rx(theta) qreg_1 {
      rz(theta) qreg_1;
      ry(-1.5707963267948966) qreg_1;
      rz(1.5707963267948966) qreg_1;
}

should generate

function rx(n, theta)
     circuit = chain(n)
     push!(circuit, rz(n, theta))
     push!(circuit, ry(n, -1.5707963267948966))
     push!(circuit, rz(n, 1.5707963267948966))
     return circuit
end

this is kinda just a standard transform between two different ASTs, which should apply for almost any other languages. You only implemented what we called the intrinsics at the moment in this PR. And since QASM allows one to define multiple registers, you will need to fuse them together and remap the qubit address in the global register address like what I do here: https://github.com/QuantumBFS/YaoTargetQASM.jl/blob/master/src/frontend.jl#L21

but since you don't need to handle control flows and only the YaoBlocks compatible part this should be simpler than mine implementation over there.

Roger-luo commented 3 years ago

PS. you can decide the syntax of total number of qubits n yourself, it doesn't have to be the first argument, a prettier implementation could be using https://github.com/MasonProtter/LegibleLambdas.jl to curry the first argument, which defines the extra method

rx(theta) = @lambda(n -> rx(n, theta))

when you generate the function, consider https://expronicon.rogerluo.dev/dev/ which may make your life easier

Sov-trotter commented 3 years ago

Thanks for the review. I'll look into this.