Skip to content

Commit

Permalink
Invalidate parameters cache on circuit copy (backport #12619) (#12620)
Browse files Browse the repository at this point in the history
* Invalidate `parameters` cache on circuit copy (#12619)

Previously, the caching of the parameter view could persist between
copies of the circuit because it was part of the `copy.copy`.

(cherry picked from commit b6c6166)

# Conflicts:
#	qiskit/circuit/quantumcircuit.py
#	test/python/circuit/test_parameters.py

* Fix conflict

* Fix conflict in test

* Update test/python/circuit/test_parameters.py

---------

Co-authored-by: Jake Lishman <[email protected]>
Co-authored-by: Elena Peña Tapia <[email protected]>
  • Loading branch information
3 people authored Jun 21, 2024
1 parent 2b2be03 commit 35a4c12
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 @@ -2147,6 +2147,8 @@ def copy_empty_like(self, name: str | None = None) -> "QuantumCircuit":

cpy._calibrations = copy.deepcopy(self._calibrations)
cpy._metadata = copy.deepcopy(self._metadata)
# Invalidate parameters caching.
cpy._parameters = None

if name:
cpy.name = name
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 @@ -176,6 +176,29 @@ def test_get_parameters_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_bind_parameters_anonymously(self):
"""Test setting parameters by insertion order anonymously"""
phase = Parameter("phase")
Expand Down

0 comments on commit 35a4c12

Please sign in to comment.