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
@@ -14,7 +14,6 @@
|
|
14
14
|
from __future__ import annotations
|
15
15
|
|
16
16
|
import logging
|
17
|
-
import warnings
|
18
17
|
import numpy as np
|
19
18
|
|
20
19
|
from qiskit.circuit import Gate, ParameterExpression, Qubit
|
@@ -59,9 +58,10 @@ class PadDynamicalDecoupling(BasePadding):
|
|
59
58
|
import numpy as np
|
60
59
|
from qiskit.circuit import QuantumCircuit
|
61
60
|
from qiskit.circuit.library import XGate
|
62
|
-
from qiskit.transpiler import PassManager, InstructionDurations
|
61
|
+
from qiskit.transpiler import PassManager, InstructionDurations, Target, CouplingMap
|
63
62
|
from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDynamicalDecoupling
|
64
63
|
from qiskit.visualization import timeline_drawer
|
64
|
+
|
65
65
|
circ = QuantumCircuit(4)
|
66
66
|
circ.h(0)
|
67
67
|
circ.cx(0, 1)
|
@@ -71,7 +71,15 @@ class PadDynamicalDecoupling(BasePadding):
|
|
71
71
|
durations = InstructionDurations(
|
72
72
|
[("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
|
73
73
|
("cx", [1, 2], 200), ("cx", [2, 3], 300),
|
74
|
-
("x", None, 50), ("measure", None, 1000)]
|
74
|
+
("x", None, 50), ("measure", None, 1000)],
|
75
|
+
dt=1e-7
|
76
|
+
)
|
77
|
+
target = Target.from_configuration(
|
78
|
+
["h", "cx", "reset", "x", "measure"],
|
79
|
+
num_qubits=4,
|
80
|
+
coupling_map=CouplingMap.from_line(4, bidirectional=False),
|
81
|
+
instruction_durations=durations,
|
82
|
+
dt=1e-7,
|
75
83
|
)
|
76
84
|
|
77
85
|
# balanced X-X sequence on all qubits
|
@@ -79,7 +87,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
79
87
|
pm = PassManager([ALAPScheduleAnalysis(durations),
|
80
88
|
PadDynamicalDecoupling(durations, dd_sequence)])
|
81
89
|
circ_dd = pm.run(circ)
|
82
|
-
timeline_drawer(circ_dd)
|
90
|
+
timeline_drawer(circ_dd, target=target)
|
83
91
|
|
84
92
|
# Uhrig sequence on qubit 0
|
85
93
|
n = 8
|
@@ -97,7 +105,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
97
105
|
]
|
98
106
|
)
|
99
107
|
circ_dd = pm.run(circ)
|
100
|
-
timeline_drawer(circ_dd)
|
108
|
+
timeline_drawer(circ_dd, target=target)
|
101
109
|
|
102
110
|
.. note::
|
103
111
|
|
@@ -158,7 +166,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
158
166
|
non-multiple of the alignment constraint value is found.
|
159
167
|
TypeError: If ``dd_sequence`` is not specified
|
160
168
|
"""
|
161
|
-
super().__init__(target=target)
|
169
|
+
super().__init__(target=target, durations=durations)
|
162
170
|
self._durations = durations
|
163
171
|
if dd_sequence is None:
|
164
172
|
raise TypeError("required argument 'dd_sequence' is not specified")
|
@@ -173,6 +181,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
173
181
|
self._dd_sequence_lengths: dict[Qubit, list[int]] = {}
|
174
182
|
self._sequence_phase = 0
|
175
183
|
if target is not None:
|
184
|
+
# The priority order for instruction durations is: target > standalone.
|
176
185
|
self._durations = target.durations()
|
177
186
|
self._alignment = target.pulse_alignment
|
178
187
|
for gate in dd_sequence:
|
@@ -181,35 +190,12 @@ class PadDynamicalDecoupling(BasePadding):
|
|
181
190
|
f"{gate.name} in dd_sequence is not supported in the target"
|
182
191
|
)
|
183
192
|
|
184
|
-
def _update_inst_durations(self, dag):
|
185
|
-
"""Update instruction durations with circuit information. If the dag contains gate
|
186
|
-
calibrations and no instruction durations were provided through the target or as a
|
187
|
-
standalone input, the circuit calibration durations will be used.
|
188
|
-
The priority order for instruction durations is: target > standalone > circuit.
|
189
|
-
"""
|
190
|
-
circ_durations = InstructionDurations()
|
191
|
-
|
192
|
-
if dag._calibrations_prop:
|
193
|
-
cal_durations = []
|
194
|
-
with warnings.catch_warnings():
|
195
|
-
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
196
|
-
# `schedule.duration` emits pulse deprecation warnings which we don't want
|
197
|
-
# to see here
|
198
|
-
for gate, gate_cals in dag._calibrations_prop.items():
|
199
|
-
for (qubits, parameters), schedule in gate_cals.items():
|
200
|
-
cal_durations.append((gate, qubits, parameters, schedule.duration))
|
201
|
-
circ_durations.update(cal_durations, circ_durations.dt)
|
202
|
-
|
203
|
-
if self._durations is not None:
|
204
|
-
circ_durations.update(self._durations, getattr(self._durations, "dt", None))
|
205
|
-
|
206
|
-
return circ_durations
|
207
|
-
|
208
193
|
def _pre_runhook(self, dag: DAGCircuit):
|
209
194
|
super()._pre_runhook(dag)
|
210
195
|
|
211
|
-
durations =
|
212
|
-
|
196
|
+
durations = InstructionDurations()
|
197
|
+
if self._durations is not None:
|
198
|
+
durations.update(self._durations, getattr(self._durations, "dt", None))
|
213
199
|
num_pulses = len(self._dd_sequence)
|
214
200
|
|
215
201
|
# Check if physical circuit is given
|
@@ -255,31 +241,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
255
241
|
|
256
242
|
sequence_lengths = []
|
257
243
|
for index, gate in enumerate(self._dd_sequence):
|
258
|
-
|
259
|
-
# Check calibration.
|
260
|
-
params = self._resolve_params(gate)
|
261
|
-
with warnings.catch_warnings():
|
262
|
-
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
263
|
-
# `schedule.duration` emits pulse deprecation warnings which we don't want
|
264
|
-
# to see here
|
265
|
-
gate_length = dag._calibrations_prop[gate.name][
|
266
|
-
((physical_index,), params)
|
267
|
-
].duration
|
268
|
-
if gate_length % self._alignment != 0:
|
269
|
-
# This is necessary to implement lightweight scheduling logic for this pass.
|
270
|
-
# Usually the pulse alignment constraint and pulse data chunk size take
|
271
|
-
# the same value, however, we can intentionally violate this pattern
|
272
|
-
# at the gate level. For example, we can create a schedule consisting of
|
273
|
-
# a pi-pulse of 32 dt followed by a post buffer, i.e. delay, of 4 dt
|
274
|
-
# on the device with 16 dt constraint. Note that the pi-pulse length
|
275
|
-
# is multiple of 16 dt but the gate length of 36 is not multiple of it.
|
276
|
-
# Such pulse gate should be excluded.
|
277
|
-
raise TranspilerError(
|
278
|
-
f"Pulse gate {gate.name} with length non-multiple of {self._alignment} "
|
279
|
-
f"is not acceptable in {self.__class__.__name__} pass."
|
280
|
-
)
|
281
|
-
except KeyError:
|
282
|
-
gate_length = durations.get(gate, physical_index)
|
244
|
+
gate_length = durations.get(gate, physical_index)
|
283
245
|
sequence_lengths.append(gate_length)
|
284
246
|
# Update gate duration. This is necessary for current timeline drawer, i.e. scheduled.
|
285
247
|
gate = gate.to_mutable()
|
@@ -382,7 +344,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
382
344
|
op = prev_node.op
|
383
345
|
theta_l, phi_l, lam_l = op.params
|
384
346
|
op.params = Optimize1qGates.compose_u3(theta, phi, lam, theta_l, phi_l, lam_l)
|
385
|
-
new_prev_node = dag.substitute_node(prev_node, op
|
347
|
+
new_prev_node = dag.substitute_node(prev_node, op)
|
386
348
|
start_time = self.property_set["node_start_time"].pop(prev_node)
|
387
349
|
if start_time is not None:
|
388
350
|
self.property_set["node_start_time"][new_prev_node] = start_time
|
@@ -16,6 +16,7 @@ from qiskit.circuit import Qubit
|
|
16
16
|
from qiskit.circuit.delay import Delay
|
17
17
|
from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGOutNode
|
18
18
|
from qiskit.transpiler.target import Target
|
19
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
19
20
|
|
20
21
|
from .base_padding import BasePadding
|
21
22
|
|
@@ -25,7 +26,9 @@ class PadDelay(BasePadding):
|
|
25
26
|
|
26
27
|
Consecutive delays will be merged in the output of this pass.
|
27
28
|
|
28
|
-
..
|
29
|
+
.. plot::
|
30
|
+
:include-source:
|
31
|
+
:nofigs:
|
29
32
|
|
30
33
|
from qiskit import QuantumCircuit
|
31
34
|
from qiskit.transpiler import InstructionDurations
|
@@ -54,7 +57,12 @@ class PadDelay(BasePadding):
|
|
54
57
|
See :class:`BasePadding` pass for details.
|
55
58
|
"""
|
56
59
|
|
57
|
-
def __init__(
|
60
|
+
def __init__(
|
61
|
+
self,
|
62
|
+
fill_very_end: bool = True,
|
63
|
+
target: Target = None,
|
64
|
+
durations: InstructionDurations = None,
|
65
|
+
):
|
58
66
|
"""Create new padding delay pass.
|
59
67
|
|
60
68
|
Args:
|
@@ -63,7 +71,7 @@ class PadDelay(BasePadding):
|
|
63
71
|
If it is supplied and does not support delay instruction on a qubit,
|
64
72
|
padding passes do not pad any idle time of the qubit.
|
65
73
|
"""
|
66
|
-
super().__init__(target=target)
|
74
|
+
super().__init__(target=target, durations=durations)
|
67
75
|
self.fill_very_end = fill_very_end
|
68
76
|
|
69
77
|
def _pad(
|
@@ -21,8 +21,7 @@ class ALAPScheduleAnalysis(BaseScheduler):
|
|
21
21
|
"""ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible.
|
22
22
|
|
23
23
|
See the :ref:`transpiler-scheduling-description` section in the :mod:`qiskit.transpiler`
|
24
|
-
module documentation for
|
25
|
-
operation, i.e. ``c_if``.
|
24
|
+
module documentation for a more detailed explanation.
|
26
25
|
"""
|
27
26
|
|
28
27
|
def run(self, dag):
|
@@ -40,8 +39,9 @@ class ALAPScheduleAnalysis(BaseScheduler):
|
|
40
39
|
"""
|
41
40
|
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
|
42
41
|
raise TranspilerError("ALAP schedule runs on physical circuits only")
|
42
|
+
if self.property_set["time_unit"] == "stretch":
|
43
|
+
raise TranspilerError("Scheduling cannot run on circuits with stretch durations.")
|
43
44
|
|
44
|
-
conditional_latency = self.property_set.get("conditional_latency", 0)
|
45
45
|
clbit_write_latency = self.property_set.get("clbit_write_latency", 0)
|
46
46
|
|
47
47
|
node_start_time = {}
|
@@ -58,43 +58,9 @@ class ALAPScheduleAnalysis(BaseScheduler):
|
|
58
58
|
# the physical meaning of t0 and t1 is flipped here.
|
59
59
|
if isinstance(node.op, self.CONDITIONAL_SUPPORTED):
|
60
60
|
t0q = max(idle_before[q] for q in node.qargs)
|
61
|
-
|
62
|
-
|
63
|
-
t0c = max(idle_before[c] for c in node.op.condition_bits)
|
64
|
-
# Assume following case (t0c > t0q):
|
65
|
-
#
|
66
|
-
# |t0q
|
67
|
-
# Q ░░░░░░░░░░░░░▒▒▒
|
68
|
-
# C ░░░░░░░░▒▒▒▒▒▒▒▒
|
69
|
-
# |t0c
|
70
|
-
#
|
71
|
-
# In this case, there is no actual clbit read before gate.
|
72
|
-
#
|
73
|
-
# |t0q' = t0c - conditional_latency
|
74
|
-
# Q ░░░░░░░░▒▒▒░░▒▒▒
|
75
|
-
# C ░░░░░░▒▒▒▒▒▒▒▒▒▒
|
76
|
-
# |t1c' = t0c + conditional_latency
|
77
|
-
#
|
78
|
-
# rather than naively doing
|
79
|
-
#
|
80
|
-
# |t1q' = t0c + duration
|
81
|
-
# Q ░░░░░▒▒▒░░░░░▒▒▒
|
82
|
-
# C ░░▒▒░░░░▒▒▒▒▒▒▒▒
|
83
|
-
# |t1c' = t0c + duration + conditional_latency
|
84
|
-
#
|
85
|
-
t0 = max(t0q, t0c - op_duration)
|
86
|
-
t1 = t0 + op_duration
|
87
|
-
for clbit in node.op.condition_bits:
|
88
|
-
idle_before[clbit] = t1 + conditional_latency
|
89
|
-
else:
|
90
|
-
t0 = t0q
|
91
|
-
t1 = t0 + op_duration
|
61
|
+
t0 = t0q
|
62
|
+
t1 = t0 + op_duration
|
92
63
|
else:
|
93
|
-
if node.op.condition_bits:
|
94
|
-
raise TranspilerError(
|
95
|
-
f"Conditional instruction {node.op.name} is not supported in ALAP scheduler."
|
96
|
-
)
|
97
|
-
|
98
64
|
if isinstance(node.op, Measure):
|
99
65
|
# clbit time is always right (alap) justified
|
100
66
|
t0 = max(idle_before[bit] for bit in node.qargs + node.cargs)
|
@@ -21,8 +21,7 @@ class ASAPScheduleAnalysis(BaseScheduler):
|
|
21
21
|
"""ASAP Scheduling pass, which schedules the start time of instructions as early as possible.
|
22
22
|
|
23
23
|
See the :ref:`transpiler-scheduling-description` section in the :mod:`qiskit.transpiler`
|
24
|
-
module documentation for
|
25
|
-
operation, i.e. ``c_if``.
|
24
|
+
module documentation for a more detailed description.
|
26
25
|
"""
|
27
26
|
|
28
27
|
def run(self, dag):
|
@@ -40,8 +39,9 @@ class ASAPScheduleAnalysis(BaseScheduler):
|
|
40
39
|
"""
|
41
40
|
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
|
42
41
|
raise TranspilerError("ASAP schedule runs on physical circuits only")
|
42
|
+
if self.property_set["time_unit"] == "stretch":
|
43
|
+
raise TranspilerError("Scheduling cannot run on circuits with stretch durations.")
|
43
44
|
|
44
|
-
conditional_latency = self.property_set.get("conditional_latency", 0)
|
45
45
|
clbit_write_latency = self.property_set.get("clbit_write_latency", 0)
|
46
46
|
|
47
47
|
node_start_time = {}
|
@@ -54,40 +54,9 @@ class ASAPScheduleAnalysis(BaseScheduler):
|
|
54
54
|
# t1: end time of instruction
|
55
55
|
if isinstance(node.op, self.CONDITIONAL_SUPPORTED):
|
56
56
|
t0q = max(idle_after[q] for q in node.qargs)
|
57
|
-
|
58
|
-
# conditional is bit tricky due to conditional_latency
|
59
|
-
t0c = max(idle_after[bit] for bit in node.op.condition_bits)
|
60
|
-
if t0q > t0c:
|
61
|
-
# This is situation something like below
|
62
|
-
#
|
63
|
-
# |t0q
|
64
|
-
# Q ▒▒▒▒▒▒▒▒▒░░
|
65
|
-
# C ▒▒▒░░░░░░░░
|
66
|
-
# |t0c
|
67
|
-
#
|
68
|
-
# In this case, you can insert readout access before tq0
|
69
|
-
#
|
70
|
-
# |t0q
|
71
|
-
# Q ▒▒▒▒▒▒▒▒▒▒▒
|
72
|
-
# C ▒▒▒░░░▒▒░░░
|
73
|
-
# |t0q - conditional_latency
|
74
|
-
#
|
75
|
-
t0c = max(t0q - conditional_latency, t0c)
|
76
|
-
t1c = t0c + conditional_latency
|
77
|
-
for bit in node.op.condition_bits:
|
78
|
-
# Lock clbit until state is read
|
79
|
-
idle_after[bit] = t1c
|
80
|
-
# It starts after register read access
|
81
|
-
t0 = max(t0q, t1c)
|
82
|
-
else:
|
83
|
-
t0 = t0q
|
57
|
+
t0 = t0q
|
84
58
|
t1 = t0 + op_duration
|
85
59
|
else:
|
86
|
-
if node.op.condition_bits:
|
87
|
-
raise TranspilerError(
|
88
|
-
f"Conditional instruction {node.op.name} is not supported in ASAP scheduler."
|
89
|
-
)
|
90
|
-
|
91
60
|
if isinstance(node.op, Measure):
|
92
61
|
# measure instruction handling is bit tricky due to clbit_write_latency
|
93
62
|
t0q = max(idle_after[q] for q in node.qargs)
|
@@ -56,29 +56,23 @@ class BaseScheduler(AnalysisPass):
|
|
56
56
|
)
|
57
57
|
self.property_set["node_start_time"] = {}
|
58
58
|
|
59
|
-
@staticmethod
|
60
59
|
def _get_node_duration(
|
60
|
+
self,
|
61
61
|
node: DAGOpNode,
|
62
62
|
dag: DAGCircuit,
|
63
63
|
) -> int:
|
64
|
-
"""A helper method to get duration from node
|
64
|
+
"""A helper method to get duration from node"""
|
65
65
|
indices = [dag.find_bit(qarg).index for qarg in node.qargs]
|
66
66
|
|
67
|
-
if
|
68
|
-
#
|
69
|
-
|
70
|
-
with warnings.catch_warnings():
|
71
|
-
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
72
|
-
# `schedule.duration` emits pulse deprecation warnings which we don't want
|
73
|
-
# to see here
|
74
|
-
duration = dag._calibrations_prop[node.op.name][cal_key].duration
|
75
|
-
|
76
|
-
# Note that node duration is updated (but this is analysis pass)
|
77
|
-
op = node.op.to_mutable()
|
78
|
-
op.duration = duration
|
79
|
-
dag.substitute_node(node, op, propagate_condition=False)
|
67
|
+
if node.name == "delay":
|
68
|
+
# `TimeUnitConversion` already handled the unit conversions.
|
69
|
+
duration = node.op.duration
|
80
70
|
else:
|
81
|
-
|
71
|
+
unit = "s" if self.durations.dt is None else "dt"
|
72
|
+
try:
|
73
|
+
duration = self.durations.get(node.name, indices, unit=unit)
|
74
|
+
except TranspilerError:
|
75
|
+
duration = None
|
82
76
|
|
83
77
|
if isinstance(duration, ParameterExpression):
|
84
78
|
raise TranspilerError(
|
@@ -12,14 +12,16 @@
|
|
12
12
|
|
13
13
|
"""Unify time unit in circuit for scheduling and following passes."""
|
14
14
|
from typing import Set
|
15
|
-
import warnings
|
16
15
|
|
17
|
-
from qiskit.circuit import Delay
|
16
|
+
from qiskit.circuit import Delay, Duration
|
17
|
+
from qiskit.circuit.classical import expr
|
18
|
+
from qiskit.circuit.duration import duration_in_dt
|
18
19
|
from qiskit.dagcircuit import DAGCircuit
|
19
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
20
21
|
from qiskit.transpiler.exceptions import TranspilerError
|
21
22
|
from qiskit.transpiler.instruction_durations import InstructionDurations
|
22
23
|
from qiskit.transpiler.target import Target
|
24
|
+
from qiskit.utils import apply_prefix
|
23
25
|
|
24
26
|
|
25
27
|
class TimeUnitConversion(TransformationPass):
|
@@ -51,6 +53,7 @@ class TimeUnitConversion(TransformationPass):
|
|
51
53
|
super().__init__()
|
52
54
|
self.inst_durations = inst_durations or InstructionDurations()
|
53
55
|
if target is not None:
|
56
|
+
# The priority order for instruction durations is: target > standalone.
|
54
57
|
self.inst_durations = target.durations()
|
55
58
|
self._durations_provided = inst_durations is not None or target is not None
|
56
59
|
|
@@ -67,84 +70,87 @@ class TimeUnitConversion(TransformationPass):
|
|
67
70
|
TranspilerError: if the units are not unifiable
|
68
71
|
"""
|
69
72
|
|
70
|
-
inst_durations =
|
73
|
+
inst_durations = InstructionDurations()
|
74
|
+
if self._durations_provided:
|
75
|
+
inst_durations.update(self.inst_durations, getattr(self.inst_durations, "dt", None))
|
76
|
+
|
77
|
+
# The float-value converted units for delay expressions, either all in 'dt'
|
78
|
+
# or all in seconds.
|
79
|
+
expression_durations = {}
|
71
80
|
|
72
81
|
# Choose unit
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
82
|
+
has_dt = False
|
83
|
+
has_si = False
|
84
|
+
|
85
|
+
# We _always_ need to traverse duration expressions to convert them to
|
86
|
+
# a float. But we also use the opportunity to note if they intermix cycles
|
87
|
+
# and wall-time, in case we don't have a `dt` to use to unify all instruction
|
88
|
+
# durations.
|
89
|
+
for node in dag.op_nodes(op=Delay):
|
90
|
+
if isinstance(node.op.duration, expr.Expr):
|
91
|
+
if any(
|
92
|
+
isinstance(x, expr.Stretch) for x in expr.iter_identifiers(node.op.duration)
|
93
|
+
):
|
94
|
+
# If any of the delays use a stretch expression, we can't run scheduling
|
95
|
+
# passes anyway, so we bail out. In theory, we _could_ still traverse
|
96
|
+
# through the stretch expression and replace any Duration value nodes it may
|
97
|
+
# contain with ones of the same units, but it'd be complex and probably unuseful.
|
98
|
+
self.property_set["time_unit"] = "stretch"
|
99
|
+
return dag
|
100
|
+
|
101
|
+
visitor = _EvalDurationImpl(inst_durations.dt)
|
102
|
+
duration = node.op.duration.accept(visitor)
|
103
|
+
if visitor.in_cycles():
|
104
|
+
has_dt = True
|
105
|
+
# We need to round in case the expression evaluated to a non-integral 'dt'.
|
106
|
+
duration = duration_in_dt(duration, 1.0)
|
107
|
+
else:
|
108
|
+
has_si = True
|
109
|
+
if duration < 0:
|
110
|
+
raise TranspilerError(
|
111
|
+
f"Expression '{node.op.duration}' resolves to a negative duration!"
|
112
|
+
)
|
113
|
+
expression_durations[node._node_id] = duration
|
114
|
+
else:
|
115
|
+
if node.op.unit == "dt":
|
116
|
+
has_dt = True
|
117
|
+
else:
|
118
|
+
has_si = True
|
119
|
+
if inst_durations.dt is None and has_dt and has_si:
|
79
120
|
raise TranspilerError(
|
80
121
|
"Fail to unify time units in delays. SI units "
|
81
122
|
"and dt unit must not be mixed when dt is not supplied."
|
82
123
|
)
|
83
|
-
units_other = inst_durations.units_used()
|
84
|
-
if self._unified(units_other) == "mixed":
|
85
|
-
raise TranspilerError(
|
86
|
-
"Fail to unify time units in instruction_durations. SI units "
|
87
|
-
"and dt unit must not be mixed when dt is not supplied."
|
88
|
-
)
|
89
124
|
|
90
|
-
|
91
|
-
|
125
|
+
if inst_durations.dt is None:
|
126
|
+
# Check what units are used in other instructions: dt or SI or mixed
|
127
|
+
units_other = inst_durations.units_used()
|
128
|
+
unified_unit = self._unified(units_other)
|
129
|
+
if unified_unit == "SI" and not has_dt:
|
92
130
|
time_unit = "s"
|
93
|
-
elif unified_unit == "dt":
|
131
|
+
elif unified_unit == "dt" and not has_si:
|
94
132
|
time_unit = "dt"
|
95
133
|
else:
|
96
134
|
raise TranspilerError(
|
97
135
|
"Fail to unify time units. SI units "
|
98
136
|
"and dt unit must not be mixed when dt is not supplied."
|
99
137
|
)
|
138
|
+
else:
|
139
|
+
time_unit = "dt"
|
100
140
|
|
101
|
-
# Make
|
102
|
-
for node in dag.op_nodes():
|
103
|
-
try:
|
104
|
-
duration = inst_durations.get(
|
105
|
-
node.op, [dag.find_bit(qarg).index for qarg in node.qargs], unit=time_unit
|
106
|
-
)
|
107
|
-
except TranspilerError:
|
108
|
-
continue
|
141
|
+
# Make instructions with local durations consistent.
|
142
|
+
for node in dag.op_nodes(Delay):
|
109
143
|
op = node.op.to_mutable()
|
110
|
-
|
144
|
+
if node._node_id in expression_durations:
|
145
|
+
op.duration = expression_durations[node._node_id]
|
146
|
+
else:
|
147
|
+
op.duration = inst_durations._convert_unit(op.duration, op.unit, time_unit)
|
111
148
|
op.unit = time_unit
|
112
|
-
dag.substitute_node(node, op
|
149
|
+
dag.substitute_node(node, op)
|
113
150
|
|
114
151
|
self.property_set["time_unit"] = time_unit
|
115
152
|
return dag
|
116
153
|
|
117
|
-
def _update_inst_durations(self, dag):
|
118
|
-
"""Update instruction durations with circuit information. If the dag contains gate
|
119
|
-
calibrations and no instruction durations were provided through the target or as a
|
120
|
-
standalone input, the circuit calibration durations will be used.
|
121
|
-
The priority order for instruction durations is: target > standalone > circuit.
|
122
|
-
"""
|
123
|
-
circ_durations = InstructionDurations()
|
124
|
-
|
125
|
-
if dag._calibrations_prop:
|
126
|
-
cal_durations = []
|
127
|
-
with warnings.catch_warnings():
|
128
|
-
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
129
|
-
# `schedule.duration` emits pulse deprecation warnings which we don't want
|
130
|
-
# to see here
|
131
|
-
for gate, gate_cals in dag._calibrations_prop.items():
|
132
|
-
for (qubits, parameters), schedule in gate_cals.items():
|
133
|
-
cal_durations.append((gate, qubits, parameters, schedule.duration))
|
134
|
-
circ_durations.update(cal_durations, circ_durations.dt)
|
135
|
-
|
136
|
-
if self._durations_provided:
|
137
|
-
circ_durations.update(self.inst_durations, getattr(self.inst_durations, "dt", None))
|
138
|
-
|
139
|
-
return circ_durations
|
140
|
-
|
141
|
-
@staticmethod
|
142
|
-
def _units_used_in_delays(dag: DAGCircuit) -> Set[str]:
|
143
|
-
units_used = set()
|
144
|
-
for node in dag.op_nodes(op=Delay):
|
145
|
-
units_used.add(node.op.unit)
|
146
|
-
return units_used
|
147
|
-
|
148
154
|
@staticmethod
|
149
155
|
def _unified(unit_set: Set[str]) -> str:
|
150
156
|
if not unit_set:
|
@@ -163,3 +169,65 @@ class TimeUnitConversion(TransformationPass):
|
|
163
169
|
return "SI"
|
164
170
|
|
165
171
|
return "mixed"
|
172
|
+
|
173
|
+
|
174
|
+
class _EvalDurationImpl(expr.ExprVisitor[float]):
|
175
|
+
"""Evaluates the expression to a single float result.
|
176
|
+
|
177
|
+
If ``dt`` is provided or all durations are already in ``dt``, the result is in ``dt``.
|
178
|
+
Otherwise, the result will be in seconds, and all durations MUST be in wall-time (SI).
|
179
|
+
"""
|
180
|
+
|
181
|
+
__slots__ = ("dt", "has_dt", "has_si")
|
182
|
+
|
183
|
+
def __init__(self, dt=None):
|
184
|
+
self.dt = dt
|
185
|
+
self.has_dt = False
|
186
|
+
self.has_si = False
|
187
|
+
|
188
|
+
def in_cycles(self):
|
189
|
+
"""Returns ``True`` if units are 'dt' after visit."""
|
190
|
+
return self.has_dt or self.dt is not None
|
191
|
+
|
192
|
+
def visit_value(self, node, /) -> float:
|
193
|
+
if isinstance(node.value, float):
|
194
|
+
return node.value
|
195
|
+
if isinstance(node.value, Duration.dt):
|
196
|
+
if self.has_si and self.dt is None:
|
197
|
+
raise TranspilerError(
|
198
|
+
"Fail to unify time units in delays. SI units "
|
199
|
+
"and dt unit must not be mixed when dt is not supplied."
|
200
|
+
)
|
201
|
+
self.has_dt = True
|
202
|
+
return node.value[0]
|
203
|
+
if isinstance(node.value, Duration):
|
204
|
+
if self.has_dt and self.dt is None:
|
205
|
+
raise TranspilerError(
|
206
|
+
"Fail to unify time units in delays. SI units "
|
207
|
+
"and dt unit must not be mixed when dt is not supplied."
|
208
|
+
)
|
209
|
+
self.has_si = True
|
210
|
+
# Setting 'divisor' to 1 when there's no 'dt' is just to simplify
|
211
|
+
# the logic (we don't need to divide).
|
212
|
+
divisor = self.dt if self.dt is not None else 1
|
213
|
+
if isinstance(node.value, Duration.s):
|
214
|
+
return node.value[0] / divisor
|
215
|
+
from_unit = node.value.unit()
|
216
|
+
return apply_prefix(node.value[0], from_unit) / divisor
|
217
|
+
raise TranspilerError(f"invalid duration expression: {node}")
|
218
|
+
|
219
|
+
def visit_binary(self, node, /) -> float:
|
220
|
+
left = node.left.accept(self)
|
221
|
+
right = node.right.accept(self)
|
222
|
+
if node.op == expr.Binary.Op.ADD:
|
223
|
+
return left + right
|
224
|
+
if node.op == expr.Binary.Op.SUB:
|
225
|
+
return left - right
|
226
|
+
if node.op == expr.Binary.Op.MUL:
|
227
|
+
return left * right
|
228
|
+
if node.op == expr.Binary.Op.DIV:
|
229
|
+
return left / right
|
230
|
+
raise TranspilerError(f"invalid duration expression: {node}")
|
231
|
+
|
232
|
+
def visit_cast(self, node, /) -> float:
|
233
|
+
return node.operand.accept(self)
|