Closed kdk closed 1 year ago
✅ Issue still reproducible as per the original author. The Code:
import qiskit as qk
qr = qk.QuantumRegister(2)
cr = qk.ClassicalRegister(1)
qc1 = qk.QuantumCircuit(qr, cr)
qc1.h(0).c_if(cr, 0)
qc1.h(1).c_if(cr, 0)
print(qc1)
qc2 = qk.QuantumCircuit(qr, cr)
qc2.h(1).c_if(cr, 0)
qc2.h(0).c_if(cr, 0)
print(qc2)
>>> qc1 == qc2
False
The output is still False when we compare both the circuits.
The two circuits given in this example are structurally different because of the data dependency flowing along bit 0; without an optimising compiler recognising that these are the same condition and that they can be merged into a single classical check, there's no practical way for the DAG comparison to see these two circuits as equal, because under the IR, they are different.
There's not entirely a problem with conditionals: if I instead make the circuits as
import qiskit as qk
qr = qk.QuantumRegister(2)
cr1 = qk.ClassicalRegister(1)
cr2 = qk.ClassicalRegister(1)
qc1 = qk.QuantumCircuit(qr, cr1, cr2)
qc1.h(0).c_if(cr1, 0)
qc1.h(1).c_if(cr2, 0)
print(qc1)
qc2 = qk.QuantumCircuit(qr, cr1, cr2)
qc2.h(1).c_if(cr2, 0)
qc2.h(0).c_if(cr1, 0)
print(qc2)
then we have qc1 == qc2
, despite the re-ordering of the circuits required.
I think that if we use "the bit can't have changed between the conditions" as a requirement, we're opening a separate can of worms - should two circuits compare equal if there's extra explicit quantum no-ops on some of its qubits too? It feels like we're getting into the realm of larger equivalence checkers at that point, which I think is a separate and larger issue than this one.
I propose to close this bug report as "not a bug", and fold its requests into a potential equivalence checker feature request (e.g. #761). In the interests of slimming the issues, I'll just close this pre-emptively, but feel free to re-open if you disagree with me.
The circuit identity check does not distinguish between classical wires used as cargs and classical wires used as conditionals, and so the following two circuits are marked as non-equivalent:
Since both gates use
c0
as a condition, and there is no gate between them which usesc0
as a carg, it should be possible to determine that the order of the two gates onc0
is not important. Ref.test.python.transpiler.test_cx_direction.TestCXDirection.test_preserves_conditions
.