From ad8ff03a01ebf0a7646f91bf89fc6d4a416e71eb Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Wed, 18 May 2022 16:37:14 -0400 Subject: [PATCH 1/2] Add string representation for PassManagerConfig This commit adds a new string representation to the PassManagerConfig class. When str() is run on a PassManagerConfig object it will return a string listing the values for all of the attributes in the class. --- qiskit/transpiler/passmanager_config.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/qiskit/transpiler/passmanager_config.py b/qiskit/transpiler/passmanager_config.py index 80f01f0cd078..7706f3e195b3 100644 --- a/qiskit/transpiler/passmanager_config.py +++ b/qiskit/transpiler/passmanager_config.py @@ -124,3 +124,24 @@ def from_backend(cls, backend, **pass_manager_options): res.target = backend.target return res + + def __str__(self): + return ( + "Pass Manager Config:\n" + f"\tinitial_layout: {self.initial_layout}\n" + f"\tbasis_gates: {self.basis_gates}\n" + f"\tinst_map: {self.inst_map}\n" + f"\tcoupling_map: {self.coupling_map}\n" + f"\tlayout_method: {self.layout_method}\n" + f"\trouting_method: {self.routing_method}\n" + f"\ttranslation_method: {self.translation_method}\n" + f"\tscheduling_method: {self.scheduling_method}\n" + f"\tinstruction_durations: {self.instruction_durations}\n" + f"\tbackend_properties: {self.backend_properties}\n" + f"\tapproximation_degree: {self.approximation_degree}\n" + f"\tseed_transpiler: {self.seed_transpiler}\n" + f"\ttiming_constraints: {self.timing_constraints}\n" + f"\tunitary_synthesis_method: {self.unitary_synthesis_method}\n" + f"\tunitary_synthesis_plugin_config: {self.unitary_synthesis_plugin_config}\n" + f"\ttarget: {self.target}\n" + ) From f1bcb578040754559556d20a3c61060cdc26f649 Mon Sep 17 00:00:00 2001 From: Matthew Treinish Date: Thu, 26 May 2022 10:17:33 -0400 Subject: [PATCH 2/2] Adjust tab indent and add tests This commit ensure that all entries under the pass manager config have a single tab indent and also adds a test to verify the output. --- qiskit/transpiler/passmanager_config.py | 17 ++- .../transpiler/test_passmanager_config.py | 112 ++++++++++++++++++ 2 files changed, 125 insertions(+), 4 deletions(-) diff --git a/qiskit/transpiler/passmanager_config.py b/qiskit/transpiler/passmanager_config.py index 7706f3e195b3..b472bc87d5d1 100644 --- a/qiskit/transpiler/passmanager_config.py +++ b/qiskit/transpiler/passmanager_config.py @@ -12,6 +12,8 @@ """Pass Manager Configuration class.""" +import pprint + from qiskit.transpiler.coupling import CouplingMap from qiskit.transpiler.instruction_durations import InstructionDurations @@ -126,22 +128,29 @@ def from_backend(cls, backend, **pass_manager_options): return res def __str__(self): + newline = "\n" + newline_tab = "\n\t" + if self.backend_properties is not None: + backend_props = pprint.pformat(self.backend_properties.to_dict()) + backend_props = backend_props.replace(newline, newline_tab) + else: + backend_props = str(None) return ( "Pass Manager Config:\n" f"\tinitial_layout: {self.initial_layout}\n" f"\tbasis_gates: {self.basis_gates}\n" - f"\tinst_map: {self.inst_map}\n" + f"\tinst_map: {str(self.inst_map).replace(newline, newline_tab)}\n" f"\tcoupling_map: {self.coupling_map}\n" f"\tlayout_method: {self.layout_method}\n" f"\trouting_method: {self.routing_method}\n" f"\ttranslation_method: {self.translation_method}\n" f"\tscheduling_method: {self.scheduling_method}\n" - f"\tinstruction_durations: {self.instruction_durations}\n" - f"\tbackend_properties: {self.backend_properties}\n" + f"\tinstruction_durations: {str(self.instruction_durations).replace(newline, newline_tab)}\n" + f"\tbackend_properties: {backend_props}\n" f"\tapproximation_degree: {self.approximation_degree}\n" f"\tseed_transpiler: {self.seed_transpiler}\n" f"\ttiming_constraints: {self.timing_constraints}\n" f"\tunitary_synthesis_method: {self.unitary_synthesis_method}\n" f"\tunitary_synthesis_plugin_config: {self.unitary_synthesis_plugin_config}\n" - f"\ttarget: {self.target}\n" + f"\ttarget: {str(self.target).replace(newline, newline_tab)}\n" ) diff --git a/test/python/transpiler/test_passmanager_config.py b/test/python/transpiler/test_passmanager_config.py index 9873a2e805fd..a03f6f8bb876 100644 --- a/test/python/transpiler/test_passmanager_config.py +++ b/test/python/transpiler/test_passmanager_config.py @@ -17,6 +17,7 @@ from qiskit.test import QiskitTestCase from qiskit.test.mock import FakeMelbourne from qiskit.test.mock.backends.almaden.fake_almaden import FakeAlmaden +from qiskit.test.mock.backends import FakeArmonk from qiskit.transpiler.coupling import CouplingMap from qiskit.transpiler.passmanager_config import PassManagerConfig @@ -68,3 +69,114 @@ def test_invalid_user_option(self): """Test from_backend() with an invalid user option.""" with self.assertRaises(TypeError): PassManagerConfig.from_backend(FakeMelbourne(), invalid_option=None) + + def test_str(self): + """Test string output.""" + pm_config = PassManagerConfig.from_backend(FakeArmonk()) + # For testing remove instruction schedule map it's str output is non-deterministic + # based on hash seed + pm_config.inst_map = None + str_out = str(pm_config) + expected = """Pass Manager Config: + initial_layout: None + basis_gates: ['id', 'rz', 'sx', 'x'] + inst_map: None + coupling_map: + layout_method: None + routing_method: None + translation_method: None + scheduling_method: None + instruction_durations: id(0,): 7.111111111111111e-08 s + rz(0,): 0.0 s + sx(0,): 7.111111111111111e-08 s + x(0,): 7.111111111111111e-08 s + measure(0,): 4.977777777777777e-06 s + + backend_properties: {'backend_name': 'ibmq_armonk', + 'backend_version': '2.4.3', + 'gates': [{'gate': 'id', + 'name': 'id0', + 'parameters': [{'date': datetime.datetime(2021, 3, 15, 0, 38, 15, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_error', + 'unit': '', + 'value': 0.00019769550670970334}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_length', + 'unit': 'ns', + 'value': 71.11111111111111}], + 'qubits': [0]}, + {'gate': 'rz', + 'name': 'rz0', + 'parameters': [{'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_error', + 'unit': '', + 'value': 0}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_length', + 'unit': 'ns', + 'value': 0}], + 'qubits': [0]}, + {'gate': 'sx', + 'name': 'sx0', + 'parameters': [{'date': datetime.datetime(2021, 3, 15, 0, 38, 15, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_error', + 'unit': '', + 'value': 0.00019769550670970334}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_length', + 'unit': 'ns', + 'value': 71.11111111111111}], + 'qubits': [0]}, + {'gate': 'x', + 'name': 'x0', + 'parameters': [{'date': datetime.datetime(2021, 3, 15, 0, 38, 15, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_error', + 'unit': '', + 'value': 0.00019769550670970334}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'gate_length', + 'unit': 'ns', + 'value': 71.11111111111111}], + 'qubits': [0]}], + 'general': [], + 'last_update_date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'qubits': [[{'date': datetime.datetime(2021, 3, 15, 0, 36, 17, tzinfo=tzoffset(None, -14400)), + 'name': 'T1', + 'unit': 'us', + 'value': 182.6611165336624}, + {'date': datetime.datetime(2021, 3, 14, 0, 33, 45, tzinfo=tzoffset(None, -18000)), + 'name': 'T2', + 'unit': 'us', + 'value': 237.8589220110257}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'frequency', + 'unit': 'GHz', + 'value': 4.971852852405576}, + {'date': datetime.datetime(2021, 3, 15, 0, 40, 24, tzinfo=tzoffset(None, -14400)), + 'name': 'anharmonicity', + 'unit': 'GHz', + 'value': -0.34719293148282626}, + {'date': datetime.datetime(2021, 3, 15, 0, 35, 20, tzinfo=tzoffset(None, -14400)), + 'name': 'readout_error', + 'unit': '', + 'value': 0.02400000000000002}, + {'date': datetime.datetime(2021, 3, 15, 0, 35, 20, tzinfo=tzoffset(None, -14400)), + 'name': 'prob_meas0_prep1', + 'unit': '', + 'value': 0.0234}, + {'date': datetime.datetime(2021, 3, 15, 0, 35, 20, tzinfo=tzoffset(None, -14400)), + 'name': 'prob_meas1_prep0', + 'unit': '', + 'value': 0.024599999999999955}, + {'date': datetime.datetime(2021, 3, 15, 0, 35, 20, tzinfo=tzoffset(None, -14400)), + 'name': 'readout_length', + 'unit': 'ns', + 'value': 4977.777777777777}]]} + approximation_degree: None + seed_transpiler: None + timing_constraints: None + unitary_synthesis_method: default + unitary_synthesis_plugin_config: None + target: None +""" + self.assertEqual(str_out, expected)