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
@@ -52,7 +52,7 @@ class SolovayKitaev(TransformationPass):
|
|
52
52
|
|
53
53
|
For example, the following circuit
|
54
54
|
|
55
|
-
..
|
55
|
+
.. code-block:: text
|
56
56
|
|
57
57
|
┌─────────┐
|
58
58
|
q_0: ┤ RX(0.8) ├
|
@@ -60,7 +60,7 @@ class SolovayKitaev(TransformationPass):
|
|
60
60
|
|
61
61
|
can be decomposed into
|
62
62
|
|
63
|
-
..
|
63
|
+
.. code-block:: text
|
64
64
|
|
65
65
|
global phase: 7π/8
|
66
66
|
┌───┐┌───┐┌───┐
|
@@ -95,7 +95,7 @@ class SolovayKitaev(TransformationPass):
|
|
95
95
|
|
96
96
|
print("Error:", np.linalg.norm(Operator(circuit).data - Operator(discretized).data))
|
97
97
|
|
98
|
-
..
|
98
|
+
.. code-block:: text
|
99
99
|
|
100
100
|
Original circuit:
|
101
101
|
┌─────────┐
|
@@ -73,6 +73,7 @@ from qiskit.transpiler.passes.optimization.optimize_1q_decomposition import (
|
|
73
73
|
from qiskit.transpiler.passes.synthesis import plugin
|
74
74
|
from qiskit.transpiler.target import Target
|
75
75
|
|
76
|
+
from qiskit._accelerate.unitary_synthesis import run_default_main_loop
|
76
77
|
|
77
78
|
GATE_NAME_MAP = {
|
78
79
|
"cx": CXGate._standard_gate,
|
@@ -456,37 +457,6 @@ class UnitarySynthesis(TransformationPass):
|
|
456
457
|
default_kwargs = {}
|
457
458
|
method_list = [(plugin_method, plugin_kwargs), (default_method, default_kwargs)]
|
458
459
|
|
459
|
-
for method, kwargs in method_list:
|
460
|
-
if method.supports_basis_gates:
|
461
|
-
kwargs["basis_gates"] = self._basis_gates
|
462
|
-
if method.supports_natural_direction:
|
463
|
-
kwargs["natural_direction"] = self._natural_direction
|
464
|
-
if method.supports_pulse_optimize:
|
465
|
-
kwargs["pulse_optimize"] = self._pulse_optimize
|
466
|
-
if method.supports_gate_lengths:
|
467
|
-
_gate_lengths = _gate_lengths or _build_gate_lengths(
|
468
|
-
self._backend_props, self._target
|
469
|
-
)
|
470
|
-
kwargs["gate_lengths"] = _gate_lengths
|
471
|
-
if method.supports_gate_errors:
|
472
|
-
_gate_errors = _gate_errors or _build_gate_errors(self._backend_props, self._target)
|
473
|
-
kwargs["gate_errors"] = _gate_errors
|
474
|
-
if method.supports_gate_lengths_by_qubit:
|
475
|
-
_gate_lengths_by_qubit = _gate_lengths_by_qubit or _build_gate_lengths_by_qubit(
|
476
|
-
self._backend_props, self._target
|
477
|
-
)
|
478
|
-
kwargs["gate_lengths_by_qubit"] = _gate_lengths_by_qubit
|
479
|
-
if method.supports_gate_errors_by_qubit:
|
480
|
-
_gate_errors_by_qubit = _gate_errors_by_qubit or _build_gate_errors_by_qubit(
|
481
|
-
self._backend_props, self._target
|
482
|
-
)
|
483
|
-
kwargs["gate_errors_by_qubit"] = _gate_errors_by_qubit
|
484
|
-
supported_bases = method.supported_bases
|
485
|
-
if supported_bases is not None:
|
486
|
-
kwargs["matched_basis"] = _choose_bases(self._basis_gates, supported_bases)
|
487
|
-
if method.supports_target:
|
488
|
-
kwargs["target"] = self._target
|
489
|
-
|
490
460
|
# Handle approximation degree as a special case for backwards compatibility, it's
|
491
461
|
# not part of the plugin interface and only something needed for the default
|
492
462
|
# pass.
|
@@ -501,9 +471,60 @@ class UnitarySynthesis(TransformationPass):
|
|
501
471
|
if plugin_method.supports_coupling_map or default_method.supports_coupling_map
|
502
472
|
else {}
|
503
473
|
)
|
504
|
-
|
505
|
-
|
506
|
-
|
474
|
+
|
475
|
+
if self.method == "default" and self._target is not None:
|
476
|
+
_coupling_edges = (
|
477
|
+
set(self._coupling_map.get_edges()) if self._coupling_map is not None else set()
|
478
|
+
)
|
479
|
+
|
480
|
+
out = run_default_main_loop(
|
481
|
+
dag,
|
482
|
+
list(qubit_indices.values()),
|
483
|
+
self._min_qubits,
|
484
|
+
self._target,
|
485
|
+
_coupling_edges,
|
486
|
+
self._approximation_degree,
|
487
|
+
self._natural_direction,
|
488
|
+
)
|
489
|
+
return out
|
490
|
+
else:
|
491
|
+
for method, kwargs in method_list:
|
492
|
+
if method.supports_basis_gates:
|
493
|
+
kwargs["basis_gates"] = self._basis_gates
|
494
|
+
if method.supports_natural_direction:
|
495
|
+
kwargs["natural_direction"] = self._natural_direction
|
496
|
+
if method.supports_pulse_optimize:
|
497
|
+
kwargs["pulse_optimize"] = self._pulse_optimize
|
498
|
+
if method.supports_gate_lengths:
|
499
|
+
_gate_lengths = _gate_lengths or _build_gate_lengths(
|
500
|
+
self._backend_props, self._target
|
501
|
+
)
|
502
|
+
kwargs["gate_lengths"] = _gate_lengths
|
503
|
+
if method.supports_gate_errors:
|
504
|
+
_gate_errors = _gate_errors or _build_gate_errors(
|
505
|
+
self._backend_props, self._target
|
506
|
+
)
|
507
|
+
kwargs["gate_errors"] = _gate_errors
|
508
|
+
if method.supports_gate_lengths_by_qubit:
|
509
|
+
_gate_lengths_by_qubit = _gate_lengths_by_qubit or _build_gate_lengths_by_qubit(
|
510
|
+
self._backend_props, self._target
|
511
|
+
)
|
512
|
+
kwargs["gate_lengths_by_qubit"] = _gate_lengths_by_qubit
|
513
|
+
if method.supports_gate_errors_by_qubit:
|
514
|
+
_gate_errors_by_qubit = _gate_errors_by_qubit or _build_gate_errors_by_qubit(
|
515
|
+
self._backend_props, self._target
|
516
|
+
)
|
517
|
+
kwargs["gate_errors_by_qubit"] = _gate_errors_by_qubit
|
518
|
+
supported_bases = method.supported_bases
|
519
|
+
if supported_bases is not None:
|
520
|
+
kwargs["matched_basis"] = _choose_bases(self._basis_gates, supported_bases)
|
521
|
+
if method.supports_target:
|
522
|
+
kwargs["target"] = self._target
|
523
|
+
|
524
|
+
out = self._run_main_loop(
|
525
|
+
dag, qubit_indices, plugin_method, plugin_kwargs, default_method, default_kwargs
|
526
|
+
)
|
527
|
+
return out
|
507
528
|
|
508
529
|
def _run_main_loop(
|
509
530
|
self, dag, qubit_indices, plugin_method, plugin_kwargs, default_method, default_kwargs
|
@@ -13,9 +13,8 @@
|
|
13
13
|
|
14
14
|
"""Add a barrier before final measurements."""
|
15
15
|
|
16
|
-
from qiskit.
|
16
|
+
from qiskit._accelerate.barrier_before_final_measurement import barrier_before_final_measurements
|
17
17
|
from qiskit.transpiler.basepasses import TransformationPass
|
18
|
-
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
19
18
|
from .merge_adjacent_barriers import MergeAdjacentBarriers
|
20
19
|
|
21
20
|
|
@@ -33,60 +32,7 @@ class BarrierBeforeFinalMeasurements(TransformationPass):
|
|
33
32
|
|
34
33
|
def run(self, dag):
|
35
34
|
"""Run the BarrierBeforeFinalMeasurements pass on `dag`."""
|
36
|
-
|
37
|
-
final_op_types = ["measure", "barrier"]
|
38
|
-
final_ops = []
|
39
|
-
for candidate_node in dag.named_nodes(*final_op_types):
|
40
|
-
is_final_op = True
|
41
|
-
|
42
|
-
for _, child_successors in dag.bfs_successors(candidate_node):
|
43
|
-
|
44
|
-
if any(
|
45
|
-
isinstance(suc, DAGOpNode) and suc.name not in final_op_types
|
46
|
-
for suc in child_successors
|
47
|
-
):
|
48
|
-
is_final_op = False
|
49
|
-
break
|
50
|
-
|
51
|
-
if is_final_op:
|
52
|
-
final_ops.append(candidate_node)
|
53
|
-
|
54
|
-
if not final_ops:
|
55
|
-
return dag
|
56
|
-
|
57
|
-
# Create a layer with the barrier and add both bits and registers from the original dag.
|
58
|
-
barrier_layer = DAGCircuit()
|
59
|
-
barrier_layer.add_qubits(dag.qubits)
|
60
|
-
for qreg in dag.qregs.values():
|
61
|
-
barrier_layer.add_qreg(qreg)
|
62
|
-
barrier_layer.add_clbits(dag.clbits)
|
63
|
-
for creg in dag.cregs.values():
|
64
|
-
barrier_layer.add_creg(creg)
|
65
|
-
|
66
|
-
# Add a barrier across all qubits so swap mapper doesn't add a swap
|
67
|
-
# from an unmeasured qubit after a measure.
|
68
|
-
final_qubits = dag.qubits
|
69
|
-
|
70
|
-
barrier_layer.apply_operation_back(
|
71
|
-
Barrier(len(final_qubits), label=self.label), final_qubits, (), check=False
|
72
|
-
)
|
73
|
-
|
74
|
-
# Preserve order of final ops collected earlier from the original DAG.
|
75
|
-
ordered_final_nodes = [
|
76
|
-
node for node in dag.topological_op_nodes() if node in set(final_ops)
|
77
|
-
]
|
78
|
-
|
79
|
-
# Move final ops to the new layer and append the new layer to the DAG.
|
80
|
-
for final_node in ordered_final_nodes:
|
81
|
-
barrier_layer.apply_operation_back(
|
82
|
-
final_node.op, final_node.qargs, final_node.cargs, check=False
|
83
|
-
)
|
84
|
-
|
85
|
-
for final_op in final_ops:
|
86
|
-
dag.remove_op_node(final_op)
|
87
|
-
|
88
|
-
dag.compose(barrier_layer)
|
89
|
-
|
35
|
+
barrier_before_final_measurements(dag, self.label)
|
90
36
|
if self.label is None:
|
91
37
|
# Merge the new barrier into any other barriers
|
92
38
|
adjacent_pass = MergeAdjacentBarriers()
|
@@ -22,6 +22,7 @@ from qiskit.circuit import (
|
|
22
22
|
)
|
23
23
|
from qiskit.dagcircuit import DAGCircuit
|
24
24
|
from qiskit.transpiler.basepasses import TransformationPass
|
25
|
+
from qiskit.utils import deprecate_func
|
25
26
|
|
26
27
|
|
27
28
|
class ConvertConditionsToIfOps(TransformationPass):
|
@@ -31,6 +32,10 @@ class ConvertConditionsToIfOps(TransformationPass):
|
|
31
32
|
This is a simple pass aimed at easing the conversion from the old style of using
|
32
33
|
:meth:`.InstructionSet.c_if` into the new style of using more complex conditional logic."""
|
33
34
|
|
35
|
+
@deprecate_func(since="1.3.0", removal_timeline="in Qiskit 2.0.0")
|
36
|
+
def __init__(self):
|
37
|
+
super().__init__()
|
38
|
+
|
34
39
|
def _run_inner(self, dag):
|
35
40
|
"""Run the pass on one :class:`.DAGCircuit`, mutating it. Returns ``True`` if the circuit
|
36
41
|
was modified and ``False`` if not."""
|
@@ -10,40 +10,17 @@
|
|
10
10
|
# copyright notice, and modified files need to carry a notice indicating
|
11
11
|
# that they have been altered from the originals.
|
12
12
|
|
13
|
-
"""Rearrange the direction of the
|
14
|
-
|
15
|
-
from math import pi
|
13
|
+
"""Rearrange the direction of the 2-qubit gate nodes to match the directed coupling map."""
|
16
14
|
|
17
15
|
from qiskit.transpiler.basepasses import TransformationPass
|
18
|
-
from qiskit.
|
19
|
-
|
20
|
-
from qiskit.converters import dag_to_circuit, circuit_to_dag
|
21
|
-
from qiskit.circuit import QuantumRegister, ControlFlowOp
|
22
|
-
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
23
|
-
from qiskit.circuit.library.standard_gates import (
|
24
|
-
SGate,
|
25
|
-
SdgGate,
|
26
|
-
SXGate,
|
27
|
-
HGate,
|
28
|
-
CXGate,
|
29
|
-
CZGate,
|
30
|
-
ECRGate,
|
31
|
-
RXXGate,
|
32
|
-
RYYGate,
|
33
|
-
RZZGate,
|
34
|
-
RZXGate,
|
35
|
-
SwapGate,
|
36
|
-
)
|
37
|
-
|
38
|
-
|
39
|
-
def _swap_node_qargs(node):
|
40
|
-
return DAGOpNode(node.op, node.qargs[::-1], node.cargs)
|
16
|
+
from qiskit._accelerate.gate_direction import fix_gate_direction_coupling, fix_gate_direction_target
|
41
17
|
|
42
18
|
|
43
19
|
class GateDirection(TransformationPass):
|
44
20
|
"""Modify asymmetric gates to match the hardware coupling direction.
|
45
21
|
|
46
|
-
This pass
|
22
|
+
This pass supports replacements for the `cx`, `cz`, `ecr`, `swap`, `rzx`, `rxx`, `ryy` and
|
23
|
+
`rzz` gates, using the following identities::
|
47
24
|
|
48
25
|
┌───┐┌───┐┌───┐
|
49
26
|
q_0: ──■── q_0: ┤ H ├┤ X ├┤ H ├
|
@@ -58,6 +35,9 @@ class GateDirection(TransformationPass):
|
|
58
35
|
│ ECR │ = ┌┴───┴┐├────┤└┬───┬┘│ Ecr │├───┤
|
59
36
|
q_1: ┤1 ├ q_1: ┤ Sdg ├┤ √X ├─┤ S ├─┤0 ├┤ H ├
|
60
37
|
└──────┘ └─────┘└────┘ └───┘ └──────┘└───┘
|
38
|
+
Note: This is done in terms of less-efficient S/SX/Sdg gates instead of the more natural
|
39
|
+
`RY(pi /2)` so we have a chance for basis translation to keep things in a discrete basis
|
40
|
+
during resynthesis, if that's what's being asked for.
|
61
41
|
|
62
42
|
|
63
43
|
┌──────┐ ┌───┐┌──────┐┌───┐
|
@@ -66,18 +46,18 @@ class GateDirection(TransformationPass):
|
|
66
46
|
q_1: ┤1 ├ q_1: ┤ H ├┤0 ├┤ H ├
|
67
47
|
└──────┘ └───┘└──────┘└───┘
|
68
48
|
|
49
|
+
cz, swap, rxx, ryy and rzz directions are fixed by reversing their qargs order.
|
50
|
+
|
69
51
|
This pass assumes that the positions of the qubits in the :attr:`.DAGCircuit.qubits` attribute
|
70
52
|
are the physical qubit indices. For example if ``dag.qubits[0]`` is qubit 0 in the
|
71
53
|
:class:`.CouplingMap` or :class:`.Target`.
|
72
54
|
"""
|
73
55
|
|
74
|
-
_KNOWN_REPLACEMENTS = frozenset(["cx", "cz", "ecr", "swap", "rzx", "rxx", "ryy", "rzz"])
|
75
|
-
|
76
56
|
def __init__(self, coupling_map, target=None):
|
77
57
|
"""GateDirection pass.
|
78
58
|
|
79
59
|
Args:
|
80
|
-
coupling_map (CouplingMap): Directed graph
|
60
|
+
coupling_map (CouplingMap): Directed graph representing a coupling map.
|
81
61
|
target (Target): The backend target to use for this pass. If this is specified
|
82
62
|
it will be used instead of the coupling map
|
83
63
|
"""
|
@@ -85,248 +65,6 @@ class GateDirection(TransformationPass):
|
|
85
65
|
self.coupling_map = coupling_map
|
86
66
|
self.target = target
|
87
67
|
|
88
|
-
# Create the replacement dag and associated register.
|
89
|
-
self._cx_dag = DAGCircuit()
|
90
|
-
qr = QuantumRegister(2)
|
91
|
-
self._cx_dag.add_qreg(qr)
|
92
|
-
self._cx_dag.apply_operation_back(HGate(), [qr[0]], [])
|
93
|
-
self._cx_dag.apply_operation_back(HGate(), [qr[1]], [])
|
94
|
-
self._cx_dag.apply_operation_back(CXGate(), [qr[1], qr[0]], [])
|
95
|
-
self._cx_dag.apply_operation_back(HGate(), [qr[0]], [])
|
96
|
-
self._cx_dag.apply_operation_back(HGate(), [qr[1]], [])
|
97
|
-
|
98
|
-
# This is done in terms of less-efficient S/SX/Sdg gates instead of the more natural
|
99
|
-
# `RY(pi /2)` so we have a chance for basis translation to keep things in a discrete basis
|
100
|
-
# during resynthesis, if that's what's being asked for.
|
101
|
-
self._ecr_dag = DAGCircuit()
|
102
|
-
qr = QuantumRegister(2)
|
103
|
-
self._ecr_dag.global_phase = -pi / 2
|
104
|
-
self._ecr_dag.add_qreg(qr)
|
105
|
-
self._ecr_dag.apply_operation_back(SGate(), [qr[0]], [])
|
106
|
-
self._ecr_dag.apply_operation_back(SXGate(), [qr[0]], [])
|
107
|
-
self._ecr_dag.apply_operation_back(SdgGate(), [qr[0]], [])
|
108
|
-
self._ecr_dag.apply_operation_back(SdgGate(), [qr[1]], [])
|
109
|
-
self._ecr_dag.apply_operation_back(SXGate(), [qr[1]], [])
|
110
|
-
self._ecr_dag.apply_operation_back(SGate(), [qr[1]], [])
|
111
|
-
self._ecr_dag.apply_operation_back(ECRGate(), [qr[1], qr[0]], [])
|
112
|
-
self._ecr_dag.apply_operation_back(HGate(), [qr[0]], [])
|
113
|
-
self._ecr_dag.apply_operation_back(HGate(), [qr[1]], [])
|
114
|
-
|
115
|
-
self._cz_dag = DAGCircuit()
|
116
|
-
qr = QuantumRegister(2)
|
117
|
-
self._cz_dag.add_qreg(qr)
|
118
|
-
self._cz_dag.apply_operation_back(CZGate(), [qr[1], qr[0]], [])
|
119
|
-
|
120
|
-
self._swap_dag = DAGCircuit()
|
121
|
-
qr = QuantumRegister(2)
|
122
|
-
self._swap_dag.add_qreg(qr)
|
123
|
-
self._swap_dag.apply_operation_back(SwapGate(), [qr[1], qr[0]], [])
|
124
|
-
|
125
|
-
# If adding more replacements (either static or dynamic), also update the class variable
|
126
|
-
# `_KNOWN_REPLACMENTS` to include them in the error messages.
|
127
|
-
self._static_replacements = {
|
128
|
-
"cx": self._cx_dag,
|
129
|
-
"cz": self._cz_dag,
|
130
|
-
"ecr": self._ecr_dag,
|
131
|
-
"swap": self._swap_dag,
|
132
|
-
}
|
133
|
-
|
134
|
-
@staticmethod
|
135
|
-
def _rzx_dag(parameter):
|
136
|
-
_rzx_dag = DAGCircuit()
|
137
|
-
qr = QuantumRegister(2)
|
138
|
-
_rzx_dag.add_qreg(qr)
|
139
|
-
_rzx_dag.apply_operation_back(HGate(), [qr[0]], [])
|
140
|
-
_rzx_dag.apply_operation_back(HGate(), [qr[1]], [])
|
141
|
-
_rzx_dag.apply_operation_back(RZXGate(parameter), [qr[1], qr[0]], [])
|
142
|
-
_rzx_dag.apply_operation_back(HGate(), [qr[0]], [])
|
143
|
-
_rzx_dag.apply_operation_back(HGate(), [qr[1]], [])
|
144
|
-
return _rzx_dag
|
145
|
-
|
146
|
-
@staticmethod
|
147
|
-
def _rxx_dag(parameter):
|
148
|
-
_rxx_dag = DAGCircuit()
|
149
|
-
qr = QuantumRegister(2)
|
150
|
-
_rxx_dag.add_qreg(qr)
|
151
|
-
_rxx_dag.apply_operation_back(RXXGate(parameter), [qr[1], qr[0]], [])
|
152
|
-
return _rxx_dag
|
153
|
-
|
154
|
-
@staticmethod
|
155
|
-
def _ryy_dag(parameter):
|
156
|
-
_ryy_dag = DAGCircuit()
|
157
|
-
qr = QuantumRegister(2)
|
158
|
-
_ryy_dag.add_qreg(qr)
|
159
|
-
_ryy_dag.apply_operation_back(RYYGate(parameter), [qr[1], qr[0]], [])
|
160
|
-
return _ryy_dag
|
161
|
-
|
162
|
-
@staticmethod
|
163
|
-
def _rzz_dag(parameter):
|
164
|
-
_rzz_dag = DAGCircuit()
|
165
|
-
qr = QuantumRegister(2)
|
166
|
-
_rzz_dag.add_qreg(qr)
|
167
|
-
_rzz_dag.apply_operation_back(RZZGate(parameter), [qr[1], qr[0]], [])
|
168
|
-
return _rzz_dag
|
169
|
-
|
170
|
-
def _run_coupling_map(self, dag, wire_map, edges=None):
|
171
|
-
if edges is None:
|
172
|
-
edges = set(self.coupling_map.get_edges())
|
173
|
-
if not edges:
|
174
|
-
return dag
|
175
|
-
# Don't include directives to avoid things like barrier, which are assumed always supported.
|
176
|
-
for node in dag.op_nodes(include_directives=False):
|
177
|
-
if isinstance(node.op, ControlFlowOp):
|
178
|
-
new_op = node.op.replace_blocks(
|
179
|
-
dag_to_circuit(
|
180
|
-
self._run_coupling_map(
|
181
|
-
circuit_to_dag(block),
|
182
|
-
{
|
183
|
-
inner: wire_map[outer]
|
184
|
-
for outer, inner in zip(node.qargs, block.qubits)
|
185
|
-
},
|
186
|
-
edges,
|
187
|
-
)
|
188
|
-
)
|
189
|
-
for block in node.op.blocks
|
190
|
-
)
|
191
|
-
dag.substitute_node(node, new_op, propagate_condition=False)
|
192
|
-
continue
|
193
|
-
if len(node.qargs) != 2:
|
194
|
-
continue
|
195
|
-
if dag.has_calibration_for(node):
|
196
|
-
continue
|
197
|
-
qargs = (wire_map[node.qargs[0]], wire_map[node.qargs[1]])
|
198
|
-
if qargs not in edges and (qargs[1], qargs[0]) not in edges:
|
199
|
-
raise TranspilerError(
|
200
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
201
|
-
)
|
202
|
-
if qargs not in edges:
|
203
|
-
replacement = self._static_replacements.get(node.name)
|
204
|
-
if replacement is not None:
|
205
|
-
dag.substitute_node_with_dag(node, replacement)
|
206
|
-
elif node.name == "rzx":
|
207
|
-
dag.substitute_node_with_dag(node, self._rzx_dag(*node.op.params))
|
208
|
-
elif node.name == "rxx":
|
209
|
-
dag.substitute_node_with_dag(node, self._rxx_dag(*node.op.params))
|
210
|
-
elif node.name == "ryy":
|
211
|
-
dag.substitute_node_with_dag(node, self._ryy_dag(*node.op.params))
|
212
|
-
elif node.name == "rzz":
|
213
|
-
dag.substitute_node_with_dag(node, self._rzz_dag(*node.op.params))
|
214
|
-
else:
|
215
|
-
raise TranspilerError(
|
216
|
-
f"'{node.name}' would be supported on '{qargs}' if the direction were"
|
217
|
-
f" swapped, but no rules are known to do that."
|
218
|
-
f" {list(self._KNOWN_REPLACEMENTS)} can be automatically flipped."
|
219
|
-
)
|
220
|
-
return dag
|
221
|
-
|
222
|
-
def _run_target(self, dag, wire_map):
|
223
|
-
# Don't include directives to avoid things like barrier, which are assumed always supported.
|
224
|
-
for node in dag.op_nodes(include_directives=False):
|
225
|
-
if isinstance(node.op, ControlFlowOp):
|
226
|
-
new_op = node.op.replace_blocks(
|
227
|
-
dag_to_circuit(
|
228
|
-
self._run_target(
|
229
|
-
circuit_to_dag(block),
|
230
|
-
{
|
231
|
-
inner: wire_map[outer]
|
232
|
-
for outer, inner in zip(node.qargs, block.qubits)
|
233
|
-
},
|
234
|
-
)
|
235
|
-
)
|
236
|
-
for block in node.op.blocks
|
237
|
-
)
|
238
|
-
dag.substitute_node(node, new_op, propagate_condition=False)
|
239
|
-
continue
|
240
|
-
if len(node.qargs) != 2:
|
241
|
-
continue
|
242
|
-
if dag.has_calibration_for(node):
|
243
|
-
continue
|
244
|
-
qargs = (wire_map[node.qargs[0]], wire_map[node.qargs[1]])
|
245
|
-
swapped = (qargs[1], qargs[0])
|
246
|
-
if node.name in self._static_replacements:
|
247
|
-
if self.target.instruction_supported(node.name, qargs):
|
248
|
-
continue
|
249
|
-
if self.target.instruction_supported(node.name, swapped):
|
250
|
-
dag.substitute_node_with_dag(node, self._static_replacements[node.name])
|
251
|
-
else:
|
252
|
-
raise TranspilerError(
|
253
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
254
|
-
f" for {node.name}"
|
255
|
-
)
|
256
|
-
elif node.name == "rzx":
|
257
|
-
if self.target.instruction_supported(
|
258
|
-
qargs=qargs, operation_class=RZXGate, parameters=node.op.params
|
259
|
-
):
|
260
|
-
continue
|
261
|
-
if self.target.instruction_supported(
|
262
|
-
qargs=swapped, operation_class=RZXGate, parameters=node.op.params
|
263
|
-
):
|
264
|
-
dag.substitute_node_with_dag(node, self._rzx_dag(*node.op.params))
|
265
|
-
else:
|
266
|
-
raise TranspilerError(
|
267
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
268
|
-
f" for {node.name}"
|
269
|
-
)
|
270
|
-
elif node.name == "rxx":
|
271
|
-
if self.target.instruction_supported(
|
272
|
-
qargs=qargs, operation_class=RXXGate, parameters=node.op.params
|
273
|
-
):
|
274
|
-
continue
|
275
|
-
if self.target.instruction_supported(
|
276
|
-
qargs=swapped, operation_class=RXXGate, parameters=node.op.params
|
277
|
-
):
|
278
|
-
dag.substitute_node_with_dag(node, self._rxx_dag(*node.op.params))
|
279
|
-
else:
|
280
|
-
raise TranspilerError(
|
281
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
282
|
-
f" for {node.name}"
|
283
|
-
)
|
284
|
-
elif node.name == "ryy":
|
285
|
-
if self.target.instruction_supported(
|
286
|
-
qargs=qargs, operation_class=RYYGate, parameters=node.op.params
|
287
|
-
):
|
288
|
-
continue
|
289
|
-
if self.target.instruction_supported(
|
290
|
-
qargs=swapped, operation_class=RYYGate, parameters=node.op.params
|
291
|
-
):
|
292
|
-
dag.substitute_node_with_dag(node, self._ryy_dag(*node.op.params))
|
293
|
-
else:
|
294
|
-
raise TranspilerError(
|
295
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
296
|
-
f" for {node.name}"
|
297
|
-
)
|
298
|
-
elif node.name == "rzz":
|
299
|
-
if self.target.instruction_supported(
|
300
|
-
qargs=qargs, operation_class=RZZGate, parameters=node.op.params
|
301
|
-
):
|
302
|
-
continue
|
303
|
-
if self.target.instruction_supported(
|
304
|
-
qargs=swapped, operation_class=RZZGate, parameters=node.op.params
|
305
|
-
):
|
306
|
-
dag.substitute_node_with_dag(node, self._rzz_dag(*node.op.params))
|
307
|
-
else:
|
308
|
-
raise TranspilerError(
|
309
|
-
f"The circuit requires a connection between physical qubits {qargs}"
|
310
|
-
f" for {node.name}"
|
311
|
-
)
|
312
|
-
elif self.target.instruction_supported(node.name, qargs):
|
313
|
-
continue
|
314
|
-
elif self.target.instruction_supported(node.name, swapped) or dag.has_calibration_for(
|
315
|
-
_swap_node_qargs(node)
|
316
|
-
):
|
317
|
-
raise TranspilerError(
|
318
|
-
f"'{node.name}' would be supported on '{qargs}' if the direction were"
|
319
|
-
f" swapped, but no rules are known to do that."
|
320
|
-
f" {list(self._KNOWN_REPLACEMENTS)} can be automatically flipped."
|
321
|
-
)
|
322
|
-
else:
|
323
|
-
raise TranspilerError(
|
324
|
-
f"'{node.name}' with parameters '{node.op.params}' is not supported on qubits"
|
325
|
-
f" '{qargs}' in either direction."
|
326
|
-
)
|
327
|
-
|
328
|
-
return dag
|
329
|
-
|
330
68
|
def run(self, dag):
|
331
69
|
"""Run the GateDirection pass on `dag`.
|
332
70
|
|
@@ -343,7 +81,6 @@ class GateDirection(TransformationPass):
|
|
343
81
|
TranspilerError: If the circuit cannot be mapped just by flipping the
|
344
82
|
cx nodes.
|
345
83
|
"""
|
346
|
-
layout_map = {bit: i for i, bit in enumerate(dag.qubits)}
|
347
84
|
if self.target is None:
|
348
|
-
return
|
349
|
-
return
|
85
|
+
return fix_gate_direction_coupling(dag, set(self.coupling_map.get_edges()))
|
86
|
+
return fix_gate_direction_target(dag, self.target)
|
@@ -12,9 +12,13 @@
|
|
12
12
|
|
13
13
|
"""Check if all gates in the DAGCircuit are in the specified basis gates."""
|
14
14
|
|
15
|
-
from qiskit.converters import circuit_to_dag
|
16
15
|
from qiskit.transpiler.basepasses import AnalysisPass
|
17
16
|
|
17
|
+
from qiskit._accelerate.gates_in_basis import (
|
18
|
+
any_gate_missing_from_basis,
|
19
|
+
any_gate_missing_from_target,
|
20
|
+
)
|
21
|
+
|
18
22
|
|
19
23
|
class GatesInBasis(AnalysisPass):
|
20
24
|
"""Check if all gates in a DAG are in a given set of gates"""
|
@@ -40,35 +44,8 @@ class GatesInBasis(AnalysisPass):
|
|
40
44
|
if self._basis_gates is None and self._target is None:
|
41
45
|
self.property_set["all_gates_in_basis"] = True
|
42
46
|
return
|
43
|
-
gates_out_of_basis = False
|
44
47
|
if self._target is not None:
|
45
|
-
|
46
|
-
def _visit_target(dag, wire_map):
|
47
|
-
for gate in dag.op_nodes():
|
48
|
-
# Barrier and store are assumed universal and supported by all backends
|
49
|
-
if gate.name in ("barrier", "store"):
|
50
|
-
continue
|
51
|
-
if not self._target.instruction_supported(
|
52
|
-
gate.name, tuple(wire_map[bit] for bit in gate.qargs)
|
53
|
-
):
|
54
|
-
return True
|
55
|
-
# Control-flow ops still need to be supported, so don't skip them in the
|
56
|
-
# previous checks.
|
57
|
-
if gate.is_control_flow():
|
58
|
-
for block in gate.op.blocks:
|
59
|
-
inner_wire_map = {
|
60
|
-
inner: wire_map[outer]
|
61
|
-
for outer, inner in zip(gate.qargs, block.qubits)
|
62
|
-
}
|
63
|
-
if _visit_target(circuit_to_dag(block), inner_wire_map):
|
64
|
-
return True
|
65
|
-
return False
|
66
|
-
|
67
|
-
qubit_map = {qubit: index for index, qubit in enumerate(dag.qubits)}
|
68
|
-
gates_out_of_basis = _visit_target(dag, qubit_map)
|
48
|
+
gates_out_of_basis = any_gate_missing_from_target(dag, self._target)
|
69
49
|
else:
|
70
|
-
|
71
|
-
if gate not in self._basis_gates:
|
72
|
-
gates_out_of_basis = True
|
73
|
-
break
|
50
|
+
gates_out_of_basis = any_gate_missing_from_basis(dag, self._basis_gates)
|
74
51
|
self.property_set["all_gates_in_basis"] = not gates_out_of_basis
|