qiskit 1.4.1__cp39-abi3-macosx_11_0_arm64.whl → 2.0.0__cp39-abi3-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (462) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +3 -9
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/circuit/__init__.py +35 -10
  5. qiskit/circuit/{add_control.py → _add_control.py} +32 -12
  6. qiskit/circuit/_classical_resource_map.py +5 -3
  7. qiskit/circuit/barrier.py +3 -7
  8. qiskit/circuit/classical/expr/__init__.py +31 -3
  9. qiskit/circuit/classical/expr/constructors.py +236 -28
  10. qiskit/circuit/classical/expr/expr.py +104 -3
  11. qiskit/circuit/classical/expr/visitors.py +75 -0
  12. qiskit/circuit/classical/types/__init__.py +12 -8
  13. qiskit/circuit/classical/types/ordering.py +14 -7
  14. qiskit/circuit/classical/types/types.py +36 -0
  15. qiskit/circuit/commutation_checker.py +34 -7
  16. qiskit/circuit/controlflow/__init__.py +32 -1
  17. qiskit/circuit/controlflow/_builder_utils.py +9 -5
  18. qiskit/circuit/controlflow/box.py +163 -0
  19. qiskit/circuit/controlflow/break_loop.py +1 -1
  20. qiskit/circuit/controlflow/builder.py +139 -39
  21. qiskit/circuit/controlflow/continue_loop.py +1 -3
  22. qiskit/circuit/controlflow/control_flow.py +10 -0
  23. qiskit/circuit/controlflow/for_loop.py +2 -1
  24. qiskit/circuit/controlflow/if_else.py +3 -16
  25. qiskit/circuit/controlflow/switch_case.py +2 -8
  26. qiskit/circuit/controlflow/while_loop.py +2 -7
  27. qiskit/circuit/controlledgate.py +2 -4
  28. qiskit/circuit/delay.py +40 -11
  29. qiskit/circuit/duration.py +0 -15
  30. qiskit/circuit/gate.py +2 -4
  31. qiskit/circuit/instruction.py +2 -141
  32. qiskit/circuit/instructionset.py +7 -54
  33. qiskit/circuit/library/__init__.py +469 -154
  34. qiskit/circuit/library/arithmetic/__init__.py +16 -10
  35. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  36. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +2 -2
  37. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +1 -1
  38. qiskit/circuit/library/arithmetic/exact_reciprocal.py +64 -21
  39. qiskit/circuit/library/arithmetic/integer_comparator.py +37 -80
  40. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +169 -2
  41. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +59 -5
  42. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +154 -6
  43. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +114 -4
  44. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +191 -15
  45. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +93 -39
  46. qiskit/circuit/library/arithmetic/quadratic_form.py +168 -2
  47. qiskit/circuit/library/arithmetic/weighted_adder.py +73 -1
  48. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  49. qiskit/circuit/library/blueprintcircuit.py +52 -16
  50. qiskit/circuit/library/data_preparation/initializer.py +1 -1
  51. qiskit/circuit/library/data_preparation/pauli_feature_map.py +4 -4
  52. qiskit/circuit/library/data_preparation/state_preparation.py +1 -1
  53. qiskit/circuit/library/generalized_gates/gms.py +1 -1
  54. qiskit/circuit/library/generalized_gates/isometry.py +1 -1
  55. qiskit/circuit/library/generalized_gates/pauli.py +1 -2
  56. qiskit/circuit/library/generalized_gates/uc.py +97 -7
  57. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +1 -1
  58. qiskit/circuit/library/generalized_gates/unitary.py +4 -2
  59. qiskit/circuit/library/graph_state.py +1 -0
  60. qiskit/circuit/library/hamiltonian_gate.py +1 -1
  61. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +1 -1
  62. qiskit/circuit/library/n_local/n_local.py +1 -1
  63. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -1
  64. qiskit/circuit/library/overlap.py +2 -2
  65. qiskit/circuit/library/pauli_evolution.py +39 -24
  66. qiskit/circuit/library/phase_oracle.py +130 -51
  67. qiskit/circuit/library/standard_gates/__init__.py +0 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +3 -4
  69. qiskit/circuit/library/standard_gates/ecr.py +3 -4
  70. qiskit/circuit/library/standard_gates/global_phase.py +5 -6
  71. qiskit/circuit/library/standard_gates/h.py +4 -9
  72. qiskit/circuit/library/standard_gates/i.py +2 -2
  73. qiskit/circuit/library/standard_gates/iswap.py +3 -4
  74. qiskit/circuit/library/standard_gates/p.py +15 -34
  75. qiskit/circuit/library/standard_gates/r.py +7 -10
  76. qiskit/circuit/library/standard_gates/rx.py +5 -15
  77. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  78. qiskit/circuit/library/standard_gates/ry.py +5 -17
  79. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  80. qiskit/circuit/library/standard_gates/rz.py +5 -17
  81. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  82. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  83. qiskit/circuit/library/standard_gates/s.py +6 -15
  84. qiskit/circuit/library/standard_gates/swap.py +4 -11
  85. qiskit/circuit/library/standard_gates/sx.py +7 -12
  86. qiskit/circuit/library/standard_gates/t.py +6 -7
  87. qiskit/circuit/library/standard_gates/u.py +2 -10
  88. qiskit/circuit/library/standard_gates/u1.py +5 -16
  89. qiskit/circuit/library/standard_gates/u2.py +2 -6
  90. qiskit/circuit/library/standard_gates/u3.py +3 -11
  91. qiskit/circuit/library/standard_gates/x.py +14 -62
  92. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  94. qiskit/circuit/library/standard_gates/y.py +4 -9
  95. qiskit/circuit/library/standard_gates/z.py +5 -15
  96. qiskit/circuit/measure.py +11 -2
  97. qiskit/circuit/parameterexpression.py +11 -0
  98. qiskit/circuit/quantumcircuit.py +890 -564
  99. qiskit/circuit/random/utils.py +12 -6
  100. qiskit/circuit/reset.py +5 -2
  101. qiskit/circuit/singleton.py +5 -11
  102. qiskit/circuit/store.py +0 -8
  103. qiskit/circuit/tools/pi_check.py +3 -0
  104. qiskit/compiler/__init__.py +1 -7
  105. qiskit/compiler/transpiler.py +38 -196
  106. qiskit/converters/circuit_to_dag.py +6 -4
  107. qiskit/converters/circuit_to_dagdependency.py +0 -2
  108. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  109. qiskit/converters/circuit_to_gate.py +1 -1
  110. qiskit/converters/circuit_to_instruction.py +16 -29
  111. qiskit/converters/dag_to_circuit.py +7 -8
  112. qiskit/converters/dag_to_dagdependency.py +0 -1
  113. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  114. qiskit/converters/dagdependency_to_circuit.py +0 -6
  115. qiskit/converters/dagdependency_to_dag.py +0 -6
  116. qiskit/dagcircuit/collect_blocks.py +32 -20
  117. qiskit/dagcircuit/dagdependency.py +3 -37
  118. qiskit/dagcircuit/dagdependency_v2.py +5 -82
  119. qiskit/dagcircuit/dagnode.py +14 -2
  120. qiskit/passmanager/__init__.py +24 -6
  121. qiskit/passmanager/passmanager.py +26 -24
  122. qiskit/primitives/__init__.py +44 -35
  123. qiskit/primitives/backend_estimator_v2.py +102 -23
  124. qiskit/primitives/backend_sampler_v2.py +5 -20
  125. qiskit/primitives/base/__init__.py +4 -4
  126. qiskit/primitives/base/base_estimator.py +77 -82
  127. qiskit/primitives/base/base_primitive_job.py +2 -2
  128. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  129. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  130. qiskit/primitives/base/base_sampler.py +52 -60
  131. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  132. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  133. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  134. qiskit/primitives/containers/bindings_array.py +3 -1
  135. qiskit/primitives/containers/bit_array.py +23 -0
  136. qiskit/primitives/containers/data_bin.py +3 -1
  137. qiskit/primitives/containers/observables_array.py +19 -2
  138. qiskit/primitives/statevector_sampler.py +6 -8
  139. qiskit/primitives/utils.py +14 -189
  140. qiskit/providers/__init__.py +4 -130
  141. qiskit/providers/backend.py +11 -314
  142. qiskit/providers/basic_provider/__init__.py +3 -1
  143. qiskit/providers/basic_provider/basic_provider.py +29 -9
  144. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  145. qiskit/providers/exceptions.py +0 -33
  146. qiskit/providers/fake_provider/__init__.py +0 -37
  147. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  148. qiskit/qasm2/__init__.py +21 -6
  149. qiskit/qasm2/export.py +2 -10
  150. qiskit/qasm2/parse.py +11 -25
  151. qiskit/qasm3/__init__.py +5 -1
  152. qiskit/qasm3/ast.py +44 -0
  153. qiskit/qasm3/exporter.py +65 -27
  154. qiskit/qasm3/printer.py +35 -4
  155. qiskit/qpy/__init__.py +162 -19
  156. qiskit/qpy/binary_io/__init__.py +0 -1
  157. qiskit/qpy/binary_io/circuits.py +96 -116
  158. qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
  159. qiskit/qpy/binary_io/schedules.py +61 -388
  160. qiskit/qpy/binary_io/value.py +159 -33
  161. qiskit/qpy/common.py +10 -7
  162. qiskit/qpy/formats.py +41 -0
  163. qiskit/qpy/interface.py +29 -62
  164. qiskit/qpy/type_keys.py +58 -221
  165. qiskit/quantum_info/analysis/distance.py +3 -1
  166. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  167. qiskit/quantum_info/operators/operator.py +6 -2
  168. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  169. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  170. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  171. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  172. qiskit/quantum_info/states/densitymatrix.py +16 -6
  173. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  174. qiskit/quantum_info/states/statevector.py +16 -6
  175. qiskit/result/__init__.py +5 -17
  176. qiskit/result/models.py +18 -11
  177. qiskit/result/result.py +38 -134
  178. qiskit/result/sampled_expval.py +1 -2
  179. qiskit/result/utils.py +3 -4
  180. qiskit/synthesis/__init__.py +21 -1
  181. qiskit/synthesis/arithmetic/__init__.py +3 -1
  182. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  183. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  184. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  185. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  186. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  187. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  188. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  189. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  190. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  191. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  192. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  193. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  194. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  195. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  196. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  197. qiskit/synthesis/evolution/product_formula.py +44 -35
  198. qiskit/synthesis/evolution/qdrift.py +17 -24
  199. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  200. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  201. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  202. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  203. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  204. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  205. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  206. qiskit/synthesis/two_qubit/__init__.py +1 -0
  207. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  208. qiskit/transpiler/__init__.py +32 -232
  209. qiskit/transpiler/basepasses.py +20 -51
  210. qiskit/transpiler/layout.py +1 -1
  211. qiskit/transpiler/passes/__init__.py +4 -40
  212. qiskit/transpiler/passes/basis/basis_translator.py +5 -4
  213. qiskit/transpiler/passes/basis/decompose.py +1 -15
  214. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  215. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  216. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  217. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  218. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +3 -4
  219. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  220. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  221. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  222. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  223. qiskit/transpiler/passes/optimization/__init__.py +2 -3
  224. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  225. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  226. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  227. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  228. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  229. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  230. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  231. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  232. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  233. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  234. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  235. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  236. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  237. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  238. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +3 -2
  239. qiskit/transpiler/passes/routing/__init__.py +0 -1
  240. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  241. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  242. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  243. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  244. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  245. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  246. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  247. qiskit/transpiler/passes/scheduling/padding/base_padding.py +32 -4
  248. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +25 -63
  249. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +12 -4
  250. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  251. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  252. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  253. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +134 -62
  254. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  255. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  256. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  257. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  258. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  259. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  260. qiskit/transpiler/passes/utils/__init__.py +0 -1
  261. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  262. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  263. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  264. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  265. qiskit/transpiler/passmanager.py +13 -0
  266. qiskit/transpiler/passmanager_config.py +5 -81
  267. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  268. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  269. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +107 -322
  270. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  272. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  273. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  274. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  275. qiskit/transpiler/target.py +78 -524
  276. qiskit/user_config.py +8 -4
  277. qiskit/utils/__init__.py +13 -12
  278. qiskit/utils/deprecation.py +4 -112
  279. qiskit/utils/optionals.py +11 -4
  280. qiskit/utils/parallel.py +214 -87
  281. qiskit/utils/units.py +4 -1
  282. qiskit/visualization/__init__.py +3 -7
  283. qiskit/visualization/array.py +4 -1
  284. qiskit/visualization/bloch.py +1 -1
  285. qiskit/visualization/circuit/_utils.py +19 -19
  286. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  287. qiskit/visualization/circuit/matplotlib.py +13 -23
  288. qiskit/visualization/circuit/text.py +7 -3
  289. qiskit/visualization/counts_visualization.py +4 -0
  290. qiskit/visualization/dag_visualization.py +2 -1
  291. qiskit/visualization/gate_map.py +39 -154
  292. qiskit/visualization/library.py +4 -1
  293. qiskit/visualization/pass_manager_visualization.py +6 -2
  294. qiskit/visualization/state_visualization.py +19 -2
  295. qiskit/visualization/timeline/core.py +19 -13
  296. qiskit/visualization/timeline/interface.py +19 -18
  297. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  298. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/METADATA +4 -3
  299. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/RECORD +303 -449
  300. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/WHEEL +2 -1
  301. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/entry_points.txt +8 -2
  302. qiskit/assembler/__init__.py +0 -42
  303. qiskit/assembler/assemble_circuits.py +0 -451
  304. qiskit/assembler/assemble_schedules.py +0 -367
  305. qiskit/assembler/disassemble.py +0 -310
  306. qiskit/assembler/run_config.py +0 -77
  307. qiskit/circuit/bit.py +0 -106
  308. qiskit/circuit/classicalfunction/__init__.py +0 -152
  309. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  310. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  311. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  312. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  313. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  314. qiskit/circuit/classicalfunction/types.py +0 -18
  315. qiskit/circuit/classicalfunction/utils.py +0 -91
  316. qiskit/circuit/classicalregister.py +0 -57
  317. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  318. qiskit/circuit/quantumregister.py +0 -75
  319. qiskit/circuit/register.py +0 -246
  320. qiskit/compiler/assembler.py +0 -689
  321. qiskit/compiler/scheduler.py +0 -109
  322. qiskit/compiler/sequencer.py +0 -71
  323. qiskit/primitives/backend_estimator.py +0 -486
  324. qiskit/primitives/backend_sampler.py +0 -222
  325. qiskit/primitives/estimator.py +0 -172
  326. qiskit/primitives/sampler.py +0 -162
  327. qiskit/providers/backend_compat.py +0 -507
  328. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  329. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  330. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  332. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  333. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  335. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  336. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  337. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  338. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  339. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  341. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  343. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  344. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  345. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  346. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  347. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  348. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  349. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  350. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  351. qiskit/providers/fake_provider/fake_1q.py +0 -91
  352. qiskit/providers/fake_provider/fake_backend.py +0 -165
  353. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  354. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  355. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  356. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  357. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  358. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  359. qiskit/providers/models/__init__.py +0 -89
  360. qiskit/providers/models/backendconfiguration.py +0 -1040
  361. qiskit/providers/models/backendproperties.py +0 -535
  362. qiskit/providers/models/backendstatus.py +0 -104
  363. qiskit/providers/models/jobstatus.py +0 -77
  364. qiskit/providers/models/pulsedefaults.py +0 -305
  365. qiskit/providers/provider.py +0 -95
  366. qiskit/pulse/__init__.py +0 -158
  367. qiskit/pulse/builder.py +0 -2262
  368. qiskit/pulse/calibration_entries.py +0 -381
  369. qiskit/pulse/channels.py +0 -227
  370. qiskit/pulse/configuration.py +0 -245
  371. qiskit/pulse/exceptions.py +0 -45
  372. qiskit/pulse/filters.py +0 -309
  373. qiskit/pulse/instruction_schedule_map.py +0 -424
  374. qiskit/pulse/instructions/__init__.py +0 -67
  375. qiskit/pulse/instructions/acquire.py +0 -150
  376. qiskit/pulse/instructions/delay.py +0 -71
  377. qiskit/pulse/instructions/directives.py +0 -154
  378. qiskit/pulse/instructions/frequency.py +0 -135
  379. qiskit/pulse/instructions/instruction.py +0 -270
  380. qiskit/pulse/instructions/phase.py +0 -152
  381. qiskit/pulse/instructions/play.py +0 -99
  382. qiskit/pulse/instructions/reference.py +0 -100
  383. qiskit/pulse/instructions/snapshot.py +0 -82
  384. qiskit/pulse/library/__init__.py +0 -97
  385. qiskit/pulse/library/continuous.py +0 -430
  386. qiskit/pulse/library/pulse.py +0 -148
  387. qiskit/pulse/library/samplers/__init__.py +0 -15
  388. qiskit/pulse/library/samplers/decorators.py +0 -295
  389. qiskit/pulse/library/samplers/strategies.py +0 -71
  390. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  391. qiskit/pulse/library/waveform.py +0 -136
  392. qiskit/pulse/macros.py +0 -262
  393. qiskit/pulse/parameter_manager.py +0 -445
  394. qiskit/pulse/parser.py +0 -314
  395. qiskit/pulse/reference_manager.py +0 -58
  396. qiskit/pulse/schedule.py +0 -1854
  397. qiskit/pulse/transforms/__init__.py +0 -106
  398. qiskit/pulse/transforms/alignments.py +0 -406
  399. qiskit/pulse/transforms/base_transforms.py +0 -71
  400. qiskit/pulse/transforms/canonicalization.py +0 -498
  401. qiskit/pulse/transforms/dag.py +0 -122
  402. qiskit/pulse/utils.py +0 -149
  403. qiskit/qobj/__init__.py +0 -75
  404. qiskit/qobj/common.py +0 -81
  405. qiskit/qobj/converters/__init__.py +0 -18
  406. qiskit/qobj/converters/lo_config.py +0 -177
  407. qiskit/qobj/converters/pulse_instruction.py +0 -897
  408. qiskit/qobj/pulse_qobj.py +0 -709
  409. qiskit/qobj/qasm_qobj.py +0 -708
  410. qiskit/qobj/utils.py +0 -46
  411. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  412. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  413. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  414. qiskit/result/mitigation/utils.py +0 -217
  415. qiskit/scheduler/__init__.py +0 -40
  416. qiskit/scheduler/config.py +0 -37
  417. qiskit/scheduler/lowering.py +0 -187
  418. qiskit/scheduler/methods/__init__.py +0 -15
  419. qiskit/scheduler/methods/basic.py +0 -140
  420. qiskit/scheduler/schedule_circuit.py +0 -69
  421. qiskit/scheduler/sequence.py +0 -104
  422. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  423. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  424. qiskit/transpiler/passes/calibration/builders.py +0 -20
  425. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  426. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  427. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  428. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  429. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  430. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  431. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  432. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  433. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  434. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  435. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  436. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  437. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  438. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  439. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  440. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  441. qiskit/utils/deprecate_pulse.py +0 -119
  442. qiskit/utils/multiprocessing.py +0 -56
  443. qiskit/visualization/pulse_v2/__init__.py +0 -21
  444. qiskit/visualization/pulse_v2/core.py +0 -901
  445. qiskit/visualization/pulse_v2/device_info.py +0 -173
  446. qiskit/visualization/pulse_v2/drawings.py +0 -253
  447. qiskit/visualization/pulse_v2/events.py +0 -254
  448. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  449. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  450. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  451. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  452. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  453. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  454. qiskit/visualization/pulse_v2/interface.py +0 -459
  455. qiskit/visualization/pulse_v2/layouts.py +0 -387
  456. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  457. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  458. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  459. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  460. qiskit/visualization/pulse_v2/types.py +0 -242
  461. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info/licenses}/LICENSE.txt +0 -0
  462. {qiskit-1.4.1.dist-info → qiskit-2.0.0.dist-info}/top_level.txt +0 -0
qiskit/user_config.py CHANGED
@@ -245,15 +245,19 @@ def set_config(key, value, section=None, file_path=None):
245
245
 
246
246
 
247
247
  def get_config():
248
- """Read the config file from the default location or env var
248
+ """Read the config file from the default location or env var.
249
249
 
250
- It will read a config file at either the default location
251
- ~/.qiskit/settings.conf or if set the value of the QISKIT_SETTINGS env var.
250
+ It will read a config file at the location specified by the ``QISKIT_SETTINGS`` environment
251
+ variable if set, or ``$HOME/.qiskit/settings.conf`` if not.
252
+
253
+ If the environment variable ``QISKIT_IGNORE_USER_SETTINGS`` is set to the string ``TRUE``, this
254
+ will return an empty configuration, regardless of all other variables.
252
255
 
253
- It will return the parsed settings dict from the parsed config file.
254
256
  Returns:
255
257
  dict: The settings dict from the parsed config file.
256
258
  """
259
+ if os.getenv("QISKIT_IGNORE_USER_SETTINGS", "false").lower() == "true":
260
+ return {}
257
261
  filename = os.getenv("QISKIT_SETTINGS", DEFAULT_FILENAME)
258
262
  if not os.path.isfile(filename):
259
263
  return {}
qiskit/utils/__init__.py CHANGED
@@ -23,9 +23,7 @@ Deprecations
23
23
 
24
24
  .. autofunction:: add_deprecation_to_docstring
25
25
  .. autofunction:: deprecate_arg
26
- .. autofunction:: deprecate_arguments
27
26
  .. autofunction:: deprecate_func
28
- .. autofunction:: deprecate_function
29
27
 
30
28
  SI unit conversion
31
29
  ==================
@@ -41,8 +39,10 @@ Class tools
41
39
  Multiprocessing
42
40
  ===============
43
41
 
44
- .. autofunction:: local_hardware_info
42
+ .. autofunction:: default_num_processes
45
43
  .. autofunction:: is_main_process
44
+ .. autofunction:: local_hardware_info
45
+ .. autofunction:: should_run_in_parallel
46
46
 
47
47
  A helper function for calling a custom function with Python
48
48
  :class:`~concurrent.futures.ProcessPoolExecutor`. Tasks can be executed in parallel using this function.
@@ -58,32 +58,33 @@ Optional Dependency Checkers
58
58
  from .deprecation import (
59
59
  add_deprecation_to_docstring,
60
60
  deprecate_arg,
61
- deprecate_arguments,
62
61
  deprecate_func,
63
- deprecate_function,
64
62
  )
65
- from .multiprocessing import local_hardware_info
66
- from .multiprocessing import is_main_process
67
63
  from .units import apply_prefix, detach_prefix
68
64
  from .classtools import wrap_method
69
65
  from .lazy_tester import LazyDependencyManager, LazyImportTester, LazySubprocessTester
70
66
 
71
67
  from . import optionals
72
68
 
73
- from .parallel import parallel_map, should_run_in_parallel
69
+ from .parallel import (
70
+ parallel_map,
71
+ should_run_in_parallel,
72
+ local_hardware_info,
73
+ is_main_process,
74
+ default_num_processes,
75
+ )
74
76
 
75
77
  __all__ = [
76
78
  "LazyDependencyManager",
77
79
  "LazyImportTester",
78
80
  "LazySubprocessTester",
79
81
  "add_deprecation_to_docstring",
82
+ "apply_prefix",
83
+ "default_num_processes",
80
84
  "deprecate_arg",
81
- "deprecate_arguments",
82
85
  "deprecate_func",
83
- "deprecate_function",
84
- "local_hardware_info",
85
86
  "is_main_process",
86
- "apply_prefix",
87
+ "local_hardware_info",
87
88
  "parallel_map",
88
89
  "should_run_in_parallel",
89
90
  ]
@@ -26,7 +26,7 @@ def deprecate_func(
26
26
  since: str,
27
27
  additional_msg: str | None = None,
28
28
  pending: bool = False,
29
- package_name: str = "qiskit",
29
+ package_name: str = "Qiskit",
30
30
  removal_timeline: str = "no earlier than 3 months after the release date",
31
31
  is_property: bool = False,
32
32
  stacklevel: int = 2,
@@ -45,7 +45,7 @@ def deprecate_func(
45
45
  For example, "Instead, use the function ``new_func`` from the module
46
46
  ``<my_module>.<my_submodule>``, which is similar but uses GPU acceleration."
47
47
  pending: Set to ``True`` if the deprecation is still pending.
48
- package_name: The PyPI package name, e.g. "qiskit-nature".
48
+ package_name: The package name shown in the deprecation message (e.g. the PyPI package name).
49
49
  removal_timeline: How soon can this deprecation be removed? Expects a value
50
50
  like "no sooner than 6 months after the latest release" or "in release 9.99".
51
51
  is_property: If the deprecated function is a `@property`, set this to True so that the
@@ -109,7 +109,7 @@ def deprecate_arg(
109
109
  additional_msg: str | None = None,
110
110
  deprecation_description: str | None = None,
111
111
  pending: bool = False,
112
- package_name: str = "qiskit",
112
+ package_name: str = "Qiskit",
113
113
  new_alias: str | None = None,
114
114
  predicate: Callable[[Any], bool] | None = None,
115
115
  removal_timeline: str = "no earlier than 3 months after the release date",
@@ -130,7 +130,7 @@ def deprecate_arg(
130
130
  (if new_alias is not set). For example, "Instead, use the argument `new_arg`,
131
131
  which is similar but does not impact the circuit's setup."
132
132
  pending: Set to `True` if the deprecation is still pending.
133
- package_name: The PyPI package name, e.g. "qiskit-nature".
133
+ package_name: The package name shown in the deprecation message (e.g. the PyPI package name).
134
134
  new_alias: If the arg has simply been renamed, set this to the new name. The decorator will
135
135
  dynamically update the `kwargs` so that when the user sets the old arg, it will be
136
136
  passed in as the `new_alias` arg.
@@ -205,114 +205,6 @@ def deprecate_arg(
205
205
  return decorator
206
206
 
207
207
 
208
- def deprecate_arguments(
209
- kwarg_map: dict[str, str | None],
210
- category: Type[Warning] = DeprecationWarning,
211
- *,
212
- since: str | None = None,
213
- ):
214
- """Deprecated. Instead, use `@deprecate_arg`.
215
-
216
- Args:
217
- kwarg_map: A dictionary of the old argument name to the new name.
218
- category: Usually either DeprecationWarning or PendingDeprecationWarning.
219
- since: The version the deprecation started at. Only Optional for backwards
220
- compatibility - this should always be set. If the deprecation is pending, set
221
- the version to when that started; but later, when switching from pending to
222
- deprecated, update `since` to the new version.
223
-
224
- Returns:
225
- Callable: The decorated callable.
226
- """
227
-
228
- def decorator(func):
229
- func_name = func.__qualname__
230
- old_kwarg_to_msg = {}
231
- for old_arg, new_arg in kwarg_map.items():
232
- msg_suffix = (
233
- "will in the future be removed." if new_arg is None else f"replaced with {new_arg}."
234
- )
235
- old_kwarg_to_msg[old_arg] = (
236
- f"{func_name} keyword argument {old_arg} is deprecated and {msg_suffix}"
237
- )
238
-
239
- @functools.wraps(func)
240
- def wrapper(*args, **kwargs):
241
- for old, new in kwarg_map.items():
242
- _maybe_warn_and_rename_kwarg(
243
- args,
244
- kwargs,
245
- func_name=func_name,
246
- original_func_co_varnames=wrapper.__original_func_co_varnames,
247
- old_arg_name=old,
248
- new_alias=new,
249
- warning_msg=old_kwarg_to_msg[old],
250
- category=category,
251
- predicate=None,
252
- )
253
- return func(*args, **kwargs)
254
-
255
- # When decorators get called repeatedly, `func` refers to the result of the prior
256
- # decorator, not the original underlying function. This trick allows us to record the
257
- # original function's variable names regardless of how many decorators are used.
258
- #
259
- # If it's the very first decorator call, we also check that *args and **kwargs are not used.
260
- if hasattr(func, "__original_func_co_varnames"):
261
- wrapper.__original_func_co_varnames = func.__original_func_co_varnames
262
- else:
263
- wrapper.__original_func_co_varnames = func.__code__.co_varnames
264
- param_kinds = {param.kind for param in inspect.signature(func).parameters.values()}
265
- if inspect.Parameter.VAR_POSITIONAL in param_kinds:
266
- raise ValueError(
267
- "@deprecate_arg cannot be used with functions that take variable *args. Use "
268
- "warnings.warn() directly instead."
269
- )
270
-
271
- for msg in old_kwarg_to_msg.values():
272
- add_deprecation_to_docstring(
273
- wrapper, msg, since=since, pending=issubclass(category, PendingDeprecationWarning)
274
- )
275
- return wrapper
276
-
277
- return decorator
278
-
279
-
280
- def deprecate_function(
281
- msg: str,
282
- stacklevel: int = 2,
283
- category: Type[Warning] = DeprecationWarning,
284
- *,
285
- since: str | None = None,
286
- ):
287
- """Deprecated. Instead, use `@deprecate_func`.
288
-
289
- Args:
290
- msg: Warning message to emit.
291
- stacklevel: The warning stacklevel to use, defaults to 2.
292
- category: Usually either DeprecationWarning or PendingDeprecationWarning.
293
- since: The version the deprecation started at. Only Optional for backwards
294
- compatibility - this should always be set. If the deprecation is pending, set
295
- the version to when that started; but later, when switching from pending to
296
- deprecated, update `since` to the new version.
297
-
298
- Returns:
299
- Callable: The decorated, deprecated callable.
300
- """
301
-
302
- def decorator(func):
303
- @functools.wraps(func)
304
- def wrapper(*args, **kwargs):
305
- warnings.warn(msg, category=category, stacklevel=stacklevel)
306
- return func(*args, **kwargs)
307
-
308
- add_deprecation_to_docstring(
309
- wrapper, msg, since=since, pending=issubclass(category, PendingDeprecationWarning)
310
- )
311
- return wrapper
312
-
313
- return decorator
314
-
315
-
316
208
  def _maybe_warn_and_rename_kwarg(
317
209
  args: tuple[Any, ...],
318
210
  kwargs: dict[str, Any],
qiskit/utils/optionals.py CHANGED
@@ -177,6 +177,13 @@ External Python Libraries
177
177
  special methods from Symengine to accelerate its handling of
178
178
  :class:`~.circuit.Parameter`\\ s if available.
179
179
 
180
+ .. py:data:: HAS_SYMPY
181
+
182
+ `SymPy <https://www.sympy.org/en/index.html>`__ is Python library for symbolic mathematics.
183
+ Sympy was historically used for the implementation of the :class:`.ParameterExpression`
184
+ class but isn't any longer. However it is needed for some legacy functionality that uses
185
+ :meth:`.ParameterExpression.sympify`. It is also used in some visualization functions.
186
+
180
187
  .. py:data:: HAS_TESTTOOLS
181
188
 
182
189
  Qiskit's test suite has more advanced functionality available if the optional
@@ -186,9 +193,8 @@ External Python Libraries
186
193
  .. py:data:: HAS_TWEEDLEDUM
187
194
 
188
195
  `Tweedledum <https://github.com/boschmitt/tweedledum>`__ is an extension library for
189
- synthesis and optimization of circuits that may involve classical oracles. Qiskit's
190
- :class:`.PhaseOracle` uses this, which is used in turn by amplification algorithms via
191
- the :class:`.AmplificationProblem`.
196
+ synthesis and optimization of circuits that may involve classical oracles. In the past
197
+ Qiskit's :class:`.PhaseOracle` used this but it is no longer used by Qiskit.
192
198
 
193
199
  .. py:data:: HAS_Z3
194
200
 
@@ -323,7 +329,8 @@ HAS_SKQUANT = _LazyImportTester(
323
329
  install="pip install scikit-quant",
324
330
  )
325
331
  HAS_SQSNOBFIT = _LazyImportTester("SQSnobFit", install="pip install SQSnobFit")
326
- HAS_SYMENGINE = _LazyImportTester("symengine", install="pip install symengine")
332
+ HAS_SYMENGINE = _LazyImportTester("symengine", install="pip install symengine<0.14")
333
+ HAS_SYMPY = _LazyImportTester("sympy", install="pip install sympy")
327
334
  HAS_TESTTOOLS = _LazyImportTester("testtools", install="pip install testtools")
328
335
  HAS_TWEEDLEDUM = _LazyImportTester("tweedledum", install="pip install tweedledum")
329
336
  HAS_Z3 = _LazyImportTester("z3", install="pip install z3-solver")
qiskit/utils/parallel.py CHANGED
@@ -10,7 +10,11 @@
10
10
  # copyright notice, and modified files need to carry a notice indicating
11
11
  # that they have been altered from the originals.
12
12
 
13
- # This file is part of QuTiP: Quantum Toolbox in Python.
13
+ # The original implementation of Qiskit's `parallel_map` in our commit c9c4ed52 was substantially
14
+ # derived from QuTiP's (https://github.com/qutip/qutip) in `qutip/parallel.py` at their commit
15
+ # f22d3cb7. It has subsequently been significantly rewritten.
16
+ #
17
+ # The original implementation was used under these licence terms:
14
18
  #
15
19
  # Copyright (c) 2011 and later, Paul D. Nation and Robert J. Johansson.
16
20
  # All rights reserved.
@@ -50,85 +54,226 @@ from the multiprocessing library.
50
54
 
51
55
  from __future__ import annotations
52
56
 
57
+ import contextlib
58
+ import functools
59
+ import multiprocessing
53
60
  import os
54
- from concurrent.futures import ProcessPoolExecutor
61
+ import platform
55
62
  import sys
63
+ import warnings
64
+ from concurrent.futures import ProcessPoolExecutor
56
65
 
57
- from qiskit.exceptions import QiskitError
58
- from qiskit.utils.multiprocessing import local_hardware_info
59
66
  from qiskit import user_config
60
67
 
61
68
 
62
- def get_platform_parallel_default():
63
- """
64
- Returns the default parallelism flag value for the current platform.
69
+ CONFIG = user_config.get_config()
65
70
 
66
- Returns:
67
- parallel_default: The default parallelism flag value for the
68
- current platform.
69
71
 
70
- """
71
- # Default False on Windows
72
- if sys.platform == "win32":
73
- parallel_default = False
74
- # On macOS default false on Python >=3.8
75
- elif sys.platform == "darwin":
76
- parallel_default = False
77
- # On linux (and other OSes) default to True
72
+ def _task_wrapper(param):
73
+ (task, value, task_args, task_kwargs) = param
74
+ return task(value, *task_args, **task_kwargs)
75
+
76
+
77
+ def _physical_cpus_assuming_twofold_smt():
78
+ if (sched_getaffinity := getattr(os, "sched_getaffinity", None)) is not None:
79
+ # It is callable, just pylint doesn't recognise it as `os.sched_getaffinity` because of the
80
+ # `getattr`.
81
+ # pylint: disable=not-callable
82
+ num_cpus = len(sched_getaffinity(0))
78
83
  else:
79
- parallel_default = True
84
+ num_cpus = os.cpu_count() or 1
85
+ return (num_cpus // 2) or 1
80
86
 
81
- return parallel_default
82
87
 
88
+ def _parallel_default():
89
+ # We default to False on `spawn`-based multiprocessing implementations, True on everything else.
90
+ if (set_start_method := multiprocessing.get_start_method(allow_none=True)) is None:
91
+ # The method hasn't been explicitly set, but it would be badly behaved of us to set it for
92
+ # the user, so handle platform defaults.
93
+ return sys.platform not in ("darwin", "win32")
94
+ return set_start_method in ("fork", "forkserver")
83
95
 
84
- CONFIG = user_config.get_config()
85
96
 
86
- if os.getenv("QISKIT_PARALLEL", None) is not None:
87
- PARALLEL_DEFAULT = os.getenv("QISKIT_PARALLEL", None).lower() == "true"
88
- else:
89
- PARALLEL_DEFAULT = get_platform_parallel_default()
97
+ @functools.cache
98
+ def default_num_processes() -> int:
99
+ """Get the number of processes that a multiprocessing parallel call will use by default.
90
100
 
91
- # Set parallel flag
92
- if os.getenv("QISKIT_IN_PARALLEL") is None:
93
- os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
101
+ Such functions typically also accept a ``num_processes`` keyword argument that will supersede
102
+ the value returned from this function.
94
103
 
95
- if os.getenv("QISKIT_NUM_PROCS") is not None:
96
- CPU_COUNT = int(os.getenv("QISKIT_NUM_PROCS"))
97
- else:
98
- CPU_COUNT = CONFIG.get("num_process", local_hardware_info()["cpus"])
104
+ In order of priority (highest to lowest), the return value will be:
99
105
 
106
+ 1. The ``QISKIT_NUM_PROCS`` environment variable, if set.
107
+ 2. The ``num_processes`` key of the Qiskit user configuration file, if set.
108
+ 3. Half of the logical CPUs available to this process, if this can be determined. This is a
109
+ proxy for the number of physical CPUs, assuming two-fold simultaneous multithreading (SMT);
110
+ empirically, multiprocessing performance of Qiskit seems to be worse when attempting to use
111
+ SMT cores.
112
+ 4. 1, if all else fails.
100
113
 
101
- def _task_wrapper(param):
102
- (task, value, task_args, task_kwargs) = param
103
- return task(value, *task_args, **task_kwargs)
114
+ If a user-configured value is set to a number less than 1, it is treated as if it were 1.
115
+ """
116
+ # Ignore both `None` (unset) and explicit set to empty string.
117
+ if env_num_processes := os.getenv("QISKIT_NUM_PROCS"):
118
+ try:
119
+ env_num_processes = int(env_num_processes)
120
+ except ValueError:
121
+ # Invalid: fall back to other methods.
122
+ warnings.warn(
123
+ "failed to interpret environment 'QISKIT_NUM_PROCS' as a number:"
124
+ f" '{env_num_processes}'"
125
+ )
126
+ else:
127
+ return env_num_processes if env_num_processes > 0 else 1
128
+ if (user_num_processes := CONFIG.get("num_processes", None)) is not None:
129
+ return user_num_processes if user_num_processes > 0 else 1
130
+ return _physical_cpus_assuming_twofold_smt()
131
+
132
+
133
+ def local_hardware_info():
134
+ """Basic hardware information about the local machine.
135
+
136
+ Attempts to estimate the number of physical CPUs in the machine, even when hyperthreading is
137
+ turned on. CPU count defaults to 1 when true count can't be determined.
104
138
 
139
+ Returns:
140
+ dict: The hardware information.
141
+ """
142
+ return {
143
+ "python_compiler": platform.python_compiler(),
144
+ "python_build": ", ".join(platform.python_build()),
145
+ "python_version": platform.python_version(),
146
+ "os": platform.system(),
147
+ "cpus": _physical_cpus_assuming_twofold_smt(),
148
+ }
149
+
150
+
151
+ def is_main_process() -> bool:
152
+ """Checks whether the current process is the main one.
153
+
154
+ Since Python 3.8, this is identical to the standard Python way of calculating this::
155
+
156
+ >>> import multiprocessing
157
+ >>> multiprocessing.parent_process() is None
158
+
159
+ This function is left for backwards compatibility, but there is little reason not to use the
160
+ built-in tooling of Python.
161
+ """
162
+ return multiprocessing.parent_process() is None
163
+
164
+
165
+ _PARALLEL_OVERRIDE = None
166
+ _PARALLEL_IGNORE_USER_SETTINGS = False
167
+ _IN_PARALLEL_ALLOW_PARALLELISM = "FALSE"
168
+ _IN_PARALLEL_FORBID_PARALLELISM = "TRUE"
105
169
 
170
+
171
+ @functools.cache
106
172
  def should_run_in_parallel(num_processes: int | None = None) -> bool:
107
- """Return whether the current parallelisation configuration suggests that we should run things
108
- like :func:`parallel_map` in parallel (``True``) or degrade to serial (``False``).
173
+ """Decide whether a multiprocessing function should spawn subprocesses for parallelization.
174
+
175
+ In particular, this is how :func:`parallel_map` decides whether to use multiprocessing or not.
176
+ The ``num_processes`` argument alone does not enforce parallelism; by default, Qiskit will only
177
+ use process-based parallelism when a ``fork``-like process spawning start method is in effect.
178
+ You can override this decision either by setting the :mod:`multiprocessing` start method you
179
+ use, setting the ``QISKIT_PARALLEL`` environment variable to ``"TRUE"``, or setting
180
+ ``parallel = true`` in your user settings file.
181
+
182
+ This function includes two context managers that can be used to temporarily modify the return
183
+ value of this function:
184
+
185
+ .. autofunction:: qiskit.utils::should_run_in_parallel.override
186
+ .. autofunction:: qiskit.utils::should_run_in_parallel.ignore_user_settings
109
187
 
110
188
  Args:
111
- num_processes: the number of processes requested for use (if given).
112
- """
113
- num_processes = CPU_COUNT if num_processes is None else num_processes
114
- return (
115
- num_processes > 1
116
- and os.getenv("QISKIT_IN_PARALLEL", "FALSE") == "FALSE"
117
- and CONFIG.get("parallel_enabled", PARALLEL_DEFAULT)
118
- )
189
+ num_processes: the maximum number of processes requested for use (``None`` implies the
190
+ default).
119
191
 
192
+ Examples:
193
+ Temporarily override the configured settings to disable parallelism::
120
194
 
121
- def parallel_map( # pylint: disable=dangerous-default-value
122
- task, values, task_args=(), task_kwargs={}, num_processes=CPU_COUNT
123
- ):
195
+ >>> with should_run_in_parallel.override(True):
196
+ ... assert should_run_in_parallel(8)
197
+ >>> with should_run_in_parallel.override(False):
198
+ ... assert not should_run_in_parallel(8)
199
+ """
200
+ # It's a configuration function with many simple choices - it'd be less clean to return late.
201
+ # pylint: disable=too-many-return-statements
202
+ num_processes = default_num_processes() if num_processes is None else num_processes
203
+ if num_processes < 2:
204
+ # There's no resources to parallelise over.
205
+ return False
206
+ if (
207
+ os.getenv("QISKIT_IN_PARALLEL", _IN_PARALLEL_ALLOW_PARALLELISM)
208
+ != _IN_PARALLEL_ALLOW_PARALLELISM
209
+ ):
210
+ # This isn't a user-set variable; we set this to talk to our own child processes.
211
+ return False
212
+ if _PARALLEL_OVERRIDE is not None:
213
+ return _PARALLEL_OVERRIDE
214
+ if _PARALLEL_IGNORE_USER_SETTINGS:
215
+ return _parallel_default()
216
+ if (env_qiskit_parallel := os.getenv("QISKIT_PARALLEL")) is not None:
217
+ return env_qiskit_parallel.lower() == "true"
218
+ if (user_qiskit_parallel := CONFIG.get("parallel_enabled", None)) is not None:
219
+ return user_qiskit_parallel
220
+ # Otherwise, fallback to the default.
221
+ return _parallel_default()
222
+
223
+
224
+ @contextlib.contextmanager
225
+ def _parallel_ignore_user_settings():
226
+ """A context manager within which :func:`should_run_in_parallel` will ignore environmental
227
+ configuration variables.
228
+
229
+ In particular, the ``QISKIT_PARALLEL`` environment variable and the user-configuration file are
230
+ ignored within this context."""
231
+ # The way around this would be to encapsulate `should_run_in_parallel` into a class, but since
232
+ # it's a singleton, it ends up being functionally no different to a global anyway.
233
+ global _PARALLEL_IGNORE_USER_SETTINGS # pylint: disable=global-statement
234
+
235
+ should_run_in_parallel.cache_clear()
236
+ previous, _PARALLEL_IGNORE_USER_SETTINGS = _PARALLEL_IGNORE_USER_SETTINGS, True
237
+ try:
238
+ yield
239
+ finally:
240
+ _PARALLEL_IGNORE_USER_SETTINGS = previous
241
+ should_run_in_parallel.cache_clear()
242
+
243
+
244
+ @contextlib.contextmanager
245
+ def _parallel_override(value: bool):
246
+ """A context manager within which :func:`should_run_in_parallel` will return the given
247
+ ``value``.
248
+
249
+ This is not a *complete* override; Qiskit will never attempt to parallelize if only a single
250
+ process is available, and will not allow process-based parallelism at a depth greater than 1."""
251
+ # The way around this would be to encapsulate `should_run_in_parallel` into a class, but since
252
+ # it's a singleton, it ends up being functionally no different to a global anyway.
253
+ global _PARALLEL_OVERRIDE # pylint: disable=global-statement
254
+
255
+ should_run_in_parallel.cache_clear()
256
+ previous, _PARALLEL_OVERRIDE = _PARALLEL_OVERRIDE, value
257
+ try:
258
+ yield
259
+ finally:
260
+ _PARALLEL_OVERRIDE = previous
261
+ should_run_in_parallel.cache_clear()
262
+
263
+
264
+ should_run_in_parallel.ignore_user_settings = _parallel_ignore_user_settings
265
+ should_run_in_parallel.override = _parallel_override
266
+
267
+
268
+ def parallel_map(task, values, task_args=(), task_kwargs=None, num_processes=None):
124
269
  """
125
270
  Parallel execution of a mapping of `values` to the function `task`. This
126
271
  is functionally equivalent to::
127
272
 
128
273
  result = [task(value, *task_args, **task_kwargs) for value in values]
129
274
 
130
- This will parallelise the results if the number of ``values`` is greater than one, and the
131
- current system configuration permits parallelization.
275
+ This will parallelise the results if the number of ``values`` is greater than one and
276
+ :func:`should_run_in_parallel` returns ``True``. If not, it will run in serial.
132
277
 
133
278
  Args:
134
279
  task (func): Function that is to be called for each value in ``values``.
@@ -136,18 +281,18 @@ def parallel_map( # pylint: disable=dangerous-default-value
136
281
  evaluated.
137
282
  task_args (list): Optional additional arguments to the ``task`` function.
138
283
  task_kwargs (dict): Optional additional keyword argument to the ``task`` function.
139
- num_processes (int): Number of processes to spawn.
284
+ num_processes (int): Number of processes to spawn. If not given, the return value of
285
+ :func:`default_num_processes` is used.
140
286
 
141
287
  Returns:
142
288
  result: The result list contains the value of ``task(value, *task_args, **task_kwargs)`` for
143
289
  each value in ``values``.
144
290
 
145
- Raises:
146
- QiskitError: If user interrupts via keyboard.
147
-
148
291
  Examples:
149
292
 
150
- .. code-block:: python
293
+ .. plot::
294
+ :include-source:
295
+ :nofigs:
151
296
 
152
297
  import time
153
298
  from qiskit.utils import parallel_map
@@ -156,36 +301,18 @@ def parallel_map( # pylint: disable=dangerous-default-value
156
301
  return 0
157
302
  parallel_map(func, list(range(10)));
158
303
  """
304
+ task_kwargs = {} if task_kwargs is None else task_kwargs
159
305
  if num_processes is None:
160
- num_processes = CPU_COUNT
161
- if len(values) == 0:
162
- return []
163
- if len(values) == 1:
164
- return [task(values[0], *task_args, **task_kwargs)]
165
-
166
- if should_run_in_parallel(num_processes):
167
- os.environ["QISKIT_IN_PARALLEL"] = "TRUE"
168
- try:
169
- results = []
170
- with ProcessPoolExecutor(max_workers=num_processes) as executor:
171
- param = ((task, value, task_args, task_kwargs) for value in values)
172
- future = executor.map(_task_wrapper, param)
173
-
174
- results = list(future)
175
-
176
- except (KeyboardInterrupt, Exception) as error:
177
- if isinstance(error, KeyboardInterrupt):
178
- os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
179
- raise QiskitError("Keyboard interrupt in parallel_map.") from error
180
- # Otherwise just reset parallel flag and error
181
- os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
182
- raise error
183
-
184
- os.environ["QISKIT_IN_PARALLEL"] = "FALSE"
185
- return results
186
-
187
- results = []
188
- for _, value in enumerate(values):
189
- result = task(value, *task_args, **task_kwargs)
190
- results.append(result)
191
- return results
306
+ num_processes = default_num_processes()
307
+ if len(values) < 2 or not should_run_in_parallel(num_processes):
308
+ return [task(value, *task_args, **task_kwargs) for value in values]
309
+ work_items = ((task, value, task_args, task_kwargs) for value in values)
310
+
311
+ # This isn't a user-set variable; we set this to talk to our own child processes.
312
+ previous_in_parallel = os.getenv("QISKIT_IN_PARALLEL", _IN_PARALLEL_ALLOW_PARALLELISM)
313
+ os.environ["QISKIT_IN_PARALLEL"] = _IN_PARALLEL_FORBID_PARALLELISM
314
+ try:
315
+ with ProcessPoolExecutor(max_workers=num_processes) as executor:
316
+ return list(executor.map(_task_wrapper, work_items))
317
+ finally:
318
+ os.environ["QISKIT_IN_PARALLEL"] = previous_in_parallel
qiskit/utils/units.py CHANGED
@@ -13,9 +13,12 @@
13
13
  """SI unit utilities"""
14
14
  from __future__ import annotations
15
15
 
16
+ import typing
17
+
16
18
  import numpy as np
17
19
 
18
- from qiskit.circuit.parameterexpression import ParameterExpression
20
+ if typing.TYPE_CHECKING:
21
+ from qiskit.circuit.parameterexpression import ParameterExpression
19
22
 
20
23
 
21
24
  def apply_prefix(value: float | ParameterExpression, unit: str) -> float | ParameterExpression: