qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__cp39-abi3-macosx_11_0_arm64.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 +3 -9
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +35 -10
- qiskit/circuit/{add_control.py → _add_control.py} +32 -12
- qiskit/circuit/_classical_resource_map.py +5 -3
- qiskit/circuit/barrier.py +3 -7
- qiskit/circuit/classical/expr/__init__.py +31 -3
- qiskit/circuit/classical/expr/constructors.py +236 -28
- qiskit/circuit/classical/expr/expr.py +104 -3
- qiskit/circuit/classical/expr/visitors.py +75 -0
- qiskit/circuit/classical/types/__init__.py +12 -8
- qiskit/circuit/classical/types/ordering.py +14 -7
- qiskit/circuit/classical/types/types.py +36 -0
- qiskit/circuit/commutation_checker.py +34 -7
- qiskit/circuit/controlflow/__init__.py +32 -1
- qiskit/circuit/controlflow/_builder_utils.py +9 -5
- qiskit/circuit/controlflow/box.py +163 -0
- qiskit/circuit/controlflow/break_loop.py +1 -1
- qiskit/circuit/controlflow/builder.py +139 -39
- qiskit/circuit/controlflow/continue_loop.py +1 -3
- qiskit/circuit/controlflow/control_flow.py +10 -0
- qiskit/circuit/controlflow/for_loop.py +2 -1
- qiskit/circuit/controlflow/if_else.py +3 -16
- qiskit/circuit/controlflow/switch_case.py +2 -8
- qiskit/circuit/controlflow/while_loop.py +2 -7
- qiskit/circuit/controlledgate.py +2 -4
- qiskit/circuit/delay.py +40 -11
- qiskit/circuit/duration.py +0 -15
- qiskit/circuit/gate.py +2 -4
- qiskit/circuit/instruction.py +2 -141
- qiskit/circuit/instructionset.py +7 -54
- qiskit/circuit/library/__init__.py +469 -154
- qiskit/circuit/library/arithmetic/__init__.py +16 -10
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
- qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
- qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
- qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
- qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
- qiskit/circuit/library/bit_flip_oracle.py +130 -0
- qiskit/circuit/library/blueprintcircuit.py +52 -16
- qiskit/circuit/library/data_preparation/initializer.py +1 -1
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
- qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
- qiskit/circuit/library/generalized_gates/gms.py +1 -1
- qiskit/circuit/library/generalized_gates/isometry.py +1 -1
- qiskit/circuit/library/generalized_gates/pauli.py +1 -2
- qiskit/circuit/library/generalized_gates/uc.py +97 -7
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +4 -2
- qiskit/circuit/library/graph_state.py +1 -0
- qiskit/circuit/library/hamiltonian_gate.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/n_local.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +39 -24
- qiskit/circuit/library/phase_oracle.py +130 -51
- qiskit/circuit/library/standard_gates/__init__.py +0 -1
- qiskit/circuit/library/standard_gates/dcx.py +3 -4
- qiskit/circuit/library/standard_gates/ecr.py +3 -4
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +4 -9
- qiskit/circuit/library/standard_gates/i.py +2 -2
- qiskit/circuit/library/standard_gates/iswap.py +3 -4
- qiskit/circuit/library/standard_gates/p.py +15 -34
- qiskit/circuit/library/standard_gates/r.py +7 -10
- qiskit/circuit/library/standard_gates/rx.py +5 -15
- qiskit/circuit/library/standard_gates/rxx.py +3 -6
- qiskit/circuit/library/standard_gates/ry.py +5 -17
- qiskit/circuit/library/standard_gates/ryy.py +3 -6
- qiskit/circuit/library/standard_gates/rz.py +5 -17
- qiskit/circuit/library/standard_gates/rzx.py +3 -6
- qiskit/circuit/library/standard_gates/rzz.py +3 -6
- qiskit/circuit/library/standard_gates/s.py +6 -15
- qiskit/circuit/library/standard_gates/swap.py +4 -11
- qiskit/circuit/library/standard_gates/sx.py +7 -12
- qiskit/circuit/library/standard_gates/t.py +6 -7
- qiskit/circuit/library/standard_gates/u.py +2 -10
- qiskit/circuit/library/standard_gates/u1.py +5 -16
- qiskit/circuit/library/standard_gates/u2.py +2 -6
- qiskit/circuit/library/standard_gates/u3.py +3 -11
- qiskit/circuit/library/standard_gates/x.py +14 -62
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
- qiskit/circuit/library/standard_gates/y.py +4 -9
- qiskit/circuit/library/standard_gates/z.py +5 -15
- qiskit/circuit/measure.py +11 -2
- qiskit/circuit/parameterexpression.py +11 -0
- qiskit/circuit/quantumcircuit.py +890 -564
- qiskit/circuit/random/utils.py +12 -6
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/singleton.py +5 -11
- qiskit/circuit/store.py +0 -8
- qiskit/circuit/tools/pi_check.py +3 -0
- qiskit/compiler/__init__.py +1 -7
- qiskit/compiler/transpiler.py +38 -196
- qiskit/converters/circuit_to_dag.py +6 -4
- qiskit/converters/circuit_to_dagdependency.py +0 -2
- qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
- qiskit/converters/circuit_to_gate.py +1 -1
- qiskit/converters/circuit_to_instruction.py +16 -29
- qiskit/converters/dag_to_circuit.py +7 -8
- qiskit/converters/dag_to_dagdependency.py +0 -1
- qiskit/converters/dag_to_dagdependency_v2.py +0 -1
- qiskit/converters/dagdependency_to_circuit.py +0 -6
- qiskit/converters/dagdependency_to_dag.py +0 -6
- qiskit/dagcircuit/collect_blocks.py +32 -20
- qiskit/dagcircuit/dagdependency.py +3 -37
- qiskit/dagcircuit/dagdependency_v2.py +5 -82
- qiskit/dagcircuit/dagnode.py +14 -2
- qiskit/passmanager/__init__.py +24 -6
- qiskit/passmanager/passmanager.py +26 -24
- qiskit/primitives/__init__.py +44 -35
- qiskit/primitives/backend_estimator_v2.py +102 -23
- qiskit/primitives/backend_sampler_v2.py +5 -20
- qiskit/primitives/base/__init__.py +4 -4
- qiskit/primitives/base/base_estimator.py +77 -82
- qiskit/primitives/base/base_primitive_job.py +2 -2
- qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
- qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
- qiskit/primitives/base/base_sampler.py +52 -60
- qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
- qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
- qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
- qiskit/primitives/containers/bindings_array.py +3 -1
- qiskit/primitives/containers/bit_array.py +23 -0
- qiskit/primitives/containers/data_bin.py +3 -1
- qiskit/primitives/containers/observables_array.py +19 -2
- qiskit/primitives/statevector_sampler.py +6 -8
- qiskit/primitives/utils.py +14 -189
- qiskit/providers/__init__.py +4 -130
- qiskit/providers/backend.py +11 -314
- qiskit/providers/basic_provider/__init__.py +3 -1
- qiskit/providers/basic_provider/basic_provider.py +29 -9
- qiskit/providers/basic_provider/basic_simulator.py +158 -298
- qiskit/providers/exceptions.py +0 -33
- qiskit/providers/fake_provider/__init__.py +0 -37
- qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
- qiskit/qasm2/__init__.py +21 -6
- qiskit/qasm2/export.py +2 -10
- qiskit/qasm2/parse.py +11 -25
- qiskit/qasm3/__init__.py +5 -1
- qiskit/qasm3/ast.py +44 -0
- qiskit/qasm3/exporter.py +65 -27
- qiskit/qasm3/printer.py +35 -4
- qiskit/qpy/__init__.py +162 -19
- qiskit/qpy/binary_io/__init__.py +0 -1
- qiskit/qpy/binary_io/circuits.py +96 -116
- qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
- qiskit/qpy/binary_io/schedules.py +61 -388
- qiskit/qpy/binary_io/value.py +159 -33
- qiskit/qpy/common.py +10 -7
- qiskit/qpy/formats.py +41 -0
- qiskit/qpy/interface.py +29 -62
- qiskit/qpy/type_keys.py +58 -221
- qiskit/quantum_info/analysis/distance.py +3 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
- qiskit/quantum_info/operators/operator.py +6 -2
- qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
- qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
- qiskit/quantum_info/states/densitymatrix.py +16 -6
- qiskit/quantum_info/states/stabilizerstate.py +35 -4
- qiskit/quantum_info/states/statevector.py +16 -6
- qiskit/result/__init__.py +5 -17
- qiskit/result/models.py +18 -11
- qiskit/result/result.py +38 -134
- qiskit/result/sampled_expval.py +1 -2
- qiskit/result/utils.py +3 -4
- qiskit/synthesis/__init__.py +21 -1
- qiskit/synthesis/arithmetic/__init__.py +3 -1
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
- qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
- qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
- qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
- qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
- qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
- qiskit/synthesis/boolean/boolean_expression.py +231 -0
- qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
- qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +44 -35
- qiskit/synthesis/evolution/qdrift.py +17 -24
- qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
- qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
- qiskit/synthesis/multi_controlled/__init__.py +1 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
- qiskit/synthesis/two_qubit/__init__.py +1 -0
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
- qiskit/transpiler/__init__.py +32 -232
- qiskit/transpiler/basepasses.py +20 -51
- qiskit/transpiler/layout.py +1 -1
- qiskit/transpiler/passes/__init__.py +4 -40
- qiskit/transpiler/passes/basis/basis_translator.py +5 -4
- qiskit/transpiler/passes/basis/decompose.py +1 -15
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
- qiskit/transpiler/passes/layout/apply_layout.py +4 -0
- qiskit/transpiler/passes/layout/dense_layout.py +2 -39
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
- qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
- qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
- qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
- qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
- qiskit/transpiler/passes/optimization/__init__.py +2 -3
- qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
- qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
- qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
- qiskit/transpiler/passes/optimization/light_cone.py +135 -0
- qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
- qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
- qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -2
- qiskit/transpiler/passes/routing/__init__.py +0 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
- qiskit/transpiler/passes/scheduling/__init__.py +1 -7
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
- qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
- qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
- qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
- qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
- qiskit/transpiler/passes/synthesis/plugin.py +4 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
- qiskit/transpiler/passes/utils/control_flow.py +2 -6
- qiskit/transpiler/passes/utils/gate_direction.py +7 -0
- qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
- qiskit/transpiler/passmanager.py +13 -0
- qiskit/transpiler/passmanager_config.py +5 -81
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
- qiskit/transpiler/preset_passmanagers/common.py +140 -167
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
- qiskit/transpiler/preset_passmanagers/level0.py +2 -11
- qiskit/transpiler/preset_passmanagers/level1.py +2 -14
- qiskit/transpiler/preset_passmanagers/level2.py +2 -12
- qiskit/transpiler/preset_passmanagers/level3.py +2 -11
- qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
- qiskit/transpiler/target.py +78 -524
- qiskit/user_config.py +8 -4
- qiskit/utils/__init__.py +13 -12
- qiskit/utils/deprecation.py +4 -112
- qiskit/utils/optionals.py +11 -4
- qiskit/utils/parallel.py +214 -87
- qiskit/utils/units.py +4 -1
- qiskit/visualization/__init__.py +3 -7
- qiskit/visualization/array.py +4 -1
- qiskit/visualization/bloch.py +1 -1
- qiskit/visualization/circuit/_utils.py +19 -19
- qiskit/visualization/circuit/circuit_visualization.py +11 -4
- qiskit/visualization/circuit/matplotlib.py +13 -23
- qiskit/visualization/circuit/text.py +7 -3
- qiskit/visualization/counts_visualization.py +4 -0
- qiskit/visualization/dag_visualization.py +2 -1
- qiskit/visualization/gate_map.py +39 -154
- qiskit/visualization/library.py +4 -1
- qiskit/visualization/pass_manager_visualization.py +6 -2
- qiskit/visualization/state_visualization.py +19 -2
- qiskit/visualization/timeline/core.py +19 -13
- qiskit/visualization/timeline/interface.py +19 -18
- qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
- qiskit/assembler/__init__.py +0 -42
- qiskit/assembler/assemble_circuits.py +0 -451
- qiskit/assembler/assemble_schedules.py +0 -367
- qiskit/assembler/disassemble.py +0 -310
- qiskit/assembler/run_config.py +0 -77
- qiskit/circuit/bit.py +0 -106
- qiskit/circuit/classicalfunction/__init__.py +0 -152
- qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
- qiskit/circuit/classicalfunction/classical_element.py +0 -54
- qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
- qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
- qiskit/circuit/classicalfunction/exceptions.py +0 -41
- qiskit/circuit/classicalfunction/types.py +0 -18
- qiskit/circuit/classicalfunction/utils.py +0 -91
- qiskit/circuit/classicalregister.py +0 -57
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
- qiskit/circuit/quantumregister.py +0 -75
- qiskit/circuit/register.py +0 -246
- qiskit/compiler/assembler.py +0 -689
- qiskit/compiler/scheduler.py +0 -109
- qiskit/compiler/sequencer.py +0 -71
- qiskit/primitives/backend_estimator.py +0 -486
- qiskit/primitives/backend_sampler.py +0 -222
- qiskit/primitives/estimator.py +0 -172
- qiskit/primitives/sampler.py +0 -162
- qiskit/providers/backend_compat.py +0 -507
- qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
- qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
- qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
- qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
- qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
- qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
- qiskit/providers/fake_provider/fake_1q.py +0 -91
- qiskit/providers/fake_provider/fake_backend.py +0 -165
- qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
- qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
- qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
- qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
- qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
- qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
- qiskit/providers/models/__init__.py +0 -89
- qiskit/providers/models/backendconfiguration.py +0 -1040
- qiskit/providers/models/backendproperties.py +0 -535
- qiskit/providers/models/backendstatus.py +0 -104
- qiskit/providers/models/jobstatus.py +0 -77
- qiskit/providers/models/pulsedefaults.py +0 -305
- qiskit/providers/provider.py +0 -95
- qiskit/pulse/__init__.py +0 -158
- qiskit/pulse/builder.py +0 -2262
- qiskit/pulse/calibration_entries.py +0 -381
- qiskit/pulse/channels.py +0 -227
- qiskit/pulse/configuration.py +0 -245
- qiskit/pulse/exceptions.py +0 -45
- qiskit/pulse/filters.py +0 -309
- qiskit/pulse/instruction_schedule_map.py +0 -424
- qiskit/pulse/instructions/__init__.py +0 -67
- qiskit/pulse/instructions/acquire.py +0 -150
- qiskit/pulse/instructions/delay.py +0 -71
- qiskit/pulse/instructions/directives.py +0 -154
- qiskit/pulse/instructions/frequency.py +0 -135
- qiskit/pulse/instructions/instruction.py +0 -270
- qiskit/pulse/instructions/phase.py +0 -152
- qiskit/pulse/instructions/play.py +0 -99
- qiskit/pulse/instructions/reference.py +0 -100
- qiskit/pulse/instructions/snapshot.py +0 -82
- qiskit/pulse/library/__init__.py +0 -97
- qiskit/pulse/library/continuous.py +0 -430
- qiskit/pulse/library/pulse.py +0 -148
- qiskit/pulse/library/samplers/__init__.py +0 -15
- qiskit/pulse/library/samplers/decorators.py +0 -295
- qiskit/pulse/library/samplers/strategies.py +0 -71
- qiskit/pulse/library/symbolic_pulses.py +0 -1989
- qiskit/pulse/library/waveform.py +0 -136
- qiskit/pulse/macros.py +0 -262
- qiskit/pulse/parameter_manager.py +0 -445
- qiskit/pulse/parser.py +0 -314
- qiskit/pulse/reference_manager.py +0 -58
- qiskit/pulse/schedule.py +0 -1854
- qiskit/pulse/transforms/__init__.py +0 -106
- qiskit/pulse/transforms/alignments.py +0 -406
- qiskit/pulse/transforms/base_transforms.py +0 -71
- qiskit/pulse/transforms/canonicalization.py +0 -498
- qiskit/pulse/transforms/dag.py +0 -122
- qiskit/pulse/utils.py +0 -149
- qiskit/qobj/__init__.py +0 -75
- qiskit/qobj/common.py +0 -81
- qiskit/qobj/converters/__init__.py +0 -18
- qiskit/qobj/converters/lo_config.py +0 -177
- qiskit/qobj/converters/pulse_instruction.py +0 -897
- qiskit/qobj/pulse_qobj.py +0 -709
- qiskit/qobj/qasm_qobj.py +0 -708
- qiskit/qobj/utils.py +0 -46
- qiskit/result/mitigation/base_readout_mitigator.py +0 -79
- qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
- qiskit/result/mitigation/local_readout_mitigator.py +0 -328
- qiskit/result/mitigation/utils.py +0 -217
- qiskit/scheduler/__init__.py +0 -40
- qiskit/scheduler/config.py +0 -37
- qiskit/scheduler/lowering.py +0 -187
- qiskit/scheduler/methods/__init__.py +0 -15
- qiskit/scheduler/methods/basic.py +0 -140
- qiskit/scheduler/schedule_circuit.py +0 -69
- qiskit/scheduler/sequence.py +0 -104
- qiskit/transpiler/passes/calibration/__init__.py +0 -17
- qiskit/transpiler/passes/calibration/base_builder.py +0 -79
- qiskit/transpiler/passes/calibration/builders.py +0 -20
- qiskit/transpiler/passes/calibration/exceptions.py +0 -22
- qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
- qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
- qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
- qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
- qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
- qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
- qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
- qiskit/transpiler/passes/scheduling/alap.py +0 -153
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
- qiskit/transpiler/passes/scheduling/asap.py +0 -175
- qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
- qiskit/utils/deprecate_pulse.py +0 -119
- qiskit/utils/multiprocessing.py +0 -56
- qiskit/visualization/pulse_v2/__init__.py +0 -21
- qiskit/visualization/pulse_v2/core.py +0 -901
- qiskit/visualization/pulse_v2/device_info.py +0 -173
- qiskit/visualization/pulse_v2/drawings.py +0 -253
- qiskit/visualization/pulse_v2/events.py +0 -254
- qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
- qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
- qiskit/visualization/pulse_v2/generators/chart.py +0 -208
- qiskit/visualization/pulse_v2/generators/frame.py +0 -436
- qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
- qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
- qiskit/visualization/pulse_v2/interface.py +0 -459
- qiskit/visualization/pulse_v2/layouts.py +0 -387
- qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
- qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
- qiskit/visualization/pulse_v2/stylesheet.py +0 -312
- qiskit/visualization/pulse_v2/types.py +0 -242
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
- {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -1,532 +0,0 @@
|
|
1
|
-
# This code is part of Qiskit.
|
2
|
-
#
|
3
|
-
# (C) Copyright IBM 2017, 2018.
|
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
|
-
"""Map a DAGCircuit onto a ``coupling_map`` adding swap gates."""
|
14
|
-
|
15
|
-
import itertools
|
16
|
-
import logging
|
17
|
-
from math import inf
|
18
|
-
import numpy as np
|
19
|
-
|
20
|
-
from qiskit.converters import dag_to_circuit, circuit_to_dag
|
21
|
-
from qiskit.circuit.classical import expr, types
|
22
|
-
from qiskit.circuit.quantumregister import QuantumRegister
|
23
|
-
from qiskit.transpiler.basepasses import TransformationPass
|
24
|
-
from qiskit.transpiler.exceptions import TranspilerError
|
25
|
-
from qiskit.dagcircuit import DAGCircuit
|
26
|
-
from qiskit.circuit.library.standard_gates import SwapGate
|
27
|
-
from qiskit.transpiler.layout import Layout
|
28
|
-
from qiskit.transpiler.target import Target
|
29
|
-
from qiskit.circuit import (
|
30
|
-
Clbit,
|
31
|
-
IfElseOp,
|
32
|
-
WhileLoopOp,
|
33
|
-
ForLoopOp,
|
34
|
-
SwitchCaseOp,
|
35
|
-
ControlFlowOp,
|
36
|
-
CASE_DEFAULT,
|
37
|
-
)
|
38
|
-
from qiskit._accelerate import stochastic_swap as stochastic_swap_rs
|
39
|
-
from qiskit._accelerate import nlayout
|
40
|
-
from qiskit.transpiler.passes.layout import disjoint_utils
|
41
|
-
from qiskit.utils import deprecate_func
|
42
|
-
|
43
|
-
from .utils import get_swap_map_dag
|
44
|
-
|
45
|
-
logger = logging.getLogger(__name__)
|
46
|
-
|
47
|
-
|
48
|
-
class StochasticSwap(TransformationPass):
|
49
|
-
"""Map a DAGCircuit onto a `coupling_map` adding swap gates.
|
50
|
-
|
51
|
-
Uses a randomized algorithm.
|
52
|
-
|
53
|
-
Notes:
|
54
|
-
1. Measurements may occur and be followed by swaps that result in repeated
|
55
|
-
measurement of the same qubit. Near-term experiments cannot implement
|
56
|
-
these circuits, so some care is required when using this mapper
|
57
|
-
with experimental backend targets.
|
58
|
-
|
59
|
-
2. We do not use the fact that the input state is zero to simplify
|
60
|
-
the circuit.
|
61
|
-
"""
|
62
|
-
|
63
|
-
@deprecate_func(
|
64
|
-
since="1.3",
|
65
|
-
removal_timeline="in the 2.0 release",
|
66
|
-
additional_msg="The StochasticSwap transpilation pass is a suboptimal "
|
67
|
-
"routing algorithm and has been superseded by the SabreSwap pass.",
|
68
|
-
)
|
69
|
-
def __init__(self, coupling_map, trials=20, seed=None, fake_run=False, initial_layout=None):
|
70
|
-
"""StochasticSwap initializer.
|
71
|
-
|
72
|
-
The coupling map is a connected graph
|
73
|
-
|
74
|
-
If these are not satisfied, the behavior is undefined.
|
75
|
-
|
76
|
-
Args:
|
77
|
-
coupling_map (Union[CouplingMap, Target]): Directed graph representing a coupling
|
78
|
-
map.
|
79
|
-
trials (int): maximum number of iterations to attempt
|
80
|
-
seed (int): seed for random number generator
|
81
|
-
fake_run (bool): if true, it will only pretend to do routing, i.e., no
|
82
|
-
swap is effectively added.
|
83
|
-
initial_layout (Layout): starting layout at beginning of pass.
|
84
|
-
"""
|
85
|
-
super().__init__()
|
86
|
-
|
87
|
-
if isinstance(coupling_map, Target):
|
88
|
-
self.target = coupling_map
|
89
|
-
self.coupling_map = self.target.build_coupling_map()
|
90
|
-
else:
|
91
|
-
self.target = None
|
92
|
-
self.coupling_map = coupling_map
|
93
|
-
self.trials = trials
|
94
|
-
self.seed = seed
|
95
|
-
self.rng = None
|
96
|
-
self.fake_run = fake_run
|
97
|
-
self.qregs = None
|
98
|
-
self.initial_layout = initial_layout
|
99
|
-
self._int_to_qubit = None
|
100
|
-
|
101
|
-
def run(self, dag):
|
102
|
-
"""Run the StochasticSwap pass on `dag`.
|
103
|
-
|
104
|
-
Args:
|
105
|
-
dag (DAGCircuit): DAG to map.
|
106
|
-
|
107
|
-
Returns:
|
108
|
-
DAGCircuit: A mapped DAG.
|
109
|
-
|
110
|
-
Raises:
|
111
|
-
TranspilerError: if the coupling map or the layout are not
|
112
|
-
compatible with the DAG, or if the coupling_map=None
|
113
|
-
"""
|
114
|
-
|
115
|
-
if self.coupling_map is None:
|
116
|
-
raise TranspilerError("StochasticSwap cannot run with coupling_map=None")
|
117
|
-
|
118
|
-
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
|
119
|
-
raise TranspilerError("StochasticSwap runs on physical circuits only")
|
120
|
-
|
121
|
-
if len(dag.qubits) > len(self.coupling_map.physical_qubits):
|
122
|
-
raise TranspilerError("The layout does not match the amount of qubits in the DAG")
|
123
|
-
disjoint_utils.require_layout_isolated_to_component(
|
124
|
-
dag, self.coupling_map if self.target is None else self.target
|
125
|
-
)
|
126
|
-
|
127
|
-
self.rng = np.random.default_rng(self.seed)
|
128
|
-
|
129
|
-
canonical_register = dag.qregs["q"]
|
130
|
-
if self.initial_layout is None:
|
131
|
-
self.initial_layout = Layout.generate_trivial_layout(canonical_register)
|
132
|
-
# Qubit indices are used to assign an integer to each virtual qubit during the routing: it's
|
133
|
-
# a mapping of {virtual: virtual}, for converting between Python and Rust forms.
|
134
|
-
self._int_to_qubit = tuple(dag.qubits)
|
135
|
-
|
136
|
-
self.qregs = dag.qregs
|
137
|
-
logger.debug("StochasticSwap rng seeded with seed=%s", self.seed)
|
138
|
-
self.coupling_map.compute_distance_matrix()
|
139
|
-
new_dag = self._mapper(dag, self.coupling_map, trials=self.trials)
|
140
|
-
return new_dag
|
141
|
-
|
142
|
-
def _layer_permutation(self, dag, layer_partition, layout, qubit_subset, coupling, trials):
|
143
|
-
"""Find a swap circuit that implements a permutation for this layer.
|
144
|
-
|
145
|
-
The goal is to swap qubits such that qubits in the same two-qubit gates
|
146
|
-
are adjacent.
|
147
|
-
|
148
|
-
Based on S. Bravyi's algorithm.
|
149
|
-
|
150
|
-
Args:
|
151
|
-
layer_partition (list): The layer_partition is a list of (qu)bit
|
152
|
-
lists and each qubit is a tuple (qreg, index).
|
153
|
-
layout (Layout): The layout is a Layout object mapping virtual
|
154
|
-
qubits in the input circuit to physical qubits in the coupling
|
155
|
-
graph. It reflects the current positions of the data.
|
156
|
-
qubit_subset (list): The qubit_subset is the set of qubits in
|
157
|
-
the coupling graph that we have chosen to map into, as tuples
|
158
|
-
(Register, index).
|
159
|
-
coupling (CouplingMap): Directed graph representing a coupling map.
|
160
|
-
This coupling map should be one that was provided to the
|
161
|
-
stochastic mapper.
|
162
|
-
trials (int): Number of attempts the randomized algorithm makes.
|
163
|
-
|
164
|
-
Returns:
|
165
|
-
Tuple: success_flag, best_circuit, best_depth, best_layout
|
166
|
-
|
167
|
-
If success_flag is True, then best_circuit contains a DAGCircuit with
|
168
|
-
the swap circuit, best_depth contains the depth of the swap circuit,
|
169
|
-
and best_layout contains the new positions of the data qubits after the
|
170
|
-
swap circuit has been applied.
|
171
|
-
|
172
|
-
Raises:
|
173
|
-
TranspilerError: if anything went wrong.
|
174
|
-
"""
|
175
|
-
logger.debug("layer_permutation: layer_partition = %s", layer_partition)
|
176
|
-
logger.debug("layer_permutation: layout = %s", layout.get_virtual_bits())
|
177
|
-
logger.debug("layer_permutation: qubit_subset = %s", qubit_subset)
|
178
|
-
logger.debug("layer_permutation: trials = %s", trials)
|
179
|
-
|
180
|
-
# The input dag is on a flat canonical register
|
181
|
-
canonical_register = QuantumRegister(len(layout), "q")
|
182
|
-
|
183
|
-
gates = [] # list of lists of tuples [[(register, index), ...], ...]
|
184
|
-
for gate_args in layer_partition:
|
185
|
-
if len(gate_args) > 2:
|
186
|
-
raise TranspilerError("Layer contains > 2-qubit gates")
|
187
|
-
if len(gate_args) == 2:
|
188
|
-
gates.append(tuple(gate_args))
|
189
|
-
logger.debug("layer_permutation: gates = %s", gates)
|
190
|
-
|
191
|
-
# Can we already apply the gates? If so, there is no work to do.
|
192
|
-
# Accessing via private attributes to avoid overhead from __getitem__
|
193
|
-
# and to optimize performance of the distance matrix access
|
194
|
-
dist = sum(coupling._dist_matrix[layout._v2p[g[0]], layout._v2p[g[1]]] for g in gates)
|
195
|
-
logger.debug("layer_permutation: distance = %s", dist)
|
196
|
-
if dist == len(gates):
|
197
|
-
logger.debug("layer_permutation: nothing to do")
|
198
|
-
circ = DAGCircuit()
|
199
|
-
circ.add_qreg(canonical_register)
|
200
|
-
return True, circ, 0, layout
|
201
|
-
|
202
|
-
# Begin loop over trials of randomized algorithm
|
203
|
-
num_qubits = len(layout)
|
204
|
-
best_depth = inf # initialize best depth
|
205
|
-
best_edges = None # best edges found
|
206
|
-
best_circuit = None # initialize best swap circuit
|
207
|
-
best_layout = None # initialize best final layout
|
208
|
-
|
209
|
-
cdist2 = coupling._dist_matrix**2
|
210
|
-
int_qubit_subset = np.fromiter(
|
211
|
-
(dag.find_bit(bit).index for bit in qubit_subset),
|
212
|
-
dtype=np.uint32,
|
213
|
-
count=len(qubit_subset),
|
214
|
-
)
|
215
|
-
|
216
|
-
int_gates = np.fromiter(
|
217
|
-
(dag.find_bit(bit).index for gate in gates for bit in gate),
|
218
|
-
dtype=np.uint32,
|
219
|
-
count=2 * len(gates),
|
220
|
-
)
|
221
|
-
|
222
|
-
layout_mapping = {dag.find_bit(k).index: v for k, v in layout.get_virtual_bits().items()}
|
223
|
-
int_layout = nlayout.NLayout(layout_mapping, num_qubits, coupling.size())
|
224
|
-
|
225
|
-
trial_circuit = DAGCircuit() # SWAP circuit for slice of swaps in this trial
|
226
|
-
trial_circuit.add_qubits(list(layout.get_virtual_bits()))
|
227
|
-
|
228
|
-
edges = np.asarray(coupling.get_edges(), dtype=np.uint32).ravel()
|
229
|
-
cdist = coupling._dist_matrix
|
230
|
-
best_edges, best_layout, best_depth = stochastic_swap_rs.swap_trials(
|
231
|
-
trials,
|
232
|
-
num_qubits,
|
233
|
-
int_layout,
|
234
|
-
int_qubit_subset,
|
235
|
-
int_gates,
|
236
|
-
cdist,
|
237
|
-
cdist2,
|
238
|
-
edges,
|
239
|
-
seed=self.seed,
|
240
|
-
)
|
241
|
-
# If we have no best circuit for this layer, all of the trials have failed
|
242
|
-
if best_layout is None:
|
243
|
-
logger.debug("layer_permutation: failed!")
|
244
|
-
return False, None, None, None
|
245
|
-
|
246
|
-
edges = best_edges.edges()
|
247
|
-
for idx in range(len(edges) // 2):
|
248
|
-
swap_src = self._int_to_qubit[edges[2 * idx]]
|
249
|
-
swap_tgt = self._int_to_qubit[edges[2 * idx + 1]]
|
250
|
-
trial_circuit.apply_operation_back(SwapGate(), (swap_src, swap_tgt), (), check=False)
|
251
|
-
best_circuit = trial_circuit
|
252
|
-
|
253
|
-
# Otherwise, we return our result for this layer
|
254
|
-
logger.debug("layer_permutation: success!")
|
255
|
-
layout_mapping = best_layout.layout_mapping()
|
256
|
-
|
257
|
-
best_lay = Layout({best_circuit.qubits[k]: v for (k, v) in layout_mapping})
|
258
|
-
return True, best_circuit, best_depth, best_lay
|
259
|
-
|
260
|
-
def _layer_update(self, dag, layer, best_layout, best_depth, best_circuit):
|
261
|
-
"""Add swaps followed by the now mapped layer from the original circuit.
|
262
|
-
|
263
|
-
Args:
|
264
|
-
dag (DAGCircuit): The DAGCircuit object that the _mapper method is building
|
265
|
-
layer (DAGCircuit): A DAGCircuit layer from the original circuit
|
266
|
-
best_layout (Layout): layout returned from _layer_permutation
|
267
|
-
best_depth (int): depth returned from _layer_permutation
|
268
|
-
best_circuit (DAGCircuit): swap circuit returned from _layer_permutation
|
269
|
-
"""
|
270
|
-
logger.debug("layer_update: layout = %s", best_layout)
|
271
|
-
logger.debug("layer_update: self.initial_layout = %s", self.initial_layout)
|
272
|
-
|
273
|
-
# Output any swaps
|
274
|
-
if best_depth > 0:
|
275
|
-
logger.debug("layer_update: there are swaps in this layer, depth %d", best_depth)
|
276
|
-
dag.compose(best_circuit, qubits=list(best_circuit.qubits), inline_captures=True)
|
277
|
-
else:
|
278
|
-
logger.debug("layer_update: there are no swaps in this layer")
|
279
|
-
# Output this layer
|
280
|
-
dag.compose(
|
281
|
-
layer["graph"], qubits=best_layout.reorder_bits(dag.qubits), inline_captures=True
|
282
|
-
)
|
283
|
-
|
284
|
-
def _mapper(self, circuit_graph, coupling_graph, trials=20):
|
285
|
-
"""Map a DAGCircuit onto a CouplingMap using swap gates.
|
286
|
-
|
287
|
-
Args:
|
288
|
-
circuit_graph (DAGCircuit): input DAG circuit
|
289
|
-
coupling_graph (CouplingMap): coupling graph to map onto
|
290
|
-
trials (int): number of trials.
|
291
|
-
|
292
|
-
Returns:
|
293
|
-
DAGCircuit: object containing a circuit equivalent to
|
294
|
-
circuit_graph that respects couplings in coupling_graph
|
295
|
-
|
296
|
-
Raises:
|
297
|
-
TranspilerError: if there was any error during the mapping
|
298
|
-
or with the parameters.
|
299
|
-
"""
|
300
|
-
# Schedule the input circuit by calling layers()
|
301
|
-
layerlist = list(circuit_graph.layers())
|
302
|
-
logger.debug("schedule:")
|
303
|
-
for i, v in enumerate(layerlist):
|
304
|
-
logger.debug(" %d: %s", i, v["partition"])
|
305
|
-
|
306
|
-
qubit_subset = self.initial_layout.get_virtual_bits().keys()
|
307
|
-
|
308
|
-
# Find swap circuit to precede each layer of input circuit
|
309
|
-
layout = self.initial_layout.copy()
|
310
|
-
|
311
|
-
# Construct an empty DAGCircuit with the same set of
|
312
|
-
# qregs and cregs as the input circuit
|
313
|
-
dagcircuit_output = None
|
314
|
-
if not self.fake_run:
|
315
|
-
dagcircuit_output = circuit_graph.copy_empty_like()
|
316
|
-
|
317
|
-
logger.debug("layout = %s", layout)
|
318
|
-
|
319
|
-
# Iterate over layers
|
320
|
-
for i, layer in enumerate(layerlist):
|
321
|
-
# First try and compute a route for the entire layer in one go.
|
322
|
-
if not layer["graph"].op_nodes(op=ControlFlowOp):
|
323
|
-
success_flag, best_circuit, best_depth, best_layout = self._layer_permutation(
|
324
|
-
circuit_graph, layer["partition"], layout, qubit_subset, coupling_graph, trials
|
325
|
-
)
|
326
|
-
|
327
|
-
logger.debug("mapper: layer %d", i)
|
328
|
-
logger.debug("mapper: success_flag=%s,best_depth=%s", success_flag, str(best_depth))
|
329
|
-
if success_flag:
|
330
|
-
layout = best_layout
|
331
|
-
|
332
|
-
# Update the DAG
|
333
|
-
if not self.fake_run:
|
334
|
-
self._layer_update(
|
335
|
-
dagcircuit_output, layer, best_layout, best_depth, best_circuit
|
336
|
-
)
|
337
|
-
continue
|
338
|
-
|
339
|
-
# If we're here, we need to go through every gate in the layer serially.
|
340
|
-
logger.debug("mapper: failed, layer %d, retrying sequentially", i)
|
341
|
-
# Go through each gate in the layer
|
342
|
-
for j, serial_layer in enumerate(layer["graph"].serial_layers()):
|
343
|
-
layer_dag = serial_layer["graph"]
|
344
|
-
# layer_dag has only one operation
|
345
|
-
op_node = layer_dag.op_nodes()[0]
|
346
|
-
if isinstance(op_node.op, ControlFlowOp):
|
347
|
-
layout = self._controlflow_layer_update(
|
348
|
-
dagcircuit_output, layer_dag, layout, circuit_graph
|
349
|
-
)
|
350
|
-
else:
|
351
|
-
(success_flag, best_circuit, best_depth, best_layout) = self._layer_permutation(
|
352
|
-
circuit_graph,
|
353
|
-
serial_layer["partition"],
|
354
|
-
layout,
|
355
|
-
qubit_subset,
|
356
|
-
coupling_graph,
|
357
|
-
trials,
|
358
|
-
)
|
359
|
-
logger.debug("mapper: layer %d, sublayer %d", i, j)
|
360
|
-
logger.debug(
|
361
|
-
"mapper: success_flag=%s,best_depth=%s,", success_flag, str(best_depth)
|
362
|
-
)
|
363
|
-
|
364
|
-
# Give up if we fail again
|
365
|
-
if not success_flag:
|
366
|
-
raise TranspilerError(f"swap mapper failed: layer {i}, sublayer {j}")
|
367
|
-
|
368
|
-
# Update the record of qubit positions
|
369
|
-
# for each inner iteration
|
370
|
-
layout = best_layout
|
371
|
-
# Update the DAG
|
372
|
-
if not self.fake_run:
|
373
|
-
self._layer_update(
|
374
|
-
dagcircuit_output,
|
375
|
-
serial_layer,
|
376
|
-
best_layout,
|
377
|
-
best_depth,
|
378
|
-
best_circuit,
|
379
|
-
)
|
380
|
-
|
381
|
-
# This is the final edgemap. We might use it to correctly replace
|
382
|
-
# any measurements that needed to be removed earlier.
|
383
|
-
logger.debug("mapper: self.initial_layout = %s", self.initial_layout)
|
384
|
-
logger.debug("mapper: layout = %s", layout)
|
385
|
-
if self.property_set["final_layout"] is None:
|
386
|
-
self.property_set["final_layout"] = layout
|
387
|
-
else:
|
388
|
-
self.property_set["final_layout"] = layout.compose(
|
389
|
-
self.property_set["final_layout"], circuit_graph.qubits
|
390
|
-
)
|
391
|
-
|
392
|
-
if self.fake_run:
|
393
|
-
return circuit_graph
|
394
|
-
return dagcircuit_output
|
395
|
-
|
396
|
-
def _controlflow_layer_update(self, dagcircuit_output, layer_dag, current_layout, root_dag):
|
397
|
-
"""
|
398
|
-
Updates the new dagcircuit with a routed control flow operation.
|
399
|
-
|
400
|
-
Args:
|
401
|
-
dagcircuit_output (DAGCircuit): dagcircuit that is being built with routed operations.
|
402
|
-
layer_dag (DAGCircuit): layer to route containing a single controlflow operation.
|
403
|
-
current_layout (Layout): current layout coming into this layer.
|
404
|
-
root_dag (DAGCircuit): root dag of pass
|
405
|
-
|
406
|
-
Returns:
|
407
|
-
Layout: updated layout after this layer has been routed.
|
408
|
-
|
409
|
-
Raises:
|
410
|
-
TranspilerError: if layer_dag does not contain a recognized ControlFlowOp.
|
411
|
-
|
412
|
-
"""
|
413
|
-
node = layer_dag.op_nodes()[0]
|
414
|
-
if not isinstance(node.op, (IfElseOp, ForLoopOp, WhileLoopOp, SwitchCaseOp)):
|
415
|
-
raise TranspilerError(f"unsupported control flow operation: {node}")
|
416
|
-
# For each block, expand it up be the full width of the containing DAG so we can be certain
|
417
|
-
# that it is routable, then route it within that. When we recombine later, we'll reduce all
|
418
|
-
# these blocks down to remove any qubits that are idle.
|
419
|
-
block_dags = []
|
420
|
-
block_layouts = []
|
421
|
-
for block in node.op.blocks:
|
422
|
-
inner_pass = self._recursive_pass(current_layout)
|
423
|
-
block_dags.append(inner_pass.run(_dag_from_block(block, node, root_dag)))
|
424
|
-
block_layouts.append(inner_pass.property_set["final_layout"].copy())
|
425
|
-
|
426
|
-
# Determine what layout we need to go towards. For some blocks (such as `for`), we must
|
427
|
-
# guarantee that the final layout is the same as the initial or the loop won't work.
|
428
|
-
if _controlflow_exhaustive_acyclic(node.op):
|
429
|
-
# We heuristically just choose to use the layout of whatever the deepest block is, to
|
430
|
-
# avoid extending the total depth by too much.
|
431
|
-
final_layout = max(
|
432
|
-
zip(block_layouts, block_dags), key=lambda x: x[1].depth(recurse=True)
|
433
|
-
)[0]
|
434
|
-
else:
|
435
|
-
final_layout = current_layout
|
436
|
-
if self.fake_run:
|
437
|
-
return final_layout
|
438
|
-
|
439
|
-
# Add swaps to the end of each block to make sure they all have the same layout at the end.
|
440
|
-
# Adding these swaps can cause fewer wires to be idle than we expect (if we have to swap
|
441
|
-
# across unused qubits), so we track that at this point too.
|
442
|
-
idle_qubits = set(root_dag.qubits)
|
443
|
-
for layout, updated_dag_block in zip(block_layouts, block_dags):
|
444
|
-
swap_dag, swap_qubits = get_swap_map_dag(
|
445
|
-
root_dag, self.coupling_map, layout, final_layout, seed=self._new_seed()
|
446
|
-
)
|
447
|
-
if swap_dag.size(recurse=False):
|
448
|
-
updated_dag_block.compose(swap_dag, qubits=swap_qubits, inline_captures=True)
|
449
|
-
idle_qubits &= set(updated_dag_block.idle_wires())
|
450
|
-
|
451
|
-
# Now for each block, expand it to be full width over all active wires (all blocks of a
|
452
|
-
# control-flow operation need to have equal input wires), and convert it to circuit form.
|
453
|
-
block_circuits = []
|
454
|
-
for updated_dag_block in block_dags:
|
455
|
-
updated_dag_block.remove_qubits(*idle_qubits)
|
456
|
-
block_circuits.append(dag_to_circuit(updated_dag_block))
|
457
|
-
|
458
|
-
new_op = node.op.replace_blocks(block_circuits)
|
459
|
-
new_qargs = block_circuits[0].qubits
|
460
|
-
dagcircuit_output.apply_operation_back(new_op, new_qargs, node.cargs, check=False)
|
461
|
-
return final_layout
|
462
|
-
|
463
|
-
def _new_seed(self):
|
464
|
-
"""Get a seed for a new RNG instance."""
|
465
|
-
return self.rng.integers(0x7FFF_FFFF_FFFF_FFFF)
|
466
|
-
|
467
|
-
def _recursive_pass(self, initial_layout):
|
468
|
-
"""Get a new instance of this class to handle a recursive call for a control-flow block.
|
469
|
-
|
470
|
-
Each pass starts with its own new seed, determined deterministically from our own."""
|
471
|
-
return self.__class__(
|
472
|
-
self.coupling_map,
|
473
|
-
# This doesn't cause an exponential explosion of the trials because we only generate a
|
474
|
-
# recursive pass instance for control-flow operations, while the trial multiplicity is
|
475
|
-
# only for non-control-flow layers.
|
476
|
-
trials=self.trials,
|
477
|
-
seed=self._new_seed(),
|
478
|
-
fake_run=self.fake_run,
|
479
|
-
initial_layout=initial_layout,
|
480
|
-
)
|
481
|
-
|
482
|
-
|
483
|
-
def _controlflow_exhaustive_acyclic(operation: ControlFlowOp):
|
484
|
-
"""Return True if the entire control-flow operation represents a block that is guaranteed to be
|
485
|
-
entered, and does not cycle back to the initial layout."""
|
486
|
-
if isinstance(operation, IfElseOp):
|
487
|
-
return len(operation.blocks) == 2
|
488
|
-
if isinstance(operation, SwitchCaseOp):
|
489
|
-
cases = operation.cases()
|
490
|
-
if isinstance(operation.target, expr.Expr):
|
491
|
-
type_ = operation.target.type
|
492
|
-
if type_.kind is types.Bool:
|
493
|
-
max_matches = 2
|
494
|
-
elif type_.kind is types.Uint:
|
495
|
-
max_matches = 1 << type_.width
|
496
|
-
else:
|
497
|
-
raise RuntimeError(f"unhandled target type: '{type_}'")
|
498
|
-
else:
|
499
|
-
max_matches = 2 if isinstance(operation.target, Clbit) else 1 << len(operation.target)
|
500
|
-
return CASE_DEFAULT in cases or len(cases) == max_matches
|
501
|
-
return False
|
502
|
-
|
503
|
-
|
504
|
-
def _dag_from_block(block, node, root_dag):
|
505
|
-
"""Get a :class:`DAGCircuit` that represents the :class:`.QuantumCircuit` ``block`` embedded
|
506
|
-
within the ``root_dag`` for full-width routing purposes. This means that all the qubits are in
|
507
|
-
the output DAG, but only the necessary clbits and classical registers are."""
|
508
|
-
out = DAGCircuit()
|
509
|
-
# The pass already ensured that `root_dag` has only a single quantum register with everything.
|
510
|
-
for qreg in root_dag.qregs.values():
|
511
|
-
out.add_qreg(qreg)
|
512
|
-
# For clbits, we need to take more care. Nested control-flow might need registers to exist for
|
513
|
-
# conditions on inner blocks. `DAGCircuit.substitute_node_with_dag` handles this register
|
514
|
-
# mapping when required, so we use that with a dummy block that pretends to act on all variables
|
515
|
-
# in the DAG.
|
516
|
-
out.add_clbits(node.cargs)
|
517
|
-
for var in block.iter_input_vars():
|
518
|
-
out.add_input_var(var)
|
519
|
-
for var in block.iter_captured_vars():
|
520
|
-
out.add_captured_var(var)
|
521
|
-
for var in block.iter_declared_vars():
|
522
|
-
out.add_declared_var(var)
|
523
|
-
|
524
|
-
dummy = out.apply_operation_back(
|
525
|
-
IfElseOp(expr.lift(True), block.copy_empty_like(vars_mode="captures")),
|
526
|
-
node.qargs,
|
527
|
-
node.cargs,
|
528
|
-
check=False,
|
529
|
-
)
|
530
|
-
wire_map = dict(itertools.chain(zip(block.qubits, node.qargs), zip(block.clbits, node.cargs)))
|
531
|
-
out.substitute_node_with_dag(dummy, circuit_to_dag(block), wires=wire_map)
|
532
|
-
return out
|
@@ -1,153 +0,0 @@
|
|
1
|
-
# This code is part of Qiskit.
|
2
|
-
#
|
3
|
-
# (C) Copyright IBM 2020.
|
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
|
-
"""ALAP Scheduling."""
|
14
|
-
|
15
|
-
from qiskit.circuit import Delay, Qubit, Measure
|
16
|
-
from qiskit.dagcircuit import DAGCircuit
|
17
|
-
from qiskit.transpiler.exceptions import TranspilerError
|
18
|
-
from qiskit.transpiler.passes.scheduling.base_scheduler import BaseSchedulerTransform
|
19
|
-
from qiskit.utils.deprecation import deprecate_func
|
20
|
-
|
21
|
-
|
22
|
-
class ALAPSchedule(BaseSchedulerTransform):
|
23
|
-
"""ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible.
|
24
|
-
|
25
|
-
See :class:`~qiskit.transpiler.passes.scheduling.base_scheduler.BaseSchedulerTransform` for the
|
26
|
-
detailed behavior of the control flow operation, i.e. ``c_if``.
|
27
|
-
"""
|
28
|
-
|
29
|
-
@deprecate_func(
|
30
|
-
additional_msg=(
|
31
|
-
"Instead, use :class:`~.ALAPScheduleAnalysis`, which is an "
|
32
|
-
"analysis pass that requires a padding pass to later modify the circuit."
|
33
|
-
),
|
34
|
-
since="1.1.0",
|
35
|
-
)
|
36
|
-
def __init__(self, *args, **kwargs):
|
37
|
-
super().__init__(*args, **kwargs)
|
38
|
-
|
39
|
-
def run(self, dag):
|
40
|
-
"""Run the ALAPSchedule pass on `dag`.
|
41
|
-
|
42
|
-
Args:
|
43
|
-
dag (DAGCircuit): DAG to schedule.
|
44
|
-
|
45
|
-
Returns:
|
46
|
-
DAGCircuit: A scheduled DAG.
|
47
|
-
|
48
|
-
Raises:
|
49
|
-
TranspilerError: if the circuit is not mapped on physical qubits.
|
50
|
-
TranspilerError: if conditional bit is added to non-supported instruction.
|
51
|
-
"""
|
52
|
-
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
|
53
|
-
raise TranspilerError("ALAP schedule runs on physical circuits only")
|
54
|
-
|
55
|
-
time_unit = self.property_set["time_unit"]
|
56
|
-
new_dag = DAGCircuit()
|
57
|
-
for qreg in dag.qregs.values():
|
58
|
-
new_dag.add_qreg(qreg)
|
59
|
-
for creg in dag.cregs.values():
|
60
|
-
new_dag.add_creg(creg)
|
61
|
-
|
62
|
-
idle_before = {q: 0 for q in dag.qubits + dag.clbits}
|
63
|
-
for node in reversed(list(dag.topological_op_nodes())):
|
64
|
-
op_duration = self._get_node_duration(node, dag)
|
65
|
-
|
66
|
-
# compute t0, t1: instruction interval, note that
|
67
|
-
# t0: start time of instruction
|
68
|
-
# t1: end time of instruction
|
69
|
-
|
70
|
-
# since this is alap scheduling, node is scheduled in reversed topological ordering
|
71
|
-
# and nodes are packed from the very end of the circuit.
|
72
|
-
# the physical meaning of t0 and t1 is flipped here.
|
73
|
-
if isinstance(node.op, self.CONDITIONAL_SUPPORTED):
|
74
|
-
t0q = max(idle_before[q] for q in node.qargs)
|
75
|
-
if node.op.condition_bits:
|
76
|
-
# conditional is bit tricky due to conditional_latency
|
77
|
-
t0c = max(idle_before[c] for c in node.op.condition_bits)
|
78
|
-
# Assume following case (t0c > t0q):
|
79
|
-
#
|
80
|
-
# |t0q
|
81
|
-
# Q ░░░░░░░░░░░░░▒▒▒
|
82
|
-
# C ░░░░░░░░▒▒▒▒▒▒▒▒
|
83
|
-
# |t0c
|
84
|
-
#
|
85
|
-
# In this case, there is no actual clbit read before gate.
|
86
|
-
#
|
87
|
-
# |t0q' = t0c - conditional_latency
|
88
|
-
# Q ░░░░░░░░▒▒▒░░▒▒▒
|
89
|
-
# C ░░░░░░▒▒▒▒▒▒▒▒▒▒
|
90
|
-
# |t1c' = t0c + conditional_latency
|
91
|
-
#
|
92
|
-
# rather than naively doing
|
93
|
-
#
|
94
|
-
# |t1q' = t0c + duration
|
95
|
-
# Q ░░░░░▒▒▒░░░░░▒▒▒
|
96
|
-
# C ░░▒▒░░░░▒▒▒▒▒▒▒▒
|
97
|
-
# |t1c' = t0c + duration + conditional_latency
|
98
|
-
#
|
99
|
-
t0 = max(t0q, t0c - op_duration)
|
100
|
-
t1 = t0 + op_duration
|
101
|
-
for clbit in node.op.condition_bits:
|
102
|
-
idle_before[clbit] = t1 + self.conditional_latency
|
103
|
-
else:
|
104
|
-
t0 = t0q
|
105
|
-
t1 = t0 + op_duration
|
106
|
-
else:
|
107
|
-
if node.op.condition_bits:
|
108
|
-
raise TranspilerError(
|
109
|
-
f"Conditional instruction {node.op.name} is not supported in ALAP scheduler."
|
110
|
-
)
|
111
|
-
|
112
|
-
if isinstance(node.op, Measure):
|
113
|
-
# clbit time is always right (alap) justified
|
114
|
-
t0 = max(idle_before[bit] for bit in node.qargs + node.cargs)
|
115
|
-
t1 = t0 + op_duration
|
116
|
-
#
|
117
|
-
# |t1 = t0 + duration
|
118
|
-
# Q ░░░░░▒▒▒▒▒▒▒▒▒▒▒
|
119
|
-
# C ░░░░░░░░░▒▒▒▒▒▒▒
|
120
|
-
# |t0 + (duration - clbit_write_latency)
|
121
|
-
#
|
122
|
-
for clbit in node.cargs:
|
123
|
-
idle_before[clbit] = t0 + (op_duration - self.clbit_write_latency)
|
124
|
-
else:
|
125
|
-
# It happens to be directives such as barrier
|
126
|
-
t0 = max(idle_before[bit] for bit in node.qargs + node.cargs)
|
127
|
-
t1 = t0 + op_duration
|
128
|
-
|
129
|
-
for bit in node.qargs:
|
130
|
-
delta = t0 - idle_before[bit]
|
131
|
-
if delta > 0 and self._delay_supported(dag.find_bit(bit).index):
|
132
|
-
new_dag.apply_operation_front(Delay(delta, time_unit), [bit], [], check=False)
|
133
|
-
idle_before[bit] = t1
|
134
|
-
|
135
|
-
new_dag.apply_operation_front(node.op, node.qargs, node.cargs, check=False)
|
136
|
-
|
137
|
-
circuit_duration = max(idle_before.values())
|
138
|
-
for bit, before in idle_before.items():
|
139
|
-
delta = circuit_duration - before
|
140
|
-
if not (delta > 0 and isinstance(bit, Qubit)):
|
141
|
-
continue
|
142
|
-
if self._delay_supported(dag.find_bit(bit).index):
|
143
|
-
new_dag.apply_operation_front(Delay(delta, time_unit), [bit], [], check=False)
|
144
|
-
|
145
|
-
new_dag.name = dag.name
|
146
|
-
new_dag.metadata = dag.metadata
|
147
|
-
new_dag._calibrations_prop = dag._calibrations_prop
|
148
|
-
|
149
|
-
# set circuit duration and unit to indicate it is scheduled
|
150
|
-
new_dag.duration = circuit_duration
|
151
|
-
new_dag.unit = time_unit
|
152
|
-
|
153
|
-
return new_dag
|