qiskit 1.4.1__cp39-abi3-win_amd64.whl → 2.0.0rc1__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 (456) 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 +2 -6
  75. qiskit/circuit/library/standard_gates/rx.py +5 -15
  76. qiskit/circuit/library/standard_gates/rxx.py +3 -6
  77. qiskit/circuit/library/standard_gates/ry.py +5 -17
  78. qiskit/circuit/library/standard_gates/ryy.py +3 -6
  79. qiskit/circuit/library/standard_gates/rz.py +5 -17
  80. qiskit/circuit/library/standard_gates/rzx.py +3 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +3 -6
  82. qiskit/circuit/library/standard_gates/s.py +6 -15
  83. qiskit/circuit/library/standard_gates/swap.py +4 -11
  84. qiskit/circuit/library/standard_gates/sx.py +7 -12
  85. qiskit/circuit/library/standard_gates/t.py +6 -7
  86. qiskit/circuit/library/standard_gates/u.py +2 -10
  87. qiskit/circuit/library/standard_gates/u1.py +5 -16
  88. qiskit/circuit/library/standard_gates/u2.py +2 -6
  89. qiskit/circuit/library/standard_gates/u3.py +3 -11
  90. qiskit/circuit/library/standard_gates/x.py +13 -60
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -5
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -5
  93. qiskit/circuit/library/standard_gates/y.py +4 -9
  94. qiskit/circuit/library/standard_gates/z.py +5 -15
  95. qiskit/circuit/measure.py +11 -2
  96. qiskit/circuit/parameterexpression.py +4 -0
  97. qiskit/circuit/quantumcircuit.py +881 -555
  98. qiskit/circuit/random/utils.py +12 -6
  99. qiskit/circuit/reset.py +5 -2
  100. qiskit/circuit/singleton.py +5 -11
  101. qiskit/circuit/store.py +0 -8
  102. qiskit/compiler/__init__.py +1 -7
  103. qiskit/compiler/transpiler.py +38 -196
  104. qiskit/converters/circuit_to_dag.py +4 -2
  105. qiskit/converters/circuit_to_dagdependency.py +0 -2
  106. qiskit/converters/circuit_to_dagdependency_v2.py +0 -1
  107. qiskit/converters/circuit_to_gate.py +1 -1
  108. qiskit/converters/circuit_to_instruction.py +16 -29
  109. qiskit/converters/dag_to_circuit.py +5 -5
  110. qiskit/converters/dag_to_dagdependency.py +0 -1
  111. qiskit/converters/dag_to_dagdependency_v2.py +0 -1
  112. qiskit/converters/dagdependency_to_circuit.py +0 -6
  113. qiskit/converters/dagdependency_to_dag.py +0 -6
  114. qiskit/dagcircuit/collect_blocks.py +32 -20
  115. qiskit/dagcircuit/dagdependency.py +3 -37
  116. qiskit/dagcircuit/dagdependency_v2.py +2 -80
  117. qiskit/dagcircuit/dagnode.py +14 -2
  118. qiskit/passmanager/__init__.py +24 -6
  119. qiskit/passmanager/passmanager.py +26 -24
  120. qiskit/primitives/__init__.py +44 -35
  121. qiskit/primitives/backend_estimator_v2.py +102 -23
  122. qiskit/primitives/backend_sampler_v2.py +5 -20
  123. qiskit/primitives/base/__init__.py +4 -4
  124. qiskit/primitives/base/base_estimator.py +77 -82
  125. qiskit/primitives/base/base_primitive_job.py +2 -2
  126. qiskit/primitives/base/{base_primitive.py → base_primitive_v1.py} +1 -1
  127. qiskit/primitives/base/{base_result.py → base_result_v1.py} +1 -1
  128. qiskit/primitives/base/base_sampler.py +52 -60
  129. qiskit/primitives/base/{estimator_result.py → estimator_result_v1.py} +2 -2
  130. qiskit/primitives/base/{sampler_result.py → sampler_result_v1.py} +2 -2
  131. qiskit/primitives/base/{validation.py → validation_v1.py} +34 -15
  132. qiskit/primitives/containers/bindings_array.py +3 -1
  133. qiskit/primitives/containers/bit_array.py +23 -0
  134. qiskit/primitives/containers/data_bin.py +3 -1
  135. qiskit/primitives/containers/observables_array.py +19 -2
  136. qiskit/primitives/statevector_sampler.py +6 -8
  137. qiskit/primitives/utils.py +14 -189
  138. qiskit/providers/__init__.py +4 -130
  139. qiskit/providers/backend.py +11 -314
  140. qiskit/providers/basic_provider/__init__.py +3 -1
  141. qiskit/providers/basic_provider/basic_provider.py +29 -9
  142. qiskit/providers/basic_provider/basic_simulator.py +158 -298
  143. qiskit/providers/exceptions.py +0 -33
  144. qiskit/providers/fake_provider/__init__.py +0 -37
  145. qiskit/providers/fake_provider/generic_backend_v2.py +32 -693
  146. qiskit/qasm2/__init__.py +21 -6
  147. qiskit/qasm2/export.py +2 -10
  148. qiskit/qasm2/parse.py +11 -25
  149. qiskit/qasm3/__init__.py +5 -1
  150. qiskit/qasm3/ast.py +44 -0
  151. qiskit/qasm3/exporter.py +65 -27
  152. qiskit/qasm3/printer.py +35 -4
  153. qiskit/qpy/__init__.py +141 -19
  154. qiskit/qpy/binary_io/__init__.py +0 -1
  155. qiskit/qpy/binary_io/circuits.py +91 -116
  156. qiskit/qpy/binary_io/schedules.py +61 -388
  157. qiskit/qpy/binary_io/value.py +154 -28
  158. qiskit/qpy/common.py +10 -7
  159. qiskit/qpy/formats.py +41 -0
  160. qiskit/qpy/interface.py +29 -62
  161. qiskit/qpy/type_keys.py +58 -221
  162. qiskit/quantum_info/analysis/distance.py +3 -1
  163. qiskit/quantum_info/operators/dihedral/dihedral.py +3 -1
  164. qiskit/quantum_info/operators/operator.py +6 -2
  165. qiskit/quantum_info/operators/symplectic/clifford.py +3 -1
  166. qiskit/quantum_info/operators/symplectic/pauli.py +4 -2
  167. qiskit/quantum_info/operators/symplectic/pauli_list.py +17 -5
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +40 -6
  169. qiskit/quantum_info/states/densitymatrix.py +16 -6
  170. qiskit/quantum_info/states/stabilizerstate.py +35 -4
  171. qiskit/quantum_info/states/statevector.py +16 -6
  172. qiskit/result/__init__.py +5 -17
  173. qiskit/result/models.py +18 -10
  174. qiskit/result/result.py +28 -126
  175. qiskit/result/sampled_expval.py +1 -2
  176. qiskit/result/utils.py +3 -4
  177. qiskit/synthesis/__init__.py +21 -1
  178. qiskit/synthesis/arithmetic/__init__.py +3 -1
  179. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +1 -1
  180. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +1 -1
  181. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +2 -2
  182. qiskit/{providers/fake_provider/backends_v1/fake_20q → synthesis/arithmetic/comparators}/__init__.py +4 -6
  183. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  184. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  185. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -1
  186. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +1 -1
  187. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  188. qiskit/{result/mitigation → synthesis/boolean}/__init__.py +2 -2
  189. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  190. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  191. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  192. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +2 -0
  193. qiskit/synthesis/evolution/lie_trotter.py +10 -7
  194. qiskit/synthesis/evolution/product_formula.py +44 -35
  195. qiskit/synthesis/evolution/qdrift.py +17 -24
  196. qiskit/synthesis/evolution/suzuki_trotter.py +20 -27
  197. qiskit/synthesis/linear/linear_depth_lnn.py +6 -221
  198. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +4 -205
  199. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  200. qiskit/synthesis/multi_controlled/mcx_synthesis.py +5 -2
  201. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  202. qiskit/synthesis/one_qubit/one_qubit_decompose.py +1 -1
  203. qiskit/synthesis/two_qubit/__init__.py +1 -0
  204. qiskit/synthesis/two_qubit/two_qubit_decompose.py +28 -145
  205. qiskit/transpiler/__init__.py +32 -232
  206. qiskit/transpiler/basepasses.py +20 -51
  207. qiskit/transpiler/layout.py +1 -1
  208. qiskit/transpiler/passes/__init__.py +2 -40
  209. qiskit/transpiler/passes/basis/basis_translator.py +4 -3
  210. qiskit/transpiler/passes/basis/decompose.py +1 -15
  211. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -5
  212. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +3 -2
  213. qiskit/transpiler/passes/layout/apply_layout.py +4 -0
  214. qiskit/transpiler/passes/layout/dense_layout.py +2 -39
  215. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +4 -4
  216. qiskit/transpiler/passes/layout/sabre_layout.py +7 -3
  217. qiskit/transpiler/passes/layout/vf2_layout.py +2 -20
  218. qiskit/transpiler/passes/layout/vf2_post_layout.py +60 -125
  219. qiskit/transpiler/passes/layout/vf2_utils.py +2 -26
  220. qiskit/transpiler/passes/optimization/__init__.py +1 -3
  221. qiskit/transpiler/passes/optimization/collect_and_collapse.py +2 -0
  222. qiskit/transpiler/passes/optimization/collect_cliffords.py +5 -0
  223. qiskit/transpiler/passes/optimization/collect_linear_functions.py +5 -0
  224. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +16 -1
  225. qiskit/transpiler/passes/optimization/commutation_analysis.py +3 -3
  226. qiskit/transpiler/passes/optimization/consolidate_blocks.py +41 -19
  227. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  228. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  229. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +0 -1
  230. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +18 -22
  231. qiskit/transpiler/passes/optimization/optimize_annotated.py +3 -2
  232. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +6 -4
  233. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +5 -2
  234. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +26 -3
  235. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +1 -0
  236. qiskit/transpiler/passes/routing/__init__.py +0 -1
  237. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +3 -1
  238. qiskit/transpiler/passes/routing/sabre_swap.py +14 -6
  239. qiskit/transpiler/passes/routing/star_prerouting.py +1 -1
  240. qiskit/transpiler/passes/scheduling/__init__.py +1 -7
  241. qiskit/transpiler/passes/scheduling/alignments/__init__.py +2 -4
  242. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -9
  243. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +17 -16
  244. qiskit/transpiler/passes/scheduling/padding/base_padding.py +30 -2
  245. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +20 -58
  246. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +11 -3
  247. qiskit/transpiler/passes/scheduling/scheduling/alap.py +5 -39
  248. qiskit/transpiler/passes/scheduling/scheduling/asap.py +4 -35
  249. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +10 -16
  250. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +127 -59
  251. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  252. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +176 -601
  253. qiskit/transpiler/passes/synthesis/hls_plugins.py +294 -1
  254. qiskit/transpiler/passes/synthesis/plugin.py +4 -0
  255. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +16 -10
  256. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -697
  257. qiskit/transpiler/passes/utils/__init__.py +0 -1
  258. qiskit/transpiler/passes/utils/check_gate_direction.py +13 -5
  259. qiskit/transpiler/passes/utils/control_flow.py +2 -6
  260. qiskit/transpiler/passes/utils/gate_direction.py +7 -0
  261. qiskit/transpiler/passes/utils/remove_final_measurements.py +40 -33
  262. qiskit/transpiler/passmanager.py +13 -0
  263. qiskit/transpiler/passmanager_config.py +5 -81
  264. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +225 -344
  265. qiskit/transpiler/preset_passmanagers/common.py +140 -167
  266. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +101 -322
  267. qiskit/transpiler/preset_passmanagers/level0.py +2 -11
  268. qiskit/transpiler/preset_passmanagers/level1.py +2 -14
  269. qiskit/transpiler/preset_passmanagers/level2.py +2 -12
  270. qiskit/transpiler/preset_passmanagers/level3.py +2 -11
  271. qiskit/transpiler/preset_passmanagers/plugin.py +5 -3
  272. qiskit/transpiler/target.py +67 -524
  273. qiskit/user_config.py +8 -4
  274. qiskit/utils/__init__.py +13 -12
  275. qiskit/utils/deprecation.py +4 -112
  276. qiskit/utils/optionals.py +11 -4
  277. qiskit/utils/parallel.py +214 -87
  278. qiskit/utils/units.py +4 -1
  279. qiskit/visualization/__init__.py +3 -7
  280. qiskit/visualization/array.py +4 -1
  281. qiskit/visualization/bloch.py +1 -1
  282. qiskit/visualization/circuit/_utils.py +19 -19
  283. qiskit/visualization/circuit/circuit_visualization.py +11 -4
  284. qiskit/visualization/circuit/matplotlib.py +13 -23
  285. qiskit/visualization/circuit/text.py +7 -3
  286. qiskit/visualization/dag_visualization.py +2 -1
  287. qiskit/visualization/gate_map.py +39 -154
  288. qiskit/visualization/pass_manager_visualization.py +6 -2
  289. qiskit/visualization/state_visualization.py +6 -0
  290. qiskit/visualization/timeline/core.py +18 -12
  291. qiskit/visualization/timeline/interface.py +19 -18
  292. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/METADATA +2 -2
  293. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/RECORD +297 -444
  294. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/WHEEL +1 -1
  295. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/entry_points.txt +8 -2
  296. qiskit/assembler/__init__.py +0 -42
  297. qiskit/assembler/assemble_circuits.py +0 -451
  298. qiskit/assembler/assemble_schedules.py +0 -367
  299. qiskit/assembler/disassemble.py +0 -310
  300. qiskit/assembler/run_config.py +0 -77
  301. qiskit/circuit/bit.py +0 -106
  302. qiskit/circuit/classicalfunction/__init__.py +0 -152
  303. qiskit/circuit/classicalfunction/boolean_expression.py +0 -138
  304. qiskit/circuit/classicalfunction/classical_element.py +0 -54
  305. qiskit/circuit/classicalfunction/classical_function_visitor.py +0 -155
  306. qiskit/circuit/classicalfunction/classicalfunction.py +0 -182
  307. qiskit/circuit/classicalfunction/exceptions.py +0 -41
  308. qiskit/circuit/classicalfunction/types.py +0 -18
  309. qiskit/circuit/classicalfunction/utils.py +0 -91
  310. qiskit/circuit/classicalregister.py +0 -57
  311. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +0 -405
  312. qiskit/circuit/quantumregister.py +0 -75
  313. qiskit/circuit/register.py +0 -246
  314. qiskit/compiler/assembler.py +0 -689
  315. qiskit/compiler/scheduler.py +0 -109
  316. qiskit/compiler/sequencer.py +0 -71
  317. qiskit/primitives/backend_estimator.py +0 -486
  318. qiskit/primitives/backend_sampler.py +0 -222
  319. qiskit/primitives/estimator.py +0 -172
  320. qiskit/primitives/sampler.py +0 -162
  321. qiskit/providers/backend_compat.py +0 -507
  322. qiskit/providers/fake_provider/backends_v1/__init__.py +0 -22
  323. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/__init__.py +0 -18
  324. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/conf_washington.json +0 -1
  325. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/defs_washington.json +0 -1
  326. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/fake_127q_pulse_v1.py +0 -37
  327. qiskit/providers/fake_provider/backends_v1/fake_127q_pulse/props_washington.json +0 -1
  328. qiskit/providers/fake_provider/backends_v1/fake_20q/conf_singapore.json +0 -1
  329. qiskit/providers/fake_provider/backends_v1/fake_20q/fake_20q.py +0 -43
  330. qiskit/providers/fake_provider/backends_v1/fake_20q/props_singapore.json +0 -1
  331. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/__init__.py +0 -18
  332. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/conf_hanoi.json +0 -1
  333. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/defs_hanoi.json +0 -1
  334. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/fake_27q_pulse_v1.py +0 -50
  335. qiskit/providers/fake_provider/backends_v1/fake_27q_pulse/props_hanoi.json +0 -1
  336. qiskit/providers/fake_provider/backends_v1/fake_5q/__init__.py +0 -18
  337. qiskit/providers/fake_provider/backends_v1/fake_5q/conf_yorktown.json +0 -1
  338. qiskit/providers/fake_provider/backends_v1/fake_5q/fake_5q_v1.py +0 -41
  339. qiskit/providers/fake_provider/backends_v1/fake_5q/props_yorktown.json +0 -1
  340. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/__init__.py +0 -18
  341. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/conf_nairobi.json +0 -1
  342. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/defs_nairobi.json +0 -1
  343. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/fake_7q_pulse_v1.py +0 -44
  344. qiskit/providers/fake_provider/backends_v1/fake_7q_pulse/props_nairobi.json +0 -1
  345. qiskit/providers/fake_provider/fake_1q.py +0 -91
  346. qiskit/providers/fake_provider/fake_backend.py +0 -165
  347. qiskit/providers/fake_provider/fake_openpulse_2q.py +0 -391
  348. qiskit/providers/fake_provider/fake_openpulse_3q.py +0 -340
  349. qiskit/providers/fake_provider/fake_pulse_backend.py +0 -49
  350. qiskit/providers/fake_provider/fake_qasm_backend.py +0 -77
  351. qiskit/providers/fake_provider/utils/backend_converter.py +0 -150
  352. qiskit/providers/fake_provider/utils/json_decoder.py +0 -109
  353. qiskit/providers/models/__init__.py +0 -89
  354. qiskit/providers/models/backendconfiguration.py +0 -1040
  355. qiskit/providers/models/backendproperties.py +0 -535
  356. qiskit/providers/models/backendstatus.py +0 -104
  357. qiskit/providers/models/jobstatus.py +0 -77
  358. qiskit/providers/models/pulsedefaults.py +0 -305
  359. qiskit/providers/provider.py +0 -95
  360. qiskit/pulse/__init__.py +0 -158
  361. qiskit/pulse/builder.py +0 -2262
  362. qiskit/pulse/calibration_entries.py +0 -381
  363. qiskit/pulse/channels.py +0 -227
  364. qiskit/pulse/configuration.py +0 -245
  365. qiskit/pulse/exceptions.py +0 -45
  366. qiskit/pulse/filters.py +0 -309
  367. qiskit/pulse/instruction_schedule_map.py +0 -424
  368. qiskit/pulse/instructions/__init__.py +0 -67
  369. qiskit/pulse/instructions/acquire.py +0 -150
  370. qiskit/pulse/instructions/delay.py +0 -71
  371. qiskit/pulse/instructions/directives.py +0 -154
  372. qiskit/pulse/instructions/frequency.py +0 -135
  373. qiskit/pulse/instructions/instruction.py +0 -270
  374. qiskit/pulse/instructions/phase.py +0 -152
  375. qiskit/pulse/instructions/play.py +0 -99
  376. qiskit/pulse/instructions/reference.py +0 -100
  377. qiskit/pulse/instructions/snapshot.py +0 -82
  378. qiskit/pulse/library/__init__.py +0 -97
  379. qiskit/pulse/library/continuous.py +0 -430
  380. qiskit/pulse/library/pulse.py +0 -148
  381. qiskit/pulse/library/samplers/__init__.py +0 -15
  382. qiskit/pulse/library/samplers/decorators.py +0 -295
  383. qiskit/pulse/library/samplers/strategies.py +0 -71
  384. qiskit/pulse/library/symbolic_pulses.py +0 -1989
  385. qiskit/pulse/library/waveform.py +0 -136
  386. qiskit/pulse/macros.py +0 -262
  387. qiskit/pulse/parameter_manager.py +0 -445
  388. qiskit/pulse/parser.py +0 -314
  389. qiskit/pulse/reference_manager.py +0 -58
  390. qiskit/pulse/schedule.py +0 -1854
  391. qiskit/pulse/transforms/__init__.py +0 -106
  392. qiskit/pulse/transforms/alignments.py +0 -406
  393. qiskit/pulse/transforms/base_transforms.py +0 -71
  394. qiskit/pulse/transforms/canonicalization.py +0 -498
  395. qiskit/pulse/transforms/dag.py +0 -122
  396. qiskit/pulse/utils.py +0 -149
  397. qiskit/qobj/__init__.py +0 -75
  398. qiskit/qobj/common.py +0 -81
  399. qiskit/qobj/converters/__init__.py +0 -18
  400. qiskit/qobj/converters/lo_config.py +0 -177
  401. qiskit/qobj/converters/pulse_instruction.py +0 -897
  402. qiskit/qobj/pulse_qobj.py +0 -709
  403. qiskit/qobj/qasm_qobj.py +0 -708
  404. qiskit/qobj/utils.py +0 -46
  405. qiskit/result/mitigation/base_readout_mitigator.py +0 -79
  406. qiskit/result/mitigation/correlated_readout_mitigator.py +0 -277
  407. qiskit/result/mitigation/local_readout_mitigator.py +0 -328
  408. qiskit/result/mitigation/utils.py +0 -217
  409. qiskit/scheduler/__init__.py +0 -40
  410. qiskit/scheduler/config.py +0 -37
  411. qiskit/scheduler/lowering.py +0 -187
  412. qiskit/scheduler/methods/__init__.py +0 -15
  413. qiskit/scheduler/methods/basic.py +0 -140
  414. qiskit/scheduler/schedule_circuit.py +0 -69
  415. qiskit/scheduler/sequence.py +0 -104
  416. qiskit/transpiler/passes/calibration/__init__.py +0 -17
  417. qiskit/transpiler/passes/calibration/base_builder.py +0 -79
  418. qiskit/transpiler/passes/calibration/builders.py +0 -20
  419. qiskit/transpiler/passes/calibration/exceptions.py +0 -22
  420. qiskit/transpiler/passes/calibration/pulse_gate.py +0 -100
  421. qiskit/transpiler/passes/calibration/rx_builder.py +0 -164
  422. qiskit/transpiler/passes/calibration/rzx_builder.py +0 -411
  423. qiskit/transpiler/passes/calibration/rzx_templates.py +0 -58
  424. qiskit/transpiler/passes/optimization/cx_cancellation.py +0 -65
  425. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +0 -162
  426. qiskit/transpiler/passes/optimization/normalize_rx_angle.py +0 -157
  427. qiskit/transpiler/passes/routing/stochastic_swap.py +0 -532
  428. qiskit/transpiler/passes/scheduling/alap.py +0 -153
  429. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +0 -255
  430. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -107
  431. qiskit/transpiler/passes/scheduling/asap.py +0 -175
  432. qiskit/transpiler/passes/scheduling/base_scheduler.py +0 -310
  433. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +0 -313
  434. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -93
  435. qiskit/utils/deprecate_pulse.py +0 -119
  436. qiskit/utils/multiprocessing.py +0 -56
  437. qiskit/visualization/pulse_v2/__init__.py +0 -21
  438. qiskit/visualization/pulse_v2/core.py +0 -901
  439. qiskit/visualization/pulse_v2/device_info.py +0 -173
  440. qiskit/visualization/pulse_v2/drawings.py +0 -253
  441. qiskit/visualization/pulse_v2/events.py +0 -254
  442. qiskit/visualization/pulse_v2/generators/__init__.py +0 -40
  443. qiskit/visualization/pulse_v2/generators/barrier.py +0 -76
  444. qiskit/visualization/pulse_v2/generators/chart.py +0 -208
  445. qiskit/visualization/pulse_v2/generators/frame.py +0 -436
  446. qiskit/visualization/pulse_v2/generators/snapshot.py +0 -133
  447. qiskit/visualization/pulse_v2/generators/waveform.py +0 -645
  448. qiskit/visualization/pulse_v2/interface.py +0 -459
  449. qiskit/visualization/pulse_v2/layouts.py +0 -387
  450. qiskit/visualization/pulse_v2/plotters/__init__.py +0 -17
  451. qiskit/visualization/pulse_v2/plotters/base_plotter.py +0 -53
  452. qiskit/visualization/pulse_v2/plotters/matplotlib.py +0 -201
  453. qiskit/visualization/pulse_v2/stylesheet.py +0 -312
  454. qiskit/visualization/pulse_v2/types.py +0 -242
  455. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.dist-info}/LICENSE.txt +0 -0
  456. {qiskit-1.4.1.dist-info → qiskit-2.0.0rc1.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: