diff --git a/crates/accelerate/src/equivalence.rs b/crates/accelerate/src/equivalence.rs index dfa338fba45a..5e7da30f108b 100644 --- a/crates/accelerate/src/equivalence.rs +++ b/crates/accelerate/src/equivalence.rs @@ -37,7 +37,7 @@ use rustworkx_core::petgraph::{ use qiskit_circuit::circuit_data::CircuitData; use qiskit_circuit::circuit_instruction::OperationFromPython; -use qiskit_circuit::imports::{ImportOnceCell, QUANTUM_CIRCUIT}; +use qiskit_circuit::imports::{PYDIGRAPH, QUANTUM_CIRCUIT}; use qiskit_circuit::operations::Param; use qiskit_circuit::operations::{Operation, OperationRef}; use qiskit_circuit::packed_instruction::PackedOperation; @@ -46,7 +46,6 @@ mod exceptions { use pyo3::import_exception_bound; import_exception_bound! {qiskit.circuit.exceptions, CircuitError} } -pub static PYDIGRAPH: ImportOnceCell = ImportOnceCell::new("rustworkx", "PyDiGraph"); // Custom Structs @@ -605,7 +604,7 @@ impl EquivalenceLibrary { raise_if_param_mismatch(py, params, equivalent_circuit.0.unsorted_parameters(py)?)?; let key: Key = Key::from_operation(gate); let equiv = Equivalence { - circuit: equivalent_circuit.clone(), + circuit: CircuitFromPython(equivalent_circuit.0.copy(py, true, false)?), params: params.into(), }; diff --git a/crates/circuit/src/imports.rs b/crates/circuit/src/imports.rs index 67ae9f85897f..b56ddb941697 100644 --- a/crates/circuit/src/imports.rs +++ b/crates/circuit/src/imports.rs @@ -74,6 +74,7 @@ pub static PARAMETER_EXPRESSION: ImportOnceCell = ImportOnceCell::new("qiskit.circuit.parameterexpression", "ParameterExpression"); pub static PARAMETER_VECTOR: ImportOnceCell = ImportOnceCell::new("qiskit.circuit.parametervector", "ParameterVector"); +pub static PYDIGRAPH: ImportOnceCell = ImportOnceCell::new("rustworkx", "PyDiGraph"); pub static QUANTUM_CIRCUIT: ImportOnceCell = ImportOnceCell::new("qiskit.circuit.quantumcircuit", "QuantumCircuit"); pub static SINGLETON_GATE: ImportOnceCell = diff --git a/releasenotes/notes/fix-equivalence-copy-205adf94f0380219.yaml b/releasenotes/notes/fix-equivalence-copy-205adf94f0380219.yaml new file mode 100644 index 000000000000..d99b97967ba5 --- /dev/null +++ b/releasenotes/notes/fix-equivalence-copy-205adf94f0380219.yaml @@ -0,0 +1,6 @@ +--- +fixes: + - | + Add missing calls to `copy` to the :class:`.Parameter` and :class:`.CircuitData` instances + being added to an `Equivalence` when calling :meth:`.EquivalenceLibrary.add_equivalence` in + :class:`.EquivalenceLibrary`. diff --git a/test/python/transpiler/test_basis_translator.py b/test/python/transpiler/test_basis_translator.py index 820c4f241a1e..75907239d836 100644 --- a/test/python/transpiler/test_basis_translator.py +++ b/test/python/transpiler/test_basis_translator.py @@ -14,6 +14,7 @@ """Test the BasisTranslator pass""" import os +from pickle import loads, dumps from numpy import pi import scipy @@ -21,6 +22,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, @@ -481,6 +483,29 @@ 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_equivalence_library_serialization(self): + """Test correct serialization of the EquivalenceLibrart that the BasisTranslator + depends on.""" + pass_ = BasisTranslator( + equivalence_library=std_eq_lib, target_basis=["cx", "id", "rz", "sx", "x"] + ) + + # Add a parameter a which we will share between circuits + param = Parameter("a") + gate = RXGate(param) + + qc = QuantumCircuit(1) + qc.append(gate, [0]) + + # Before serialization, should not fail. + first = pass_.run(circuit_to_dag(qc)) + + # After serialization, should not fail. + pass_ = BasisTranslator( + equivalence_library=loads(dumps(std_eq_lib)), target_basis=["cx", "id", "rz", "sx", "x"] + ) + self.assertEqual(first, pass_.run(circuit_to_dag(qc))) + class TestUnrollerCompatability(QiskitTestCase): """Tests backward compatability with the Unroller pass.