qiskit 1.3.0__cp39-abi3-win32.whl → 1.3.0b1__cp39-abi3-win32.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 (361) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +1 -20
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/assembler/assemble_schedules.py +0 -2
  5. qiskit/circuit/__init__.py +1 -44
  6. qiskit/circuit/_standard_gates_commutations.py +0 -585
  7. qiskit/circuit/barrier.py +0 -2
  8. qiskit/circuit/controlflow/builder.py +3 -3
  9. qiskit/circuit/controlflow/if_else.py +5 -13
  10. qiskit/circuit/controlflow/while_loop.py +2 -10
  11. qiskit/circuit/delay.py +3 -20
  12. qiskit/circuit/equivalence.py +214 -13
  13. qiskit/circuit/gate.py +1 -3
  14. qiskit/circuit/instruction.py +11 -32
  15. qiskit/circuit/instructionset.py +0 -2
  16. qiskit/circuit/library/__init__.py +14 -110
  17. qiskit/circuit/library/arithmetic/__init__.py +2 -9
  18. qiskit/circuit/library/arithmetic/adders/__init__.py +0 -1
  19. qiskit/circuit/library/arithmetic/adders/adder.py +2 -154
  20. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +56 -20
  21. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +1 -14
  22. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +91 -21
  23. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
  24. qiskit/circuit/library/arithmetic/multipliers/__init__.py +0 -1
  25. qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +1 -8
  26. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +3 -94
  27. qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +1 -8
  28. qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
  29. qiskit/circuit/library/basis_change/qft.py +38 -20
  30. qiskit/circuit/library/blueprintcircuit.py +0 -64
  31. qiskit/circuit/library/boolean_logic/__init__.py +4 -4
  32. qiskit/circuit/library/boolean_logic/inner_product.py +4 -81
  33. qiskit/circuit/library/boolean_logic/quantum_and.py +4 -107
  34. qiskit/circuit/library/boolean_logic/quantum_or.py +3 -107
  35. qiskit/circuit/library/boolean_logic/quantum_xor.py +3 -97
  36. qiskit/circuit/library/data_preparation/__init__.py +3 -6
  37. qiskit/circuit/library/data_preparation/pauli_feature_map.py +29 -342
  38. qiskit/circuit/library/data_preparation/{_z_feature_map.py → z_feature_map.py} +34 -45
  39. qiskit/circuit/library/data_preparation/zz_feature_map.py +118 -0
  40. qiskit/circuit/library/fourier_checking.py +11 -72
  41. qiskit/circuit/library/generalized_gates/__init__.py +1 -1
  42. qiskit/circuit/library/generalized_gates/diagonal.py +51 -45
  43. qiskit/circuit/library/generalized_gates/gms.py +14 -67
  44. qiskit/circuit/library/generalized_gates/gr.py +4 -4
  45. qiskit/circuit/library/generalized_gates/isometry.py +2 -2
  46. qiskit/circuit/library/generalized_gates/linear_function.py +6 -12
  47. qiskit/circuit/library/generalized_gates/mcmt.py +107 -167
  48. qiskit/circuit/library/generalized_gates/permutation.py +6 -8
  49. qiskit/circuit/library/generalized_gates/rv.py +9 -8
  50. qiskit/circuit/library/graph_state.py +10 -93
  51. qiskit/circuit/library/grover_operator.py +2 -270
  52. qiskit/circuit/library/hidden_linear_function.py +20 -83
  53. qiskit/circuit/library/iqp.py +20 -99
  54. qiskit/circuit/library/n_local/__init__.py +7 -19
  55. qiskit/circuit/library/n_local/efficient_su2.py +5 -118
  56. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +0 -259
  57. qiskit/circuit/library/n_local/excitation_preserving.py +6 -130
  58. qiskit/circuit/library/n_local/n_local.py +5 -406
  59. qiskit/circuit/library/n_local/pauli_two_design.py +4 -106
  60. qiskit/circuit/library/n_local/qaoa_ansatz.py +1 -80
  61. qiskit/circuit/library/n_local/real_amplitudes.py +7 -127
  62. qiskit/circuit/library/n_local/two_local.py +7 -14
  63. qiskit/circuit/library/overlap.py +26 -91
  64. qiskit/circuit/library/pauli_evolution.py +15 -17
  65. qiskit/circuit/library/phase_estimation.py +4 -80
  66. qiskit/circuit/library/quantum_volume.py +20 -72
  67. qiskit/circuit/library/standard_gates/__init__.py +1 -20
  68. qiskit/circuit/library/standard_gates/dcx.py +1 -2
  69. qiskit/circuit/library/standard_gates/ecr.py +2 -2
  70. qiskit/circuit/library/standard_gates/h.py +3 -4
  71. qiskit/circuit/library/standard_gates/i.py +1 -2
  72. qiskit/circuit/library/standard_gates/iswap.py +2 -2
  73. qiskit/circuit/library/standard_gates/p.py +12 -20
  74. qiskit/circuit/library/standard_gates/r.py +1 -1
  75. qiskit/circuit/library/standard_gates/rx.py +3 -4
  76. qiskit/circuit/library/standard_gates/rxx.py +2 -2
  77. qiskit/circuit/library/standard_gates/ry.py +3 -4
  78. qiskit/circuit/library/standard_gates/ryy.py +2 -2
  79. qiskit/circuit/library/standard_gates/rz.py +12 -13
  80. qiskit/circuit/library/standard_gates/rzx.py +6 -6
  81. qiskit/circuit/library/standard_gates/rzz.py +1 -1
  82. qiskit/circuit/library/standard_gates/s.py +4 -4
  83. qiskit/circuit/library/standard_gates/swap.py +3 -3
  84. qiskit/circuit/library/standard_gates/sx.py +3 -4
  85. qiskit/circuit/library/standard_gates/t.py +2 -2
  86. qiskit/circuit/library/standard_gates/u.py +3 -11
  87. qiskit/circuit/library/standard_gates/u1.py +15 -65
  88. qiskit/circuit/library/standard_gates/u2.py +1 -4
  89. qiskit/circuit/library/standard_gates/u3.py +3 -31
  90. qiskit/circuit/library/standard_gates/x.py +5 -7
  91. qiskit/circuit/library/standard_gates/xx_minus_yy.py +2 -2
  92. qiskit/circuit/library/standard_gates/xx_plus_yy.py +2 -2
  93. qiskit/circuit/library/standard_gates/y.py +3 -4
  94. qiskit/circuit/library/standard_gates/z.py +3 -3
  95. qiskit/circuit/library/templates/clifford/clifford_2_1.py +8 -9
  96. qiskit/circuit/library/templates/clifford/clifford_2_2.py +9 -10
  97. qiskit/circuit/library/templates/clifford/clifford_2_3.py +7 -9
  98. qiskit/circuit/library/templates/clifford/clifford_2_4.py +8 -9
  99. qiskit/circuit/library/templates/clifford/clifford_3_1.py +8 -9
  100. qiskit/circuit/library/templates/clifford/clifford_4_1.py +9 -10
  101. qiskit/circuit/library/templates/clifford/clifford_4_2.py +9 -10
  102. qiskit/circuit/library/templates/clifford/clifford_4_3.py +9 -10
  103. qiskit/circuit/library/templates/clifford/clifford_4_4.py +9 -10
  104. qiskit/circuit/library/templates/clifford/clifford_5_1.py +9 -10
  105. qiskit/circuit/library/templates/clifford/clifford_6_1.py +9 -10
  106. qiskit/circuit/library/templates/clifford/clifford_6_2.py +9 -10
  107. qiskit/circuit/library/templates/clifford/clifford_6_3.py +9 -10
  108. qiskit/circuit/library/templates/clifford/clifford_6_4.py +8 -9
  109. qiskit/circuit/library/templates/clifford/clifford_6_5.py +9 -10
  110. qiskit/circuit/library/templates/clifford/clifford_8_1.py +9 -10
  111. qiskit/circuit/library/templates/clifford/clifford_8_2.py +9 -10
  112. qiskit/circuit/library/templates/clifford/clifford_8_3.py +9 -10
  113. qiskit/circuit/library/templates/nct/template_nct_2a_1.py +7 -9
  114. qiskit/circuit/library/templates/nct/template_nct_2a_2.py +8 -10
  115. qiskit/circuit/library/templates/nct/template_nct_2a_3.py +10 -12
  116. qiskit/circuit/library/templates/nct/template_nct_4a_1.py +14 -16
  117. qiskit/circuit/library/templates/nct/template_nct_4a_2.py +12 -14
  118. qiskit/circuit/library/templates/nct/template_nct_4a_3.py +10 -12
  119. qiskit/circuit/library/templates/nct/template_nct_4b_1.py +12 -14
  120. qiskit/circuit/library/templates/nct/template_nct_4b_2.py +10 -12
  121. qiskit/circuit/library/templates/nct/template_nct_5a_1.py +10 -12
  122. qiskit/circuit/library/templates/nct/template_nct_5a_2.py +10 -12
  123. qiskit/circuit/library/templates/nct/template_nct_5a_3.py +10 -12
  124. qiskit/circuit/library/templates/nct/template_nct_5a_4.py +9 -11
  125. qiskit/circuit/library/templates/nct/template_nct_6a_1.py +9 -11
  126. qiskit/circuit/library/templates/nct/template_nct_6a_2.py +10 -12
  127. qiskit/circuit/library/templates/nct/template_nct_6a_3.py +10 -12
  128. qiskit/circuit/library/templates/nct/template_nct_6a_4.py +10 -12
  129. qiskit/circuit/library/templates/nct/template_nct_6b_1.py +10 -12
  130. qiskit/circuit/library/templates/nct/template_nct_6b_2.py +10 -12
  131. qiskit/circuit/library/templates/nct/template_nct_6c_1.py +10 -12
  132. qiskit/circuit/library/templates/nct/template_nct_7a_1.py +11 -13
  133. qiskit/circuit/library/templates/nct/template_nct_7b_1.py +11 -13
  134. qiskit/circuit/library/templates/nct/template_nct_7c_1.py +11 -13
  135. qiskit/circuit/library/templates/nct/template_nct_7d_1.py +11 -13
  136. qiskit/circuit/library/templates/nct/template_nct_7e_1.py +11 -13
  137. qiskit/circuit/library/templates/nct/template_nct_9a_1.py +11 -13
  138. qiskit/circuit/library/templates/nct/template_nct_9c_1.py +9 -11
  139. qiskit/circuit/library/templates/nct/template_nct_9c_10.py +10 -12
  140. qiskit/circuit/library/templates/nct/template_nct_9c_11.py +10 -12
  141. qiskit/circuit/library/templates/nct/template_nct_9c_12.py +10 -12
  142. qiskit/circuit/library/templates/nct/template_nct_9c_2.py +10 -12
  143. qiskit/circuit/library/templates/nct/template_nct_9c_3.py +10 -12
  144. qiskit/circuit/library/templates/nct/template_nct_9c_4.py +10 -12
  145. qiskit/circuit/library/templates/nct/template_nct_9c_5.py +10 -12
  146. qiskit/circuit/library/templates/nct/template_nct_9c_6.py +10 -12
  147. qiskit/circuit/library/templates/nct/template_nct_9c_7.py +10 -12
  148. qiskit/circuit/library/templates/nct/template_nct_9c_8.py +10 -12
  149. qiskit/circuit/library/templates/nct/template_nct_9c_9.py +10 -12
  150. qiskit/circuit/library/templates/nct/template_nct_9d_1.py +9 -11
  151. qiskit/circuit/library/templates/nct/template_nct_9d_10.py +10 -12
  152. qiskit/circuit/library/templates/nct/template_nct_9d_2.py +10 -12
  153. qiskit/circuit/library/templates/nct/template_nct_9d_3.py +10 -12
  154. qiskit/circuit/library/templates/nct/template_nct_9d_4.py +10 -12
  155. qiskit/circuit/library/templates/nct/template_nct_9d_5.py +10 -12
  156. qiskit/circuit/library/templates/nct/template_nct_9d_6.py +10 -12
  157. qiskit/circuit/library/templates/nct/template_nct_9d_7.py +10 -12
  158. qiskit/circuit/library/templates/nct/template_nct_9d_8.py +10 -12
  159. qiskit/circuit/library/templates/nct/template_nct_9d_9.py +10 -12
  160. qiskit/circuit/library/templates/rzx/rzx_cy.py +10 -11
  161. qiskit/circuit/library/templates/rzx/rzx_xz.py +15 -16
  162. qiskit/circuit/library/templates/rzx/rzx_yz.py +10 -12
  163. qiskit/circuit/library/templates/rzx/rzx_zz1.py +20 -22
  164. qiskit/circuit/library/templates/rzx/rzx_zz2.py +15 -16
  165. qiskit/circuit/library/templates/rzx/rzx_zz3.py +15 -17
  166. qiskit/circuit/parameter.py +0 -4
  167. qiskit/circuit/parameterexpression.py +34 -167
  168. qiskit/circuit/quantumcircuit.py +126 -162
  169. qiskit/circuit/singleton.py +0 -2
  170. qiskit/circuit/store.py +0 -2
  171. qiskit/compiler/assembler.py +4 -17
  172. qiskit/compiler/scheduler.py +0 -2
  173. qiskit/compiler/sequencer.py +0 -2
  174. qiskit/compiler/transpiler.py +26 -81
  175. qiskit/converters/circuit_to_dag.py +2 -2
  176. qiskit/converters/circuit_to_dagdependency.py +1 -1
  177. qiskit/converters/circuit_to_dagdependency_v2.py +1 -1
  178. qiskit/converters/circuit_to_instruction.py +1 -1
  179. qiskit/converters/dag_to_circuit.py +5 -7
  180. qiskit/converters/dag_to_dagdependency.py +1 -1
  181. qiskit/converters/dag_to_dagdependency_v2.py +1 -1
  182. qiskit/converters/dagdependency_to_circuit.py +1 -5
  183. qiskit/converters/dagdependency_to_dag.py +1 -6
  184. qiskit/dagcircuit/collect_blocks.py +3 -3
  185. qiskit/dagcircuit/dagdependency.py +5 -18
  186. qiskit/dagcircuit/dagdependency_v2.py +1 -1
  187. qiskit/dagcircuit/dagnode.py +2 -2
  188. qiskit/passmanager/__init__.py +2 -2
  189. qiskit/primitives/backend_estimator.py +2 -5
  190. qiskit/primitives/backend_sampler_v2.py +18 -61
  191. qiskit/primitives/base/base_estimator.py +2 -2
  192. qiskit/primitives/containers/data_bin.py +1 -9
  193. qiskit/primitives/statevector_sampler.py +1 -1
  194. qiskit/primitives/utils.py +1 -1
  195. qiskit/providers/__init__.py +3 -3
  196. qiskit/providers/backend.py +1 -12
  197. qiskit/providers/backend_compat.py +3 -23
  198. qiskit/providers/basic_provider/basic_simulator.py +2 -12
  199. qiskit/providers/fake_provider/fake_pulse_backend.py +1 -6
  200. qiskit/providers/fake_provider/generic_backend_v2.py +30 -46
  201. qiskit/providers/models/pulsedefaults.py +0 -2
  202. qiskit/pulse/builder.py +18 -59
  203. qiskit/pulse/calibration_entries.py +1 -4
  204. qiskit/pulse/channels.py +0 -2
  205. qiskit/pulse/exceptions.py +0 -2
  206. qiskit/pulse/instruction_schedule_map.py +6 -21
  207. qiskit/pulse/instructions/acquire.py +0 -2
  208. qiskit/pulse/instructions/delay.py +0 -2
  209. qiskit/pulse/instructions/directives.py +0 -8
  210. qiskit/pulse/instructions/frequency.py +0 -3
  211. qiskit/pulse/instructions/instruction.py +0 -2
  212. qiskit/pulse/instructions/phase.py +0 -3
  213. qiskit/pulse/instructions/play.py +0 -2
  214. qiskit/pulse/instructions/reference.py +0 -2
  215. qiskit/pulse/instructions/snapshot.py +0 -2
  216. qiskit/pulse/library/pulse.py +0 -2
  217. qiskit/pulse/library/symbolic_pulses.py +0 -28
  218. qiskit/pulse/library/waveform.py +0 -2
  219. qiskit/pulse/macros.py +1 -1
  220. qiskit/pulse/schedule.py +13 -12
  221. qiskit/pulse/transforms/alignments.py +3 -5
  222. qiskit/pulse/transforms/dag.py +0 -7
  223. qiskit/qasm2/export.py +3 -5
  224. qiskit/qasm2/parse.py +2 -46
  225. qiskit/qasm3/__init__.py +0 -1
  226. qiskit/qasm3/ast.py +15 -123
  227. qiskit/qasm3/exporter.py +77 -103
  228. qiskit/qobj/converters/pulse_instruction.py +4 -6
  229. qiskit/qpy/__init__.py +0 -181
  230. qiskit/qpy/binary_io/circuits.py +5 -20
  231. qiskit/qpy/binary_io/schedules.py +4 -3
  232. qiskit/qpy/binary_io/value.py +13 -310
  233. qiskit/qpy/common.py +2 -46
  234. qiskit/qpy/formats.py +0 -7
  235. qiskit/qpy/interface.py +4 -40
  236. qiskit/quantum_info/__init__.py +0 -4
  237. qiskit/quantum_info/operators/channel/transformations.py +21 -28
  238. qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
  239. qiskit/quantum_info/operators/operator.py +8 -54
  240. qiskit/quantum_info/operators/symplectic/base_pauli.py +19 -11
  241. qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
  242. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +1 -1
  243. qiskit/quantum_info/operators/symplectic/pauli.py +0 -2
  244. qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
  245. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +2 -23
  246. qiskit/quantum_info/states/densitymatrix.py +5 -5
  247. qiskit/quantum_info/states/stabilizerstate.py +1 -1
  248. qiskit/quantum_info/states/statevector.py +6 -6
  249. qiskit/result/mitigation/base_readout_mitigator.py +1 -1
  250. qiskit/result/mitigation/correlated_readout_mitigator.py +1 -9
  251. qiskit/result/mitigation/local_readout_mitigator.py +1 -9
  252. qiskit/result/mitigation/utils.py +0 -57
  253. qiskit/scheduler/config.py +0 -2
  254. qiskit/scheduler/methods/basic.py +0 -3
  255. qiskit/scheduler/schedule_circuit.py +0 -2
  256. qiskit/scheduler/sequence.py +0 -2
  257. qiskit/synthesis/__init__.py +0 -25
  258. qiskit/synthesis/clifford/clifford_decompose_bm.py +2 -1
  259. qiskit/synthesis/clifford/clifford_decompose_greedy.py +2 -3
  260. qiskit/synthesis/clifford/clifford_decompose_layers.py +1 -2
  261. qiskit/synthesis/evolution/__init__.py +0 -1
  262. qiskit/synthesis/evolution/lie_trotter.py +42 -16
  263. qiskit/synthesis/evolution/product_formula.py +238 -165
  264. qiskit/synthesis/evolution/qdrift.py +29 -36
  265. qiskit/synthesis/evolution/suzuki_trotter.py +27 -87
  266. qiskit/synthesis/multi_controlled/__init__.py +0 -1
  267. qiskit/synthesis/qft/qft_decompose_full.py +1 -19
  268. qiskit/synthesis/qft/qft_decompose_lnn.py +1 -2
  269. qiskit/synthesis/stabilizer/stabilizer_decompose.py +1 -2
  270. qiskit/synthesis/two_qubit/two_qubit_decompose.py +63 -4
  271. qiskit/synthesis/two_qubit/weyl.py +97 -0
  272. qiskit/synthesis/unitary/qsd.py +5 -5
  273. qiskit/transpiler/__init__.py +14 -21
  274. qiskit/transpiler/basepasses.py +1 -1
  275. qiskit/transpiler/passes/__init__.py +0 -2
  276. qiskit/transpiler/passes/basis/basis_translator.py +565 -9
  277. qiskit/transpiler/passes/basis/decompose.py +12 -45
  278. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  279. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  280. qiskit/transpiler/passes/calibration/pulse_gate.py +2 -4
  281. qiskit/transpiler/passes/calibration/rx_builder.py +7 -11
  282. qiskit/transpiler/passes/calibration/rzx_builder.py +30 -46
  283. qiskit/transpiler/passes/layout/disjoint_utils.py +13 -15
  284. qiskit/transpiler/passes/layout/sabre_layout.py +2 -7
  285. qiskit/transpiler/passes/layout/sabre_pre_layout.py +0 -5
  286. qiskit/transpiler/passes/optimization/__init__.py +0 -1
  287. qiskit/transpiler/passes/optimization/collect_cliffords.py +3 -19
  288. qiskit/transpiler/passes/optimization/collect_linear_functions.py +1 -1
  289. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
  290. qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +1 -1
  291. qiskit/transpiler/passes/optimization/consolidate_blocks.py +131 -48
  292. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +2 -4
  293. qiskit/transpiler/passes/optimization/elide_permutations.py +32 -9
  294. qiskit/transpiler/passes/optimization/inverse_cancellation.py +0 -2
  295. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +11 -5
  296. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
  297. qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +1 -1
  298. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +5 -5
  299. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +4 -4
  300. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +2 -2
  301. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +1 -1
  302. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
  303. qiskit/transpiler/passes/routing/sabre_swap.py +3 -7
  304. qiskit/transpiler/passes/routing/star_prerouting.py +2 -2
  305. qiskit/transpiler/passes/scheduling/alap.py +1 -1
  306. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +2 -2
  307. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  308. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +0 -2
  309. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
  310. qiskit/transpiler/passes/scheduling/asap.py +1 -1
  311. qiskit/transpiler/passes/scheduling/base_scheduler.py +12 -14
  312. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +4 -9
  313. qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
  314. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +5 -16
  315. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +1 -4
  316. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +2 -6
  317. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +4 -9
  318. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +99 -262
  319. qiskit/transpiler/passes/synthesis/hls_plugins.py +7 -638
  320. qiskit/transpiler/passes/synthesis/qubit_tracker.py +132 -0
  321. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
  322. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +34 -55
  323. qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +56 -2
  324. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +0 -5
  325. qiskit/transpiler/passes/utils/gate_direction.py +275 -12
  326. qiskit/transpiler/passes/utils/gates_basis.py +30 -7
  327. qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +1 -2
  328. qiskit/transpiler/passmanager_config.py +4 -22
  329. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +14 -40
  330. qiskit/transpiler/preset_passmanagers/common.py +3 -5
  331. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +42 -125
  332. qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
  333. qiskit/transpiler/target.py +16 -74
  334. qiskit/visualization/circuit/_utils.py +2 -2
  335. qiskit/visualization/circuit/circuit_visualization.py +2 -3
  336. qiskit/visualization/circuit/matplotlib.py +1 -1
  337. qiskit/visualization/dag_visualization.py +1 -1
  338. qiskit/visualization/pass_manager_visualization.py +14 -3
  339. qiskit/visualization/pulse_v2/interface.py +1 -3
  340. qiskit/visualization/timeline/core.py +2 -25
  341. qiskit/visualization/timeline/interface.py +0 -12
  342. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/METADATA +19 -20
  343. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/RECORD +347 -358
  344. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/WHEEL +1 -1
  345. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/entry_points.txt +0 -19
  346. qiskit/circuit/library/data_preparation/_zz_feature_map.py +0 -150
  347. qiskit/circuit/twirling.py +0 -145
  348. qiskit/synthesis/arithmetic/__init__.py +0 -16
  349. qiskit/synthesis/arithmetic/adders/__init__.py +0 -17
  350. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +0 -154
  351. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +0 -103
  352. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +0 -161
  353. qiskit/synthesis/arithmetic/multipliers/__init__.py +0 -16
  354. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +0 -102
  355. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +0 -99
  356. qiskit/synthesis/evolution/pauli_network.py +0 -80
  357. qiskit/synthesis/multi_controlled/mcmt_vchain.py +0 -52
  358. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +0 -69
  359. qiskit/utils/deprecate_pulse.py +0 -119
  360. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/LICENSE.txt +0 -0
  361. {qiskit-1.3.0.dist-info → qiskit-1.3.0b1.dist-info}/top_level.txt +0 -0
@@ -54,7 +54,7 @@ class Unroll3qOrMore(TransformationPass):
54
54
  QiskitError: if a 3q+ gate is not decomposable
55
55
  """
56
56
  for node in dag.multi_qubit_ops():
57
- if dag._has_calibration_for(node):
57
+ if dag.has_calibration_for(node):
58
58
  continue
59
59
 
60
60
  if isinstance(node.op, ControlFlowOp):
@@ -74,7 +74,7 @@ class UnrollCustomDefinitions(TransformationPass):
74
74
  if getattr(node.op, "_directive", False):
75
75
  continue
76
76
 
77
- if dag._has_calibration_for(node) or len(node.qargs) < self._min_qubits:
77
+ if dag.has_calibration_for(node) or len(node.qargs) < self._min_qubits:
78
78
  continue
79
79
 
80
80
  controlled_gate_open_ctrl = isinstance(node.op, ControlledGate) and node.op._open_ctrl
@@ -19,7 +19,6 @@ from qiskit.pulse import Schedule, ScheduleBlock
19
19
  from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap
20
20
  from qiskit.transpiler.target import Target
21
21
  from qiskit.transpiler.exceptions import TranspilerError
22
- from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
23
22
 
24
23
  from .base_builder import CalibrationBuilder
25
24
 
@@ -48,7 +47,6 @@ class PulseGates(CalibrationBuilder):
48
47
  https://arxiv.org/abs/2104.14722
49
48
  """
50
49
 
51
- @deprecate_pulse_dependency
52
50
  def __init__(
53
51
  self,
54
52
  inst_map: InstructionScheduleMap = None,
@@ -82,7 +80,7 @@ class PulseGates(CalibrationBuilder):
82
80
  Returns:
83
81
  Return ``True`` is calibration can be provided.
84
82
  """
85
- return self.target._has_calibration(node_op.name, tuple(qubits))
83
+ return self.target.has_calibration(node_op.name, tuple(qubits))
86
84
 
87
85
  def get_calibration(self, node_op: CircuitInst, qubits: List) -> Union[Schedule, ScheduleBlock]:
88
86
  """Gets the calibrated schedule for the given instruction and qubits.
@@ -97,4 +95,4 @@ class PulseGates(CalibrationBuilder):
97
95
  Raises:
98
96
  TranspilerError: When node is parameterized and calibration is raw schedule object.
99
97
  """
100
- return self.target._get_calibration(node_op.name, tuple(qubits), *node_op.params)
98
+ return self.target.get_calibration(node_op.name, tuple(qubits), *node_op.params)
@@ -24,7 +24,6 @@ from qiskit.pulse.channels import Channel
24
24
  from qiskit.pulse.library.symbolic_pulses import Drag
25
25
  from qiskit.transpiler.passes.calibration.base_builder import CalibrationBuilder
26
26
  from qiskit.transpiler.target import Target
27
- from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
28
27
 
29
28
 
30
29
  class RXCalibrationBuilder(CalibrationBuilder):
@@ -46,7 +45,7 @@ class RXCalibrationBuilder(CalibrationBuilder):
46
45
  from qiskit.circuit.library import QuantumVolume
47
46
  from qiskit.circuit.library.standard_gates import RXGate
48
47
 
49
- from qiskit.transpiler.passes import RXCalibrationBuilder
48
+ from calibration.rx_builder import RXCalibrationBuilder
50
49
 
51
50
  qv = QuantumVolume(4, 4, seed=1004)
52
51
 
@@ -76,7 +75,6 @@ class RXCalibrationBuilder(CalibrationBuilder):
76
75
  `arXiv:2004.11205 <https://arxiv.org/abs/2004.11205>`
77
76
  """
78
77
 
79
- @deprecate_pulse_dependency
80
78
  def __init__(
81
79
  self,
82
80
  target: Target = None,
@@ -101,15 +99,13 @@ class RXCalibrationBuilder(CalibrationBuilder):
101
99
  """
102
100
  return (
103
101
  isinstance(node_op, RXGate)
104
- and self.target._has_calibration("sx", tuple(qubits))
105
- and (len(self.target._get_calibration("sx", tuple(qubits)).instructions) == 1)
102
+ and self.target.has_calibration("sx", tuple(qubits))
103
+ and (len(self.target.get_calibration("sx", tuple(qubits)).instructions) == 1)
106
104
  and isinstance(
107
- self.target._get_calibration("sx", tuple(qubits)).instructions[0][1].pulse,
105
+ self.target.get_calibration("sx", tuple(qubits)).instructions[0][1].pulse,
108
106
  ScalableSymbolicPulse,
109
107
  )
110
- and self.target._get_calibration("sx", tuple(qubits))
111
- .instructions[0][1]
112
- .pulse.pulse_type
108
+ and self.target.get_calibration("sx", tuple(qubits)).instructions[0][1].pulse.pulse_type
113
109
  == "Drag"
114
110
  )
115
111
 
@@ -126,13 +122,13 @@ class RXCalibrationBuilder(CalibrationBuilder):
126
122
  raise QiskitError("Target rotation angle is not assigned.") from ex
127
123
 
128
124
  params = (
129
- self.target._get_calibration("sx", tuple(qubits))
125
+ self.target.get_calibration("sx", tuple(qubits))
130
126
  .instructions[0][1]
131
127
  .pulse.parameters.copy()
132
128
  )
133
129
  new_rx_sched = _create_rx_sched(
134
130
  rx_angle=angle,
135
- channel=self.target._get_calibration("sx", tuple(qubits)).channels[0],
131
+ channel=self.target.get_calibration("sx", tuple(qubits)).channels[0],
136
132
  duration=params["duration"],
137
133
  amp=params["amp"],
138
134
  sigma=params["sigma"],
@@ -36,7 +36,6 @@ from qiskit.pulse import builder
36
36
  from qiskit.pulse.filters import filter_instructions
37
37
  from qiskit.pulse.instruction_schedule_map import InstructionScheduleMap
38
38
  from qiskit.transpiler.target import Target
39
- from qiskit.utils.deprecate_pulse import deprecate_pulse_dependency
40
39
 
41
40
  from .base_builder import CalibrationBuilder
42
41
  from .exceptions import CalibrationNotAvailable
@@ -66,7 +65,6 @@ class RZXCalibrationBuilder(CalibrationBuilder):
66
65
  angle. Additional details can be found in https://arxiv.org/abs/2012.11660.
67
66
  """
68
67
 
69
- @deprecate_pulse_dependency
70
68
  def __init__(
71
69
  self,
72
70
  instruction_schedule_map: InstructionScheduleMap = None,
@@ -91,7 +89,7 @@ class RZXCalibrationBuilder(CalibrationBuilder):
91
89
  self._inst_map = instruction_schedule_map
92
90
  self._verbose = verbose
93
91
  if target:
94
- self._inst_map = target._instruction_schedule_map()
92
+ self._inst_map = target.instruction_schedule_map()
95
93
  if self._inst_map is None:
96
94
  raise QiskitError("Calibrations can only be added to Pulse-enabled backends")
97
95
 
@@ -204,20 +202,15 @@ class RZXCalibrationBuilder(CalibrationBuilder):
204
202
 
205
203
  # The CR instruction is in the forward (native) direction
206
204
  if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
207
- with warnings.catch_warnings():
208
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
209
- # `InstructionScheduleMap.get` and the pulse builder emit deprecation warnings
210
- # as they use classes and methods which are deprecated in Qiskit 1.3 as part of the
211
- # Qiskit Pulse deprecation
212
- xgate = self._inst_map.get("x", qubits[0])
213
- with builder.build(
214
- default_alignment="sequential", name=f"rzx({theta:.3f})"
215
- ) as rzx_theta_native:
216
- for cr_tone, comp_tone in zip(cr_tones, comp_tones):
217
- with builder.align_left():
218
- self.rescale_cr_inst(cr_tone, theta)
219
- self.rescale_cr_inst(comp_tone, theta)
220
- builder.call(xgate)
205
+ xgate = self._inst_map.get("x", qubits[0])
206
+ with builder.build(
207
+ default_alignment="sequential", name=f"rzx({theta:.3f})"
208
+ ) as rzx_theta_native:
209
+ for cr_tone, comp_tone in zip(cr_tones, comp_tones):
210
+ with builder.align_left():
211
+ self.rescale_cr_inst(cr_tone, theta)
212
+ self.rescale_cr_inst(comp_tone, theta)
213
+ builder.call(xgate)
221
214
  return rzx_theta_native
222
215
 
223
216
  # The direction is not native. Add Hadamard gates to flip the direction.
@@ -304,15 +297,11 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder):
304
297
 
305
298
  # RZXCalibrationNoEcho only good for forward CR direction
306
299
  if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
307
- with warnings.catch_warnings():
308
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
309
- # Pulse builder emits deprecation warnings as part of the
310
- # Qiskit Pulse deprecation
311
- with builder.build(default_alignment="left", name=f"rzx({theta:.3f})") as rzx_theta:
312
- stretched_dur = self.rescale_cr_inst(cr_tones[0], 2 * theta)
313
- self.rescale_cr_inst(comp_tones[0], 2 * theta)
314
- # Placeholder to make pulse gate work
315
- builder.delay(stretched_dur, DriveChannel(qubits[0]))
300
+ with builder.build(default_alignment="left", name=f"rzx({theta:.3f})") as rzx_theta:
301
+ stretched_dur = self.rescale_cr_inst(cr_tones[0], 2 * theta)
302
+ self.rescale_cr_inst(comp_tones[0], 2 * theta)
303
+ # Placeholder to make pulse gate work
304
+ builder.delay(stretched_dur, DriveChannel(qubits[0]))
316
305
  return rzx_theta
317
306
 
318
307
  raise QiskitError("RZXCalibrationBuilderNoEcho only supports hardware-native RZX gates.")
@@ -358,27 +347,22 @@ def _check_calibration_type(
358
347
  QiskitError: Unknown calibration type is detected.
359
348
  """
360
349
  cal_type = None
361
- with warnings.catch_warnings():
362
- warnings.simplefilter(action="ignore", category=DeprecationWarning)
363
- # `InstructionScheduleMap.get` and `filter_instructions` emit deprecation warnings
364
- # as they use classes and methods which are deprecated in Qiskit 1.3 as part of the
365
- # Qiskit Pulse deprecation
366
- if inst_sched_map.has("cx", qubits):
367
- cr_sched = inst_sched_map.get("cx", qubits=qubits)
368
- elif inst_sched_map.has("ecr", qubits):
369
- cr_sched = inst_sched_map.get("ecr", qubits=qubits)
370
- cal_type = CRCalType.ECR_FORWARD
371
- elif inst_sched_map.has("ecr", tuple(reversed(qubits))):
372
- cr_sched = inst_sched_map.get("ecr", tuple(reversed(qubits)))
373
- cal_type = CRCalType.ECR_REVERSE
374
- else:
375
- raise QiskitError(
376
- f"Native direction cannot be determined: operation on qubits {qubits} "
377
- f"for the following instruction schedule map:\n{inst_sched_map}"
378
- )
350
+ if inst_sched_map.has("cx", qubits):
351
+ cr_sched = inst_sched_map.get("cx", qubits=qubits)
352
+ elif inst_sched_map.has("ecr", qubits):
353
+ cr_sched = inst_sched_map.get("ecr", qubits=qubits)
354
+ cal_type = CRCalType.ECR_FORWARD
355
+ elif inst_sched_map.has("ecr", tuple(reversed(qubits))):
356
+ cr_sched = inst_sched_map.get("ecr", tuple(reversed(qubits)))
357
+ cal_type = CRCalType.ECR_REVERSE
358
+ else:
359
+ raise QiskitError(
360
+ f"Native direction cannot be determined: operation on qubits {qubits} "
361
+ f"for the following instruction schedule map:\n{inst_sched_map}"
362
+ )
379
363
 
380
- cr_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_cr_tone]).instructions]
381
- comp_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_comp_tone]).instructions]
364
+ cr_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_cr_tone]).instructions]
365
+ comp_tones = [t[1] for t in filter_instructions(cr_sched, [_filter_comp_tone]).instructions]
382
366
 
383
367
  if cal_type is None:
384
368
  if len(comp_tones) == 0:
@@ -107,7 +107,7 @@ def split_barriers(dag: DAGCircuit):
107
107
  num_qubits = len(node.qargs)
108
108
  if num_qubits == 1:
109
109
  continue
110
- if node.label:
110
+ if node.op.label:
111
111
  barrier_uuid = f"{node.op.label}_uuid={uuid.uuid4()}"
112
112
  else:
113
113
  barrier_uuid = f"_none_uuid={uuid.uuid4()}"
@@ -125,30 +125,28 @@ def split_barriers(dag: DAGCircuit):
125
125
  def combine_barriers(dag: DAGCircuit, retain_uuid: bool = True):
126
126
  """Mutate input dag to combine barriers with UUID labels into a single barrier."""
127
127
  qubit_indices = {bit: index for index, bit in enumerate(dag.qubits)}
128
- uuid_map: dict[str, DAGOpNode] = {}
128
+ uuid_map: dict[uuid.UUID, DAGOpNode] = {}
129
129
  for node in dag.op_nodes(Barrier):
130
- if node.label:
131
- if "_uuid=" in node.label:
132
- barrier_uuid = node.label
130
+ if node.op.label:
131
+ if "_uuid=" in node.op.label:
132
+ barrier_uuid = node.op.label
133
133
  else:
134
134
  continue
135
135
  if barrier_uuid in uuid_map:
136
136
  other_node = uuid_map[barrier_uuid]
137
137
  num_qubits = len(other_node.qargs) + len(node.qargs)
138
- if not retain_uuid:
139
- if isinstance(node.label, str) and node.label.startswith("_none_uuid="):
140
- label = None
141
- elif isinstance(node.label, str) and "_uuid=" in node.label:
142
- label = "_uuid=".join(node.label.split("_uuid=")[:-1])
143
- else:
144
- label = barrier_uuid
145
- else:
146
- label = barrier_uuid
147
- new_op = Barrier(num_qubits, label=label)
138
+ new_op = Barrier(num_qubits, label=barrier_uuid)
148
139
  new_node = dag.replace_block_with_op([node, other_node], new_op, qubit_indices)
149
140
  uuid_map[barrier_uuid] = new_node
150
141
  else:
151
142
  uuid_map[barrier_uuid] = node
143
+ if not retain_uuid:
144
+ for node in dag.op_nodes(Barrier):
145
+ if isinstance(node.op.label, str) and node.op.label.startswith("_none_uuid="):
146
+ node.op.label = None
147
+ elif isinstance(node.op.label, str) and "_uuid=" in node.op.label:
148
+ original_label = "_uuid=".join(node.op.label.split("_uuid=")[:-1])
149
+ node.op.label = original_label
152
150
 
153
151
 
154
152
  def require_layout_isolated_to_component(
@@ -101,10 +101,7 @@ class SabreLayout(TransformationPass):
101
101
 
102
102
  **References:**
103
103
 
104
- [1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
105
- "LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
106
- `arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
107
- [2] Li, Gushu, Yufei Ding, and Yuan Xie. "Tackling the qubit mapping problem
104
+ [1] Li, Gushu, Yufei Ding, and Yuan Xie. "Tackling the qubit mapping problem
108
105
  for NISQ-era quantum devices." ASPLOS 2019.
109
106
  `arXiv:1809.02573 <https://arxiv.org/pdf/1809.02573.pdf>`_
110
107
  """
@@ -148,9 +145,7 @@ class SabreLayout(TransformationPass):
148
145
  (and ``routing_pass`` is not set) then the number of local
149
146
  physical CPUs will be used as the default value. This option is
150
147
  mutually exclusive with the ``routing_pass`` argument and an error
151
- will be raised if both are used. An additional 3 or 4 trials
152
- depending on the ``coupling_map`` value are run with common layouts
153
- on top of the random trial count specified by this value.
148
+ will be raised if both are used.
154
149
  skip_routing (bool): If this is set ``True`` and ``routing_pass`` is not used
155
150
  then routing will not be applied to the output circuit. Only the layout
156
151
  will be set in the property set. This is a tradeoff to run custom
@@ -31,11 +31,6 @@ class SabrePreLayout(AnalysisPass):
31
31
  ``sabre_starting_layouts`` (``list[Layout]``)
32
32
  An optional list of :class:`~.Layout` objects to use for additional Sabre layout trials.
33
33
 
34
- **References:**
35
-
36
- [1] Henry Zou and Matthew Treinish and Kevin Hartman and Alexander Ivrii and Jake Lishman.
37
- "LightSABRE: A Lightweight and Enhanced SABRE Algorithm"
38
- `arXiv:2409.08368 <https://doi.org/10.48550/arXiv.2409.08368>`__
39
34
  """
40
35
 
41
36
  def __init__(
@@ -38,6 +38,5 @@ from .collect_cliffords import CollectCliffords
38
38
  from .elide_permutations import ElidePermutations
39
39
  from .normalize_rx_angle import NormalizeRXAngle
40
40
  from .optimize_annotated import OptimizeAnnotated
41
- from .remove_identity_equiv import RemoveIdentityEquivalent
42
41
  from .split_2q_unitaries import Split2QUnitaries
43
42
  from .collect_and_collapse import CollectAndCollapse
@@ -15,7 +15,6 @@
15
15
 
16
16
  from functools import partial
17
17
 
18
- from qiskit.exceptions import QiskitError
19
18
  from qiskit.transpiler.passes.optimization.collect_and_collapse import (
20
19
  CollectAndCollapse,
21
20
  collect_using_filter_function,
@@ -38,7 +37,6 @@ class CollectCliffords(CollectAndCollapse):
38
37
  min_block_size=2,
39
38
  split_layers=False,
40
39
  collect_from_back=False,
41
- matrix_based=False,
42
40
  ):
43
41
  """CollectCliffords initializer.
44
42
 
@@ -53,13 +51,11 @@ class CollectCliffords(CollectAndCollapse):
53
51
  over disjoint qubit subsets.
54
52
  collect_from_back (bool): specifies if blocks should be collected started
55
53
  from the end of the circuit.
56
- matrix_based (bool): specifies whether to collect unitary gates
57
- which are Clifford gates only for certain parameters (based on their unitary matrix).
58
54
  """
59
55
 
60
56
  collect_function = partial(
61
57
  collect_using_filter_function,
62
- filter_function=partial(_is_clifford_gate, matrix_based=matrix_based),
58
+ filter_function=_is_clifford_gate,
63
59
  split_blocks=split_blocks,
64
60
  min_block_size=min_block_size,
65
61
  split_layers=split_layers,
@@ -81,21 +77,9 @@ clifford_gate_names = (
81
77
  )
82
78
 
83
79
 
84
- def _is_clifford_gate(node, matrix_based=False):
80
+ def _is_clifford_gate(node):
85
81
  """Specifies whether a node holds a clifford gate."""
86
- if getattr(node.op, "_condition", None) is not None:
87
- return False
88
- if node.op.name in clifford_gate_names:
89
- return True
90
-
91
- if not matrix_based:
92
- return False
93
-
94
- try:
95
- Clifford(node.op)
96
- return True
97
- except QiskitError:
98
- return False
82
+ return node.op.name in clifford_gate_names and getattr(node.op, "condition", None) is None
99
83
 
100
84
 
101
85
  def _collapse_to_clifford(circuit):
@@ -71,7 +71,7 @@ class CollectLinearFunctions(CollectAndCollapse):
71
71
 
72
72
  def _is_linear_gate(node):
73
73
  """Specifies whether a node holds a linear gate."""
74
- return node.op.name in ("cx", "swap") and getattr(node, "condition", None) is None
74
+ return node.op.name in ("cx", "swap") and getattr(node.op, "condition", None) is None
75
75
 
76
76
 
77
77
  def _collapse_to_linear_function(circuit):
@@ -120,7 +120,7 @@ class CollectMultiQBlocks(AnalysisPass):
120
120
  if not isinstance(x, DAGOpNode):
121
121
  return "d"
122
122
  if isinstance(x.op, Gate):
123
- if x.op.is_parameterized() or getattr(x.op, "_condition", None) is not None:
123
+ if x.op.is_parameterized() or getattr(x.op, "condition", None) is not None:
124
124
  return "c"
125
125
  return "b" + chr(ord("a") + len(x.qargs))
126
126
  return "d"
@@ -133,7 +133,7 @@ class CollectMultiQBlocks(AnalysisPass):
133
133
 
134
134
  # check if the node is a gate and if it is parameterized
135
135
  if (
136
- getattr(nd.op, "_condition", None) is not None
136
+ getattr(nd.op, "condition", None) is not None
137
137
  or nd.op.is_parameterized()
138
138
  or not isinstance(nd.op, Gate)
139
139
  ):
@@ -49,7 +49,7 @@ class CommutativeInverseCancellation(TransformationPass):
49
49
  # checking can be extended to cover additional cases.
50
50
  if getattr(node.op, "_directive", False) or node.name in {"measure", "reset", "delay"}:
51
51
  return True
52
- if getattr(node, "condition", None):
52
+ if getattr(node.op, "condition", None):
53
53
  return True
54
54
  if node.op.is_parameterized():
55
55
  return True
@@ -12,26 +12,27 @@
12
12
 
13
13
  """Replace each block of consecutive gates by a single Unitary node."""
14
14
  from __future__ import annotations
15
- from math import pi
16
15
 
17
- from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
18
- from qiskit.circuit.library.standard_gates import CXGate, CZGate, iSwapGate, ECRGate, RXXGate
16
+ import numpy as np
19
17
 
18
+ from qiskit.circuit.classicalregister import ClassicalRegister
19
+ from qiskit.circuit.quantumregister import QuantumRegister
20
+ from qiskit.circuit.quantumcircuit import QuantumCircuit
21
+ from qiskit.dagcircuit.dagnode import DAGOpNode
22
+ from qiskit.quantum_info import Operator
23
+ from qiskit.synthesis.two_qubit import TwoQubitBasisDecomposer
24
+ from qiskit.circuit.library.generalized_gates.unitary import UnitaryGate
25
+ from qiskit.circuit.library.standard_gates import CXGate
20
26
  from qiskit.transpiler.basepasses import TransformationPass
21
27
  from qiskit.transpiler.passmanager import PassManager
22
- from qiskit._accelerate.consolidate_blocks import consolidate_blocks
28
+ from qiskit.transpiler.passes.synthesis import unitary_synthesis
29
+ from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES
30
+ from qiskit._accelerate.convert_2q_block_matrix import blocks_to_matrix
31
+ from qiskit.exceptions import QiskitError
23
32
 
24
33
  from .collect_1q_runs import Collect1qRuns
25
34
  from .collect_2q_blocks import Collect2qBlocks
26
35
 
27
- KAK_GATE_NAMES = {
28
- "cx": CXGate(),
29
- "cz": CZGate(),
30
- "iswap": iSwapGate(),
31
- "ecr": ECRGate(),
32
- "rxx": RXXGate(pi / 2),
33
- }
34
-
35
36
 
36
37
  class ConsolidateBlocks(TransformationPass):
37
38
  """Replace each block of consecutive gates by a single Unitary node.
@@ -73,20 +74,13 @@ class ConsolidateBlocks(TransformationPass):
73
74
  if basis_gates is not None:
74
75
  self.basis_gates = set(basis_gates)
75
76
  self.force_consolidate = force_consolidate
77
+
76
78
  if kak_basis_gate is not None:
77
79
  self.decomposer = TwoQubitBasisDecomposer(kak_basis_gate)
78
80
  elif basis_gates is not None:
79
- kak_gates = KAK_GATE_NAMES.keys() & (basis_gates or [])
80
- if kak_gates:
81
- self.decomposer = TwoQubitBasisDecomposer(
82
- KAK_GATE_NAMES[kak_gates.pop()], basis_fidelity=approximation_degree or 1.0
83
- )
84
- elif "rzx" in basis_gates:
85
- self.decomposer = TwoQubitBasisDecomposer(
86
- CXGate(), basis_fidelity=approximation_degree or 1.0
87
- )
88
- else:
89
- self.decomposer = None
81
+ self.decomposer = unitary_synthesis._decomposer_2q_from_basis_gates(
82
+ basis_gates, approximation_degree=approximation_degree
83
+ )
90
84
  else:
91
85
  self.decomposer = TwoQubitBasisDecomposer(CXGate())
92
86
 
@@ -99,23 +93,89 @@ class ConsolidateBlocks(TransformationPass):
99
93
  if self.decomposer is None:
100
94
  return dag
101
95
 
102
- blocks = self.property_set["block_list"]
103
- if blocks is not None:
104
- blocks = [[node._node_id for node in block] for block in blocks]
105
- runs = self.property_set["run_list"]
106
- if runs is not None:
107
- runs = [[node._node_id for node in run] for run in runs]
108
-
109
- consolidate_blocks(
110
- dag,
111
- self.decomposer._inner_decomposer,
112
- self.decomposer.gate.name,
113
- self.force_consolidate,
114
- target=self.target,
115
- basis_gates=self.basis_gates,
116
- blocks=blocks,
117
- runs=runs,
118
- )
96
+ blocks = self.property_set["block_list"] or []
97
+ basis_gate_name = self.decomposer.gate.name
98
+ all_block_gates = set()
99
+ for block in blocks:
100
+ if len(block) == 1 and self._check_not_in_basis(dag, block[0].name, block[0].qargs):
101
+ all_block_gates.add(block[0])
102
+ dag.substitute_node(block[0], UnitaryGate(block[0].op.to_matrix()))
103
+ else:
104
+ basis_count = 0
105
+ outside_basis = False
106
+ block_qargs = set()
107
+ block_cargs = set()
108
+ for nd in block:
109
+ block_qargs |= set(nd.qargs)
110
+ if isinstance(nd, DAGOpNode) and getattr(nd, "condition", None):
111
+ block_cargs |= set(getattr(nd, "condition", None)[0])
112
+ all_block_gates.add(nd)
113
+ block_index_map = self._block_qargs_to_indices(dag, block_qargs)
114
+ for nd in block:
115
+ if nd.name == basis_gate_name:
116
+ basis_count += 1
117
+ if self._check_not_in_basis(dag, nd.name, nd.qargs):
118
+ outside_basis = True
119
+ if len(block_qargs) > 2:
120
+ q = QuantumRegister(len(block_qargs))
121
+ qc = QuantumCircuit(q)
122
+ if block_cargs:
123
+ c = ClassicalRegister(len(block_cargs))
124
+ qc.add_register(c)
125
+ for nd in block:
126
+ qc.append(nd.op, [q[block_index_map[i]] for i in nd.qargs])
127
+ unitary = UnitaryGate(Operator(qc), check_input=False)
128
+ else:
129
+ try:
130
+ matrix = blocks_to_matrix(block, block_index_map)
131
+ except QiskitError:
132
+ # If building a matrix for the block fails we should not consolidate it
133
+ # because there is nothing we can do with it.
134
+ continue
135
+ unitary = UnitaryGate(matrix, check_input=False)
136
+
137
+ max_2q_depth = 20 # If depth > 20, there will be 1q gates to consolidate.
138
+ if ( # pylint: disable=too-many-boolean-expressions
139
+ self.force_consolidate
140
+ or unitary.num_qubits > 2
141
+ or self.decomposer.num_basis_gates(matrix) < basis_count
142
+ or len(block) > max_2q_depth
143
+ or ((self.basis_gates is not None) and outside_basis)
144
+ or ((self.target is not None) and outside_basis)
145
+ ):
146
+ identity = np.eye(2**unitary.num_qubits)
147
+ if np.allclose(identity, unitary.to_matrix()):
148
+ for node in block:
149
+ dag.remove_op_node(node)
150
+ else:
151
+ dag.replace_block_with_op(
152
+ block, unitary, block_index_map, cycle_check=False
153
+ )
154
+ # If 1q runs are collected before consolidate those too
155
+ runs = self.property_set["run_list"] or []
156
+ identity_1q = np.eye(2)
157
+ for run in runs:
158
+ if any(gate in all_block_gates for gate in run):
159
+ continue
160
+ if len(run) == 1 and not self._check_not_in_basis(dag, run[0].name, run[0].qargs):
161
+ dag.substitute_node(run[0], UnitaryGate(run[0].op.to_matrix(), check_input=False))
162
+ else:
163
+ qubit = run[0].qargs[0]
164
+ operator = run[0].op.to_matrix()
165
+ already_in_block = False
166
+ for gate in run[1:]:
167
+ if gate in all_block_gates:
168
+ already_in_block = True
169
+ operator = gate.op.to_matrix().dot(operator)
170
+ if already_in_block:
171
+ continue
172
+ unitary = UnitaryGate(operator, check_input=False)
173
+ if np.allclose(identity_1q, unitary.to_matrix()):
174
+ for node in run:
175
+ dag.remove_op_node(node)
176
+ else:
177
+ dag.replace_block_with_op(run, unitary, {qubit: 0}, cycle_check=False)
178
+
119
179
  dag = self._handle_control_flow_ops(dag)
120
180
 
121
181
  # Clear collected blocks and runs as they are no longer valid after consolidation
@@ -135,15 +195,38 @@ class ConsolidateBlocks(TransformationPass):
135
195
  pass_manager = PassManager()
136
196
  if "run_list" in self.property_set:
137
197
  pass_manager.append(Collect1qRuns())
198
+ if "block_list" in self.property_set:
138
199
  pass_manager.append(Collect2qBlocks())
139
200
 
140
201
  pass_manager.append(self)
141
- control_flow_nodes = dag.control_flow_op_nodes()
142
- if control_flow_nodes is not None:
143
- for node in control_flow_nodes:
144
- dag.substitute_node(
145
- node,
146
- node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks),
147
- propagate_condition=False,
148
- )
202
+ for node in dag.op_nodes():
203
+ if node.name not in CONTROL_FLOW_OP_NAMES:
204
+ continue
205
+ dag.substitute_node(
206
+ node,
207
+ node.op.replace_blocks(pass_manager.run(block) for block in node.op.blocks),
208
+ propagate_condition=False,
209
+ )
149
210
  return dag
211
+
212
+ def _check_not_in_basis(self, dag, gate_name, qargs):
213
+ if self.target is not None:
214
+ return not self.target.instruction_supported(
215
+ gate_name, tuple(dag.find_bit(qubit).index for qubit in qargs)
216
+ )
217
+ else:
218
+ return self.basis_gates and gate_name not in self.basis_gates
219
+
220
+ def _block_qargs_to_indices(self, dag, block_qargs):
221
+ """Map each qubit in block_qargs to its wire position among the block's wires.
222
+ Args:
223
+ block_qargs (list): list of qubits that a block acts on
224
+ global_index_map (dict): mapping from each qubit in the
225
+ circuit to its wire position within that circuit
226
+ Returns:
227
+ dict: mapping from qarg to position in block
228
+ """
229
+ block_indices = [dag.find_bit(q).index for q in block_qargs]
230
+ ordered_block_indices = {bit: index for index, bit in enumerate(sorted(block_indices))}
231
+ block_positions = {q: ordered_block_indices[dag.find_bit(q).index] for q in block_qargs}
232
+ return block_positions