From 6a97ae3794b8698f637d66fa5fa00697f168e8de Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 21 Jan 2021 12:11:20 -0500 Subject: [PATCH 1/2] Add unroll step to level2 passmanager optimization loop This commit adds the basis translation step to the level 2 preset passmanager's optimization loop. The level 2 optimization loop runs the commutative cancellation pass which use Rx and U1 gates as part of it's optimization step which may not be in the target basis gates. This can result in a gate outside of the target basis ended up in the output. To avoid this in a general manner we need to rely on the basis translation step because we can't write a pass to do the simplified rotation in a manner compatible with any basis (especially since the target basis could be using custom gates). Fixes #5644 --- .../transpiler/preset_passmanagers/level2.py | 2 +- .../transpiler/test_preset_passmanagers.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py index 6c265cdb40b8..76f9e48f7a38 100644 --- a/qiskit/transpiler/preset_passmanagers/level2.py +++ b/qiskit/transpiler/preset_passmanagers/level2.py @@ -206,7 +206,7 @@ def _opt_control(property_set): pm2.append(_direction_check) pm2.append(_direction, condition=_direction_condition) pm2.append(_reset) - pm2.append(_depth_check + _opt, do_while=_opt_control) + pm2.append(_depth_check + _opt + _unroll, do_while=_opt_control) if scheduling_method: pm2.append(_scheduling) diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py index 1116607e2508..ca7b2b38a72c 100644 --- a/test/python/transpiler/test_preset_passmanagers.py +++ b/test/python/transpiler/test_preset_passmanagers.py @@ -14,6 +14,8 @@ from test import combine from ddt import ddt, data +import numpy as np + from qiskit import QuantumCircuit, ClassicalRegister, QuantumRegister from qiskit.circuit import Qubit from qiskit.compiler import transpile, assemble @@ -85,6 +87,23 @@ def test_level0_keeps_reset(self): result = transpile(circuit, basis_gates=None, optimization_level=0) self.assertEqual(result, circuit) + def test_level2_respects_basis(self): + """Test that level2 with commutative cancellation respects basis""" + qc = QuantumCircuit(3) + qc.h(0) + qc.h(1) + qc.cp(np.pi/8,0,1) + qc.cp(np.pi/4,0,2) + result = transpile(qc, basis_gates=['id', 'rz', 'sx', 'x', 'cx'], + optimization_level=2) + + dag = circuit_to_dag(result) + op_nodes = [node.name for node in dag.topological_op_nodes()] + # Assert no u1 or rx gates from commutative cancellation end up in + # end up in the output since they're not in the target basis gates + self.assertNotIn('u1', op_nodes) + self.assertNotIn('u1', op_nodes) + @ddt class TestTranspileLevels(QiskitTestCase): From 3b4ef22038fbcb5ea6738a05dd87f7da59f64608 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 21 Jan 2021 13:50:15 -0500 Subject: [PATCH 2/2] Fix lint --- test/python/transpiler/test_preset_passmanagers.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py index ca7b2b38a72c..feeedd3e1eaf 100644 --- a/test/python/transpiler/test_preset_passmanagers.py +++ b/test/python/transpiler/test_preset_passmanagers.py @@ -92,8 +92,8 @@ def test_level2_respects_basis(self): qc = QuantumCircuit(3) qc.h(0) qc.h(1) - qc.cp(np.pi/8,0,1) - qc.cp(np.pi/4,0,2) + qc.cp(np.pi / 8, 0, 1) + qc.cp(np.pi / 4, 0, 2) result = transpile(qc, basis_gates=['id', 'rz', 'sx', 'x', 'cx'], optimization_level=2) @@ -102,7 +102,7 @@ def test_level2_respects_basis(self): # Assert no u1 or rx gates from commutative cancellation end up in # end up in the output since they're not in the target basis gates self.assertNotIn('u1', op_nodes) - self.assertNotIn('u1', op_nodes) + self.assertNotIn('rx', op_nodes) @ddt