qiskit 1.3.0b1__cp39-abi3-win32.whl → 1.3.0rc2__cp39-abi3-win32.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 +20 -1
- qiskit/_accelerate.pyd +0 -0
- qiskit/assembler/assemble_schedules.py +2 -0
- qiskit/circuit/__init__.py +44 -1
- qiskit/circuit/_standard_gates_commutations.py +585 -0
- qiskit/circuit/barrier.py +2 -0
- qiskit/circuit/controlflow/builder.py +3 -3
- qiskit/circuit/controlflow/if_else.py +13 -5
- qiskit/circuit/controlflow/while_loop.py +10 -2
- qiskit/circuit/delay.py +20 -3
- qiskit/circuit/equivalence.py +13 -214
- qiskit/circuit/gate.py +3 -1
- qiskit/circuit/instruction.py +32 -11
- qiskit/circuit/instructionset.py +2 -0
- qiskit/circuit/library/__init__.py +110 -14
- qiskit/circuit/library/arithmetic/__init__.py +9 -2
- qiskit/circuit/library/arithmetic/adders/__init__.py +1 -0
- qiskit/circuit/library/arithmetic/adders/adder.py +154 -2
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +20 -56
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +14 -1
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +21 -91
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +1 -0
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +8 -1
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +94 -3
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +8 -1
- qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +20 -38
- qiskit/circuit/library/blueprintcircuit.py +64 -0
- qiskit/circuit/library/boolean_logic/__init__.py +4 -4
- qiskit/circuit/library/boolean_logic/inner_product.py +81 -4
- qiskit/circuit/library/boolean_logic/quantum_and.py +107 -4
- qiskit/circuit/library/boolean_logic/quantum_or.py +107 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +97 -3
- qiskit/circuit/library/data_preparation/__init__.py +6 -3
- qiskit/circuit/library/data_preparation/{z_feature_map.py → _z_feature_map.py} +45 -34
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +342 -29
- qiskit/circuit/library/fourier_checking.py +72 -11
- qiskit/circuit/library/generalized_gates/__init__.py +1 -1
- qiskit/circuit/library/generalized_gates/diagonal.py +45 -51
- qiskit/circuit/library/generalized_gates/gms.py +67 -14
- qiskit/circuit/library/generalized_gates/gr.py +4 -4
- qiskit/circuit/library/generalized_gates/isometry.py +2 -2
- qiskit/circuit/library/generalized_gates/linear_function.py +12 -6
- qiskit/circuit/library/generalized_gates/mcmt.py +167 -107
- qiskit/circuit/library/generalized_gates/permutation.py +8 -6
- qiskit/circuit/library/generalized_gates/rv.py +8 -9
- qiskit/circuit/library/graph_state.py +93 -10
- qiskit/circuit/library/grover_operator.py +270 -2
- qiskit/circuit/library/hidden_linear_function.py +83 -20
- qiskit/circuit/library/iqp.py +99 -20
- qiskit/circuit/library/n_local/__init__.py +19 -7
- qiskit/circuit/library/n_local/efficient_su2.py +118 -5
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +259 -0
- qiskit/circuit/library/n_local/excitation_preserving.py +130 -6
- qiskit/circuit/library/n_local/n_local.py +406 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +106 -4
- qiskit/circuit/library/n_local/qaoa_ansatz.py +80 -1
- qiskit/circuit/library/n_local/real_amplitudes.py +127 -7
- qiskit/circuit/library/n_local/two_local.py +14 -7
- qiskit/circuit/library/overlap.py +91 -26
- qiskit/circuit/library/pauli_evolution.py +17 -15
- qiskit/circuit/library/phase_estimation.py +80 -4
- qiskit/circuit/library/quantum_volume.py +72 -20
- qiskit/circuit/library/standard_gates/__init__.py +20 -1
- qiskit/circuit/library/standard_gates/dcx.py +2 -1
- qiskit/circuit/library/standard_gates/ecr.py +2 -2
- qiskit/circuit/library/standard_gates/h.py +4 -3
- qiskit/circuit/library/standard_gates/i.py +2 -1
- qiskit/circuit/library/standard_gates/iswap.py +2 -2
- qiskit/circuit/library/standard_gates/p.py +20 -12
- qiskit/circuit/library/standard_gates/r.py +1 -1
- qiskit/circuit/library/standard_gates/rx.py +4 -3
- qiskit/circuit/library/standard_gates/rxx.py +2 -2
- qiskit/circuit/library/standard_gates/ry.py +4 -3
- qiskit/circuit/library/standard_gates/ryy.py +2 -2
- qiskit/circuit/library/standard_gates/rz.py +13 -12
- qiskit/circuit/library/standard_gates/rzx.py +6 -6
- qiskit/circuit/library/standard_gates/rzz.py +1 -1
- qiskit/circuit/library/standard_gates/s.py +4 -4
- qiskit/circuit/library/standard_gates/swap.py +3 -3
- qiskit/circuit/library/standard_gates/sx.py +4 -3
- qiskit/circuit/library/standard_gates/t.py +2 -2
- qiskit/circuit/library/standard_gates/u.py +11 -3
- qiskit/circuit/library/standard_gates/u1.py +65 -15
- qiskit/circuit/library/standard_gates/u2.py +4 -1
- qiskit/circuit/library/standard_gates/u3.py +31 -3
- qiskit/circuit/library/standard_gates/x.py +7 -5
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -2
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -2
- qiskit/circuit/library/standard_gates/y.py +4 -3
- qiskit/circuit/library/standard_gates/z.py +3 -3
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +9 -7
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +9 -8
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +10 -9
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +10 -9
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +9 -7
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +10 -8
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +16 -14
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +14 -12
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +14 -12
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +13 -11
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +11 -9
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +12 -10
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +12 -10
- qiskit/circuit/library/templates/rzx/rzx_cy.py +11 -10
- qiskit/circuit/library/templates/rzx/rzx_xz.py +16 -15
- qiskit/circuit/library/templates/rzx/rzx_yz.py +12 -10
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +22 -20
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +16 -15
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +17 -15
- qiskit/circuit/parameter.py +4 -0
- qiskit/circuit/parameterexpression.py +167 -34
- qiskit/circuit/quantumcircuit.py +162 -126
- qiskit/circuit/singleton.py +2 -0
- qiskit/circuit/store.py +2 -0
- qiskit/circuit/twirling.py +145 -0
- qiskit/compiler/assembler.py +17 -4
- qiskit/compiler/scheduler.py +2 -0
- qiskit/compiler/sequencer.py +2 -0
- qiskit/compiler/transpiler.py +81 -26
- qiskit/converters/circuit_to_dag.py +2 -2
- qiskit/converters/circuit_to_dagdependency.py +1 -1
- qiskit/converters/circuit_to_dagdependency_v2.py +1 -1
- qiskit/converters/circuit_to_instruction.py +1 -1
- qiskit/converters/dag_to_circuit.py +7 -5
- qiskit/converters/dag_to_dagdependency.py +1 -1
- qiskit/converters/dag_to_dagdependency_v2.py +1 -1
- qiskit/converters/dagdependency_to_circuit.py +5 -1
- qiskit/converters/dagdependency_to_dag.py +6 -1
- qiskit/dagcircuit/collect_blocks.py +3 -3
- qiskit/dagcircuit/dagdependency.py +18 -5
- qiskit/dagcircuit/dagdependency_v2.py +1 -1
- qiskit/dagcircuit/dagnode.py +2 -2
- qiskit/passmanager/__init__.py +2 -2
- qiskit/primitives/backend_estimator.py +5 -2
- qiskit/primitives/backend_sampler_v2.py +61 -18
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +9 -1
- qiskit/primitives/statevector_sampler.py +1 -1
- qiskit/primitives/utils.py +1 -1
- qiskit/providers/__init__.py +3 -3
- qiskit/providers/backend.py +12 -1
- qiskit/providers/backend_compat.py +23 -3
- qiskit/providers/basic_provider/basic_simulator.py +12 -2
- qiskit/providers/fake_provider/fake_pulse_backend.py +6 -1
- qiskit/providers/fake_provider/generic_backend_v2.py +46 -30
- qiskit/providers/models/pulsedefaults.py +2 -0
- qiskit/pulse/builder.py +59 -18
- qiskit/pulse/calibration_entries.py +4 -1
- qiskit/pulse/channels.py +2 -0
- qiskit/pulse/exceptions.py +2 -0
- qiskit/pulse/instruction_schedule_map.py +21 -6
- qiskit/pulse/instructions/acquire.py +2 -0
- qiskit/pulse/instructions/delay.py +2 -0
- qiskit/pulse/instructions/directives.py +8 -0
- qiskit/pulse/instructions/frequency.py +3 -0
- qiskit/pulse/instructions/instruction.py +2 -0
- qiskit/pulse/instructions/phase.py +3 -0
- qiskit/pulse/instructions/play.py +2 -0
- qiskit/pulse/instructions/reference.py +2 -0
- qiskit/pulse/instructions/snapshot.py +2 -0
- qiskit/pulse/library/pulse.py +2 -0
- qiskit/pulse/library/symbolic_pulses.py +28 -0
- qiskit/pulse/library/waveform.py +2 -0
- qiskit/pulse/macros.py +1 -1
- qiskit/pulse/schedule.py +12 -13
- qiskit/pulse/transforms/alignments.py +5 -3
- qiskit/pulse/transforms/dag.py +7 -0
- qiskit/qasm2/export.py +5 -3
- qiskit/qasm2/parse.py +46 -2
- qiskit/qasm3/__init__.py +1 -0
- qiskit/qasm3/ast.py +123 -15
- qiskit/qasm3/exporter.py +103 -77
- qiskit/qobj/converters/pulse_instruction.py +6 -4
- qiskit/qpy/__init__.py +181 -0
- qiskit/qpy/binary_io/circuits.py +20 -5
- qiskit/qpy/binary_io/schedules.py +3 -4
- qiskit/qpy/binary_io/value.py +310 -13
- qiskit/qpy/common.py +46 -2
- qiskit/qpy/formats.py +7 -0
- qiskit/qpy/interface.py +40 -4
- qiskit/quantum_info/__init__.py +4 -0
- qiskit/quantum_info/operators/channel/transformations.py +28 -21
- qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
- qiskit/quantum_info/operators/operator.py +54 -8
- qiskit/quantum_info/operators/symplectic/base_pauli.py +11 -19
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
- qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +23 -2
- qiskit/quantum_info/states/densitymatrix.py +5 -5
- qiskit/quantum_info/states/stabilizerstate.py +1 -1
- qiskit/quantum_info/states/statevector.py +6 -6
- qiskit/result/mitigation/base_readout_mitigator.py +1 -1
- qiskit/result/mitigation/correlated_readout_mitigator.py +9 -1
- qiskit/result/mitigation/local_readout_mitigator.py +9 -1
- qiskit/result/mitigation/utils.py +57 -0
- qiskit/scheduler/config.py +2 -0
- qiskit/scheduler/methods/basic.py +3 -0
- qiskit/scheduler/schedule_circuit.py +2 -0
- qiskit/scheduler/sequence.py +2 -0
- qiskit/synthesis/__init__.py +25 -0
- qiskit/synthesis/arithmetic/__init__.py +16 -0
- qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
- qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +102 -0
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +99 -0
- qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -2
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +3 -2
- qiskit/synthesis/clifford/clifford_decompose_layers.py +2 -1
- qiskit/synthesis/evolution/__init__.py +1 -0
- qiskit/synthesis/evolution/lie_trotter.py +16 -42
- qiskit/synthesis/evolution/pauli_network.py +80 -0
- qiskit/synthesis/evolution/product_formula.py +165 -238
- qiskit/synthesis/evolution/qdrift.py +36 -29
- qiskit/synthesis/evolution/suzuki_trotter.py +87 -27
- qiskit/synthesis/multi_controlled/__init__.py +1 -0
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
- qiskit/synthesis/qft/qft_decompose_full.py +19 -1
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -1
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -1
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +4 -63
- qiskit/synthesis/unitary/qsd.py +5 -5
- qiskit/transpiler/__init__.py +21 -14
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +9 -565
- qiskit/transpiler/passes/basis/decompose.py +45 -12
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/pulse_gate.py +4 -2
- qiskit/transpiler/passes/calibration/rx_builder.py +11 -7
- qiskit/transpiler/passes/calibration/rzx_builder.py +46 -30
- qiskit/transpiler/passes/layout/disjoint_utils.py +15 -13
- qiskit/transpiler/passes/layout/sabre_layout.py +7 -2
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +5 -0
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_cliffords.py +19 -3
- qiskit/transpiler/passes/optimization/collect_linear_functions.py +1 -1
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +48 -131
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +4 -2
- qiskit/transpiler/passes/optimization/elide_permutations.py +9 -32
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +5 -11
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +1 -1
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +69 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +5 -5
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +4 -4
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +2 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +7 -3
- qiskit/transpiler/passes/routing/star_prerouting.py +2 -2
- qiskit/transpiler/passes/scheduling/alap.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
- qiskit/transpiler/passes/scheduling/asap.py +1 -1
- qiskit/transpiler/passes/scheduling/base_scheduler.py +14 -12
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +9 -4
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +16 -5
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +4 -1
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +6 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +9 -4
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +262 -99
- qiskit/transpiler/passes/synthesis/hls_plugins.py +637 -7
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +55 -34
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +2 -56
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +5 -0
- qiskit/transpiler/passes/utils/gate_direction.py +12 -275
- qiskit/transpiler/passes/utils/gates_basis.py +7 -30
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +2 -1
- qiskit/transpiler/passmanager_config.py +22 -4
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +40 -14
- qiskit/transpiler/preset_passmanagers/common.py +5 -3
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +125 -42
- qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
- qiskit/transpiler/target.py +74 -16
- qiskit/utils/deprecate_pulse.py +119 -0
- qiskit/visualization/circuit/_utils.py +2 -2
- qiskit/visualization/circuit/circuit_visualization.py +3 -2
- qiskit/visualization/circuit/matplotlib.py +1 -1
- qiskit/visualization/dag_visualization.py +1 -1
- qiskit/visualization/pass_manager_visualization.py +3 -14
- qiskit/visualization/pulse_v2/interface.py +3 -1
- qiskit/visualization/timeline/core.py +25 -2
- qiskit/visualization/timeline/interface.py +12 -0
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/METADATA +9 -8
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/RECORD +357 -346
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/WHEEL +1 -1
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/entry_points.txt +19 -0
- qiskit/circuit/library/data_preparation/zz_feature_map.py +0 -118
- qiskit/synthesis/two_qubit/weyl.py +0 -97
- qiskit/transpiler/passes/synthesis/qubit_tracker.py +0 -132
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/top_level.txt +0 -0
@@ -54,7 +54,7 @@ class Unroll3qOrMore(TransformationPass):
|
|
54
54
|
QiskitError: if a 3q+ gate is not decomposable
|
55
55
|
"""
|
56
56
|
for node in dag.multi_qubit_ops():
|
57
|
-
if dag.
|
57
|
+
if dag._has_calibration_for(node):
|
58
58
|
continue
|
59
59
|
|
60
60
|
if isinstance(node.op, ControlFlowOp):
|
@@ -74,7 +74,7 @@ class UnrollCustomDefinitions(TransformationPass):
|
|
74
74
|
if getattr(node.op, "_directive", False):
|
75
75
|
continue
|
76
76
|
|
77
|
-
if dag.
|
77
|
+
if dag._has_calibration_for(node) or len(node.qargs) < self._min_qubits:
|
78
78
|
continue
|
79
79
|
|
80
80
|
controlled_gate_open_ctrl = isinstance(node.op, ControlledGate) and node.op._open_ctrl
|
@@ -19,6 +19,7 @@ from qiskit.pulse import Schedule, ScheduleBlock
|
|
19
19
|
from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap
|
20
20
|
from qiskit.transpiler.target import Target
|
21
21
|
from qiskit.transpiler.exceptions import TranspilerError
|
22
|
+
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
|
22
23
|
|
23
24
|
from .base_builder import CalibrationBuilder
|
24
25
|
|
@@ -47,6 +48,7 @@ class PulseGates(CalibrationBuilder):
|
|
47
48
|
https://arxiv.org/abs/2104.14722
|
48
49
|
"""
|
49
50
|
|
51
|
+
@deprecate_pulse_dependency
|
50
52
|
def __init__(
|
51
53
|
self,
|
52
54
|
inst_map: InstructionScheduleMap = None,
|
@@ -80,7 +82,7 @@ class PulseGates(CalibrationBuilder):
|
|
80
82
|
Returns:
|
81
83
|
Return ``True`` is calibration can be provided.
|
82
84
|
"""
|
83
|
-
return self.target.
|
85
|
+
return self.target._has_calibration(node_op.name, tuple(qubits))
|
84
86
|
|
85
87
|
def get_calibration(self, node_op: CircuitInst, qubits: List) -> Union[Schedule, ScheduleBlock]:
|
86
88
|
"""Gets the calibrated schedule for the given instruction and qubits.
|
@@ -95,4 +97,4 @@ class PulseGates(CalibrationBuilder):
|
|
95
97
|
Raises:
|
96
98
|
TranspilerError: When node is parameterized and calibration is raw schedule object.
|
97
99
|
"""
|
98
|
-
return self.target.
|
100
|
+
return self.target._get_calibration(node_op.name, tuple(qubits), *node_op.params)
|
@@ -24,6 +24,7 @@ from qiskit.pulse.channels import Channel
|
|
24
24
|
from qiskit.pulse.library.symbolic_pulses import Drag
|
25
25
|
from qiskit.transpiler.passes.calibration.base_builder import CalibrationBuilder
|
26
26
|
from qiskit.transpiler.target import Target
|
27
|
+
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
|
27
28
|
|
28
29
|
|
29
30
|
class RXCalibrationBuilder(CalibrationBuilder):
|
@@ -45,7 +46,7 @@ class RXCalibrationBuilder(CalibrationBuilder):
|
|
45
46
|
from qiskit.circuit.library import QuantumVolume
|
46
47
|
from qiskit.circuit.library.standard_gates import RXGate
|
47
48
|
|
48
|
-
from
|
49
|
+
from qiskit.transpiler.passes import RXCalibrationBuilder
|
49
50
|
|
50
51
|
qv = QuantumVolume(4, 4, seed=1004)
|
51
52
|
|
@@ -75,6 +76,7 @@ class RXCalibrationBuilder(CalibrationBuilder):
|
|
75
76
|
`arXiv:2004.11205 <https://arxiv.org/abs/2004.11205>`
|
76
77
|
"""
|
77
78
|
|
79
|
+
@deprecate_pulse_dependency
|
78
80
|
def __init__(
|
79
81
|
self,
|
80
82
|
target: Target = None,
|
@@ -99,13 +101,15 @@ class RXCalibrationBuilder(CalibrationBuilder):
|
|
99
101
|
"""
|
100
102
|
return (
|
101
103
|
isinstance(node_op, RXGate)
|
102
|
-
and self.target.
|
103
|
-
and (len(self.target.
|
104
|
+
and self.target._has_calibration("sx", tuple(qubits))
|
105
|
+
and (len(self.target._get_calibration("sx", tuple(qubits)).instructions) == 1)
|
104
106
|
and isinstance(
|
105
|
-
self.target.
|
107
|
+
self.target._get_calibration("sx", tuple(qubits)).instructions[0][1].pulse,
|
106
108
|
ScalableSymbolicPulse,
|
107
109
|
)
|
108
|
-
and self.target.
|
110
|
+
and self.target._get_calibration("sx", tuple(qubits))
|
111
|
+
.instructions[0][1]
|
112
|
+
.pulse.pulse_type
|
109
113
|
== "Drag"
|
110
114
|
)
|
111
115
|
|
@@ -122,13 +126,13 @@ class RXCalibrationBuilder(CalibrationBuilder):
|
|
122
126
|
raise QiskitError("Target rotation angle is not assigned.") from ex
|
123
127
|
|
124
128
|
params = (
|
125
|
-
self.target.
|
129
|
+
self.target._get_calibration("sx", tuple(qubits))
|
126
130
|
.instructions[0][1]
|
127
131
|
.pulse.parameters.copy()
|
128
132
|
)
|
129
133
|
new_rx_sched = _create_rx_sched(
|
130
134
|
rx_angle=angle,
|
131
|
-
channel=self.target.
|
135
|
+
channel=self.target._get_calibration("sx", tuple(qubits)).channels[0],
|
132
136
|
duration=params["duration"],
|
133
137
|
amp=params["amp"],
|
134
138
|
sigma=params["sigma"],
|
@@ -36,6 +36,7 @@ from qiskit.pulse import builder
|
|
36
36
|
from qiskit.pulse.filters import filter_instructions
|
37
37
|
from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap
|
38
38
|
from qiskit.transpiler.target import Target
|
39
|
+
from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
|
39
40
|
|
40
41
|
from .base_builder import CalibrationBuilder
|
41
42
|
from .exceptions import CalibrationNotAvailable
|
@@ -65,6 +66,7 @@ class RZXCalibrationBuilder(CalibrationBuilder):
|
|
65
66
|
angle. Additional details can be found in https://arxiv.org/abs/2012.11660.
|
66
67
|
"""
|
67
68
|
|
69
|
+
@deprecate_pulse_dependency
|
68
70
|
def __init__(
|
69
71
|
self,
|
70
72
|
instruction_schedule_map: InstructionScheduleMap = None,
|
@@ -89,7 +91,7 @@ class RZXCalibrationBuilder(CalibrationBuilder):
|
|
89
91
|
self._inst_map = instruction_schedule_map
|
90
92
|
self._verbose = verbose
|
91
93
|
if target:
|
92
|
-
self._inst_map = target.
|
94
|
+
self._inst_map = target._instruction_schedule_map()
|
93
95
|
if self._inst_map is None:
|
94
96
|
raise QiskitError("Calibrations can only be added to Pulse-enabled backends")
|
95
97
|
|
@@ -202,15 +204,20 @@ class RZXCalibrationBuilder(CalibrationBuilder):
|
|
202
204
|
|
203
205
|
# The CR instruction is in the forward (native) direction
|
204
206
|
if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
207
|
+
with warnings.catch_warnings():
|
208
|
+
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
209
|
+
# `InstructionScheduleMap.get` and the pulse builder emit deprecation warnings
|
210
|
+
# as they use classes and methods which are deprecated in Qiskit 1.3 as part of the
|
211
|
+
# Qiskit Pulse deprecation
|
212
|
+
xgate = self._inst_map.get("x", qubits[0])
|
213
|
+
with builder.build(
|
214
|
+
default_alignment="sequential", name=f"rzx({theta:.3f})"
|
215
|
+
) as rzx_theta_native:
|
216
|
+
for cr_tone, comp_tone in zip(cr_tones, comp_tones):
|
217
|
+
with builder.align_left():
|
218
|
+
self.rescale_cr_inst(cr_tone, theta)
|
219
|
+
self.rescale_cr_inst(comp_tone, theta)
|
220
|
+
builder.call(xgate)
|
214
221
|
return rzx_theta_native
|
215
222
|
|
216
223
|
# The direction is not native. Add Hadamard gates to flip the direction.
|
@@ -297,11 +304,15 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder):
|
|
297
304
|
|
298
305
|
# RZXCalibrationNoEcho only good for forward CR direction
|
299
306
|
if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
|
300
|
-
with
|
301
|
-
|
302
|
-
|
303
|
-
#
|
304
|
-
builder.
|
307
|
+
with warnings.catch_warnings():
|
308
|
+
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
309
|
+
# Pulse builder emits deprecation warnings as part of the
|
310
|
+
# Qiskit Pulse deprecation
|
311
|
+
with builder.build(default_alignment="left", name=f"rzx({theta:.3f})") as rzx_theta:
|
312
|
+
stretched_dur = self.rescale_cr_inst(cr_tones[0], 2 * theta)
|
313
|
+
self.rescale_cr_inst(comp_tones[0], 2 * theta)
|
314
|
+
# Placeholder to make pulse gate work
|
315
|
+
builder.delay(stretched_dur, DriveChannel(qubits[0]))
|
305
316
|
return rzx_theta
|
306
317
|
|
307
318
|
raise QiskitError("RZXCalibrationBuilderNoEcho only supports hardware-native RZX gates.")
|
@@ -347,22 +358,27 @@ def _check_calibration_type(
|
|
347
358
|
QiskitError: Unknown calibration type is detected.
|
348
359
|
"""
|
349
360
|
cal_type = None
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
361
|
+
with warnings.catch_warnings():
|
362
|
+
warnings.simplefilter(action="ignore", category=DeprecationWarning)
|
363
|
+
# `InstructionScheduleMap.get` and `filter_instructions` emit deprecation warnings
|
364
|
+
# as they use classes and methods which are deprecated in Qiskit 1.3 as part of the
|
365
|
+
# Qiskit Pulse deprecation
|
366
|
+
if inst_sched_map.has("cx", qubits):
|
367
|
+
cr_sched = inst_sched_map.get("cx", qubits=qubits)
|
368
|
+
elif inst_sched_map.has("ecr", qubits):
|
369
|
+
cr_sched = inst_sched_map.get("ecr", qubits=qubits)
|
370
|
+
cal_type = CRCalType.ECR_FORWARD
|
371
|
+
elif inst_sched_map.has("ecr", tuple(reversed(qubits))):
|
372
|
+
cr_sched = inst_sched_map.get("ecr", tuple(reversed(qubits)))
|
373
|
+
cal_type = CRCalType.ECR_REVERSE
|
374
|
+
else:
|
375
|
+
raise QiskitError(
|
376
|
+
f"Native direction cannot be determined: operation on qubits {qubits} "
|
377
|
+
f"for the following instruction schedule map:\n{inst_sched_map}"
|
378
|
+
)
|
363
379
|
|
364
|
-
|
365
|
-
|
380
|
+
cr_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_cr_tone]).instructions]
|
381
|
+
comp_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_comp_tone]).instructions]
|
366
382
|
|
367
383
|
if cal_type is None:
|
368
384
|
if len(comp_tones) == 0:
|
@@ -107,7 +107,7 @@ def split_barriers(dag: DAGCircuit):
|
|
107
107
|
num_qubits = len(node.qargs)
|
108
108
|
if num_qubits == 1:
|
109
109
|
continue
|
110
|
-
if node.
|
110
|
+
if node.label:
|
111
111
|
barrier_uuid = f"{node.op.label}_uuid={uuid.uuid4()}"
|
112
112
|
else:
|
113
113
|
barrier_uuid = f"_none_uuid={uuid.uuid4()}"
|
@@ -125,28 +125,30 @@ def split_barriers(dag: DAGCircuit):
|
|
125
125
|
def combine_barriers(dag: DAGCircuit, retain_uuid: bool = True):
|
126
126
|
"""Mutate input dag to combine barriers with UUID labels into a single barrier."""
|
127
127
|
qubit_indices = {bit: index for index, bit in enumerate(dag.qubits)}
|
128
|
-
uuid_map: dict[
|
128
|
+
uuid_map: dict[str, DAGOpNode] = {}
|
129
129
|
for node in dag.op_nodes(Barrier):
|
130
|
-
if node.
|
131
|
-
if "_uuid=" in node.
|
132
|
-
barrier_uuid = node.
|
130
|
+
if node.label:
|
131
|
+
if "_uuid=" in node.label:
|
132
|
+
barrier_uuid = node.label
|
133
133
|
else:
|
134
134
|
continue
|
135
135
|
if barrier_uuid in uuid_map:
|
136
136
|
other_node = uuid_map[barrier_uuid]
|
137
137
|
num_qubits = len(other_node.qargs) + len(node.qargs)
|
138
|
-
|
138
|
+
if not retain_uuid:
|
139
|
+
if isinstance(node.label, str) and node.label.startswith("_none_uuid="):
|
140
|
+
label = None
|
141
|
+
elif isinstance(node.label, str) and "_uuid=" in node.label:
|
142
|
+
label = "_uuid=".join(node.label.split("_uuid=")[:-1])
|
143
|
+
else:
|
144
|
+
label = barrier_uuid
|
145
|
+
else:
|
146
|
+
label = barrier_uuid
|
147
|
+
new_op = Barrier(num_qubits, label=label)
|
139
148
|
new_node = dag.replace_block_with_op([node, other_node], new_op, qubit_indices)
|
140
149
|
uuid_map[barrier_uuid] = new_node
|
141
150
|
else:
|
142
151
|
uuid_map[barrier_uuid] = node
|
143
|
-
if not retain_uuid:
|
144
|
-
for node in dag.op_nodes(Barrier):
|
145
|
-
if isinstance(node.op.label, str) and node.op.label.startswith("_none_uuid="):
|
146
|
-
node.op.label = None
|
147
|
-
elif isinstance(node.op.label, str) and "_uuid=" in node.op.label:
|
148
|
-
original_label = "_uuid=".join(node.op.label.split("_uuid=")[:-1])
|
149
|
-
node.op.label = original_label
|
150
152
|
|
151
153
|
|
152
154
|
def require_layout_isolated_to_component(
|
@@ -101,7 +101,10 @@ class SabreLayout(TransformationPass):
|
|
101
101
|
|
102
102
|
**References:**
|
103
103
|
|
104
|
-
[1]
|
104
|
+
[1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
|
105
|
+
"LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
|
106
|
+
`arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
|
107
|
+
[2] Li, Gushu, Yufei Ding, and Yuan Xie. "Tackling the qubit mapping problem
|
105
108
|
for NISQ-era quantum devices." ASPLOS 2019.
|
106
109
|
`arXiv:1809.02573 <https://arxiv.org/pdf/1809.02573.pdf>`_
|
107
110
|
"""
|
@@ -145,7 +148,9 @@ class SabreLayout(TransformationPass):
|
|
145
148
|
(and ``routing_pass`` is not set) then the number of local
|
146
149
|
physical CPUs will be used as the default value. This option is
|
147
150
|
mutually exclusive with the ``routing_pass`` argument and an error
|
148
|
-
will be raised if both are used.
|
151
|
+
will be raised if both are used. An additional 3 or 4 trials
|
152
|
+
depending on the ``coupling_map`` value are run with common layouts
|
153
|
+
on top of the random trial count specified by this value.
|
149
154
|
skip_routing (bool): If this is set ``True`` and ``routing_pass`` is not used
|
150
155
|
then routing will not be applied to the output circuit. Only the layout
|
151
156
|
will be set in the property set. This is a tradeoff to run custom
|
@@ -31,6 +31,11 @@ class SabrePreLayout(AnalysisPass):
|
|
31
31
|
``sabre_starting_layouts`` (``list[Layout]``)
|
32
32
|
An optional list of :class:`~.Layout` objects to use for additional Sabre layout trials.
|
33
33
|
|
34
|
+
**References:**
|
35
|
+
|
36
|
+
[1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
|
37
|
+
"LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
|
38
|
+
`arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
|
34
39
|
"""
|
35
40
|
|
36
41
|
def __init__(
|
@@ -38,5 +38,6 @@ from .collect_cliffords import CollectCliffords
|
|
38
38
|
from .elide_permutations import ElidePermutations
|
39
39
|
from .normalize_rx_angle import NormalizeRXAngle
|
40
40
|
from .optimize_annotated import OptimizeAnnotated
|
41
|
+
from .remove_identity_equiv import RemoveIdentityEquivalent
|
41
42
|
from .split_2q_unitaries import Split2QUnitaries
|
42
43
|
from .collect_and_collapse import CollectAndCollapse
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
from functools import partial
|
17
17
|
|
18
|
+
from qiskit.exceptions import QiskitError
|
18
19
|
from qiskit.transpiler.passes.optimization.collect_and_collapse import (
|
19
20
|
CollectAndCollapse,
|
20
21
|
collect_using_filter_function,
|
@@ -37,6 +38,7 @@ class CollectCliffords(CollectAndCollapse):
|
|
37
38
|
min_block_size=2,
|
38
39
|
split_layers=False,
|
39
40
|
collect_from_back=False,
|
41
|
+
matrix_based=False,
|
40
42
|
):
|
41
43
|
"""CollectCliffords initializer.
|
42
44
|
|
@@ -51,11 +53,13 @@ class CollectCliffords(CollectAndCollapse):
|
|
51
53
|
over disjoint qubit subsets.
|
52
54
|
collect_from_back (bool): specifies if blocks should be collected started
|
53
55
|
from the end of the circuit.
|
56
|
+
matrix_based (bool): specifies whether to collect unitary gates
|
57
|
+
which are Clifford gates only for certain parameters (based on their unitary matrix).
|
54
58
|
"""
|
55
59
|
|
56
60
|
collect_function = partial(
|
57
61
|
collect_using_filter_function,
|
58
|
-
filter_function=_is_clifford_gate,
|
62
|
+
filter_function=partial(_is_clifford_gate, matrix_based=matrix_based),
|
59
63
|
split_blocks=split_blocks,
|
60
64
|
min_block_size=min_block_size,
|
61
65
|
split_layers=split_layers,
|
@@ -77,9 +81,21 @@ clifford_gate_names = (
|
|
77
81
|
)
|
78
82
|
|
79
83
|
|
80
|
-
def _is_clifford_gate(node):
|
84
|
+
def _is_clifford_gate(node, matrix_based=False):
|
81
85
|
"""Specifies whether a node holds a clifford gate."""
|
82
|
-
|
86
|
+
if getattr(node.op, "_condition", None) is not None:
|
87
|
+
return False
|
88
|
+
if node.op.name in clifford_gate_names:
|
89
|
+
return True
|
90
|
+
|
91
|
+
if not matrix_based:
|
92
|
+
return False
|
93
|
+
|
94
|
+
try:
|
95
|
+
Clifford(node.op)
|
96
|
+
return True
|
97
|
+
except QiskitError:
|
98
|
+
return False
|
83
99
|
|
84
100
|
|
85
101
|
def _collapse_to_clifford(circuit):
|
@@ -71,7 +71,7 @@ class CollectLinearFunctions(CollectAndCollapse):
|
|
71
71
|
|
72
72
|
def _is_linear_gate(node):
|
73
73
|
"""Specifies whether a node holds a linear gate."""
|
74
|
-
return node.op.name in ("cx", "swap") and getattr(node
|
74
|
+
return node.op.name in ("cx", "swap") and getattr(node, "condition", None) is None
|
75
75
|
|
76
76
|
|
77
77
|
def _collapse_to_linear_function(circuit):
|
@@ -120,7 +120,7 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
120
120
|
if not isinstance(x, DAGOpNode):
|
121
121
|
return "d"
|
122
122
|
if isinstance(x.op, Gate):
|
123
|
-
if x.op.is_parameterized() or getattr(x.op, "
|
123
|
+
if x.op.is_parameterized() or getattr(x.op, "_condition", None) is not None:
|
124
124
|
return "c"
|
125
125
|
return "b" + chr(ord("a") + len(x.qargs))
|
126
126
|
return "d"
|
@@ -133,7 +133,7 @@ class CollectMultiQBlocks(AnalysisPass):
|
|
133
133
|
|
134
134
|
# check if the node is a gate and if it is parameterized
|
135
135
|
if (
|
136
|
-
getattr(nd.op, "
|
136
|
+
getattr(nd.op, "_condition", None) is not None
|
137
137
|
or nd.op.is_parameterized()
|
138
138
|
or not isinstance(nd.op, Gate)
|
139
139
|
):
|
@@ -49,7 +49,7 @@ class CommutativeInverseCancellation(TransformationPass):
|
|
49
49
|
# checking can be extended to cover additional cases.
|
50
50
|
if getattr(node.op, "_directive", False) or node.name in {"measure", "reset", "delay"}:
|
51
51
|
return True
|
52
|
-
if getattr(node
|
52
|
+
if getattr(node, "condition", None):
|
53
53
|
return True
|
54
54
|
if node.op.is_parameterized():
|
55
55
|
return True
|
@@ -12,27 +12,26 @@
|
|
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
|
15
16
|
|
16
|
-
import numpy as np
|
17
|
-
|
18
|
-
from qiskit.circuit.classicalregister import ClassicalRegister
|
19
|
-
from qiskit.circuit.quantumregister import QuantumRegister
|
20
|
-
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
21
|
-
from qiskit.dagcircuit.dagnode import DAGOpNode
|
22
|
-
from qiskit.quantum_info import Operator
|
23
17
|
from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
|
24
|
-
from qiskit.circuit.library.
|
25
|
-
|
18
|
+
from qiskit.circuit.library.standard_gates import CXGate, CZGate, iSwapGate, ECRGate, RXXGate
|
19
|
+
|
26
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
27
21
|
from qiskit.transpiler.passmanager import PassManager
|
28
|
-
from qiskit.
|
29
|
-
from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
|
30
|
-
from qiskit._accelerate.convert_2q_block_matrix import blocks_to_matrix
|
31
|
-
from qiskit.exceptions import QiskitError
|
22
|
+
from qiskit._accelerate.consolidate_blocks import consolidate_blocks
|
32
23
|
|
33
24
|
from .collect_1q_runs import Collect1qRuns
|
34
25
|
from .collect_2q_blocks import Collect2qBlocks
|
35
26
|
|
27
|
+
KAK_GATE_NAMES = {
|
28
|
+
"cx": CXGate(),
|
29
|
+
"cz": CZGate(),
|
30
|
+
"iswap": iSwapGate(),
|
31
|
+
"ecr": ECRGate(),
|
32
|
+
"rxx": RXXGate(pi / 2),
|
33
|
+
}
|
34
|
+
|
36
35
|
|
37
36
|
class ConsolidateBlocks(TransformationPass):
|
38
37
|
"""Replace each block of consecutive gates by a single Unitary node.
|
@@ -74,13 +73,20 @@ class ConsolidateBlocks(TransformationPass):
|
|
74
73
|
if basis_gates is not None:
|
75
74
|
self.basis_gates = set(basis_gates)
|
76
75
|
self.force_consolidate = force_consolidate
|
77
|
-
|
78
76
|
if kak_basis_gate is not None:
|
79
77
|
self.decomposer = TwoQubitBasisDecomposer(kak_basis_gate)
|
80
78
|
elif basis_gates is not None:
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
kak_gates = KAK_GATE_NAMES.keys() & (basis_gates or [])
|
80
|
+
if kak_gates:
|
81
|
+
self.decomposer = TwoQubitBasisDecomposer(
|
82
|
+
KAK_GATE_NAMES[kak_gates.pop()], basis_fidelity=approximation_degree or 1.0
|
83
|
+
)
|
84
|
+
elif "rzx" in basis_gates:
|
85
|
+
self.decomposer = TwoQubitBasisDecomposer(
|
86
|
+
CXGate(), basis_fidelity=approximation_degree or 1.0
|
87
|
+
)
|
88
|
+
else:
|
89
|
+
self.decomposer = None
|
84
90
|
else:
|
85
91
|
self.decomposer = TwoQubitBasisDecomposer(CXGate())
|
86
92
|
|
@@ -93,89 +99,23 @@ class ConsolidateBlocks(TransformationPass):
|
|
93
99
|
if self.decomposer is None:
|
94
100
|
return dag
|
95
101
|
|
96
|
-
blocks = self.property_set["block_list"]
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
block_index_map = self._block_qargs_to_indices(dag, block_qargs)
|
114
|
-
for nd in block:
|
115
|
-
if nd.name == basis_gate_name:
|
116
|
-
basis_count += 1
|
117
|
-
if self._check_not_in_basis(dag, nd.name, nd.qargs):
|
118
|
-
outside_basis = True
|
119
|
-
if len(block_qargs) > 2:
|
120
|
-
q = QuantumRegister(len(block_qargs))
|
121
|
-
qc = QuantumCircuit(q)
|
122
|
-
if block_cargs:
|
123
|
-
c = ClassicalRegister(len(block_cargs))
|
124
|
-
qc.add_register(c)
|
125
|
-
for nd in block:
|
126
|
-
qc.append(nd.op, [q[block_index_map[i]] for i in nd.qargs])
|
127
|
-
unitary = UnitaryGate(Operator(qc), check_input=False)
|
128
|
-
else:
|
129
|
-
try:
|
130
|
-
matrix = blocks_to_matrix(block, block_index_map)
|
131
|
-
except QiskitError:
|
132
|
-
# If building a matrix for the block fails we should not consolidate it
|
133
|
-
# because there is nothing we can do with it.
|
134
|
-
continue
|
135
|
-
unitary = UnitaryGate(matrix, check_input=False)
|
136
|
-
|
137
|
-
max_2q_depth = 20 # If depth > 20, there will be 1q gates to consolidate.
|
138
|
-
if ( # pylint: disable=too-many-boolean-expressions
|
139
|
-
self.force_consolidate
|
140
|
-
or unitary.num_qubits > 2
|
141
|
-
or self.decomposer.num_basis_gates(matrix) < basis_count
|
142
|
-
or len(block) > max_2q_depth
|
143
|
-
or ((self.basis_gates is not None) and outside_basis)
|
144
|
-
or ((self.target is not None) and outside_basis)
|
145
|
-
):
|
146
|
-
identity = np.eye(2**unitary.num_qubits)
|
147
|
-
if np.allclose(identity, unitary.to_matrix()):
|
148
|
-
for node in block:
|
149
|
-
dag.remove_op_node(node)
|
150
|
-
else:
|
151
|
-
dag.replace_block_with_op(
|
152
|
-
block, unitary, block_index_map, cycle_check=False
|
153
|
-
)
|
154
|
-
# If 1q runs are collected before consolidate those too
|
155
|
-
runs = self.property_set["run_list"] or []
|
156
|
-
identity_1q = np.eye(2)
|
157
|
-
for run in runs:
|
158
|
-
if any(gate in all_block_gates for gate in run):
|
159
|
-
continue
|
160
|
-
if len(run) == 1 and not self._check_not_in_basis(dag, run[0].name, run[0].qargs):
|
161
|
-
dag.substitute_node(run[0], UnitaryGate(run[0].op.to_matrix(), check_input=False))
|
162
|
-
else:
|
163
|
-
qubit = run[0].qargs[0]
|
164
|
-
operator = run[0].op.to_matrix()
|
165
|
-
already_in_block = False
|
166
|
-
for gate in run[1:]:
|
167
|
-
if gate in all_block_gates:
|
168
|
-
already_in_block = True
|
169
|
-
operator = gate.op.to_matrix().dot(operator)
|
170
|
-
if already_in_block:
|
171
|
-
continue
|
172
|
-
unitary = UnitaryGate(operator, check_input=False)
|
173
|
-
if np.allclose(identity_1q, unitary.to_matrix()):
|
174
|
-
for node in run:
|
175
|
-
dag.remove_op_node(node)
|
176
|
-
else:
|
177
|
-
dag.replace_block_with_op(run, unitary, {qubit: 0}, cycle_check=False)
|
178
|
-
|
102
|
+
blocks = self.property_set["block_list"]
|
103
|
+
if blocks is not None:
|
104
|
+
blocks = [[node._node_id for node in block] for block in blocks]
|
105
|
+
runs = self.property_set["run_list"]
|
106
|
+
if runs is not None:
|
107
|
+
runs = [[node._node_id for node in run] for run in runs]
|
108
|
+
|
109
|
+
consolidate_blocks(
|
110
|
+
dag,
|
111
|
+
self.decomposer._inner_decomposer,
|
112
|
+
self.decomposer.gate.name,
|
113
|
+
self.force_consolidate,
|
114
|
+
target=self.target,
|
115
|
+
basis_gates=self.basis_gates,
|
116
|
+
blocks=blocks,
|
117
|
+
runs=runs,
|
118
|
+
)
|
179
119
|
dag = self._handle_control_flow_ops(dag)
|
180
120
|
|
181
121
|
# Clear collected blocks and runs as they are no longer valid after consolidation
|
@@ -195,38 +135,15 @@ class ConsolidateBlocks(TransformationPass):
|
|
195
135
|
pass_manager = PassManager()
|
196
136
|
if "run_list" in self.property_set:
|
197
137
|
pass_manager.append(Collect1qRuns())
|
198
|
-
if "block_list" in self.property_set:
|
199
138
|
pass_manager.append(Collect2qBlocks())
|
200
139
|
|
201
140
|
pass_manager.append(self)
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
141
|
+
control_flow_nodes = dag.control_flow_op_nodes()
|
142
|
+
if control_flow_nodes is not None:
|
143
|
+
for node in control_flow_nodes:
|
144
|
+
dag.substitute_node(
|
145
|
+
node,
|
146
|
+
node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks),
|
147
|
+
propagate_condition=False,
|
148
|
+
)
|
210
149
|
return dag
|
211
|
-
|
212
|
-
def _check_not_in_basis(self, dag, gate_name, qargs):
|
213
|
-
if self.target is not None:
|
214
|
-
return not self.target.instruction_supported(
|
215
|
-
gate_name, tuple(dag.find_bit(qubit).index for qubit in qargs)
|
216
|
-
)
|
217
|
-
else:
|
218
|
-
return self.basis_gates and gate_name not in self.basis_gates
|
219
|
-
|
220
|
-
def _block_qargs_to_indices(self, dag, block_qargs):
|
221
|
-
"""Map each qubit in block_qargs to its wire position among the block's wires.
|
222
|
-
Args:
|
223
|
-
block_qargs (list): list of qubits that a block acts on
|
224
|
-
global_index_map (dict): mapping from each qubit in the
|
225
|
-
circuit to its wire position within that circuit
|
226
|
-
Returns:
|
227
|
-
dict: mapping from qarg to position in block
|
228
|
-
"""
|
229
|
-
block_indices = [dag.find_bit(q).index for q in block_qargs]
|
230
|
-
ordered_block_indices = {bit: index for index, bit in enumerate(sorted(block_indices))}
|
231
|
-
block_positions = {q: ordered_block_indices[dag.find_bit(q).index] for q in block_qargs}
|
232
|
-
return block_positions
|