qiskit 1.4.2__cp39-abi3-win_amd64.whl → 2.0.0rc2__cp39-abi3-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (455) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +2 -5
  3. qiskit/_accelerate.pyd +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 +2 -141
  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 +3 -7
  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 +7 -1
  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 +93 -130
  156. qiskit/qpy/binary_io/schedules.py +69 -439
  157. qiskit/qpy/binary_io/value.py +154 -31
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +34 -81
  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/evolution/lie_trotter.py +10 -7
  193. qiskit/synthesis/evolution/product_formula.py +44 -35
  194. qiskit/synthesis/evolution/qdrift.py +17 -24
  195. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  196. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  197. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  198. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  199. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  200. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  201. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  202. qiskit/synthesis/two_qubit/__init__.py +1 -0
  203. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  204. qiskit/transpiler/__init__.py +32 -232
  205. qiskit/transpiler/basepasses.py +20 -51
  206. qiskit/transpiler/layout.py +1 -1
  207. qiskit/transpiler/passes/__init__.py +2 -40
  208. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  209. qiskit/transpiler/passes/basis/decompose.py +1 -15
  210. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  211. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  212. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  213. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  214. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  215. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  216. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  217. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  218. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  219. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  220. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  221. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  222. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  224. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  225. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  226. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  227. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  228. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  229. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  230. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  231. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  232. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  233. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  234. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  235. qiskit/transpiler/passes/routing/__init__.py +0 -1
  236. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  237. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  238. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  239. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  240. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  241. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  242. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  243. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  244. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  245. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  246. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  247. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  248. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  249. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  250. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  251. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  252. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  253. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  254. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  255. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  256. qiskit/transpiler/passes/utils/__init__.py +0 -1
  257. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  258. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  259. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  260. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  261. qiskit/transpiler/passmanager.py +13 -0
  262. qiskit/transpiler/passmanager_config.py +5 -81
  263. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  264. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  265. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  266. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  267. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  268. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  269. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  270. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  271. qiskit/transpiler/target.py +67 -524
  272. qiskit/user_config.py +8 -4
  273. qiskit/utils/__init__.py +13 -12
  274. qiskit/utils/deprecation.py +4 -112
  275. qiskit/utils/optionals.py +11 -4
  276. qiskit/utils/parallel.py +214 -87
  277. qiskit/utils/units.py +4 -1
  278. qiskit/visualization/__init__.py +3 -7
  279. qiskit/visualization/array.py +4 -1
  280. qiskit/visualization/bloch.py +1 -1
  281. qiskit/visualization/circuit/_utils.py +19 -19
  282. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  283. qiskit/visualization/circuit/matplotlib.py +13 -23
  284. qiskit/visualization/circuit/text.py +7 -3
  285. qiskit/visualization/dag_visualization.py +2 -1
  286. qiskit/visualization/gate_map.py +39 -154
  287. qiskit/visualization/pass_manager_visualization.py +6 -2
  288. qiskit/visualization/state_visualization.py +6 -0
  289. qiskit/visualization/timeline/core.py +18 -12
  290. qiskit/visualization/timeline/interface.py +19 -18
  291. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.dist-info}/METADATA +2 -2
  292. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.dist-info}/RECORD +296 -443
  293. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.dist-info}/entry_points.txt +8 -2
  294. qiskit/assembler/__init__.py +0 -42
  295. qiskit/assembler/assemble_circuits.py +0 -451
  296. qiskit/assembler/assemble_schedules.py +0 -367
  297. qiskit/assembler/disassemble.py +0 -310
  298. qiskit/assembler/run_config.py +0 -77
  299. qiskit/circuit/bit.py +0 -106
  300. qiskit/circuit/classicalfunction/__init__.py +0 -152
  301. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  302. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  303. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  304. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  305. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  306. qiskit/circuit/classicalfunction/types.py +0 -18
  307. qiskit/circuit/classicalfunction/utils.py +0 -91
  308. qiskit/circuit/classicalregister.py +0 -57
  309. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  310. qiskit/circuit/quantumregister.py +0 -75
  311. qiskit/circuit/register.py +0 -246
  312. qiskit/compiler/assembler.py +0 -689
  313. qiskit/compiler/scheduler.py +0 -109
  314. qiskit/compiler/sequencer.py +0 -71
  315. qiskit/primitives/backend_estimator.py +0 -486
  316. qiskit/primitives/backend_sampler.py +0 -222
  317. qiskit/primitives/estimator.py +0 -172
  318. qiskit/primitives/sampler.py +0 -162
  319. qiskit/providers/backend_compat.py +0 -507
  320. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  321. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  322. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  327. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  330. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  335. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  339. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/fake_1q.py +0 -91
  344. qiskit/providers/fake_provider/fake_backend.py +0 -165
  345. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  346. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  347. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  348. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  349. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  350. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  351. qiskit/providers/models/__init__.py +0 -89
  352. qiskit/providers/models/backendconfiguration.py +0 -1040
  353. qiskit/providers/models/backendproperties.py +0 -535
  354. qiskit/providers/models/backendstatus.py +0 -104
  355. qiskit/providers/models/jobstatus.py +0 -77
  356. qiskit/providers/models/pulsedefaults.py +0 -305
  357. qiskit/providers/provider.py +0 -95
  358. qiskit/pulse/__init__.py +0 -158
  359. qiskit/pulse/builder.py +0 -2262
  360. qiskit/pulse/calibration_entries.py +0 -381
  361. qiskit/pulse/channels.py +0 -227
  362. qiskit/pulse/configuration.py +0 -245
  363. qiskit/pulse/exceptions.py +0 -45
  364. qiskit/pulse/filters.py +0 -309
  365. qiskit/pulse/instruction_schedule_map.py +0 -424
  366. qiskit/pulse/instructions/__init__.py +0 -67
  367. qiskit/pulse/instructions/acquire.py +0 -150
  368. qiskit/pulse/instructions/delay.py +0 -71
  369. qiskit/pulse/instructions/directives.py +0 -154
  370. qiskit/pulse/instructions/frequency.py +0 -135
  371. qiskit/pulse/instructions/instruction.py +0 -270
  372. qiskit/pulse/instructions/phase.py +0 -152
  373. qiskit/pulse/instructions/play.py +0 -99
  374. qiskit/pulse/instructions/reference.py +0 -100
  375. qiskit/pulse/instructions/snapshot.py +0 -82
  376. qiskit/pulse/library/__init__.py +0 -97
  377. qiskit/pulse/library/continuous.py +0 -430
  378. qiskit/pulse/library/pulse.py +0 -148
  379. qiskit/pulse/library/samplers/__init__.py +0 -15
  380. qiskit/pulse/library/samplers/decorators.py +0 -295
  381. qiskit/pulse/library/samplers/strategies.py +0 -71
  382. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  383. qiskit/pulse/library/waveform.py +0 -136
  384. qiskit/pulse/macros.py +0 -262
  385. qiskit/pulse/parameter_manager.py +0 -445
  386. qiskit/pulse/parser.py +0 -314
  387. qiskit/pulse/reference_manager.py +0 -58
  388. qiskit/pulse/schedule.py +0 -1854
  389. qiskit/pulse/transforms/__init__.py +0 -106
  390. qiskit/pulse/transforms/alignments.py +0 -406
  391. qiskit/pulse/transforms/base_transforms.py +0 -71
  392. qiskit/pulse/transforms/canonicalization.py +0 -498
  393. qiskit/pulse/transforms/dag.py +0 -122
  394. qiskit/pulse/utils.py +0 -149
  395. qiskit/qobj/__init__.py +0 -75
  396. qiskit/qobj/common.py +0 -81
  397. qiskit/qobj/converters/__init__.py +0 -18
  398. qiskit/qobj/converters/lo_config.py +0 -177
  399. qiskit/qobj/converters/pulse_instruction.py +0 -897
  400. qiskit/qobj/pulse_qobj.py +0 -709
  401. qiskit/qobj/qasm_qobj.py +0 -708
  402. qiskit/qobj/utils.py +0 -46
  403. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  404. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  405. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  406. qiskit/result/mitigation/utils.py +0 -217
  407. qiskit/scheduler/__init__.py +0 -40
  408. qiskit/scheduler/config.py +0 -37
  409. qiskit/scheduler/lowering.py +0 -187
  410. qiskit/scheduler/methods/__init__.py +0 -15
  411. qiskit/scheduler/methods/basic.py +0 -140
  412. qiskit/scheduler/schedule_circuit.py +0 -69
  413. qiskit/scheduler/sequence.py +0 -104
  414. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  415. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  416. qiskit/transpiler/passes/calibration/builders.py +0 -20
  417. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  418. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  419. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  420. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  421. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  422. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  423. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  424. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  425. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  426. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  427. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  428. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  429. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  430. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  431. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  432. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  433. qiskit/utils/deprecate_pulse.py +0 -119
  434. qiskit/utils/multiprocessing.py +0 -56
  435. qiskit/visualization/pulse_v2/__init__.py +0 -21
  436. qiskit/visualization/pulse_v2/core.py +0 -901
  437. qiskit/visualization/pulse_v2/device_info.py +0 -173
  438. qiskit/visualization/pulse_v2/drawings.py +0 -253
  439. qiskit/visualization/pulse_v2/events.py +0 -254
  440. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  441. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  442. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  443. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  444. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  445. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  446. qiskit/visualization/pulse_v2/interface.py +0 -459
  447. qiskit/visualization/pulse_v2/layouts.py +0 -387
  448. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  449. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  450. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  451. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  452. qiskit/visualization/pulse_v2/types.py +0 -242
  453. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.dist-info}/LICENSE.txt +0 -0
  454. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.dist-info}/WHEEL +0 -0
  455. {qiskit-1.4.2.dist-info → qiskit-2.0.0rc2.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)