qiskit 1.4.0__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0rc1__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 (456) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +2 -5
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +24 -5
  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 +248 -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 +7 -140
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +34 -5
  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/hamiltonian_gate.py +1 -1
  60. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  61. qiskit/circuit/library/n_local/n_local.py +1 -1
  62. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  63. qiskit/circuit/library/overlap.py +2 -2
  64. qiskit/circuit/library/pauli_evolution.py +39 -24
  65. qiskit/circuit/library/phase_oracle.py +130 -51
  66. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  67. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  68. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  69. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  70. qiskit/circuit/library/standard_gates/h.py +4 -9
  71. qiskit/circuit/library/standard_gates/i.py +2 -2
  72. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  73. qiskit/circuit/library/standard_gates/p.py +15 -34
  74. qiskit/circuit/library/standard_gates/r.py +2 -6
  75. qiskit/circuit/library/standard_gates/rx.py +5 -15
  76. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  77. qiskit/circuit/library/standard_gates/ry.py +5 -17
  78. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  79. qiskit/circuit/library/standard_gates/rz.py +5 -17
  80. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  82. qiskit/circuit/library/standard_gates/s.py +6 -15
  83. qiskit/circuit/library/standard_gates/swap.py +4 -11
  84. qiskit/circuit/library/standard_gates/sx.py +7 -12
  85. qiskit/circuit/library/standard_gates/t.py +6 -7
  86. qiskit/circuit/library/standard_gates/u.py +2 -10
  87. qiskit/circuit/library/standard_gates/u1.py +5 -16
  88. qiskit/circuit/library/standard_gates/u2.py +2 -6
  89. qiskit/circuit/library/standard_gates/u3.py +3 -11
  90. qiskit/circuit/library/standard_gates/x.py +13 -60
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/y.py +4 -9
  94. qiskit/circuit/library/standard_gates/z.py +5 -15
  95. qiskit/circuit/measure.py +11 -2
  96. qiskit/circuit/parameterexpression.py +4 -0
  97. qiskit/circuit/quantumcircuit.py +881 -555
  98. qiskit/circuit/random/utils.py +12 -6
  99. qiskit/circuit/reset.py +5 -2
  100. qiskit/circuit/singleton.py +5 -11
  101. qiskit/circuit/store.py +0 -8
  102. qiskit/compiler/__init__.py +1 -7
  103. qiskit/compiler/transpiler.py +38 -196
  104. qiskit/converters/circuit_to_dag.py +4 -2
  105. qiskit/converters/circuit_to_dagdependency.py +0 -2
  106. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  107. qiskit/converters/circuit_to_gate.py +1 -1
  108. qiskit/converters/circuit_to_instruction.py +16 -29
  109. qiskit/converters/dag_to_circuit.py +5 -5
  110. qiskit/converters/dag_to_dagdependency.py +0 -1
  111. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  112. qiskit/converters/dagdependency_to_circuit.py +0 -6
  113. qiskit/converters/dagdependency_to_dag.py +0 -6
  114. qiskit/dagcircuit/collect_blocks.py +32 -20
  115. qiskit/dagcircuit/dagdependency.py +3 -37
  116. qiskit/dagcircuit/dagdependency_v2.py +2 -80
  117. qiskit/dagcircuit/dagnode.py +14 -2
  118. qiskit/passmanager/__init__.py +24 -6
  119. qiskit/passmanager/passmanager.py +26 -24
  120. qiskit/primitives/__init__.py +44 -35
  121. qiskit/primitives/backend_estimator_v2.py +102 -23
  122. qiskit/primitives/backend_sampler_v2.py +5 -20
  123. qiskit/primitives/base/__init__.py +4 -4
  124. qiskit/primitives/base/base_estimator.py +77 -82
  125. qiskit/primitives/base/base_primitive_job.py +2 -2
  126. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  127. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  128. qiskit/primitives/base/base_sampler.py +52 -60
  129. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  130. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  131. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  132. qiskit/primitives/containers/bindings_array.py +3 -1
  133. qiskit/primitives/containers/bit_array.py +23 -0
  134. qiskit/primitives/containers/data_bin.py +3 -1
  135. qiskit/primitives/containers/observables_array.py +19 -2
  136. qiskit/primitives/statevector_sampler.py +6 -8
  137. qiskit/primitives/utils.py +14 -189
  138. qiskit/providers/__init__.py +4 -130
  139. qiskit/providers/backend.py +11 -314
  140. qiskit/providers/basic_provider/__init__.py +3 -1
  141. qiskit/providers/basic_provider/basic_provider.py +29 -9
  142. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  143. qiskit/providers/exceptions.py +0 -33
  144. qiskit/providers/fake_provider/__init__.py +0 -37
  145. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  146. qiskit/qasm2/__init__.py +21 -6
  147. qiskit/qasm2/export.py +2 -10
  148. qiskit/qasm2/parse.py +11 -25
  149. qiskit/qasm3/__init__.py +5 -1
  150. qiskit/qasm3/ast.py +44 -0
  151. qiskit/qasm3/exporter.py +65 -27
  152. qiskit/qasm3/printer.py +35 -4
  153. qiskit/qpy/__init__.py +141 -19
  154. qiskit/qpy/binary_io/__init__.py +0 -1
  155. qiskit/qpy/binary_io/circuits.py +91 -116
  156. qiskit/qpy/binary_io/schedules.py +61 -388
  157. qiskit/qpy/binary_io/value.py +168 -28
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +29 -62
  161. qiskit/qpy/type_keys.py +58 -221
  162. qiskit/quantum_info/analysis/distance.py +3 -1
  163. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  164. qiskit/quantum_info/operators/operator.py +6 -2
  165. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  166. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  167. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  169. qiskit/quantum_info/states/densitymatrix.py +16 -6
  170. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  171. qiskit/quantum_info/states/statevector.py +16 -6
  172. qiskit/result/__init__.py +5 -17
  173. qiskit/result/models.py +18 -10
  174. qiskit/result/result.py +28 -126
  175. qiskit/result/sampled_expval.py +1 -2
  176. qiskit/result/utils.py +3 -4
  177. qiskit/synthesis/__init__.py +21 -1
  178. qiskit/synthesis/arithmetic/__init__.py +3 -1
  179. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  180. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  182. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  183. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  184. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  185. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  186. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  188. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  189. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  190. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  191. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  192. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +2 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +5 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +67 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/dag_visualization.py +2 -1
  287. qiskit/visualization/gate_map.py +39 -154
  288. qiskit/visualization/pass_manager_visualization.py +6 -2
  289. qiskit/visualization/state_visualization.py +6 -0
  290. qiskit/visualization/timeline/core.py +27 -12
  291. qiskit/visualization/timeline/interface.py +23 -18
  292. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
  293. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
  294. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +2 -1
  295. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
  296. qiskit/assembler/__init__.py +0 -42
  297. qiskit/assembler/assemble_circuits.py +0 -451
  298. qiskit/assembler/assemble_schedules.py +0 -367
  299. qiskit/assembler/disassemble.py +0 -310
  300. qiskit/assembler/run_config.py +0 -77
  301. qiskit/circuit/bit.py +0 -106
  302. qiskit/circuit/classicalfunction/__init__.py +0 -152
  303. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  304. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  305. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  306. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  307. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  308. qiskit/circuit/classicalfunction/types.py +0 -18
  309. qiskit/circuit/classicalfunction/utils.py +0 -91
  310. qiskit/circuit/classicalregister.py +0 -57
  311. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  312. qiskit/circuit/quantumregister.py +0 -75
  313. qiskit/circuit/register.py +0 -246
  314. qiskit/compiler/assembler.py +0 -689
  315. qiskit/compiler/scheduler.py +0 -109
  316. qiskit/compiler/sequencer.py +0 -71
  317. qiskit/primitives/backend_estimator.py +0 -486
  318. qiskit/primitives/backend_sampler.py +0 -222
  319. qiskit/primitives/estimator.py +0 -172
  320. qiskit/primitives/sampler.py +0 -162
  321. qiskit/providers/backend_compat.py +0 -507
  322. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  330. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/fake_1q.py +0 -91
  346. qiskit/providers/fake_provider/fake_backend.py +0 -165
  347. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  348. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  349. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  350. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  351. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  352. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  353. qiskit/providers/models/__init__.py +0 -89
  354. qiskit/providers/models/backendconfiguration.py +0 -1040
  355. qiskit/providers/models/backendproperties.py +0 -535
  356. qiskit/providers/models/backendstatus.py +0 -104
  357. qiskit/providers/models/jobstatus.py +0 -77
  358. qiskit/providers/models/pulsedefaults.py +0 -305
  359. qiskit/providers/provider.py +0 -95
  360. qiskit/pulse/__init__.py +0 -158
  361. qiskit/pulse/builder.py +0 -2262
  362. qiskit/pulse/calibration_entries.py +0 -381
  363. qiskit/pulse/channels.py +0 -227
  364. qiskit/pulse/configuration.py +0 -245
  365. qiskit/pulse/exceptions.py +0 -45
  366. qiskit/pulse/filters.py +0 -309
  367. qiskit/pulse/instruction_schedule_map.py +0 -424
  368. qiskit/pulse/instructions/__init__.py +0 -67
  369. qiskit/pulse/instructions/acquire.py +0 -150
  370. qiskit/pulse/instructions/delay.py +0 -71
  371. qiskit/pulse/instructions/directives.py +0 -154
  372. qiskit/pulse/instructions/frequency.py +0 -135
  373. qiskit/pulse/instructions/instruction.py +0 -270
  374. qiskit/pulse/instructions/phase.py +0 -152
  375. qiskit/pulse/instructions/play.py +0 -99
  376. qiskit/pulse/instructions/reference.py +0 -100
  377. qiskit/pulse/instructions/snapshot.py +0 -82
  378. qiskit/pulse/library/__init__.py +0 -97
  379. qiskit/pulse/library/continuous.py +0 -430
  380. qiskit/pulse/library/pulse.py +0 -148
  381. qiskit/pulse/library/samplers/__init__.py +0 -15
  382. qiskit/pulse/library/samplers/decorators.py +0 -295
  383. qiskit/pulse/library/samplers/strategies.py +0 -71
  384. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  385. qiskit/pulse/library/waveform.py +0 -136
  386. qiskit/pulse/macros.py +0 -262
  387. qiskit/pulse/parameter_manager.py +0 -445
  388. qiskit/pulse/parser.py +0 -314
  389. qiskit/pulse/reference_manager.py +0 -58
  390. qiskit/pulse/schedule.py +0 -1854
  391. qiskit/pulse/transforms/__init__.py +0 -106
  392. qiskit/pulse/transforms/alignments.py +0 -406
  393. qiskit/pulse/transforms/base_transforms.py +0 -71
  394. qiskit/pulse/transforms/canonicalization.py +0 -498
  395. qiskit/pulse/transforms/dag.py +0 -122
  396. qiskit/pulse/utils.py +0 -149
  397. qiskit/qobj/__init__.py +0 -75
  398. qiskit/qobj/common.py +0 -81
  399. qiskit/qobj/converters/__init__.py +0 -18
  400. qiskit/qobj/converters/lo_config.py +0 -177
  401. qiskit/qobj/converters/pulse_instruction.py +0 -897
  402. qiskit/qobj/pulse_qobj.py +0 -709
  403. qiskit/qobj/qasm_qobj.py +0 -708
  404. qiskit/qobj/utils.py +0 -46
  405. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  406. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  407. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  408. qiskit/result/mitigation/utils.py +0 -217
  409. qiskit/scheduler/__init__.py +0 -40
  410. qiskit/scheduler/config.py +0 -37
  411. qiskit/scheduler/lowering.py +0 -187
  412. qiskit/scheduler/methods/__init__.py +0 -15
  413. qiskit/scheduler/methods/basic.py +0 -140
  414. qiskit/scheduler/schedule_circuit.py +0 -69
  415. qiskit/scheduler/sequence.py +0 -104
  416. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  417. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  418. qiskit/transpiler/passes/calibration/builders.py +0 -20
  419. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  420. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  421. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  422. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  423. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  424. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  425. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  426. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  427. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  428. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  429. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  430. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  431. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  432. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  433. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  434. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  435. qiskit/utils/deprecate_pulse.py +0 -119
  436. qiskit/utils/multiprocessing.py +0 -56
  437. qiskit/visualization/pulse_v2/__init__.py +0 -21
  438. qiskit/visualization/pulse_v2/core.py +0 -901
  439. qiskit/visualization/pulse_v2/device_info.py +0 -173
  440. qiskit/visualization/pulse_v2/drawings.py +0 -253
  441. qiskit/visualization/pulse_v2/events.py +0 -254
  442. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  443. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  444. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  445. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  446. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  447. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  448. qiskit/visualization/pulse_v2/interface.py +0 -459
  449. qiskit/visualization/pulse_v2/layouts.py +0 -387
  450. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  451. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  452. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  453. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  454. qiskit/visualization/pulse_v2/types.py +0 -242
  455. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
  456. {qiskit-1.4.0.dist-info → qiskit-2.0.0rc1.dist-info}/top_level.txt +0 -0
@@ -14,7 +14,6 @@
14
14
  from __future__ import annotations
15
15
 
16
16
  import logging
17
- import warnings
18
17
  import numpy as np
19
18
 
20
19
  from qiskit.circuit import Gate, ParameterExpression, Qubit
@@ -59,9 +58,10 @@ class PadDynamicalDecoupling(BasePadding):
59
58
  import numpy as np
60
59
  from qiskit.circuit import QuantumCircuit
61
60
  from qiskit.circuit.library import XGate
62
- from qiskit.transpiler import PassManager, InstructionDurations
61
+ from qiskit.transpiler import PassManager, InstructionDurations, Target, CouplingMap
63
62
  from qiskit.transpiler.passes import ALAPScheduleAnalysis, PadDynamicalDecoupling
64
63
  from qiskit.visualization import timeline_drawer
64
+
65
65
  circ = QuantumCircuit(4)
66
66
  circ.h(0)
67
67
  circ.cx(0, 1)
@@ -71,7 +71,15 @@ class PadDynamicalDecoupling(BasePadding):
71
71
  durations = InstructionDurations(
72
72
  [("h", 0, 50), ("cx", [0, 1], 700), ("reset", None, 10),
73
73
  ("cx", [1, 2], 200), ("cx", [2, 3], 300),
74
- ("x", None, 50), ("measure", None, 1000)]
74
+ ("x", None, 50), ("measure", None, 1000)],
75
+ dt=1e-7
76
+ )
77
+ target = Target.from_configuration(
78
+ ["h", "cx", "reset", "x", "measure"],
79
+ num_qubits=4,
80
+ coupling_map=CouplingMap.from_line(4, bidirectional=False),
81
+ instruction_durations=durations,
82
+ dt=1e-7,
75
83
  )
76
84
 
77
85
  # balanced X-X sequence on all qubits
@@ -79,7 +87,7 @@ class PadDynamicalDecoupling(BasePadding):
79
87
  pm = PassManager([ALAPScheduleAnalysis(durations),
80
88
  PadDynamicalDecoupling(durations, dd_sequence)])
81
89
  circ_dd = pm.run(circ)
82
- timeline_drawer(circ_dd)
90
+ timeline_drawer(circ_dd, target=target)
83
91
 
84
92
  # Uhrig sequence on qubit 0
85
93
  n = 8
@@ -97,7 +105,7 @@ class PadDynamicalDecoupling(BasePadding):
97
105
  ]
98
106
  )
99
107
  circ_dd = pm.run(circ)
100
- timeline_drawer(circ_dd)
108
+ timeline_drawer(circ_dd, target=target)
101
109
 
102
110
  .. note::
103
111
 
@@ -158,7 +166,7 @@ class PadDynamicalDecoupling(BasePadding):
158
166
  non-multiple of the alignment constraint value is found.
159
167
  TypeError: If ``dd_sequence`` is not specified
160
168
  """
161
- super().__init__(target=target)
169
+ super().__init__(target=target, durations=durations)
162
170
  self._durations = durations
163
171
  if dd_sequence is None:
164
172
  raise TypeError("required argument 'dd_sequence' is not specified")
@@ -173,6 +181,7 @@ class PadDynamicalDecoupling(BasePadding):
173
181
  self._dd_sequence_lengths: dict[Qubit, list[int]] = {}
174
182
  self._sequence_phase = 0
175
183
  if target is not None:
184
+ # The priority order for instruction durations is: target > standalone.
176
185
  self._durations = target.durations()
177
186
  self._alignment = target.pulse_alignment
178
187
  for gate in dd_sequence:
@@ -181,35 +190,12 @@ class PadDynamicalDecoupling(BasePadding):
181
190
  f"{gate.name} in dd_sequence is not supported in the target"
182
191
  )
183
192
 
184
- def _update_inst_durations(self, dag):
185
- """Update instruction durations with circuit information. If the dag contains gate
186
- calibrations and no instruction durations were provided through the target or as a
187
- standalone input, the circuit calibration durations will be used.
188
- The priority order for instruction durations is: target > standalone > circuit.
189
- """
190
- circ_durations = InstructionDurations()
191
-
192
- if dag._calibrations_prop:
193
- cal_durations = []
194
- with warnings.catch_warnings():
195
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
196
- # `schedule.duration` emits pulse deprecation warnings which we don't want
197
- # to see here
198
- for gate, gate_cals in dag._calibrations_prop.items():
199
- for (qubits, parameters), schedule in gate_cals.items():
200
- cal_durations.append((gate, qubits, parameters, schedule.duration))
201
- circ_durations.update(cal_durations, circ_durations.dt)
202
-
203
- if self._durations is not None:
204
- circ_durations.update(self._durations, getattr(self._durations, "dt", None))
205
-
206
- return circ_durations
207
-
208
193
  def _pre_runhook(self, dag: DAGCircuit):
209
194
  super()._pre_runhook(dag)
210
195
 
211
- durations = self._update_inst_durations(dag)
212
-
196
+ durations = InstructionDurations()
197
+ if self._durations is not None:
198
+ durations.update(self._durations, getattr(self._durations, "dt", None))
213
199
  num_pulses = len(self._dd_sequence)
214
200
 
215
201
  # Check if physical circuit is given
@@ -255,31 +241,7 @@ class PadDynamicalDecoupling(BasePadding):
255
241
 
256
242
  sequence_lengths = []
257
243
  for index, gate in enumerate(self._dd_sequence):
258
- try:
259
- # Check calibration.
260
- params = self._resolve_params(gate)
261
- with warnings.catch_warnings():
262
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
263
- # `schedule.duration` emits pulse deprecation warnings which we don't want
264
- # to see here
265
- gate_length = dag._calibrations_prop[gate.name][
266
- ((physical_index,), params)
267
- ].duration
268
- if gate_length % self._alignment != 0:
269
- # This is necessary to implement lightweight scheduling logic for this pass.
270
- # Usually the pulse alignment constraint and pulse data chunk size take
271
- # the same value, however, we can intentionally violate this pattern
272
- # at the gate level. For example, we can create a schedule consisting of
273
- # a pi-pulse of 32 dt followed by a post buffer, i.e. delay, of 4 dt
274
- # on the device with 16 dt constraint. Note that the pi-pulse length
275
- # is multiple of 16 dt but the gate length of 36 is not multiple of it.
276
- # Such pulse gate should be excluded.
277
- raise TranspilerError(
278
- f"Pulse gate {gate.name} with length non-multiple of {self._alignment} "
279
- f"is not acceptable in {self.__class__.__name__} pass."
280
- )
281
- except KeyError:
282
- gate_length = durations.get(gate, physical_index)
244
+ gate_length = durations.get(gate, physical_index)
283
245
  sequence_lengths.append(gate_length)
284
246
  # Update gate duration. This is necessary for current timeline drawer, i.e. scheduled.
285
247
  gate = gate.to_mutable()
@@ -382,7 +344,7 @@ class PadDynamicalDecoupling(BasePadding):
382
344
  op = prev_node.op
383
345
  theta_l, phi_l, lam_l = op.params
384
346
  op.params = Optimize1qGates.compose_u3(theta, phi, lam, theta_l, phi_l, lam_l)
385
- new_prev_node = dag.substitute_node(prev_node, op, propagate_condition=False)
347
+ new_prev_node = dag.substitute_node(prev_node, op)
386
348
  start_time = self.property_set["node_start_time"].pop(prev_node)
387
349
  if start_time is not None:
388
350
  self.property_set["node_start_time"][new_prev_node] = start_time
@@ -16,6 +16,7 @@ from qiskit.circuit import Qubit
16
16
  from qiskit.circuit.delay import Delay
17
17
  from qiskit.dagcircuit import DAGCircuit, DAGNode, DAGOutNode
18
18
  from qiskit.transpiler.target import Target
19
+ from qiskit.transpiler.instruction_durations import InstructionDurations
19
20
 
20
21
  from .base_padding import BasePadding
21
22
 
@@ -25,7 +26,9 @@ class PadDelay(BasePadding):
25
26
 
26
27
  Consecutive delays will be merged in the output of this pass.
27
28
 
28
- .. code-block:: python
29
+ .. plot::
30
+ :include-source:
31
+ :nofigs:
29
32
 
30
33
  from qiskit import QuantumCircuit
31
34
  from qiskit.transpiler import InstructionDurations
@@ -54,7 +57,12 @@ class PadDelay(BasePadding):
54
57
  See :class:`BasePadding` pass for details.
55
58
  """
56
59
 
57
- def __init__(self, fill_very_end: bool = True, target: Target = None):
60
+ def __init__(
61
+ self,
62
+ fill_very_end: bool = True,
63
+ target: Target = None,
64
+ durations: InstructionDurations = None,
65
+ ):
58
66
  """Create new padding delay pass.
59
67
 
60
68
  Args:
@@ -63,7 +71,7 @@ class PadDelay(BasePadding):
63
71
  If it is supplied and does not support delay instruction on a qubit,
64
72
  padding passes do not pad any idle time of the qubit.
65
73
  """
66
- super().__init__(target=target)
74
+ super().__init__(target=target, durations=durations)
67
75
  self.fill_very_end = fill_very_end
68
76
 
69
77
  def _pad(
@@ -21,8 +21,7 @@ class ALAPScheduleAnalysis(BaseScheduler):
21
21
  """ALAP Scheduling pass, which schedules the **stop** time of instructions as late as possible.
22
22
 
23
23
  See the :ref:`transpiler-scheduling-description` section in the :mod:`qiskit.transpiler`
24
- module documentation for the detailed behavior of the control flow
25
- operation, i.e. ``c_if``.
24
+ module documentation for a more detailed explanation.
26
25
  """
27
26
 
28
27
  def run(self, dag):
@@ -40,8 +39,9 @@ class ALAPScheduleAnalysis(BaseScheduler):
40
39
  """
41
40
  if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
42
41
  raise TranspilerError("ALAP schedule runs on physical circuits only")
42
+ if self.property_set["time_unit"] == "stretch":
43
+ raise TranspilerError("Scheduling cannot run on circuits with stretch durations.")
43
44
 
44
- conditional_latency = self.property_set.get("conditional_latency", 0)
45
45
  clbit_write_latency = self.property_set.get("clbit_write_latency", 0)
46
46
 
47
47
  node_start_time = {}
@@ -58,43 +58,9 @@ class ALAPScheduleAnalysis(BaseScheduler):
58
58
  # the physical meaning of t0 and t1 is flipped here.
59
59
  if isinstance(node.op, self.CONDITIONAL_SUPPORTED):
60
60
  t0q = max(idle_before[q] for q in node.qargs)
61
- if node.op.condition_bits:
62
- # conditional is bit tricky due to conditional_latency
63
- t0c = max(idle_before[c] for c in node.op.condition_bits)
64
- # Assume following case (t0c > t0q):
65
- #
66
- # |t0q
67
- # Q ░░░░░░░░░░░░░▒▒▒
68
- # C ░░░░░░░░▒▒▒▒▒▒▒▒
69
- # |t0c
70
- #
71
- # In this case, there is no actual clbit read before gate.
72
- #
73
- # |t0q' = t0c - conditional_latency
74
- # Q ░░░░░░░░▒▒▒░░▒▒▒
75
- # C ░░░░░░▒▒▒▒▒▒▒▒▒▒
76
- # |t1c' = t0c + conditional_latency
77
- #
78
- # rather than naively doing
79
- #
80
- # |t1q' = t0c + duration
81
- # Q ░░░░░▒▒▒░░░░░▒▒▒
82
- # C ░░▒▒░░░░▒▒▒▒▒▒▒▒
83
- # |t1c' = t0c + duration + conditional_latency
84
- #
85
- t0 = max(t0q, t0c - op_duration)
86
- t1 = t0 + op_duration
87
- for clbit in node.op.condition_bits:
88
- idle_before[clbit] = t1 + conditional_latency
89
- else:
90
- t0 = t0q
91
- t1 = t0 + op_duration
61
+ t0 = t0q
62
+ t1 = t0 + op_duration
92
63
  else:
93
- if node.op.condition_bits:
94
- raise TranspilerError(
95
- f"Conditional instruction {node.op.name} is not supported in ALAP scheduler."
96
- )
97
-
98
64
  if isinstance(node.op, Measure):
99
65
  # clbit time is always right (alap) justified
100
66
  t0 = max(idle_before[bit] for bit in node.qargs + node.cargs)
@@ -21,8 +21,7 @@ class ASAPScheduleAnalysis(BaseScheduler):
21
21
  """ASAP Scheduling pass, which schedules the start time of instructions as early as possible.
22
22
 
23
23
  See the :ref:`transpiler-scheduling-description` section in the :mod:`qiskit.transpiler`
24
- module documentation for the detailed behavior of the control flow
25
- operation, i.e. ``c_if``.
24
+ module documentation for a more detailed description.
26
25
  """
27
26
 
28
27
  def run(self, dag):
@@ -40,8 +39,9 @@ class ASAPScheduleAnalysis(BaseScheduler):
40
39
  """
41
40
  if len(dag.qregs) != 1 or dag.qregs.get("q", None) is None:
42
41
  raise TranspilerError("ASAP schedule runs on physical circuits only")
42
+ if self.property_set["time_unit"] == "stretch":
43
+ raise TranspilerError("Scheduling cannot run on circuits with stretch durations.")
43
44
 
44
- conditional_latency = self.property_set.get("conditional_latency", 0)
45
45
  clbit_write_latency = self.property_set.get("clbit_write_latency", 0)
46
46
 
47
47
  node_start_time = {}
@@ -54,40 +54,9 @@ class ASAPScheduleAnalysis(BaseScheduler):
54
54
  # t1: end time of instruction
55
55
  if isinstance(node.op, self.CONDITIONAL_SUPPORTED):
56
56
  t0q = max(idle_after[q] for q in node.qargs)
57
- if node.op.condition_bits:
58
- # conditional is bit tricky due to conditional_latency
59
- t0c = max(idle_after[bit] for bit in node.op.condition_bits)
60
- if t0q > t0c:
61
- # This is situation something like below
62
- #
63
- # |t0q
64
- # Q ▒▒▒▒▒▒▒▒▒░░
65
- # C ▒▒▒░░░░░░░░
66
- # |t0c
67
- #
68
- # In this case, you can insert readout access before tq0
69
- #
70
- # |t0q
71
- # Q ▒▒▒▒▒▒▒▒▒▒▒
72
- # C ▒▒▒░░░▒▒░░░
73
- # |t0q - conditional_latency
74
- #
75
- t0c = max(t0q - conditional_latency, t0c)
76
- t1c = t0c + conditional_latency
77
- for bit in node.op.condition_bits:
78
- # Lock clbit until state is read
79
- idle_after[bit] = t1c
80
- # It starts after register read access
81
- t0 = max(t0q, t1c)
82
- else:
83
- t0 = t0q
57
+ t0 = t0q
84
58
  t1 = t0 + op_duration
85
59
  else:
86
- if node.op.condition_bits:
87
- raise TranspilerError(
88
- f"Conditional instruction {node.op.name} is not supported in ASAP scheduler."
89
- )
90
-
91
60
  if isinstance(node.op, Measure):
92
61
  # measure instruction handling is bit tricky due to clbit_write_latency
93
62
  t0q = max(idle_after[q] for q in node.qargs)
@@ -56,29 +56,23 @@ class BaseScheduler(AnalysisPass):
56
56
  )
57
57
  self.property_set["node_start_time"] = {}
58
58
 
59
- @staticmethod
60
59
  def _get_node_duration(
60
+ self,
61
61
  node: DAGOpNode,
62
62
  dag: DAGCircuit,
63
63
  ) -> int:
64
- """A helper method to get duration from node or calibration."""
64
+ """A helper method to get duration from node"""
65
65
  indices = [dag.find_bit(qarg).index for qarg in node.qargs]
66
66
 
67
- if dag._has_calibration_for(node):
68
- # If node has calibration, this value should be the highest priority
69
- cal_key = tuple(indices), tuple(float(p) for p in node.op.params)
70
- with warnings.catch_warnings():
71
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
72
- # `schedule.duration` emits pulse deprecation warnings which we don't want
73
- # to see here
74
- duration = dag._calibrations_prop[node.op.name][cal_key].duration
75
-
76
- # Note that node duration is updated (but this is analysis pass)
77
- op = node.op.to_mutable()
78
- op.duration = duration
79
- dag.substitute_node(node, op, propagate_condition=False)
67
+ if node.name == "delay":
68
+ # `TimeUnitConversion` already handled the unit conversions.
69
+ duration = node.op.duration
80
70
  else:
81
- duration = node.duration
71
+ unit = "s" if self.durations.dt is None else "dt"
72
+ try:
73
+ duration = self.durations.get(node.name, indices, unit=unit)
74
+ except TranspilerError:
75
+ duration = None
82
76
 
83
77
  if isinstance(duration, ParameterExpression):
84
78
  raise TranspilerError(
@@ -12,14 +12,16 @@
12
12
 
13
13
  """Unify time unit in circuit for scheduling and following passes."""
14
14
  from typing import Set
15
- import warnings
16
15
 
17
- from qiskit.circuit import Delay
16
+ from qiskit.circuit import Delay, Duration
17
+ from qiskit.circuit.classical import expr
18
+ from qiskit.circuit.duration import duration_in_dt
18
19
  from qiskit.dagcircuit import DAGCircuit
19
20
  from qiskit.transpiler.basepasses import TransformationPass
20
21
  from qiskit.transpiler.exceptions import TranspilerError
21
22
  from qiskit.transpiler.instruction_durations import InstructionDurations
22
23
  from qiskit.transpiler.target import Target
24
+ from qiskit.utils import apply_prefix
23
25
 
24
26
 
25
27
  class TimeUnitConversion(TransformationPass):
@@ -51,6 +53,7 @@ class TimeUnitConversion(TransformationPass):
51
53
  super().__init__()
52
54
  self.inst_durations = inst_durations or InstructionDurations()
53
55
  if target is not None:
56
+ # The priority order for instruction durations is: target > standalone.
54
57
  self.inst_durations = target.durations()
55
58
  self._durations_provided = inst_durations is not None or target is not None
56
59
 
@@ -67,84 +70,87 @@ class TimeUnitConversion(TransformationPass):
67
70
  TranspilerError: if the units are not unifiable
68
71
  """
69
72
 
70
- inst_durations = self._update_inst_durations(dag)
73
+ inst_durations = InstructionDurations()
74
+ if self._durations_provided:
75
+ inst_durations.update(self.inst_durations, getattr(self.inst_durations, "dt", None))
76
+
77
+ # The float-value converted units for delay expressions, either all in 'dt'
78
+ # or all in seconds.
79
+ expression_durations = {}
71
80
 
72
81
  # Choose unit
73
- if inst_durations.dt is not None:
74
- time_unit = "dt"
75
- else:
76
- # Check what units are used in delays and other instructions: dt or SI or mixed
77
- units_delay = self._units_used_in_delays(dag)
78
- if self._unified(units_delay) == "mixed":
82
+ has_dt = False
83
+ has_si = False
84
+
85
+ # We _always_ need to traverse duration expressions to convert them to
86
+ # a float. But we also use the opportunity to note if they intermix cycles
87
+ # and wall-time, in case we don't have a `dt` to use to unify all instruction
88
+ # durations.
89
+ for node in dag.op_nodes(op=Delay):
90
+ if isinstance(node.op.duration, expr.Expr):
91
+ if any(
92
+ isinstance(x, expr.Stretch) for x in expr.iter_identifiers(node.op.duration)
93
+ ):
94
+ # If any of the delays use a stretch expression, we can't run scheduling
95
+ # passes anyway, so we bail out. In theory, we _could_ still traverse
96
+ # through the stretch expression and replace any Duration value nodes it may
97
+ # contain with ones of the same units, but it'd be complex and probably unuseful.
98
+ self.property_set["time_unit"] = "stretch"
99
+ return dag
100
+
101
+ visitor = _EvalDurationImpl(inst_durations.dt)
102
+ duration = node.op.duration.accept(visitor)
103
+ if visitor.in_cycles():
104
+ has_dt = True
105
+ # We need to round in case the expression evaluated to a non-integral 'dt'.
106
+ duration = duration_in_dt(duration, 1.0)
107
+ else:
108
+ has_si = True
109
+ if duration < 0:
110
+ raise TranspilerError(
111
+ f"Expression '{node.op.duration}' resolves to a negative duration!"
112
+ )
113
+ expression_durations[node._node_id] = duration
114
+ else:
115
+ if node.op.unit == "dt":
116
+ has_dt = True
117
+ else:
118
+ has_si = True
119
+ if inst_durations.dt is None and has_dt and has_si:
79
120
  raise TranspilerError(
80
121
  "Fail to unify time units in delays. SI units "
81
122
  "and dt unit must not be mixed when dt is not supplied."
82
123
  )
83
- units_other = inst_durations.units_used()
84
- if self._unified(units_other) == "mixed":
85
- raise TranspilerError(
86
- "Fail to unify time units in instruction_durations. SI units "
87
- "and dt unit must not be mixed when dt is not supplied."
88
- )
89
124
 
90
- unified_unit = self._unified(units_delay | units_other)
91
- if unified_unit == "SI":
125
+ if inst_durations.dt is None:
126
+ # Check what units are used in other instructions: dt or SI or mixed
127
+ units_other = inst_durations.units_used()
128
+ unified_unit = self._unified(units_other)
129
+ if unified_unit == "SI" and not has_dt:
92
130
  time_unit = "s"
93
- elif unified_unit == "dt":
131
+ elif unified_unit == "dt" and not has_si:
94
132
  time_unit = "dt"
95
133
  else:
96
134
  raise TranspilerError(
97
135
  "Fail to unify time units. SI units "
98
136
  "and dt unit must not be mixed when dt is not supplied."
99
137
  )
138
+ else:
139
+ time_unit = "dt"
100
140
 
101
- # Make units consistent
102
- for node in dag.op_nodes():
103
- try:
104
- duration = inst_durations.get(
105
- node.op, [dag.find_bit(qarg).index for qarg in node.qargs], unit=time_unit
106
- )
107
- except TranspilerError:
108
- continue
141
+ # Make instructions with local durations consistent.
142
+ for node in dag.op_nodes(Delay):
109
143
  op = node.op.to_mutable()
110
- op.duration = duration
144
+ if node._node_id in expression_durations:
145
+ op.duration = expression_durations[node._node_id]
146
+ else:
147
+ op.duration = inst_durations._convert_unit(op.duration, op.unit, time_unit)
111
148
  op.unit = time_unit
112
- dag.substitute_node(node, op, propagate_condition=False)
149
+ dag.substitute_node(node, op)
113
150
 
114
151
  self.property_set["time_unit"] = time_unit
115
152
  return dag
116
153
 
117
- def _update_inst_durations(self, dag):
118
- """Update instruction durations with circuit information. If the dag contains gate
119
- calibrations and no instruction durations were provided through the target or as a
120
- standalone input, the circuit calibration durations will be used.
121
- The priority order for instruction durations is: target > standalone > circuit.
122
- """
123
- circ_durations = InstructionDurations()
124
-
125
- if dag._calibrations_prop:
126
- cal_durations = []
127
- with warnings.catch_warnings():
128
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
129
- # `schedule.duration` emits pulse deprecation warnings which we don't want
130
- # to see here
131
- for gate, gate_cals in dag._calibrations_prop.items():
132
- for (qubits, parameters), schedule in gate_cals.items():
133
- cal_durations.append((gate, qubits, parameters, schedule.duration))
134
- circ_durations.update(cal_durations, circ_durations.dt)
135
-
136
- if self._durations_provided:
137
- circ_durations.update(self.inst_durations, getattr(self.inst_durations, "dt", None))
138
-
139
- return circ_durations
140
-
141
- @staticmethod
142
- def _units_used_in_delays(dag: DAGCircuit) -> Set[str]:
143
- units_used = set()
144
- for node in dag.op_nodes(op=Delay):
145
- units_used.add(node.op.unit)
146
- return units_used
147
-
148
154
  @staticmethod
149
155
  def _unified(unit_set: Set[str]) -> str:
150
156
  if not unit_set:
@@ -163,3 +169,65 @@ class TimeUnitConversion(TransformationPass):
163
169
  return "SI"
164
170
 
165
171
  return "mixed"
172
+
173
+
174
+ class _EvalDurationImpl(expr.ExprVisitor[float]):
175
+ """Evaluates the expression to a single float result.
176
+
177
+ If ``dt`` is provided or all durations are already in ``dt``, the result is in ``dt``.
178
+ Otherwise, the result will be in seconds, and all durations MUST be in wall-time (SI).
179
+ """
180
+
181
+ __slots__ = ("dt", "has_dt", "has_si")
182
+
183
+ def __init__(self, dt=None):
184
+ self.dt = dt
185
+ self.has_dt = False
186
+ self.has_si = False
187
+
188
+ def in_cycles(self):
189
+ """Returns ``True`` if units are 'dt' after visit."""
190
+ return self.has_dt or self.dt is not None
191
+
192
+ def visit_value(self, node, /) -> float:
193
+ if isinstance(node.value, float):
194
+ return node.value
195
+ if isinstance(node.value, Duration.dt):
196
+ if self.has_si and self.dt is None:
197
+ raise TranspilerError(
198
+ "Fail to unify time units in delays. SI units "
199
+ "and dt unit must not be mixed when dt is not supplied."
200
+ )
201
+ self.has_dt = True
202
+ return node.value[0]
203
+ if isinstance(node.value, Duration):
204
+ if self.has_dt and self.dt is None:
205
+ raise TranspilerError(
206
+ "Fail to unify time units in delays. SI units "
207
+ "and dt unit must not be mixed when dt is not supplied."
208
+ )
209
+ self.has_si = True
210
+ # Setting 'divisor' to 1 when there's no 'dt' is just to simplify
211
+ # the logic (we don't need to divide).
212
+ divisor = self.dt if self.dt is not None else 1
213
+ if isinstance(node.value, Duration.s):
214
+ return node.value[0] / divisor
215
+ from_unit = node.value.unit()
216
+ return apply_prefix(node.value[0], from_unit) / divisor
217
+ raise TranspilerError(f"invalid duration expression: {node}")
218
+
219
+ def visit_binary(self, node, /) -> float:
220
+ left = node.left.accept(self)
221
+ right = node.right.accept(self)
222
+ if node.op == expr.Binary.Op.ADD:
223
+ return left + right
224
+ if node.op == expr.Binary.Op.SUB:
225
+ return left - right
226
+ if node.op == expr.Binary.Op.MUL:
227
+ return left * right
228
+ if node.op == expr.Binary.Op.DIV:
229
+ return left / right
230
+ raise TranspilerError(f"invalid duration expression: {node}")
231
+
232
+ def visit_cast(self, node, /) -> float:
233
+ return node.operand.accept(self)