qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__cp39-abi3-macosx_11_0_arm64.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 (462) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +3 -9
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +35 -10
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +236 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +469 -154
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/graph_state.py +1 -0
  60. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  61. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  62. qiskit/circuit/library/n_local/n_local.py +1 -1
  63. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  64. qiskit/circuit/library/overlap.py +2 -2
  65. qiskit/circuit/library/pauli_evolution.py +39 -24
  66. qiskit/circuit/library/phase_oracle.py +130 -51
  67. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  69. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  70. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  71. qiskit/circuit/library/standard_gates/h.py +4 -9
  72. qiskit/circuit/library/standard_gates/i.py +2 -2
  73. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  74. qiskit/circuit/library/standard_gates/p.py +15 -34
  75. qiskit/circuit/library/standard_gates/r.py +7 -10
  76. qiskit/circuit/library/standard_gates/rx.py +5 -15
  77. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  78. qiskit/circuit/library/standard_gates/ry.py +5 -17
  79. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  80. qiskit/circuit/library/standard_gates/rz.py +5 -17
  81. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  82. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  83. qiskit/circuit/library/standard_gates/s.py +6 -15
  84. qiskit/circuit/library/standard_gates/swap.py +4 -11
  85. qiskit/circuit/library/standard_gates/sx.py +7 -12
  86. qiskit/circuit/library/standard_gates/t.py +6 -7
  87. qiskit/circuit/library/standard_gates/u.py +2 -10
  88. qiskit/circuit/library/standard_gates/u1.py +5 -16
  89. qiskit/circuit/library/standard_gates/u2.py +2 -6
  90. qiskit/circuit/library/standard_gates/u3.py +3 -11
  91. qiskit/circuit/library/standard_gates/x.py +14 -62
  92. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  94. qiskit/circuit/library/standard_gates/y.py +4 -9
  95. qiskit/circuit/library/standard_gates/z.py +5 -15
  96. qiskit/circuit/measure.py +11 -2
  97. qiskit/circuit/parameterexpression.py +11 -0
  98. qiskit/circuit/quantumcircuit.py +890 -564
  99. qiskit/circuit/random/utils.py +12 -6
  100. qiskit/circuit/reset.py +5 -2
  101. qiskit/circuit/singleton.py +5 -11
  102. qiskit/circuit/store.py +0 -8
  103. qiskit/circuit/tools/pi_check.py +3 -0
  104. qiskit/compiler/__init__.py +1 -7
  105. qiskit/compiler/transpiler.py +38 -196
  106. qiskit/converters/circuit_to_dag.py +6 -4
  107. qiskit/converters/circuit_to_dagdependency.py +0 -2
  108. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  109. qiskit/converters/circuit_to_gate.py +1 -1
  110. qiskit/converters/circuit_to_instruction.py +16 -29
  111. qiskit/converters/dag_to_circuit.py +7 -8
  112. qiskit/converters/dag_to_dagdependency.py +0 -1
  113. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  114. qiskit/converters/dagdependency_to_circuit.py +0 -6
  115. qiskit/converters/dagdependency_to_dag.py +0 -6
  116. qiskit/dagcircuit/collect_blocks.py +32 -20
  117. qiskit/dagcircuit/dagdependency.py +3 -37
  118. qiskit/dagcircuit/dagdependency_v2.py +5 -82
  119. qiskit/dagcircuit/dagnode.py +14 -2
  120. qiskit/passmanager/__init__.py +24 -6
  121. qiskit/passmanager/passmanager.py +26 -24
  122. qiskit/primitives/__init__.py +44 -35
  123. qiskit/primitives/backend_estimator_v2.py +102 -23
  124. qiskit/primitives/backend_sampler_v2.py +5 -20
  125. qiskit/primitives/base/__init__.py +4 -4
  126. qiskit/primitives/base/base_estimator.py +77 -82
  127. qiskit/primitives/base/base_primitive_job.py +2 -2
  128. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  129. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  130. qiskit/primitives/base/base_sampler.py +52 -60
  131. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  132. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  133. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  134. qiskit/primitives/containers/bindings_array.py +3 -1
  135. qiskit/primitives/containers/bit_array.py +23 -0
  136. qiskit/primitives/containers/data_bin.py +3 -1
  137. qiskit/primitives/containers/observables_array.py +19 -2
  138. qiskit/primitives/statevector_sampler.py +6 -8
  139. qiskit/primitives/utils.py +14 -189
  140. qiskit/providers/__init__.py +4 -130
  141. qiskit/providers/backend.py +11 -314
  142. qiskit/providers/basic_provider/__init__.py +3 -1
  143. qiskit/providers/basic_provider/basic_provider.py +29 -9
  144. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  145. qiskit/providers/exceptions.py +0 -33
  146. qiskit/providers/fake_provider/__init__.py +0 -37
  147. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  148. qiskit/qasm2/__init__.py +21 -6
  149. qiskit/qasm2/export.py +2 -10
  150. qiskit/qasm2/parse.py +11 -25
  151. qiskit/qasm3/__init__.py +5 -1
  152. qiskit/qasm3/ast.py +44 -0
  153. qiskit/qasm3/exporter.py +65 -27
  154. qiskit/qasm3/printer.py +35 -4
  155. qiskit/qpy/__init__.py +162 -19
  156. qiskit/qpy/binary_io/__init__.py +0 -1
  157. qiskit/qpy/binary_io/circuits.py +96 -116
  158. qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
  159. qiskit/qpy/binary_io/schedules.py +61 -388
  160. qiskit/qpy/binary_io/value.py +159 -33
  161. qiskit/qpy/common.py +10 -7
  162. qiskit/qpy/formats.py +41 -0
  163. qiskit/qpy/interface.py +29 -62
  164. qiskit/qpy/type_keys.py +58 -221
  165. qiskit/quantum_info/analysis/distance.py +3 -1
  166. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  167. qiskit/quantum_info/operators/operator.py +6 -2
  168. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  169. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  170. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  171. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  172. qiskit/quantum_info/states/densitymatrix.py +16 -6
  173. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  174. qiskit/quantum_info/states/statevector.py +16 -6
  175. qiskit/result/__init__.py +5 -17
  176. qiskit/result/models.py +18 -11
  177. qiskit/result/result.py +38 -134
  178. qiskit/result/sampled_expval.py +1 -2
  179. qiskit/result/utils.py +3 -4
  180. qiskit/synthesis/__init__.py +21 -1
  181. qiskit/synthesis/arithmetic/__init__.py +3 -1
  182. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  183. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  184. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  185. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  186. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  187. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  188. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  189. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  190. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  191. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  192. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  193. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  194. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  195. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  196. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  197. qiskit/synthesis/evolution/product_formula.py +44 -35
  198. qiskit/synthesis/evolution/qdrift.py +17 -24
  199. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  200. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  201. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  202. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  203. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  204. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  205. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  206. qiskit/synthesis/two_qubit/__init__.py +1 -0
  207. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  208. qiskit/transpiler/__init__.py +32 -232
  209. qiskit/transpiler/basepasses.py +20 -51
  210. qiskit/transpiler/layout.py +1 -1
  211. qiskit/transpiler/passes/__init__.py +4 -40
  212. qiskit/transpiler/passes/basis/basis_translator.py +5 -4
  213. qiskit/transpiler/passes/basis/decompose.py +1 -15
  214. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  215. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  216. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  217. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  218. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
  219. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  220. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  221. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  222. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  223. qiskit/transpiler/passes/optimization/__init__.py +2 -3
  224. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  225. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  226. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  227. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  228. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  229. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  230. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  231. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  232. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  233. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  234. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  235. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  236. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  237. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  238. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -2
  239. qiskit/transpiler/passes/routing/__init__.py +0 -1
  240. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  241. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  242. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  243. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  244. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  245. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  246. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  247. qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
  248. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
  249. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
  250. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  251. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  252. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  253. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
  254. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  255. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  256. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  257. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  258. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  259. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  260. qiskit/transpiler/passes/utils/__init__.py +0 -1
  261. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  262. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  263. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  264. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  265. qiskit/transpiler/passmanager.py +13 -0
  266. qiskit/transpiler/passmanager_config.py +5 -81
  267. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  268. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  269. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
  270. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  272. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  273. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  274. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  275. qiskit/transpiler/target.py +78 -524
  276. qiskit/user_config.py +8 -4
  277. qiskit/utils/__init__.py +13 -12
  278. qiskit/utils/deprecation.py +4 -112
  279. qiskit/utils/optionals.py +11 -4
  280. qiskit/utils/parallel.py +214 -87
  281. qiskit/utils/units.py +4 -1
  282. qiskit/visualization/__init__.py +3 -7
  283. qiskit/visualization/array.py +4 -1
  284. qiskit/visualization/bloch.py +1 -1
  285. qiskit/visualization/circuit/_utils.py +19 -19
  286. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  287. qiskit/visualization/circuit/matplotlib.py +13 -23
  288. qiskit/visualization/circuit/text.py +7 -3
  289. qiskit/visualization/counts_visualization.py +4 -0
  290. qiskit/visualization/dag_visualization.py +2 -1
  291. qiskit/visualization/gate_map.py +39 -154
  292. qiskit/visualization/library.py +4 -1
  293. qiskit/visualization/pass_manager_visualization.py +6 -2
  294. qiskit/visualization/state_visualization.py +19 -2
  295. qiskit/visualization/timeline/core.py +19 -13
  296. qiskit/visualization/timeline/interface.py +19 -18
  297. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  298. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
  299. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
  300. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
  301. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
  302. qiskit/assembler/__init__.py +0 -42
  303. qiskit/assembler/assemble_circuits.py +0 -451
  304. qiskit/assembler/assemble_schedules.py +0 -367
  305. qiskit/assembler/disassemble.py +0 -310
  306. qiskit/assembler/run_config.py +0 -77
  307. qiskit/circuit/bit.py +0 -106
  308. qiskit/circuit/classicalfunction/__init__.py +0 -152
  309. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  310. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  311. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  312. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  313. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  314. qiskit/circuit/classicalfunction/types.py +0 -18
  315. qiskit/circuit/classicalfunction/utils.py +0 -91
  316. qiskit/circuit/classicalregister.py +0 -57
  317. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  318. qiskit/circuit/quantumregister.py +0 -75
  319. qiskit/circuit/register.py +0 -246
  320. qiskit/compiler/assembler.py +0 -689
  321. qiskit/compiler/scheduler.py +0 -109
  322. qiskit/compiler/sequencer.py +0 -71
  323. qiskit/primitives/backend_estimator.py +0 -486
  324. qiskit/primitives/backend_sampler.py +0 -222
  325. qiskit/primitives/estimator.py +0 -172
  326. qiskit/primitives/sampler.py +0 -162
  327. qiskit/providers/backend_compat.py +0 -507
  328. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  333. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  335. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  336. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  339. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  341. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  343. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  344. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  345. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  348. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  349. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  350. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  351. qiskit/providers/fake_provider/fake_1q.py +0 -91
  352. qiskit/providers/fake_provider/fake_backend.py +0 -165
  353. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  354. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  355. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  356. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  357. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  358. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  359. qiskit/providers/models/__init__.py +0 -89
  360. qiskit/providers/models/backendconfiguration.py +0 -1040
  361. qiskit/providers/models/backendproperties.py +0 -535
  362. qiskit/providers/models/backendstatus.py +0 -104
  363. qiskit/providers/models/jobstatus.py +0 -77
  364. qiskit/providers/models/pulsedefaults.py +0 -305
  365. qiskit/providers/provider.py +0 -95
  366. qiskit/pulse/__init__.py +0 -158
  367. qiskit/pulse/builder.py +0 -2262
  368. qiskit/pulse/calibration_entries.py +0 -381
  369. qiskit/pulse/channels.py +0 -227
  370. qiskit/pulse/configuration.py +0 -245
  371. qiskit/pulse/exceptions.py +0 -45
  372. qiskit/pulse/filters.py +0 -309
  373. qiskit/pulse/instruction_schedule_map.py +0 -424
  374. qiskit/pulse/instructions/__init__.py +0 -67
  375. qiskit/pulse/instructions/acquire.py +0 -150
  376. qiskit/pulse/instructions/delay.py +0 -71
  377. qiskit/pulse/instructions/directives.py +0 -154
  378. qiskit/pulse/instructions/frequency.py +0 -135
  379. qiskit/pulse/instructions/instruction.py +0 -270
  380. qiskit/pulse/instructions/phase.py +0 -152
  381. qiskit/pulse/instructions/play.py +0 -99
  382. qiskit/pulse/instructions/reference.py +0 -100
  383. qiskit/pulse/instructions/snapshot.py +0 -82
  384. qiskit/pulse/library/__init__.py +0 -97
  385. qiskit/pulse/library/continuous.py +0 -430
  386. qiskit/pulse/library/pulse.py +0 -148
  387. qiskit/pulse/library/samplers/__init__.py +0 -15
  388. qiskit/pulse/library/samplers/decorators.py +0 -295
  389. qiskit/pulse/library/samplers/strategies.py +0 -71
  390. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  391. qiskit/pulse/library/waveform.py +0 -136
  392. qiskit/pulse/macros.py +0 -262
  393. qiskit/pulse/parameter_manager.py +0 -445
  394. qiskit/pulse/parser.py +0 -314
  395. qiskit/pulse/reference_manager.py +0 -58
  396. qiskit/pulse/schedule.py +0 -1854
  397. qiskit/pulse/transforms/__init__.py +0 -106
  398. qiskit/pulse/transforms/alignments.py +0 -406
  399. qiskit/pulse/transforms/base_transforms.py +0 -71
  400. qiskit/pulse/transforms/canonicalization.py +0 -498
  401. qiskit/pulse/transforms/dag.py +0 -122
  402. qiskit/pulse/utils.py +0 -149
  403. qiskit/qobj/__init__.py +0 -75
  404. qiskit/qobj/common.py +0 -81
  405. qiskit/qobj/converters/__init__.py +0 -18
  406. qiskit/qobj/converters/lo_config.py +0 -177
  407. qiskit/qobj/converters/pulse_instruction.py +0 -897
  408. qiskit/qobj/pulse_qobj.py +0 -709
  409. qiskit/qobj/qasm_qobj.py +0 -708
  410. qiskit/qobj/utils.py +0 -46
  411. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  412. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  413. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  414. qiskit/result/mitigation/utils.py +0 -217
  415. qiskit/scheduler/__init__.py +0 -40
  416. qiskit/scheduler/config.py +0 -37
  417. qiskit/scheduler/lowering.py +0 -187
  418. qiskit/scheduler/methods/__init__.py +0 -15
  419. qiskit/scheduler/methods/basic.py +0 -140
  420. qiskit/scheduler/schedule_circuit.py +0 -69
  421. qiskit/scheduler/sequence.py +0 -104
  422. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  423. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  424. qiskit/transpiler/passes/calibration/builders.py +0 -20
  425. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  426. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  427. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  428. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  429. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  430. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  431. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  432. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  433. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  434. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  435. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  436. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  437. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  438. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  439. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  440. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  441. qiskit/utils/deprecate_pulse.py +0 -119
  442. qiskit/utils/multiprocessing.py +0 -56
  443. qiskit/visualization/pulse_v2/__init__.py +0 -21
  444. qiskit/visualization/pulse_v2/core.py +0 -901
  445. qiskit/visualization/pulse_v2/device_info.py +0 -173
  446. qiskit/visualization/pulse_v2/drawings.py +0 -253
  447. qiskit/visualization/pulse_v2/events.py +0 -254
  448. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  449. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  450. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  451. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  452. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  453. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  454. qiskit/visualization/pulse_v2/interface.py +0 -459
  455. qiskit/visualization/pulse_v2/layouts.py +0 -387
  456. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  457. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  458. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  459. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  460. qiskit/visualization/pulse_v2/types.py +0 -242
  461. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  462. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
@@ -33,16 +33,15 @@ data, and it's best to point to the same instance of the data where possible rat
33
33
  heap-allocating a new version of the same thing. Where possible, the class constructors will return
34
34
  singleton instances to facilitate this.
35
35
 
36
- The two different types available are for Booleans (corresponding to :class:`.Clbit` and the
37
- literals ``True`` and ``False``), and unsigned integers (corresponding to
38
- :class:`.ClassicalRegister` and Python integers).
36
+ The :class:`Bool` type represents :class:`.Clbit` and the literals ``True`` and ``False``, the
37
+ :class:`Uint` type represents :class:`.ClassicalRegister` and Python integers, the :class:`Float`
38
+ type represents Python floats, and the :class:`Duration` type represents a duration for use in
39
+ timing-aware circuit operations.
39
40
 
40
41
  .. autoclass:: Bool
41
42
  .. autoclass:: Uint
42
-
43
- Note that :class:`Uint` defines a family of types parametrized by their width; it is not one single
44
- type, which may be slightly different to the 'classical' programming languages you are used to.
45
-
43
+ .. autoclass:: Float
44
+ .. autoclass:: Duration
46
45
 
47
46
  Working with types
48
47
  ==================
@@ -89,12 +88,17 @@ embedded into the :mod:`types` module. You can query the casting kinds using :f
89
88
  The return values from this function are an enumeration explaining the types of cast that are
90
89
  allowed from the left type to the right type.
91
90
 
91
+ Note that casts between :class:`Float` and :class:`Uint` are considered dangerous in either
92
+ direction, and must be done explicitly.
93
+
92
94
  .. autoclass:: CastKind
93
95
  """
94
96
 
95
97
  __all__ = [
96
98
  "Type",
97
99
  "Bool",
100
+ "Duration",
101
+ "Float",
98
102
  "Uint",
99
103
  "Ordering",
100
104
  "order",
@@ -105,5 +109,5 @@ __all__ = [
105
109
  "cast_kind",
106
110
  ]
107
111
 
108
- from .types import Type, Bool, Uint
112
+ from .types import Type, Bool, Duration, Float, Uint
109
113
  from .ordering import Ordering, order, is_subtype, is_supertype, greater, CastKind, cast_kind
@@ -26,7 +26,7 @@ __all__ = [
26
26
 
27
27
  import enum
28
28
 
29
- from .types import Type, Bool, Uint
29
+ from .types import Type, Bool, Duration, Float, Uint
30
30
 
31
31
 
32
32
  # While the type system is simple, it's overkill to represent the complete partial ordering graph of
@@ -55,10 +55,6 @@ class Ordering(enum.Enum):
55
55
  return str(self)
56
56
 
57
57
 
58
- def _order_bool_bool(_a: Bool, _b: Bool, /) -> Ordering:
59
- return Ordering.EQUAL
60
-
61
-
62
58
  def _order_uint_uint(left: Uint, right: Uint, /) -> Ordering:
63
59
  if left.width < right.width:
64
60
  return Ordering.LESS
@@ -68,8 +64,10 @@ def _order_uint_uint(left: Uint, right: Uint, /) -> Ordering:
68
64
 
69
65
 
70
66
  _ORDERERS = {
71
- (Bool, Bool): _order_bool_bool,
67
+ (Bool, Bool): lambda _a, _b, /: Ordering.EQUAL,
72
68
  (Uint, Uint): _order_uint_uint,
69
+ (Float, Float): lambda _a, _b, /: Ordering.EQUAL,
70
+ (Duration, Duration): lambda _a, _b, /: Ordering.EQUAL,
73
71
  }
74
72
 
75
73
 
@@ -195,8 +193,14 @@ def _uint_cast(from_: Uint, to_: Uint, /) -> CastKind:
195
193
  _ALLOWED_CASTS = {
196
194
  (Bool, Bool): lambda _a, _b, /: CastKind.EQUAL,
197
195
  (Bool, Uint): lambda _a, _b, /: CastKind.LOSSLESS,
196
+ (Bool, Float): lambda _a, _b, /: CastKind.LOSSLESS,
198
197
  (Uint, Bool): lambda _a, _b, /: CastKind.IMPLICIT,
199
198
  (Uint, Uint): _uint_cast,
199
+ (Uint, Float): lambda _a, _b, /: CastKind.DANGEROUS,
200
+ (Float, Float): lambda _a, _b, /: CastKind.EQUAL,
201
+ (Float, Uint): lambda _a, _b, /: CastKind.DANGEROUS,
202
+ (Float, Bool): lambda _a, _b, /: CastKind.DANGEROUS,
203
+ (Duration, Duration): lambda _a, _b, /: CastKind.EQUAL,
200
204
  }
201
205
 
202
206
 
@@ -205,7 +209,10 @@ def cast_kind(from_: Type, to_: Type, /) -> CastKind:
205
209
 
206
210
  Examples:
207
211
 
208
- .. code-block:: python
212
+ .. plot::
213
+ :include-source:
214
+ :nofigs:
215
+
209
216
 
210
217
  >>> from qiskit.circuit.classical import types
211
218
  >>> types.cast_kind(types.Bool(), types.Bool())
@@ -22,6 +22,8 @@ from __future__ import annotations
22
22
  __all__ = [
23
23
  "Type",
24
24
  "Bool",
25
+ "Duration",
26
+ "Float",
25
27
  "Uint",
26
28
  ]
27
29
 
@@ -115,3 +117,37 @@ class Uint(Type):
115
117
 
116
118
  def __eq__(self, other):
117
119
  return isinstance(other, Uint) and self.width == other.width
120
+
121
+
122
+ @typing.final
123
+ class Float(Type, metaclass=_Singleton):
124
+ """An IEEE-754 double-precision floating point number.
125
+ In the future, this may also be used to represent other fixed-width floats.
126
+ """
127
+
128
+ __slots__ = ()
129
+
130
+ def __repr__(self):
131
+ return "Float()"
132
+
133
+ def __hash__(self):
134
+ return hash(self.__class__)
135
+
136
+ def __eq__(self, other):
137
+ return isinstance(other, Float)
138
+
139
+
140
+ @typing.final
141
+ class Duration(Type, metaclass=_Singleton):
142
+ """A length of time, possibly negative."""
143
+
144
+ __slots__ = ()
145
+
146
+ def __repr__(self):
147
+ return "Duration()"
148
+
149
+ def __hash__(self):
150
+ return hash(self.__class__)
151
+
152
+ def __eq__(self, other):
153
+ return isinstance(other, Duration)
@@ -12,6 +12,7 @@
12
12
 
13
13
  """Code from commutative_analysis pass that checks commutation relations between DAG nodes."""
14
14
 
15
+ from __future__ import annotations
15
16
  from typing import List, Union, Set, Optional
16
17
 
17
18
  from qiskit.circuit.operation import Operation
@@ -19,11 +20,31 @@ from qiskit._accelerate.commutation_checker import CommutationChecker as RustChe
19
20
 
20
21
 
21
22
  class CommutationChecker:
22
- """This code is essentially copy-pasted from commutative_analysis.py.
23
- This code cleverly hashes commutativity and non-commutativity results between DAG nodes and seems
24
- quite efficient for large Clifford circuits.
25
- They may be other possible efficiency improvements: using rule-based commutativity analysis,
26
- evicting from the cache less useful entries, etc.
23
+ r"""Check commutations of two operations.
24
+
25
+ Two unitaries :math:`A` and :math:`B` on :math:`n` qubits commute if
26
+
27
+ .. math::
28
+
29
+ \frac{2^n F_{\text{process}}(AB, BA) + 1}{2^n + 1} > 1 - \varepsilon,
30
+
31
+ where
32
+
33
+ .. math::
34
+
35
+ F_{\text{process}}(U_1, U_2) = \left|\frac{\mathrm{Tr}(U_1 U_2^\dagger)}{2^n} \right|^2,
36
+
37
+ and we set :math:`\varepsilon` to :math:`10^{-12}` to account for round-off errors on
38
+ few-qubit systems. This metric is chosen for consistency with other closeness checks in
39
+ Qiskit.
40
+
41
+ When possible, commutation relations are queried from a lookup table. This is the case
42
+ for standard gates without parameters (such as :class:`.XGate` or :class:`.HGate`) or
43
+ gates with free parameters (such as :class:`.RXGate` with a :class:`.ParameterExpression` as
44
+ angle). Otherwise, a matrix-based check is performed, where two operations are said to
45
+ commute, if the average gate fidelity of performing the commutation is above a certain threshold
46
+ (see ``approximation_degree``). The result of this commutation is then added to the
47
+ cached lookup table.
27
48
  """
28
49
 
29
50
  def __init__(
@@ -40,9 +61,10 @@ class CommutationChecker:
40
61
  op1,
41
62
  op2,
42
63
  max_num_qubits: int = 3,
64
+ approximation_degree: float = 1.0,
43
65
  ) -> bool:
44
66
  """Checks if two DAGOpNodes commute."""
45
- return self.cc.commute_nodes(op1, op2, max_num_qubits)
67
+ return self.cc.commute_nodes(op1, op2, max_num_qubits, approximation_degree)
46
68
 
47
69
  def commute(
48
70
  self,
@@ -53,6 +75,7 @@ class CommutationChecker:
53
75
  qargs2: List,
54
76
  cargs2: List,
55
77
  max_num_qubits: int = 3,
78
+ approximation_degree: float = 1.0,
56
79
  ) -> bool:
57
80
  """
58
81
  Checks if two Operations commute. The return value of `True` means that the operations
@@ -69,11 +92,15 @@ class CommutationChecker:
69
92
  cargs2: second operation's clbits.
70
93
  max_num_qubits: the maximum number of qubits to consider, the check may be skipped if
71
94
  the number of qubits for either operation exceeds this amount.
95
+ approximation_degree: If the average gate fidelity in between the two operations
96
+ is above this number (up to ``1e-12``) they are assumed to commute.
72
97
 
73
98
  Returns:
74
99
  bool: whether two operations commute.
75
100
  """
76
- return self.cc.commute(op1, qargs1, cargs1, op2, qargs2, cargs2, max_num_qubits)
101
+ return self.cc.commute(
102
+ op1, qargs1, cargs1, op2, qargs2, cargs2, max_num_qubits, approximation_degree
103
+ )
77
104
 
78
105
  def num_cached_entries(self):
79
106
  """Returns number of cached entries"""
@@ -18,11 +18,42 @@ from .control_flow import ControlFlowOp
18
18
  from .continue_loop import ContinueLoopOp
19
19
  from .break_loop import BreakLoopOp
20
20
 
21
+ from .box import BoxOp
21
22
  from .if_else import IfElseOp
22
23
  from .while_loop import WhileLoopOp
23
24
  from .for_loop import ForLoopOp
24
25
  from .switch_case import SwitchCaseOp, CASE_DEFAULT
25
26
 
26
27
 
27
- CONTROL_FLOW_OP_NAMES = frozenset(("for_loop", "while_loop", "if_else", "switch_case"))
28
+ CONTROL_FLOW_OP_NAMES = frozenset(("for_loop", "while_loop", "if_else", "switch_case", "box"))
28
29
  """Set of the instruction names of Qiskit's known control-flow operations."""
30
+
31
+
32
+ def get_control_flow_name_mapping():
33
+ """Return a dictionary mapping the names of control-flow operations
34
+ to their corresponding classes."
35
+
36
+ Examples:
37
+
38
+ .. code-block:: python
39
+
40
+ from qiskit.circuit import get_control_flow_name_mapping
41
+
42
+ ctrl_flow_name_map = get_control_flow_name_mapping()
43
+ if_else_object = ctrl_flow_name_map["if_else"]
44
+
45
+ print(if_else_object)
46
+
47
+ .. code-block:: text
48
+
49
+ <class 'qiskit.circuit.controlflow.if_else.IfElseOp'>
50
+ """
51
+
52
+ name_mapping = {
53
+ "if_else": IfElseOp,
54
+ "while_loop": WhileLoopOp,
55
+ "for_loop": ForLoopOp,
56
+ "switch_case": SwitchCaseOp,
57
+ "box": BoxOp,
58
+ }
59
+ return name_mapping
@@ -17,14 +17,16 @@ from __future__ import annotations
17
17
  import dataclasses
18
18
  from typing import Iterable, Tuple, Set, Union, TypeVar, TYPE_CHECKING
19
19
 
20
+ from qiskit.circuit import ( # pylint: disable=cyclic-import
21
+ ClassicalRegister,
22
+ Clbit,
23
+ QuantumRegister,
24
+ )
20
25
  from qiskit.circuit.classical import expr, types
21
26
  from qiskit.circuit.exceptions import CircuitError
22
- from qiskit.circuit.register import Register
23
- from qiskit.circuit.classicalregister import ClassicalRegister, Clbit
24
- from qiskit.circuit.quantumregister import QuantumRegister
25
27
 
26
28
  if TYPE_CHECKING:
27
- from qiskit.circuit import QuantumCircuit
29
+ from qiskit.circuit import QuantumCircuit, Register
28
30
 
29
31
  _ConditionT = TypeVar(
30
32
  "_ConditionT", bound=Union[Tuple[ClassicalRegister, int], Tuple[Clbit, int], expr.Expr]
@@ -180,10 +182,12 @@ def _unify_circuit_resources_rebuild( # pylint: disable=invalid-name # (it's t
180
182
  *circuit.cregs,
181
183
  global_phase=circuit.global_phase,
182
184
  inputs=circuit.iter_input_vars(),
183
- captures=circuit.iter_captured_vars(),
185
+ captures=circuit.iter_captures(),
184
186
  )
185
187
  for var in circuit.iter_declared_vars():
186
188
  out.add_uninitialized_var(var)
189
+ for stretch in circuit.iter_declared_stretches():
190
+ out.add_stretch(stretch)
187
191
  for instruction in circuit.data:
188
192
  out._append(instruction)
189
193
  out_circuits.append(out)
@@ -0,0 +1,163 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2025.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+
13
+ """Simple box basic block."""
14
+
15
+ from __future__ import annotations
16
+
17
+ import typing
18
+
19
+ from qiskit.circuit.exceptions import CircuitError
20
+ from .control_flow import ControlFlowOp
21
+
22
+ if typing.TYPE_CHECKING:
23
+ from qiskit.circuit import QuantumCircuit
24
+
25
+
26
+ class BoxOp(ControlFlowOp):
27
+ """A scoped "box" of operations on a circuit that are treated atomically in the greater context.
28
+
29
+ A "box" is a control-flow construct that is entered unconditionally. The contents of the box
30
+ behave somewhat as if the start and end of the box were barriers, except it is permissible to
31
+ commute operations "all the way" through the box. The box is also an explicit scope for the
32
+ purposes of variables, stretches and compiler passes.
33
+
34
+ Typically you create this by using the builder-interface form of :meth:`.QuantumCircuit.box`.
35
+ """
36
+
37
+ def __init__(
38
+ self,
39
+ body: QuantumCircuit,
40
+ duration: None = None,
41
+ unit: typing.Literal["dt", "s", "ms", "us", "ns", "ps"] = "dt",
42
+ label: str | None = None,
43
+ ):
44
+ """
45
+ Default constructor of :class:`BoxOp`.
46
+
47
+ Args:
48
+ body: the circuit to use as the body of the box. This should explicit close over any
49
+ :class:`.expr.Var` variables that must be incident from the outer circuit. The
50
+ expected number of qubit and clbits for the resulting instruction are inferred from
51
+ the number in the circuit, even if they are idle.
52
+ duration: an optional duration for the box as a whole.
53
+ unit: the unit of the ``duration``.
54
+ label: an optional string label for the instruction.
55
+ """
56
+ super().__init__("box", body.num_qubits, body.num_clbits, [body], label=label)
57
+ self.duration = duration
58
+ self.unit = unit
59
+
60
+ @property
61
+ def params(self):
62
+ return self._params
63
+
64
+ @params.setter
65
+ def params(self, parameters):
66
+ # pylint: disable=cyclic-import
67
+ from qiskit.circuit import QuantumCircuit
68
+
69
+ (body,) = parameters
70
+
71
+ if not isinstance(body, QuantumCircuit):
72
+ raise CircuitError(
73
+ "BoxOp expects a body parameter of type "
74
+ f"QuantumCircuit, but received {type(body)}."
75
+ )
76
+
77
+ if body.num_qubits != self.num_qubits or body.num_clbits != self.num_clbits:
78
+ raise CircuitError(
79
+ "Attempted to assign a body parameter with a num_qubits or "
80
+ "num_clbits different than that of the BoxOp. "
81
+ f"BoxOp num_qubits/clbits: {self.num_qubits}/{self.num_clbits} "
82
+ f"Supplied body num_qubits/clbits: {body.num_qubits}/{body.num_clbits}."
83
+ )
84
+
85
+ self._params = [body]
86
+
87
+ @property
88
+ def body(self):
89
+ """The ``body`` :class:`.QuantumCircuit` of the operation.
90
+
91
+ This is the same as object returned as the sole entry in :meth:`params` and :meth:`blocks`.
92
+ """
93
+ # Not settable via this property; the only meaningful way to replace a body is via
94
+ # larger `QuantumCircuit` methods, or using `replace_blocks`.
95
+ return self.params[0]
96
+
97
+ @property
98
+ def blocks(self):
99
+ return (self._params[0],)
100
+
101
+ def replace_blocks(self, blocks):
102
+ (body,) = blocks
103
+ return BoxOp(body, duration=self.duration, unit=self.unit, label=self.label)
104
+
105
+ def __eq__(self, other):
106
+ return (
107
+ isinstance(other, BoxOp)
108
+ and self.duration == other.duration
109
+ and self.unit == other.unit
110
+ and super().__eq__(other)
111
+ )
112
+
113
+
114
+ class BoxContext:
115
+ """Context-manager that powers :meth:`.QuantumCircuit.box`.
116
+
117
+ This is not part of the public interface, and should not be instantiated by users.
118
+ """
119
+
120
+ __slots__ = ("_circuit", "_duration", "_unit", "_label")
121
+
122
+ def __init__(
123
+ self,
124
+ circuit: QuantumCircuit,
125
+ *,
126
+ duration: None = None,
127
+ unit: typing.Literal["dt", "s", "ms", "us", "ns", "ps"] = "dt",
128
+ label: str | None = None,
129
+ ):
130
+ """
131
+ Args:
132
+ circuit: the outermost scope of the circuit under construction.
133
+ duration: the final duration of the box.
134
+ unit: the unit of ``duration``.
135
+ label: an optional label for the box.
136
+ """
137
+ self._circuit = circuit
138
+ self._duration = duration
139
+ self._unit = unit
140
+ self._label = label
141
+
142
+ def __enter__(self):
143
+ # For a box to have the semantics of internal qubit alignment with a resolvable duration, we
144
+ # can't allow conditional jumps to exit it. Technically an unconditional `break` or
145
+ # `continue` could work, but we're not getting into that.
146
+ self._circuit._push_scope(allow_jumps=False)
147
+
148
+ def __exit__(self, exc_type, exc_val, exc_tb):
149
+ if exc_type is not None:
150
+ # If we're leaving the context manager because an exception was raised, there's nothing
151
+ # to do except restore the circuit state.
152
+ self._circuit._pop_scope()
153
+ return False
154
+ scope = self._circuit._pop_scope()
155
+ # Boxes do not need to pass any further resources in, because there's no jumps out of a
156
+ # `box` permitted.
157
+ body = scope.build(scope.qubits(), scope.clbits())
158
+ self._circuit.append(
159
+ BoxOp(body, duration=self._duration, unit=self._unit, label=self._label),
160
+ body.qubits,
161
+ body.clbits,
162
+ )
163
+ return False
@@ -48,7 +48,7 @@ class BreakLoopPlaceholder(InstructionPlaceholder):
48
48
 
49
49
  def concrete_instruction(self, qubits, clbits):
50
50
  return (
51
- self._copy_mutable_properties(BreakLoopOp(len(qubits), len(clbits), label=self.label)),
51
+ BreakLoopOp(len(qubits), len(clbits), label=self.label),
52
52
  InstructionResources(qubits=tuple(qubits), clbits=tuple(clbits)),
53
53
  )
54
54