From bcd98951eaf90e206a1f2d265ceea7f96e8b73fa Mon Sep 17 00:00:00 2001 From: Tan Jun Liang <43441314+poig@users.noreply.github.com> Date: Fri, 17 Jun 2022 05:20:11 +0800 Subject: [PATCH] decompose(reps=1) repeating decompose (#8142) * decompose() repeat decompose https://github.com/Qiskit/qiskit-terra/issues/8139#issue-1261865139 summary: ``` circuit.decompose(reps = 5) # repeat decompose 5 times ``` * add reps parameters forgot * Update quantumcircuit.py * Update qiskit/circuit/quantumcircuit.py Co-authored-by: Julien Gacon * Update quantumcircuit.py * Update quantumcircuit.py * Update blueprintcircuit.py * Update blueprintcircuit.py * fixing some bug fixed also: https://github.com/Qiskit/qiskit-terra/issues/5974#issue-823183659 but need to fix label gate repeat decompose not working. * Update decompose.py * Update decompose.py * fix https://github.com/Qiskit/qiskit-terra/issues/5974 * Update decompose.py * test_case & fix decompose repeat work with multi_gate * Update test_decompose.py * Update test_decompose.py * Update test_decompose.py * Update decompose.py * Update decompose.py * Update decompose.py * Update test_decompose.py * fix lint * Update decompose.py * fix lint * change back preset * changing back * Update quantumcircuit.py * original version * release_note * Update releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml Co-authored-by: Julien Gacon * Update add-parameters-to-decompose-5a541d1b5afe2c68.yaml * Update add-parameters-to-decompose-5a541d1b5afe2c68.yaml * Update releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml Co-authored-by: Jake Lishman * Update releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml Co-authored-by: Jake Lishman Co-authored-by: Julien Gacon Co-authored-by: Jake Lishman Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- qiskit/circuit/library/blueprintcircuit.py | 4 ++-- qiskit/circuit/quantumcircuit.py | 12 +++++++++--- ...parameters-to-decompose-5a541d1b5afe2c68.yaml | 16 ++++++++++++++++ test/python/transpiler/test_decompose.py | 6 ++++++ 4 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml diff --git a/qiskit/circuit/library/blueprintcircuit.py b/qiskit/circuit/library/blueprintcircuit.py index 3711793df1..da2d6348c7 100644 --- a/qiskit/circuit/library/blueprintcircuit.py +++ b/qiskit/circuit/library/blueprintcircuit.py @@ -91,10 +91,10 @@ class BlueprintCircuit(QuantumCircuit, ABC): self._build() return super().data - def decompose(self, gates_to_decompose=None): + def decompose(self, gates_to_decompose=None, reps=1): if not self._is_built: self._build() - return super().decompose(gates_to_decompose) + return super().decompose(gates_to_decompose, reps) def draw(self, *args, **kwargs): if not self._is_built: diff --git a/qiskit/circuit/quantumcircuit.py b/qiskit/circuit/quantumcircuit.py index d5d19f1303..7acb5d10f9 100644 --- a/qiskit/circuit/quantumcircuit.py +++ b/qiskit/circuit/quantumcircuit.py @@ -1502,6 +1502,7 @@ class QuantumCircuit: gates_to_decompose: Optional[ Union[Type[Gate], Sequence[Type[Gate]], Sequence[str], str] ] = None, + reps: int = 1, ) -> "QuantumCircuit": """Call a decomposition pass on this circuit, to decompose one level (shallow decompose). @@ -1509,6 +1510,9 @@ class QuantumCircuit: Args: gates_to_decompose (str or list(str)): optional subset of gates to decompose. Defaults to all gates in circuit. + reps (int): Optional number of times the circuit should be decomposed. + For instance, ``reps=2`` equals calling ``circuit.decompose().decompose()``. + can decompose specific gates specific time Returns: QuantumCircuit: a circuit one level decomposed @@ -1518,9 +1522,11 @@ class QuantumCircuit: from qiskit.converters.circuit_to_dag import circuit_to_dag from qiskit.converters.dag_to_circuit import dag_to_circuit - pass_ = Decompose(gates_to_decompose=gates_to_decompose) - decomposed_dag = pass_.run(circuit_to_dag(self)) - return dag_to_circuit(decomposed_dag) + pass_ = Decompose(gates_to_decompose) + dag = circuit_to_dag(self) + for _ in range(reps): + dag = pass_.run(dag) + return dag_to_circuit(dag) def _check_compatible_regs(self, rhs: "QuantumCircuit") -> None: """Raise exception if the circuits are defined on incompatible registers""" diff --git a/releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml b/releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml new file mode 100644 index 0000000000..06f2f2e102 --- /dev/null +++ b/releasenotes/notes/add-parameters-to-decompose-5a541d1b5afe2c68.yaml @@ -0,0 +1,16 @@ +features: + - | + Added a new optional argument, ``reps``, to + :meth:`.QuantumCircuit.decompose`, which allows + repeated decomposition of the circuit. For example:: + + from qiskit import QuantumCircuit + + circuit = QuantumCircuit(1) + circuit.ry(0.5, 0) + + # Equivalent to circuit.decompose().decompose() + circuit.decompose(reps=2) + + # decompose 2 times, but only RY gate 2 times and R gate 1 times + circuit.decompose(gates_to_decompose=['ry','r'], reps=2) diff --git a/test/python/transpiler/test_decompose.py b/test/python/transpiler/test_decompose.py index a82e1b49bc..1a0aaf4a4b 100644 --- a/test/python/transpiler/test_decompose.py +++ b/test/python/transpiler/test_decompose.py @@ -294,3 +294,9 @@ class TestDecompose(QiskitTestCase): decomposed = circuit.decompose() self.assertEqual(len(decomposed.data), 0) + + def test_decompose_reps(self): + """Test decompose reps function is decomposed correctly""" + decom_circ = self.complex_circuit.decompose(reps=2) + decomposed = self.complex_circuit.decompose().decompose() + self.assertEqual(decom_circ, decomposed)