epiqc / ScaffCC

Compilation, analysis and optimization framework for the Scaffold quantum programming language.
BSD 2-Clause "Simplified" License
188 stars 53 forks source link

Wrong QASM output for Teleportation circuit #28

Open vadym-kl opened 5 years ago

vadym-kl commented 5 years ago

The code below

// Prepares (|00> + |11>)/Sqrt(2) given input qubits are both |0>
module PrepareEntangledPair( qbit a, qbit b ) {
    H(a);
    CNOT(a,b);
}

// Un-prepares (|00> + |11>)/Sqrt(2) given input qubits are both |0>
module PrepareEntangledPairAdjoint( qbit a, qbit b ) {
    CNOT(a,b);
    H(a);
}

module Teleport( qbit msg, qbit here, qbit there ) {
    PrepareEntangledPair(here,there);
    PrepareEntangledPairAdjoint(msg,here);
    if( MeasZ(msg) ) { Z(there); }
    if( MeasZ(here) ) { X(there); }
}

int main() {
    // We assume that newly allocated qubits are in |0> state
    qbit q[3];

    // Set the first qubit to |+>
    PrepX(q[0], 0);
    Teleport(q[0],q[1],q[2]);

    // Measure third qubit in X basis
    if( MeasX(q[2]) ) { return 1; } else { return 0; }
}

Produces the following QASM file :

qubit q0
qubit q1
qubit q2
PrepX q0
H q1
CNOT q1,q2
CNOT q0,q1
H q0
MeasZ q0
Z q2
MeasZ q1
X q2
MeasX q2

The QASM was obtained by running scaffold.sh -f teleport.scaffold on epiqc/scaffcc Docker image.

cuhrazatee commented 4 years ago

What is the expected output?

bamarsha commented 4 years ago

I'm not sure what the flat QASM (scaffold.sh -f) output should be exactly, but the OpenQASM (scaffold.sh -b) output has a similar problem:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
h q[0];
h q[1];
cx q[1],q[2];
cx q[0],q[1];
h q[0];
measure q[0] -> ;
z q[2];
measure q[1] -> ;
x q[2];
h q[2];
measure q[2] -> ;

The measurement results are not assigned correctly, and z q[2] and x q[2], which should be conditioned on the results, are applied unconditionally. I would expect something like:

OPENQASM 2.0;
include "qelib1.inc";
qreg q[3];
h q[0];
h q[1];
cx q[1],q[2];
cx q[0],q[1];
h q[0];
measure q[0] -> m1;
if (m1 == 1) z q[2];
measure q[1] -> m2;
if (m2 == 1) x q[2];
h q[2];
measure q[2] -> m3;