qiskit 1.3.0__cp39-abi3-win32.whl → 1.3.0b1__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 +1 -20
- qiskit/_accelerate.pyd +0 -0
- qiskit/assembler/assemble_schedules.py +0 -2
- qiskit/circuit/__init__.py +1 -44
- qiskit/circuit/_standard_gates_commutations.py +0 -585
- qiskit/circuit/barrier.py +0 -2
- qiskit/circuit/controlflow/builder.py +3 -3
- qiskit/circuit/controlflow/if_else.py +5 -13
- qiskit/circuit/controlflow/while_loop.py +2 -10
- qiskit/circuit/delay.py +3 -20
- qiskit/circuit/equivalence.py +214 -13
- qiskit/circuit/gate.py +1 -3
- qiskit/circuit/instruction.py +11 -32
- qiskit/circuit/instructionset.py +0 -2
- qiskit/circuit/library/__init__.py +14 -110
- qiskit/circuit/library/arithmetic/__init__.py +2 -9
- qiskit/circuit/library/arithmetic/adders/__init__.py +0 -1
- qiskit/circuit/library/arithmetic/adders/adder.py +2 -154
- qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +56 -20
- qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +1 -14
- qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +91 -21
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/multipliers/__init__.py +0 -1
- qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -8
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -94
- qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +1 -8
- qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +38 -20
- qiskit/circuit/library/blueprintcircuit.py +0 -64
- qiskit/circuit/library/boolean_logic/__init__.py +4 -4
- qiskit/circuit/library/boolean_logic/inner_product.py +4 -81
- qiskit/circuit/library/boolean_logic/quantum_and.py +4 -107
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -107
- qiskit/circuit/library/boolean_logic/quantum_xor.py +3 -97
- qiskit/circuit/library/data_preparation/__init__.py +3 -6
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +29 -342
- qiskit/circuit/library/data_preparation/{_z_feature_map.py → z_feature_map.py} +34 -45
- qiskit/circuit/library/data_preparation/zz_feature_map.py +118 -0
- qiskit/circuit/library/fourier_checking.py +11 -72
- qiskit/circuit/library/generalized_gates/__init__.py +1 -1
- qiskit/circuit/library/generalized_gates/diagonal.py +51 -45
- qiskit/circuit/library/generalized_gates/gms.py +14 -67
- 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 +6 -12
- qiskit/circuit/library/generalized_gates/mcmt.py +107 -167
- qiskit/circuit/library/generalized_gates/permutation.py +6 -8
- qiskit/circuit/library/generalized_gates/rv.py +9 -8
- qiskit/circuit/library/graph_state.py +10 -93
- qiskit/circuit/library/grover_operator.py +2 -270
- qiskit/circuit/library/hidden_linear_function.py +20 -83
- qiskit/circuit/library/iqp.py +20 -99
- qiskit/circuit/library/n_local/__init__.py +7 -19
- qiskit/circuit/library/n_local/efficient_su2.py +5 -118
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +0 -259
- qiskit/circuit/library/n_local/excitation_preserving.py +6 -130
- qiskit/circuit/library/n_local/n_local.py +5 -406
- qiskit/circuit/library/n_local/pauli_two_design.py +4 -106
- qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -80
- qiskit/circuit/library/n_local/real_amplitudes.py +7 -127
- qiskit/circuit/library/n_local/two_local.py +7 -14
- qiskit/circuit/library/overlap.py +26 -91
- qiskit/circuit/library/pauli_evolution.py +15 -17
- qiskit/circuit/library/phase_estimation.py +4 -80
- qiskit/circuit/library/quantum_volume.py +20 -72
- qiskit/circuit/library/standard_gates/__init__.py +1 -20
- qiskit/circuit/library/standard_gates/dcx.py +1 -2
- qiskit/circuit/library/standard_gates/ecr.py +2 -2
- qiskit/circuit/library/standard_gates/h.py +3 -4
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +2 -2
- qiskit/circuit/library/standard_gates/p.py +12 -20
- qiskit/circuit/library/standard_gates/r.py +1 -1
- qiskit/circuit/library/standard_gates/rx.py +3 -4
- qiskit/circuit/library/standard_gates/rxx.py +2 -2
- qiskit/circuit/library/standard_gates/ry.py +3 -4
- qiskit/circuit/library/standard_gates/ryy.py +2 -2
- qiskit/circuit/library/standard_gates/rz.py +12 -13
- 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 +3 -4
- qiskit/circuit/library/standard_gates/t.py +2 -2
- qiskit/circuit/library/standard_gates/u.py +3 -11
- qiskit/circuit/library/standard_gates/u1.py +15 -65
- qiskit/circuit/library/standard_gates/u2.py +1 -4
- qiskit/circuit/library/standard_gates/u3.py +3 -31
- qiskit/circuit/library/standard_gates/x.py +5 -7
- 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 +3 -4
- qiskit/circuit/library/standard_gates/z.py +3 -3
- qiskit/circuit/library/templates/clifford/clifford_2_1.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_2_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_2_3.py +7 -9
- qiskit/circuit/library/templates/clifford/clifford_2_4.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_3_1.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_4_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_3.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_4_4.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_5_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_3.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_6_4.py +8 -9
- qiskit/circuit/library/templates/clifford/clifford_6_5.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_1.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_2.py +9 -10
- qiskit/circuit/library/templates/clifford/clifford_8_3.py +9 -10
- qiskit/circuit/library/templates/nct/template_nct_2a_1.py +7 -9
- qiskit/circuit/library/templates/nct/template_nct_2a_2.py +8 -10
- qiskit/circuit/library/templates/nct/template_nct_2a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_4a_1.py +14 -16
- qiskit/circuit/library/templates/nct/template_nct_4a_2.py +12 -14
- qiskit/circuit/library/templates/nct/template_nct_4a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_4b_1.py +12 -14
- qiskit/circuit/library/templates/nct/template_nct_4b_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_5a_4.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_6a_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_6a_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6a_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6a_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6b_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6b_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_6c_1.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_7a_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7b_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7c_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7d_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_7e_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_9a_1.py +11 -13
- qiskit/circuit/library/templates/nct/template_nct_9c_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_9c_10.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_11.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_12.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_5.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_6.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_7.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_8.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9c_9.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_1.py +9 -11
- qiskit/circuit/library/templates/nct/template_nct_9d_10.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_2.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_3.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_4.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_5.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_6.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_7.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_8.py +10 -12
- qiskit/circuit/library/templates/nct/template_nct_9d_9.py +10 -12
- qiskit/circuit/library/templates/rzx/rzx_cy.py +10 -11
- qiskit/circuit/library/templates/rzx/rzx_xz.py +15 -16
- qiskit/circuit/library/templates/rzx/rzx_yz.py +10 -12
- qiskit/circuit/library/templates/rzx/rzx_zz1.py +20 -22
- qiskit/circuit/library/templates/rzx/rzx_zz2.py +15 -16
- qiskit/circuit/library/templates/rzx/rzx_zz3.py +15 -17
- qiskit/circuit/parameter.py +0 -4
- qiskit/circuit/parameterexpression.py +34 -167
- qiskit/circuit/quantumcircuit.py +126 -162
- qiskit/circuit/singleton.py +0 -2
- qiskit/circuit/store.py +0 -2
- qiskit/compiler/assembler.py +4 -17
- qiskit/compiler/scheduler.py +0 -2
- qiskit/compiler/sequencer.py +0 -2
- qiskit/compiler/transpiler.py +26 -81
- 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 +5 -7
- qiskit/converters/dag_to_dagdependency.py +1 -1
- qiskit/converters/dag_to_dagdependency_v2.py +1 -1
- qiskit/converters/dagdependency_to_circuit.py +1 -5
- qiskit/converters/dagdependency_to_dag.py +1 -6
- qiskit/dagcircuit/collect_blocks.py +3 -3
- qiskit/dagcircuit/dagdependency.py +5 -18
- qiskit/dagcircuit/dagdependency_v2.py +1 -1
- qiskit/dagcircuit/dagnode.py +2 -2
- qiskit/passmanager/__init__.py +2 -2
- qiskit/primitives/backend_estimator.py +2 -5
- qiskit/primitives/backend_sampler_v2.py +18 -61
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +1 -9
- qiskit/primitives/statevector_sampler.py +1 -1
- qiskit/primitives/utils.py +1 -1
- qiskit/providers/__init__.py +3 -3
- qiskit/providers/backend.py +1 -12
- qiskit/providers/backend_compat.py +3 -23
- qiskit/providers/basic_provider/basic_simulator.py +2 -12
- qiskit/providers/fake_provider/fake_pulse_backend.py +1 -6
- qiskit/providers/fake_provider/generic_backend_v2.py +30 -46
- qiskit/providers/models/pulsedefaults.py +0 -2
- qiskit/pulse/builder.py +18 -59
- qiskit/pulse/calibration_entries.py +1 -4
- qiskit/pulse/channels.py +0 -2
- qiskit/pulse/exceptions.py +0 -2
- qiskit/pulse/instruction_schedule_map.py +6 -21
- qiskit/pulse/instructions/acquire.py +0 -2
- qiskit/pulse/instructions/delay.py +0 -2
- qiskit/pulse/instructions/directives.py +0 -8
- qiskit/pulse/instructions/frequency.py +0 -3
- qiskit/pulse/instructions/instruction.py +0 -2
- qiskit/pulse/instructions/phase.py +0 -3
- qiskit/pulse/instructions/play.py +0 -2
- qiskit/pulse/instructions/reference.py +0 -2
- qiskit/pulse/instructions/snapshot.py +0 -2
- qiskit/pulse/library/pulse.py +0 -2
- qiskit/pulse/library/symbolic_pulses.py +0 -28
- qiskit/pulse/library/waveform.py +0 -2
- qiskit/pulse/macros.py +1 -1
- qiskit/pulse/schedule.py +13 -12
- qiskit/pulse/transforms/alignments.py +3 -5
- qiskit/pulse/transforms/dag.py +0 -7
- qiskit/qasm2/export.py +3 -5
- qiskit/qasm2/parse.py +2 -46
- qiskit/qasm3/__init__.py +0 -1
- qiskit/qasm3/ast.py +15 -123
- qiskit/qasm3/exporter.py +77 -103
- qiskit/qobj/converters/pulse_instruction.py +4 -6
- qiskit/qpy/__init__.py +0 -181
- qiskit/qpy/binary_io/circuits.py +5 -20
- qiskit/qpy/binary_io/schedules.py +4 -3
- qiskit/qpy/binary_io/value.py +13 -310
- qiskit/qpy/common.py +2 -46
- qiskit/qpy/formats.py +0 -7
- qiskit/qpy/interface.py +4 -40
- qiskit/quantum_info/__init__.py +0 -4
- qiskit/quantum_info/operators/channel/transformations.py +21 -28
- qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
- qiskit/quantum_info/operators/operator.py +8 -54
- qiskit/quantum_info/operators/symplectic/base_pauli.py +19 -11
- 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 +0 -2
- qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +2 -23
- 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 +1 -9
- qiskit/result/mitigation/local_readout_mitigator.py +1 -9
- qiskit/result/mitigation/utils.py +0 -57
- qiskit/scheduler/config.py +0 -2
- qiskit/scheduler/methods/basic.py +0 -3
- qiskit/scheduler/schedule_circuit.py +0 -2
- qiskit/scheduler/sequence.py +0 -2
- qiskit/synthesis/__init__.py +0 -25
- qiskit/synthesis/clifford/clifford_decompose_bm.py +2 -1
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +2 -3
- qiskit/synthesis/clifford/clifford_decompose_layers.py +1 -2
- qiskit/synthesis/evolution/__init__.py +0 -1
- qiskit/synthesis/evolution/lie_trotter.py +42 -16
- qiskit/synthesis/evolution/product_formula.py +238 -165
- qiskit/synthesis/evolution/qdrift.py +29 -36
- qiskit/synthesis/evolution/suzuki_trotter.py +27 -87
- qiskit/synthesis/multi_controlled/__init__.py +0 -1
- qiskit/synthesis/qft/qft_decompose_full.py +1 -19
- qiskit/synthesis/qft/qft_decompose_lnn.py +1 -2
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +1 -2
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +63 -4
- qiskit/synthesis/two_qubit/weyl.py +97 -0
- qiskit/synthesis/unitary/qsd.py +5 -5
- qiskit/transpiler/__init__.py +14 -21
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/passes/__init__.py +0 -2
- qiskit/transpiler/passes/basis/basis_translator.py +565 -9
- qiskit/transpiler/passes/basis/decompose.py +12 -45
- 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 +2 -4
- qiskit/transpiler/passes/calibration/rx_builder.py +7 -11
- qiskit/transpiler/passes/calibration/rzx_builder.py +30 -46
- qiskit/transpiler/passes/layout/disjoint_utils.py +13 -15
- qiskit/transpiler/passes/layout/sabre_layout.py +2 -7
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +0 -5
- qiskit/transpiler/passes/optimization/__init__.py +0 -1
- qiskit/transpiler/passes/optimization/collect_cliffords.py +3 -19
- 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 +131 -48
- qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +2 -4
- qiskit/transpiler/passes/optimization/elide_permutations.py +32 -9
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +0 -2
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +11 -5
- 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/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 +3 -7
- 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 +0 -2
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
- qiskit/transpiler/passes/scheduling/asap.py +1 -1
- qiskit/transpiler/passes/scheduling/base_scheduler.py +12 -14
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +4 -9
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +5 -16
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +1 -4
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +2 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -9
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +99 -262
- qiskit/transpiler/passes/synthesis/hls_plugins.py +7 -638
- qiskit/transpiler/passes/synthesis/qubit_tracker.py +132 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -55
- qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +56 -2
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -5
- qiskit/transpiler/passes/utils/gate_direction.py +275 -12
- qiskit/transpiler/passes/utils/gates_basis.py +30 -7
- qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +1 -2
- qiskit/transpiler/passmanager_config.py +4 -22
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +14 -40
- qiskit/transpiler/preset_passmanagers/common.py +3 -5
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +42 -125
- qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
- qiskit/transpiler/target.py +16 -74
- qiskit/visualization/circuit/_utils.py +2 -2
- qiskit/visualization/circuit/circuit_visualization.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +1 -1
- qiskit/visualization/dag_visualization.py +1 -1
- qiskit/visualization/pass_manager_visualization.py +14 -3
- qiskit/visualization/pulse_v2/interface.py +1 -3
- qiskit/visualization/timeline/core.py +2 -25
- qiskit/visualization/timeline/interface.py +0 -12
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/METADATA +19 -20
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/RECORD +347 -358
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/WHEEL +1 -1
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/entry_points.txt +0 -19
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +0 -150
- qiskit/circuit/twirling.py +0 -145
- qiskit/synthesis/arithmetic/__init__.py +0 -16
- qiskit/synthesis/arithmetic/adders/__init__.py +0 -17
- qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +0 -154
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +0 -103
- qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +0 -161
- qiskit/synthesis/arithmetic/multipliers/__init__.py +0 -16
- qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +0 -102
- qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +0 -99
- qiskit/synthesis/evolution/pauli_network.py +0 -80
- qiskit/synthesis/multi_controlled/mcmt_vchain.py +0 -52
- qiskit/transpiler/passes/optimization/remove_identity_equiv.py +0 -69
- qiskit/utils/deprecate_pulse.py +0 -119
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ from qiskit.circuit.instruction import Instruction
|
|
28
28
|
from qiskit.converters import circuit_to_dag, dag_to_circuit
|
29
29
|
from qiskit.transpiler.basepasses import TransformationPass
|
30
30
|
from qiskit.circuit.quantumcircuit import QuantumCircuit
|
31
|
-
from qiskit.circuit import ControlledGate, EquivalenceLibrary, equivalence
|
31
|
+
from qiskit.circuit import ControlledGate, EquivalenceLibrary, equivalence
|
32
32
|
from qiskit.transpiler.passes.utils import control_flow
|
33
33
|
from qiskit.transpiler.target import Target
|
34
34
|
from qiskit.transpiler.coupling import CouplingMap
|
@@ -42,8 +42,8 @@ from qiskit.circuit.annotated_operation import (
|
|
42
42
|
PowerModifier,
|
43
43
|
)
|
44
44
|
|
45
|
-
from qiskit._accelerate.high_level_synthesis import QubitTracker, QubitContext
|
46
45
|
from .plugin import HighLevelSynthesisPluginManager
|
46
|
+
from .qubit_tracker import QubitTracker
|
47
47
|
|
48
48
|
if typing.TYPE_CHECKING:
|
49
49
|
from qiskit.dagcircuit import DAGOpNode
|
@@ -271,161 +271,96 @@ class HighLevelSynthesis(TransformationPass):
|
|
271
271
|
(for instance, when the specified synthesis method is not available).
|
272
272
|
"""
|
273
273
|
qubits = tuple(dag.find_bit(q).index for q in dag.qubits)
|
274
|
-
context = QubitContext(list(range(len(dag.qubits))))
|
275
|
-
tracker = QubitTracker(num_qubits=dag.num_qubits())
|
276
274
|
if self.qubits_initially_zero:
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
return out_dag
|
281
|
-
|
282
|
-
def _run(
|
283
|
-
self,
|
284
|
-
dag: DAGCircuit,
|
285
|
-
tracker: QubitTracker,
|
286
|
-
context: QubitContext,
|
287
|
-
use_ancillas: bool,
|
288
|
-
top_level: bool,
|
289
|
-
) -> DAGCircuit:
|
290
|
-
"""
|
291
|
-
The main recursive function that synthesizes a DAGCircuit.
|
292
|
-
|
293
|
-
Input:
|
294
|
-
dag: the DAG to be synthesized.
|
295
|
-
tracker: the global tracker, tracking the state of original qubits.
|
296
|
-
context: the correspondence between the dag's qubits and the global qubits.
|
297
|
-
use_ancillas: if True, synthesis algorithms are allowed to use ancillas.
|
298
|
-
top_level: specifies if this is the top-level of the recursion.
|
299
|
-
|
300
|
-
The function returns the synthesized DAG.
|
275
|
+
clean, dirty = set(qubits), set()
|
276
|
+
else:
|
277
|
+
clean, dirty = set(), set(qubits)
|
301
278
|
|
302
|
-
|
303
|
-
|
304
|
-
the function update in-place the global qubits tracker and extends the local-to-global
|
305
|
-
context.
|
306
|
-
"""
|
279
|
+
tracker = QubitTracker(qubits=qubits, clean=clean, dirty=dirty)
|
280
|
+
return self._run(dag, tracker)
|
307
281
|
|
308
|
-
|
309
|
-
|
282
|
+
def _run(self, dag: DAGCircuit, tracker: QubitTracker) -> DAGCircuit:
|
283
|
+
# Check if HighLevelSynthesis can be skipped.
|
284
|
+
for node in dag.op_nodes():
|
285
|
+
qubits = tuple(dag.find_bit(q).index for q in node.qargs)
|
286
|
+
if not self._definitely_skip_node(node, qubits, dag):
|
287
|
+
break
|
288
|
+
else:
|
289
|
+
# The for-loop terminates without reaching the break statement
|
290
|
+
return dag
|
310
291
|
|
311
|
-
#
|
312
|
-
#
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
if not self._definitely_skip_node(node, qubits, dag):
|
317
|
-
break
|
318
|
-
else:
|
319
|
-
# The for-loop terminates without reaching the break statement
|
320
|
-
if dag.num_qubits() != context.num_qubits():
|
321
|
-
raise TranspilerError("HighLevelSynthesis internal error.")
|
322
|
-
return dag
|
323
|
-
|
324
|
-
# STEP 2: Analyze the nodes in the DAG. For each node in the DAG that needs
|
325
|
-
# to be synthesized, we recursively synthesize it and store the result. For
|
326
|
-
# instance, the result of synthesizing a custom gate is a DAGCircuit corresponding
|
327
|
-
# to the (recursively synthesized) gate's definition. When the result is a
|
328
|
-
# DAG, we also store its context (the mapping of its qubits to global qubits).
|
329
|
-
# In addition, we keep track of the qubit states using the (global) qubits tracker.
|
330
|
-
#
|
331
|
-
# Note: This is a first version of a potentially more elaborate approach to find
|
332
|
-
# good operation/ancilla allocations. The current approach is greedy and just gives
|
333
|
-
# all available ancilla qubits to the current operation ("the-first-takes-all" approach).
|
334
|
-
# It does not distribute ancilla qubits between different operations present in the DAG.
|
292
|
+
# Start by analyzing the nodes in the DAG. This for-loop is a first version of a potentially
|
293
|
+
# more elaborate approach to find good operation/ancilla allocations. It greedily iterates
|
294
|
+
# over the nodes, checking whether we can synthesize them, while keeping track of the
|
295
|
+
# qubit states. It does not trade-off allocations and just gives all available qubits
|
296
|
+
# to the current operation (a "the-first-takes-all" approach).
|
335
297
|
synthesized_nodes = {}
|
336
298
|
|
337
299
|
for node in dag.topological_op_nodes():
|
338
300
|
qubits = tuple(dag.find_bit(q).index for q in node.qargs)
|
339
|
-
processed = False
|
340
301
|
synthesized = None
|
341
|
-
|
342
|
-
|
343
|
-
# Start by handling special operations. Other cases can also be
|
344
|
-
# considered: swaps, automatically simplifying control gate (e.g. if
|
345
|
-
# a control is 0).
|
346
|
-
if node.op.name in ["id", "delay", "barrier"]:
|
347
|
-
# tracker not updated, these are no-ops
|
348
|
-
processed = True
|
349
|
-
|
350
|
-
elif node.op.name == "reset":
|
351
|
-
# reset qubits to 0
|
352
|
-
tracker.set_clean(context.to_globals(qubits))
|
353
|
-
processed = True
|
302
|
+
used_qubits = None
|
354
303
|
|
355
304
|
# check if synthesis for the operation can be skipped
|
356
|
-
|
357
|
-
|
305
|
+
if self._definitely_skip_node(node, qubits, dag):
|
306
|
+
pass
|
358
307
|
|
359
308
|
# next check control flow
|
360
309
|
elif node.is_control_flow():
|
361
|
-
|
362
|
-
|
363
|
-
partial(
|
364
|
-
|
365
|
-
tracker=tracker,
|
366
|
-
context=inner_context,
|
367
|
-
use_ancillas=False,
|
368
|
-
top_level=False,
|
369
|
-
),
|
370
|
-
node.op,
|
310
|
+
dag.substitute_node(
|
311
|
+
node,
|
312
|
+
control_flow.map_blocks(partial(self._run, tracker=tracker.copy()), node.op),
|
313
|
+
propagate_condition=False,
|
371
314
|
)
|
372
315
|
|
373
316
|
# now we are free to synthesize
|
374
317
|
else:
|
375
|
-
#
|
376
|
-
#
|
377
|
-
|
378
|
-
# current DAG's context are updated in-place.
|
379
|
-
synthesized, synthesized_context = self._synthesize_operation(
|
380
|
-
node.op, qubits, tracker, context, use_ancillas=use_ancillas
|
381
|
-
)
|
318
|
+
# this returns the synthesized operation and the qubits it acts on -- note that this
|
319
|
+
# may be different from the original qubits, since we may use auxiliary qubits
|
320
|
+
synthesized, used_qubits = self._synthesize_operation(node.op, qubits, tracker)
|
382
321
|
|
383
|
-
#
|
322
|
+
# if the synthesis changed the operation (i.e. it is not None), store the result
|
323
|
+
# and mark the operation qubits as used
|
384
324
|
if synthesized is not None:
|
385
|
-
synthesized_nodes[node
|
325
|
+
synthesized_nodes[node] = (synthesized, used_qubits)
|
326
|
+
tracker.used(qubits) # assumes that auxiliary are returned in the same state
|
386
327
|
|
387
|
-
#
|
388
|
-
|
389
|
-
|
328
|
+
# if the synthesis did not change anything, just update the qubit tracker
|
329
|
+
# other cases can be added: swaps, controlled gates (e.g. if control is 0), ...
|
330
|
+
else:
|
331
|
+
if node.op.name in ["id", "delay", "barrier"]:
|
332
|
+
pass # tracker not updated, these are no-ops
|
333
|
+
elif node.op.name == "reset":
|
334
|
+
tracker.reset(qubits) # reset qubits to 0
|
335
|
+
else:
|
336
|
+
tracker.used(qubits) # any other op used the clean state up
|
390
337
|
|
391
|
-
#
|
338
|
+
# we did not change anything just return the input
|
392
339
|
if len(synthesized_nodes) == 0:
|
393
|
-
if dag.num_qubits() != context.num_qubits():
|
394
|
-
raise TranspilerError("HighLevelSynthesis internal error.")
|
395
340
|
return dag
|
396
341
|
|
397
|
-
#
|
342
|
+
# Otherwise, we will rebuild with the new operations. Note that we could also
|
398
343
|
# check if no operation changed in size and substitute in-place, but rebuilding is
|
399
344
|
# generally as fast or faster, unless very few operations are changed.
|
400
345
|
out = dag.copy_empty_like()
|
401
|
-
|
402
|
-
|
403
|
-
if num_additional_qubits > 0:
|
404
|
-
out.add_qubits([Qubit() for _ in range(num_additional_qubits)])
|
405
|
-
|
406
|
-
index_to_qubit = dict(enumerate(out.qubits))
|
407
|
-
outer_to_local = context.to_local_mapping()
|
346
|
+
index_to_qubit = dict(enumerate(dag.qubits))
|
408
347
|
|
409
348
|
for node in dag.topological_op_nodes():
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
349
|
+
if node in synthesized_nodes:
|
350
|
+
op, qubits = synthesized_nodes[node]
|
351
|
+
qargs = tuple(index_to_qubit[index] for index in qubits)
|
414
352
|
if isinstance(op, Operation):
|
415
|
-
out.apply_operation_back(op,
|
353
|
+
out.apply_operation_back(op, qargs, cargs=[])
|
416
354
|
continue
|
417
355
|
|
418
356
|
if isinstance(op, QuantumCircuit):
|
419
357
|
op = circuit_to_dag(op, copy_operations=False)
|
420
358
|
|
421
|
-
inner_to_global = op_context.to_global_mapping()
|
422
359
|
if isinstance(op, DAGCircuit):
|
423
360
|
qubit_map = {
|
424
|
-
|
425
|
-
for (i, q) in enumerate(op.qubits)
|
361
|
+
qubit: index_to_qubit[index] for index, qubit in zip(qubits, op.qubits)
|
426
362
|
}
|
427
363
|
clbit_map = dict(zip(op.clbits, node.cargs))
|
428
|
-
|
429
364
|
for sub_node in op.op_nodes():
|
430
365
|
out.apply_operation_back(
|
431
366
|
sub_node.op,
|
@@ -433,15 +368,11 @@ class HighLevelSynthesis(TransformationPass):
|
|
433
368
|
tuple(clbit_map[carg] for carg in sub_node.cargs),
|
434
369
|
)
|
435
370
|
out.global_phase += op.global_phase
|
436
|
-
|
437
371
|
else:
|
438
|
-
raise
|
372
|
+
raise RuntimeError(f"Unexpected synthesized type: {type(op)}")
|
439
373
|
else:
|
440
374
|
out.apply_operation_back(node.op, node.qargs, node.cargs, check=False)
|
441
375
|
|
442
|
-
if out.num_qubits() != context.num_qubits():
|
443
|
-
raise TranspilerError("HighLevelSynthesis internal error.")
|
444
|
-
|
445
376
|
return out
|
446
377
|
|
447
378
|
def _synthesize_operation(
|
@@ -449,23 +380,7 @@ class HighLevelSynthesis(TransformationPass):
|
|
449
380
|
operation: Operation,
|
450
381
|
qubits: tuple[int],
|
451
382
|
tracker: QubitTracker,
|
452
|
-
|
453
|
-
use_ancillas: bool,
|
454
|
-
) -> tuple[QuantumCircuit | Operation | DAGCircuit | None, QubitContext | None]:
|
455
|
-
"""
|
456
|
-
Synthesizes an operation. The function receives the qubits on which the operation
|
457
|
-
is defined in the current DAG, the correspondence between the qubits of the current
|
458
|
-
DAG and the global qubits and the global qubits tracker. The function returns the
|
459
|
-
result of synthesizing the operation. The value of `None` means that the operation
|
460
|
-
should remain as it is. When it's a circuit, we also return the context, i.e. the
|
461
|
-
correspondence of its local qubits and the global qubits. The function changes
|
462
|
-
in-place the tracker (state of the global qubits), the qubits (when the synthesized
|
463
|
-
operation is defined over additional ancilla qubits), and the context (to keep track
|
464
|
-
of where these ancilla qubits maps to).
|
465
|
-
"""
|
466
|
-
|
467
|
-
synthesized_context = None
|
468
|
-
|
383
|
+
) -> tuple[QuantumCircuit | Operation | DAGCircuit | None, list[int] | None]:
|
469
384
|
# Try to synthesize the operation. We'll go through the following options:
|
470
385
|
# (1) Annotations: if the operator is annotated, synthesize the base operation
|
471
386
|
# and then apply the modifiers. Returns a circuit (e.g. applying a power)
|
@@ -474,62 +389,31 @@ class HighLevelSynthesis(TransformationPass):
|
|
474
389
|
# if the operation is a Clifford). Returns a circuit.
|
475
390
|
# (3) Unrolling custom definitions: try defining the operation if it is not yet
|
476
391
|
# in the set of supported instructions. Returns a circuit.
|
477
|
-
#
|
478
392
|
# If any of the above were triggered, we will recurse and go again through these steps
|
479
393
|
# until no further change occurred. At this point, we convert circuits to DAGs (the final
|
480
394
|
# possible return type). If there was no change, we just return ``None``.
|
481
|
-
num_original_qubits = len(qubits)
|
482
|
-
qubits = list(qubits)
|
483
|
-
|
484
395
|
synthesized = None
|
485
396
|
|
486
397
|
# Try synthesizing via AnnotatedOperation. This is faster than an isinstance check
|
487
398
|
# but a bit less safe since someone could create operations with a ``modifiers`` attribute.
|
488
399
|
if len(modifiers := getattr(operation, "modifiers", [])) > 0:
|
489
|
-
#
|
400
|
+
# The base operation must be synthesized without using potential control qubits
|
490
401
|
# used in the modifiers.
|
491
402
|
num_ctrl = sum(
|
492
403
|
mod.num_ctrl_qubits for mod in modifiers if isinstance(mod, ControlModifier)
|
493
404
|
)
|
494
405
|
baseop_qubits = qubits[num_ctrl:] # reminder: control qubits are the first ones
|
406
|
+
baseop_tracker = tracker.copy(drop=qubits[:num_ctrl]) # no access to control qubits
|
495
407
|
|
496
408
|
# get qubits of base operation
|
497
|
-
control_qubits = qubits[0:num_ctrl]
|
498
|
-
|
499
|
-
# Do not allow access to control qubits
|
500
|
-
tracker.disable(context.to_globals(control_qubits))
|
501
409
|
synthesized_base_op, _ = self._synthesize_operation(
|
502
|
-
operation.base_op,
|
503
|
-
baseop_qubits,
|
504
|
-
tracker,
|
505
|
-
context,
|
506
|
-
use_ancillas=use_ancillas,
|
410
|
+
operation.base_op, baseop_qubits, baseop_tracker
|
507
411
|
)
|
508
|
-
|
509
412
|
if synthesized_base_op is None:
|
510
413
|
synthesized_base_op = operation.base_op
|
511
414
|
elif isinstance(synthesized_base_op, DAGCircuit):
|
512
415
|
synthesized_base_op = dag_to_circuit(synthesized_base_op)
|
513
416
|
|
514
|
-
# Handle the case that synthesizing the base operation introduced
|
515
|
-
# additional qubits (e.g. the base operation is a circuit that includes
|
516
|
-
# an MCX gate).
|
517
|
-
if synthesized_base_op.num_qubits > len(baseop_qubits):
|
518
|
-
global_aux_qubits = tracker.borrow(
|
519
|
-
synthesized_base_op.num_qubits - len(baseop_qubits),
|
520
|
-
context.to_globals(baseop_qubits),
|
521
|
-
)
|
522
|
-
global_to_local = context.to_local_mapping()
|
523
|
-
for aq in global_aux_qubits:
|
524
|
-
if aq in global_to_local:
|
525
|
-
qubits.append(global_to_local[aq])
|
526
|
-
else:
|
527
|
-
new_local_qubit = context.add_qubit(aq)
|
528
|
-
qubits.append(new_local_qubit)
|
529
|
-
# Restore access to control qubits.
|
530
|
-
tracker.enable(context.to_globals(control_qubits))
|
531
|
-
|
532
|
-
# This step currently does not introduce ancilla qubits.
|
533
417
|
synthesized = self._apply_annotations(synthesized_base_op, operation.modifiers)
|
534
418
|
|
535
419
|
# If it was no AnnotatedOperation, try synthesizing via HLS or by unrolling.
|
@@ -537,106 +421,57 @@ class HighLevelSynthesis(TransformationPass):
|
|
537
421
|
# Try synthesis via HLS -- which will return ``None`` if unsuccessful.
|
538
422
|
indices = qubits if self._use_qubit_indices else None
|
539
423
|
if len(hls_methods := self._methods_to_try(operation.name)) > 0:
|
540
|
-
if use_ancillas:
|
541
|
-
num_clean_available = tracker.num_clean(context.to_globals(qubits))
|
542
|
-
num_dirty_available = tracker.num_dirty(context.to_globals(qubits))
|
543
|
-
else:
|
544
|
-
num_clean_available = 0
|
545
|
-
num_dirty_available = 0
|
546
424
|
synthesized = self._synthesize_op_using_plugins(
|
547
425
|
hls_methods,
|
548
426
|
operation,
|
549
427
|
indices,
|
550
|
-
|
551
|
-
|
428
|
+
tracker.num_clean(qubits),
|
429
|
+
tracker.num_dirty(qubits),
|
552
430
|
)
|
553
431
|
|
554
|
-
# It may happen that the plugin synthesis method uses clean/dirty ancilla qubits
|
555
|
-
if (synthesized is not None) and (synthesized.num_qubits > len(qubits)):
|
556
|
-
# need to borrow more qubits from tracker
|
557
|
-
global_aux_qubits = tracker.borrow(
|
558
|
-
synthesized.num_qubits - len(qubits), context.to_globals(qubits)
|
559
|
-
)
|
560
|
-
global_to_local = context.to_local_mapping()
|
561
|
-
|
562
|
-
for aq in global_aux_qubits:
|
563
|
-
if aq in global_to_local:
|
564
|
-
qubits.append(global_to_local[aq])
|
565
|
-
else:
|
566
|
-
new_local_qubit = context.add_qubit(aq)
|
567
|
-
qubits.append(new_local_qubit)
|
568
|
-
|
569
432
|
# If HLS did not apply, or was unsuccessful, try unrolling custom definitions.
|
570
433
|
if synthesized is None and not self._top_level_only:
|
571
|
-
synthesized = self.
|
434
|
+
synthesized = self._unroll_custom_definition(operation, indices)
|
572
435
|
|
573
436
|
if synthesized is None:
|
574
|
-
# if we didn't synthesize, there was nothing to unroll
|
575
|
-
|
576
|
-
pass
|
577
|
-
|
578
|
-
# if it has been synthesized, recurse and finally store the decomposition
|
579
|
-
elif isinstance(synthesized, Operation):
|
580
|
-
resynthesized, resynthesized_context = self._synthesize_operation(
|
581
|
-
synthesized, qubits, tracker, context, use_ancillas=use_ancillas
|
582
|
-
)
|
583
|
-
|
584
|
-
if resynthesized is not None:
|
585
|
-
synthesized = resynthesized
|
586
|
-
else:
|
587
|
-
tracker.set_dirty(context.to_globals(qubits))
|
588
|
-
if isinstance(resynthesized, DAGCircuit):
|
589
|
-
synthesized_context = resynthesized_context
|
590
|
-
|
591
|
-
elif isinstance(synthesized, QuantumCircuit):
|
592
|
-
# Synthesized is a quantum circuit which we want to process recursively.
|
593
|
-
# For example, it's the definition circuit of a custom gate
|
594
|
-
# or a circuit obtained by calling a synthesis method on a high-level-object.
|
595
|
-
# In the second case, synthesized may have more qubits than the original node.
|
596
|
-
|
597
|
-
as_dag = circuit_to_dag(synthesized, copy_operations=False)
|
598
|
-
inner_context = context.restrict(qubits)
|
599
|
-
|
600
|
-
if as_dag.num_qubits() != inner_context.num_qubits():
|
601
|
-
raise TranspilerError("HighLevelSynthesis internal error.")
|
602
|
-
|
603
|
-
# We save the current state of the tracker to be able to return the ancilla
|
604
|
-
# qubits to the current positions. Note that at this point we do not know
|
605
|
-
# which ancilla qubits will be allocated.
|
606
|
-
saved_tracker = tracker.copy()
|
607
|
-
synthesized = self._run(
|
608
|
-
as_dag, tracker, inner_context, use_ancillas=use_ancillas, top_level=False
|
609
|
-
)
|
610
|
-
synthesized_context = inner_context
|
437
|
+
# if we didn't synthesize, there was nothing to unroll, so just set the used qubits
|
438
|
+
used_qubits = qubits
|
611
439
|
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
global_to_local = context.to_local_mapping()
|
618
|
-
|
619
|
-
for aq in global_aux_qubits:
|
620
|
-
if aq in global_to_local:
|
621
|
-
qubits.append(global_to_local[aq])
|
622
|
-
else:
|
623
|
-
new_local_qubit = context.add_qubit(aq)
|
624
|
-
qubits.append(new_local_qubit)
|
625
|
-
|
626
|
-
if len(qubits) > num_original_qubits:
|
627
|
-
tracker.replace_state(
|
628
|
-
saved_tracker, context.to_globals(qubits[num_original_qubits:])
|
440
|
+
else:
|
441
|
+
# if it has been synthesized, recurse and finally store the decomposition
|
442
|
+
if isinstance(synthesized, Operation):
|
443
|
+
re_synthesized, qubits = self._synthesize_operation(
|
444
|
+
synthesized, qubits, tracker.copy()
|
629
445
|
)
|
446
|
+
if re_synthesized is not None:
|
447
|
+
synthesized = re_synthesized
|
448
|
+
used_qubits = qubits
|
449
|
+
|
450
|
+
elif isinstance(synthesized, QuantumCircuit):
|
451
|
+
aux_qubits = tracker.borrow(synthesized.num_qubits - len(qubits), qubits)
|
452
|
+
used_qubits = qubits + tuple(aux_qubits)
|
453
|
+
as_dag = circuit_to_dag(synthesized, copy_operations=False)
|
454
|
+
|
455
|
+
# map used qubits to subcircuit
|
456
|
+
new_qubits = [as_dag.find_bit(q).index for q in as_dag.qubits]
|
457
|
+
qubit_map = dict(zip(used_qubits, new_qubits))
|
458
|
+
|
459
|
+
synthesized = self._run(as_dag, tracker.copy(qubit_map))
|
460
|
+
if synthesized.num_qubits() != len(used_qubits):
|
461
|
+
raise RuntimeError(
|
462
|
+
f"Mismatching number of qubits, using {synthesized.num_qubits()} "
|
463
|
+
f"but have {len(used_qubits)}."
|
464
|
+
)
|
630
465
|
|
631
|
-
|
632
|
-
|
466
|
+
else:
|
467
|
+
raise RuntimeError(f"Unexpected synthesized type: {type(synthesized)}")
|
633
468
|
|
634
|
-
if
|
635
|
-
raise
|
469
|
+
if synthesized is not None and used_qubits is None:
|
470
|
+
raise RuntimeError("Failed to find qubit indices on", synthesized)
|
636
471
|
|
637
|
-
return synthesized,
|
472
|
+
return synthesized, used_qubits
|
638
473
|
|
639
|
-
def
|
474
|
+
def _unroll_custom_definition(
|
640
475
|
self, inst: Instruction, qubits: list[int] | None
|
641
476
|
) -> QuantumCircuit | None:
|
642
477
|
# check if the operation is already supported natively
|
@@ -811,10 +646,9 @@ class HighLevelSynthesis(TransformationPass):
|
|
811
646
|
node (which is _most_ nodes)."""
|
812
647
|
|
813
648
|
if (
|
814
|
-
dag.
|
649
|
+
dag.has_calibration_for(node)
|
815
650
|
or len(node.qargs) < self._min_qubits
|
816
651
|
or node.is_directive()
|
817
|
-
or (self._instruction_supported(node.name, qubits) and not node.is_control_flow())
|
818
652
|
):
|
819
653
|
return True
|
820
654
|
|
@@ -832,12 +666,15 @@ class HighLevelSynthesis(TransformationPass):
|
|
832
666
|
# If all the above constraints hold, and it's already supported or the basis translator
|
833
667
|
# can handle it, we'll leave it be.
|
834
668
|
and (
|
669
|
+
self._instruction_supported(node.name, qubits)
|
835
670
|
# This uses unfortunately private details of `EquivalenceLibrary`, but so does the
|
836
671
|
# `BasisTranslator`, and this is supposed to just be temporary til this is moved
|
837
672
|
# into Rust space.
|
838
|
-
|
839
|
-
|
840
|
-
|
673
|
+
or (
|
674
|
+
self._equiv_lib is not None
|
675
|
+
and equivalence.Key(name=node.name, num_qubits=node.num_qubits)
|
676
|
+
in self._equiv_lib._key_to_node_index
|
677
|
+
)
|
841
678
|
)
|
842
679
|
)
|
843
680
|
|