qiskit 1.1.2__cp38-abi3-macosx_10_9_universal2.whl → 1.2.0__cp38-abi3-macosx_10_9_universal2.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 +27 -24
- qiskit/_accelerate.abi3.so +0 -0
- qiskit/_numpy_compat.py +1 -1
- qiskit/assembler/assemble_circuits.py +107 -64
- qiskit/assembler/assemble_schedules.py +5 -12
- qiskit/assembler/disassemble.py +10 -1
- qiskit/circuit/__init__.py +6 -3
- qiskit/circuit/_classical_resource_map.py +5 -5
- qiskit/circuit/_utils.py +0 -13
- qiskit/circuit/add_control.py +1 -1
- qiskit/circuit/annotated_operation.py +23 -1
- qiskit/circuit/classical/expr/expr.py +4 -4
- qiskit/circuit/classical/expr/visitors.py +1 -1
- qiskit/circuit/classical/types/__init__.py +1 -1
- qiskit/circuit/classical/types/types.py +2 -2
- qiskit/circuit/classicalfunction/boolean_expression.py +1 -1
- qiskit/circuit/classicalfunction/classical_function_visitor.py +5 -5
- qiskit/circuit/classicalfunction/utils.py +1 -1
- qiskit/circuit/classicalregister.py +1 -1
- qiskit/circuit/commutation_checker.py +83 -35
- qiskit/circuit/controlflow/_builder_utils.py +1 -1
- qiskit/circuit/controlflow/builder.py +10 -6
- qiskit/circuit/controlflow/if_else.py +2 -2
- qiskit/circuit/controlflow/switch_case.py +1 -1
- qiskit/circuit/delay.py +1 -1
- qiskit/circuit/duration.py +2 -2
- qiskit/circuit/equivalence.py +5 -7
- qiskit/circuit/gate.py +11 -8
- qiskit/circuit/instruction.py +31 -13
- qiskit/circuit/instructionset.py +2 -5
- qiskit/circuit/library/__init__.py +2 -1
- qiskit/circuit/library/arithmetic/linear_amplitude_function.py +1 -1
- qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +1 -1
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +3 -3
- qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +1 -1
- qiskit/circuit/library/basis_change/__init__.py +1 -1
- qiskit/circuit/library/basis_change/qft.py +40 -6
- qiskit/circuit/library/blueprintcircuit.py +3 -5
- qiskit/circuit/library/data_preparation/__init__.py +9 -2
- qiskit/circuit/library/data_preparation/initializer.py +8 -0
- qiskit/circuit/library/data_preparation/state_preparation.py +98 -178
- qiskit/circuit/library/generalized_gates/isometry.py +8 -8
- qiskit/circuit/library/generalized_gates/linear_function.py +3 -2
- qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +4 -4
- qiskit/circuit/library/generalized_gates/permutation.py +8 -9
- qiskit/circuit/library/generalized_gates/uc.py +3 -3
- qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +2 -2
- qiskit/circuit/library/generalized_gates/unitary.py +13 -11
- qiskit/circuit/library/graph_state.py +1 -1
- qiskit/circuit/library/hamiltonian_gate.py +1 -2
- qiskit/circuit/library/hidden_linear_function.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -2
- qiskit/circuit/library/n_local/n_local.py +4 -5
- qiskit/circuit/library/n_local/pauli_two_design.py +1 -1
- qiskit/circuit/library/n_local/qaoa_ansatz.py +6 -8
- qiskit/circuit/library/n_local/two_local.py +1 -1
- qiskit/circuit/library/overlap.py +11 -5
- qiskit/circuit/library/pauli_evolution.py +7 -3
- qiskit/circuit/library/standard_gates/dcx.py +3 -0
- qiskit/circuit/library/standard_gates/ecr.py +3 -0
- qiskit/circuit/library/standard_gates/global_phase.py +3 -0
- qiskit/circuit/library/standard_gates/h.py +13 -5
- qiskit/circuit/library/standard_gates/i.py +3 -0
- qiskit/circuit/library/standard_gates/iswap.py +3 -0
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +19 -10
- qiskit/circuit/library/standard_gates/p.py +14 -9
- qiskit/circuit/library/standard_gates/r.py +3 -0
- qiskit/circuit/library/standard_gates/rx.py +21 -6
- qiskit/circuit/library/standard_gates/rxx.py +40 -1
- qiskit/circuit/library/standard_gates/ry.py +21 -6
- qiskit/circuit/library/standard_gates/ryy.py +40 -1
- qiskit/circuit/library/standard_gates/rz.py +22 -6
- qiskit/circuit/library/standard_gates/rzx.py +40 -1
- qiskit/circuit/library/standard_gates/rzz.py +41 -2
- qiskit/circuit/library/standard_gates/s.py +77 -0
- qiskit/circuit/library/standard_gates/swap.py +12 -5
- qiskit/circuit/library/standard_gates/sx.py +14 -5
- qiskit/circuit/library/standard_gates/t.py +5 -0
- qiskit/circuit/library/standard_gates/u.py +22 -7
- qiskit/circuit/library/standard_gates/u1.py +8 -3
- qiskit/circuit/library/standard_gates/u2.py +3 -0
- qiskit/circuit/library/standard_gates/u3.py +22 -7
- qiskit/circuit/library/standard_gates/x.py +156 -92
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +40 -1
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +52 -11
- qiskit/circuit/library/standard_gates/y.py +6 -1
- qiskit/circuit/library/standard_gates/z.py +8 -1
- qiskit/circuit/operation.py +1 -1
- qiskit/circuit/parameter.py +9 -10
- qiskit/circuit/parameterexpression.py +16 -13
- qiskit/circuit/parametertable.py +1 -190
- qiskit/circuit/parametervector.py +1 -1
- qiskit/circuit/quantumcircuit.py +395 -387
- qiskit/circuit/quantumcircuitdata.py +3 -5
- qiskit/circuit/quantumregister.py +1 -1
- qiskit/circuit/random/__init__.py +1 -1
- qiskit/circuit/random/utils.py +175 -26
- qiskit/circuit/register.py +5 -7
- qiskit/circuit/singleton.py +3 -3
- qiskit/circuit/tools/pi_check.py +4 -4
- qiskit/compiler/assembler.py +95 -24
- qiskit/compiler/scheduler.py +2 -2
- qiskit/compiler/transpiler.py +42 -128
- qiskit/converters/circuit_to_dag.py +4 -6
- qiskit/converters/circuit_to_gate.py +4 -8
- qiskit/converters/circuit_to_instruction.py +5 -17
- qiskit/converters/dag_to_circuit.py +2 -6
- qiskit/dagcircuit/collect_blocks.py +2 -2
- qiskit/dagcircuit/dagcircuit.py +190 -187
- qiskit/dagcircuit/dagdependency.py +4 -4
- qiskit/dagcircuit/dagdependency_v2.py +4 -4
- qiskit/dagcircuit/dagdepnode.py +1 -1
- qiskit/dagcircuit/dagnode.py +66 -157
- qiskit/passmanager/flow_controllers.py +1 -1
- qiskit/passmanager/passmanager.py +3 -3
- qiskit/primitives/__init__.py +1 -5
- qiskit/primitives/backend_estimator.py +25 -15
- qiskit/primitives/backend_estimator_v2.py +31 -7
- qiskit/primitives/backend_sampler.py +21 -12
- qiskit/primitives/backend_sampler_v2.py +12 -3
- qiskit/primitives/base/base_estimator.py +31 -4
- qiskit/primitives/base/base_primitive.py +2 -2
- qiskit/primitives/base/base_result.py +2 -2
- qiskit/primitives/base/base_sampler.py +26 -2
- qiskit/primitives/base/estimator_result.py +2 -2
- qiskit/primitives/base/sampler_result.py +2 -2
- qiskit/primitives/containers/__init__.py +0 -1
- qiskit/primitives/containers/bindings_array.py +2 -2
- qiskit/primitives/containers/bit_array.py +108 -10
- qiskit/primitives/containers/shape.py +3 -3
- qiskit/primitives/estimator.py +9 -2
- qiskit/primitives/primitive_job.py +1 -1
- qiskit/primitives/sampler.py +10 -3
- qiskit/primitives/statevector_estimator.py +5 -3
- qiskit/primitives/statevector_sampler.py +11 -5
- qiskit/primitives/utils.py +16 -0
- qiskit/providers/backend.py +15 -6
- qiskit/providers/backend_compat.py +7 -4
- qiskit/providers/basic_provider/basic_provider_tools.py +1 -1
- qiskit/providers/basic_provider/basic_simulator.py +33 -25
- qiskit/providers/fake_provider/fake_backend.py +10 -3
- qiskit/providers/fake_provider/fake_openpulse_2q.py +157 -149
- qiskit/providers/fake_provider/fake_openpulse_3q.py +228 -220
- qiskit/providers/fake_provider/fake_pulse_backend.py +2 -1
- qiskit/providers/fake_provider/fake_qasm_backend.py +7 -2
- qiskit/providers/fake_provider/generic_backend_v2.py +514 -68
- qiskit/providers/models/__init__.py +48 -11
- qiskit/providers/models/backendconfiguration.py +50 -4
- qiskit/providers/models/backendproperties.py +13 -2
- qiskit/providers/models/pulsedefaults.py +10 -11
- qiskit/providers/options.py +13 -13
- qiskit/providers/providerutils.py +3 -1
- qiskit/pulse/configuration.py +8 -12
- qiskit/pulse/instruction_schedule_map.py +3 -5
- qiskit/pulse/instructions/acquire.py +7 -8
- qiskit/pulse/instructions/instruction.py +2 -3
- qiskit/pulse/library/samplers/decorators.py +5 -9
- qiskit/pulse/library/symbolic_pulses.py +4 -7
- qiskit/pulse/library/waveform.py +2 -5
- qiskit/pulse/macros.py +11 -6
- qiskit/pulse/parser.py +8 -10
- qiskit/pulse/schedule.py +9 -17
- qiskit/pulse/transforms/alignments.py +1 -3
- qiskit/pulse/utils.py +1 -2
- qiskit/qasm/libs/stdgates.inc +35 -28
- qiskit/qasm2/__init__.py +7 -7
- qiskit/qasm2/export.py +5 -9
- qiskit/qasm2/parse.py +1 -1
- qiskit/qasm3/ast.py +9 -25
- qiskit/qasm3/exporter.py +582 -479
- qiskit/qasm3/printer.py +7 -16
- qiskit/qobj/common.py +10 -0
- qiskit/qobj/converters/lo_config.py +9 -0
- qiskit/qobj/converters/pulse_instruction.py +13 -6
- qiskit/qobj/pulse_qobj.py +69 -15
- qiskit/qobj/qasm_qobj.py +72 -20
- qiskit/qobj/utils.py +9 -0
- qiskit/qpy/__init__.py +1 -1
- qiskit/qpy/binary_io/circuits.py +8 -5
- qiskit/qpy/binary_io/schedules.py +1 -1
- qiskit/qpy/binary_io/value.py +3 -3
- qiskit/qpy/interface.py +3 -2
- qiskit/qpy/type_keys.py +2 -2
- qiskit/quantum_info/operators/channel/quantum_channel.py +3 -6
- qiskit/quantum_info/operators/channel/superop.py +2 -2
- qiskit/quantum_info/operators/channel/transformations.py +1 -1
- qiskit/quantum_info/operators/dihedral/dihedral.py +3 -4
- qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +1 -3
- qiskit/quantum_info/operators/dihedral/random.py +6 -3
- qiskit/quantum_info/operators/measures.py +2 -2
- qiskit/quantum_info/operators/op_shape.py +12 -20
- qiskit/quantum_info/operators/operator.py +14 -21
- qiskit/quantum_info/operators/predicates.py +1 -0
- qiskit/quantum_info/operators/symplectic/base_pauli.py +7 -11
- qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
- qiskit/quantum_info/operators/symplectic/pauli.py +3 -3
- qiskit/quantum_info/operators/symplectic/pauli_list.py +9 -10
- qiskit/quantum_info/operators/symplectic/random.py +1 -1
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +15 -17
- qiskit/quantum_info/quaternion.py +1 -1
- qiskit/quantum_info/states/densitymatrix.py +5 -8
- qiskit/quantum_info/states/stabilizerstate.py +128 -37
- qiskit/quantum_info/states/statevector.py +4 -8
- qiskit/result/counts.py +2 -2
- qiskit/result/mitigation/correlated_readout_mitigator.py +2 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -2
- qiskit/result/mitigation/utils.py +1 -3
- qiskit/result/models.py +17 -16
- qiskit/result/result.py +15 -20
- qiskit/scheduler/lowering.py +2 -2
- qiskit/synthesis/__init__.py +2 -1
- qiskit/synthesis/clifford/__init__.py +1 -1
- qiskit/synthesis/clifford/clifford_decompose_ag.py +2 -2
- qiskit/synthesis/clifford/clifford_decompose_bm.py +10 -240
- qiskit/synthesis/clifford/clifford_decompose_greedy.py +9 -303
- qiskit/synthesis/clifford/clifford_decompose_layers.py +25 -23
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +1 -1
- qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +1 -1
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +2 -2
- qiskit/synthesis/evolution/evolution_synthesis.py +4 -2
- qiskit/synthesis/evolution/lie_trotter.py +46 -19
- qiskit/synthesis/evolution/product_formula.py +111 -55
- qiskit/synthesis/evolution/qdrift.py +40 -10
- qiskit/synthesis/evolution/suzuki_trotter.py +43 -33
- qiskit/synthesis/linear/__init__.py +1 -0
- qiskit/synthesis/linear/cnot_synth.py +22 -96
- qiskit/synthesis/linear/linear_depth_lnn.py +8 -8
- qiskit/synthesis/linear/linear_matrix_utils.py +13 -161
- qiskit/synthesis/linear_phase/cnot_phase_synth.py +1 -1
- qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +3 -3
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +1 -1
- qiskit/synthesis/one_qubit/one_qubit_decompose.py +29 -29
- qiskit/synthesis/permutation/permutation_full.py +5 -29
- qiskit/synthesis/permutation/permutation_lnn.py +2 -24
- qiskit/synthesis/permutation/permutation_utils.py +2 -59
- qiskit/synthesis/qft/__init__.py +1 -0
- qiskit/synthesis/qft/qft_decompose_full.py +79 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +17 -9
- qiskit/synthesis/stabilizer/stabilizer_circuit.py +6 -6
- qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -2
- qiskit/synthesis/two_qubit/local_invariance.py +8 -38
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +48 -129
- qiskit/synthesis/unitary/aqc/cnot_structures.py +1 -1
- qiskit/synthesis/unitary/qsd.py +5 -3
- qiskit/transpiler/__init__.py +1 -0
- qiskit/transpiler/basepasses.py +1 -1
- qiskit/transpiler/coupling.py +3 -3
- qiskit/transpiler/instruction_durations.py +1 -2
- qiskit/transpiler/layout.py +3 -3
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +84 -64
- qiskit/transpiler/passes/basis/translate_parameterized.py +3 -5
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +10 -10
- qiskit/transpiler/passes/calibration/rx_builder.py +3 -3
- qiskit/transpiler/passes/calibration/rzx_builder.py +3 -3
- qiskit/transpiler/passes/layout/apply_layout.py +13 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +10 -8
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +4 -1
- qiskit/transpiler/passes/layout/set_layout.py +2 -2
- qiskit/transpiler/passes/layout/vf2_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_utils.py +3 -3
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
- qiskit/transpiler/passes/optimization/commutation_analysis.py +7 -10
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +35 -19
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +17 -8
- qiskit/transpiler/passes/optimization/inverse_cancellation.py +6 -6
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +64 -41
- qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
- qiskit/transpiler/passes/optimization/split_2q_unitaries.py +83 -0
- qiskit/transpiler/passes/optimization/template_matching/backward_match.py +1 -1
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +2 -2
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -1
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -2
- qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
- qiskit/transpiler/passes/routing/layout_transformation.py +2 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +35 -26
- qiskit/transpiler/passes/routing/star_prerouting.py +80 -105
- qiskit/transpiler/passes/routing/stochastic_swap.py +1 -3
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -2
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +1 -1
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +5 -5
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +3 -3
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -14
- qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +7 -6
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -3
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +211 -36
- qiskit/transpiler/passes/synthesis/plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +80 -40
- qiskit/transpiler/passes/utils/__init__.py +0 -1
- qiskit/transpiler/passes/utils/check_gate_direction.py +4 -4
- qiskit/transpiler/passes/utils/check_map.py +3 -6
- qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +3 -4
- qiskit/transpiler/passes/utils/error.py +2 -2
- qiskit/transpiler/passes/utils/fixed_point.py +3 -3
- qiskit/transpiler/passes/utils/gate_direction.py +1 -1
- qiskit/transpiler/passes/utils/gates_basis.py +1 -2
- qiskit/transpiler/passmanager.py +7 -6
- qiskit/transpiler/preset_passmanagers/__init__.py +4 -228
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +73 -18
- qiskit/transpiler/preset_passmanagers/common.py +3 -6
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +518 -0
- qiskit/transpiler/preset_passmanagers/level0.py +1 -1
- qiskit/transpiler/target.py +27 -8
- qiskit/user_config.py +29 -6
- qiskit/utils/classtools.py +3 -3
- qiskit/utils/deprecation.py +3 -2
- qiskit/utils/lazy_tester.py +2 -2
- qiskit/utils/optionals.py +8 -8
- qiskit/visualization/bloch.py +18 -23
- qiskit/visualization/circuit/_utils.py +34 -10
- qiskit/visualization/circuit/circuit_visualization.py +23 -16
- qiskit/visualization/circuit/latex.py +29 -27
- qiskit/visualization/circuit/matplotlib.py +4 -2
- qiskit/visualization/circuit/qcstyle.py +2 -2
- qiskit/visualization/circuit/text.py +9 -15
- qiskit/visualization/dag_visualization.py +2 -2
- qiskit/visualization/pulse_v2/core.py +1 -1
- qiskit/visualization/pulse_v2/events.py +1 -1
- qiskit/visualization/pulse_v2/generators/frame.py +3 -4
- qiskit/visualization/pulse_v2/generators/waveform.py +5 -9
- qiskit/visualization/pulse_v2/layouts.py +1 -5
- qiskit/visualization/pulse_v2/plotters/matplotlib.py +1 -2
- qiskit/visualization/state_visualization.py +5 -6
- qiskit/visualization/timeline/plotters/matplotlib.py +1 -2
- qiskit/visualization/transition_visualization.py +7 -2
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/METADATA +12 -12
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/RECORD +342 -340
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/entry_points.txt +3 -0
- qiskit/transpiler/passes/utils/block_to_matrix.py +0 -47
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/WHEEL +0 -0
- {qiskit-1.1.2.dist-info → qiskit-1.2.0.dist-info}/top_level.txt +0 -0
@@ -16,16 +16,17 @@ from collections import defaultdict
|
|
16
16
|
import numpy as np
|
17
17
|
|
18
18
|
from qiskit.circuit.quantumregister import QuantumRegister
|
19
|
-
from qiskit.
|
19
|
+
from qiskit.circuit.parameterexpression import ParameterExpression
|
20
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
21
21
|
from qiskit.transpiler.passmanager import PassManager
|
22
22
|
from qiskit.transpiler.passes.optimization.commutation_analysis import CommutationAnalysis
|
23
23
|
from qiskit.dagcircuit import DAGCircuit, DAGInNode, DAGOutNode
|
24
|
+
from qiskit.circuit.commutation_library import CommutationChecker, StandardGateCommutations
|
24
25
|
from qiskit.circuit.library.standard_gates.u1 import U1Gate
|
25
26
|
from qiskit.circuit.library.standard_gates.rx import RXGate
|
26
27
|
from qiskit.circuit.library.standard_gates.p import PhaseGate
|
27
28
|
from qiskit.circuit.library.standard_gates.rz import RZGate
|
28
|
-
from qiskit.circuit import
|
29
|
+
from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
|
29
30
|
|
30
31
|
|
31
32
|
_CUTOFF_PRECISION = 1e-5
|
@@ -62,7 +63,18 @@ class CommutativeCancellation(TransformationPass):
|
|
62
63
|
self.basis = set(target.operation_names)
|
63
64
|
|
64
65
|
self._var_z_map = {"rz": RZGate, "p": PhaseGate, "u1": U1Gate}
|
65
|
-
|
66
|
+
|
67
|
+
self._z_rotations = {"p", "z", "u1", "rz", "t", "s"}
|
68
|
+
self._x_rotations = {"x", "rx"}
|
69
|
+
self._gates = {"cx", "cy", "cz", "h", "y"} # Now the gates supported are hard-coded
|
70
|
+
|
71
|
+
# build a commutation checker restricted to the gates we cancel -- the others we
|
72
|
+
# do not have to investigate, which allows to save time
|
73
|
+
commutation_checker = CommutationChecker(
|
74
|
+
StandardGateCommutations, gates=self._gates | self._z_rotations | self._x_rotations
|
75
|
+
)
|
76
|
+
|
77
|
+
self.requires.append(CommutationAnalysis(_commutation_checker=commutation_checker))
|
66
78
|
|
67
79
|
def run(self, dag):
|
68
80
|
"""Run the CommutativeCancellation pass on `dag`.
|
@@ -72,23 +84,17 @@ class CommutativeCancellation(TransformationPass):
|
|
72
84
|
|
73
85
|
Returns:
|
74
86
|
DAGCircuit: the optimized DAG.
|
75
|
-
|
76
|
-
Raises:
|
77
|
-
TranspilerError: when the 1-qubit rotation gates are not found
|
78
87
|
"""
|
79
88
|
var_z_gate = None
|
80
89
|
z_var_gates = [gate for gate in dag.count_ops().keys() if gate in self._var_z_map]
|
81
90
|
if z_var_gates:
|
82
|
-
#
|
91
|
+
# prioritize z gates in circuit
|
83
92
|
var_z_gate = self._var_z_map[next(iter(z_var_gates))]
|
84
93
|
else:
|
85
94
|
z_var_gates = [gate for gate in self.basis if gate in self._var_z_map]
|
86
95
|
if z_var_gates:
|
87
96
|
var_z_gate = self._var_z_map[next(iter(z_var_gates))]
|
88
97
|
|
89
|
-
# Now the gates supported are hard-coded
|
90
|
-
q_gate_list = ["cx", "cy", "cz", "h", "y"]
|
91
|
-
|
92
98
|
# Gate sets to be cancelled
|
93
99
|
cancellation_sets = defaultdict(lambda: [])
|
94
100
|
|
@@ -107,9 +113,11 @@ class CommutativeCancellation(TransformationPass):
|
|
107
113
|
continue
|
108
114
|
for node in com_set:
|
109
115
|
num_qargs = len(node.qargs)
|
110
|
-
if
|
116
|
+
if any(isinstance(p, ParameterExpression) for p in node.params):
|
117
|
+
continue # no support for cancellation of parameterized gates
|
118
|
+
if num_qargs == 1 and node.name in self._gates:
|
111
119
|
cancellation_sets[(node.name, wire, com_set_idx)].append(node)
|
112
|
-
if num_qargs == 1 and node.name in
|
120
|
+
if num_qargs == 1 and node.name in self._z_rotations:
|
113
121
|
cancellation_sets[("z_rotation", wire, com_set_idx)].append(node)
|
114
122
|
if num_qargs == 1 and node.name in ["rx", "x"]:
|
115
123
|
cancellation_sets[("x_rotation", wire, com_set_idx)].append(node)
|
@@ -130,7 +138,7 @@ class CommutativeCancellation(TransformationPass):
|
|
130
138
|
if cancel_set_key[0] == "z_rotation" and var_z_gate is None:
|
131
139
|
continue
|
132
140
|
set_len = len(cancellation_sets[cancel_set_key])
|
133
|
-
if set_len > 1 and cancel_set_key[0] in
|
141
|
+
if set_len > 1 and cancel_set_key[0] in self._gates:
|
134
142
|
gates_to_cancel = cancellation_sets[cancel_set_key]
|
135
143
|
for c_node in gates_to_cancel[: (set_len // 2) * 2]:
|
136
144
|
dag.remove_op_node(c_node)
|
@@ -142,31 +150,37 @@ class CommutativeCancellation(TransformationPass):
|
|
142
150
|
total_phase = 0.0
|
143
151
|
for current_node in run:
|
144
152
|
if (
|
145
|
-
|
153
|
+
current_node.condition is not None
|
146
154
|
or len(current_node.qargs) != 1
|
147
155
|
or current_node.qargs[0] != run_qarg
|
148
156
|
):
|
149
|
-
raise
|
157
|
+
raise RuntimeError("internal error")
|
150
158
|
|
151
159
|
if current_node.name in ["p", "u1", "rz", "rx"]:
|
152
|
-
current_angle = float(current_node.
|
160
|
+
current_angle = float(current_node.params[0])
|
153
161
|
elif current_node.name in ["z", "x"]:
|
154
162
|
current_angle = np.pi
|
155
163
|
elif current_node.name == "t":
|
156
164
|
current_angle = np.pi / 4
|
157
165
|
elif current_node.name == "s":
|
158
166
|
current_angle = np.pi / 2
|
167
|
+
else:
|
168
|
+
raise RuntimeError(
|
169
|
+
f"Angle for operation {current_node.name } is not defined"
|
170
|
+
)
|
159
171
|
|
160
172
|
# Compose gates
|
161
173
|
total_angle = current_angle + total_angle
|
162
|
-
if current_node.
|
163
|
-
total_phase += current_node.
|
174
|
+
if current_node.definition:
|
175
|
+
total_phase += current_node.definition.global_phase
|
164
176
|
|
165
177
|
# Replace the data of the first node in the run
|
166
178
|
if cancel_set_key[0] == "z_rotation":
|
167
179
|
new_op = var_z_gate(total_angle)
|
168
180
|
elif cancel_set_key[0] == "x_rotation":
|
169
181
|
new_op = RXGate(total_angle)
|
182
|
+
else:
|
183
|
+
raise RuntimeError("impossible case")
|
170
184
|
|
171
185
|
new_op_phase = 0
|
172
186
|
if np.mod(total_angle, (2 * np.pi)) > _CUTOFF_PRECISION:
|
@@ -198,7 +212,9 @@ class CommutativeCancellation(TransformationPass):
|
|
198
212
|
"""
|
199
213
|
|
200
214
|
pass_manager = PassManager([CommutationAnalysis(), self])
|
201
|
-
for node in dag.op_nodes(
|
215
|
+
for node in dag.op_nodes():
|
216
|
+
if node.name not in CONTROL_FLOW_OP_NAMES:
|
217
|
+
continue
|
202
218
|
mapped_blocks = []
|
203
219
|
for block in node.op.blocks:
|
204
220
|
new_circ = pass_manager.run(block)
|
@@ -24,10 +24,12 @@ from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
|
|
24
24
|
from qiskit.circuit.library.generalized_gates.unitary import UnitaryGate
|
25
25
|
from qiskit.circuit.library.standard_gates import CXGate
|
26
26
|
from qiskit.transpiler.basepasses import TransformationPass
|
27
|
-
from qiskit.circuit.controlflow import ControlFlowOp
|
28
27
|
from qiskit.transpiler.passmanager import PassManager
|
29
28
|
from qiskit.transpiler.passes.synthesis import unitary_synthesis
|
30
|
-
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
|
32
|
+
|
31
33
|
from .collect_1q_runs import Collect1qRuns
|
32
34
|
from .collect_2q_blocks import Collect2qBlocks
|
33
35
|
|
@@ -105,14 +107,14 @@ class ConsolidateBlocks(TransformationPass):
|
|
105
107
|
block_cargs = set()
|
106
108
|
for nd in block:
|
107
109
|
block_qargs |= set(nd.qargs)
|
108
|
-
if isinstance(nd, DAGOpNode) and getattr(nd
|
109
|
-
block_cargs |= set(getattr(nd
|
110
|
+
if isinstance(nd, DAGOpNode) and getattr(nd, "condition", None):
|
111
|
+
block_cargs |= set(getattr(nd, "condition", None)[0])
|
110
112
|
all_block_gates.add(nd)
|
111
113
|
block_index_map = self._block_qargs_to_indices(dag, block_qargs)
|
112
114
|
for nd in block:
|
113
|
-
if nd.
|
115
|
+
if nd.name == basis_gate_name:
|
114
116
|
basis_count += 1
|
115
|
-
if self._check_not_in_basis(dag, nd.
|
117
|
+
if self._check_not_in_basis(dag, nd.name, nd.qargs):
|
116
118
|
outside_basis = True
|
117
119
|
if len(block_qargs) > 2:
|
118
120
|
q = QuantumRegister(len(block_qargs))
|
@@ -124,7 +126,12 @@ class ConsolidateBlocks(TransformationPass):
|
|
124
126
|
qc.append(nd.op, [q[block_index_map[i]] for i in nd.qargs])
|
125
127
|
unitary = UnitaryGate(Operator(qc), check_input=False)
|
126
128
|
else:
|
127
|
-
|
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
|
128
135
|
unitary = UnitaryGate(matrix, check_input=False)
|
129
136
|
|
130
137
|
max_2q_depth = 20 # If depth > 20, there will be 1q gates to consolidate.
|
@@ -192,7 +199,9 @@ class ConsolidateBlocks(TransformationPass):
|
|
192
199
|
pass_manager.append(Collect2qBlocks())
|
193
200
|
|
194
201
|
pass_manager.append(self)
|
195
|
-
for node in dag.op_nodes(
|
202
|
+
for node in dag.op_nodes():
|
203
|
+
if node.name not in CONTROL_FLOW_OP_NAMES:
|
204
|
+
continue
|
196
205
|
node.op = node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks)
|
197
206
|
return dag
|
198
207
|
|
@@ -53,8 +53,8 @@ class InverseCancellation(TransformationPass):
|
|
53
53
|
)
|
54
54
|
else:
|
55
55
|
raise TranspilerError(
|
56
|
-
"InverseCancellation pass does not take input type {}. Input must be"
|
57
|
-
" a Gate."
|
56
|
+
f"InverseCancellation pass does not take input type {type(gates)}. Input must be"
|
57
|
+
" a Gate."
|
58
58
|
)
|
59
59
|
|
60
60
|
self.self_inverse_gates = []
|
@@ -112,15 +112,15 @@ class InverseCancellation(TransformationPass):
|
|
112
112
|
partitions = []
|
113
113
|
chunk = []
|
114
114
|
max_index = len(gate_cancel_run) - 1
|
115
|
-
for i in
|
116
|
-
if
|
117
|
-
chunk.append(
|
115
|
+
for i, cancel_gate in enumerate(gate_cancel_run):
|
116
|
+
if cancel_gate.op == gate:
|
117
|
+
chunk.append(cancel_gate)
|
118
118
|
else:
|
119
119
|
if chunk:
|
120
120
|
partitions.append(chunk)
|
121
121
|
chunk = []
|
122
122
|
continue
|
123
|
-
if i == max_index or
|
123
|
+
if i == max_index or cancel_gate.qargs != gate_cancel_run[i + 1].qargs:
|
124
124
|
partitions.append(chunk)
|
125
125
|
chunk = []
|
126
126
|
# Remove an even number of gates from each chunk
|
@@ -33,6 +33,7 @@ from qiskit.circuit.library.standard_gates import (
|
|
33
33
|
XGate,
|
34
34
|
)
|
35
35
|
from qiskit.circuit import Qubit
|
36
|
+
from qiskit.circuit.quantumcircuitdata import CircuitInstruction
|
36
37
|
from qiskit.dagcircuit.dagcircuit import DAGCircuit
|
37
38
|
from qiskit.dagcircuit.dagnode import DAGOpNode
|
38
39
|
|
@@ -110,16 +111,7 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
110
111
|
else:
|
111
112
|
return None
|
112
113
|
|
113
|
-
def
|
114
|
-
"""
|
115
|
-
Re-synthesizes one 2x2 `matrix`, typically extracted via `dag.collect_1q_runs`.
|
116
|
-
|
117
|
-
Returns the newly synthesized circuit in the indicated basis, or None
|
118
|
-
if no synthesis routine applied.
|
119
|
-
|
120
|
-
When multiple synthesis options are available, it prefers the one with the lowest
|
121
|
-
error when the circuit is applied to `qubit`.
|
122
|
-
"""
|
114
|
+
def _get_decomposer(self, qubit=None):
|
123
115
|
# include path for when target exists but target.num_qubits is None (BasicSimulator)
|
124
116
|
if self._target is not None and self._target.num_qubits is not None:
|
125
117
|
if qubit is not None:
|
@@ -133,6 +125,19 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
133
125
|
decomposers = _possible_decomposers(available_1q_basis)
|
134
126
|
else:
|
135
127
|
decomposers = self._global_decomposers
|
128
|
+
return decomposers
|
129
|
+
|
130
|
+
def _resynthesize_run(self, matrix, qubit=None):
|
131
|
+
"""
|
132
|
+
Re-synthesizes one 2x2 `matrix`, typically extracted via `dag.collect_1q_runs`.
|
133
|
+
|
134
|
+
Returns the newly synthesized circuit in the indicated basis, or None
|
135
|
+
if no synthesis routine applied.
|
136
|
+
|
137
|
+
When multiple synthesis options are available, it prefers the one with the lowest
|
138
|
+
error when the circuit is applied to `qubit`.
|
139
|
+
"""
|
140
|
+
decomposers = self._get_decomposer(qubit)
|
136
141
|
|
137
142
|
best_synth_circuit = euler_one_qubit_decomposer.unitary_to_gate_sequence(
|
138
143
|
matrix,
|
@@ -149,10 +154,13 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
149
154
|
out_dag.global_phase = best_synth_circuit.global_phase
|
150
155
|
|
151
156
|
for gate_name, angles in best_synth_circuit:
|
152
|
-
|
157
|
+
op = CircuitInstruction.from_standard(gate_name, qubits, angles)
|
158
|
+
out_dag.apply_operation_back(op.operation, qubits, check=False)
|
153
159
|
return out_dag
|
154
160
|
|
155
|
-
def _substitution_checks(
|
161
|
+
def _substitution_checks(
|
162
|
+
self, dag, old_run, new_circ, basis, qubit, old_error=None, new_error=None
|
163
|
+
):
|
156
164
|
"""
|
157
165
|
Returns `True` when it is recommended to replace `old_run` with `new_circ` over `basis`.
|
158
166
|
"""
|
@@ -176,11 +184,14 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
176
184
|
# if we're outside of the basis set, we're obligated to logically decompose.
|
177
185
|
# if we're outside of the set of gates for which we have physical definitions,
|
178
186
|
# then we _try_ to decompose, using the results if we see improvement.
|
179
|
-
new_error = 0.0
|
180
|
-
old_error = 0.0
|
181
187
|
if not uncalibrated_and_not_basis_p:
|
182
|
-
new_error
|
183
|
-
|
188
|
+
if new_error is None:
|
189
|
+
new_error = self._error(new_circ, qubit)
|
190
|
+
if old_error is None:
|
191
|
+
old_error = self._error(old_run, qubit)
|
192
|
+
else:
|
193
|
+
new_error = 0.0
|
194
|
+
old_error = 0.0
|
184
195
|
|
185
196
|
return (
|
186
197
|
uncalibrated_and_not_basis_p
|
@@ -198,32 +209,47 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
198
209
|
Returns:
|
199
210
|
DAGCircuit: the optimized DAG.
|
200
211
|
"""
|
201
|
-
runs =
|
202
|
-
|
212
|
+
runs = []
|
213
|
+
qubits = []
|
214
|
+
bases = []
|
215
|
+
for run in dag.collect_1q_runs():
|
203
216
|
qubit = dag.find_bit(run[0].qargs[0]).index
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
217
|
+
runs.append(run)
|
218
|
+
qubits.append(qubit)
|
219
|
+
bases.append(self._get_decomposer(qubit))
|
220
|
+
best_sequences = euler_one_qubit_decomposer.optimize_1q_gates_decomposition(
|
221
|
+
runs, qubits, bases, simplify=True, error_map=self.error_map
|
222
|
+
)
|
223
|
+
for index, best_circuit_sequence in enumerate(best_sequences):
|
224
|
+
run = runs[index]
|
225
|
+
qubit = qubits[index]
|
209
226
|
if self._target is None:
|
210
227
|
basis = self._basis_gates
|
211
228
|
else:
|
212
229
|
basis = self._target.operation_names_for_qargs((qubit,))
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
230
|
+
if best_circuit_sequence is not None:
|
231
|
+
(old_error, new_error, best_circuit_sequence) = best_circuit_sequence
|
232
|
+
if self._substitution_checks(
|
233
|
+
dag,
|
234
|
+
run,
|
235
|
+
best_circuit_sequence,
|
236
|
+
basis,
|
237
|
+
qubit,
|
238
|
+
old_error=old_error,
|
239
|
+
new_error=new_error,
|
240
|
+
):
|
241
|
+
first_node_id = run[0]._node_id
|
242
|
+
qubit = run[0].qargs
|
243
|
+
for gate, angles in best_circuit_sequence:
|
244
|
+
op = CircuitInstruction.from_standard(gate, qubit, angles)
|
245
|
+
node = DAGOpNode.from_instruction(op, dag=dag)
|
246
|
+
node._node_id = dag._multi_graph.add_node(node)
|
247
|
+
dag._increment_op(gate.name)
|
248
|
+
dag._multi_graph.insert_node_on_in_edges(node._node_id, first_node_id)
|
249
|
+
dag.global_phase += best_circuit_sequence.global_phase
|
250
|
+
# Delete the other nodes in the run
|
251
|
+
for current_node in run:
|
252
|
+
dag.remove_op_node(current_node)
|
227
253
|
|
228
254
|
return dag
|
229
255
|
|
@@ -241,10 +267,7 @@ class Optimize1qGatesDecomposition(TransformationPass):
|
|
241
267
|
circuit, qubit, self.error_map
|
242
268
|
)
|
243
269
|
else:
|
244
|
-
|
245
|
-
return euler_one_qubit_decomposer.compute_error_list(
|
246
|
-
circuit_list, qubit, self.error_map
|
247
|
-
)
|
270
|
+
return euler_one_qubit_decomposer.compute_error_list(circuit, qubit, self.error_map)
|
248
271
|
|
249
272
|
|
250
273
|
def _possible_decomposers(basis_set):
|
@@ -308,7 +308,7 @@ class Optimize1qGates(TransformationPass):
|
|
308
308
|
if "u3" in self.basis:
|
309
309
|
new_op = U3Gate(*right_parameters)
|
310
310
|
else:
|
311
|
-
raise TranspilerError("It was not possible to use the basis
|
311
|
+
raise TranspilerError(f"It was not possible to use the basis {self.basis}")
|
312
312
|
|
313
313
|
dag.global_phase += right_global_phase
|
314
314
|
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# This code is part of Qiskit.
|
2
|
+
#
|
3
|
+
# (C) Copyright IBM 2017, 2024.
|
4
|
+
#
|
5
|
+
# This code is licensed under the Apache License, Version 2.0. You may
|
6
|
+
# obtain a copy of this license in the LICENSE.txt file in the root directory
|
7
|
+
# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
|
8
|
+
#
|
9
|
+
# Any modifications or derivative works of this code must retain this
|
10
|
+
# copyright notice, and modified files need to carry a notice indicating
|
11
|
+
# that they have been altered from the originals.
|
12
|
+
"""Splits each two-qubit gate in the `dag` into two single-qubit gates, if possible without error."""
|
13
|
+
from typing import Optional
|
14
|
+
|
15
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
16
|
+
from qiskit.circuit.quantumcircuitdata import CircuitInstruction
|
17
|
+
from qiskit.dagcircuit.dagcircuit import DAGCircuit, DAGOpNode
|
18
|
+
from qiskit.circuit.library.generalized_gates import UnitaryGate
|
19
|
+
from qiskit.synthesis.two_qubit.two_qubit_decompose import TwoQubitWeylDecomposition
|
20
|
+
|
21
|
+
|
22
|
+
class Split2QUnitaries(TransformationPass):
|
23
|
+
"""Attempt to splits two-qubit gates in a :class:`.DAGCircuit` into two single-qubit gates
|
24
|
+
|
25
|
+
This pass will analyze all the two qubit gates in the circuit and analyze the gate's unitary
|
26
|
+
matrix to determine if the gate is actually a product of 2 single qubit gates. In these
|
27
|
+
cases the 2q gate can be simplified into two single qubit gates and this pass will
|
28
|
+
perform this optimization and will replace the two qubit gate with two single qubit
|
29
|
+
:class:`.UnitaryGate`.
|
30
|
+
"""
|
31
|
+
|
32
|
+
def __init__(self, fidelity: Optional[float] = 1.0 - 1e-16):
|
33
|
+
"""Split2QUnitaries initializer.
|
34
|
+
|
35
|
+
Args:
|
36
|
+
fidelity (float): Allowed tolerance for splitting two-qubit unitaries and gate decompositions
|
37
|
+
"""
|
38
|
+
super().__init__()
|
39
|
+
self.requested_fidelity = fidelity
|
40
|
+
|
41
|
+
def run(self, dag: DAGCircuit):
|
42
|
+
"""Run the Split2QUnitaries pass on `dag`."""
|
43
|
+
for node in dag.topological_op_nodes():
|
44
|
+
# skip operations without two-qubits and for which we can not determine a potential 1q split
|
45
|
+
if (
|
46
|
+
len(node.cargs) > 0
|
47
|
+
or len(node.qargs) != 2
|
48
|
+
or node.matrix is None
|
49
|
+
or node.is_parameterized()
|
50
|
+
):
|
51
|
+
continue
|
52
|
+
|
53
|
+
decomp = TwoQubitWeylDecomposition(node.op, fidelity=self.requested_fidelity)
|
54
|
+
if (
|
55
|
+
decomp._inner_decomposition.specialization
|
56
|
+
== TwoQubitWeylDecomposition._specializations.IdEquiv
|
57
|
+
):
|
58
|
+
new_dag = DAGCircuit()
|
59
|
+
new_dag.add_qubits(node.qargs)
|
60
|
+
|
61
|
+
ur = decomp.K1r
|
62
|
+
ur_node = DAGOpNode.from_instruction(
|
63
|
+
CircuitInstruction(UnitaryGate(ur), qubits=(node.qargs[0],)), dag=new_dag
|
64
|
+
)
|
65
|
+
|
66
|
+
ul = decomp.K1l
|
67
|
+
ul_node = DAGOpNode.from_instruction(
|
68
|
+
CircuitInstruction(UnitaryGate(ul), qubits=(node.qargs[1],)), dag=new_dag
|
69
|
+
)
|
70
|
+
new_dag._apply_op_node_back(ur_node)
|
71
|
+
new_dag._apply_op_node_back(ul_node)
|
72
|
+
new_dag.global_phase = decomp.global_phase
|
73
|
+
dag.substitute_node_with_dag(node, new_dag)
|
74
|
+
elif (
|
75
|
+
decomp._inner_decomposition.specialization
|
76
|
+
== TwoQubitWeylDecomposition._specializations.SWAPEquiv
|
77
|
+
):
|
78
|
+
# TODO maybe also look into swap-gate-like gates? Things to consider:
|
79
|
+
# * As the qubit mapping may change, we'll always need to build a new dag in this pass
|
80
|
+
# * There may not be many swap-gate-like gates in an arbitrary input circuit
|
81
|
+
# * Removing swap gates from a user-routed input circuit here is unexpected
|
82
|
+
pass
|
83
|
+
return dag
|
@@ -622,7 +622,7 @@ class BackwardMatch:
|
|
622
622
|
)
|
623
623
|
self.matching_list.append_scenario(new_matching_scenario)
|
624
624
|
|
625
|
-
# Third option: if blocking the
|
625
|
+
# Third option: if blocking the successors breaks a match, we consider
|
626
626
|
# also the possibility to block all predecessors (push the gate to the left).
|
627
627
|
if broken_matches and all(global_broken):
|
628
628
|
|
@@ -507,7 +507,7 @@ class TemplateSubstitution:
|
|
507
507
|
to_native_symbolic = lambda x: x
|
508
508
|
|
509
509
|
circuit_params, template_params = [], []
|
510
|
-
# Set of all parameter names that are present in the circuits to be
|
510
|
+
# Set of all parameter names that are present in the circuits to be optimized.
|
511
511
|
circuit_params_set = set()
|
512
512
|
|
513
513
|
template_dag_dep = copy.deepcopy(self.template_dag_dep)
|
@@ -17,8 +17,9 @@ from collections import defaultdict
|
|
17
17
|
from qiskit.circuit import Gate, QuantumCircuit, Qubit
|
18
18
|
from qiskit.converters import circuit_to_dag
|
19
19
|
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
20
|
-
from qiskit.transpiler import TransformationPass
|
21
|
-
|
20
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
21
|
+
from qiskit.transpiler.exceptions import TranspilerError
|
22
|
+
from qiskit.transpiler.layout import Layout
|
22
23
|
from qiskit.transpiler.passes.routing.commuting_2q_gate_routing.swap_strategy import SwapStrategy
|
23
24
|
from qiskit.transpiler.passes.routing.commuting_2q_gate_routing.commuting_2q_block import (
|
24
25
|
Commuting2qBlock,
|
@@ -15,9 +15,10 @@ from __future__ import annotations
|
|
15
15
|
|
16
16
|
import numpy as np
|
17
17
|
|
18
|
-
from qiskit.transpiler import Layout, CouplingMap
|
19
18
|
from qiskit.transpiler.basepasses import TransformationPass
|
19
|
+
from qiskit.transpiler.coupling import CouplingMap
|
20
20
|
from qiskit.transpiler.exceptions import TranspilerError
|
21
|
+
from qiskit.transpiler.layout import Layout
|
21
22
|
from qiskit.transpiler.passes.routing.algorithms import ApproximateTokenSwapper
|
22
23
|
from qiskit.transpiler.target import Target
|
23
24
|
|