Skip to content

Commit

Permalink
Fix qpy for multiple controlled parametrized gates (#10758) (#10795)
Browse files Browse the repository at this point in the history
* Add exception for controlled gate

* Add reno

(cherry picked from commit ebb1197)

Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
  • Loading branch information
mergify[bot] and ElePT authored Sep 7, 2023
1 parent 946aa28 commit e4b0471
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 1 deletion.
6 changes: 5 additions & 1 deletion qiskit/qpy/binary_io/circuits.py
Original file line number Diff line number Diff line change
Expand Up @@ -540,14 +540,18 @@ def _write_instruction(file_obj, instruction, custom_operations, index_map):
)
or gate_class_name == "Gate"
or gate_class_name == "Instruction"
or gate_class_name == "ControlledGate"
or isinstance(instruction.operation, library.BlueprintCircuit)
):
if instruction.operation.name not in custom_operations:
custom_operations[instruction.operation.name] = instruction.operation
custom_operations_list.append(instruction.operation.name)
gate_class_name = instruction.operation.name

elif gate_class_name == "ControlledGate":
gate_class_name = instruction.operation.name + "_" + str(uuid.uuid4())
custom_operations[gate_class_name] = instruction.operation
custom_operations_list.append(gate_class_name)

elif isinstance(instruction.operation, library.PauliEvolutionGate):
gate_class_name = r"###PauliEvolutionGate_" + str(uuid.uuid4())
custom_operations[gate_class_name] = instruction.operation
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
fixes:
- |
Fixed a bug in QPY serialization (:mod:`qiskit.qpy`) where if a circuit contained
multiple instances of parametrized controlled gates of the same class (not custom),
the parameter values from the first instance were used to build the gate definitions
of subsequent instances. The gates were rendered correctly despite this bug because
the correct parameter values were stored, but not used to build the gates. Fixed
`#10735 <https://github.com/Qiskit/qiskit-terra/issues/10735>`__.
20 changes: 20 additions & 0 deletions test/python/circuit/test_circuit_load_from_qpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from qiskit.circuit.gate import Gate
from qiskit.circuit.library import (
XGate,
RYGate,
QFT,
QAOAAnsatz,
PauliEvolutionGate,
Expand Down Expand Up @@ -1310,6 +1311,25 @@ def _define(self) -> None:
self.assertEqual(qc.decompose(), new_circ.decompose())
self.assertDeprecatedBitProperties(qc, new_circ)

def test_multiple_controlled_gates(self):
"""Test multiple controlled gates with same name but different
parameter values.
Reproduce from: https://github.com/Qiskit/qiskit-terra/issues/10735
"""

qc = QuantumCircuit(3)
for i in range(3):
c2ry = RYGate(i + 1).control(2)
qc.append(c2ry, [i % 3, (i + 1) % 3, (i + 2) % 3])
qpy_file = io.BytesIO()
dump(qc, qpy_file)
qpy_file.seek(0)
new_circ = load(qpy_file)[0]
self.assertEqual(qc, new_circ)
self.assertEqual(qc.decompose(), new_circ.decompose())
self.assertDeprecatedBitProperties(qc, new_circ)

def test_load_with_loose_bits(self):
"""Test that loading from a circuit with loose bits works."""
qc = QuantumCircuit([Qubit(), Qubit(), Clbit()])
Expand Down

0 comments on commit e4b0471

Please sign in to comment.