qiskit 2.0.3__cp39-abi3-win_amd64.whl → 2.1.0__cp39-abi3-win_amd64.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 +19 -1
- qiskit/_accelerate.pyd +0 -0
- qiskit/circuit/__init__.py +104 -20
- qiskit/circuit/_add_control.py +57 -31
- qiskit/circuit/_classical_resource_map.py +4 -0
- qiskit/circuit/annotation.py +504 -0
- qiskit/circuit/classical/expr/__init__.py +1 -1
- qiskit/circuit/classical/expr/expr.py +104 -446
- qiskit/circuit/classical/expr/visitors.py +6 -0
- qiskit/circuit/classical/types/types.py +7 -130
- qiskit/circuit/controlflow/box.py +32 -7
- qiskit/circuit/delay.py +11 -9
- qiskit/circuit/library/arithmetic/adders/adder.py +4 -4
- qiskit/circuit/library/arithmetic/multipliers/multiplier.py +2 -2
- qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +8 -4
- qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
- qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
- qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
- qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
- qiskit/circuit/library/basis_change/qft.py +2 -2
- qiskit/circuit/library/blueprintcircuit.py +6 -0
- qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
- qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
- qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
- qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
- qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
- qiskit/circuit/library/fourier_checking.py +2 -2
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
- qiskit/circuit/library/generalized_gates/gms.py +5 -1
- qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +5 -1
- qiskit/circuit/library/generalized_gates/uc.py +1 -1
- qiskit/circuit/library/generalized_gates/unitary.py +21 -2
- qiskit/circuit/library/graph_state.py +2 -2
- qiskit/circuit/library/grover_operator.py +2 -2
- qiskit/circuit/library/hidden_linear_function.py +2 -2
- qiskit/circuit/library/iqp.py +2 -2
- qiskit/circuit/library/n_local/efficient_su2.py +2 -2
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
- qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
- qiskit/circuit/library/n_local/n_local.py +4 -3
- qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
- qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
- qiskit/circuit/library/n_local/two_local.py +2 -2
- qiskit/circuit/library/overlap.py +2 -2
- qiskit/circuit/library/pauli_evolution.py +3 -2
- qiskit/circuit/library/phase_estimation.py +2 -2
- qiskit/circuit/library/standard_gates/dcx.py +11 -12
- qiskit/circuit/library/standard_gates/ecr.py +21 -24
- qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
- qiskit/circuit/library/standard_gates/global_phase.py +5 -6
- qiskit/circuit/library/standard_gates/h.py +22 -45
- qiskit/circuit/library/standard_gates/i.py +1 -1
- qiskit/circuit/library/standard_gates/iswap.py +13 -31
- qiskit/circuit/library/standard_gates/p.py +19 -26
- qiskit/circuit/library/standard_gates/r.py +11 -17
- qiskit/circuit/library/standard_gates/rx.py +21 -45
- qiskit/circuit/library/standard_gates/rxx.py +7 -22
- qiskit/circuit/library/standard_gates/ry.py +21 -39
- qiskit/circuit/library/standard_gates/ryy.py +13 -28
- qiskit/circuit/library/standard_gates/rz.py +18 -35
- qiskit/circuit/library/standard_gates/rzx.py +7 -22
- qiskit/circuit/library/standard_gates/rzz.py +7 -19
- qiskit/circuit/library/standard_gates/s.py +44 -39
- qiskit/circuit/library/standard_gates/swap.py +25 -38
- qiskit/circuit/library/standard_gates/sx.py +34 -41
- qiskit/circuit/library/standard_gates/t.py +18 -27
- qiskit/circuit/library/standard_gates/u.py +8 -24
- qiskit/circuit/library/standard_gates/u1.py +28 -52
- qiskit/circuit/library/standard_gates/u2.py +9 -9
- qiskit/circuit/library/standard_gates/u3.py +24 -40
- qiskit/circuit/library/standard_gates/x.py +190 -336
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
- qiskit/circuit/library/standard_gates/y.py +19 -23
- qiskit/circuit/library/standard_gates/z.py +31 -38
- qiskit/circuit/parameter.py +14 -5
- qiskit/circuit/parameterexpression.py +109 -75
- qiskit/circuit/quantumcircuit.py +172 -99
- qiskit/circuit/quantumcircuitdata.py +1 -0
- qiskit/circuit/random/__init__.py +37 -2
- qiskit/circuit/random/utils.py +445 -56
- qiskit/circuit/tools/pi_check.py +5 -13
- qiskit/compiler/transpiler.py +1 -1
- qiskit/converters/circuit_to_instruction.py +2 -2
- qiskit/dagcircuit/dagnode.py +8 -3
- qiskit/primitives/__init__.py +2 -2
- qiskit/primitives/base/base_estimator.py +2 -2
- qiskit/primitives/containers/data_bin.py +0 -3
- qiskit/primitives/containers/observables_array.py +192 -108
- qiskit/primitives/primitive_job.py +29 -10
- qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
- qiskit/qasm3/__init__.py +106 -12
- qiskit/qasm3/ast.py +15 -1
- qiskit/qasm3/exporter.py +59 -36
- qiskit/qasm3/printer.py +12 -0
- qiskit/qpy/__init__.py +182 -6
- qiskit/qpy/binary_io/circuits.py +256 -24
- qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
- qiskit/qpy/binary_io/schedules.py +12 -32
- qiskit/qpy/binary_io/value.py +36 -18
- qiskit/qpy/common.py +11 -3
- qiskit/qpy/formats.py +17 -1
- qiskit/qpy/interface.py +52 -12
- qiskit/qpy/type_keys.py +7 -1
- qiskit/quantum_info/__init__.py +10 -0
- qiskit/quantum_info/operators/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
- qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
- qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
- qiskit/result/sampled_expval.py +3 -1
- qiskit/synthesis/__init__.py +10 -0
- qiskit/synthesis/arithmetic/__init__.py +1 -1
- qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
- qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
- qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
- qiskit/synthesis/evolution/lie_trotter.py +10 -7
- qiskit/synthesis/evolution/product_formula.py +10 -7
- qiskit/synthesis/evolution/qdrift.py +10 -7
- qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
- qiskit/synthesis/multi_controlled/__init__.py +4 -0
- qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
- qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
- qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
- qiskit/synthesis/unitary/qsd.py +80 -9
- qiskit/transpiler/__init__.py +10 -3
- qiskit/transpiler/instruction_durations.py +2 -20
- qiskit/transpiler/passes/__init__.py +5 -2
- qiskit/transpiler/passes/layout/dense_layout.py +26 -6
- qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
- qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
- qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
- qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
- qiskit/transpiler/passes/layout/vf2_utils.py +10 -0
- qiskit/transpiler/passes/optimization/__init__.py +1 -1
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
- qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
- qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
- qiskit/transpiler/passes/routing/sabre_swap.py +4 -2
- qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
- qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
- qiskit/transpiler/passes/synthesis/__init__.py +1 -0
- qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
- qiskit/transpiler/passes/synthesis/hls_plugins.py +494 -93
- qiskit/transpiler/passes/synthesis/plugin.py +4 -0
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
- qiskit/transpiler/passmanager_config.py +3 -0
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
- qiskit/transpiler/preset_passmanagers/common.py +101 -0
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
- qiskit/transpiler/preset_passmanagers/level3.py +2 -2
- qiskit/transpiler/target.py +15 -2
- qiskit/utils/optionals.py +6 -5
- qiskit/visualization/circuit/_utils.py +5 -3
- qiskit/visualization/circuit/latex.py +9 -2
- qiskit/visualization/circuit/matplotlib.py +26 -4
- qiskit/visualization/circuit/qcstyle.py +9 -157
- qiskit/visualization/dag/__init__.py +13 -0
- qiskit/visualization/dag/dagstyle.py +103 -0
- qiskit/visualization/dag/styles/__init__.py +13 -0
- qiskit/visualization/dag/styles/color.json +10 -0
- qiskit/visualization/dag/styles/plain.json +5 -0
- qiskit/visualization/dag_visualization.py +169 -98
- qiskit/visualization/style.py +223 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/METADATA +7 -6
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/RECORD +178 -169
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/entry_points.txt +6 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
- qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/WHEEL +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
- {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/top_level.txt +0 -0
qiskit/VERSION.txt
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0
|
1
|
+
2.1.0
|
qiskit/__init__.py
CHANGED
@@ -44,6 +44,14 @@ else:
|
|
44
44
|
" See https://qisk.it/packaging-1-0 for more detail."
|
45
45
|
)
|
46
46
|
|
47
|
+
if sys.version_info < (3, 10):
|
48
|
+
warnings.warn(
|
49
|
+
"Using Qiskit with Python 3.9 is deprecated as of the 2.1.0 release. "
|
50
|
+
"Support for running Qiskit with Python 3.9 will be removed in the "
|
51
|
+
"2.3.0 release, which coincides with when Python 3.9 goes end of life.",
|
52
|
+
DeprecationWarning,
|
53
|
+
)
|
54
|
+
|
47
55
|
from . import _accelerate
|
48
56
|
import qiskit._numpy_compat
|
49
57
|
|
@@ -52,10 +60,14 @@ import qiskit._numpy_compat
|
|
52
60
|
# We manually define them on import so people can directly import qiskit._accelerate.* submodules
|
53
61
|
# and not have to rely on attribute access. No action needed for top-level extension packages.
|
54
62
|
sys.modules["qiskit._accelerate.circuit"] = _accelerate.circuit
|
63
|
+
sys.modules["qiskit._accelerate.circuit.classical"] = _accelerate.circuit.classical
|
64
|
+
sys.modules["qiskit._accelerate.circuit.classical.expr"] = _accelerate.circuit.classical.expr
|
65
|
+
sys.modules["qiskit._accelerate.circuit.classical.types"] = _accelerate.circuit.classical.types
|
55
66
|
sys.modules["qiskit._accelerate.circuit_library"] = _accelerate.circuit_library
|
56
67
|
sys.modules["qiskit._accelerate.basis_translator"] = _accelerate.basis_translator
|
57
68
|
sys.modules["qiskit._accelerate.converters"] = _accelerate.converters
|
58
69
|
sys.modules["qiskit._accelerate.dense_layout"] = _accelerate.dense_layout
|
70
|
+
sys.modules["qiskit._accelerate.disjoint_utils"] = _accelerate.disjoint_utils
|
59
71
|
sys.modules["qiskit._accelerate.equivalence"] = _accelerate.equivalence
|
60
72
|
sys.modules["qiskit._accelerate.error_map"] = _accelerate.error_map
|
61
73
|
sys.modules["qiskit._accelerate.gates_in_basis"] = _accelerate.gates_in_basis
|
@@ -64,9 +76,13 @@ sys.modules["qiskit._accelerate.uc_gate"] = _accelerate.uc_gate
|
|
64
76
|
sys.modules["qiskit._accelerate.euler_one_qubit_decomposer"] = (
|
65
77
|
_accelerate.euler_one_qubit_decomposer
|
66
78
|
)
|
79
|
+
sys.modules["qiskit._accelerate.optimize_1q_gates_decomposition"] = (
|
80
|
+
_accelerate.optimize_1q_gates_decomposition
|
81
|
+
)
|
67
82
|
sys.modules["qiskit._accelerate.nlayout"] = _accelerate.nlayout
|
68
83
|
sys.modules["qiskit._accelerate.optimize_1q_gates"] = _accelerate.optimize_1q_gates
|
69
84
|
sys.modules["qiskit._accelerate.pauli_expval"] = _accelerate.pauli_expval
|
85
|
+
sys.modules["qiskit._accelerate.pauli_lindblad_map"] = _accelerate.pauli_lindblad_map
|
70
86
|
sys.modules["qiskit._accelerate.qasm2"] = _accelerate.qasm2
|
71
87
|
sys.modules["qiskit._accelerate.qasm3"] = _accelerate.qasm3
|
72
88
|
sys.modules["qiskit._accelerate.remove_diagonal_gates_before_measure"] = (
|
@@ -77,7 +93,6 @@ sys.modules["qiskit._accelerate.sabre"] = _accelerate.sabre
|
|
77
93
|
sys.modules["qiskit._accelerate.sampled_exp_val"] = _accelerate.sampled_exp_val
|
78
94
|
sys.modules["qiskit._accelerate.sparse_observable"] = _accelerate.sparse_observable
|
79
95
|
sys.modules["qiskit._accelerate.sparse_pauli_op"] = _accelerate.sparse_pauli_op
|
80
|
-
sys.modules["qiskit._accelerate.star_prerouting"] = _accelerate.star_prerouting
|
81
96
|
sys.modules["qiskit._accelerate.elide_permutations"] = _accelerate.elide_permutations
|
82
97
|
sys.modules["qiskit._accelerate.target"] = _accelerate.target
|
83
98
|
sys.modules["qiskit._accelerate.two_qubit_decompose"] = _accelerate.two_qubit_decompose
|
@@ -95,9 +110,11 @@ sys.modules["qiskit._accelerate.commutation_cancellation"] = _accelerate.commuta
|
|
95
110
|
sys.modules["qiskit._accelerate.consolidate_blocks"] = _accelerate.consolidate_blocks
|
96
111
|
sys.modules["qiskit._accelerate.synthesis.linear_phase"] = _accelerate.synthesis.linear_phase
|
97
112
|
sys.modules["qiskit._accelerate.synthesis.evolution"] = _accelerate.synthesis.evolution
|
113
|
+
sys.modules["qiskit._accelerate.synthesis.discrete_basis"] = _accelerate.synthesis.discrete_basis
|
98
114
|
sys.modules["qiskit._accelerate.synthesis.multi_controlled"] = (
|
99
115
|
_accelerate.synthesis.multi_controlled
|
100
116
|
)
|
117
|
+
sys.modules["qiskit._accelerate.synthesis.qft"] = _accelerate.synthesis.qft
|
101
118
|
sys.modules["qiskit._accelerate.split_2q_unitaries"] = _accelerate.split_2q_unitaries
|
102
119
|
sys.modules["qiskit._accelerate.gate_direction"] = _accelerate.gate_direction
|
103
120
|
sys.modules["qiskit._accelerate.inverse_cancellation"] = _accelerate.inverse_cancellation
|
@@ -107,6 +124,7 @@ sys.modules["qiskit._accelerate.twirling"] = _accelerate.twirling
|
|
107
124
|
sys.modules["qiskit._accelerate.high_level_synthesis"] = _accelerate.high_level_synthesis
|
108
125
|
sys.modules["qiskit._accelerate.remove_identity_equiv"] = _accelerate.remove_identity_equiv
|
109
126
|
sys.modules["qiskit._accelerate.circuit_duration"] = _accelerate.circuit_duration
|
127
|
+
sys.modules["qiskit._accelerate.cos_sin_decomp"] = _accelerate.cos_sin_decomp
|
110
128
|
|
111
129
|
from qiskit.exceptions import QiskitError, MissingOptionalLibraryError
|
112
130
|
|
qiskit/_accelerate.pyd
CHANGED
Binary file
|
qiskit/circuit/__init__.py
CHANGED
@@ -269,11 +269,16 @@ circuit. The top-level ones are:
|
|
269
269
|
* :class:`ControlFlowOp`, which has specific subclasses:
|
270
270
|
* :class:`BreakLoopOp`, to break out of the nearest containing loop
|
271
271
|
* :class:`ContinueLoopOp`, to move immediately to the next iteration of the containing loop
|
272
|
+
* :class:`BoxOp`, a simple grouping of instructions
|
272
273
|
* :class:`ForLoopOp`, to loop over a fixed range of values
|
273
274
|
* :class:`IfElseOp`, to conditionally enter one of two subcircuits
|
274
275
|
* :class:`SwitchCaseOp`, to conditionally enter one of many subcircuits
|
275
|
-
* :class:`WhileLoopOp`, to repeat a subcircuit until a condition is falsified
|
276
|
-
|
276
|
+
* :class:`WhileLoopOp`, to repeat a subcircuit until a condition is falsified.
|
277
|
+
|
278
|
+
Certain instructions can be "annotated" with metadata, which is typically intended to be consumed by
|
279
|
+
a compiler pass either locally, or in later backend processing. Currently this is limited to
|
280
|
+
:class:`BoxOp`. These annotations are represented by custom subclasses of :class:`Annotation`, and
|
281
|
+
there is further discussion of the support infrastructure in :mod:`qiskit.circuit.annotation`.
|
277
282
|
|
278
283
|
:ref:`Circuits can include classical expressions that are evaluated in real time
|
279
284
|
<circuit-repr-real-time-classical>`, while the QPU is executing a single shot of the circuit. These
|
@@ -307,6 +312,7 @@ assist compilation workflows. These include:
|
|
307
312
|
There are also utilities for generating random circuits:
|
308
313
|
|
309
314
|
* :func:`random.random_circuit`
|
315
|
+
* :func:`random.random_circuit_from_graph`
|
310
316
|
* :func:`random.random_clifford_circuit`
|
311
317
|
|
312
318
|
Finally, the circuit module has its own exception class, to indicate when things went wrong in
|
@@ -556,12 +562,15 @@ happen incoherently and to collapse any entanglement.
|
|
556
562
|
|
557
563
|
Hardware can be instructed to apply a real-time idle period on a given qubit. A scheduled circuit
|
558
564
|
(see :mod:`qiskit.transpiler`) will include all the idle times on qubits explicitly in terms of this
|
559
|
-
:class:`Delay`.
|
565
|
+
:class:`Delay`. :class:`.BoxOp` can also have an explicit duration attached, in its
|
566
|
+
:attr:`.BoxOp.duration` field.
|
560
567
|
|
561
568
|
.. autoclass:: Delay
|
562
569
|
:show-inheritance:
|
563
|
-
.. autoclass:: Duration
|
564
570
|
|
571
|
+
Delay durations can be specified either with concrete, constant times, or with delayed-resolution
|
572
|
+
"duration expressions" built out of :class:`.expr.Stretch` objects. See :ref:`circuit-stretches`
|
573
|
+
for more on this.
|
565
574
|
|
566
575
|
The :class:`Barrier` instruction can span an arbitrary number of qubits and clbits, and is a no-op
|
567
576
|
in hardware. During transpilation and optimization, however, it blocks any optimizations from
|
@@ -711,9 +720,9 @@ classes associated to each name.
|
|
711
720
|
.. autofunction:: get_control_flow_name_mapping
|
712
721
|
|
713
722
|
These control-flow operations (:class:`IfElseOp`, :class:`WhileLoopOp`,
|
714
|
-
:class:`SwitchCaseOp`, :class:`ForLoopOp` and :class
|
715
|
-
the branching conditions and strategies, but contain all the different subcircuit blocks that
|
716
|
-
|
723
|
+
:class:`SwitchCaseOp`, :class:`ForLoopOp` and :class:`.BoxOp`) all have specific state that defines
|
724
|
+
the branching conditions and strategies, but contain all the different subcircuit blocks that might
|
725
|
+
be entered in their :attr:`~ControlFlowOp.blocks` property.
|
717
726
|
|
718
727
|
.. autosummary::
|
719
728
|
:toctree: ../stubs/
|
@@ -796,6 +805,28 @@ automatically.
|
|
796
805
|
Consult :ref:`the control-flow construction documentation <circuit-control-flow-methods>` for more
|
797
806
|
information on how to build circuits with control flow.
|
798
807
|
|
808
|
+
|
809
|
+
Instruction-local annotations
|
810
|
+
-----------------------------
|
811
|
+
|
812
|
+
.. seealso::
|
813
|
+
|
814
|
+
:mod:`qiskit.circuit.annotation`
|
815
|
+
The module-level discussion of the annotation framework, including how to defined custom
|
816
|
+
annotations, and how the system interacts with the compiler and with serialization to other
|
817
|
+
formats.
|
818
|
+
|
819
|
+
|
820
|
+
Certain circuit instructions can be "annotated" with instruction-local annotations. As of Qiskit
|
821
|
+
2.1.0, this is limited to :class:`.BoxOp`. All annotations are subclasses of one base
|
822
|
+
interface-defining object, but typically represent entirely custom analyses and commands.
|
823
|
+
|
824
|
+
.. autosummary::
|
825
|
+
:toctree: ../stubs
|
826
|
+
|
827
|
+
Annotation
|
828
|
+
|
829
|
+
|
799
830
|
Investigating commutation relations
|
800
831
|
-----------------------------------
|
801
832
|
|
@@ -820,6 +851,70 @@ are available in the :class:`CommutationChecker`.
|
|
820
851
|
CommutationChecker
|
821
852
|
|
822
853
|
|
854
|
+
.. _circuit-stretches:
|
855
|
+
|
856
|
+
Delayed-resolution scheduling
|
857
|
+
-----------------------------
|
858
|
+
|
859
|
+
Typically, the output of Qiskit's compiler cannot be directly executed on a QPU. First, it is
|
860
|
+
likely to pass through some vendor-specific pulse-level compiler, which converts the gates and
|
861
|
+
measurements into signals to the controlling electronics of the QPU. While Qiskit's
|
862
|
+
:class:`.Target` can represent *some* of the timing constraints that these pulses will have, it is
|
863
|
+
generally not entirely complete. This is especially true when dynamic circuits (feed-forward
|
864
|
+
operations) are involved; the delays induced by the classical components are often dependent on
|
865
|
+
low-level post-optimization details of backend compilers, and cannot be known by Qiskit.
|
866
|
+
|
867
|
+
In these situations, a user can still exert control over the relative scheduling of pulses, such as
|
868
|
+
for dynamical decoupling, by using "stretch" durations. These are constructed by
|
869
|
+
:meth:`.QuantumCircuit.add_stretch`, and interact with the classical-expression system described in
|
870
|
+
:mod:`qiskit.circuit.classical`, although they are not real-time mutable.
|
871
|
+
|
872
|
+
For example, we can add stretches and boxes to set up a system where two separate dynamic-decoupling
|
873
|
+
sequences are applied to the same qubit, while a pair of other qubits undergoes a delay of unknown
|
874
|
+
duration. The two sequences are constrained to have the same length, even though internally the
|
875
|
+
concrete DD pulses have differing lengths.
|
876
|
+
|
877
|
+
.. code-block:: python
|
878
|
+
|
879
|
+
from qiskit import QuantumCircuit
|
880
|
+
from qiskit.circuit.classical import expr
|
881
|
+
|
882
|
+
qc = QuantumCircuit(3, 3)
|
883
|
+
# This sets up three duration "degrees of freedom" that will
|
884
|
+
# be resolved later by a backend compiler.
|
885
|
+
a = qc.add_stretch("a")
|
886
|
+
b = qc.add_stretch("b")
|
887
|
+
c = qc.add_stretch("c")
|
888
|
+
|
889
|
+
# This set of operations involves feed-forward operations that
|
890
|
+
# Qiskit cannot know the length of.
|
891
|
+
with qc.box():
|
892
|
+
qc.h(1)
|
893
|
+
qc.cx(1, 2)
|
894
|
+
qc.measure([1, 2], [1, 2])
|
895
|
+
with qc.if_test(expr.equal(qc.clbits[1], qc.clbits[2])):
|
896
|
+
qc.h(1)
|
897
|
+
|
898
|
+
# While that stuff is happening to qubits (1, 2), we want
|
899
|
+
# qubit 0 to do two different DD sequences. The two DD
|
900
|
+
# sequences are fixed to be the same length as each other,
|
901
|
+
# even though they're both internally stretchy.
|
902
|
+
with qc.box(duration=a):
|
903
|
+
# Textbook NMRish XX DD.
|
904
|
+
qc.delay(b, 0)
|
905
|
+
qc.x(0)
|
906
|
+
qc.delay(expr.mul(2, b), 0)
|
907
|
+
qc.x(0)
|
908
|
+
qc.delay(b, 0)
|
909
|
+
with qc.box(duration=a):
|
910
|
+
# XY4-like DD.
|
911
|
+
for _ in range(2):
|
912
|
+
qc.delay(c, 0)
|
913
|
+
qc.y(0)
|
914
|
+
qc.delay(expr.mul(2, c), 0)
|
915
|
+
qc.x(0)
|
916
|
+
qc.delay(c, 0)
|
917
|
+
|
823
918
|
.. _circuit-custom-gates:
|
824
919
|
|
825
920
|
Creating custom instructions
|
@@ -1053,19 +1148,6 @@ default instances of the :class:`.BasisTranslator`.
|
|
1053
1148
|
:data:`StandardEquivalenceLibrary`.
|
1054
1149
|
|
1055
1150
|
|
1056
|
-
|
1057
|
-
Generating random circuits
|
1058
|
-
--------------------------
|
1059
|
-
|
1060
|
-
..
|
1061
|
-
If we expand these capabilities in the future, it's probably best to move it to its own
|
1062
|
-
module-level documentation page than to expand this "inline" module documentation.
|
1063
|
-
|
1064
|
-
.. currentmodule:: qiskit.circuit.random
|
1065
|
-
.. autofunction:: random_circuit
|
1066
|
-
.. autofunction:: random_clifford_circuit
|
1067
|
-
.. currentmodule:: qiskit.circuit
|
1068
|
-
|
1069
1151
|
Apply Pauli twirling to a circuit
|
1070
1152
|
---------------------------------
|
1071
1153
|
|
@@ -1306,6 +1388,8 @@ from .quantumcircuit import QuantumCircuit
|
|
1306
1388
|
from .gate import Gate
|
1307
1389
|
|
1308
1390
|
# pylint: disable=cyclic-import
|
1391
|
+
from . import annotation
|
1392
|
+
from .annotation import Annotation
|
1309
1393
|
from .controlledgate import ControlledGate
|
1310
1394
|
from . import singleton
|
1311
1395
|
from .instruction import Instruction
|
qiskit/circuit/_add_control.py
CHANGED
@@ -24,21 +24,47 @@ from . import ControlledGate, Gate, QuantumRegister, QuantumCircuit
|
|
24
24
|
from ._utils import _ctrl_state_to_int
|
25
25
|
|
26
26
|
|
27
|
+
# The list of gates whose controlled versions have efficient synthesis algorithms.
|
28
|
+
# For example, a controlled version of X is MCX (with many synthesis algorithms avalable),
|
29
|
+
# and a controlled version of Z is MCX + two Hadamard gates.
|
30
|
+
#
|
31
|
+
# Note: when adding a new gate to this list, also add the decomposition of its controlled
|
32
|
+
# version to apply_basic_controlled_gate.
|
33
|
+
EFFICIENTLY_CONTROLLED_GATES = [
|
34
|
+
"p",
|
35
|
+
"u",
|
36
|
+
"x",
|
37
|
+
"z",
|
38
|
+
"y",
|
39
|
+
"h",
|
40
|
+
"sx",
|
41
|
+
"sxdg",
|
42
|
+
"rx",
|
43
|
+
"ry",
|
44
|
+
"rz",
|
45
|
+
"cx",
|
46
|
+
"cz",
|
47
|
+
]
|
48
|
+
|
49
|
+
|
27
50
|
def add_control(
|
28
51
|
operation: Gate | ControlledGate,
|
29
52
|
num_ctrl_qubits: int,
|
30
53
|
label: str | None,
|
31
54
|
ctrl_state: str | int | None,
|
32
55
|
) -> ControlledGate:
|
33
|
-
"""
|
34
|
-
library, it will be returned (e.g. XGate.control() = CnotGate().
|
56
|
+
"""Return the controlled version of the gate.
|
35
57
|
|
36
|
-
|
37
|
-
|
38
|
-
|
58
|
+
This function first checks whether the gate's name corresponds to a known
|
59
|
+
method for generating its controlled version. Currently, these methods exist
|
60
|
+
for gates in ``EFFICIENTLY_CONTROLLED_GATES``.
|
39
61
|
|
40
|
-
|
41
|
-
|
62
|
+
For gates not in ``EFFICIENTLY_CONTROLLED_GATES``, the function calls the unroller
|
63
|
+
to decompose the gate into gates in ``EFFICIENTLY_CONTROLLED_GATES``,
|
64
|
+
and then generates the controlled version by controlling every gate in this
|
65
|
+
decomposition.
|
66
|
+
|
67
|
+
Open controls are implemented by conjugating the control line with X gates.
|
42
68
|
|
43
69
|
This function is meant to be called from the
|
44
70
|
:method:`qiskit.circuit.gate.Gate.control()` method.
|
@@ -72,11 +98,18 @@ def control(
|
|
72
98
|
label: str | None = None,
|
73
99
|
ctrl_state: str | int | None = None,
|
74
100
|
) -> ControlledGate:
|
75
|
-
"""Return controlled version of gate
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
101
|
+
"""Return the controlled version of the gate.
|
102
|
+
|
103
|
+
This function first checks whether the gate's name corresponds to a known
|
104
|
+
method for generating its controlled version. Currently, these methods exist
|
105
|
+
for gates in ``EFFICIENTLY_CONTROLLED_GATES``.
|
106
|
+
|
107
|
+
For gates not in ``EFFICIENTLY_CONTROLLED_GATES``, the function calls the unroller
|
108
|
+
to decompose the gate into gates in ``EFFICIENTLY_CONTROLLED_GATES``,
|
109
|
+
and then generates the controlled version by controlling every gate in this
|
110
|
+
decomposition.
|
111
|
+
|
112
|
+
Open controls are implemented by conjugating the control line with X gates.
|
80
113
|
|
81
114
|
Args:
|
82
115
|
operation: The gate used to create the ControlledGate.
|
@@ -109,16 +142,14 @@ def control(
|
|
109
142
|
|
110
143
|
global_phase = 0
|
111
144
|
|
112
|
-
|
113
|
-
|
114
|
-
if operation.name in basis:
|
115
|
-
apply_basic_controlled_gate(controlled_circ, operation, q_control, q_target[0])
|
145
|
+
if operation.name in EFFICIENTLY_CONTROLLED_GATES:
|
146
|
+
apply_basic_controlled_gate(controlled_circ, operation, q_control, q_target)
|
116
147
|
else:
|
117
148
|
if isinstance(operation, controlledgate.ControlledGate):
|
118
149
|
operation = operation.to_mutable()
|
119
150
|
operation.ctrl_state = None
|
120
151
|
|
121
|
-
unrolled_gate = _unroll_gate(operation, basis_gates=
|
152
|
+
unrolled_gate = _unroll_gate(operation, basis_gates=EFFICIENTLY_CONTROLLED_GATES)
|
122
153
|
if unrolled_gate.definition.global_phase:
|
123
154
|
global_phase += unrolled_gate.definition.global_phase
|
124
155
|
|
@@ -139,9 +170,6 @@ def control(
|
|
139
170
|
|
140
171
|
apply_basic_controlled_gate(controlled_circ, gate, q_control, target)
|
141
172
|
|
142
|
-
if gate.definition is not None and gate.definition.global_phase and gate.name != "rz":
|
143
|
-
global_phase += gate.definition.global_phase
|
144
|
-
|
145
173
|
# apply controlled global phase
|
146
174
|
if global_phase:
|
147
175
|
if len(q_control) < 2:
|
@@ -185,16 +213,14 @@ def control(
|
|
185
213
|
def apply_basic_controlled_gate(circuit, gate, controls, target):
|
186
214
|
"""Apply a controlled version of ``gate`` to the circuit.
|
187
215
|
|
188
|
-
This implements multi-control operations for
|
189
|
-
|
190
|
-
["p", "u", "x", "z", "y", "h", "sx", "sxdg", "rx", "ry", "rz", "cx"]
|
216
|
+
This implements multi-control operations for every gate in
|
217
|
+
``EFFICIENTLY_CONTROLLED_GATES``.
|
191
218
|
|
192
219
|
"""
|
193
220
|
num_ctrl_qubits = len(controls)
|
194
221
|
|
195
222
|
if gate.name == "x":
|
196
223
|
circuit.mcx(controls, target)
|
197
|
-
|
198
224
|
elif gate.name == "rx":
|
199
225
|
circuit.mcrx(
|
200
226
|
gate.definition.data[0].operation.params[0],
|
@@ -217,7 +243,6 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
217
243
|
target,
|
218
244
|
use_basis_gates=False,
|
219
245
|
)
|
220
|
-
# continue
|
221
246
|
elif gate.name == "p":
|
222
247
|
from qiskit.circuit.library import MCPhaseGate
|
223
248
|
|
@@ -230,6 +255,13 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
230
255
|
controls[:] + [target[0]], # CX has two targets
|
231
256
|
target[1],
|
232
257
|
)
|
258
|
+
elif gate.name == "cz":
|
259
|
+
circuit.h(target[1])
|
260
|
+
circuit.mcx(
|
261
|
+
controls[:] + [target[0]], # CZ has two targets
|
262
|
+
target[1],
|
263
|
+
)
|
264
|
+
circuit.h(target[1])
|
233
265
|
elif gate.name == "u":
|
234
266
|
theta, phi, lamb = gate.params
|
235
267
|
if num_ctrl_qubits == 1:
|
@@ -254,17 +286,14 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
254
286
|
circuit.mcry(theta, controls, target, use_basis_gates=False)
|
255
287
|
circuit.mcrz(phi, controls, target, use_basis_gates=False)
|
256
288
|
circuit.mcp((phi + lamb) / 2, controls[1:], controls[0])
|
257
|
-
|
258
289
|
elif gate.name == "z":
|
259
290
|
circuit.h(target)
|
260
291
|
circuit.mcx(controls, target)
|
261
292
|
circuit.h(target)
|
262
|
-
|
263
293
|
elif gate.name == "y":
|
264
294
|
circuit.sdg(target)
|
265
295
|
circuit.mcx(controls, target)
|
266
296
|
circuit.s(target)
|
267
|
-
|
268
297
|
elif gate.name == "h":
|
269
298
|
circuit.s(target)
|
270
299
|
circuit.h(target)
|
@@ -273,17 +302,14 @@ def apply_basic_controlled_gate(circuit, gate, controls, target):
|
|
273
302
|
circuit.tdg(target)
|
274
303
|
circuit.h(target)
|
275
304
|
circuit.sdg(target)
|
276
|
-
|
277
305
|
elif gate.name == "sx":
|
278
306
|
circuit.h(target)
|
279
307
|
circuit.mcp(pi / 2, controls, target)
|
280
308
|
circuit.h(target)
|
281
|
-
|
282
309
|
elif gate.name == "sxdg":
|
283
310
|
circuit.h(target)
|
284
311
|
circuit.mcp(3 * pi / 2, controls, target)
|
285
312
|
circuit.h(target)
|
286
|
-
|
287
313
|
else:
|
288
314
|
raise CircuitError(f"Gate {gate} not in supported basis.")
|
289
315
|
|
@@ -36,6 +36,10 @@ class VariableMapper(expr.ExprVisitor[expr.Expr]):
|
|
36
36
|
``ValueError`` will be raised instead. The given ``add_register`` callable may choose to raise
|
37
37
|
its own exception."""
|
38
38
|
|
39
|
+
# We don't want docstrings for the inherited visitor methods, which are self-explanatory and
|
40
|
+
# would just be noise.
|
41
|
+
# pylint: disable=missing-function-docstring
|
42
|
+
|
39
43
|
__slots__ = ("target_cregs", "register_map", "bit_map", "var_map", "add_register")
|
40
44
|
|
41
45
|
def __init__(
|