Skip to content

Commit

Permalink
Invalidate parameters cache on circuit copy (#12619)
Browse files Browse the repository at this point in the history
Previously, the caching of the parameter view could persist between
copies of the circuit because it was part of the `copy.copy`.
  • Loading branch information
jakelishman authored Jun 20, 2024
1 parent 7d1731b commit b6c6166
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
2 changes: 2 additions & 0 deletions qiskit/circuit/quantumcircuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -3674,6 +3674,8 @@ def copy_empty_like(
cpy._data = CircuitData(
self._data.qubits, self._data.clbits, global_phase=self._data.global_phase
)
# Invalidate parameters caching.
cpy._parameters = None

cpy._calibrations = _copy.deepcopy(self._calibrations)
cpy._metadata = _copy.deepcopy(self._metadata)
Expand Down
7 changes: 7 additions & 0 deletions releasenotes/notes/fix-parameter-cache-05eac2f24477ccb8.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
The :attr:`.QuantumCircuit.parameters` attribute will now correctly be empty
when using :meth:`.QuantumCircuit.copy_empty_like` on a parametric circuit.
Previously, an internal cache would be copied over without invalidation.
Fix `#12617 <https://github.com/Qiskit/qiskit/issues/12617>`__.
23 changes: 23 additions & 0 deletions test/python/circuit/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,29 @@ def test_parameters_property_by_index(self):
for i, vi in enumerate(v):
self.assertEqual(vi, qc.parameters[i])

def test_parameters_property_independent_after_copy(self):
"""Test that any `parameters` property caching is invalidated after a copy operation."""
a = Parameter("a")
b = Parameter("b")
c = Parameter("c")

qc1 = QuantumCircuit(1)
qc1.rz(a, 0)
self.assertEqual(set(qc1.parameters), {a})

qc2 = qc1.copy_empty_like()
self.assertEqual(set(qc2.parameters), set())

qc3 = qc1.copy()
self.assertEqual(set(qc3.parameters), {a})
qc3.rz(b, 0)
self.assertEqual(set(qc3.parameters), {a, b})
self.assertEqual(set(qc1.parameters), {a})

qc1.rz(c, 0)
self.assertEqual(set(qc1.parameters), {a, c})
self.assertEqual(set(qc3.parameters), {a, b})

def test_get_parameter(self):
"""Test the `get_parameter` method."""
x = Parameter("x")
Expand Down

0 comments on commit b6c6166

Please sign in to comment.