qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0rc1__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 +2 -5
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/circuit/__init__.py +24 -5
- 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 +248 -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 +34 -5
- 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/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 +2 -6
- 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 +13 -60
- 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 +4 -0
- qiskit/circuit/quantumcircuit.py +881 -555
- 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/compiler/__init__.py +1 -7
- qiskit/compiler/transpiler.py +38 -196
- qiskit/converters/circuit_to_dag.py +4 -2
- 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 +5 -5
- 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 +2 -80
- 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 +141 -19
- qiskit/qpy/binary_io/__init__.py +0 -1
- qiskit/qpy/binary_io/circuits.py +91 -116
- qiskit/qpy/binary_io/schedules.py +61 -388
- qiskit/qpy/binary_io/value.py +154 -28
- 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 -10
- qiskit/result/result.py +28 -126
- 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 +2 -40
- qiskit/transpiler/passes/basis/basis_translator.py +4 -3
- 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 +4 -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 +1 -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 +1 -0
- 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 +30 -2
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
- 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 +127 -59
- 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 +101 -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 +67 -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/dag_visualization.py +2 -1
- qiskit/visualization/gate_map.py +39 -154
- qiskit/visualization/pass_manager_visualization.py +6 -2
- qiskit/visualization/state_visualization.py +6 -0
- qiskit/visualization/timeline/core.py +18 -12
- qiskit/visualization/timeline/interface.py +19 -18
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.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.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,135 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2019.
|
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
|
+
"""Cancel the redundant (self-adjoint) gates through commutation relations."""
|
14
|
+
from __future__ import annotations
|
15
|
+
import warnings
|
16
|
+
from qiskit.circuit import Gate, Qubit
|
17
|
+
from qiskit.circuit.commutation_library import SessionCommutationChecker as scc
|
18
|
+
from qiskit.circuit.library import PauliGate, ZGate
|
19
|
+
from qiskit.dagcircuit import DAGCircuit
|
20
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
21
|
+
from qiskit.transpiler.passes.utils.remove_final_measurements import calc_final_ops
|
22
|
+
|
23
|
+
translation_table = str.maketrans({"+": "X", "-": "X", "l": "Y", "r": "Y", "0": "Z", "1": "Z"})
|
24
|
+
|
25
|
+
|
26
|
+
class LightCone(TransformationPass):
|
27
|
+
"""Remove the gates that do not affect the outcome of a measurement on a circuit.
|
28
|
+
|
29
|
+
Pass for computing the light-cone of an observable or measurement. The Pass can handle
|
30
|
+
either an observable one would like to measure or a measurement on a set of qubits.
|
31
|
+
"""
|
32
|
+
|
33
|
+
def __init__(self, bit_terms: str | None = None, indices: list[int] | None = None) -> None:
|
34
|
+
"""
|
35
|
+
Args:
|
36
|
+
bit_terms: If ``None`` the light-cone will be computed for the set of measurements
|
37
|
+
in the circuit. If a string is specified, the light-cone will correspond to the
|
38
|
+
reduced circuit with the same expectation value for the observable.
|
39
|
+
indices: list of non-trivial indices corresponding to the observable in ``bit_terms``.
|
40
|
+
"""
|
41
|
+
super().__init__()
|
42
|
+
valid_characters = {"X", "Y", "Z", "+", "-", "l", "r", "0", "1"}
|
43
|
+
self.bit_terms = None
|
44
|
+
if bit_terms is not None:
|
45
|
+
if not indices:
|
46
|
+
raise ValueError("`indices` must be non-empty when providing `bit_terms`.")
|
47
|
+
if not set(bit_terms).issubset(valid_characters):
|
48
|
+
raise ValueError(
|
49
|
+
f"`bit_terms` should contain only characters in {valid_characters}."
|
50
|
+
)
|
51
|
+
if len(bit_terms) != len(indices):
|
52
|
+
raise ValueError("`bit_terms` must be the same length as `indices`.")
|
53
|
+
self.bit_terms = bit_terms.translate(translation_table)
|
54
|
+
self.indices = indices
|
55
|
+
|
56
|
+
@staticmethod
|
57
|
+
def _find_measurement_qubits(dag: DAGCircuit) -> set[Qubit]:
|
58
|
+
final_nodes = calc_final_ops(dag, {"measure"})
|
59
|
+
qubits_measured = set()
|
60
|
+
for node in final_nodes:
|
61
|
+
qubits_measured |= set(node.qargs)
|
62
|
+
return qubits_measured
|
63
|
+
|
64
|
+
def _get_initial_lightcone(
|
65
|
+
self, dag: DAGCircuit
|
66
|
+
) -> tuple[set[Qubit], list[tuple[Gate, list[Qubit]]]]:
|
67
|
+
"""Returns the initial light-cone.
|
68
|
+
If observable is `None`, the light-cone is the set of measured qubits.
|
69
|
+
If a `bit_terms` is provided, the qubits corresponding to the
|
70
|
+
non-trivial Paulis define the light-cone.
|
71
|
+
"""
|
72
|
+
lightcone_qubits = self._find_measurement_qubits(dag)
|
73
|
+
if self.bit_terms is None:
|
74
|
+
lightcone_operations = [(ZGate(), [qubit_index]) for qubit_index in lightcone_qubits]
|
75
|
+
else:
|
76
|
+
# Having both measurements and an observable is not allowed
|
77
|
+
if len(dag.qubits) < max(self.indices) + 1:
|
78
|
+
raise ValueError("`indices` contains values outside the qubit range.")
|
79
|
+
if lightcone_qubits:
|
80
|
+
raise ValueError(
|
81
|
+
"The circuit contains measurements and an observable has been given: "
|
82
|
+
"remove the observable or the measurements."
|
83
|
+
)
|
84
|
+
lightcone_qubits = [dag.qubits[i] for i in self.indices]
|
85
|
+
# `lightcone_operations` is a list of tuples, each containing (operation, list_of_qubits)
|
86
|
+
lightcone_operations = [(PauliGate(self.bit_terms), lightcone_qubits)]
|
87
|
+
|
88
|
+
return set(lightcone_qubits), lightcone_operations
|
89
|
+
|
90
|
+
def run(self, dag: DAGCircuit) -> DAGCircuit:
|
91
|
+
"""Run the LightCone pass on `dag`.
|
92
|
+
|
93
|
+
Args:
|
94
|
+
dag: The DAG to reduce.
|
95
|
+
|
96
|
+
Returns:
|
97
|
+
The DAG reduced to the light-cone of the observable.
|
98
|
+
"""
|
99
|
+
|
100
|
+
# Get the initial light-cone and operations
|
101
|
+
lightcone_qubits, lightcone_operations = self._get_initial_lightcone(dag)
|
102
|
+
|
103
|
+
# Initialize a new, empty DAG
|
104
|
+
new_dag = dag.copy_empty_like()
|
105
|
+
|
106
|
+
# Iterate over the nodes in reverse topological order
|
107
|
+
for node in reversed(list(dag.topological_op_nodes())):
|
108
|
+
# Check if the node belongs to the light-cone
|
109
|
+
if lightcone_qubits.intersection(node.qargs):
|
110
|
+
# Check commutation with all previous operations
|
111
|
+
commutes_bool = True
|
112
|
+
for op in lightcone_operations:
|
113
|
+
max_num_qubits = max(len(op[1]), len(node.qargs))
|
114
|
+
if max_num_qubits > 10:
|
115
|
+
warnings.warn(
|
116
|
+
"LightCone pass is checking commutation of"
|
117
|
+
f"operators of size {max_num_qubits}."
|
118
|
+
"This operation can be slow.",
|
119
|
+
category=RuntimeWarning,
|
120
|
+
)
|
121
|
+
commute_bool = scc.commute(
|
122
|
+
op[0], op[1], [], node.op, node.qargs, [], max_num_qubits=max_num_qubits
|
123
|
+
)
|
124
|
+
if not commute_bool:
|
125
|
+
# If the current node does not commute, update the light-cone
|
126
|
+
lightcone_qubits.update(node.qargs)
|
127
|
+
lightcone_operations.append((node.op, node.qargs))
|
128
|
+
commutes_bool = False
|
129
|
+
break
|
130
|
+
|
131
|
+
# If the node is in the light-cone and commutes with previous `ops`,
|
132
|
+
# add it to the new DAG at the front
|
133
|
+
if not commutes_bool:
|
134
|
+
new_dag.apply_operation_front(node.op, node.qargs, node.cargs)
|
135
|
+
return new_dag
|
@@ -224,7 +224,6 @@ class Optimize1qGatesSimpleCommutation(TransformationPass):
|
|
224
224
|
|
225
225
|
# perform the replacement if it was indeed a good idea
|
226
226
|
if self._optimize1q._substitution_checks(
|
227
|
-
dag,
|
228
227
|
(preceding_run or []) + run + (succeeding_run or []),
|
229
228
|
new_preceding_run.op_nodes() + new_run.op_nodes() + new_succeeding_run.op_nodes(),
|
230
229
|
self._optimize1q._basis_gates,
|
@@ -63,7 +63,6 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
63
63
|
The decision to replace the original chain with a new re-synthesis depends on:
|
64
64
|
- whether the original chain was out of basis: replace
|
65
65
|
- whether the original chain was in basis but re-synthesis is lower error: replace
|
66
|
-
- whether the original chain contains a pulse gate: do not replace
|
67
66
|
- whether the original chain amounts to identity: replace with null
|
68
67
|
|
69
68
|
Error is computed as a multiplication of the errors of individual gates on that qubit.
|
@@ -81,17 +80,19 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
81
80
|
"""
|
82
81
|
super().__init__()
|
83
82
|
|
84
|
-
if basis:
|
83
|
+
if basis and len(basis) > 0:
|
85
84
|
self._basis_gates = set(basis)
|
86
85
|
else:
|
87
86
|
self._basis_gates = None
|
88
|
-
|
87
|
+
# Bypass target if it doesn't contain any basis gates (i.e. it's a _FakeTarget), as this
|
88
|
+
# not part of the official target model.
|
89
|
+
self._target = target if target is not None and len(target.operation_names) > 0 else None
|
89
90
|
self._global_decomposers = None
|
90
91
|
self._local_decomposers_cache = {}
|
91
92
|
|
92
|
-
if
|
93
|
+
if self._basis_gates:
|
93
94
|
self._global_decomposers = _possible_decomposers(set(basis))
|
94
|
-
elif target is None:
|
95
|
+
elif target is None or len(target.operation_names) == 0:
|
95
96
|
self._global_decomposers = _possible_decomposers(None)
|
96
97
|
self._basis_gates = None
|
97
98
|
|
@@ -115,7 +116,11 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
115
116
|
|
116
117
|
def _get_decomposer(self, qubit=None):
|
117
118
|
# include path for when target exists but target.num_qubits is None (BasicSimulator)
|
118
|
-
if
|
119
|
+
if (
|
120
|
+
self._target is not None
|
121
|
+
and self._target.num_qubits is not None
|
122
|
+
and len(self._target.operation_names) > 0
|
123
|
+
):
|
119
124
|
if qubit is not None:
|
120
125
|
qubits_tuple = (qubit,)
|
121
126
|
else:
|
@@ -160,33 +165,24 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
160
165
|
out_dag.apply_operation_back(op.operation, qubits, check=False)
|
161
166
|
return out_dag
|
162
167
|
|
163
|
-
def _substitution_checks(
|
164
|
-
self, dag, old_run, new_circ, basis, qubit, old_error=None, new_error=None
|
165
|
-
):
|
168
|
+
def _substitution_checks(self, old_run, new_circ, basis, qubit, old_error=None, new_error=None):
|
166
169
|
"""
|
167
170
|
Returns `True` when it is recommended to replace `old_run` with `new_circ` over `basis`.
|
168
171
|
"""
|
169
172
|
if new_circ is None:
|
170
173
|
return False
|
171
174
|
|
172
|
-
#
|
173
|
-
has_cals_p = dag._calibrations_prop is not None and len(dag._calibrations_prop) > 0
|
174
|
-
# does this run have uncalibrated gates?
|
175
|
-
uncalibrated_p = not has_cals_p or any(not dag._has_calibration_for(g) for g in old_run)
|
176
|
-
# does this run have gates not in the image of ._decomposers _and_ uncalibrated?
|
175
|
+
# does this run have gates not in the image of ._decomposers?
|
177
176
|
if basis is not None:
|
178
|
-
|
179
|
-
g.name not in basis and (not has_cals_p or not dag._has_calibration_for(g))
|
180
|
-
for g in old_run
|
181
|
-
)
|
177
|
+
not_basis_p = any(g.name not in basis for g in old_run)
|
182
178
|
else:
|
183
179
|
# If no basis is specified then we're always in the basis
|
184
|
-
|
180
|
+
not_basis_p = False
|
185
181
|
|
186
182
|
# if we're outside of the basis set, we're obligated to logically decompose.
|
187
183
|
# if we're outside of the set of gates for which we have physical definitions,
|
188
184
|
# then we _try_ to decompose, using the results if we see improvement.
|
189
|
-
if not
|
185
|
+
if not not_basis_p:
|
190
186
|
if new_error is None:
|
191
187
|
new_error = self._error(new_circ, qubit)
|
192
188
|
if old_error is None:
|
@@ -196,8 +192,8 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
196
192
|
old_error = 0.0
|
197
193
|
|
198
194
|
return (
|
199
|
-
|
200
|
-
or (
|
195
|
+
not_basis_p
|
196
|
+
or (True and new_error < old_error)
|
201
197
|
or (math.isclose(new_error[0], 0) and not math.isclose(old_error[0], 0))
|
202
198
|
)
|
203
199
|
|
@@ -126,7 +126,8 @@ class OptimizeAnnotated(TransformationPass):
|
|
126
126
|
for node in dag.op_nodes():
|
127
127
|
if isinstance(node.op, ControlFlowOp):
|
128
128
|
dag.substitute_node(
|
129
|
-
node,
|
129
|
+
node,
|
130
|
+
control_flow.map_blocks(self.run, node.op),
|
130
131
|
)
|
131
132
|
|
132
133
|
# First, optimize every node in the DAG.
|
@@ -165,7 +166,7 @@ class OptimizeAnnotated(TransformationPass):
|
|
165
166
|
node.op.modifiers = canonical_modifiers
|
166
167
|
else:
|
167
168
|
# no need for annotated operations
|
168
|
-
dag.substitute_node(node, cur
|
169
|
+
dag.substitute_node(node, cur)
|
169
170
|
did_something = True
|
170
171
|
return dag, did_something
|
171
172
|
|
@@ -32,7 +32,7 @@ class RemoveIdentityEquivalent(TransformationPass):
|
|
32
32
|
|
33
33
|
.. math::
|
34
34
|
|
35
|
-
\bar{F} = \frac{1 + F_{\text{process}}}{1 + d},\
|
35
|
+
\bar{F} = \frac{1 + d F_{\text{process}}}{1 + d},\
|
36
36
|
|
37
37
|
F_{\text{process}} = \frac{|\mathrm{Tr}(G)|^2}{d^2}
|
38
38
|
|
@@ -47,9 +47,11 @@ class RemoveIdentityEquivalent(TransformationPass):
|
|
47
47
|
Args:
|
48
48
|
approximation_degree: The degree to approximate for the equivalence check. This can be a
|
49
49
|
floating point value between 0 and 1, or ``None``. If the value is 1 this does not
|
50
|
-
approximate above floating point precision. For a value < 1 this is used as a
|
51
|
-
factor for the cutoff fidelity. If the value is ``None`` this approximates up
|
52
|
-
fidelity for the gate specified in ``target``.
|
50
|
+
approximate above the floating point precision. For a value < 1 this is used as a
|
51
|
+
scaling factor for the cutoff fidelity. If the value is ``None`` this approximates up
|
52
|
+
to the fidelity for the gate specified in ``target``. In case no ``target`` is set
|
53
|
+
we approximate up to ``16 * machine_eps`` as default to account for accumulations
|
54
|
+
on few-qubit systems.
|
53
55
|
|
54
56
|
target: If ``approximation_degree`` is set to ``None`` and a :class:`.Target` is provided
|
55
57
|
for this field the tolerance for determining whether an operation is equivalent to
|
@@ -14,7 +14,8 @@
|
|
14
14
|
|
15
15
|
from qiskit.transpiler.basepasses import TransformationPass
|
16
16
|
from qiskit.transpiler.passes.utils import control_flow
|
17
|
-
from qiskit.circuit
|
17
|
+
from qiskit.circuit import QuantumCircuit
|
18
|
+
from qiskit.circuit import IfElseOp
|
18
19
|
from qiskit.circuit.reset import Reset
|
19
20
|
from qiskit.circuit.measure import Measure
|
20
21
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
@@ -36,7 +37,9 @@ class ResetAfterMeasureSimplification(TransformationPass):
|
|
36
37
|
for node in dag.op_nodes(Measure):
|
37
38
|
succ = next(dag.quantum_successors(node))
|
38
39
|
if isinstance(succ, DAGOpNode) and isinstance(succ.op, Reset):
|
39
|
-
|
40
|
+
x_body = QuantumCircuit(1)
|
41
|
+
x_body.x(0)
|
42
|
+
new_x = IfElseOp((node.cargs[0], 1), x_body)
|
40
43
|
new_dag = DAGCircuit()
|
41
44
|
new_dag.add_qubits(node.qargs)
|
42
45
|
new_dag.add_clbits(node.cargs)
|
@@ -13,6 +13,7 @@
|
|
13
13
|
"""Splits each two-qubit gate in the `dag` into two single-qubit gates, if possible without error."""
|
14
14
|
|
15
15
|
from qiskit.transpiler.basepasses import TransformationPass
|
16
|
+
from qiskit.transpiler.layout import Layout
|
16
17
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
17
18
|
from qiskit._accelerate.split_2q_unitaries import split_2q_unitaries
|
18
19
|
|
@@ -24,17 +25,39 @@ class Split2QUnitaries(TransformationPass):
|
|
24
25
|
matrix is actually a product of 2 single qubit gates. In these cases the 2q gate can be
|
25
26
|
simplified into two single qubit gates and this pass will perform this optimization and will
|
26
27
|
replace the two qubit gate with two single qubit :class:`.UnitaryGate`.
|
28
|
+
|
29
|
+
If some of the gates can be viewed as a swap joined by the product of 2 single qubit gates,
|
30
|
+
the pass will recreate the DAG, permuting the swapped qubits similar
|
31
|
+
to how it's done in :class:`ElidePermutations`.
|
27
32
|
"""
|
28
33
|
|
29
|
-
def __init__(self, fidelity: float = 1.0 - 1e-16):
|
34
|
+
def __init__(self, fidelity: float = 1.0 - 1e-16, split_swap: bool = False):
|
30
35
|
"""
|
31
36
|
Args:
|
32
37
|
fidelity: Allowed tolerance for splitting two-qubit unitaries and gate decompositions.
|
38
|
+
split_swap: Whether to attempt to split swap gates, resulting in a permutation of the qubits.
|
33
39
|
"""
|
34
40
|
super().__init__()
|
35
41
|
self.requested_fidelity = fidelity
|
42
|
+
self.split_swap = split_swap
|
36
43
|
|
37
44
|
def run(self, dag: DAGCircuit) -> DAGCircuit:
|
38
45
|
"""Run the Split2QUnitaries pass on `dag`."""
|
39
|
-
split_2q_unitaries(dag, self.requested_fidelity)
|
40
|
-
|
46
|
+
result = split_2q_unitaries(dag, self.requested_fidelity, self.split_swap)
|
47
|
+
if result is None:
|
48
|
+
return dag
|
49
|
+
|
50
|
+
(new_dag, qubit_mapping) = result
|
51
|
+
input_qubit_mapping = {qubit: index for index, qubit in enumerate(dag.qubits)}
|
52
|
+
self.property_set["original_layout"] = Layout(input_qubit_mapping)
|
53
|
+
if self.property_set["original_qubit_indices"] is None:
|
54
|
+
self.property_set["original_qubit_indices"] = input_qubit_mapping
|
55
|
+
|
56
|
+
new_layout = Layout({dag.qubits[out]: idx for idx, out in enumerate(qubit_mapping)})
|
57
|
+
if current_layout := self.property_set["virtual_permutation_layout"]:
|
58
|
+
self.property_set["virtual_permutation_layout"] = new_layout.compose(
|
59
|
+
current_layout, dag.qubits
|
60
|
+
)
|
61
|
+
else:
|
62
|
+
self.property_set["virtual_permutation_layout"] = new_layout
|
63
|
+
return new_dag
|
@@ -443,6 +443,7 @@ class TemplateSubstitution:
|
|
443
443
|
self.dag_dep_optimized = dag_dep_opt
|
444
444
|
self.dag_optimized = dagdependency_to_dag(dag_dep_opt)
|
445
445
|
|
446
|
+
@_optionals.HAS_SYMPY.require_in_call("Bind parameters in templates")
|
446
447
|
def _attempt_bind(self, template_sublist, circuit_sublist):
|
447
448
|
"""
|
448
449
|
Copies the template and attempts to bind any parameters,
|
@@ -15,7 +15,6 @@
|
|
15
15
|
from .basic_swap import BasicSwap
|
16
16
|
from .layout_transformation import LayoutTransformation
|
17
17
|
from .lookahead_swap import LookaheadSwap
|
18
|
-
from .stochastic_swap import StochasticSwap
|
19
18
|
from .sabre_swap import SabreSwap
|
20
19
|
from .commuting_2q_gate_routing.commuting_2q_gate_router import Commuting2qGateRouter
|
21
20
|
from .commuting_2q_gate_routing.swap_strategy import SwapStrategy
|
@@ -52,7 +52,9 @@ class Commuting2qGateRouter(TransformationPass):
|
|
52
52
|
To do this we use a line swap strategy for qubits 0, 1, 3, and 4 defined it in terms
|
53
53
|
of virtual qubits 0, 1, 2, and 3.
|
54
54
|
|
55
|
-
..
|
55
|
+
.. plot::
|
56
|
+
:include-source:
|
57
|
+
:nofigs:
|
56
58
|
|
57
59
|
from qiskit import QuantumCircuit
|
58
60
|
from qiskit.circuit.library import PauliEvolutionGate
|
@@ -20,7 +20,7 @@ import rustworkx
|
|
20
20
|
|
21
21
|
from qiskit.circuit import SwitchCaseOp, Clbit, ClassicalRegister
|
22
22
|
from qiskit.circuit.library.standard_gates import SwapGate
|
23
|
-
from qiskit.circuit.controlflow import
|
23
|
+
from qiskit.circuit.controlflow import node_resources
|
24
24
|
from qiskit.converters import dag_to_circuit
|
25
25
|
from qiskit.transpiler.basepasses import TransformationPass
|
26
26
|
from qiskit.transpiler.coupling import CouplingMap
|
@@ -29,7 +29,7 @@ from qiskit.transpiler.layout import Layout
|
|
29
29
|
from qiskit.transpiler.target import Target
|
30
30
|
from qiskit.transpiler.passes.layout import disjoint_utils
|
31
31
|
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
32
|
-
from qiskit.utils
|
32
|
+
from qiskit.utils import default_num_processes
|
33
33
|
|
34
34
|
from qiskit._accelerate.sabre import sabre_routing, Heuristic, SetScaling, NeighborTable, SabreDAG
|
35
35
|
from qiskit._accelerate.nlayout import NLayout
|
@@ -167,7 +167,7 @@ class SabreSwap(TransformationPass):
|
|
167
167
|
self.heuristic = heuristic
|
168
168
|
self.seed = seed
|
169
169
|
if trials is None:
|
170
|
-
self.trials =
|
170
|
+
self.trials = default_num_processes()
|
171
171
|
else:
|
172
172
|
self.trials = trials
|
173
173
|
|
@@ -301,8 +301,6 @@ def _build_sabre_dag(dag, num_physical_qubits, qubit_indices):
|
|
301
301
|
node_blocks = {}
|
302
302
|
for node in block_dag.topological_op_nodes():
|
303
303
|
cargs_bits = set(node.cargs)
|
304
|
-
if node.condition is not None:
|
305
|
-
cargs_bits.update(condition_resources(node.condition).clbits)
|
306
304
|
if node.is_control_flow() and isinstance(node.op, SwitchCaseOp):
|
307
305
|
target = node.op.target
|
308
306
|
if isinstance(target, Clbit):
|
@@ -416,6 +414,12 @@ def _apply_sabre_result(
|
|
416
414
|
block_root_logical_map = {
|
417
415
|
inner: root_logical_map[outer] for inner, outer in zip(block.qubits, node.qargs)
|
418
416
|
}
|
417
|
+
# The virtual qubits originally incident to the block should be retained even if not
|
418
|
+
# actually used; the user might be marking them out specially (like in `box`).
|
419
|
+
# There are other transpiler passes to remove those dependencies if desired.
|
420
|
+
incident_qubits = {
|
421
|
+
layout.virtual_to_physical(block_root_logical_map[bit]) for bit in block.qubits
|
422
|
+
}
|
419
423
|
block_dag, block_layout = recurse(
|
420
424
|
empty_dag(block),
|
421
425
|
circuit_to_dag_dict[id(block)],
|
@@ -429,7 +433,11 @@ def _apply_sabre_result(
|
|
429
433
|
)
|
430
434
|
apply_swaps(block_dag, block_result.swap_epilogue, block_layout)
|
431
435
|
mapped_block_dags.append(block_dag)
|
432
|
-
idle_qubits.intersection_update(
|
436
|
+
idle_qubits.intersection_update(
|
437
|
+
bit
|
438
|
+
for bit in block_dag.idle_wires()
|
439
|
+
if block_dag.find_bit(bit).index not in incident_qubits
|
440
|
+
)
|
433
441
|
|
434
442
|
mapped_blocks = []
|
435
443
|
for mapped_block_dag in mapped_block_dags:
|
@@ -388,7 +388,7 @@ def _extract_nodes(nodes, dag):
|
|
388
388
|
qubit_indices = [dag.find_bit(qubit).index for qubit in node.qargs]
|
389
389
|
classical_bit_indices = set()
|
390
390
|
|
391
|
-
if node
|
391
|
+
if getattr(node, "condition", None) is not None:
|
392
392
|
classical_bit_indices.update(condition_resources(node.op.condition).clbits)
|
393
393
|
|
394
394
|
if isinstance(node.op, SwitchCaseOp):
|
@@ -12,16 +12,10 @@
|
|
12
12
|
|
13
13
|
"""Module containing circuit scheduling passes."""
|
14
14
|
|
15
|
-
from .alap import ALAPSchedule
|
16
|
-
from .asap import ASAPSchedule
|
17
|
-
from .dynamical_decoupling import DynamicalDecoupling
|
18
15
|
from .scheduling import ALAPScheduleAnalysis, ASAPScheduleAnalysis, SetIOLatency
|
19
16
|
from .time_unit_conversion import TimeUnitConversion
|
20
17
|
from .padding import PadDelay, PadDynamicalDecoupling
|
21
|
-
from .alignments import InstructionDurationCheck,
|
18
|
+
from .alignments import InstructionDurationCheck, ConstrainedReschedule
|
22
19
|
|
23
20
|
# For backward compatibility
|
24
21
|
from . import alignments as instruction_alignments
|
25
|
-
|
26
|
-
# TODO Deprecated pass. Will be removed after deprecation period.
|
27
|
-
from .alignments import AlignMeasures
|
@@ -63,7 +63,7 @@ Granularity constraint
|
|
63
63
|
configuration in units of dt. This is the constraint for a single pulse :class:`Play`
|
64
64
|
instruction that may constitute your pulse gate.
|
65
65
|
The length of waveform samples should be multiple of this constraint value.
|
66
|
-
Violation of this constraint may result in
|
66
|
+
Violation of this constraint may result in failure in backend execution.
|
67
67
|
|
68
68
|
Minimum pulse length constraint
|
69
69
|
|
@@ -71,11 +71,9 @@ Minimum pulse length constraint
|
|
71
71
|
configuration in units of dt. This is the constraint for a single pulse :class:`Play`
|
72
72
|
instruction that may constitute your pulse gate.
|
73
73
|
The length of waveform samples should be greater than this constraint value.
|
74
|
-
Violation of this constraint may result in
|
74
|
+
Violation of this constraint may result in failure in backend execution.
|
75
75
|
|
76
76
|
"""
|
77
77
|
|
78
78
|
from .check_durations import InstructionDurationCheck
|
79
|
-
from .pulse_gate_validation import ValidatePulseGates
|
80
79
|
from .reschedule import ConstrainedReschedule
|
81
|
-
from .align_measures import AlignMeasures
|
@@ -22,7 +22,7 @@ class InstructionDurationCheck(AnalysisPass):
|
|
22
22
|
|
23
23
|
This pass investigates the input quantum circuit and checks if the circuit requires
|
24
24
|
rescheduling for execution. Note that this pass can be triggered without scheduling.
|
25
|
-
This pass only checks the duration of delay instructions
|
25
|
+
This pass only checks the duration of delay instructions,
|
26
26
|
which report duration values without pre-scheduling.
|
27
27
|
|
28
28
|
This pass assumes backend supported instructions, i.e. basis gates, have no violation
|
@@ -68,11 +68,3 @@ class InstructionDurationCheck(AnalysisPass):
|
|
68
68
|
if not (dur % self.acquire_align == 0 and dur % self.pulse_align == 0):
|
69
69
|
self.property_set["reschedule_required"] = True
|
70
70
|
return
|
71
|
-
|
72
|
-
# Check custom gate durations
|
73
|
-
for inst_defs in dag._calibrations_prop.values():
|
74
|
-
for caldef in inst_defs.values():
|
75
|
-
dur = caldef.duration
|
76
|
-
if not (dur % self.acquire_align == 0 and dur % self.pulse_align == 0):
|
77
|
-
self.property_set["reschedule_required"] = True
|
78
|
-
return
|
@@ -84,6 +84,8 @@ class ConstrainedReschedule(AnalysisPass):
|
|
84
84
|
self.acquire_align = acquire_alignment
|
85
85
|
self.pulse_align = pulse_alignment
|
86
86
|
if target is not None:
|
87
|
+
self.durations = target.durations()
|
88
|
+
self.target = target
|
87
89
|
self.acquire_align = target.acquire_alignment
|
88
90
|
self.pulse_align = target.pulse_alignment
|
89
91
|
|
@@ -117,7 +119,6 @@ class ConstrainedReschedule(AnalysisPass):
|
|
117
119
|
node: Current node.
|
118
120
|
"""
|
119
121
|
node_start_time = self.property_set["node_start_time"]
|
120
|
-
conditional_latency = self.property_set.get("conditional_latency", 0)
|
121
122
|
clbit_write_latency = self.property_set.get("clbit_write_latency", 0)
|
122
123
|
|
123
124
|
if isinstance(node.op, Gate):
|
@@ -142,20 +143,25 @@ class ConstrainedReschedule(AnalysisPass):
|
|
142
143
|
node_start_time[node] = this_t0
|
143
144
|
|
144
145
|
# Compute shifted t1 of this node separately for qreg and creg
|
145
|
-
|
146
|
+
if self.target is not None:
|
147
|
+
try:
|
148
|
+
duration = self.durations.get(node.op, [dag.find_bit(x).index for x in node.qargs])
|
149
|
+
except TranspilerError:
|
150
|
+
duration = 0
|
151
|
+
new_t1q = this_t0 + duration
|
152
|
+
|
153
|
+
elif node.name == "delay":
|
154
|
+
new_t1q = this_t0 + node.op.duration
|
155
|
+
else:
|
156
|
+
new_t1q = this_t0
|
146
157
|
this_qubits = set(node.qargs)
|
147
158
|
if isinstance(node.op, (Measure, Reset)):
|
148
159
|
# creg access ends at the end of instruction
|
149
160
|
new_t1c = new_t1q
|
150
161
|
this_clbits = set(node.cargs)
|
151
162
|
else:
|
152
|
-
|
153
|
-
|
154
|
-
new_t1c = this_t0
|
155
|
-
this_clbits = set(node.op.condition_bits)
|
156
|
-
else:
|
157
|
-
new_t1c = None
|
158
|
-
this_clbits = set()
|
163
|
+
new_t1c = None
|
164
|
+
this_clbits = set()
|
159
165
|
|
160
166
|
# Check immediate successors for overlap
|
161
167
|
for next_node in self._get_next_gate(dag, node):
|
@@ -167,13 +173,8 @@ class ConstrainedReschedule(AnalysisPass):
|
|
167
173
|
next_t0c = next_t0q + clbit_write_latency
|
168
174
|
next_clbits = set(next_node.cargs)
|
169
175
|
else:
|
170
|
-
|
171
|
-
|
172
|
-
next_t0c = next_t0q - conditional_latency
|
173
|
-
next_clbits = set(next_node.op.condition_bits)
|
174
|
-
else:
|
175
|
-
next_t0c = None
|
176
|
-
next_clbits = set()
|
176
|
+
next_t0c = None
|
177
|
+
next_clbits = set()
|
177
178
|
# Compute overlap if there is qubits overlap
|
178
179
|
if any(this_qubits & next_qubits):
|
179
180
|
qreg_overlap = new_t1q - next_t0q
|
@@ -22,6 +22,7 @@ from qiskit.dagcircuit import DAGCircuit, DAGNode
|
|
22
22
|
from qiskit.transpiler.basepasses import TransformationPass
|
23
23
|
from qiskit.transpiler.exceptions import TranspilerError
|
24
24
|
from qiskit.transpiler.target import Target
|
25
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
25
26
|
|
26
27
|
logger = logging.getLogger(__name__)
|
27
28
|
|
@@ -57,6 +58,7 @@ class BasePadding(TransformationPass):
|
|
57
58
|
def __init__(
|
58
59
|
self,
|
59
60
|
target: Target = None,
|
61
|
+
durations: InstructionDurations = None,
|
60
62
|
):
|
61
63
|
"""BasePadding initializer.
|
62
64
|
|
@@ -67,6 +69,30 @@ class BasePadding(TransformationPass):
|
|
67
69
|
"""
|
68
70
|
super().__init__()
|
69
71
|
self.target = target
|
72
|
+
self.durations = durations
|
73
|
+
|
74
|
+
def get_duration(self, node, dag): # pylint: disable=too-many-return-statements
|
75
|
+
"""Get duration of a given node in the circuit."""
|
76
|
+
if node.name == "delay":
|
77
|
+
return node.op.duration
|
78
|
+
if node.name == "barrier":
|
79
|
+
return 0
|
80
|
+
if not self.target and not self.durations:
|
81
|
+
return None
|
82
|
+
indices = [dag.find_bit(qarg).index for qarg in node.qargs]
|
83
|
+
|
84
|
+
if self.target:
|
85
|
+
props_dict = self.target.get(node.name)
|
86
|
+
if not props_dict:
|
87
|
+
return None
|
88
|
+
props = props_dict.get(tuple(indices))
|
89
|
+
if not props:
|
90
|
+
return None
|
91
|
+
if self.target.dt is None:
|
92
|
+
return props.duration
|
93
|
+
else:
|
94
|
+
return self.target.seconds_to_dt(props.duration)
|
95
|
+
return self.durations.get(node.name, indices)
|
70
96
|
|
71
97
|
def run(self, dag: DAGCircuit):
|
72
98
|
"""Run the padding pass on ``dag``.
|
@@ -99,7 +125,6 @@ class BasePadding(TransformationPass):
|
|
99
125
|
new_dag.name = dag.name
|
100
126
|
new_dag.metadata = dag.metadata
|
101
127
|
new_dag.unit = self.property_set["time_unit"]
|
102
|
-
new_dag._calibrations_prop = dag._calibrations_prop
|
103
128
|
new_dag.global_phase = dag.global_phase
|
104
129
|
|
105
130
|
idle_after = {bit: 0 for bit in dag.qubits}
|
@@ -112,7 +137,7 @@ class BasePadding(TransformationPass):
|
|
112
137
|
for node in dag.topological_op_nodes():
|
113
138
|
if node in node_start_time:
|
114
139
|
t0 = node_start_time[node]
|
115
|
-
t1 = t0 + node
|
140
|
+
t1 = t0 + self.get_duration(node, dag)
|
116
141
|
circuit_duration = max(circuit_duration, t1)
|
117
142
|
|
118
143
|
if isinstance(node.op, Delay):
|
@@ -185,6 +210,9 @@ class BasePadding(TransformationPass):
|
|
185
210
|
f"The input circuit {dag.name} is not scheduled. Call one of scheduling passes "
|
186
211
|
f"before running the {self.__class__.__name__} pass."
|
187
212
|
)
|
213
|
+
if self.property_set["time_unit"] == "stretch":
|
214
|
+
# This should have already been raised during scheduling, but just in case.
|
215
|
+
raise TranspilerError("Scheduling cannot run on circuits with stretch durations.")
|
188
216
|
for qarg, _ in enumerate(dag.qubits):
|
189
217
|
if not self.__delay_supported(qarg):
|
190
218
|
logger.debug(
|