diff --git a/qiskit/transpiler/passes/basis/basis_translator.py b/qiskit/transpiler/passes/basis/basis_translator.py index a1d3e7f0d39c..e7b9cbe05746 100644 --- a/qiskit/transpiler/passes/basis/basis_translator.py +++ b/qiskit/transpiler/passes/basis/basis_translator.py @@ -124,6 +124,8 @@ def __init__(self, equivalence_library, target_basis, target=None, min_qubits=0) for qarg in self._target[gate]: self._qargs_with_non_global_operation[qarg].add(gate) + print("inside pas: target:", target, "target basis", target_basis) + def run(self, dag): """Translate an input DAGCircuit to the target basis. @@ -153,6 +155,8 @@ def run(self, dag): source_basis, qargs_local_source_basis = self._extract_basis_target(dag, qarg_indices) target_basis = set(target_basis).union(basic_instrs) + print("final target basis", target_basis) + # If the source basis is a subset of the target basis and we have no circuit # instructions on qargs that have non-global operations there is nothing to # translate and we can exit early. diff --git a/qiskit/transpiler/passes/layout/vf2_utils.py b/qiskit/transpiler/passes/layout/vf2_utils.py index 037ccc37155d..dcf8a5e2a80f 100644 --- a/qiskit/transpiler/passes/layout/vf2_utils.py +++ b/qiskit/transpiler/passes/layout/vf2_utils.py @@ -201,7 +201,7 @@ def build_average_error_map(target, properties, coupling_map): # running the fallback heuristic if not built and target is not None and coupling_map is None: coupling_map = target.build_coupling_map() - if not built and coupling_map is not None: + if not built and coupling_map is not None and num_qubits is not None: for qubit in range(num_qubits): avg_map.add_error( (qubit, qubit), diff --git a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py index 68e266a09e70..fba1f26b71f9 100644 --- a/qiskit/transpiler/preset_passmanagers/builtin_plugins.py +++ b/qiskit/transpiler/preset_passmanagers/builtin_plugins.py @@ -14,6 +14,7 @@ import os +from qiskit.transpiler.target import FakeTarget from qiskit.transpiler.passes.optimization.split_2q_unitaries import Split2QUnitaries from qiskit.transpiler.passmanager import PassManager from qiskit.transpiler.exceptions import TranspilerError @@ -94,6 +95,7 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana or ( pass_manager_config.target is not None and pass_manager_config.target.build_coupling_map() is not None + and not isinstance(pass_manager_config.target, FakeTarget) ) ): init = common.generate_unroll_3q( @@ -113,6 +115,7 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana or ( pass_manager_config.target is not None and pass_manager_config.target.build_coupling_map() is not None + and not isinstance(pass_manager_config.target, FakeTarget) ) ): init += common.generate_unroll_3q( @@ -144,15 +147,17 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana ) elif optimization_level in {2, 3}: - init = common.generate_unroll_3q( - pass_manager_config.target, - pass_manager_config.basis_gates, - pass_manager_config.approximation_degree, - pass_manager_config.unitary_synthesis_method, - pass_manager_config.unitary_synthesis_plugin_config, - pass_manager_config.hls_config, - pass_manager_config.qubits_initially_zero, - ) + init = PassManager() + if not isinstance(pass_manager_config.target, FakeTarget): + init = common.generate_unroll_3q( + pass_manager_config.target, + pass_manager_config.basis_gates, + pass_manager_config.approximation_degree, + pass_manager_config.unitary_synthesis_method, + pass_manager_config.unitary_synthesis_plugin_config, + pass_manager_config.hls_config, + pass_manager_config.qubits_initially_zero, + ) if pass_manager_config.routing_method != "none": init.append(ElidePermutations()) init.append(RemoveDiagonalGatesBeforeMeasure()) @@ -176,7 +181,12 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana ) init.append(CommutativeCancellation()) init.append(Collect2qBlocks()) - init.append(ConsolidateBlocks()) + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + print("HERE??", pass_manager_config.basis_gates) + init.append(ConsolidateBlocks()) # If approximation degree is None that indicates a request to approximate up to the # error rates in the target. However, in the init stage we don't yet know the target # qubits being used to figure out the fidelity so just use the default fidelity parameter @@ -209,7 +219,7 @@ def pass_manager(self, pass_manager_config, optimization_level=None) -> PassMana class UnitarySynthesisPassManager(PassManagerStagePlugin): - """Plugin class for translation stage with :class:`~.BasisTranslator`""" + """Plugin class for translation stage with :class:`~.UnitarySynthesis`""" def pass_manager(self, pass_manager_config, optimization_level=None) -> PassManager: return common.generate_translation_passmanager( @@ -557,10 +567,18 @@ def _opt_control(property_set): ) if optimization_level == 1: # Steps for optimization level 1 - _opt = [ - Optimize1qGatesDecomposition( - basis=pass_manager_config.basis_gates, target=pass_manager_config.target - ), + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + _opt = [ + Optimize1qGatesDecomposition( + basis=pass_manager_config.basis_gates, target=pass_manager_config.target + ) + ] + else: + _opt = [] + _opt += [ InverseCancellation( [ CXGate(), @@ -580,60 +598,29 @@ def _opt_control(property_set): ] elif optimization_level == 2: - _opt = [ - Optimize1qGatesDecomposition( - basis=pass_manager_config.basis_gates, target=pass_manager_config.target - ), + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + _opt = [ + Optimize1qGatesDecomposition( + basis=pass_manager_config.basis_gates, target=pass_manager_config.target + ) + ] + else: + _opt = [] + _opt += [ CommutativeCancellation(target=pass_manager_config.target), ] elif optimization_level == 3: # Steps for optimization level 3 - _opt = [ - Collect2qBlocks(), - ConsolidateBlocks( - basis_gates=pass_manager_config.basis_gates, - target=pass_manager_config.target, - approximation_degree=pass_manager_config.approximation_degree, - ), - UnitarySynthesis( - pass_manager_config.basis_gates, - approximation_degree=pass_manager_config.approximation_degree, - coupling_map=pass_manager_config.coupling_map, - backend_props=pass_manager_config.backend_properties, - method=pass_manager_config.unitary_synthesis_method, - plugin_config=pass_manager_config.unitary_synthesis_plugin_config, - target=pass_manager_config.target, - ), - Optimize1qGatesDecomposition( - basis=pass_manager_config.basis_gates, target=pass_manager_config.target - ), - CommutativeCancellation(target=pass_manager_config.target), - ] - - def _opt_control(property_set): - return not property_set["optimization_loop_minimum_point"] - - else: - raise TranspilerError(f"Invalid optimization_level: {optimization_level}") - - unroll = translation.to_flow_controller() + _opt = [Collect2qBlocks()] - # Build nested Flow controllers - def _unroll_condition(property_set): - return not property_set["all_gates_in_basis"] - - # Check if any gate is not in the basis, and if so, run unroll passes - _unroll_if_out_of_basis = [ - GatesInBasis(pass_manager_config.basis_gates, target=pass_manager_config.target), - ConditionalController(unroll, condition=_unroll_condition), - ] - - if optimization_level == 3: - optimization.append(_minimum_point_check) - elif optimization_level == 2: - optimization.append( - [ - Collect2qBlocks(), + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + _opt += [ ConsolidateBlocks( basis_gates=pass_manager_config.basis_gates, target=pass_manager_config.target, @@ -648,8 +635,71 @@ def _unroll_condition(property_set): plugin_config=pass_manager_config.unitary_synthesis_plugin_config, target=pass_manager_config.target, ), + Optimize1qGatesDecomposition( + basis=pass_manager_config.basis_gates, target=pass_manager_config.target + ), ] - ) + + _opt += [CommutativeCancellation(target=pass_manager_config.target)] + + def _opt_control(property_set): + return not property_set["optimization_loop_minimum_point"] + + else: + raise TranspilerError(f"Invalid optimization_level: {optimization_level}") + + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + unroll = translation.to_flow_controller() + + # Build nested Flow controllers + def _unroll_condition(property_set): + return not property_set["all_gates_in_basis"] + + # Check if any gate is not in the basis, and if so, run unroll passes + _unroll_if_out_of_basis = [ + GatesInBasis( + pass_manager_config.basis_gates, target=pass_manager_config.target + ), + ConditionalController(unroll, condition=_unroll_condition), + ] + else: + _unroll_if_out_of_basis = [] + + if optimization_level == 3: + optimization.append(_minimum_point_check) + elif optimization_level == 2: + if ( + pass_manager_config.basis_gates is not None + and len(pass_manager_config.basis_gates) > 0 + ): + optimization.append( + [ + Collect2qBlocks(), + ConsolidateBlocks( + basis_gates=pass_manager_config.basis_gates, + target=pass_manager_config.target, + approximation_degree=pass_manager_config.approximation_degree, + ), + UnitarySynthesis( + pass_manager_config.basis_gates, + approximation_degree=pass_manager_config.approximation_degree, + coupling_map=pass_manager_config.coupling_map, + backend_props=pass_manager_config.backend_properties, + method=pass_manager_config.unitary_synthesis_method, + plugin_config=pass_manager_config.unitary_synthesis_plugin_config, + target=pass_manager_config.target, + ), + ] + ) + else: + optimization.append( + [ + Collect2qBlocks(), + ] + ) optimization.append(_depth_check + _size_check) else: optimization.append(_depth_check + _size_check) @@ -659,6 +709,8 @@ def _unroll_condition(property_set): else _opt + _unroll_if_out_of_basis + _depth_check + _size_check ) optimization.append(DoWhileController(opt_loop, do_while=_opt_control)) + print("opt", optimization._tasks) + return optimization else: return None diff --git a/qiskit/transpiler/preset_passmanagers/common.py b/qiskit/transpiler/preset_passmanagers/common.py index f01639ed115e..8b2a9137075c 100644 --- a/qiskit/transpiler/preset_passmanagers/common.py +++ b/qiskit/transpiler/preset_passmanagers/common.py @@ -453,6 +453,11 @@ def generate_translation_passmanager( Raises: TranspilerError: If the ``method`` kwarg is not a valid value """ + if basis_gates is None and ( + target is None or (target is not None and len(target.operation_names) == 0) + ): + return PassManager([]) + if method == "translator": unroll = [ # Use unitary synthesis for basis aware decomposition of diff --git a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py index 830618845352..8a73ab856541 100644 --- a/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +++ b/qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py @@ -283,7 +283,8 @@ def generate_preset_pass_manager( _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 (basis_gates is None or coupling_map is None or instruction_durations is not None) + and (instruction_durations is not None) ) # Resolve loose constraints case-by-case against backend constraints. @@ -344,7 +345,7 @@ def generate_preset_pass_manager( timing_constraints = target.timing_constraints() if backend_properties is None: with warnings.catch_warnings(): - # TODO this approach (target-to-properties) is going to be removed soon (1.3) in favor + # TODO: this approach (target-to-properties) is going to be removed soon (1.3) in favor # of backend-to-target approach # https://github.com/Qiskit/qiskit/pull/12850 warnings.filterwarnings( @@ -360,6 +361,7 @@ def generate_preset_pass_manager( approximation_degree = _parse_approximation_degree(approximation_degree) seed_transpiler = _parse_seed_transpiler(seed_transpiler) + print("target", target) pm_options = { "target": target, "basis_gates": basis_gates, @@ -398,6 +400,8 @@ def generate_preset_pass_manager( pm = level_3_pass_manager(pm_config) else: raise ValueError(f"Invalid optimization level {optimization_level}") + + # print("all", pm._tasks) return pm @@ -481,6 +485,7 @@ def _parse_coupling_map(coupling_map, backend): if isinstance(coupling_map, list) and all( isinstance(i, list) and len(i) == 2 for i in coupling_map ): + print("here") return CouplingMap(coupling_map) else: raise TranspilerError( diff --git a/qiskit/transpiler/preset_passmanagers/level0.py b/qiskit/transpiler/preset_passmanagers/level0.py index 58381b3db7a8..ca74f7e34de5 100644 --- a/qiskit/transpiler/preset_passmanagers/level0.py +++ b/qiskit/transpiler/preset_passmanagers/level0.py @@ -69,9 +69,12 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa layout = None routing = None - translation = plugin_manager.get_passmanager_stage( - "translation", translation_method, pass_manager_config, optimization_level=0 - ) + if basis_gates: + translation = plugin_manager.get_passmanager_stage( + "translation", translation_method, pass_manager_config, optimization_level=0 + ) + else: + translation = None if (coupling_map and not coupling_map.is_symmetric) or ( target is not None and target.get_non_global_operation_names(strict_direction=True) @@ -97,9 +100,12 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa init = plugin_manager.get_passmanager_stage( "init", init_method, pass_manager_config, optimization_level=0 ) - optimization = plugin_manager.get_passmanager_stage( - "optimization", optimization_method, pass_manager_config, optimization_level=0 - ) + if basis_gates or (target and not isinstance(target, FakeTarget)): + optimization = plugin_manager.get_passmanager_stage( + "optimization", optimization_method, pass_manager_config, optimization_level=0 + ) + else: + optimization = None return StagedPassManager( pre_init=pre_init, diff --git a/qiskit/transpiler/preset_passmanagers/level1.py b/qiskit/transpiler/preset_passmanagers/level1.py index 0a0b1c2a8e43..7548fc5c87ac 100644 --- a/qiskit/transpiler/preset_passmanagers/level1.py +++ b/qiskit/transpiler/preset_passmanagers/level1.py @@ -74,9 +74,12 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa layout = None routing = None - translation = plugin_manager.get_passmanager_stage( - "translation", translation_method, pass_manager_config, optimization_level=1 - ) + if basis_gates: + translation = plugin_manager.get_passmanager_stage( + "translation", translation_method, pass_manager_config, optimization_level=1 + ) + else: + translation = None if (coupling_map and not coupling_map.is_symmetric) or ( target is not None and target.get_non_global_operation_names(strict_direction=True) @@ -87,9 +90,12 @@ def level_1_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa else: pre_optimization = common.generate_pre_op_passmanager(remove_reset_in_zero=False) - optimization = plugin_manager.get_passmanager_stage( - "optimization", optimization_method, pass_manager_config, optimization_level=1 - ) + if basis_gates: + optimization = plugin_manager.get_passmanager_stage( + "optimization", optimization_method, pass_manager_config, optimization_level=1 + ) + else: + optimization = None sched = plugin_manager.get_passmanager_stage( "scheduling", scheduling_method, pass_manager_config, optimization_level=1 diff --git a/qiskit/transpiler/preset_passmanagers/level2.py b/qiskit/transpiler/preset_passmanagers/level2.py index b22743883fbe..1bd057577a30 100644 --- a/qiskit/transpiler/preset_passmanagers/level2.py +++ b/qiskit/transpiler/preset_passmanagers/level2.py @@ -73,9 +73,13 @@ 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 - ) + + if basis_gates: + translation = plugin_manager.get_passmanager_stage( + "translation", translation_method, pass_manager_config, optimization_level=2 + ) + else: + translation = None if (coupling_map and not coupling_map.is_symmetric) or ( target is not None and target.get_non_global_operation_names(strict_direction=True) @@ -86,9 +90,12 @@ def level_2_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa else: pre_optimization = common.generate_pre_op_passmanager(remove_reset_in_zero=False) - optimization = plugin_manager.get_passmanager_stage( - "optimization", optimization_method, pass_manager_config, optimization_level=2 - ) + if basis_gates: + optimization = plugin_manager.get_passmanager_stage( + "optimization", optimization_method, pass_manager_config, optimization_level=2 + ) + else: + optimization = None sched = plugin_manager.get_passmanager_stage( "scheduling", scheduling_method, pass_manager_config, optimization_level=2 diff --git a/qiskit/transpiler/preset_passmanagers/level3.py b/qiskit/transpiler/preset_passmanagers/level3.py index c1393a0b7c6e..17e7ae240db9 100644 --- a/qiskit/transpiler/preset_passmanagers/level3.py +++ b/qiskit/transpiler/preset_passmanagers/level3.py @@ -87,13 +87,17 @@ def level_3_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa layout = None routing = None - translation = plugin_manager.get_passmanager_stage( - "translation", translation_method, pass_manager_config, optimization_level=3 - ) + if basis_gates: + translation = plugin_manager.get_passmanager_stage( + "translation", translation_method, pass_manager_config, optimization_level=3 + ) + else: + translation = None 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) ): diff --git a/qiskit/transpiler/target.py b/qiskit/transpiler/target.py index da4a44a8ee02..0b3a04b51ce2 100644 --- a/qiskit/transpiler/target.py +++ b/qiskit/transpiler/target.py @@ -823,6 +823,7 @@ def build_coupling_map(self, two_q_gate=None, filter_idle_qubits=False): return cmap if self._coupling_graph is None: self._build_coupling_graph() + # if there is no connectivity constraints in the coupling graph treat it as not # existing and return if self._coupling_graph is not None: @@ -929,7 +930,7 @@ def __setstate__(self, state: tuple): @classmethod def from_configuration( cls, - basis_gates: list[str], + basis_gates: list[str] | None, num_qubits: int | None = None, coupling_map: CouplingMap | None = None, inst_map: InstructionScheduleMap | None = None, @@ -1022,20 +1023,34 @@ def from_configuration( qubit_properties = qubit_props_list_from_props(properties=backend_properties) - target = cls( - num_qubits=num_qubits, - dt=dt, - granularity=granularity, - min_length=min_length, - pulse_alignment=pulse_alignment, - acquire_alignment=acquire_alignment, - qubit_properties=qubit_properties, - concurrent_measurements=concurrent_measurements, - ) - name_mapping = get_standard_gate_name_mapping() - if custom_name_mapping is not None: - name_mapping.update(custom_name_mapping) - + if basis_gates is None: + if num_qubits is None and coupling_map is not None: + num_qubits = len(coupling_map.graph) + target = FakeTarget( + coupling_map=coupling_map, + num_qubits=num_qubits, + dt=dt, + granularity=granularity, + min_length=min_length, + pulse_alignment=pulse_alignment, + acquire_alignment=acquire_alignment, + qubit_properties=qubit_properties, + concurrent_measurements=concurrent_measurements, + ) + else: + target = cls( + num_qubits=num_qubits, + dt=dt, + granularity=granularity, + min_length=min_length, + pulse_alignment=pulse_alignment, + acquire_alignment=acquire_alignment, + qubit_properties=qubit_properties, + concurrent_measurements=concurrent_measurements, + ) + name_mapping = get_standard_gate_name_mapping() + if custom_name_mapping is not None: + name_mapping.update(custom_name_mapping) # While BackendProperties can also contain coupling information we # rely solely on CouplingMap to determine connectivity. This is because # in legacy transpiler usage (and implicitly in the BackendV1 data model) @@ -1043,38 +1058,40 @@ def from_configuration( # the properties is only used for error rate and duration population. # If coupling map is not specified we ignore the backend_properties if coupling_map is None: - for gate in basis_gates: - if gate not in name_mapping: - raise KeyError( - f"The specified basis gate: {gate} is not present in the standard gate " - "names or a provided custom_name_mapping" - ) - target.add_instruction(name_mapping[gate], name=gate) + if basis_gates is not None: + for gate in basis_gates: + if gate not in name_mapping: + raise KeyError( + f"The specified basis gate: {gate} is not present in the standard gate " + "names or a provided custom_name_mapping" + ) + target.add_instruction(name_mapping[gate], name=gate) else: one_qubit_gates = [] two_qubit_gates = [] global_ideal_variable_width_gates = [] # pylint: disable=invalid-name if num_qubits is None: num_qubits = len(coupling_map.graph) - for gate in basis_gates: - if gate not in name_mapping: - raise KeyError( - f"The specified basis gate: {gate} is not present in the standard gate " - "names or a provided custom_name_mapping" - ) - gate_obj = name_mapping[gate] - if gate_obj.num_qubits == 1: - one_qubit_gates.append(gate) - elif gate_obj.num_qubits == 2: - two_qubit_gates.append(gate) - elif inspect.isclass(gate_obj): - global_ideal_variable_width_gates.append(gate) - else: - raise TranspilerError( - f"The specified basis gate: {gate} has {gate_obj.num_qubits} " - "qubits. This constructor method only supports fixed width operations " - "with <= 2 qubits (because connectivity is defined on a CouplingMap)." - ) + if basis_gates is not None: + for gate in basis_gates: + if gate not in name_mapping: + raise KeyError( + f"The specified basis gate: {gate} is not present in the standard gate " + "names or a provided custom_name_mapping" + ) + gate_obj = name_mapping[gate] + if gate_obj.num_qubits == 1: + one_qubit_gates.append(gate) + elif gate_obj.num_qubits == 2: + two_qubit_gates.append(gate) + elif inspect.isclass(gate_obj): + global_ideal_variable_width_gates.append(gate) + else: + raise TranspilerError( + f"The specified basis gate: {gate} has {gate_obj.num_qubits} " + "qubits. This constructor method only supports fixed width operations " + "with <= 2 qubits (because connectivity is defined on a CouplingMap)." + ) for gate in one_qubit_gates: gate_properties: dict[tuple, InstructionProperties] = {} for qubit in range(num_qubits): @@ -1259,3 +1276,14 @@ def target_to_backend_properties(target: Target): return BackendProperties.from_dict(properties_dict) else: return None + + +class FakeTarget(Target): + """Fake target that only contains a connectivity constraint.""" + + def __init__(self, coupling_map=None, **kwargs): + super().__init__(**kwargs) + self._coupling_map = coupling_map + + def build_coupling_map(self, two_q_gate=None, filter_idle_qubits=False): + return self._coupling_map diff --git a/test/python/compiler/test_transpiler.py b/test/python/compiler/test_transpiler.py index 825dfd6bdfe7..1cc54b3252b4 100644 --- a/test/python/compiler/test_transpiler.py +++ b/test/python/compiler/test_transpiler.py @@ -2039,7 +2039,8 @@ def _visit_block(circuit, qubit_mapping=None): qubit_mapping={qubit: index for index, qubit in enumerate(transpiled.qubits)}, ) - @data(1, 2, 3) + # @data(1, 2, 3) + @data(3) def test_transpile_identity_circuit_no_target(self, opt_level): """Test circuit equivalent to identity is optimized away for all optimization levels >0. diff --git a/test/python/transpiler/test_preset_passmanagers.py b/test/python/transpiler/test_preset_passmanagers.py index b762d84032bb..18edd84bb657 100644 --- a/test/python/transpiler/test_preset_passmanagers.py +++ b/test/python/transpiler/test_preset_passmanagers.py @@ -91,7 +91,8 @@ def circuit_2532(): class TestPresetPassManager(QiskitTestCase): """Test preset passmanagers work as expected.""" - @combine(level=[0, 1, 2, 3], name="level{level}") + # @combine(level=[0, 1, 2, 3], name="level{level}") + @combine(level=[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") @@ -143,7 +144,14 @@ def test_no_basis_gates(self, level): circuit = QuantumCircuit(q) circuit.h(q[0]) circuit.cz(q[0], q[1]) - result = transpile(circuit, basis_gates=None, optimization_level=level) + + 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 + ) self.assertEqual(result, circuit) def test_level0_keeps_reset(self): @@ -1261,7 +1269,11 @@ def test_size_optimization(self, level): qc.cx(7, 6) qc.cx(6, 7) - circ = transpile(qc, optimization_level=level).decompose() + def callback_func(**kwargs): + t_pass = kwargs["pass_"].name() + print("callback", t_pass) + + circ = transpile(qc, optimization_level=level, callback=callback_func).decompose() circ_data = circ.data free_qubits = {0, 1, 2, 3} diff --git a/test/utils/base.py b/test/utils/base.py index dded6bbda2b2..0d614b319fc5 100644 --- a/test/utils/base.py +++ b/test/utils/base.py @@ -303,6 +303,17 @@ 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.