Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Discard cache for standard gates in assign_parameters #13557

Merged
merged 4 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions crates/circuit/src/circuit_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1392,15 +1392,12 @@ impl CircuitData {
#[cfg(feature = "cache_pygates")]
{
// Standard gates can all rebuild their definitions, so if the
// cached py_op exists, update the `params` attribute and clear out
// any existing cache.
if let Some(borrowed) = previous.py_op.get() {
borrowed
.bind(py)
.getattr(params_attr)?
.set_item(parameter, new_param)?;
borrowed.bind(py).setattr("_definition", py.None())?
}
// cached py_op exists, discard it to prompt the instruction
// to rebuild its cached python gate upon request later on. This is
// done to avoid an unintentional duplicated reference to the same gate
// instance in python. For more information, see
// https://github.com/Qiskit/qiskit/issues/13504
previous.py_op.take();
}
} else {
// Track user operations we've seen so we can rebind their definitions.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
fixes:
- |
Fix incorrect behavior in :class:`.CircuitData` in which, upon parameter assignment,
we attempted to modify the cached operation inside of a ``PackedInstruction``. Now
we instead discard said cache prompting the ``PackedInstruction`` to build a new Python
operation should it be needed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to link the issue here, but let's do that in #13556.

17 changes: 17 additions & 0 deletions test/python/transpiler/test_basis_translator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit
from qiskit import transpile
from qiskit.circuit import Gate, Parameter, EquivalenceLibrary, Qubit, Clbit, Measure
from qiskit.circuit.equivalence_library import StandardEquivalenceLibrary as std_eq_lib
from qiskit.circuit.classical import expr, types
from qiskit.circuit.library import (
HGate,
Expand Down Expand Up @@ -481,6 +482,22 @@ def test_different_bits(self):
out = BasisTranslator(std_eqlib, basis).run(circuit_to_dag(base))
self.assertEqual(set(out.count_ops(recurse=True)), basis)

def test_correct_parameter_assignment(self):
"""Test correct parameter assignment from an equivalence during translation"""
rx_key = next(key for key in std_eq_lib.keys() if key.name == "rx")

# The circuit doesn't need to be parametric.
qc = QuantumCircuit(1)
qc.rx(0.5, 0)

BasisTranslator(
equivalence_library=std_eq_lib,
target_basis=["cx", "id", "rz", "sx", "x"],
)(qc)

inst = std_eq_lib._get_equivalences(rx_key)[0].circuit.data[0]
self.assertEqual(inst.params, inst.operation.params)


class TestUnrollerCompatability(QiskitTestCase):
"""Tests backward compatability with the Unroller pass.
Expand Down
Loading