Fix registerless bit conditions in circuit_to_instruction (#7395)

* Fix registerless bit conditions in circuit_to_instruction

This version of the change is stable for backports, but a more thorough
refactor of `circuit_to_instruction` is in order to support multiple
registers, overlapping registers and remove the creation of unnecessary
registers.

* Fix ambiguous cross-reference

* Be consistent in writing conditions

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>

Co-authored-by: Kevin Krsulich <kevin@krsulich.net>
This commit is contained in:
Jake Lishman 2021-12-13 20:20:21 +00:00 committed by GitHub
parent 309bfb173e
commit 3562e268c7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 9 deletions

View File

@ -113,14 +113,7 @@ def circuit_to_instruction(circuit, parameter_map=None, equivalence_library=None
if condition: if condition:
reg, val = condition reg, val = condition
if isinstance(reg, Clbit): if isinstance(reg, Clbit):
idx = 0 rule[0].condition = (clbit_map[reg], val)
for creg in circuit.cregs:
if reg not in creg:
idx += creg.size
else:
cond_reg = creg
break
rule[0].condition = (c[idx + list(cond_reg).index(reg)], val)
elif reg.size == c.size: elif reg.size == c.size:
rule[0].condition = (c, val) rule[0].condition = (c, val)
else: else:

View File

@ -0,0 +1,14 @@
---
fixes:
- |
Fixed conversion of :class:`.QuantumCircuit`\ s with classical conditions on
single, registerless :class:`.Clbit` \s to :class:`~.circuit.Instruction`\ s when
using the :func:`.circuit_to_instruction` function or the
:meth:`.QuantumCircuit.to_instruction` method. For example, the following
will now work::
from qiskit.circuit import QuantumCircuit, Qubit, Clbit
qc = QuantumCircuit([Qubit(), Clbit()])
qc.h(0).c_if(qc.clbits[0], 0)
qc.to_instruction()

View File

@ -16,7 +16,7 @@ import unittest
from qiskit.converters import circuit_to_instruction from qiskit.converters import circuit_to_instruction
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit.circuit import Qubit, Clbit from qiskit.circuit import Qubit, Clbit, Instruction
from qiskit.circuit import Parameter from qiskit.circuit import Parameter
from qiskit.test import QiskitTestCase from qiskit.test import QiskitTestCase
from qiskit.exceptions import QiskitError from qiskit.exceptions import QiskitError
@ -186,6 +186,23 @@ class TestCircuitToInstruction(QiskitTestCase):
self.assertEqual(inst.definition[2][0].params, [gamma, phi, 0]) self.assertEqual(inst.definition[2][0].params, [gamma, phi, 0])
self.assertEqual(str(inst.definition[3][0].params[0]), "gamma + phi") self.assertEqual(str(inst.definition[3][0].params[0]), "gamma + phi")
def test_registerless_classical_bits(self):
"""Test that conditions on registerless classical bits can be handled during the conversion.
Regression test of gh-7394."""
expected = QuantumCircuit([Qubit(), Clbit()])
expected.h(0).c_if(expected.clbits[0], 0)
test = circuit_to_instruction(expected)
self.assertIsInstance(test, Instruction)
self.assertIsInstance(test.definition, QuantumCircuit)
self.assertEqual(len(test.definition.data), 1)
test_instruction, _, _ = test.definition.data[0]
expected_instruction, _, _ = expected.data[0]
self.assertIs(type(test_instruction), type(expected_instruction))
self.assertEqual(test_instruction.condition, (test.definition.clbits[0], 0))
if __name__ == "__main__": if __name__ == "__main__":
unittest.main(verbosity=2) unittest.main(verbosity=2)