From 269c26fd0552836db54f27d511e07167f58d7990 Mon Sep 17 00:00:00 2001 From: gadial Date: Mon, 11 Nov 2024 15:21:08 +0200 Subject: [PATCH] Fixes a bug with the compilation of controlled gates (#2251) --- qiskit_aer/backends/aer_compiler.py | 8 +++--- ...trolled_gate_compile-c94fb7c41fa961db.yaml | 5 ++++ .../backends/aer_simulator/test_circuit.py | 28 ++++++++++++++++++- 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/fix_controlled_gate_compile-c94fb7c41fa961db.yaml diff --git a/qiskit_aer/backends/aer_compiler.py b/qiskit_aer/backends/aer_compiler.py index 846eb10052..561e586353 100644 --- a/qiskit_aer/backends/aer_compiler.py +++ b/qiskit_aer/backends/aer_compiler.py @@ -920,17 +920,17 @@ def _assemble_op( if ctrl_state_pos > 0: # Add x gates for ctrl qubits which state=0 ctrl_state = int(name[ctrl_state_pos+2:len(name)]) - for i in range(len(qubits)): + for i in range(len(qubits)-1): if (ctrl_state >> i) & 1 == 0: - qubits_i = [qubits[len(qubits) - 1 - i]] + qubits_i = [qubits[i]] aer_circ.gate("x", qubits_i, params, [], conditional_reg, aer_cond_expr, label if label else "x") num_of_aer_ops += 1 aer_circ.gate(gate_name, qubits, params, [], conditional_reg, aer_cond_expr, label if label else gate_name) - for i in range(len(qubits)): + for i in range(len(qubits)-1): if (ctrl_state >> i) & 1 == 0: - qubits_i = [qubits[len(qubits) - 1 - i]] + qubits_i = [qubits[i]] aer_circ.gate("x", qubits_i, params, [], conditional_reg, aer_cond_expr, label if label else "x") num_of_aer_ops += 1 diff --git a/releasenotes/notes/fix_controlled_gate_compile-c94fb7c41fa961db.yaml b/releasenotes/notes/fix_controlled_gate_compile-c94fb7c41fa961db.yaml new file mode 100644 index 0000000000..4c00851fb8 --- /dev/null +++ b/releasenotes/notes/fix_controlled_gate_compile-c94fb7c41fa961db.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes a bug in the compilation of circuits with controlled gates that resulted + in adding X gates on the incorrect qubits. diff --git a/test/terra/backends/aer_simulator/test_circuit.py b/test/terra/backends/aer_simulator/test_circuit.py index 42367b67ab..1ec1f39136 100644 --- a/test/terra/backends/aer_simulator/test_circuit.py +++ b/test/terra/backends/aer_simulator/test_circuit.py @@ -18,10 +18,12 @@ import numpy as np from qiskit import ClassicalRegister, QuantumCircuit, QuantumRegister, assemble from qiskit.circuit.gate import Gate -from qiskit.circuit.library.standard_gates import HGate +from qiskit.circuit.library.standard_gates import HGate, XGate, ZGate +from qiskit.quantum_info import Statevector from test.terra.reference import ref_algorithms from test.terra.backends.simulator_test_case import SimulatorTestCase, supported_methods +from qiskit_aer.backends import StatevectorSimulator @ddt @@ -259,3 +261,27 @@ def _define(self): self.fail("do not reach here") except Exception as e: self.assertTrue('"params" is incorrect length' in repr(e)) + + def test_controlled_gates(self): + """Test gates with control qubits""" + backend = StatevectorSimulator() + num_qubits = 4 + circuit = QuantumCircuit(num_qubits) + cccx = XGate().control(num_ctrl_qubits=3, label=None, ctrl_state="100") + circuit.x(2) + circuit.compose(cccx, range(num_qubits), inplace=True) + job = backend.run(circuit) + state = job.result().get_statevector() + ref_state = Statevector(circuit) + self.assertEqual(state, ref_state) + + num_qubits = 3 + circuit = QuantumCircuit(num_qubits) + cccz = ZGate().control(num_ctrl_qubits=2, label=None, ctrl_state="10") + circuit.x(1) + circuit.x(2) + circuit.compose(cccz, range(num_qubits), inplace=True) + job = backend.run(circuit) + state = job.result().get_statevector() + ref_state = Statevector(circuit) + self.assertEqual(state, ref_state)