qiskit 1.4.1__cp39-abi3-win_amd64.whl → 2.0.0rc1__cp39-abi3-win_amd64.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.pyd +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 +1 -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
@@ -1,310 +0,0 @@
|
|
1
|
-
# This code is part of Qiskit.
|
2
|
-
#
|
3
|
-
# (C) Copyright IBM 2020.
|
4
|
-
#
|
5
|
-
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
-
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
-
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
-
#
|
9
|
-
# Any modifications or derivative works of this code must retain this
|
10
|
-
# copyright notice, and modified files need to carry a notice indicating
|
11
|
-
# that they have been altered from the originals.
|
12
|
-
|
13
|
-
"""Base circuit scheduling pass."""
|
14
|
-
import warnings
|
15
|
-
|
16
|
-
from qiskit.circuit import Delay, Gate, Measure, Reset
|
17
|
-
from qiskit.circuit.parameterexpression import ParameterExpression
|
18
|
-
from qiskit.dagcircuit import DAGOpNode, DAGCircuit, DAGOutNode
|
19
|
-
from qiskit.transpiler.basepasses import TransformationPass
|
20
|
-
from qiskit.transpiler.exceptions import TranspilerError
|
21
|
-
from qiskit.transpiler.instruction_durations import InstructionDurations
|
22
|
-
from qiskit.transpiler.passes.scheduling.time_unit_conversion import TimeUnitConversion
|
23
|
-
from qiskit.transpiler.target import Target
|
24
|
-
|
25
|
-
|
26
|
-
class BaseSchedulerTransform(TransformationPass):
|
27
|
-
"""Base scheduler pass.
|
28
|
-
|
29
|
-
.. warning::
|
30
|
-
|
31
|
-
This base class is not part of the public interface for this module
|
32
|
-
it should not be used to develop new scheduling passes as the passes
|
33
|
-
which are using this are pending a future deprecation and subsequent
|
34
|
-
removal. If you are developing new scheduling passes look at the
|
35
|
-
``BaseScheduler`` class instead which is used in the new scheduling
|
36
|
-
pass workflow.
|
37
|
-
|
38
|
-
Policy of topological node ordering in scheduling
|
39
|
-
|
40
|
-
The DAG representation of ``QuantumCircuit`` respects the node ordering also in the
|
41
|
-
classical register wires, though theoretically two conditional instructions
|
42
|
-
conditioned on the same register are commute, i.e. read-access to the
|
43
|
-
classical register doesn't change its state.
|
44
|
-
|
45
|
-
.. code-block:: text
|
46
|
-
|
47
|
-
qc = QuantumCircuit(2, 1)
|
48
|
-
qc.delay(100, 0)
|
49
|
-
qc.x(0).c_if(0, True)
|
50
|
-
qc.x(1).c_if(0, True)
|
51
|
-
|
52
|
-
The scheduler SHOULD comply with above topological ordering policy of the DAG circuit.
|
53
|
-
Accordingly, the `asap`-scheduled circuit will become
|
54
|
-
|
55
|
-
.. code-block:: text
|
56
|
-
|
57
|
-
┌────────────────┐ ┌───┐
|
58
|
-
q_0: ┤ Delay(100[dt]) ├───┤ X ├──────────────
|
59
|
-
├────────────────┤ └─╥─┘ ┌───┐
|
60
|
-
q_1: ┤ Delay(100[dt]) ├─────╫────────┤ X ├───
|
61
|
-
└────────────────┘ ║ └─╥─┘
|
62
|
-
┌────╨────┐┌────╨────┐
|
63
|
-
c: 1/══════════════════╡ c_0=0x1 ╞╡ c_0=0x1 ╞
|
64
|
-
└─────────┘└─────────┘
|
65
|
-
|
66
|
-
Note that this scheduling might be inefficient in some cases,
|
67
|
-
because the second conditional operation can start without waiting the delay of 100 dt.
|
68
|
-
However, such optimization should be done by another pass,
|
69
|
-
otherwise scheduling may break topological ordering of the original circuit.
|
70
|
-
|
71
|
-
Realistic control flow scheduling respecting for microarchitecture
|
72
|
-
|
73
|
-
In the dispersive QND readout scheme, qubit is measured with microwave stimulus to qubit (Q)
|
74
|
-
followed by resonator ring-down (depopulation). This microwave signal is recorded
|
75
|
-
in the buffer memory (B) with hardware kernel, then a discriminated (D) binary value
|
76
|
-
is moved to the classical register (C).
|
77
|
-
The sequence from t0 to t1 of the measure instruction interval might be modeled as follows:
|
78
|
-
|
79
|
-
.. code-block:: text
|
80
|
-
|
81
|
-
Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
82
|
-
B ░░▒▒▒▒▒▒▒▒░░░░░░░░░
|
83
|
-
D ░░░░░░░░░░▒▒▒▒▒▒░░░
|
84
|
-
C ░░░░░░░░░░░░░░░░▒▒░
|
85
|
-
|
86
|
-
However, ``QuantumCircuit`` representation is not enough accurate to represent
|
87
|
-
this model. In the circuit representation, thus ``Qubit`` is occupied by the
|
88
|
-
stimulus microwave signal during the first half of the interval,
|
89
|
-
and ``Clbit`` is only occupied at the very end of the interval.
|
90
|
-
|
91
|
-
This precise model may induce weird edge case.
|
92
|
-
|
93
|
-
.. code-block:: text
|
94
|
-
|
95
|
-
┌───┐
|
96
|
-
q_0: ───┤ X ├──────
|
97
|
-
└─╥─┘ ┌─┐
|
98
|
-
q_1: ─────╫─────┤M├
|
99
|
-
┌────╨────┐└╥┘
|
100
|
-
c: 1/╡ c_0=0x1 ╞═╩═
|
101
|
-
└─────────┘ 0
|
102
|
-
|
103
|
-
In this example, user may intend to measure the state of ``q_1``, after ``XGate`` is
|
104
|
-
applied to the ``q_0``. This is correct interpretation from viewpoint of
|
105
|
-
the topological node ordering, i.e. x gate node come in front of the measure node.
|
106
|
-
However, according to the measurement model above, the data in the register
|
107
|
-
is unchanged during the stimulus, thus two nodes are simultaneously operated.
|
108
|
-
If one `alap`-schedule this circuit, it may return following circuit.
|
109
|
-
|
110
|
-
.. code-block:: text
|
111
|
-
|
112
|
-
┌────────────────┐ ┌───┐
|
113
|
-
q_0: ┤ Delay(500[dt]) ├───┤ X ├──────
|
114
|
-
└────────────────┘ └─╥─┘ ┌─┐
|
115
|
-
q_1: ───────────────────────╫─────┤M├
|
116
|
-
┌────╨────┐└╥┘
|
117
|
-
c: 1/══════════════════╡ c_0=0x1 ╞═╩═
|
118
|
-
└─────────┘ 0
|
119
|
-
|
120
|
-
Note that there is no delay on ``q_1`` wire, and the measure instruction immediately
|
121
|
-
start after t=0, while the conditional gate starts after the delay.
|
122
|
-
It looks like the topological ordering between the nodes are flipped in the scheduled view.
|
123
|
-
This behavior can be understood by considering the control flow model described above,
|
124
|
-
|
125
|
-
.. code-block:: text
|
126
|
-
|
127
|
-
: Quantum Circuit, first-measure
|
128
|
-
0 ░░░░░░░░░░░░▒▒▒▒▒▒░
|
129
|
-
1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
130
|
-
|
131
|
-
: In wire q0
|
132
|
-
Q ░░░░░░░░░░░░░░░▒▒▒░
|
133
|
-
C ░░░░░░░░░░░░▒▒░░░░░
|
134
|
-
|
135
|
-
: In wire q1
|
136
|
-
Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
137
|
-
B ░░▒▒▒▒▒▒▒▒░░░░░░░░░
|
138
|
-
D ░░░░░░░░░░▒▒▒▒▒▒░░░
|
139
|
-
C ░░░░░░░░░░░░░░░░▒▒░
|
140
|
-
|
141
|
-
Since there is no qubit register (Q0, Q1) overlap, the node ordering is determined by the
|
142
|
-
shared classical register C. As you can see, the execution order is still
|
143
|
-
preserved on C, i.e. read C then apply ``XGate``, finally store the measured outcome in C.
|
144
|
-
Because ``DAGOpNode`` cannot define different durations for associated registers,
|
145
|
-
the time ordering of two nodes is inverted anyways.
|
146
|
-
|
147
|
-
This behavior can be controlled by ``clbit_write_latency`` and ``conditional_latency``.
|
148
|
-
The former parameter determines the delay of the register write-access from
|
149
|
-
the beginning of the measure instruction t0, and another parameter determines
|
150
|
-
the delay of conditional gate operation from t0 which comes from the register read-access.
|
151
|
-
|
152
|
-
Since we usually expect topological ordering and time ordering are identical
|
153
|
-
without the context of microarchitecture, both latencies are set to zero by default.
|
154
|
-
In this case, ``Measure`` instruction immediately locks the register C.
|
155
|
-
Under this configuration, the `alap`-scheduled circuit of above example may become
|
156
|
-
|
157
|
-
.. code-block:: text
|
158
|
-
|
159
|
-
┌───┐
|
160
|
-
q_0: ───┤ X ├──────
|
161
|
-
└─╥─┘ ┌─┐
|
162
|
-
q_1: ─────╫─────┤M├
|
163
|
-
┌────╨────┐└╥┘
|
164
|
-
c: 1/╡ c_0=0x1 ╞═╩═
|
165
|
-
└─────────┘ 0
|
166
|
-
|
167
|
-
If the backend microarchitecture supports smart scheduling of the control flow, i.e.
|
168
|
-
it may separately schedule qubit and classical register,
|
169
|
-
insertion of the delay yields unnecessary longer total execution time.
|
170
|
-
|
171
|
-
.. code-block:: text
|
172
|
-
|
173
|
-
: Quantum Circuit, first-xgate
|
174
|
-
0 ░▒▒▒░░░░░░░░░░░░░░░
|
175
|
-
1 ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
176
|
-
|
177
|
-
: In wire q0
|
178
|
-
Q ░▒▒▒░░░░░░░░░░░░░░░
|
179
|
-
C ░░░░░░░░░░░░░░░░░░░ (zero latency)
|
180
|
-
|
181
|
-
: In wire q1
|
182
|
-
Q ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
183
|
-
C ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░ (zero latency, scheduled after C0 read-access)
|
184
|
-
|
185
|
-
However this result is much more intuitive in the topological ordering view.
|
186
|
-
If finite conditional latency is provided, for example, 30 dt, the circuit
|
187
|
-
is scheduled as follows.
|
188
|
-
|
189
|
-
.. code-block:: text
|
190
|
-
|
191
|
-
┌───────────────┐ ┌───┐
|
192
|
-
q_0: ┤ Delay(30[dt]) ├───┤ X ├──────
|
193
|
-
├───────────────┤ └─╥─┘ ┌─┐
|
194
|
-
q_1: ┤ Delay(30[dt]) ├─────╫─────┤M├
|
195
|
-
└───────────────┘┌────╨────┐└╥┘
|
196
|
-
c: 1/═════════════════╡ c_0=0x1 ╞═╩═
|
197
|
-
└─────────┘ 0
|
198
|
-
|
199
|
-
with the timing model:
|
200
|
-
|
201
|
-
.. code-block:: text
|
202
|
-
|
203
|
-
: Quantum Circuit, first-xgate
|
204
|
-
0 ░░▒▒▒░░░░░░░░░░░░░░░
|
205
|
-
1 ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
206
|
-
|
207
|
-
: In wire q0
|
208
|
-
Q ░░▒▒▒░░░░░░░░░░░░░░░
|
209
|
-
C ░▒░░░░░░░░░░░░░░░░░░ (30dt latency)
|
210
|
-
|
211
|
-
: In wire q1
|
212
|
-
Q ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
213
|
-
C ░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░
|
214
|
-
|
215
|
-
See https://arxiv.org/abs/2102.01682 for more details.
|
216
|
-
|
217
|
-
"""
|
218
|
-
|
219
|
-
CONDITIONAL_SUPPORTED = (Gate, Delay)
|
220
|
-
|
221
|
-
def __init__(
|
222
|
-
self,
|
223
|
-
durations: InstructionDurations = None,
|
224
|
-
clbit_write_latency: int = 0,
|
225
|
-
conditional_latency: int = 0,
|
226
|
-
target: Target = None,
|
227
|
-
):
|
228
|
-
"""Scheduler initializer.
|
229
|
-
|
230
|
-
Args:
|
231
|
-
durations: Durations of instructions to be used in scheduling
|
232
|
-
clbit_write_latency: A control flow constraints. Because standard superconducting
|
233
|
-
quantum processor implement dispersive QND readout, the actual data transfer
|
234
|
-
to the clbit happens after the round-trip stimulus signal is buffered
|
235
|
-
and discriminated into quantum state.
|
236
|
-
The interval ``[t0, t0 + clbit_write_latency]`` is regarded as idle time
|
237
|
-
for clbits associated with the measure instruction.
|
238
|
-
This defaults to 0 dt which is identical to Qiskit Pulse scheduler.
|
239
|
-
conditional_latency: A control flow constraints. This value represents
|
240
|
-
a latency of reading a classical register for the conditional operation.
|
241
|
-
The gate operation occurs after this latency. This appears as a delay
|
242
|
-
in front of the DAGOpNode of the gate.
|
243
|
-
This defaults to 0 dt.
|
244
|
-
target: The :class:`~.Target` representing the target backend, if both
|
245
|
-
``durations`` and this are specified then this argument will take
|
246
|
-
precedence and ``durations`` will be ignored.
|
247
|
-
"""
|
248
|
-
super().__init__()
|
249
|
-
self.durations = durations
|
250
|
-
# Ensure op node durations are attached and in consistent unit
|
251
|
-
if target is not None:
|
252
|
-
self.durations = target.durations()
|
253
|
-
self.requires.append(TimeUnitConversion(self.durations))
|
254
|
-
|
255
|
-
# Control flow constraints.
|
256
|
-
self.clbit_write_latency = clbit_write_latency
|
257
|
-
self.conditional_latency = conditional_latency
|
258
|
-
|
259
|
-
self.target = target
|
260
|
-
|
261
|
-
@staticmethod
|
262
|
-
def _get_node_duration(
|
263
|
-
node: DAGOpNode,
|
264
|
-
dag: DAGCircuit,
|
265
|
-
) -> int:
|
266
|
-
"""A helper method to get duration from node or calibration."""
|
267
|
-
indices = [dag.find_bit(qarg).index for qarg in node.qargs]
|
268
|
-
|
269
|
-
if dag._has_calibration_for(node):
|
270
|
-
# If node has calibration, this value should be the highest priority
|
271
|
-
cal_key = tuple(indices), tuple(float(p) for p in node.op.params)
|
272
|
-
duration = dag._calibrations_prop[node.op.name][cal_key].duration
|
273
|
-
else:
|
274
|
-
duration = node.op.duration
|
275
|
-
|
276
|
-
if isinstance(node.op, Reset):
|
277
|
-
warnings.warn(
|
278
|
-
"Qiskit scheduler assumes Reset works similarly to Measure instruction. "
|
279
|
-
"Actual behavior depends on the control system of your quantum backend. "
|
280
|
-
"Your backend may provide a plugin scheduler pass."
|
281
|
-
)
|
282
|
-
elif isinstance(node.op, Measure):
|
283
|
-
is_mid_circuit = not any(
|
284
|
-
isinstance(x, DAGOutNode) for x in dag.quantum_successors(node)
|
285
|
-
)
|
286
|
-
if is_mid_circuit:
|
287
|
-
warnings.warn(
|
288
|
-
"Qiskit scheduler assumes mid-circuit measurement works as a standard instruction. "
|
289
|
-
"Actual backend may apply custom scheduling. "
|
290
|
-
"Your backend may provide a plugin scheduler pass."
|
291
|
-
)
|
292
|
-
|
293
|
-
if isinstance(duration, ParameterExpression):
|
294
|
-
raise TranspilerError(
|
295
|
-
f"Parameterized duration ({duration}) "
|
296
|
-
f"of {node.op.name} on qubits {indices} is not bounded."
|
297
|
-
)
|
298
|
-
if duration is None:
|
299
|
-
raise TranspilerError(f"Duration of {node.op.name} on qubits {indices} is not found.")
|
300
|
-
|
301
|
-
return duration
|
302
|
-
|
303
|
-
def _delay_supported(self, qarg: int) -> bool:
|
304
|
-
"""Delay operation is supported on the qubit (qarg) or not."""
|
305
|
-
if self.target is None or self.target.instruction_supported("delay", qargs=(qarg,)):
|
306
|
-
return True
|
307
|
-
return False
|
308
|
-
|
309
|
-
def run(self, dag: DAGCircuit):
|
310
|
-
raise NotImplementedError
|
@@ -1,313 +0,0 @@
|
|
1
|
-
# This code is part of Qiskit.
|
2
|
-
#
|
3
|
-
# (C) Copyright IBM 2021, 2024.
|
4
|
-
#
|
5
|
-
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
-
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
-
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
-
#
|
9
|
-
# Any modifications or derivative works of this code must retain this
|
10
|
-
# copyright notice, and modified files need to carry a notice indicating
|
11
|
-
# that they have been altered from the originals.
|
12
|
-
|
13
|
-
"""Dynamical Decoupling insertion pass."""
|
14
|
-
|
15
|
-
import itertools
|
16
|
-
import warnings
|
17
|
-
|
18
|
-
import numpy as np
|
19
|
-
from qiskit.circuit import Gate, Delay, Reset
|
20
|
-
from qiskit.circuit.library.standard_gates import IGate, UGate, U3Gate
|
21
|
-
from qiskit.dagcircuit import DAGOpNode, DAGInNode
|
22
|
-
from qiskit.quantum_info.operators.predicates import matrix_equal
|
23
|
-
from qiskit.synthesis.one_qubit import OneQubitEulerDecomposer
|
24
|
-
from qiskit.transpiler.basepasses import TransformationPass
|
25
|
-
from qiskit.transpiler.exceptions import TranspilerError
|
26
|
-
from qiskit.transpiler.instruction_durations import InstructionDurations
|
27
|
-
from qiskit.transpiler.passes.optimization import Optimize1qGates
|
28
|
-
from qiskit.utils.deprecation import deprecate_func
|
29
|
-
|
30
|
-
|
31
|
-
class DynamicalDecoupling(TransformationPass):
|
32
|
-
"""Dynamical decoupling insertion pass.
|
33
|
-
|
34
|
-
This pass works on a scheduled, physical circuit. It scans the circuit for
|
35
|
-
idle periods of time (i.e. those containing delay instructions) and inserts
|
36
|
-
a DD sequence of gates in those spots. These gates amount to the identity,
|
37
|
-
so do not alter the logical action of the circuit, but have the effect of
|
38
|
-
mitigating decoherence in those idle periods.
|
39
|
-
|
40
|
-
As a special case, the pass allows a length-1 sequence (e.g. [XGate()]).
|
41
|
-
In this case the DD insertion happens only when the gate inverse can be
|
42
|
-
absorbed into a neighboring gate in the circuit (so we would still be
|
43
|
-
replacing Delay with something that is equivalent to the identity).
|
44
|
-
This can be used, for instance, as a Hahn echo.
|
45
|
-
|
46
|
-
This pass ensures that the inserted sequence preserves the circuit exactly
|
47
|
-
(including global phase).
|
48
|
-
|
49
|
-
.. plot::
|
50
|
-
:alt: Output from the previous code.
|
51
|
-
:include-source:
|
52
|
-
|
53
|
-
import numpy as np
|
54
|
-
from qiskit.circuit import QuantumCircuit
|
55
|
-
from qiskit.circuit.library import XGate
|
56
|
-
from qiskit.transpiler import PassManager, InstructionDurations
|
57
|
-
from qiskit.transpiler.passes import ALAPSchedule, DynamicalDecoupling
|
58
|
-
from qiskit.visualization import timeline_drawer
|
59
|
-
|
60
|
-
# Because the legacy passes do not propagate the scheduling information correctly, it is
|
61
|
-
# necessary to run a no-op "re-schedule" before the output circuits can be drawn.
|
62
|
-
def draw(circuit):
|
63
|
-
from qiskit import transpile
|
64
|
-
|
65
|
-
scheduled = transpile(
|
66
|
-
circuit,
|
67
|
-
optimization_level=0,
|
68
|
-
instruction_durations=InstructionDurations(),
|
69
|
-
scheduling_method="alap",
|
70
|
-
)
|
71
|
-
return timeline_drawer(scheduled)
|
72
|
-
|
73
|
-
circ = QuantumCircuit(4)
|
74
|
-
circ.h(0)
|
75
|
-
circ.cx(0, 1)
|
76
|
-
circ.cx(1, 2)
|
77
|
-
circ.cx(2, 3)
|
78
|
-
circ.measure_all()
|
79
|
-
durations = InstructionDurations(
|
80
|
-
[("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
|
81
|
-
("cx", [1, 2], 200), ("cx", [2, 3], 300),
|
82
|
-
("x", None, 50), ("measure", None, 1000)]
|
83
|
-
)
|
84
|
-
# balanced X-X sequence on all qubits
|
85
|
-
dd_sequence = [XGate(), XGate()]
|
86
|
-
pm = PassManager([ALAPSchedule(durations),
|
87
|
-
DynamicalDecoupling(durations, dd_sequence)])
|
88
|
-
circ_dd = pm.run(circ)
|
89
|
-
draw(circ_dd)
|
90
|
-
|
91
|
-
# Uhrig sequence on qubit 0
|
92
|
-
n = 8
|
93
|
-
dd_sequence = [XGate()] * n
|
94
|
-
def uhrig_pulse_location(k):
|
95
|
-
return np.sin(np.pi * (k + 1) / (2 * n + 2)) ** 2
|
96
|
-
spacing = []
|
97
|
-
for k in range(n):
|
98
|
-
spacing.append(uhrig_pulse_location(k) - sum(spacing))
|
99
|
-
spacing.append(1 - sum(spacing))
|
100
|
-
pm = PassManager(
|
101
|
-
[
|
102
|
-
ALAPSchedule(durations),
|
103
|
-
DynamicalDecoupling(durations, dd_sequence, qubits=[0], spacing=spacing),
|
104
|
-
]
|
105
|
-
)
|
106
|
-
circ_dd = pm.run(circ)
|
107
|
-
draw(circ_dd)
|
108
|
-
"""
|
109
|
-
|
110
|
-
@deprecate_func(
|
111
|
-
additional_msg=(
|
112
|
-
"Instead, use :class:`~.PadDynamicalDecoupling`, which performs the same "
|
113
|
-
"function but requires scheduling and alignment analysis passes to run prior to it."
|
114
|
-
),
|
115
|
-
since="1.1.0",
|
116
|
-
)
|
117
|
-
def __init__(
|
118
|
-
self, durations, dd_sequence, qubits=None, spacing=None, skip_reset_qubits=True, target=None
|
119
|
-
):
|
120
|
-
"""Dynamical decoupling initializer.
|
121
|
-
|
122
|
-
Args:
|
123
|
-
durations (InstructionDurations): Durations of instructions to be
|
124
|
-
used in scheduling.
|
125
|
-
dd_sequence (list[Gate]): sequence of gates to apply in idle spots.
|
126
|
-
qubits (list[int]): physical qubits on which to apply DD.
|
127
|
-
If None, all qubits will undergo DD (when possible).
|
128
|
-
spacing (list[float]): a list of spacings between the DD gates.
|
129
|
-
The available slack will be divided according to this.
|
130
|
-
The list length must be one more than the length of dd_sequence,
|
131
|
-
and the elements must sum to 1. If None, a balanced spacing
|
132
|
-
will be used [d/2, d, d, ..., d, d, d/2].
|
133
|
-
skip_reset_qubits (bool): if True, does not insert DD on idle
|
134
|
-
periods that immediately follow initialized/reset qubits (as
|
135
|
-
qubits in the ground state are less susceptible to decoherence).
|
136
|
-
target (Target): The :class:`~.Target` representing the target backend, if both
|
137
|
-
``durations`` and this are specified then this argument will take
|
138
|
-
precedence and ``durations`` will be ignored.
|
139
|
-
"""
|
140
|
-
super().__init__()
|
141
|
-
self._durations = durations
|
142
|
-
self._dd_sequence = dd_sequence
|
143
|
-
self._qubits = qubits
|
144
|
-
self._spacing = spacing
|
145
|
-
self._skip_reset_qubits = skip_reset_qubits
|
146
|
-
self._target = target
|
147
|
-
if target is not None:
|
148
|
-
self._durations = target.durations()
|
149
|
-
for gate in dd_sequence:
|
150
|
-
if gate.name not in target.operation_names:
|
151
|
-
raise TranspilerError(
|
152
|
-
f"{gate.name} in dd_sequence is not supported in the target"
|
153
|
-
)
|
154
|
-
|
155
|
-
def run(self, dag):
|
156
|
-
"""Run the DynamicalDecoupling pass on dag.
|
157
|
-
|
158
|
-
Args:
|
159
|
-
dag (DAGCircuit): a scheduled DAG.
|
160
|
-
|
161
|
-
Returns:
|
162
|
-
DAGCircuit: equivalent circuit with delays interrupted by DD,
|
163
|
-
where possible.
|
164
|
-
|
165
|
-
Raises:
|
166
|
-
TranspilerError: if the circuit is not mapped on physical qubits.
|
167
|
-
"""
|
168
|
-
if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
|
169
|
-
raise TranspilerError("DD runs on physical circuits only.")
|
170
|
-
|
171
|
-
if dag.duration is None:
|
172
|
-
raise TranspilerError("DD runs after circuit is scheduled.")
|
173
|
-
|
174
|
-
durations = self._update_inst_durations(dag)
|
175
|
-
|
176
|
-
num_pulses = len(self._dd_sequence)
|
177
|
-
sequence_gphase = 0
|
178
|
-
if num_pulses != 1:
|
179
|
-
if num_pulses % 2 != 0:
|
180
|
-
raise TranspilerError("DD sequence must contain an even number of gates (or 1).")
|
181
|
-
noop = np.eye(2)
|
182
|
-
for gate in self._dd_sequence:
|
183
|
-
noop = noop.dot(gate.to_matrix())
|
184
|
-
if not matrix_equal(noop, IGate().to_matrix(), ignore_phase=True):
|
185
|
-
raise TranspilerError("The DD sequence does not make an identity operation.")
|
186
|
-
sequence_gphase = np.angle(noop[0][0])
|
187
|
-
|
188
|
-
if self._qubits is None:
|
189
|
-
self._qubits = set(range(dag.num_qubits()))
|
190
|
-
else:
|
191
|
-
self._qubits = set(self._qubits)
|
192
|
-
|
193
|
-
if self._spacing:
|
194
|
-
if sum(self._spacing) != 1 or any(a < 0 for a in self._spacing):
|
195
|
-
raise TranspilerError(
|
196
|
-
"The spacings must be given in terms of fractions "
|
197
|
-
"of the slack period and sum to 1."
|
198
|
-
)
|
199
|
-
else: # default to balanced spacing
|
200
|
-
mid = 1 / num_pulses
|
201
|
-
end = mid / 2
|
202
|
-
self._spacing = [end] + [mid] * (num_pulses - 1) + [end]
|
203
|
-
|
204
|
-
for qarg in list(self._qubits):
|
205
|
-
for gate in self._dd_sequence:
|
206
|
-
if not self.__gate_supported(gate, qarg):
|
207
|
-
self._qubits.discard(qarg)
|
208
|
-
break
|
209
|
-
|
210
|
-
index_sequence_duration_map = {}
|
211
|
-
for physical_qubit in self._qubits:
|
212
|
-
dd_sequence_duration = 0
|
213
|
-
for index, gate in enumerate(self._dd_sequence):
|
214
|
-
gate = gate.to_mutable()
|
215
|
-
self._dd_sequence[index] = gate
|
216
|
-
gate.duration = durations.get(gate, physical_qubit)
|
217
|
-
|
218
|
-
dd_sequence_duration += gate.duration
|
219
|
-
index_sequence_duration_map[physical_qubit] = dd_sequence_duration
|
220
|
-
|
221
|
-
new_dag = dag.copy_empty_like()
|
222
|
-
|
223
|
-
for nd in dag.topological_op_nodes():
|
224
|
-
if not isinstance(nd.op, Delay):
|
225
|
-
new_dag.apply_operation_back(nd.op, nd.qargs, nd.cargs, check=False)
|
226
|
-
continue
|
227
|
-
|
228
|
-
dag_qubit = nd.qargs[0]
|
229
|
-
physical_qubit = dag.find_bit(dag_qubit).index
|
230
|
-
if physical_qubit not in self._qubits: # skip unwanted qubits
|
231
|
-
new_dag.apply_operation_back(nd.op, nd.qargs, nd.cargs, check=False)
|
232
|
-
continue
|
233
|
-
|
234
|
-
pred = next(dag.predecessors(nd))
|
235
|
-
succ = next(dag.successors(nd))
|
236
|
-
if self._skip_reset_qubits: # discount initial delays
|
237
|
-
if isinstance(pred, DAGInNode) or isinstance(pred.op, Reset):
|
238
|
-
new_dag.apply_operation_back(nd.op, nd.qargs, nd.cargs, check=False)
|
239
|
-
continue
|
240
|
-
|
241
|
-
dd_sequence_duration = index_sequence_duration_map[physical_qubit]
|
242
|
-
slack = nd.op.duration - dd_sequence_duration
|
243
|
-
if slack <= 0: # dd doesn't fit
|
244
|
-
new_dag.apply_operation_back(nd.op, nd.qargs, nd.cargs, check=False)
|
245
|
-
continue
|
246
|
-
|
247
|
-
if num_pulses == 1: # special case of using a single gate for DD
|
248
|
-
u_inv = self._dd_sequence[0].inverse().to_matrix()
|
249
|
-
theta, phi, lam, phase = OneQubitEulerDecomposer().angles_and_phase(u_inv)
|
250
|
-
# absorb the inverse into the successor (from left in circuit)
|
251
|
-
if isinstance(succ, DAGOpNode) and isinstance(succ.op, (UGate, U3Gate)):
|
252
|
-
theta_r, phi_r, lam_r = succ.op.params
|
253
|
-
succ.op.params = Optimize1qGates.compose_u3(
|
254
|
-
theta_r, phi_r, lam_r, theta, phi, lam
|
255
|
-
)
|
256
|
-
sequence_gphase += phase
|
257
|
-
# absorb the inverse into the predecessor (from right in circuit)
|
258
|
-
elif isinstance(pred, DAGOpNode) and isinstance(pred.op, (UGate, U3Gate)):
|
259
|
-
theta_l, phi_l, lam_l = pred.op.params
|
260
|
-
pred.op.params = Optimize1qGates.compose_u3(
|
261
|
-
theta, phi, lam, theta_l, phi_l, lam_l
|
262
|
-
)
|
263
|
-
sequence_gphase += phase
|
264
|
-
# don't do anything if there's no single-qubit gate to absorb the inverse
|
265
|
-
else:
|
266
|
-
new_dag.apply_operation_back(nd.op, nd.qargs, nd.cargs, check=False)
|
267
|
-
continue
|
268
|
-
|
269
|
-
# insert the actual DD sequence
|
270
|
-
taus = [int(slack * a) for a in self._spacing]
|
271
|
-
unused_slack = slack - sum(taus) # unused, due to rounding to int multiples of dt
|
272
|
-
middle_index = int((len(taus) - 1) / 2) # arbitrary: redistribute to middle
|
273
|
-
taus[middle_index] += unused_slack # now we add up to original delay duration
|
274
|
-
|
275
|
-
for tau, gate in itertools.zip_longest(taus, self._dd_sequence):
|
276
|
-
if tau > 0:
|
277
|
-
new_dag.apply_operation_back(Delay(tau), [dag_qubit], check=False)
|
278
|
-
if gate is not None:
|
279
|
-
new_dag.apply_operation_back(gate, [dag_qubit], check=False)
|
280
|
-
|
281
|
-
new_dag.global_phase = new_dag.global_phase + sequence_gphase
|
282
|
-
|
283
|
-
return new_dag
|
284
|
-
|
285
|
-
def _update_inst_durations(self, dag):
|
286
|
-
"""Update instruction durations with circuit information. If the dag contains gate
|
287
|
-
calibrations and no instruction durations were provided through the target or as a
|
288
|
-
standalone input, the circuit calibration durations will be used.
|
289
|
-
The priority order for instruction durations is: target > standalone > circuit.
|
290
|
-
"""
|
291
|
-
circ_durations = InstructionDurations()
|
292
|
-
|
293
|
-
if dag._calibrations_prop:
|
294
|
-
cal_durations = []
|
295
|
-
with warnings.catch_warnings():
|
296
|
-
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
297
|
-
# `schedule.duration` emits pulse deprecation warnings which we don't want
|
298
|
-
# to see here
|
299
|
-
for gate, gate_cals in dag._calibrations_prop.items():
|
300
|
-
for (qubits, parameters), schedule in gate_cals.items():
|
301
|
-
cal_durations.append((gate, qubits, parameters, schedule.duration))
|
302
|
-
circ_durations.update(cal_durations, circ_durations.dt)
|
303
|
-
|
304
|
-
if self._durations is not None:
|
305
|
-
circ_durations.update(self._durations, getattr(self._durations, "dt", None))
|
306
|
-
|
307
|
-
return circ_durations
|
308
|
-
|
309
|
-
def __gate_supported(self, gate: Gate, qarg: int) -> bool:
|
310
|
-
"""A gate is supported on the qubit (qarg) or not."""
|
311
|
-
if self._target is None or self._target.instruction_supported(gate.name, qargs=(qarg,)):
|
312
|
-
return True
|
313
|
-
return False
|