qiskit 1.1.2__cp38-abi3-win32.whl → 1.2.0__cp38-abi3-win32.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +27 -24
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +1 -1
- qiskit/assembler/assemble_circuits.py +107 -64
- qiskit/assembler/assemble_schedules.py +5 -12
- qiskit/assembler/disassemble.py +10 -1
- qiskit/circuit/__init__.py +6 -3
- qiskit/circuit/_classical_resource_map.py +5 -5
- qiskit/circuit/_utils.py +0 -13
- qiskit/circuit/add_control.py +1 -1
- qiskit/circuit/annotated_operation.py +23 -1
- qiskit/circuit/classical/expr/expr.py +4 -4
- qiskit/circuit/classical/expr/visitors.py +1 -1
- qiskit/circuit/classical/types/__init__.py +1 -1
- qiskit/circuit/classical/types/types.py +2 -2
- qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
- qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
- qiskit/circuit/classicalfunction/utils.py +1 -1
- qiskit/circuit/classicalregister.py +1 -1
- qiskit/circuit/commutation_checker.py +83 -35
- qiskit/circuit/controlflow/_builder_utils.py +1 -1
- qiskit/circuit/controlflow/builder.py +10 -6
- qiskit/circuit/controlflow/if_else.py +2 -2
- qiskit/circuit/controlflow/switch_case.py +1 -1
- qiskit/circuit/delay.py +1 -1
- qiskit/circuit/duration.py +2 -2
- qiskit/circuit/equivalence.py +5 -7
- qiskit/circuit/gate.py +11 -8
- qiskit/circuit/instruction.py +31 -13
- qiskit/circuit/instructionset.py +2 -5
- qiskit/circuit/library/__init__.py +2 -1
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
- qiskit/circuit/library/basis_change/__init__.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +40 -6
- qiskit/circuit/library/blueprintcircuit.py +3 -5
- qiskit/circuit/library/data_preparation/__init__.py +9 -2
- qiskit/circuit/library/data_preparation/initializer.py +8 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
- qiskit/circuit/library/generalized_gates/isometry.py +8 -8
- qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
- qiskit/circuit/library/generalized_gates/permutation.py +8 -9
- qiskit/circuit/library/generalized_gates/uc.py +3 -3
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
- qiskit/circuit/library/generalized_gates/unitary.py +13 -11
- qiskit/circuit/library/graph_state.py +1 -1
- qiskit/circuit/library/hamiltonian_gate.py +1 -2
- qiskit/circuit/library/hidden_linear_function.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
- qiskit/circuit/library/n_local/n_local.py +4 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
- qiskit/circuit/library/n_local/two_local.py +1 -1
- qiskit/circuit/library/overlap.py +11 -5
- qiskit/circuit/library/pauli_evolution.py +7 -3
- qiskit/circuit/library/standard_gates/dcx.py +3 -0
- qiskit/circuit/library/standard_gates/ecr.py +3 -0
- qiskit/circuit/library/standard_gates/global_phase.py +3 -0
- qiskit/circuit/library/standard_gates/h.py +13 -5
- qiskit/circuit/library/standard_gates/i.py +3 -0
- qiskit/circuit/library/standard_gates/iswap.py +3 -0
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
- qiskit/circuit/library/standard_gates/p.py +14 -9
- qiskit/circuit/library/standard_gates/r.py +3 -0
- qiskit/circuit/library/standard_gates/rx.py +21 -6
- qiskit/circuit/library/standard_gates/rxx.py +40 -1
- qiskit/circuit/library/standard_gates/ry.py +21 -6
- qiskit/circuit/library/standard_gates/ryy.py +40 -1
- qiskit/circuit/library/standard_gates/rz.py +22 -6
- qiskit/circuit/library/standard_gates/rzx.py +40 -1
- qiskit/circuit/library/standard_gates/rzz.py +41 -2
- qiskit/circuit/library/standard_gates/s.py +77 -0
- qiskit/circuit/library/standard_gates/swap.py +12 -5
- qiskit/circuit/library/standard_gates/sx.py +14 -5
- qiskit/circuit/library/standard_gates/t.py +5 -0
- qiskit/circuit/library/standard_gates/u.py +22 -7
- qiskit/circuit/library/standard_gates/u1.py +8 -3
- qiskit/circuit/library/standard_gates/u2.py +3 -0
- qiskit/circuit/library/standard_gates/u3.py +22 -7
- qiskit/circuit/library/standard_gates/x.py +156 -92
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
- qiskit/circuit/library/standard_gates/y.py +6 -1
- qiskit/circuit/library/standard_gates/z.py +8 -1
- qiskit/circuit/operation.py +1 -1
- qiskit/circuit/parameter.py +9 -10
- qiskit/circuit/parameterexpression.py +16 -13
- qiskit/circuit/parametertable.py +1 -190
- qiskit/circuit/parametervector.py +1 -1
- qiskit/circuit/quantumcircuit.py +395 -387
- qiskit/circuit/quantumcircuitdata.py +3 -5
- qiskit/circuit/quantumregister.py +1 -1
- qiskit/circuit/random/__init__.py +1 -1
- qiskit/circuit/random/utils.py +175 -26
- qiskit/circuit/register.py +5 -7
- qiskit/circuit/singleton.py +3 -3
- qiskit/circuit/tools/pi_check.py +4 -4
- qiskit/compiler/assembler.py +95 -24
- qiskit/compiler/scheduler.py +2 -2
- qiskit/compiler/transpiler.py +42 -128
- qiskit/converters/circuit_to_dag.py +4 -6
- qiskit/converters/circuit_to_gate.py +4 -8
- qiskit/converters/circuit_to_instruction.py +5 -17
- qiskit/converters/dag_to_circuit.py +2 -6
- qiskit/dagcircuit/collect_blocks.py +2 -2
- qiskit/dagcircuit/dagcircuit.py +190 -187
- qiskit/dagcircuit/dagdependency.py +4 -4
- qiskit/dagcircuit/dagdependency_v2.py +4 -4
- qiskit/dagcircuit/dagdepnode.py +1 -1
- qiskit/dagcircuit/dagnode.py +66 -157
- qiskit/passmanager/flow_controllers.py +1 -1
- qiskit/passmanager/passmanager.py +3 -3
- qiskit/primitives/__init__.py +1 -5
- qiskit/primitives/backend_estimator.py +25 -15
- qiskit/primitives/backend_estimator_v2.py +31 -7
- qiskit/primitives/backend_sampler.py +21 -12
- qiskit/primitives/backend_sampler_v2.py +12 -3
- qiskit/primitives/base/base_estimator.py +31 -4
- qiskit/primitives/base/base_primitive.py +2 -2
- qiskit/primitives/base/base_result.py +2 -2
- qiskit/primitives/base/base_sampler.py +26 -2
- qiskit/primitives/base/estimator_result.py +2 -2
- qiskit/primitives/base/sampler_result.py +2 -2
- qiskit/primitives/containers/__init__.py +0 -1
- qiskit/primitives/containers/bindings_array.py +2 -2
- qiskit/primitives/containers/bit_array.py +108 -10
- qiskit/primitives/containers/shape.py +3 -3
- qiskit/primitives/estimator.py +9 -2
- qiskit/primitives/primitive_job.py +1 -1
- qiskit/primitives/sampler.py +10 -3
- qiskit/primitives/statevector_estimator.py +5 -3
- qiskit/primitives/statevector_sampler.py +11 -5
- qiskit/primitives/utils.py +16 -0
- qiskit/providers/backend.py +15 -6
- qiskit/providers/backend_compat.py +7 -4
- qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
- qiskit/providers/basic_provider/basic_simulator.py +33 -25
- qiskit/providers/fake_provider/fake_backend.py +10 -3
- qiskit/providers/fake_provider/fake_openpulse_2q.py +157 -149
- qiskit/providers/fake_provider/fake_openpulse_3q.py +228 -220
- qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
- qiskit/providers/fake_provider/fake_qasm_backend.py +7 -2
- qiskit/providers/fake_provider/generic_backend_v2.py +514 -68
- qiskit/providers/models/__init__.py +48 -11
- qiskit/providers/models/backendconfiguration.py +50 -4
- qiskit/providers/models/backendproperties.py +13 -2
- qiskit/providers/models/pulsedefaults.py +10 -11
- qiskit/providers/options.py +13 -13
- qiskit/providers/providerutils.py +3 -1
- qiskit/pulse/configuration.py +8 -12
- qiskit/pulse/instruction_schedule_map.py +3 -5
- qiskit/pulse/instructions/acquire.py +7 -8
- qiskit/pulse/instructions/instruction.py +2 -3
- qiskit/pulse/library/samplers/decorators.py +5 -9
- qiskit/pulse/library/symbolic_pulses.py +4 -7
- qiskit/pulse/library/waveform.py +2 -5
- qiskit/pulse/macros.py +11 -6
- qiskit/pulse/parser.py +8 -10
- qiskit/pulse/schedule.py +9 -17
- qiskit/pulse/transforms/alignments.py +1 -3
- qiskit/pulse/utils.py +1 -2
- qiskit/qasm/libs/stdgates.inc +35 -28
- qiskit/qasm2/__init__.py +7 -7
- qiskit/qasm2/export.py +5 -9
- qiskit/qasm2/parse.py +1 -1
- qiskit/qasm3/ast.py +9 -25
- qiskit/qasm3/exporter.py +582 -479
- qiskit/qasm3/printer.py +7 -16
- qiskit/qobj/common.py +10 -0
- qiskit/qobj/converters/lo_config.py +9 -0
- qiskit/qobj/converters/pulse_instruction.py +13 -6
- qiskit/qobj/pulse_qobj.py +69 -15
- qiskit/qobj/qasm_qobj.py +72 -20
- qiskit/qobj/utils.py +9 -0
- qiskit/qpy/__init__.py +1 -1
- qiskit/qpy/binary_io/circuits.py +8 -5
- qiskit/qpy/binary_io/schedules.py +1 -1
- qiskit/qpy/binary_io/value.py +3 -3
- qiskit/qpy/interface.py +3 -2
- qiskit/qpy/type_keys.py +2 -2
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
- qiskit/quantum_info/operators/channel/superop.py +2 -2
- qiskit/quantum_info/operators/channel/transformations.py +1 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
- qiskit/quantum_info/operators/dihedral/random.py +6 -3
- qiskit/quantum_info/operators/measures.py +2 -2
- qiskit/quantum_info/operators/op_shape.py +12 -20
- qiskit/quantum_info/operators/operator.py +14 -21
- qiskit/quantum_info/operators/predicates.py +1 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +3 -3
- qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
- qiskit/quantum_info/operators/symplectic/random.py +1 -1
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +15 -17
- qiskit/quantum_info/quaternion.py +1 -1
- qiskit/quantum_info/states/densitymatrix.py +5 -8
- qiskit/quantum_info/states/stabilizerstate.py +128 -37
- qiskit/quantum_info/states/statevector.py +4 -8
- qiskit/result/counts.py +2 -2
- qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -2
- qiskit/result/mitigation/utils.py +1 -3
- qiskit/result/models.py +17 -16
- qiskit/result/result.py +15 -20
- qiskit/scheduler/lowering.py +2 -2
- qiskit/synthesis/__init__.py +2 -1
- qiskit/synthesis/clifford/__init__.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
- qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
- qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +2 -2
- qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
- qiskit/synthesis/evolution/lie_trotter.py +46 -19
- qiskit/synthesis/evolution/product_formula.py +111 -55
- qiskit/synthesis/evolution/qdrift.py +40 -10
- qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
- qiskit/synthesis/linear/__init__.py +1 -0
- qiskit/synthesis/linear/cnot_synth.py +22 -96
- qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
- qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
- qiskit/synthesis/permutation/permutation_full.py +5 -29
- qiskit/synthesis/permutation/permutation_lnn.py +2 -24
- qiskit/synthesis/permutation/permutation_utils.py +2 -59
- qiskit/synthesis/qft/__init__.py +1 -0
- qiskit/synthesis/qft/qft_decompose_full.py +79 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
- qiskit/synthesis/two_qubit/local_invariance.py +8 -38
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
- qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
- qiskit/synthesis/unitary/qsd.py +5 -3
- qiskit/transpiler/__init__.py +1 -0
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/coupling.py +3 -3
- qiskit/transpiler/instruction_durations.py +1 -2
- qiskit/transpiler/layout.py +3 -3
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +84 -64
- qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
- qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
- qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
- qiskit/transpiler/passes/layout/apply_layout.py +13 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
- qiskit/transpiler/passes/layout/set_layout.py +2 -2
- qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +17 -8
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
- qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
- qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -14
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
- qiskit/transpiler/passes/synthesis/plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +80 -40
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
- qiskit/transpiler/passes/utils/check_map.py +3 -6
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
- qiskit/transpiler/passes/utils/error.py +2 -2
- qiskit/transpiler/passes/utils/fixed_point.py +3 -3
- qiskit/transpiler/passes/utils/gate_direction.py +1 -1
- qiskit/transpiler/passes/utils/gates_basis.py +1 -2
- qiskit/transpiler/passmanager.py +7 -6
- qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +73 -18
- qiskit/transpiler/preset_passmanagers/common.py +3 -6
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
- qiskit/transpiler/preset_passmanagers/level0.py +1 -1
- qiskit/transpiler/target.py +27 -8
- qiskit/user_config.py +29 -6
- qiskit/utils/classtools.py +3 -3
- qiskit/utils/deprecation.py +3 -2
- qiskit/utils/lazy_tester.py +2 -2
- qiskit/utils/optionals.py +8 -8
- qiskit/visualization/bloch.py +18 -23
- qiskit/visualization/circuit/_utils.py +34 -10
- qiskit/visualization/circuit/circuit_visualization.py +23 -16
- qiskit/visualization/circuit/latex.py +29 -27
- qiskit/visualization/circuit/matplotlib.py +4 -2
- qiskit/visualization/circuit/qcstyle.py +2 -2
- qiskit/visualization/circuit/text.py +9 -15
- qiskit/visualization/dag_visualization.py +2 -2
- qiskit/visualization/pulse_v2/core.py +1 -1
- qiskit/visualization/pulse_v2/events.py +1 -1
- qiskit/visualization/pulse_v2/generators/frame.py +3 -4
- qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
- qiskit/visualization/pulse_v2/layouts.py +1 -5
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
- qiskit/visualization/state_visualization.py +5 -6
- qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
- qiskit/visualization/transition_visualization.py +7 -2
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/METADATA +12 -12
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/RECORD +342 -340
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/entry_points.txt +3 -0
- qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/WHEEL +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,518 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2024.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
|
13
|
+
"""
|
14
|
+
Preset pass manager generation function
|
15
|
+
"""
|
16
|
+
|
17
|
+
import copy
|
18
|
+
import warnings
|
19
|
+
|
20
|
+
from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
|
21
|
+
from qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping
|
22
|
+
from qiskit.circuit.quantumregister import Qubit
|
23
|
+
from qiskit.providers.backend_compat import BackendV2Converter
|
24
|
+
from qiskit.transpiler.coupling import CouplingMap
|
25
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
26
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
27
|
+
from qiskit.transpiler.layout import Layout
|
28
|
+
from qiskit.transpiler.passmanager_config import PassManagerConfig
|
29
|
+
from qiskit.transpiler.target import Target, target_to_backend_properties
|
30
|
+
from qiskit.transpiler.timing_constraints import TimingConstraints
|
31
|
+
|
32
|
+
from .level0 import level_0_pass_manager
|
33
|
+
from .level1 import level_1_pass_manager
|
34
|
+
from .level2 import level_2_pass_manager
|
35
|
+
from .level3 import level_3_pass_manager
|
36
|
+
|
37
|
+
|
38
|
+
def generate_preset_pass_manager(
|
39
|
+
optimization_level,
|
40
|
+
backend=None,
|
41
|
+
target=None,
|
42
|
+
basis_gates=None,
|
43
|
+
inst_map=None,
|
44
|
+
coupling_map=None,
|
45
|
+
instruction_durations=None,
|
46
|
+
backend_properties=None,
|
47
|
+
timing_constraints=None,
|
48
|
+
initial_layout=None,
|
49
|
+
layout_method=None,
|
50
|
+
routing_method=None,
|
51
|
+
translation_method=None,
|
52
|
+
scheduling_method=None,
|
53
|
+
approximation_degree=1.0,
|
54
|
+
seed_transpiler=None,
|
55
|
+
unitary_synthesis_method="default",
|
56
|
+
unitary_synthesis_plugin_config=None,
|
57
|
+
hls_config=None,
|
58
|
+
init_method=None,
|
59
|
+
optimization_method=None,
|
60
|
+
dt=None,
|
61
|
+
*,
|
62
|
+
_skip_target=False,
|
63
|
+
):
|
64
|
+
"""Generate a preset :class:`~.PassManager`
|
65
|
+
|
66
|
+
This function is used to quickly generate a preset pass manager. Preset pass
|
67
|
+
managers are the default pass managers used by the :func:`~.transpile`
|
68
|
+
function. This function provides a convenient and simple method to construct
|
69
|
+
a standalone :class:`~.PassManager` object that mirrors what the :func:`~.transpile`
|
70
|
+
function internally builds and uses.
|
71
|
+
|
72
|
+
The target constraints for the pass manager construction can be specified through a :class:`.Target`
|
73
|
+
instance, a :class:`.BackendV1` or :class:`.BackendV2` instance, or via loose constraints
|
74
|
+
(``basis_gates``, ``inst_map``, ``coupling_map``, ``backend_properties``, ``instruction_durations``,
|
75
|
+
``dt`` or ``timing_constraints``).
|
76
|
+
The order of priorities for target constraints works as follows: if a ``target``
|
77
|
+
input is provided, it will take priority over any ``backend`` input or loose constraints.
|
78
|
+
If a ``backend`` is provided together with any loose constraint
|
79
|
+
from the list above, the loose constraint will take priority over the corresponding backend
|
80
|
+
constraint. This behavior is independent of whether the ``backend`` instance is of type
|
81
|
+
:class:`.BackendV1` or :class:`.BackendV2`, as summarized in the table below. The first column
|
82
|
+
in the table summarizes the potential user-provided constraints, and each cell shows whether
|
83
|
+
the priority is assigned to that specific constraint input or another input
|
84
|
+
(`target`/`backend(V1)`/`backend(V2)`).
|
85
|
+
|
86
|
+
============================ ========= ======================== =======================
|
87
|
+
User Provided target backend(V1) backend(V2)
|
88
|
+
============================ ========= ======================== =======================
|
89
|
+
**basis_gates** target basis_gates basis_gates
|
90
|
+
**coupling_map** target coupling_map coupling_map
|
91
|
+
**instruction_durations** target instruction_durations instruction_durations
|
92
|
+
**inst_map** target inst_map inst_map
|
93
|
+
**dt** target dt dt
|
94
|
+
**timing_constraints** target timing_constraints timing_constraints
|
95
|
+
**backend_properties** target backend_properties backend_properties
|
96
|
+
============================ ========= ======================== =======================
|
97
|
+
|
98
|
+
Args:
|
99
|
+
optimization_level (int): The optimization level to generate a
|
100
|
+
:class:`~.PassManager` for. This can be 0, 1, 2, or 3. Higher
|
101
|
+
levels generate more optimized circuits, at the expense of
|
102
|
+
longer transpilation time:
|
103
|
+
|
104
|
+
* 0: no optimization
|
105
|
+
* 1: light optimization
|
106
|
+
* 2: heavy optimization
|
107
|
+
* 3: even heavier optimization
|
108
|
+
|
109
|
+
backend (Backend): An optional backend object which can be used as the
|
110
|
+
source of the default values for the ``basis_gates``, ``inst_map``,
|
111
|
+
``coupling_map``, ``backend_properties``, ``instruction_durations``,
|
112
|
+
``timing_constraints``, and ``target``. If any of those other arguments
|
113
|
+
are specified in addition to ``backend`` they will take precedence
|
114
|
+
over the value contained in the backend.
|
115
|
+
target (Target): The :class:`~.Target` representing a backend compilation
|
116
|
+
target. The following attributes will be inferred from this
|
117
|
+
argument if they are not set: ``coupling_map``, ``basis_gates``,
|
118
|
+
``instruction_durations``, ``inst_map``, ``timing_constraints``
|
119
|
+
and ``backend_properties``.
|
120
|
+
basis_gates (list): List of basis gate names to unroll to
|
121
|
+
(e.g: ``['u1', 'u2', 'u3', 'cx']``).
|
122
|
+
inst_map (InstructionScheduleMap): Mapping object that maps gates to schedules.
|
123
|
+
If any user defined calibration is found in the map and this is used in a
|
124
|
+
circuit, transpiler attaches the custom gate definition to the circuit.
|
125
|
+
This enables one to flexibly override the low-level instruction
|
126
|
+
implementation.
|
127
|
+
coupling_map (CouplingMap or list): Directed graph represented a coupling
|
128
|
+
map. Multiple formats are supported:
|
129
|
+
|
130
|
+
#. ``CouplingMap`` instance
|
131
|
+
#. List, must be given as an adjacency matrix, where each entry
|
132
|
+
specifies all directed two-qubit interactions supported by backend,
|
133
|
+
e.g: ``[[0, 1], [0, 3], [1, 2], [1, 5], [2, 5], [4, 1], [5, 3]]``
|
134
|
+
|
135
|
+
instruction_durations (InstructionDurations or list): Dictionary of duration
|
136
|
+
(in dt) for each instruction. If specified, these durations overwrite the
|
137
|
+
gate lengths in ``backend.properties``. Applicable only if ``scheduling_method``
|
138
|
+
is specified.
|
139
|
+
The format of ``instruction_durations`` must be as follows:
|
140
|
+
They must be given as an :class:`.InstructionDurations` instance or a list of tuples
|
141
|
+
|
142
|
+
```
|
143
|
+
[(instruction_name, qubits, duration, unit), ...].
|
144
|
+
| [('cx', [0, 1], 12.3, 'ns'), ('u3', [0], 4.56, 'ns')]
|
145
|
+
| [('cx', [0, 1], 1000), ('u3', [0], 300)]
|
146
|
+
```
|
147
|
+
|
148
|
+
If ``unit`` is omitted, the default is ``'dt'``, which is a sample time depending on backend.
|
149
|
+
If the time unit is ``'dt'``, the duration must be an integer.
|
150
|
+
dt (float): Backend sample time (resolution) in seconds.
|
151
|
+
If provided, this value will overwrite the ``dt`` value in ``instruction_durations``.
|
152
|
+
If ``None`` (default) and a backend is provided, ``backend.dt`` is used.
|
153
|
+
timing_constraints (TimingConstraints): Hardware time alignment restrictions.
|
154
|
+
A quantum computer backend may report a set of restrictions, namely:
|
155
|
+
|
156
|
+
- granularity: An integer value representing minimum pulse gate
|
157
|
+
resolution in units of ``dt``. A user-defined pulse gate should have
|
158
|
+
duration of a multiple of this granularity value.
|
159
|
+
- min_length: An integer value representing minimum pulse gate
|
160
|
+
length in units of ``dt``. A user-defined pulse gate should be longer
|
161
|
+
than this length.
|
162
|
+
- pulse_alignment: An integer value representing a time resolution of gate
|
163
|
+
instruction starting time. Gate instruction should start at time which
|
164
|
+
is a multiple of the alignment value.
|
165
|
+
- acquire_alignment: An integer value representing a time resolution of measure
|
166
|
+
instruction starting time. Measure instruction should start at time which
|
167
|
+
is a multiple of the alignment value.
|
168
|
+
|
169
|
+
This information will be provided by the backend configuration.
|
170
|
+
If the backend doesn't have any restriction on the instruction time allocation,
|
171
|
+
then ``timing_constraints`` is None and no adjustment will be performed.
|
172
|
+
|
173
|
+
initial_layout (Layout | List[int]): Initial position of virtual qubits on
|
174
|
+
physical qubits.
|
175
|
+
layout_method (str): The :class:`~.Pass` to use for choosing initial qubit
|
176
|
+
placement. Valid choices are ``'trivial'``, ``'dense'``,
|
177
|
+
and ``'sabre'``, representing :class:`~.TrivialLayout`, :class:`~.DenseLayout` and
|
178
|
+
:class:`~.SabreLayout` respectively. This can also
|
179
|
+
be the external plugin name to use for the ``layout`` stage of the output
|
180
|
+
:class:`~.StagedPassManager`. You can see a list of installed plugins by using
|
181
|
+
:func:`~.list_stage_plugins` with ``"layout"`` for the ``stage_name`` argument.
|
182
|
+
routing_method (str): The pass to use for routing qubits on the
|
183
|
+
architecture. Valid choices are ``'basic'``, ``'lookahead'``, ``'stochastic'``,
|
184
|
+
``'sabre'``, and ``'none'`` representing :class:`~.BasicSwap`,
|
185
|
+
:class:`~.LookaheadSwap`, :class:`~.StochasticSwap`, :class:`~.SabreSwap`, and
|
186
|
+
erroring if routing is required respectively. This can also be the external plugin
|
187
|
+
name to use for the ``routing`` stage of the output :class:`~.StagedPassManager`.
|
188
|
+
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
|
189
|
+
``"routing"`` for the ``stage_name`` argument.
|
190
|
+
translation_method (str): The method to use for translating gates to
|
191
|
+
basis gates. Valid choices ``'translator'``, ``'synthesis'`` representing
|
192
|
+
:class:`~.BasisTranslator`, and :class:`~.UnitarySynthesis` respectively. This can
|
193
|
+
also be the external plugin name to use for the ``translation`` stage of the output
|
194
|
+
:class:`~.StagedPassManager`. You can see a list of installed plugins by using
|
195
|
+
:func:`~.list_stage_plugins` with ``"translation"`` for the ``stage_name`` argument.
|
196
|
+
scheduling_method (str): The pass to use for scheduling instructions. Valid choices
|
197
|
+
are ``'alap'`` and ``'asap'``. This can also be the external plugin name to use
|
198
|
+
for the ``scheduling`` stage of the output :class:`~.StagedPassManager`. You can
|
199
|
+
see a list of installed plugins by using :func:`~.list_stage_plugins` with
|
200
|
+
``"scheduling"`` for the ``stage_name`` argument.
|
201
|
+
backend_properties (BackendProperties): Properties returned by a
|
202
|
+
backend, including information on gate errors, readout errors,
|
203
|
+
qubit coherence times, etc.
|
204
|
+
approximation_degree (float): Heuristic dial used for circuit approximation
|
205
|
+
(1.0=no approximation, 0.0=maximal approximation).
|
206
|
+
seed_transpiler (int): Sets random seed for the stochastic parts of
|
207
|
+
the transpiler.
|
208
|
+
unitary_synthesis_method (str): The name of the unitary synthesis
|
209
|
+
method to use. By default ``'default'`` is used. You can see a list of
|
210
|
+
installed plugins with :func:`.unitary_synthesis_plugin_names`.
|
211
|
+
unitary_synthesis_plugin_config (dict): An optional configuration dictionary
|
212
|
+
that will be passed directly to the unitary synthesis plugin. By
|
213
|
+
default this setting will have no effect as the default unitary
|
214
|
+
synthesis method does not take custom configuration. This should
|
215
|
+
only be necessary when a unitary synthesis plugin is specified with
|
216
|
+
the ``unitary_synthesis_method`` argument. As this is custom for each
|
217
|
+
unitary synthesis plugin refer to the plugin documentation for how
|
218
|
+
to use this option.
|
219
|
+
hls_config (HLSConfig): An optional configuration class :class:`~.HLSConfig`
|
220
|
+
that will be passed directly to :class:`~.HighLevelSynthesis` transformation pass.
|
221
|
+
This configuration class allows to specify for various high-level objects
|
222
|
+
the lists of synthesis algorithms and their parameters.
|
223
|
+
init_method (str): The plugin name to use for the ``init`` stage of
|
224
|
+
the output :class:`~.StagedPassManager`. By default an external
|
225
|
+
plugin is not used. You can see a list of installed plugins by
|
226
|
+
using :func:`~.list_stage_plugins` with ``"init"`` for the stage
|
227
|
+
name argument.
|
228
|
+
optimization_method (str): The plugin name to use for the
|
229
|
+
``optimization`` stage of the output
|
230
|
+
:class:`~.StagedPassManager`. By default an external
|
231
|
+
plugin is not used. You can see a list of installed plugins by
|
232
|
+
using :func:`~.list_stage_plugins` with ``"optimization"`` for the
|
233
|
+
``stage_name`` argument.
|
234
|
+
|
235
|
+
Returns:
|
236
|
+
StagedPassManager: The preset pass manager for the given options
|
237
|
+
|
238
|
+
Raises:
|
239
|
+
ValueError: if an invalid value for ``optimization_level`` is passed in.
|
240
|
+
"""
|
241
|
+
|
242
|
+
if backend is not None and getattr(backend, "version", 0) <= 1:
|
243
|
+
# This is a temporary conversion step to allow for a smoother transition
|
244
|
+
# to a fully target-based transpiler pipeline while maintaining the behavior
|
245
|
+
# of `transpile` with BackendV1 inputs.
|
246
|
+
warnings.warn(
|
247
|
+
"The `generate_preset_pass_manager` function will stop supporting inputs of "
|
248
|
+
f"type `BackendV1` ( {backend} ) in the `backend` parameter in a future "
|
249
|
+
"release no earlier than 2.0. `BackendV1` is deprecated and implementations "
|
250
|
+
"should move to `BackendV2`.",
|
251
|
+
category=DeprecationWarning,
|
252
|
+
stacklevel=2,
|
253
|
+
)
|
254
|
+
backend = BackendV2Converter(backend)
|
255
|
+
|
256
|
+
# Check if a custom inst_map was specified before overwriting inst_map
|
257
|
+
_given_inst_map = bool(inst_map)
|
258
|
+
# If there are no loose constraints => use backend target if available
|
259
|
+
_no_loose_constraints = (
|
260
|
+
basis_gates is None
|
261
|
+
and coupling_map is None
|
262
|
+
and dt is None
|
263
|
+
and instruction_durations is None
|
264
|
+
and backend_properties is None
|
265
|
+
and timing_constraints is None
|
266
|
+
)
|
267
|
+
# If it's an edge case => do not build target
|
268
|
+
_skip_target = (
|
269
|
+
target is None
|
270
|
+
and backend is None
|
271
|
+
and (basis_gates is None or coupling_map is None or instruction_durations is not None)
|
272
|
+
)
|
273
|
+
|
274
|
+
# Resolve loose constraints case-by-case against backend constraints.
|
275
|
+
# The order of priority is loose constraints > backend.
|
276
|
+
dt = _parse_dt(dt, backend)
|
277
|
+
instruction_durations = _parse_instruction_durations(backend, instruction_durations, dt)
|
278
|
+
timing_constraints = _parse_timing_constraints(backend, timing_constraints)
|
279
|
+
inst_map = _parse_inst_map(inst_map, backend)
|
280
|
+
# The basis gates parser will set _skip_target to True if a custom basis gate is found
|
281
|
+
# (known edge case).
|
282
|
+
basis_gates, name_mapping, _skip_target = _parse_basis_gates(
|
283
|
+
basis_gates, backend, inst_map, _skip_target
|
284
|
+
)
|
285
|
+
coupling_map = _parse_coupling_map(coupling_map, backend)
|
286
|
+
|
287
|
+
if target is None:
|
288
|
+
if backend is not None and _no_loose_constraints:
|
289
|
+
# If a backend is specified without loose constraints, use its target directly.
|
290
|
+
target = backend.target
|
291
|
+
elif not _skip_target:
|
292
|
+
# Only parse backend properties when the target isn't skipped to
|
293
|
+
# preserve the former behavior of transpile.
|
294
|
+
backend_properties = _parse_backend_properties(backend_properties, backend)
|
295
|
+
# Build target from constraints.
|
296
|
+
target = Target.from_configuration(
|
297
|
+
basis_gates=basis_gates,
|
298
|
+
num_qubits=backend.num_qubits if backend is not None else None,
|
299
|
+
coupling_map=coupling_map,
|
300
|
+
# If the instruction map has custom gates, do not give as config, the information
|
301
|
+
# will be added to the target with update_from_instruction_schedule_map
|
302
|
+
inst_map=inst_map if inst_map and not inst_map.has_custom_gate() else None,
|
303
|
+
backend_properties=backend_properties,
|
304
|
+
instruction_durations=instruction_durations,
|
305
|
+
concurrent_measurements=(
|
306
|
+
backend.target.concurrent_measurements if backend is not None else None
|
307
|
+
),
|
308
|
+
dt=dt,
|
309
|
+
timing_constraints=timing_constraints,
|
310
|
+
custom_name_mapping=name_mapping,
|
311
|
+
)
|
312
|
+
|
313
|
+
# Update target with custom gate information. Note that this is an exception to the priority
|
314
|
+
# order (target > loose constraints), added to handle custom gates for scheduling passes.
|
315
|
+
if target is not None and _given_inst_map and inst_map.has_custom_gate():
|
316
|
+
target = copy.deepcopy(target)
|
317
|
+
target.update_from_instruction_schedule_map(inst_map)
|
318
|
+
|
319
|
+
if target is not None:
|
320
|
+
if coupling_map is None:
|
321
|
+
coupling_map = target.build_coupling_map()
|
322
|
+
if basis_gates is None:
|
323
|
+
basis_gates = target.operation_names
|
324
|
+
if instruction_durations is None:
|
325
|
+
instruction_durations = target.durations()
|
326
|
+
if inst_map is None:
|
327
|
+
inst_map = target.instruction_schedule_map()
|
328
|
+
if timing_constraints is None:
|
329
|
+
timing_constraints = target.timing_constraints()
|
330
|
+
if backend_properties is None:
|
331
|
+
with warnings.catch_warnings():
|
332
|
+
# TODO this approach (target-to-properties) is going to be removed soon (1.3) in favor
|
333
|
+
# of backend-to-target approach
|
334
|
+
# https://github.com/Qiskit/qiskit/pull/12850
|
335
|
+
warnings.filterwarnings(
|
336
|
+
"ignore",
|
337
|
+
category=DeprecationWarning,
|
338
|
+
message=r".+qiskit\.transpiler\.target\.target_to_backend_properties.+",
|
339
|
+
module="qiskit",
|
340
|
+
)
|
341
|
+
backend_properties = target_to_backend_properties(target)
|
342
|
+
|
343
|
+
# Parse non-target dependent pm options
|
344
|
+
initial_layout = _parse_initial_layout(initial_layout)
|
345
|
+
approximation_degree = _parse_approximation_degree(approximation_degree)
|
346
|
+
|
347
|
+
pm_options = {
|
348
|
+
"target": target,
|
349
|
+
"basis_gates": basis_gates,
|
350
|
+
"inst_map": inst_map,
|
351
|
+
"coupling_map": coupling_map,
|
352
|
+
"instruction_durations": instruction_durations,
|
353
|
+
"backend_properties": backend_properties,
|
354
|
+
"timing_constraints": timing_constraints,
|
355
|
+
"layout_method": layout_method,
|
356
|
+
"routing_method": routing_method,
|
357
|
+
"translation_method": translation_method,
|
358
|
+
"scheduling_method": scheduling_method,
|
359
|
+
"approximation_degree": approximation_degree,
|
360
|
+
"seed_transpiler": seed_transpiler,
|
361
|
+
"unitary_synthesis_method": unitary_synthesis_method,
|
362
|
+
"unitary_synthesis_plugin_config": unitary_synthesis_plugin_config,
|
363
|
+
"initial_layout": initial_layout,
|
364
|
+
"hls_config": hls_config,
|
365
|
+
"init_method": init_method,
|
366
|
+
"optimization_method": optimization_method,
|
367
|
+
}
|
368
|
+
|
369
|
+
if backend is not None:
|
370
|
+
pm_options["_skip_target"] = _skip_target
|
371
|
+
pm_config = PassManagerConfig.from_backend(backend, **pm_options)
|
372
|
+
else:
|
373
|
+
pm_config = PassManagerConfig(**pm_options)
|
374
|
+
if optimization_level == 0:
|
375
|
+
pm = level_0_pass_manager(pm_config)
|
376
|
+
elif optimization_level == 1:
|
377
|
+
pm = level_1_pass_manager(pm_config)
|
378
|
+
elif optimization_level == 2:
|
379
|
+
pm = level_2_pass_manager(pm_config)
|
380
|
+
elif optimization_level == 3:
|
381
|
+
pm = level_3_pass_manager(pm_config)
|
382
|
+
else:
|
383
|
+
raise ValueError(f"Invalid optimization level {optimization_level}")
|
384
|
+
return pm
|
385
|
+
|
386
|
+
|
387
|
+
def _parse_basis_gates(basis_gates, backend, inst_map, skip_target):
|
388
|
+
name_mapping = {}
|
389
|
+
standard_gates = get_standard_gate_name_mapping()
|
390
|
+
# Add control flow gates by default to basis set
|
391
|
+
default_gates = {"measure", "delay", "reset"}.union(CONTROL_FLOW_OP_NAMES)
|
392
|
+
|
393
|
+
try:
|
394
|
+
instructions = set(basis_gates)
|
395
|
+
for name in default_gates:
|
396
|
+
if name not in instructions:
|
397
|
+
instructions.add(name)
|
398
|
+
except TypeError:
|
399
|
+
instructions = None
|
400
|
+
|
401
|
+
if backend is None:
|
402
|
+
# Check for custom instructions
|
403
|
+
if instructions is None:
|
404
|
+
return None, name_mapping, skip_target
|
405
|
+
|
406
|
+
for inst in instructions:
|
407
|
+
if inst not in standard_gates or inst not in default_gates:
|
408
|
+
skip_target = True
|
409
|
+
break
|
410
|
+
|
411
|
+
return list(instructions), name_mapping, skip_target
|
412
|
+
|
413
|
+
instructions = instructions or backend.operation_names
|
414
|
+
name_mapping.update(
|
415
|
+
{name: backend.target.operation_from_name(name) for name in backend.operation_names}
|
416
|
+
)
|
417
|
+
|
418
|
+
# Check for custom instructions before removing calibrations
|
419
|
+
for inst in instructions:
|
420
|
+
if inst not in standard_gates or inst not in default_gates:
|
421
|
+
skip_target = True
|
422
|
+
break
|
423
|
+
|
424
|
+
# Remove calibrated instructions, as they will be added later from the instruction schedule map
|
425
|
+
if inst_map is not None and not skip_target:
|
426
|
+
for inst in inst_map.instructions:
|
427
|
+
for qubit in inst_map.qubits_with_instruction(inst):
|
428
|
+
entry = inst_map._get_calibration_entry(inst, qubit)
|
429
|
+
if entry.user_provided and inst in instructions:
|
430
|
+
instructions.remove(inst)
|
431
|
+
|
432
|
+
return list(instructions) if instructions else None, name_mapping, skip_target
|
433
|
+
|
434
|
+
|
435
|
+
def _parse_inst_map(inst_map, backend):
|
436
|
+
# try getting inst_map from user, else backend
|
437
|
+
if inst_map is None and backend is not None:
|
438
|
+
inst_map = backend.target.instruction_schedule_map()
|
439
|
+
return inst_map
|
440
|
+
|
441
|
+
|
442
|
+
def _parse_backend_properties(backend_properties, backend):
|
443
|
+
# try getting backend_props from user, else backend
|
444
|
+
if backend_properties is None and backend is not None:
|
445
|
+
backend_properties = target_to_backend_properties(backend.target)
|
446
|
+
return backend_properties
|
447
|
+
|
448
|
+
|
449
|
+
def _parse_dt(dt, backend):
|
450
|
+
# try getting dt from user, else backend
|
451
|
+
if dt is None and backend is not None:
|
452
|
+
dt = backend.target.dt
|
453
|
+
return dt
|
454
|
+
|
455
|
+
|
456
|
+
def _parse_coupling_map(coupling_map, backend):
|
457
|
+
# try getting coupling_map from user, else backend
|
458
|
+
if coupling_map is None and backend is not None:
|
459
|
+
coupling_map = backend.coupling_map
|
460
|
+
|
461
|
+
# coupling_map could be None, or a list of lists, e.g. [[0, 1], [2, 1]]
|
462
|
+
if coupling_map is None or isinstance(coupling_map, CouplingMap):
|
463
|
+
return coupling_map
|
464
|
+
if isinstance(coupling_map, list) and all(
|
465
|
+
isinstance(i, list) and len(i) == 2 for i in coupling_map
|
466
|
+
):
|
467
|
+
return CouplingMap(coupling_map)
|
468
|
+
else:
|
469
|
+
raise TranspilerError(
|
470
|
+
"Only a single input coupling map can be used with generate_preset_pass_manager()."
|
471
|
+
)
|
472
|
+
|
473
|
+
|
474
|
+
def _parse_instruction_durations(backend, inst_durations, dt):
|
475
|
+
"""Create a list of ``InstructionDuration``s. If ``inst_durations`` is provided,
|
476
|
+
the backend will be ignored, otherwise, the durations will be populated from the
|
477
|
+
backend.
|
478
|
+
"""
|
479
|
+
final_durations = InstructionDurations()
|
480
|
+
if not inst_durations:
|
481
|
+
backend_durations = InstructionDurations()
|
482
|
+
if backend is not None:
|
483
|
+
backend_durations = backend.instruction_durations
|
484
|
+
final_durations.update(backend_durations, dt or backend_durations.dt)
|
485
|
+
else:
|
486
|
+
final_durations.update(inst_durations, dt or getattr(inst_durations, "dt", None))
|
487
|
+
return final_durations
|
488
|
+
|
489
|
+
|
490
|
+
def _parse_timing_constraints(backend, timing_constraints):
|
491
|
+
if isinstance(timing_constraints, TimingConstraints):
|
492
|
+
return timing_constraints
|
493
|
+
if backend is None and timing_constraints is None:
|
494
|
+
timing_constraints = TimingConstraints()
|
495
|
+
elif backend is not None:
|
496
|
+
timing_constraints = backend.target.timing_constraints()
|
497
|
+
return timing_constraints
|
498
|
+
|
499
|
+
|
500
|
+
def _parse_initial_layout(initial_layout):
|
501
|
+
# initial_layout could be None, or a list of ints, e.g. [0, 5, 14]
|
502
|
+
# or a list of tuples/None e.g. [qr[0], None, qr[1]] or a dict e.g. {qr[0]: 0}
|
503
|
+
if initial_layout is None or isinstance(initial_layout, Layout):
|
504
|
+
return initial_layout
|
505
|
+
if isinstance(initial_layout, dict):
|
506
|
+
return Layout(initial_layout)
|
507
|
+
initial_layout = list(initial_layout)
|
508
|
+
if all(phys is None or isinstance(phys, Qubit) for phys in initial_layout):
|
509
|
+
return Layout.from_qubit_list(initial_layout)
|
510
|
+
return initial_layout
|
511
|
+
|
512
|
+
|
513
|
+
def _parse_approximation_degree(approximation_degree):
|
514
|
+
if approximation_degree is None:
|
515
|
+
return None
|
516
|
+
if approximation_degree < 0.0 or approximation_degree > 1.0:
|
517
|
+
raise TranspilerError("Approximation degree must be in [0.0, 1.0]")
|
518
|
+
return approximation_degree
|
@@ -48,7 +48,7 @@ def level_0_pass_manager(pass_manager_config: PassManagerConfig) -> StagedPassMa
|
|
48
48
|
initial_layout = pass_manager_config.initial_layout
|
49
49
|
init_method = pass_manager_config.init_method or "default"
|
50
50
|
layout_method = pass_manager_config.layout_method or "default"
|
51
|
-
routing_method = pass_manager_config.routing_method or "
|
51
|
+
routing_method = pass_manager_config.routing_method or "sabre"
|
52
52
|
translation_method = pass_manager_config.translation_method or "translator"
|
53
53
|
optimization_method = pass_manager_config.optimization_method or "default"
|
54
54
|
scheduling_method = pass_manager_config.scheduling_method or "default"
|
qiskit/transpiler/target.py
CHANGED
@@ -20,6 +20,7 @@ from a backend
|
|
20
20
|
from __future__ import annotations
|
21
21
|
|
22
22
|
import itertools
|
23
|
+
import warnings
|
23
24
|
|
24
25
|
from typing import Optional, List, Any
|
25
26
|
from collections.abc import Mapping
|
@@ -50,6 +51,7 @@ from qiskit.exceptions import QiskitError
|
|
50
51
|
# full target
|
51
52
|
from qiskit.providers.backend import QubitProperties # pylint: disable=unused-import
|
52
53
|
from qiskit.providers.models.backendproperties import BackendProperties
|
54
|
+
from qiskit.utils import deprecate_func
|
53
55
|
|
54
56
|
|
55
57
|
logger = logging.getLogger(__name__)
|
@@ -411,7 +413,7 @@ class Target(Mapping):
|
|
411
413
|
if properties is None:
|
412
414
|
properties = {None: None}
|
413
415
|
if instruction_name in self._gate_map:
|
414
|
-
raise AttributeError("Instruction
|
416
|
+
raise AttributeError(f"Instruction {instruction_name} is already in the target")
|
415
417
|
self._gate_name_map[instruction_name] = instruction
|
416
418
|
if is_class:
|
417
419
|
qargs_val = {None: None}
|
@@ -426,7 +428,9 @@ class Target(Mapping):
|
|
426
428
|
f"of qubits in the properties dictionary: {qarg}"
|
427
429
|
)
|
428
430
|
if qarg is not None:
|
429
|
-
self.num_qubits = max(
|
431
|
+
self.num_qubits = max(
|
432
|
+
self.num_qubits if self.num_qubits is not None else 0, max(qarg) + 1
|
433
|
+
)
|
430
434
|
qargs_val[qarg] = properties[qarg]
|
431
435
|
self._qarg_gate_map[qarg].add(instruction_name)
|
432
436
|
self._gate_map[instruction_name] = qargs_val
|
@@ -814,7 +818,7 @@ class Target(Mapping):
|
|
814
818
|
if qargs in self._gate_map[op_name]:
|
815
819
|
return True
|
816
820
|
if self._gate_map[op_name] is None or None in self._gate_map[op_name]:
|
817
|
-
return
|
821
|
+
return obj.num_qubits == len(qargs) and all(
|
818
822
|
x < self.num_qubits for x in qargs
|
819
823
|
)
|
820
824
|
return False
|
@@ -940,7 +944,9 @@ class Target(Mapping):
|
|
940
944
|
is globally defined.
|
941
945
|
"""
|
942
946
|
return [
|
943
|
-
(self._gate_name_map[op], qarg)
|
947
|
+
(self._gate_name_map[op], qarg)
|
948
|
+
for op, qargs in self._gate_map.items()
|
949
|
+
for qarg in qargs
|
944
950
|
]
|
945
951
|
|
946
952
|
def instruction_properties(self, index):
|
@@ -979,13 +985,14 @@ class Target(Mapping):
|
|
979
985
|
InstructionProperties: The instruction properties for the specified instruction tuple
|
980
986
|
"""
|
981
987
|
instruction_properties = [
|
982
|
-
inst_props for
|
988
|
+
inst_props for qargs in self._gate_map.values() for inst_props in qargs.values()
|
983
989
|
]
|
984
990
|
return instruction_properties[index]
|
985
991
|
|
986
992
|
def _build_coupling_graph(self):
|
987
993
|
self._coupling_graph = rx.PyDiGraph(multigraph=False)
|
988
|
-
self.
|
994
|
+
if self.num_qubits is not None:
|
995
|
+
self._coupling_graph.add_nodes_from([{} for _ in range(self.num_qubits)])
|
989
996
|
for gate, qarg_map in self._gate_map.items():
|
990
997
|
if qarg_map is None:
|
991
998
|
if self._gate_name_map[gate].num_qubits == 2:
|
@@ -1057,7 +1064,7 @@ class Target(Mapping):
|
|
1057
1064
|
for qargs, properties in self._gate_map[two_q_gate].items():
|
1058
1065
|
if len(qargs) != 2:
|
1059
1066
|
raise ValueError(
|
1060
|
-
"Specified two_q_gate:
|
1067
|
+
f"Specified two_q_gate: {two_q_gate} is not a 2 qubit instruction"
|
1061
1068
|
)
|
1062
1069
|
coupling_graph.add_edge(*qargs, {two_q_gate: properties})
|
1063
1070
|
cmap = CouplingMap()
|
@@ -1437,6 +1444,15 @@ class Target(Mapping):
|
|
1437
1444
|
return target
|
1438
1445
|
|
1439
1446
|
|
1447
|
+
@deprecate_func(
|
1448
|
+
since="1.2",
|
1449
|
+
removal_timeline="in the 2.0 release",
|
1450
|
+
additional_msg="This method is used to build an element from the deprecated "
|
1451
|
+
"``qiskit.providers.models`` module. These models are part of the deprecated `BackendV1` "
|
1452
|
+
"workflow and no longer necessary for `BackendV2`. If a user workflow requires these "
|
1453
|
+
"representations it likely relies on deprecated functionality and "
|
1454
|
+
"should be updated to use `BackendV2`.",
|
1455
|
+
)
|
1440
1456
|
def target_to_backend_properties(target: Target):
|
1441
1457
|
"""Convert a :class:`~.Target` object into a legacy :class:`~.BackendProperties`"""
|
1442
1458
|
|
@@ -1515,6 +1531,9 @@ def target_to_backend_properties(target: Target):
|
|
1515
1531
|
if gates or qubits:
|
1516
1532
|
properties_dict["gates"] = gates
|
1517
1533
|
properties_dict["qubits"] = qubits
|
1518
|
-
|
1534
|
+
with warnings.catch_warnings():
|
1535
|
+
# This raises BackendProperties internally
|
1536
|
+
warnings.filterwarnings("ignore", category=DeprecationWarning)
|
1537
|
+
return BackendProperties.from_dict(properties_dict)
|
1519
1538
|
else:
|
1520
1539
|
return None
|