qiskit 1.4.0__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 +7 -140
- 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 +168 -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 +5 -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 +27 -12
- qiskit/visualization/timeline/interface.py +23 -18
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
- {qiskit-1.4.0.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.0.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -23,10 +23,8 @@ from rustworkx import PyDiGraph, vf2_mapping, PyGraph
|
|
23
23
|
from qiskit.transpiler.layout import Layout
|
24
24
|
from qiskit.transpiler.basepasses import AnalysisPass
|
25
25
|
from qiskit.transpiler.exceptions import TranspilerError
|
26
|
-
from qiskit.providers.exceptions import BackendPropertyError
|
27
26
|
from qiskit.transpiler.passes.layout import vf2_utils
|
28
27
|
|
29
|
-
from qiskit.utils import deprecate_arg
|
30
28
|
|
31
29
|
logger = logging.getLogger(__name__)
|
32
30
|
|
@@ -79,8 +77,7 @@ class VF2PostLayout(AnalysisPass):
|
|
79
77
|
* ``">2q gates in basis"``: If VF2PostLayout can't work with the basis of the circuit.
|
80
78
|
|
81
79
|
By default, this pass will construct a heuristic scoring map based on
|
82
|
-
the error rates in the provided ``target
|
83
|
-
is not provided). However, analysis passes can be run prior to this pass
|
80
|
+
the error rates in the provided ``target``. However, analysis passes can be run prior to this pass
|
84
81
|
and set ``vf2_avg_error_map`` in the property set with a :class:`~.ErrorMap`
|
85
82
|
instance. If a value is ``NaN`` that is treated as an ideal edge
|
86
83
|
For example if an error map is created as::
|
@@ -100,32 +97,9 @@ class VF2PostLayout(AnalysisPass):
|
|
100
97
|
is run.
|
101
98
|
"""
|
102
99
|
|
103
|
-
@deprecate_arg(
|
104
|
-
name="properties",
|
105
|
-
since="1.4",
|
106
|
-
package_name="Qiskit",
|
107
|
-
removal_timeline="in Qiskit 2.0",
|
108
|
-
additional_msg="The BackendProperties data structure has been deprecated and will be "
|
109
|
-
"removed in Qiskit 2.0. The `target` input argument should be used instead. "
|
110
|
-
"You can use Target.from_configuration() to build the target from the properties "
|
111
|
-
"object, but in 2.0 you will need to generate a target directly.",
|
112
|
-
)
|
113
|
-
@deprecate_arg(
|
114
|
-
name="coupling_map",
|
115
|
-
since="1.4",
|
116
|
-
package_name="Qiskit",
|
117
|
-
removal_timeline="in Qiskit 2.0",
|
118
|
-
additional_msg="This argument was only used with `properties`, which relied on "
|
119
|
-
"the deprecated BackendProperties data structure. The `target` input argument "
|
120
|
-
"should be used instead. "
|
121
|
-
"You can use Target.from_configuration() to build the target from coupling "
|
122
|
-
"map + properties, but in 2.0 you will need to generate a target directly.",
|
123
|
-
)
|
124
100
|
def __init__(
|
125
101
|
self,
|
126
102
|
target=None,
|
127
|
-
coupling_map=None,
|
128
|
-
properties=None,
|
129
103
|
seed=None,
|
130
104
|
call_limit=None,
|
131
105
|
time_limit=None,
|
@@ -136,12 +110,6 @@ class VF2PostLayout(AnalysisPass):
|
|
136
110
|
|
137
111
|
Args:
|
138
112
|
target (Target): A target representing the backend device to run ``VF2PostLayout`` on.
|
139
|
-
If specified it will supersede a set value for ``properties`` and
|
140
|
-
``coupling_map``.
|
141
|
-
coupling_map (CouplingMap): Directed graph representing a coupling map.
|
142
|
-
properties (BackendProperties): The backend properties for the backend. If
|
143
|
-
:meth:`~qiskit.providers.models.BackendProperties.readout_error` is available
|
144
|
-
it is used to score the layout.
|
145
113
|
seed (int): Sets the seed of the PRNG. -1 Means no node shuffling.
|
146
114
|
call_limit (int): The number of state visits to attempt in each execution of
|
147
115
|
VF2.
|
@@ -160,12 +128,10 @@ class VF2PostLayout(AnalysisPass):
|
|
160
128
|
a layout. A value of ``0`` (the default) means 'unlimited'.
|
161
129
|
|
162
130
|
Raises:
|
163
|
-
TypeError: At runtime, if
|
131
|
+
TypeError: At runtime, if ``target`` isn't provided.
|
164
132
|
"""
|
165
133
|
super().__init__()
|
166
134
|
self.target = target
|
167
|
-
self.coupling_map = coupling_map
|
168
|
-
self.properties = properties
|
169
135
|
self.call_limit = call_limit
|
170
136
|
self.time_limit = time_limit
|
171
137
|
self.max_trials = max_trials
|
@@ -175,16 +141,12 @@ class VF2PostLayout(AnalysisPass):
|
|
175
141
|
|
176
142
|
def run(self, dag):
|
177
143
|
"""run the layout method"""
|
178
|
-
if self.target is None
|
179
|
-
raise TranspilerError(
|
180
|
-
"A target must be specified or a coupling map and properties must be provided"
|
181
|
-
)
|
144
|
+
if self.target is None:
|
145
|
+
raise TranspilerError("A target must be specified or a coupling map must be provided")
|
182
146
|
if not self.strict_direction:
|
183
147
|
self.avg_error_map = self.property_set["vf2_avg_error_map"]
|
184
148
|
if self.avg_error_map is None:
|
185
|
-
self.avg_error_map = vf2_utils.build_average_error_map(
|
186
|
-
self.target, self.properties, self.coupling_map
|
187
|
-
)
|
149
|
+
self.avg_error_map = vf2_utils.build_average_error_map(self.target, None)
|
188
150
|
|
189
151
|
result = vf2_utils.build_interaction_graph(dag, self.strict_direction)
|
190
152
|
if result is None:
|
@@ -194,67 +156,62 @@ class VF2PostLayout(AnalysisPass):
|
|
194
156
|
scoring_bit_list = vf2_utils.build_bit_list(im_graph, im_graph_node_map)
|
195
157
|
scoring_edge_list = vf2_utils.build_edge_list(im_graph)
|
196
158
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
cm_graph = PyDiGraph(multigraph=False)
|
204
|
-
else:
|
205
|
-
cm_graph = PyGraph(multigraph=False)
|
206
|
-
# If None is present in qargs there are globally defined ideal operations
|
207
|
-
# we should add these to all entries based on the number of qubits, so we
|
208
|
-
# treat that as a valid operation even if there is no scoring for the
|
209
|
-
# strict direction case
|
210
|
-
global_ops = None
|
211
|
-
if None in self.target.qargs:
|
212
|
-
global_ops = {1: [], 2: []}
|
213
|
-
for op in self.target.operation_names_for_qargs(None):
|
214
|
-
operation = self.target.operation_for_name(op)
|
215
|
-
# If operation is a class this is a variable width ideal instruction
|
216
|
-
# so we treat it as available on both 1 and 2 qubits
|
217
|
-
if inspect.isclass(operation):
|
218
|
-
global_ops[1].append(op)
|
219
|
-
global_ops[2].append(op)
|
220
|
-
else:
|
221
|
-
num_qubits = operation.num_qubits
|
222
|
-
if num_qubits in global_ops:
|
223
|
-
global_ops[num_qubits].append(op)
|
224
|
-
op_names = []
|
225
|
-
for i in range(self.target.num_qubits):
|
226
|
-
try:
|
227
|
-
entry = set(self.target.operation_names_for_qargs((i,)))
|
228
|
-
except KeyError:
|
229
|
-
entry = set()
|
230
|
-
if global_ops is not None:
|
231
|
-
entry.update(global_ops[1])
|
232
|
-
op_names.append(entry)
|
233
|
-
cm_graph.add_nodes_from(op_names)
|
234
|
-
for qargs in self.target.qargs:
|
235
|
-
len_args = len(qargs)
|
236
|
-
# If qargs == 1 we already populated it and if qargs > 2 there are no instructions
|
237
|
-
# using those in the circuit because we'd have already returned by this point
|
238
|
-
if len_args == 2:
|
239
|
-
ops = set(self.target.operation_names_for_qargs(qargs))
|
240
|
-
if global_ops is not None:
|
241
|
-
ops.update(global_ops[2])
|
242
|
-
cm_graph.add_edge(qargs[0], qargs[1], ops)
|
243
|
-
cm_nodes = list(cm_graph.node_indexes())
|
244
|
-
# Filter qubits without any supported operations. If they
|
245
|
-
# don't support any operations, they're not valid for layout selection.
|
246
|
-
# This is only needed in the undirected case because in strict direction
|
247
|
-
# mode the node matcher will not match since none of the circuit ops
|
248
|
-
# will match the cmap ops.
|
249
|
-
if not self.strict_direction:
|
250
|
-
has_operations = set(itertools.chain.from_iterable(self.target.qargs))
|
251
|
-
to_remove = set(cm_graph.node_indices()).difference(has_operations)
|
252
|
-
if to_remove:
|
253
|
-
cm_graph.remove_nodes_from(list(to_remove))
|
159
|
+
# If qargs is None then target is global and ideal so no
|
160
|
+
# scoring is needed
|
161
|
+
if self.target.qargs is None:
|
162
|
+
return
|
163
|
+
if self.strict_direction:
|
164
|
+
cm_graph = PyDiGraph(multigraph=False)
|
254
165
|
else:
|
255
|
-
cm_graph
|
256
|
-
|
257
|
-
|
166
|
+
cm_graph = PyGraph(multigraph=False)
|
167
|
+
# If None is present in qargs there are globally defined ideal operations
|
168
|
+
# we should add these to all entries based on the number of qubits, so we
|
169
|
+
# treat that as a valid operation even if there is no scoring for the
|
170
|
+
# strict direction case
|
171
|
+
global_ops = None
|
172
|
+
if None in self.target.qargs:
|
173
|
+
global_ops = {1: [], 2: []}
|
174
|
+
for op in self.target.operation_names_for_qargs(None):
|
175
|
+
operation = self.target.operation_for_name(op)
|
176
|
+
# If operation is a class this is a variable width ideal instruction
|
177
|
+
# so we treat it as available on both 1 and 2 qubits
|
178
|
+
if inspect.isclass(operation):
|
179
|
+
global_ops[1].append(op)
|
180
|
+
global_ops[2].append(op)
|
181
|
+
else:
|
182
|
+
num_qubits = operation.num_qubits
|
183
|
+
if num_qubits in global_ops:
|
184
|
+
global_ops[num_qubits].append(op)
|
185
|
+
op_names = []
|
186
|
+
for i in range(self.target.num_qubits):
|
187
|
+
try:
|
188
|
+
entry = set(self.target.operation_names_for_qargs((i,)))
|
189
|
+
except KeyError:
|
190
|
+
entry = set()
|
191
|
+
if global_ops is not None:
|
192
|
+
entry.update(global_ops[1])
|
193
|
+
op_names.append(entry)
|
194
|
+
cm_graph.add_nodes_from(op_names)
|
195
|
+
for qargs in self.target.qargs:
|
196
|
+
len_args = len(qargs)
|
197
|
+
# If qargs == 1 we already populated it and if qargs > 2 there are no instructions
|
198
|
+
# using those in the circuit because we'd have already returned by this point
|
199
|
+
if len_args == 2:
|
200
|
+
ops = set(self.target.operation_names_for_qargs(qargs))
|
201
|
+
if global_ops is not None:
|
202
|
+
ops.update(global_ops[2])
|
203
|
+
cm_graph.add_edge(qargs[0], qargs[1], ops)
|
204
|
+
cm_nodes = list(cm_graph.node_indexes())
|
205
|
+
# Filter qubits without any supported operations. If they
|
206
|
+
# don't support any operations, they're not valid for layout selection.
|
207
|
+
# This is only needed in the undirected case because in strict direction
|
208
|
+
# mode the node matcher will not match since none of the circuit ops
|
209
|
+
# will match the cmap ops.
|
210
|
+
if not self.strict_direction:
|
211
|
+
has_operations = set(itertools.chain.from_iterable(self.target.qargs))
|
212
|
+
to_remove = set(cm_graph.node_indices()).difference(has_operations)
|
213
|
+
if to_remove:
|
214
|
+
cm_graph.remove_nodes_from(list(to_remove))
|
258
215
|
|
259
216
|
logger.debug("Running VF2 to find post transpile mappings")
|
260
217
|
if self.target and self.strict_direction:
|
@@ -416,26 +373,4 @@ class VF2PostLayout(AnalysisPass):
|
|
416
373
|
props = self.target[gate][qargs]
|
417
374
|
if props is not None and props.error is not None:
|
418
375
|
fidelity *= (1 - props.error) ** count
|
419
|
-
else:
|
420
|
-
for bit, node_index in bit_map.items():
|
421
|
-
gate_counts = im_graph[node_index]
|
422
|
-
for gate, count in gate_counts.items():
|
423
|
-
if gate == "measure":
|
424
|
-
try:
|
425
|
-
fidelity *= (1 - self.properties.readout_error(bits[bit])) ** count
|
426
|
-
except BackendPropertyError:
|
427
|
-
pass
|
428
|
-
else:
|
429
|
-
try:
|
430
|
-
fidelity *= (1 - self.properties.gate_error(gate, bits[bit])) ** count
|
431
|
-
except BackendPropertyError:
|
432
|
-
pass
|
433
|
-
for edge in im_graph.edge_index_map().values():
|
434
|
-
qargs = (bits[reverse_bit_map[edge[0]]], bits[reverse_bit_map[edge[1]]])
|
435
|
-
gate_counts = edge[2]
|
436
|
-
for gate, count in gate_counts.items():
|
437
|
-
try:
|
438
|
-
fidelity *= (1 - self.properties.gate_error(gate, qargs)) ** count
|
439
|
-
except BackendPropertyError:
|
440
|
-
pass
|
441
376
|
return 1 - fidelity
|
@@ -13,7 +13,6 @@
|
|
13
13
|
"""This module contains common utils for vf2 layout passes."""
|
14
14
|
|
15
15
|
from collections import defaultdict
|
16
|
-
import statistics
|
17
16
|
import random
|
18
17
|
|
19
18
|
import numpy as np
|
@@ -142,7 +141,7 @@ def score_layout(
|
|
142
141
|
)
|
143
142
|
|
144
143
|
|
145
|
-
def build_average_error_map(target,
|
144
|
+
def build_average_error_map(target, coupling_map):
|
146
145
|
"""Build an average error map used for scoring layouts pre-basis translation."""
|
147
146
|
num_qubits = 0
|
148
147
|
if target is not None and target.qargs is not None:
|
@@ -173,35 +172,12 @@ def build_average_error_map(target, properties, coupling_map):
|
|
173
172
|
qargs = (qargs[0], qargs[0])
|
174
173
|
avg_map.add_error(qargs, qarg_error / count)
|
175
174
|
built = True
|
176
|
-
elif properties is not None:
|
177
|
-
errors = defaultdict(list)
|
178
|
-
for qubit in range(len(properties.qubits)):
|
179
|
-
errors[(qubit,)].append(properties.readout_error(qubit))
|
180
|
-
for gate in properties.gates:
|
181
|
-
qubits = tuple(gate.qubits)
|
182
|
-
for param in gate.parameters:
|
183
|
-
if param.name == "gate_error":
|
184
|
-
errors[qubits].append(param.value)
|
185
|
-
for k, v in errors.items():
|
186
|
-
if len(k) == 1:
|
187
|
-
qargs = (k[0], k[0])
|
188
|
-
else:
|
189
|
-
qargs = k
|
190
|
-
# If the properties payload contains an index outside the number of qubits
|
191
|
-
# the properties are invalid for the given input. This normally happens either
|
192
|
-
# with a malconstructed properties payload or if the faulty qubits feature of
|
193
|
-
# BackendV1/BackendPropeties is being used. In such cases we map noise characteristics
|
194
|
-
# so we should just treat the mapping as an ideal case.
|
195
|
-
if qargs[0] >= num_qubits or qargs[1] >= num_qubits:
|
196
|
-
continue
|
197
|
-
avg_map.add_error(qargs, statistics.mean(v))
|
198
|
-
built = True
|
199
175
|
# if there are no error rates in the target we should fallback to using the degree heuristic
|
200
176
|
# used for a coupling map. To do this we can build the coupling map from the target before
|
201
177
|
# running the fallback heuristic
|
202
178
|
if not built and target is not None and coupling_map is None:
|
203
179
|
coupling_map = target.build_coupling_map()
|
204
|
-
if not built and coupling_map is not None:
|
180
|
+
if not built and coupling_map is not None and num_qubits is not None:
|
205
181
|
for qubit in range(num_qubits):
|
206
182
|
avg_map.add_error(
|
207
183
|
(qubit, qubit),
|
@@ -20,7 +20,6 @@ from .consolidate_blocks import ConsolidateBlocks
|
|
20
20
|
from .commutation_analysis import CommutationAnalysis
|
21
21
|
from .commutative_cancellation import CommutativeCancellation
|
22
22
|
from .commutative_inverse_cancellation import CommutativeInverseCancellation
|
23
|
-
from .cx_cancellation import CXCancellation
|
24
23
|
from .optimize_1q_commutation import Optimize1qGatesSimpleCommutation
|
25
24
|
from .optimize_swap_before_measure import OptimizeSwapBeforeMeasure
|
26
25
|
from .remove_reset_in_zero_state import RemoveResetInZeroState
|
@@ -30,14 +29,13 @@ from .hoare_opt import HoareOptimizer
|
|
30
29
|
from .template_optimization import TemplateOptimization
|
31
30
|
from .inverse_cancellation import InverseCancellation
|
32
31
|
from .collect_1q_runs import Collect1qRuns
|
33
|
-
from .echo_rzx_weyl_decomposition import EchoRZXWeylDecomposition
|
34
32
|
from .collect_linear_functions import CollectLinearFunctions
|
35
33
|
from .reset_after_measure_simplification import ResetAfterMeasureSimplification
|
36
34
|
from .optimize_cliffords import OptimizeCliffords
|
37
35
|
from .collect_cliffords import CollectCliffords
|
38
36
|
from .elide_permutations import ElidePermutations
|
39
|
-
from .normalize_rx_angle import NormalizeRXAngle
|
40
37
|
from .optimize_annotated import OptimizeAnnotated
|
41
38
|
from .remove_identity_equiv import RemoveIdentityEquivalent
|
42
39
|
from .split_2q_unitaries import Split2QUnitaries
|
43
40
|
from .collect_and_collapse import CollectAndCollapse
|
41
|
+
from .contract_idle_wires_in_control_flow import ContractIdleWiresInControlFlow
|
@@ -95,6 +95,7 @@ def collect_using_filter_function(
|
|
95
95
|
min_block_size,
|
96
96
|
split_layers=False,
|
97
97
|
collect_from_back=False,
|
98
|
+
max_block_width=None,
|
98
99
|
):
|
99
100
|
"""Corresponds to an important block collection strategy that greedily collects
|
100
101
|
maximal blocks of nodes matching a given ``filter_function``.
|
@@ -105,6 +106,7 @@ def collect_using_filter_function(
|
|
105
106
|
min_block_size=min_block_size,
|
106
107
|
split_layers=split_layers,
|
107
108
|
collect_from_back=collect_from_back,
|
109
|
+
max_block_width=max_block_width,
|
108
110
|
)
|
109
111
|
|
110
112
|
|
@@ -39,6 +39,7 @@ class CollectCliffords(CollectAndCollapse):
|
|
39
39
|
split_layers=False,
|
40
40
|
collect_from_back=False,
|
41
41
|
matrix_based=False,
|
42
|
+
max_block_width=None,
|
42
43
|
):
|
43
44
|
"""CollectCliffords initializer.
|
44
45
|
|
@@ -55,6 +56,9 @@ class CollectCliffords(CollectAndCollapse):
|
|
55
56
|
from the end of the circuit.
|
56
57
|
matrix_based (bool): specifies whether to collect unitary gates
|
57
58
|
which are Clifford gates only for certain parameters (based on their unitary matrix).
|
59
|
+
max_block_width (int | None): specifies the maximum width of the block
|
60
|
+
(that is, the number of qubits over which the block is defined)
|
61
|
+
for the block to be collected.
|
58
62
|
"""
|
59
63
|
|
60
64
|
collect_function = partial(
|
@@ -64,6 +68,7 @@ class CollectCliffords(CollectAndCollapse):
|
|
64
68
|
min_block_size=min_block_size,
|
65
69
|
split_layers=split_layers,
|
66
70
|
collect_from_back=collect_from_back,
|
71
|
+
max_block_width=max_block_width,
|
67
72
|
)
|
68
73
|
collapse_function = partial(collapse_to_operation, collapse_function=_collapse_to_clifford)
|
69
74
|
|
@@ -34,6 +34,7 @@ class CollectLinearFunctions(CollectAndCollapse):
|
|
34
34
|
min_block_size=2,
|
35
35
|
split_layers=False,
|
36
36
|
collect_from_back=False,
|
37
|
+
max_block_width=None,
|
37
38
|
):
|
38
39
|
"""CollectLinearFunctions initializer.
|
39
40
|
|
@@ -48,6 +49,9 @@ class CollectLinearFunctions(CollectAndCollapse):
|
|
48
49
|
over disjoint qubit subsets.
|
49
50
|
collect_from_back (bool): specifies if blocks should be collected started
|
50
51
|
from the end of the circuit.
|
52
|
+
max_block_width (int | None): specifies the maximum width of the block
|
53
|
+
(that is, the number of qubits over which the block is defined)
|
54
|
+
for the block to be collected.
|
51
55
|
"""
|
52
56
|
|
53
57
|
collect_function = partial(
|
@@ -57,6 +61,7 @@ class CollectLinearFunctions(CollectAndCollapse):
|
|
57
61
|
min_block_size=min_block_size,
|
58
62
|
split_layers=split_layers,
|
59
63
|
collect_from_back=collect_from_back,
|
64
|
+
max_block_width=max_block_width,
|
60
65
|
)
|
61
66
|
collapse_function = partial(
|
62
67
|
collapse_to_operation, collapse_function=_collapse_to_linear_function
|
@@ -33,13 +33,18 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
33
33
|
Some gates may not be present in any block (e.g. if the number
|
34
34
|
of operands is greater than ``max_block_size``)
|
35
35
|
|
36
|
+
By default, blocks are collected in the direction from the inputs towards the
|
37
|
+
outputs of the DAG. The option ``collect_from_back`` allows to change this
|
38
|
+
direction, that is to collect blocks from the outputs towards the inputs.
|
39
|
+
Note that the blocks are still reported in a valid topological order.
|
40
|
+
|
36
41
|
A Disjoint Set Union data structure (DSU) is used to maintain blocks as
|
37
42
|
gates are processed. This data structure points each qubit to a set at all
|
38
43
|
times and the sets correspond to current blocks. These change over time
|
39
44
|
and the data structure allows these changes to be done quickly.
|
40
45
|
"""
|
41
46
|
|
42
|
-
def __init__(self, max_block_size=2):
|
47
|
+
def __init__(self, max_block_size=2, collect_from_back=False):
|
43
48
|
super().__init__()
|
44
49
|
self.parent = {} # parent array for the union
|
45
50
|
|
@@ -49,6 +54,7 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
49
54
|
self.gate_groups = {} # current gate lists for the groups
|
50
55
|
|
51
56
|
self.max_block_size = max_block_size # maximum block size
|
57
|
+
self.collect_from_back = collect_from_back # backward collection
|
52
58
|
|
53
59
|
def find_set(self, index):
|
54
60
|
"""DSU function for finding root of set of items
|
@@ -127,6 +133,10 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
127
133
|
|
128
134
|
op_nodes = dag.topological_op_nodes(key=collect_key)
|
129
135
|
|
136
|
+
# When collecting from the back, the order of nodes is reversed
|
137
|
+
if self.collect_from_back:
|
138
|
+
op_nodes = reversed(list(op_nodes))
|
139
|
+
|
130
140
|
for nd in op_nodes:
|
131
141
|
can_process = True
|
132
142
|
makes_too_big = False
|
@@ -222,6 +232,11 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
222
232
|
if item == index and len(self.gate_groups[index]) != 0:
|
223
233
|
block_list.append(self.gate_groups[index][:])
|
224
234
|
|
235
|
+
# When collecting from the back, both the order of the blocks
|
236
|
+
# and the order of nodes in each block should be reversed.
|
237
|
+
if self.collect_from_back:
|
238
|
+
block_list = [block[::-1] for block in block_list[::-1]]
|
239
|
+
|
225
240
|
self.property_set["block_list"] = block_list
|
226
241
|
|
227
242
|
return dag
|
@@ -18,10 +18,10 @@ from qiskit._accelerate.commutation_analysis import analyze_commutations
|
|
18
18
|
|
19
19
|
|
20
20
|
class CommutationAnalysis(AnalysisPass):
|
21
|
-
"""Analysis pass to find commutation relations between DAG nodes.
|
21
|
+
r"""Analysis pass to find commutation relations between DAG nodes.
|
22
22
|
|
23
|
-
``property_set['commutation_set']``
|
24
|
-
the commutation relations on a given wire
|
23
|
+
This sets ``property_set['commutation_set']`` to a dictionary that describes
|
24
|
+
the commutation relations on a given wire: all the gates on a wire
|
25
25
|
are grouped into a set of gates that commute.
|
26
26
|
"""
|
27
27
|
|
@@ -12,10 +12,22 @@
|
|
12
12
|
|
13
13
|
"""Replace each block of consecutive gates by a single Unitary node."""
|
14
14
|
from __future__ import annotations
|
15
|
-
from math import pi
|
16
15
|
|
17
|
-
from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
|
18
|
-
from qiskit.circuit.library.standard_gates import
|
16
|
+
from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer, TwoQubitControlledUDecomposer
|
17
|
+
from qiskit.circuit.library.standard_gates import (
|
18
|
+
CXGate,
|
19
|
+
CZGate,
|
20
|
+
iSwapGate,
|
21
|
+
ECRGate,
|
22
|
+
RXXGate,
|
23
|
+
RYYGate,
|
24
|
+
RZZGate,
|
25
|
+
RZXGate,
|
26
|
+
CRXGate,
|
27
|
+
CRYGate,
|
28
|
+
CRZGate,
|
29
|
+
CPhaseGate,
|
30
|
+
)
|
19
31
|
|
20
32
|
from qiskit.transpiler.basepasses import TransformationPass
|
21
33
|
from qiskit.transpiler.passmanager import PassManager
|
@@ -29,7 +41,17 @@ KAK_GATE_NAMES = {
|
|
29
41
|
"cz": CZGate(),
|
30
42
|
"iswap": iSwapGate(),
|
31
43
|
"ecr": ECRGate(),
|
32
|
-
|
44
|
+
}
|
45
|
+
|
46
|
+
KAK_GATE_PARAM_NAMES = {
|
47
|
+
"rxx": RXXGate,
|
48
|
+
"rzz": RZZGate,
|
49
|
+
"ryy": RYYGate,
|
50
|
+
"rzx": RZXGate,
|
51
|
+
"cphase": CPhaseGate,
|
52
|
+
"crx": CRXGate,
|
53
|
+
"cry": CRYGate,
|
54
|
+
"crz": CRZGate,
|
33
55
|
}
|
34
56
|
|
35
57
|
|
@@ -69,7 +91,9 @@ class ConsolidateBlocks(TransformationPass):
|
|
69
91
|
"""
|
70
92
|
super().__init__()
|
71
93
|
self.basis_gates = None
|
72
|
-
|
94
|
+
# Bypass target if it doesn't contain any basis gates (i.e. it's a _FakeTarget), as this
|
95
|
+
# not part of the official target model.
|
96
|
+
self.target = target if target is not None and len(target.operation_names) > 0 else None
|
73
97
|
if basis_gates is not None:
|
74
98
|
self.basis_gates = set(basis_gates)
|
75
99
|
self.force_consolidate = force_consolidate
|
@@ -77,13 +101,14 @@ class ConsolidateBlocks(TransformationPass):
|
|
77
101
|
self.decomposer = TwoQubitBasisDecomposer(kak_basis_gate)
|
78
102
|
elif basis_gates is not None:
|
79
103
|
kak_gates = KAK_GATE_NAMES.keys() & (basis_gates or [])
|
80
|
-
|
81
|
-
|
82
|
-
|
104
|
+
kak_param_gates = KAK_GATE_PARAM_NAMES.keys() & (basis_gates or [])
|
105
|
+
if kak_param_gates:
|
106
|
+
self.decomposer = TwoQubitControlledUDecomposer(
|
107
|
+
KAK_GATE_PARAM_NAMES[list(kak_param_gates)[0]]
|
83
108
|
)
|
84
|
-
elif
|
109
|
+
elif kak_gates:
|
85
110
|
self.decomposer = TwoQubitBasisDecomposer(
|
86
|
-
|
111
|
+
KAK_GATE_NAMES[list(kak_gates)[0]], basis_fidelity=approximation_degree or 1.0
|
87
112
|
)
|
88
113
|
else:
|
89
114
|
self.decomposer = None
|
@@ -109,7 +134,7 @@ class ConsolidateBlocks(TransformationPass):
|
|
109
134
|
consolidate_blocks(
|
110
135
|
dag,
|
111
136
|
self.decomposer._inner_decomposer,
|
112
|
-
self.decomposer.
|
137
|
+
self.decomposer.gate_name,
|
113
138
|
self.force_consolidate,
|
114
139
|
target=self.target,
|
115
140
|
basis_gates=self.basis_gates,
|
@@ -138,12 +163,9 @@ class ConsolidateBlocks(TransformationPass):
|
|
138
163
|
pass_manager.append(Collect2qBlocks())
|
139
164
|
|
140
165
|
pass_manager.append(self)
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks),
|
147
|
-
propagate_condition=False,
|
148
|
-
)
|
166
|
+
for node in dag.control_flow_op_nodes():
|
167
|
+
dag.substitute_node(
|
168
|
+
node,
|
169
|
+
node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks),
|
170
|
+
)
|
149
171
|
return dag
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2025
|
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
|
+
"""Contract control-flow operations that contain idle wires."""
|
14
|
+
|
15
|
+
from qiskit.circuit import Qubit, Clbit, QuantumCircuit
|
16
|
+
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
17
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
18
|
+
|
19
|
+
|
20
|
+
class ContractIdleWiresInControlFlow(TransformationPass):
|
21
|
+
"""Remove idle qubits from control-flow operations of a :class:`.DAGCircuit`."""
|
22
|
+
|
23
|
+
def run(self, dag):
|
24
|
+
# `control_flow_op_nodes` is eager and doesn't borrow; we're mutating the DAG in the loop.
|
25
|
+
for node in dag.control_flow_op_nodes() or []:
|
26
|
+
inst = node._to_circuit_instruction()
|
27
|
+
new_inst = _contract_control_flow(inst)
|
28
|
+
if new_inst is inst:
|
29
|
+
# No top-level contraction; nothing to do.
|
30
|
+
continue
|
31
|
+
replacement = DAGCircuit()
|
32
|
+
# Dictionaries to retain insertion order for reproducibility, and because we can
|
33
|
+
# then re-use them as mapping dictionaries.
|
34
|
+
qubits, clbits, vars_ = {}, {}, {}
|
35
|
+
for _, _, wire in dag.edges(node):
|
36
|
+
if isinstance(wire, Qubit):
|
37
|
+
qubits[wire] = wire
|
38
|
+
elif isinstance(wire, Clbit):
|
39
|
+
clbits[wire] = wire
|
40
|
+
else:
|
41
|
+
vars_[wire] = wire
|
42
|
+
replacement.add_qubits(list(qubits))
|
43
|
+
replacement.add_clbits(list(clbits))
|
44
|
+
for var in vars_:
|
45
|
+
replacement.add_captured_var(var)
|
46
|
+
replacement._apply_op_node_back(DAGOpNode.from_instruction(new_inst))
|
47
|
+
# The replacement DAG is defined over all the same qubits, but with the correct
|
48
|
+
# qubits now explicitly marked as idle, so everything gets linked up correctly.
|
49
|
+
dag.substitute_node_with_dag(node, replacement, wires=qubits | clbits | vars_)
|
50
|
+
return dag
|
51
|
+
|
52
|
+
|
53
|
+
def _contract_control_flow(inst):
|
54
|
+
"""Contract a `CircuitInstruction` containing a control-flow operation.
|
55
|
+
|
56
|
+
Returns the input object by the same reference if there's no contraction to be done at the call
|
57
|
+
site, though nested control-flow ops may have been contracted in place."""
|
58
|
+
op = inst.operation
|
59
|
+
idle = set(inst.qubits)
|
60
|
+
for block in op.blocks:
|
61
|
+
qubit_map = dict(zip(block.qubits, inst.qubits))
|
62
|
+
for i, inner in enumerate(block.data):
|
63
|
+
if inner.is_control_flow():
|
64
|
+
# In `QuantumCircuit` it's easy to replace an instruction with a narrower one, so it
|
65
|
+
# doesn't matter much if this is replacing it with itself.
|
66
|
+
block.data[i] = inner = _contract_control_flow(inner)
|
67
|
+
for qubit in inner.qubits:
|
68
|
+
idle.discard(qubit_map[qubit])
|
69
|
+
# If a box, we still want the prior side-effect of contracting any internal control-flow
|
70
|
+
# operations (optimisations are still valid _within_ a box), but we don't want to contract the
|
71
|
+
# box itself. If there's no idle qubits, we're also done here.
|
72
|
+
if not idle or inst.name == "box":
|
73
|
+
return inst
|
74
|
+
|
75
|
+
def contract(block):
|
76
|
+
out = QuantumCircuit(
|
77
|
+
name=block.name,
|
78
|
+
global_phase=block.global_phase,
|
79
|
+
metadata=block.metadata,
|
80
|
+
captures=block.iter_captures(),
|
81
|
+
)
|
82
|
+
out.add_bits(
|
83
|
+
[
|
84
|
+
block_qubit
|
85
|
+
for (block_qubit, inst_qubit) in zip(block.qubits, inst.qubits)
|
86
|
+
if inst_qubit not in idle
|
87
|
+
]
|
88
|
+
)
|
89
|
+
out.add_bits(block.clbits)
|
90
|
+
for creg in block.cregs:
|
91
|
+
out.add_register(creg)
|
92
|
+
# Control-flow ops can only have captures and locals, and we already added the captures.
|
93
|
+
for var in block.iter_declared_vars():
|
94
|
+
out.add_uninitialized_var(var)
|
95
|
+
for stretch in block.iter_declared_stretches():
|
96
|
+
out.add_stretch(stretch)
|
97
|
+
for inner in block:
|
98
|
+
out._append(inner)
|
99
|
+
return out
|
100
|
+
|
101
|
+
return inst.replace(
|
102
|
+
operation=op.replace_blocks(contract(block) for block in op.blocks),
|
103
|
+
qubits=[qubit for qubit in inst.qubits if qubit not in idle],
|
104
|
+
)
|