cda-tum / mqt-qcec

MQT QCEC - A tool for Quantum Circuit Equivalence Checking
https://mqt.readthedocs.io/projects/qcec
MIT License
95 stars 21 forks source link

Different behaviours when measuring all qubits and measuring some qubits #440

Open ritu-thombre99 opened 3 months ago

ritu-thombre99 commented 3 months ago

Environment information

OS: MacOS MQT version: 2.6.0 Compiler: C++

Description

Running Steane code for bit-flip detection. When transpiled using Qiskit transpile and custom backend:

  1. If all qubits are measured, the transpiled circuit is equivalent to the original circuit
  2. When measuring only some qubits, the transpiled circuit is NOT equivalent to the original circuit

Backend

from qiskit.providers.fake_provider import GenericBackendV2
from qiskit.visualization import plot_error_map
from qiskit.transpiler import CouplingMap
connection=[
        (0, 1),
        (1, 2),
        (2, 3),
        (2, 5),
        (4, 5),
        (5, 6),
        (5, 8),
        (7, 8),
        (8, 9),
        (9, 10),
        (3, 11),
        (7, 12),
    ]
cmap = CouplingMap([list([elem[0],elem[1]]) for elem in connection])
backend = GenericBackendV2(num_qubits=13, coupling_map = connection)
plot_error_map(backend)

image

Measure all:

Input Circuit:

from qiskit import QuantumCircuit, transpile

qc = QuantumCircuit(10)

# bit flip on qubit 5
qc.x(5)
qc.cx(0, 7)
qc.cx(2, 7)
qc.cx(4, 7)
qc.cx(6, 7)

qc.cx(1, 8)
qc.cx(2, 8)
qc.cx(5, 8)
qc.cx(6, 8)

qc.cx(3, 9)
qc.cx(4, 9)
qc.cx(5, 9)
qc.cx(6, 9)

qc.measure_all()
qc.draw('mpl')

image

Transpiled Circuit

qc_final = transpile(qc, backend)
qc_final.draw('mpl')

image

Equivalence:

from mqt import qcec
result = qcec.verify(qc, qc_final,)
print(result.equivalence)

Output: equivalent

Measure 3 qubits:

Input Circuit:

from qiskit import QuantumCircuit, transpile
qc = QuantumCircuit(10,3)

# bit flip on qubit 5
qc.x(5)
qc.cx(0, 7)
qc.cx(2, 7)
qc.cx(4, 7)
qc.cx(6, 7)

qc.cx(1, 8)
qc.cx(2, 8)
qc.cx(5, 8)
qc.cx(6, 8)

qc.cx(3, 9)
qc.cx(4, 9)
qc.cx(5, 9)
qc.cx(6, 9)

qc.measure([7, 8, 9], [0, 1, 2])
qc.draw('mpl')

image

Transpiled Circuit

qc_final = transpile(qc, backend)
qc_final.draw('mpl')

image

Equivalence:

Code 1:

from mqt import qcec
result = qcec.verify(qc, qc_final,)
print(result.equivalence)

Output:

not_equivalent

[QCEC] Warning: at least one of the circuits has garbage qubits, but partial equivalence checking is turned off. In order to take into account the garbage qubits, enable partial equivalence checking. Consult the documentation for moreinformation.equivalent 

Code 2:

from mqt import qcec
result = qcec.verify(qc, qc_final,backpropagate_output_permutation=True)
print(result.equivalence)

Output:

not_equivalent

[QCEC] Warning: circuits have different number of primary inputs! Proceed with caution!
[QCEC] Warning: at least one of the circuits has garbage qubits, but partial equivalence checking is turned off. In order to take into account the garbage qubits, enable partial equivalence checking. Consult the documentation for moreinformation.

Code 3:

from mqt import qcec
result = qcec.verify(qc, qc_final,
                     backpropagate_output_permutation=True,
                     fix_output_permutation_mismatch=True,
                    )

print(result.equivalence)

Output:

not_equivalent

[QCEC] Warning: circuits have different number of primary inputs! Proceed with caution!
Uncorrected mismatch in output qubits!
Uncorrected mismatch in output qubits!
Uncorrected mismatch in output qubits!
[QCEC] Warning: at least one of the circuits has garbage qubits, but partial equivalence checking is turned off. In order to take into account the garbage qubits, enable partial equivalence checking. Consult the documentation for moreinformation.

Code 4:

from mqt import qcec
result = qcec.verify(qc, qc_final,
                     fix_output_permutation_mismatch=True,
                    )

print(result.equivalence)

Output:

not_equivalent

Uncorrected mismatch in output qubits!
Uncorrected mismatch in output qubits!
Uncorrected mismatch in output qubits!
[QCEC] Warning: at least one of the circuits has garbage qubits, but partial equivalence checking is turned off. In order to take into account the garbage qubits, enable partial equivalence checking. Consult the documentation for moreinformation.
1

Expected behavior

Should be equivalent in both cases.

How to Reproduce

Import qiskit, mqt.qcec and the run the code blocks mentioned above.

burgholzer commented 3 months ago

Have you actually tried the suggestion from the very first warning message:

[QCEC] Warning: at least one of the circuits has garbage qubits, but partial equivalence checking is turned off. In order to take into account the garbage qubits, enable partial equivalence checking. Consult the documentation for more information.

See https://mqt.readthedocs.io/projects/qcec/en/latest/library/configuration/Functionality.html#mqt.qcec.Configuration.Functionality.check_partial_equivalence

When measuring all qubits, there is perfect information on where the individual qubits of the circuit end up at the end of the circuit. This allows the equivalence check to succeed.

When only parts of the circuit are measured, this becomes a much tougher problem because one has to make sure that the "right" qubits are being compared and the other qubits are ignored for the equivalence check.

Maybe you could try with the above suggestion and come back here with the results. Happy to investigate further, once these results are here.