Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ElePT committed Nov 1, 2024
1 parent c3a2573 commit cbd0973
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 51 deletions.
2 changes: 2 additions & 0 deletions qiskit/transpiler/passes/synthesis/high_level_synthesis.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ def __init__(
self._basis_gates = basis_gates
self._min_qubits = min_qubits

# include cases where target exists with no basis gates, or the basis gates
# are an empty list
self._top_level_only = (self._basis_gates is None or len(self._basis_gates) == 0) and (
self._target is None or len(self._target.operation_names) == 0
)
Expand Down
13 changes: 12 additions & 1 deletion qiskit/transpiler/preset_passmanagers/builtin_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,9 @@ def _opt_control(property_set):
)
if optimization_level == 1:
# Steps for optimization level 1

# If there are no basis gates (None/empty list), don't run
# Optimize1qGatesDecomposition
if (
pass_manager_config.basis_gates is not None
and len(pass_manager_config.basis_gates) > 0
Expand All @@ -569,6 +572,7 @@ def _opt_control(property_set):
]
else:
_opt = []

_opt += [
InverseCancellation(
[
Expand All @@ -589,6 +593,10 @@ def _opt_control(property_set):
]

elif optimization_level == 2:
# Steps for optimization level 2

# If there are no basis gates (None/empty list), don't run
# Optimize1qGatesDecomposition
if (
pass_manager_config.basis_gates is not None
and len(pass_manager_config.basis_gates) > 0
Expand All @@ -613,7 +621,8 @@ def _opt_control(property_set):
approximation_degree=pass_manager_config.approximation_degree,
),
]

# If there are no basis gates (None/empty list), don't run
# Optimize1qGatesDecomposition or UnitarySynthesis
if (
pass_manager_config.basis_gates is not None
and len(pass_manager_config.basis_gates) > 0
Expand Down Expand Up @@ -656,6 +665,8 @@ def _unroll_condition(property_set):
if optimization_level == 3:
optimization.append(_minimum_point_check)
elif optimization_level == 2:
# If there are no basis gates (None/empty list), don't run
# UnitarySynthesis
if (
pass_manager_config.basis_gates is not None
and len(pass_manager_config.basis_gates) > 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,11 @@ def generate_preset_pass_manager(
and timing_constraints is None
)
# If it's an edge case => do not build target
_skip_target = (
target is None
and backend is None
# and (basis_gates is None or coupling_map is None or instruction_durations is not None)
and (instruction_durations is not None)
)
# NOTE (1.3.0): we are skipping the target in the case where
# instruction_durations is provided without additional constraints
# instead of providing a target-based alternative because the argument
# will be removed in 2.0 as part of the Pulse deprecation efforts.
_skip_target = target is None and backend is None and instruction_durations is not None

# Resolve loose constraints case-by-case against backend constraints.
# The order of priority is loose constraints > backend.
Expand Down
1 change: 0 additions & 1 deletion qiskit/transpiler/preset_passmanagers/level2.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
else:
layout = None
routing = None

translation = plugin_manager.get_passmanager_stage(
"translation", translation_method, pass_manager_config, optimization_level=2
)
Expand Down
1 change: 0 additions & 1 deletion qiskit/transpiler/preset_passmanagers/level3.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
optimization = plugin_manager.get_passmanager_stage(
"optimization", optimization_method, pass_manager_config, optimization_level=3
)

if (coupling_map and not coupling_map.is_symmetric) or (
target is not None and target.get_non_global_operation_names(strict_direction=True)
):
Expand Down
22 changes: 19 additions & 3 deletions qiskit/transpiler/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ def build_coupling_map(self, two_q_gate=None, filter_idle_qubits=False):
if self._coupling_graph is None:
self._build_coupling_graph()

# if there is no connectivity constraints in the coupling graph treat it as not
# if there are no connectivity constraints in the coupling graph, treat it as not
# existing and return
if self._coupling_graph is not None:
cmap = CouplingMap()
Expand Down Expand Up @@ -1068,6 +1068,10 @@ def from_configuration(
qubit_properties = qubit_props_list_from_props(properties=backend_properties)

if basis_gates is None:
# The Target class requires basis_gates.
# If there are no basis_gates, we can't build a proper Target instance,
# but we can generate a "pseudo" target that holds connectivity constraints
# and is compatible with our transpilation pipeline
if num_qubits is None and coupling_map is not None:
num_qubits = len(coupling_map.graph)
target = FakeTarget(
Expand Down Expand Up @@ -1323,7 +1327,12 @@ def target_to_backend_properties(target: Target):


class FakeTarget(Target):
"""Fake target that only contains a connectivity constraint."""
"""
Pseudo-target class for internal use in the transpilation pipeline.
Differently to the :class:`.Target` class, this preudo-target is initialized
with a `coupling_map` argument that allows to store connectivity constraints
without basis gates.
"""

def __init__(self, coupling_map=None, **kwargs):
super().__init__(**kwargs)
Expand All @@ -1333,4 +1342,11 @@ def build_coupling_map(self, two_q_gate=None, filter_idle_qubits=False):
return self._coupling_map

def instruction_supported(self, *args, **kwargs):
return True
"""Checks whether an instruction is supported by the
Target based on instruction name and qargs. Note that if there are no
basis gates in the Target, this method will always return ``True``.
"""
if len(self.operation_names) == 0:
return True
else:
return super().instruction_supported(*args, **kwargs)
16 changes: 2 additions & 14 deletions test/python/compiler/test_transpiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2097,8 +2097,7 @@ def _visit_block(circuit, qubit_mapping=None):
qubit_mapping={qubit: index for index, qubit in enumerate(transpiled.qubits)},
)

# @data(1, 2, 3)
@data(3)
@data(1, 2, 3)
def test_transpile_identity_circuit_no_target(self, opt_level):
"""Test circuit equivalent to identity is optimized away for all optimization levels >0.
Expand Down Expand Up @@ -2198,14 +2197,6 @@ def test_barrier_not_output_input_preservered(self, opt_level):
@combine(opt_level=[0, 1, 2, 3])
def test_transpile_annotated_ops(self, opt_level):
"""Test transpilation of circuits with annotated operations."""
passes = []
kwargss = []

def callback_func(**kwargs):
t_pass = kwargs["pass_"].name()
kwargss.append(kwargs)
passes.append(t_pass)

qc = QuantumCircuit(3)
qc.append(AnnotatedOperation(SGate(), InverseModifier()), [0])
qc.append(AnnotatedOperation(XGate(), ControlModifier(1)), [1, 2])
Expand All @@ -2214,10 +2205,7 @@ def callback_func(**kwargs):
expected.sdg(0)
expected.cx(1, 2)
expected.h(2)
transpiled = transpile(
qc, optimization_level=opt_level, seed_transpiler=42, callback=callback_func
)
print("Callback out:", passes)
transpiled = transpile(qc, optimization_level=opt_level, seed_transpiler=42)
self.assertNotIn("annotated", transpiled.count_ops().keys())
self.assertEqual(Operator(qc), Operator(transpiled))
self.assertEqual(Operator(qc), Operator(expected))
Expand Down
17 changes: 3 additions & 14 deletions test/python/transpiler/test_preset_passmanagers.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,7 @@ def circuit_2532():
class TestPresetPassManager(QiskitTestCase):
"""Test preset passmanagers work as expected."""

# @combine(level=[0, 1, 2, 3], name="level{level}")
@combine(level=[3], name="level{level}")
@combine(level=[0, 1, 2, 3], name="level{level}")
def test_no_coupling_map_with_sabre(self, level):
"""Test that coupling_map can be None with Sabre (level={level})"""
q = QuantumRegister(2, name="q")
Expand Down Expand Up @@ -145,13 +144,7 @@ def test_no_basis_gates(self, level):
circuit.h(q[0])
circuit.cz(q[0], q[1])

def callback_func(**kwargs):
t_pass = kwargs["pass_"].name()
print("callback", t_pass)

result = transpile(
circuit, basis_gates=None, optimization_level=level, callback=callback_func
)
result = transpile(circuit, basis_gates=None, optimization_level=level)
self.assertEqual(result, circuit)

def test_level0_keeps_reset(self):
Expand Down Expand Up @@ -1271,11 +1264,7 @@ def test_size_optimization(self, level):
qc.cx(7, 6)
qc.cx(6, 7)

def callback_func(**kwargs):
t_pass = kwargs["pass_"].name()
print("callback", t_pass)

circ = transpile(qc, optimization_level=level, callback=callback_func).decompose()
circ = transpile(qc, optimization_level=level).decompose()

circ_data = circ.data
free_qubits = {0, 1, 2, 3}
Expand Down
11 changes: 0 additions & 11 deletions test/utils/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,17 +324,6 @@ def setUp(self):
self.useFixture(fixtures.MonkeyPatch("sys.stderr", stderr))
self.useFixture(fixtures.LoggerFixture(nuke_handlers=False, level=None))

# a dummy setting config to make sure it does not intervene
# with the test runner environment. See https://github.com/Qiskit/qiskit/pull/12463
self._mock_setting = unittest.mock.patch.dict(
os.environ, {"QISKIT_SETTINGS": "dummy_setting.conf"}
)
self._mock_setting.start()

def tearDown(self):
super().tearDown()
self._mock_setting.stop()


def dicts_almost_equal(dict1, dict2, delta=None, places=None, default_value=0):
"""Test if two dictionaries with numeric values are almost equal.
Expand Down

0 comments on commit cbd0973

Please sign in to comment.