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.
Files changed (180) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +19 -1
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/circuit/__init__.py +104 -20
  5. qiskit/circuit/_add_control.py +57 -31
  6. qiskit/circuit/_classical_resource_map.py +4 -0
  7. qiskit/circuit/annotation.py +504 -0
  8. qiskit/circuit/classical/expr/__init__.py +1 -1
  9. qiskit/circuit/classical/expr/expr.py +104 -446
  10. qiskit/circuit/classical/expr/visitors.py +6 -0
  11. qiskit/circuit/classical/types/types.py +7 -130
  12. qiskit/circuit/controlflow/box.py +32 -7
  13. qiskit/circuit/delay.py +11 -9
  14. qiskit/circuit/library/arithmetic/adders/adder.py +4 -4
  15. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +2 -2
  16. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +8 -4
  17. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +23 -15
  18. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +22 -14
  19. qiskit/circuit/library/arithmetic/quadratic_form.py +6 -0
  20. qiskit/circuit/library/arithmetic/weighted_adder.py +43 -24
  21. qiskit/circuit/library/basis_change/qft.py +2 -2
  22. qiskit/circuit/library/blueprintcircuit.py +6 -0
  23. qiskit/circuit/library/boolean_logic/inner_product.py +2 -2
  24. qiskit/circuit/library/boolean_logic/quantum_and.py +2 -2
  25. qiskit/circuit/library/boolean_logic/quantum_or.py +3 -3
  26. qiskit/circuit/library/boolean_logic/quantum_xor.py +2 -2
  27. qiskit/circuit/library/data_preparation/_z_feature_map.py +2 -2
  28. qiskit/circuit/library/data_preparation/_zz_feature_map.py +2 -2
  29. qiskit/circuit/library/data_preparation/pauli_feature_map.py +2 -2
  30. qiskit/circuit/library/fourier_checking.py +2 -2
  31. qiskit/circuit/library/generalized_gates/diagonal.py +5 -1
  32. qiskit/circuit/library/generalized_gates/gms.py +5 -1
  33. qiskit/circuit/library/generalized_gates/linear_function.py +2 -2
  34. qiskit/circuit/library/generalized_gates/permutation.py +5 -1
  35. qiskit/circuit/library/generalized_gates/uc.py +1 -1
  36. qiskit/circuit/library/generalized_gates/unitary.py +21 -2
  37. qiskit/circuit/library/graph_state.py +2 -2
  38. qiskit/circuit/library/grover_operator.py +2 -2
  39. qiskit/circuit/library/hidden_linear_function.py +2 -2
  40. qiskit/circuit/library/iqp.py +2 -2
  41. qiskit/circuit/library/n_local/efficient_su2.py +2 -2
  42. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  43. qiskit/circuit/library/n_local/excitation_preserving.py +7 -9
  44. qiskit/circuit/library/n_local/n_local.py +4 -3
  45. qiskit/circuit/library/n_local/pauli_two_design.py +2 -2
  46. qiskit/circuit/library/n_local/real_amplitudes.py +2 -2
  47. qiskit/circuit/library/n_local/two_local.py +2 -2
  48. qiskit/circuit/library/overlap.py +2 -2
  49. qiskit/circuit/library/pauli_evolution.py +3 -2
  50. qiskit/circuit/library/phase_estimation.py +2 -2
  51. qiskit/circuit/library/standard_gates/dcx.py +11 -12
  52. qiskit/circuit/library/standard_gates/ecr.py +21 -24
  53. qiskit/circuit/library/standard_gates/equivalence_library.py +232 -96
  54. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  55. qiskit/circuit/library/standard_gates/h.py +22 -45
  56. qiskit/circuit/library/standard_gates/i.py +1 -1
  57. qiskit/circuit/library/standard_gates/iswap.py +13 -31
  58. qiskit/circuit/library/standard_gates/p.py +19 -26
  59. qiskit/circuit/library/standard_gates/r.py +11 -17
  60. qiskit/circuit/library/standard_gates/rx.py +21 -45
  61. qiskit/circuit/library/standard_gates/rxx.py +7 -22
  62. qiskit/circuit/library/standard_gates/ry.py +21 -39
  63. qiskit/circuit/library/standard_gates/ryy.py +13 -28
  64. qiskit/circuit/library/standard_gates/rz.py +18 -35
  65. qiskit/circuit/library/standard_gates/rzx.py +7 -22
  66. qiskit/circuit/library/standard_gates/rzz.py +7 -19
  67. qiskit/circuit/library/standard_gates/s.py +44 -39
  68. qiskit/circuit/library/standard_gates/swap.py +25 -38
  69. qiskit/circuit/library/standard_gates/sx.py +34 -41
  70. qiskit/circuit/library/standard_gates/t.py +18 -27
  71. qiskit/circuit/library/standard_gates/u.py +8 -24
  72. qiskit/circuit/library/standard_gates/u1.py +28 -52
  73. qiskit/circuit/library/standard_gates/u2.py +9 -9
  74. qiskit/circuit/library/standard_gates/u3.py +24 -40
  75. qiskit/circuit/library/standard_gates/x.py +190 -336
  76. qiskit/circuit/library/standard_gates/xx_minus_yy.py +12 -50
  77. qiskit/circuit/library/standard_gates/xx_plus_yy.py +13 -52
  78. qiskit/circuit/library/standard_gates/y.py +19 -23
  79. qiskit/circuit/library/standard_gates/z.py +31 -38
  80. qiskit/circuit/parameter.py +14 -5
  81. qiskit/circuit/parameterexpression.py +109 -75
  82. qiskit/circuit/quantumcircuit.py +172 -99
  83. qiskit/circuit/quantumcircuitdata.py +1 -0
  84. qiskit/circuit/random/__init__.py +37 -2
  85. qiskit/circuit/random/utils.py +445 -56
  86. qiskit/circuit/tools/pi_check.py +5 -13
  87. qiskit/compiler/transpiler.py +1 -1
  88. qiskit/converters/circuit_to_instruction.py +2 -2
  89. qiskit/dagcircuit/dagnode.py +8 -3
  90. qiskit/primitives/__init__.py +2 -2
  91. qiskit/primitives/base/base_estimator.py +2 -2
  92. qiskit/primitives/containers/data_bin.py +0 -3
  93. qiskit/primitives/containers/observables_array.py +192 -108
  94. qiskit/primitives/primitive_job.py +29 -10
  95. qiskit/providers/fake_provider/generic_backend_v2.py +2 -0
  96. qiskit/qasm3/__init__.py +106 -12
  97. qiskit/qasm3/ast.py +15 -1
  98. qiskit/qasm3/exporter.py +59 -36
  99. qiskit/qasm3/printer.py +12 -0
  100. qiskit/qpy/__init__.py +182 -6
  101. qiskit/qpy/binary_io/circuits.py +256 -24
  102. qiskit/qpy/binary_io/parse_sympy_repr.py +5 -0
  103. qiskit/qpy/binary_io/schedules.py +12 -32
  104. qiskit/qpy/binary_io/value.py +36 -18
  105. qiskit/qpy/common.py +11 -3
  106. qiskit/qpy/formats.py +17 -1
  107. qiskit/qpy/interface.py +52 -12
  108. qiskit/qpy/type_keys.py +7 -1
  109. qiskit/quantum_info/__init__.py +10 -0
  110. qiskit/quantum_info/operators/__init__.py +1 -0
  111. qiskit/quantum_info/operators/symplectic/__init__.py +1 -0
  112. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +26 -0
  113. qiskit/quantum_info/operators/symplectic/pauli.py +2 -2
  114. qiskit/result/sampled_expval.py +3 -1
  115. qiskit/synthesis/__init__.py +10 -0
  116. qiskit/synthesis/arithmetic/__init__.py +1 -1
  117. qiskit/synthesis/arithmetic/adders/__init__.py +1 -0
  118. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +6 -2
  119. qiskit/synthesis/arithmetic/adders/rv_ripple_carry_adder.py +156 -0
  120. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +14 -126
  121. qiskit/synthesis/discrete_basis/solovay_kitaev.py +161 -121
  122. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  123. qiskit/synthesis/evolution/product_formula.py +10 -7
  124. qiskit/synthesis/evolution/qdrift.py +10 -7
  125. qiskit/synthesis/evolution/suzuki_trotter.py +10 -7
  126. qiskit/synthesis/multi_controlled/__init__.py +4 -0
  127. qiskit/synthesis/multi_controlled/mcx_synthesis.py +402 -178
  128. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +14 -15
  129. qiskit/synthesis/qft/qft_decompose_lnn.py +7 -25
  130. qiskit/synthesis/unitary/qsd.py +80 -9
  131. qiskit/transpiler/__init__.py +10 -3
  132. qiskit/transpiler/instruction_durations.py +2 -20
  133. qiskit/transpiler/passes/__init__.py +5 -2
  134. qiskit/transpiler/passes/layout/dense_layout.py +26 -6
  135. qiskit/transpiler/passes/layout/disjoint_utils.py +1 -166
  136. qiskit/transpiler/passes/layout/sabre_layout.py +22 -3
  137. qiskit/transpiler/passes/layout/sabre_pre_layout.py +1 -1
  138. qiskit/transpiler/passes/layout/vf2_layout.py +49 -13
  139. qiskit/transpiler/passes/layout/vf2_utils.py +10 -0
  140. qiskit/transpiler/passes/optimization/__init__.py +1 -1
  141. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +2 -1
  142. qiskit/transpiler/passes/optimization/optimize_clifford_t.py +68 -0
  143. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -9
  144. qiskit/transpiler/passes/routing/sabre_swap.py +4 -2
  145. qiskit/transpiler/passes/routing/star_prerouting.py +106 -81
  146. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  147. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  148. qiskit/transpiler/passes/scheduling/padding/__init__.py +1 -0
  149. qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py +876 -0
  150. qiskit/transpiler/passes/synthesis/__init__.py +1 -0
  151. qiskit/transpiler/passes/synthesis/clifford_unitary_synth_plugin.py +123 -0
  152. qiskit/transpiler/passes/synthesis/hls_plugins.py +494 -93
  153. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  154. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +27 -22
  155. qiskit/transpiler/passmanager_config.py +3 -0
  156. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +149 -28
  157. qiskit/transpiler/preset_passmanagers/common.py +101 -0
  158. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +6 -0
  159. qiskit/transpiler/preset_passmanagers/level3.py +2 -2
  160. qiskit/transpiler/target.py +15 -2
  161. qiskit/utils/optionals.py +6 -5
  162. qiskit/visualization/circuit/_utils.py +5 -3
  163. qiskit/visualization/circuit/latex.py +9 -2
  164. qiskit/visualization/circuit/matplotlib.py +26 -4
  165. qiskit/visualization/circuit/qcstyle.py +9 -157
  166. qiskit/visualization/dag/__init__.py +13 -0
  167. qiskit/visualization/dag/dagstyle.py +103 -0
  168. qiskit/visualization/dag/styles/__init__.py +13 -0
  169. qiskit/visualization/dag/styles/color.json +10 -0
  170. qiskit/visualization/dag/styles/plain.json +5 -0
  171. qiskit/visualization/dag_visualization.py +169 -98
  172. qiskit/visualization/style.py +223 -0
  173. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/METADATA +7 -6
  174. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/RECORD +178 -169
  175. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/entry_points.txt +6 -0
  176. qiskit/synthesis/discrete_basis/commutator_decompose.py +0 -265
  177. qiskit/synthesis/discrete_basis/gate_sequence.py +0 -421
  178. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/WHEEL +0 -0
  179. {qiskit-2.0.3.dist-info → qiskit-2.1.0.dist-info}/licenses/LICENSE.txt +0 -0
  180. {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.3
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
@@ -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
- * :class:`BoxOp`, to group a series of instructions for later processing
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:`BoxOp`) all have specific state that defines
715
- the branching conditions and strategies, but contain all the different subcircuit blocks that
716
- might be entered in their :attr:`~ControlFlowOp.blocks` property.
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
@@ -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
- """For standard gates, if the controlled version already exists in the
34
- library, it will be returned (e.g. XGate.control() = CnotGate().
56
+ """Return the controlled version of the gate.
35
57
 
36
- For more generic gates, this method implements the controlled
37
- version by first decomposing into the ['u1', 'u3', 'cx'] basis, then
38
- controlling each gate in the decomposition.
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
- Open controls are implemented by conjugating the control line with
41
- X gates. Adds num_ctrl_qubits controls to operation.
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 using controlled rotations. This function
76
- first checks the name of the operation to see if it knows of a method from which
77
- to generate a controlled version. Currently, these are ``x``, ``rx``, ``ry``, and ``rz``.
78
- If a method is not directly known, it calls the unroller to convert to `u1`, `u3`,
79
- and `cx` gates.
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
- basis = ["p", "u", "x", "z", "y", "h", "sx", "sxdg", "rx", "ry", "rz", "cx"]
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=basis)
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 the following basis gates:
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__(