cda-tum / mqt-qcec

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

Different behaviour with and without barriers #439

Open ritu-thombre99 opened 1 month ago

ritu-thombre99 commented 1 month ago

Environment information

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

Description

This is related to the earlier issue 424

I'm trying to run a circuit equivalence check for two particular circuits (Steane code). The segmentation fault was fixed by removing measurements of two qubits onto the same clbit.

But now, when I run the code with Barriers, it runs properly (the result being non_equivalent) However, when I run it after removing all the barriers I get the following error:

ValueError                                Traceback (most recent call last)
Cell In[204], line 3
      1 from mqt import qcec
      2 from qiskit import qasm2
----> 3 result = qcec.verify(qc1, qc2,
      4                      transform_dynamic_circuit=True,
      5                      backpropagate_output_permutation=True,
      6                      fix_output_permutation_mismatch=True,
      7                     )
      9 print(result.equivalence)

File /opt/anaconda3/envs/smt_compiler/lib/python3.11/site-packages/mqt/qcec/verify.py:59, in verify(circ1, circ2, configuration, **kwargs)
     56 ecm = EquivalenceCheckingManager(circ1, circ2, configuration)
     58 # execute the check
---> 59 ecm.run()
     61 # obtain the result
     62 return ecm.get_results()

ValueError: DD for non-unitary operation not available!

Circuit 1:

from qiskit import QuantumCircuit, qasm3, transpile, qasm2
import numpy as np
from qiskit.transpiler.passes import RemoveBarriers

qc1 = QuantumCircuit(10, 3)

qc1.x(5)
qc1.cx(0, 7)
qc1.cx(2, 7)
qc1.cx(4, 7)
qc1.cx(6, 7)

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

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

qc1.measure([7, 8, 9], [0, 1, 2])

qc1.draw('mpl')

image

Circuit 2:

output = """OPENQASM 3.0;
include "stdgates.inc";
bit[3] c;
qubit[15] q;
cx q[0], q[1];
cx q[4], q[5];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[5];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[1];
cx q[5], q[8];
cx q[10], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[3];
cx q[8], q[5];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[3], q[2];
cx q[5], q[8];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[3];
cx q[7], q[8];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
rx(pi) q[2];
cx q[3], q[11];
cx q[5], q[8];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[1];
cx q[8], q[9];
cx q[11], q[3];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[5];
cx q[3], q[11];
cx q[9], q[8];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[3], q[11];
cx q[5], q[2];
cx q[8], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[5];
cx q[7], q[8];
cx q[9], q[10];
cx q[11], q[3];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[2], q[1];
cx q[3], q[11];
cx q[5], q[8];
cx q[10], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[0], q[1];
cx q[2], q[5];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[1], q[0];
cx q[5], q[2];
c[0] = measure q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[0], q[1];
cx q[2], q[5];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[5], q[8];
c[1] = measure q[0];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[4], q[5];
cx q[8], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[5], q[4];
cx q[9], q[8];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[4], q[5];
cx q[8], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[10], q[9];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
cx q[9], q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
c[2] = measure q[10];
barrier q[0], q[1], q[2], q[3], q[4], q[5], q[6], q[7], q[8], q[9], q[10], q[11], q[12], q[13], q[14];
"""

qc2 = qasm3.loads(output)
# qc2 = RemoveBarriers()(qc2) # to remove the barriers
qc2.draw('mpl')

Circuit 2 without barriers: image Output: ValueError: DD for non-unitary operation not available!

Circuit 2 with barriers: image Output: not_equivalent

Expected behavior

Not equivalent even when running the code with circuits that do not have barriers

How to Reproduce

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

burgholzer commented 3 weeks ago

I can confirm that this is a bug in how we eliminate measurements at the end of the circuit before we perform the equivalence check. The barriers after the measurements in the circuit prevent the optimiser to remove the measurements and the equivalence checker, then, can't handle them.

This should be a pretty easy fix here: https://github.com/cda-tum/mqt-core/blob/5be1c3ec4efb773d0330298621704e876afa7c16/src/circuit_optimizer/CircuitOptimizer.cpp#L468-L570

On vacation right now, but can look at that once I am back. Maybe @pehamTom has some time until then?