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

qasm to blocks implementation #13

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

qasm to blocks implementation #13

wants to merge 2 commits into from

Conversation

Sov-trotter
Copy link
Member

No description provided.

@Sov-trotter Sov-trotter marked this pull request as draft May 29, 2021 11:56
@Sov-trotter Sov-trotter linked an issue May 29, 2021 that may be closed by this pull request
@Sov-trotter
Copy link
Member Author

Sov-trotter commented May 29, 2021

@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(QuantumBFS/YaoBlocksQobj.jl#16)

@Roger-luo
Copy link
Member

Roger-luo commented May 29, 2021

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
Copy link
Member

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
Copy link
Member Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

support QASM -> Blocks
2 participants