qiskit 1.1.2__cp38-abi3-win32.whl → 1.2.0__cp38-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 +27 -24
- qiskit/_accelerate.pyd +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
@@ -18,7 +18,7 @@ import time
|
|
18
18
|
|
19
19
|
import rustworkx
|
20
20
|
|
21
|
-
from qiskit.circuit import SwitchCaseOp,
|
21
|
+
from qiskit.circuit import SwitchCaseOp, Clbit, ClassicalRegister
|
22
22
|
from qiskit.circuit.library.standard_gates import SwapGate
|
23
23
|
from qiskit.circuit.controlflow import condition_resources, node_resources
|
24
24
|
from qiskit.converters import dag_to_circuit
|
@@ -28,15 +28,10 @@ from qiskit.transpiler.exceptions import TranspilerError
|
|
28
28
|
from qiskit.transpiler.layout import Layout
|
29
29
|
from qiskit.transpiler.target import Target
|
30
30
|
from qiskit.transpiler.passes.layout import disjoint_utils
|
31
|
-
from qiskit.dagcircuit import DAGCircuit
|
31
|
+
from qiskit.dagcircuit import DAGCircuit, DAGOpNode
|
32
32
|
from qiskit.utils.parallel import CPU_COUNT
|
33
33
|
|
34
|
-
from qiskit._accelerate.sabre import
|
35
|
-
sabre_routing,
|
36
|
-
Heuristic,
|
37
|
-
NeighborTable,
|
38
|
-
SabreDAG,
|
39
|
-
)
|
34
|
+
from qiskit._accelerate.sabre import sabre_routing, Heuristic, SetScaling, NeighborTable, SabreDAG
|
40
35
|
from qiskit._accelerate.nlayout import NLayout
|
41
36
|
|
42
37
|
logger = logging.getLogger(__name__)
|
@@ -211,14 +206,27 @@ class SabreSwap(TransformationPass):
|
|
211
206
|
" This circuit cannot be routed to this device."
|
212
207
|
)
|
213
208
|
|
214
|
-
if self.heuristic
|
215
|
-
heuristic =
|
209
|
+
if isinstance(self.heuristic, Heuristic):
|
210
|
+
heuristic = self.heuristic
|
211
|
+
elif self.heuristic == "basic":
|
212
|
+
heuristic = Heuristic(attempt_limit=10 * num_dag_qubits).with_basic(
|
213
|
+
1.0, SetScaling.Size
|
214
|
+
)
|
216
215
|
elif self.heuristic == "lookahead":
|
217
|
-
heuristic =
|
216
|
+
heuristic = (
|
217
|
+
Heuristic(attempt_limit=10 * num_dag_qubits)
|
218
|
+
.with_basic(1.0, SetScaling.Size)
|
219
|
+
.with_lookahead(0.5, 20, SetScaling.Size)
|
220
|
+
)
|
218
221
|
elif self.heuristic == "decay":
|
219
|
-
heuristic =
|
222
|
+
heuristic = (
|
223
|
+
Heuristic(attempt_limit=10 * num_dag_qubits)
|
224
|
+
.with_basic(1.0, SetScaling.Size)
|
225
|
+
.with_lookahead(0.5, 20, SetScaling.Size)
|
226
|
+
.with_decay(0.001, 5)
|
227
|
+
)
|
220
228
|
else:
|
221
|
-
raise TranspilerError("Heuristic
|
229
|
+
raise TranspilerError(f"Heuristic {self.heuristic} not recognized.")
|
222
230
|
disjoint_utils.require_layout_isolated_to_component(
|
223
231
|
dag, self.coupling_map if self.target is None else self.target
|
224
232
|
)
|
@@ -289,9 +297,9 @@ def _build_sabre_dag(dag, num_physical_qubits, qubit_indices):
|
|
289
297
|
node_blocks = {}
|
290
298
|
for node in block_dag.topological_op_nodes():
|
291
299
|
cargs_bits = set(node.cargs)
|
292
|
-
if node.
|
293
|
-
cargs_bits.update(condition_resources(node.
|
294
|
-
if isinstance(node.op, SwitchCaseOp):
|
300
|
+
if node.condition is not None:
|
301
|
+
cargs_bits.update(condition_resources(node.condition).clbits)
|
302
|
+
if node.is_control_flow() and isinstance(node.op, SwitchCaseOp):
|
295
303
|
target = node.op.target
|
296
304
|
if isinstance(target, Clbit):
|
297
305
|
cargs_bits.add(target)
|
@@ -300,7 +308,7 @@ def _build_sabre_dag(dag, num_physical_qubits, qubit_indices):
|
|
300
308
|
else: # Expr
|
301
309
|
cargs_bits.update(node_resources(target).clbits)
|
302
310
|
cargs = {block_dag.find_bit(x).index for x in cargs_bits}
|
303
|
-
if
|
311
|
+
if node.is_control_flow():
|
304
312
|
node_blocks[node._node_id] = [
|
305
313
|
recurse(
|
306
314
|
block,
|
@@ -313,7 +321,7 @@ def _build_sabre_dag(dag, num_physical_qubits, qubit_indices):
|
|
313
321
|
node._node_id,
|
314
322
|
[wire_map[x] for x in node.qargs],
|
315
323
|
cargs,
|
316
|
-
|
324
|
+
node.is_directive(),
|
317
325
|
)
|
318
326
|
)
|
319
327
|
return SabreDAG(num_physical_qubits, block_dag.num_clbits(), dag_list, node_blocks)
|
@@ -383,14 +391,15 @@ def _apply_sabre_result(
|
|
383
391
|
node = source_dag._multi_graph[node_id]
|
384
392
|
if node_id in swap_map:
|
385
393
|
apply_swaps(dest_dag, swap_map[node_id], layout)
|
386
|
-
if not
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
+
if not node.is_control_flow():
|
395
|
+
qubits = [
|
396
|
+
physical_qubits[layout.virtual_to_physical(root_logical_map[q])]
|
397
|
+
for q in node.qargs
|
398
|
+
]
|
399
|
+
dest_dag._apply_op_node_back(
|
400
|
+
DAGOpNode.from_instruction(
|
401
|
+
node._to_circuit_instruction().replace(qubits=qubits)
|
402
|
+
),
|
394
403
|
check=False,
|
395
404
|
)
|
396
405
|
continue
|
@@ -14,11 +14,15 @@
|
|
14
14
|
from typing import Iterable, Union, Optional, List, Tuple
|
15
15
|
from math import floor, log10
|
16
16
|
|
17
|
-
from qiskit.circuit import Barrier
|
17
|
+
from qiskit.circuit import SwitchCaseOp, Clbit, ClassicalRegister, Barrier
|
18
|
+
from qiskit.circuit.controlflow import condition_resources, node_resources
|
18
19
|
from qiskit.dagcircuit import DAGOpNode, DAGDepNode, DAGDependency, DAGCircuit
|
19
|
-
from qiskit.transpiler import Layout
|
20
20
|
from qiskit.transpiler.basepasses import TransformationPass
|
21
|
-
from qiskit.
|
21
|
+
from qiskit.transpiler.layout import Layout
|
22
|
+
from qiskit.transpiler.passes.routing.sabre_swap import _build_sabre_dag, _apply_sabre_result
|
23
|
+
|
24
|
+
from qiskit._accelerate import star_prerouting
|
25
|
+
from qiskit._accelerate.nlayout import NLayout
|
22
26
|
|
23
27
|
|
24
28
|
class StarBlock:
|
@@ -260,7 +264,7 @@ class StarPreRouting(TransformationPass):
|
|
260
264
|
# star block by a linear sequence of gates
|
261
265
|
new_dag, qubit_mapping = self.star_preroute(dag, star_blocks, processing_order)
|
262
266
|
|
263
|
-
# Fix output
|
267
|
+
# Fix output permutation -- copied from ElidePermutations
|
264
268
|
input_qubit_mapping = {qubit: index for index, qubit in enumerate(dag.qubits)}
|
265
269
|
self.property_set["original_layout"] = Layout(input_qubit_mapping)
|
266
270
|
if self.property_set["original_qubit_indices"] is None:
|
@@ -305,113 +309,84 @@ class StarPreRouting(TransformationPass):
|
|
305
309
|
new_dag: a dag specifying the pre-routed circuit
|
306
310
|
qubit_mapping: the final qubit mapping after pre-routing
|
307
311
|
"""
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
is_first_star = True
|
321
|
-
last_2q_gate = [
|
322
|
-
op
|
323
|
-
for op in reversed(processing_order)
|
324
|
-
if ((len(op.qargs) > 1) and (op.name != "barrier"))
|
312
|
+
# Convert the DAG to a SabreDAG
|
313
|
+
num_qubits = len(dag.qubits)
|
314
|
+
canonical_register = dag.qregs["q"]
|
315
|
+
current_layout = Layout.generate_trivial_layout(canonical_register)
|
316
|
+
qubit_indices = {bit: idx for idx, bit in enumerate(canonical_register)}
|
317
|
+
layout_mapping = {qubit_indices[k]: v for k, v in current_layout.get_virtual_bits().items()}
|
318
|
+
initial_layout = NLayout(layout_mapping, num_qubits, num_qubits)
|
319
|
+
sabre_dag, circuit_to_dag_dict = _build_sabre_dag(dag, num_qubits, qubit_indices)
|
320
|
+
|
321
|
+
# Extract the nodes from the blocks for the Rust representation
|
322
|
+
rust_blocks = [
|
323
|
+
(block.center is not None, _extract_nodes(block.get_nodes(), dag)) for block in blocks
|
325
324
|
]
|
326
|
-
if len(last_2q_gate) > 0:
|
327
|
-
last_2q_gate = last_2q_gate[0]
|
328
|
-
else:
|
329
|
-
last_2q_gate = None
|
330
325
|
|
326
|
+
# Determine the processing order of the nodes in the DAG for the Rust representation
|
331
327
|
int_digits = floor(log10(len(processing_order))) + 1
|
332
328
|
processing_order_index_map = {
|
333
|
-
node: f"a{
|
334
|
-
for index, node in enumerate(processing_order)
|
329
|
+
node: f"a{index:0{int_digits}}" for index, node in enumerate(processing_order)
|
335
330
|
}
|
336
331
|
|
337
332
|
def tie_breaker_key(node):
|
338
333
|
return processing_order_index_map.get(node, node.sort_key)
|
339
334
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
)
|
399
|
-
# Swap mapping
|
400
|
-
index_0 = dag.find_bit(inner_node.qargs[0]).index
|
401
|
-
index_1 = dag.find_bit(inner_node.qargs[1]).index
|
402
|
-
qubit_mapping[index_1], qubit_mapping[index_0] = (
|
403
|
-
qubit_mapping[index_0],
|
404
|
-
qubit_mapping[index_1],
|
405
|
-
)
|
406
|
-
|
407
|
-
prev = inner_node.qargs
|
408
|
-
is_first_star = False
|
409
|
-
else:
|
410
|
-
# the node is not part of a block
|
411
|
-
new_dag.apply_operation_back(
|
412
|
-
node.op,
|
413
|
-
_apply_mapping(node.qargs, qubit_mapping, dag.qubits),
|
414
|
-
node.cargs,
|
415
|
-
check=False,
|
416
|
-
)
|
417
|
-
return new_dag, qubit_mapping
|
335
|
+
rust_processing_order = _extract_nodes(dag.topological_op_nodes(key=tie_breaker_key), dag)
|
336
|
+
|
337
|
+
# Run the star prerouting algorithm to obtain the new DAG and qubit mapping
|
338
|
+
*sabre_result, qubit_mapping = star_prerouting.star_preroute(
|
339
|
+
sabre_dag, rust_blocks, rust_processing_order
|
340
|
+
)
|
341
|
+
|
342
|
+
res_dag = _apply_sabre_result(
|
343
|
+
dag.copy_empty_like(),
|
344
|
+
dag,
|
345
|
+
sabre_result,
|
346
|
+
initial_layout,
|
347
|
+
dag.qubits,
|
348
|
+
circuit_to_dag_dict,
|
349
|
+
)
|
350
|
+
|
351
|
+
return res_dag, qubit_mapping
|
352
|
+
|
353
|
+
|
354
|
+
def _extract_nodes(nodes, dag):
|
355
|
+
"""Extract and format node information for Rust representation used in SabreDAG.
|
356
|
+
|
357
|
+
Each node is represented as a tuple containing:
|
358
|
+
- Node ID (int): The unique identifier of the node in the DAG.
|
359
|
+
- Qubit indices (list of int): Indices of qubits involved in the node's operation.
|
360
|
+
- Classical bit indices (set of int): Indices of classical bits involved in the node's operation.
|
361
|
+
- Directive flag (bool): Indicates whether the operation is a directive (True) or not (False).
|
362
|
+
|
363
|
+
Args:
|
364
|
+
nodes (list[DAGOpNode]): List of DAGOpNode objects to extract information from.
|
365
|
+
dag (DAGCircuit): DAGCircuit object containing the circuit structure.
|
366
|
+
|
367
|
+
Returns:
|
368
|
+
list of tuples: Each tuple contains information about a node in the format described above.
|
369
|
+
"""
|
370
|
+
extracted_node_info = []
|
371
|
+
for node in nodes:
|
372
|
+
qubit_indices = [dag.find_bit(qubit).index for qubit in node.qargs]
|
373
|
+
classical_bit_indices = set()
|
374
|
+
|
375
|
+
if node.op.condition is not None:
|
376
|
+
classical_bit_indices.update(condition_resources(node.op.condition).clbits)
|
377
|
+
|
378
|
+
if isinstance(node.op, SwitchCaseOp):
|
379
|
+
switch_case_target = node.op.target
|
380
|
+
if isinstance(switch_case_target, Clbit):
|
381
|
+
classical_bit_indices.add(switch_case_target)
|
382
|
+
elif isinstance(switch_case_target, ClassicalRegister):
|
383
|
+
classical_bit_indices.update(switch_case_target)
|
384
|
+
else: # Assume target is an expression involving classical bits
|
385
|
+
classical_bit_indices.update(node_resources(switch_case_target).clbits)
|
386
|
+
|
387
|
+
is_directive = getattr(node.op, "_directive", False)
|
388
|
+
extracted_node_info.append(
|
389
|
+
(node._node_id, qubit_indices, classical_bit_indices, is_directive)
|
390
|
+
)
|
391
|
+
|
392
|
+
return extracted_node_info
|
@@ -357,9 +357,7 @@ class StochasticSwap(TransformationPass):
|
|
357
357
|
|
358
358
|
# Give up if we fail again
|
359
359
|
if not success_flag:
|
360
|
-
raise TranspilerError(
|
361
|
-
"swap mapper failed: " + "layer %d, sublayer %d" % (i, j)
|
362
|
-
)
|
360
|
+
raise TranspilerError(f"swap mapper failed: layer {i}, sublayer {j}")
|
363
361
|
|
364
362
|
# Update the record of qubit positions
|
365
363
|
# for each inner iteration
|
@@ -15,10 +15,9 @@
|
|
15
15
|
from qiskit.circuit import Delay, Qubit, Measure
|
16
16
|
from qiskit.dagcircuit import DAGCircuit
|
17
17
|
from qiskit.transpiler.exceptions import TranspilerError
|
18
|
+
from qiskit.transpiler.passes.scheduling.base_scheduler import BaseSchedulerTransform
|
18
19
|
from qiskit.utils.deprecation import deprecate_func
|
19
20
|
|
20
|
-
from .base_scheduler import BaseSchedulerTransform
|
21
|
-
|
22
21
|
|
23
22
|
class ALAPSchedule(BaseSchedulerTransform):
|
24
23
|
"""ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible.
|
@@ -44,7 +44,7 @@ Pulse alignment constraint
|
|
44
44
|
multiple of this value. Violation of this constraint may result in the
|
45
45
|
backend execution failure.
|
46
46
|
|
47
|
-
In most of the
|
47
|
+
In most of the scenarios, the scheduled start time of ``DAGOpNode`` corresponds to the
|
48
48
|
start time of the underlying pulse instruction composing the node operation.
|
49
49
|
However, this assumption can be intentionally broken by defining a pulse gate,
|
50
50
|
i.e. calibration, with the schedule involving pre-buffer, i.e. some random pulse delay
|
@@ -62,7 +62,7 @@ Granularity constraint
|
|
62
62
|
This value is reported by ``timing_constraints["granularity"]`` in the backend
|
63
63
|
configuration in units of dt. This is the constraint for a single pulse :class:`Play`
|
64
64
|
instruction that may constitute your pulse gate.
|
65
|
-
The length of waveform samples should be
|
65
|
+
The length of waveform samples should be multiple of this constraint value.
|
66
66
|
Violation of this constraint may result in failue in backend execution.
|
67
67
|
|
68
68
|
Minimum pulse length constraint
|
@@ -14,7 +14,7 @@
|
|
14
14
|
from qiskit.circuit.delay import Delay
|
15
15
|
from qiskit.dagcircuit import DAGCircuit
|
16
16
|
from qiskit.transpiler.basepasses import AnalysisPass
|
17
|
-
from qiskit.transpiler import Target
|
17
|
+
from qiskit.transpiler.target import Target
|
18
18
|
|
19
19
|
|
20
20
|
class InstructionDurationCheck(AnalysisPass):
|
@@ -16,7 +16,7 @@ from qiskit.dagcircuit import DAGCircuit
|
|
16
16
|
from qiskit.pulse import Play
|
17
17
|
from qiskit.transpiler.basepasses import AnalysisPass
|
18
18
|
from qiskit.transpiler.exceptions import TranspilerError
|
19
|
-
from qiskit.transpiler import Target
|
19
|
+
from qiskit.transpiler.target import Target
|
20
20
|
|
21
21
|
|
22
22
|
class ValidatePulseGates(AnalysisPass):
|
@@ -31,7 +31,7 @@ class ValidatePulseGates(AnalysisPass):
|
|
31
31
|
|
32
32
|
In Qiskit SDK, we can define the pulse-level implementation of custom quantum gate
|
33
33
|
instructions, as a `pulse gate
|
34
|
-
<https://docs.quantum.ibm.com/
|
34
|
+
<https://docs.quantum.ibm.com/guides/pulse>`__,
|
35
35
|
thus user gates should satisfy all waveform memory constraints imposed by the backend.
|
36
36
|
|
37
37
|
This pass validates all attached calibration entries and raises ``TranspilerError`` to
|
@@ -21,7 +21,7 @@ from qiskit.circuit.reset import Reset
|
|
21
21
|
from qiskit.dagcircuit import DAGCircuit, DAGOpNode, DAGOutNode
|
22
22
|
from qiskit.transpiler.basepasses import AnalysisPass
|
23
23
|
from qiskit.transpiler.exceptions import TranspilerError
|
24
|
-
from qiskit.transpiler import Target
|
24
|
+
from qiskit.transpiler.target import Target
|
25
25
|
|
26
26
|
|
27
27
|
class ConstrainedReschedule(AnalysisPass):
|
@@ -15,10 +15,9 @@
|
|
15
15
|
from qiskit.circuit import Delay, Qubit, Measure
|
16
16
|
from qiskit.dagcircuit import DAGCircuit
|
17
17
|
from qiskit.transpiler.exceptions import TranspilerError
|
18
|
+
from qiskit.transpiler.passes.scheduling.base_scheduler import BaseSchedulerTransform
|
18
19
|
from qiskit.utils.deprecation import deprecate_func
|
19
20
|
|
20
|
-
from .base_scheduler import BaseSchedulerTransform
|
21
|
-
|
22
21
|
|
23
22
|
class ASAPSchedule(BaseSchedulerTransform):
|
24
23
|
"""ASAP Scheduling pass, which schedules the start time of instructions as early as possible..
|
@@ -13,13 +13,13 @@
|
|
13
13
|
"""Base circuit scheduling pass."""
|
14
14
|
import warnings
|
15
15
|
|
16
|
-
from qiskit.transpiler import InstructionDurations
|
17
|
-
from qiskit.transpiler.basepasses import TransformationPass
|
18
|
-
from qiskit.transpiler.passes.scheduling.time_unit_conversion import TimeUnitConversion
|
19
|
-
from qiskit.dagcircuit import DAGOpNode, DAGCircuit, DAGOutNode
|
20
16
|
from qiskit.circuit import Delay, Gate, Measure, Reset
|
21
17
|
from qiskit.circuit.parameterexpression import ParameterExpression
|
18
|
+
from qiskit.dagcircuit import DAGOpNode, DAGCircuit, DAGOutNode
|
19
|
+
from qiskit.transpiler.basepasses import TransformationPass
|
22
20
|
from qiskit.transpiler.exceptions import TranspilerError
|
21
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
22
|
+
from qiskit.transpiler.passes.scheduling.time_unit_conversion import TimeUnitConversion
|
23
23
|
from qiskit.transpiler.target import Target
|
24
24
|
|
25
25
|
|
@@ -68,7 +68,7 @@ class BaseSchedulerTransform(TransformationPass):
|
|
68
68
|
However, such optimization should be done by another pass,
|
69
69
|
otherwise scheduling may break topological ordering of the original circuit.
|
70
70
|
|
71
|
-
Realistic control flow scheduling respecting for
|
71
|
+
Realistic control flow scheduling respecting for microarchitecture
|
72
72
|
|
73
73
|
In the dispersive QND readout scheme, qubit is measured with microwave stimulus to qubit (Q)
|
74
74
|
followed by resonator ring-down (depopulation). This microwave signal is recorded
|
@@ -20,10 +20,10 @@ from qiskit.circuit.library.standard_gates import IGate, UGate, U3Gate
|
|
20
20
|
from qiskit.dagcircuit import DAGOpNode, DAGInNode
|
21
21
|
from qiskit.quantum_info.operators.predicates import matrix_equal
|
22
22
|
from qiskit.synthesis.one_qubit import OneQubitEulerDecomposer
|
23
|
-
from qiskit.transpiler import InstructionDurations
|
24
|
-
from qiskit.transpiler.passes.optimization import Optimize1qGates
|
25
23
|
from qiskit.transpiler.basepasses import TransformationPass
|
26
24
|
from qiskit.transpiler.exceptions import TranspilerError
|
25
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
26
|
+
from qiskit.transpiler.passes.optimization import Optimize1qGates
|
27
27
|
from qiskit.utils.deprecation import deprecate_func
|
28
28
|
|
29
29
|
|
@@ -130,7 +130,7 @@ class DynamicalDecoupling(TransformationPass):
|
|
130
130
|
will be used [d/2, d, d, ..., d, d, d/2].
|
131
131
|
skip_reset_qubits (bool): if True, does not insert DD on idle
|
132
132
|
periods that immediately follow initialized/reset qubits (as
|
133
|
-
qubits in the ground state are less
|
133
|
+
qubits in the ground state are less susceptible to decoherence).
|
134
134
|
target (Target): The :class:`~.Target` representing the target backend, if both
|
135
135
|
``durations`` and this are specified then this argument will take
|
136
136
|
precedence and ``durations`` will be ignored.
|
@@ -202,7 +202,7 @@ class BasePadding(TransformationPass):
|
|
202
202
|
):
|
203
203
|
"""Add new operation to DAG with scheduled information.
|
204
204
|
|
205
|
-
This is identical to apply_operation_back + updating the node_start_time
|
205
|
+
This is identical to apply_operation_back + updating the node_start_time property.
|
206
206
|
|
207
207
|
Args:
|
208
208
|
dag: DAG circuit on which the sequence is applied.
|
@@ -20,15 +20,15 @@ from qiskit.circuit import Gate, ParameterExpression, Qubit
|
|
20
20
|
from qiskit.circuit.delay import Delay
|
21
21
|
from qiskit.circuit.library.standard_gates import IGate, UGate, U3Gate
|
22
22
|
from qiskit.circuit.reset import Reset
|
23
|
-
from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGInNode, DAGOpNode
|
23
|
+
from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGInNode, DAGOpNode, DAGOutNode
|
24
24
|
from qiskit.quantum_info.operators.predicates import matrix_equal
|
25
25
|
from qiskit.synthesis.one_qubit import OneQubitEulerDecomposer
|
26
26
|
from qiskit.transpiler.exceptions import TranspilerError
|
27
27
|
from qiskit.transpiler.instruction_durations import InstructionDurations
|
28
28
|
from qiskit.transpiler.passes.optimization import Optimize1qGates
|
29
|
+
from qiskit.transpiler.passes.scheduling.padding.base_padding import BasePadding
|
29
30
|
from qiskit.transpiler.target import Target
|
30
31
|
|
31
|
-
from .base_padding import BasePadding
|
32
32
|
|
33
33
|
logger = logging.getLogger(__name__)
|
34
34
|
|
@@ -128,7 +128,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
128
128
|
will be used [d/2, d, d, ..., d, d, d/2].
|
129
129
|
skip_reset_qubits: If True, does not insert DD on idle periods that
|
130
130
|
immediately follow initialized/reset qubits
|
131
|
-
(as qubits in the ground state are less
|
131
|
+
(as qubits in the ground state are less susceptible to decoherence).
|
132
132
|
pulse_alignment: The hardware constraints for gate timing allocation.
|
133
133
|
This is usually provided from ``backend.configuration().timing_constraints``.
|
134
134
|
If provided, the delay length, i.e. ``spacing``, is implicitly adjusted to
|
@@ -311,7 +311,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
311
311
|
# slack = 992 dt - 4 x 160 dt = 352 dt
|
312
312
|
#
|
313
313
|
# unconstraind sequence: 44dt-X1-88dt-Y2-88dt-X3-88dt-Y4-44dt
|
314
|
-
#
|
314
|
+
# constrained sequence : 32dt-X1-80dt-Y2-80dt-X3-80dt-Y4-32dt + extra slack 48 dt
|
315
315
|
#
|
316
316
|
# Now we evenly split extra slack into start and end of the sequence.
|
317
317
|
# The distributed slack should be multiple of 16.
|
@@ -331,8 +331,7 @@ class PadDynamicalDecoupling(BasePadding):
|
|
331
331
|
if time_interval % self._alignment != 0:
|
332
332
|
raise TranspilerError(
|
333
333
|
f"Time interval {time_interval} is not divisible by alignment {self._alignment} "
|
334
|
-
f"between
|
335
|
-
f"on qargs {next_node.qargs}."
|
334
|
+
f"between {_format_node(prev_node)} and {_format_node(next_node)}."
|
336
335
|
)
|
337
336
|
|
338
337
|
if not self.__is_dd_qubit(dag.qubits.index(qubit)):
|
@@ -361,17 +360,17 @@ class PadDynamicalDecoupling(BasePadding):
|
|
361
360
|
theta, phi, lam, phase = OneQubitEulerDecomposer().angles_and_phase(u_inv)
|
362
361
|
if isinstance(next_node, DAGOpNode) and isinstance(next_node.op, (UGate, U3Gate)):
|
363
362
|
# Absorb the inverse into the successor (from left in circuit)
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
363
|
+
op = next_node.op
|
364
|
+
theta_r, phi_r, lam_r = op.params
|
365
|
+
op.params = Optimize1qGates.compose_u3(theta_r, phi_r, lam_r, theta, phi, lam)
|
366
|
+
next_node.op = op
|
368
367
|
sequence_gphase += phase
|
369
368
|
elif isinstance(prev_node, DAGOpNode) and isinstance(prev_node.op, (UGate, U3Gate)):
|
370
369
|
# Absorb the inverse into the predecessor (from right in circuit)
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
370
|
+
op = prev_node.op
|
371
|
+
theta_l, phi_l, lam_l = op.params
|
372
|
+
op.params = Optimize1qGates.compose_u3(theta, phi, lam, theta_l, phi_l, lam_l)
|
373
|
+
prev_node.op = op
|
375
374
|
sequence_gphase += phase
|
376
375
|
else:
|
377
376
|
# Don't do anything if there's no single-qubit gate to absorb the inverse
|
@@ -430,3 +429,10 @@ class PadDynamicalDecoupling(BasePadding):
|
|
430
429
|
else:
|
431
430
|
params.append(p)
|
432
431
|
return tuple(params)
|
432
|
+
|
433
|
+
|
434
|
+
def _format_node(node: DAGNode) -> str:
|
435
|
+
"""Util to format the DAGNode, DAGInNode, and DAGOutNode."""
|
436
|
+
if isinstance(node, (DAGInNode, DAGOutNode)):
|
437
|
+
return f"{node.__class__.__name__} on qarg {node.wire}"
|
438
|
+
return f"DAGNode {node.name} on qargs {node.qargs}"
|
@@ -14,13 +14,13 @@
|
|
14
14
|
|
15
15
|
import warnings
|
16
16
|
|
17
|
-
from qiskit.transpiler import InstructionDurations
|
18
|
-
from qiskit.transpiler.basepasses import AnalysisPass
|
19
|
-
from qiskit.transpiler.passes.scheduling.time_unit_conversion import TimeUnitConversion
|
20
|
-
from qiskit.dagcircuit import DAGOpNode, DAGCircuit
|
21
17
|
from qiskit.circuit import Delay, Gate
|
22
18
|
from qiskit.circuit.parameterexpression import ParameterExpression
|
19
|
+
from qiskit.dagcircuit import DAGOpNode, DAGCircuit
|
20
|
+
from qiskit.transpiler.basepasses import AnalysisPass
|
23
21
|
from qiskit.transpiler.exceptions import TranspilerError
|
22
|
+
from qiskit.transpiler.instruction_durations import InstructionDurations
|
23
|
+
from qiskit.transpiler.passes.scheduling.time_unit_conversion import TimeUnitConversion
|
24
24
|
from qiskit.transpiler.target import Target
|
25
25
|
|
26
26
|
|
@@ -70,8 +70,9 @@ class BaseScheduler(AnalysisPass):
|
|
70
70
|
duration = dag.calibrations[node.op.name][cal_key].duration
|
71
71
|
|
72
72
|
# Note that node duration is updated (but this is analysis pass)
|
73
|
-
|
74
|
-
|
73
|
+
op = node.op.to_mutable()
|
74
|
+
op.duration = duration
|
75
|
+
node.op = op
|
75
76
|
else:
|
76
77
|
duration = node.op.duration
|
77
78
|
|
@@ -105,9 +105,10 @@ class TimeUnitConversion(TransformationPass):
|
|
105
105
|
)
|
106
106
|
except TranspilerError:
|
107
107
|
continue
|
108
|
-
|
109
|
-
|
110
|
-
|
108
|
+
op = node.op.to_mutable()
|
109
|
+
op.duration = duration
|
110
|
+
op.unit = time_unit
|
111
|
+
node.op = op
|
111
112
|
|
112
113
|
self.property_set["time_unit"] = time_unit
|
113
114
|
return dag
|