qiskit 1.3.0b1__cp39-abi3-win32.whl → 1.3.0rc2__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 (360) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +20 -1
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/assembler/assemble_schedules.py +2 -0
  5. qiskit/circuit/__init__.py +44 -1
  6. qiskit/circuit/_standard_gates_commutations.py +585 -0
  7. qiskit/circuit/barrier.py +2 -0
  8. qiskit/circuit/controlflow/builder.py +3 -3
  9. qiskit/circuit/controlflow/if_else.py +13 -5
  10. qiskit/circuit/controlflow/while_loop.py +10 -2
  11. qiskit/circuit/delay.py +20 -3
  12. qiskit/circuit/equivalence.py +13 -214
  13. qiskit/circuit/gate.py +3 -1
  14. qiskit/circuit/instruction.py +32 -11
  15. qiskit/circuit/instructionset.py +2 -0
  16. qiskit/circuit/library/__init__.py +110 -14
  17. qiskit/circuit/library/arithmetic/__init__.py +9 -2
  18. qiskit/circuit/library/arithmetic/adders/__init__.py +1 -0
  19. qiskit/circuit/library/arithmetic/adders/adder.py +154 -2
  20. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +20 -56
  21. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +14 -1
  22. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +21 -91
  23. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +1 -1
  24. qiskit/circuit/library/arithmetic/multipliers/__init__.py +1 -0
  25. qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +8 -1
  26. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +94 -3
  27. qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +8 -1
  28. qiskit/circuit/library/arithmetic/weighted_adder.py +1 -1
  29. qiskit/circuit/library/basis_change/qft.py +20 -38
  30. qiskit/circuit/library/blueprintcircuit.py +64 -0
  31. qiskit/circuit/library/boolean_logic/__init__.py +4 -4
  32. qiskit/circuit/library/boolean_logic/inner_product.py +81 -4
  33. qiskit/circuit/library/boolean_logic/quantum_and.py +107 -4
  34. qiskit/circuit/library/boolean_logic/quantum_or.py +107 -3
  35. qiskit/circuit/library/boolean_logic/quantum_xor.py +97 -3
  36. qiskit/circuit/library/data_preparation/__init__.py +6 -3
  37. qiskit/circuit/library/data_preparation/{z_feature_map.py → _z_feature_map.py} +45 -34
  38. qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
  39. qiskit/circuit/library/data_preparation/pauli_feature_map.py +342 -29
  40. qiskit/circuit/library/fourier_checking.py +72 -11
  41. qiskit/circuit/library/generalized_gates/__init__.py +1 -1
  42. qiskit/circuit/library/generalized_gates/diagonal.py +45 -51
  43. qiskit/circuit/library/generalized_gates/gms.py +67 -14
  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 +12 -6
  47. qiskit/circuit/library/generalized_gates/mcmt.py +167 -107
  48. qiskit/circuit/library/generalized_gates/permutation.py +8 -6
  49. qiskit/circuit/library/generalized_gates/rv.py +8 -9
  50. qiskit/circuit/library/graph_state.py +93 -10
  51. qiskit/circuit/library/grover_operator.py +270 -2
  52. qiskit/circuit/library/hidden_linear_function.py +83 -20
  53. qiskit/circuit/library/iqp.py +99 -20
  54. qiskit/circuit/library/n_local/__init__.py +19 -7
  55. qiskit/circuit/library/n_local/efficient_su2.py +118 -5
  56. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +259 -0
  57. qiskit/circuit/library/n_local/excitation_preserving.py +130 -6
  58. qiskit/circuit/library/n_local/n_local.py +406 -5
  59. qiskit/circuit/library/n_local/pauli_two_design.py +106 -4
  60. qiskit/circuit/library/n_local/qaoa_ansatz.py +80 -1
  61. qiskit/circuit/library/n_local/real_amplitudes.py +127 -7
  62. qiskit/circuit/library/n_local/two_local.py +14 -7
  63. qiskit/circuit/library/overlap.py +91 -26
  64. qiskit/circuit/library/pauli_evolution.py +17 -15
  65. qiskit/circuit/library/phase_estimation.py +80 -4
  66. qiskit/circuit/library/quantum_volume.py +72 -20
  67. qiskit/circuit/library/standard_gates/__init__.py +20 -1
  68. qiskit/circuit/library/standard_gates/dcx.py +2 -1
  69. qiskit/circuit/library/standard_gates/ecr.py +2 -2
  70. qiskit/circuit/library/standard_gates/h.py +4 -3
  71. qiskit/circuit/library/standard_gates/i.py +2 -1
  72. qiskit/circuit/library/standard_gates/iswap.py +2 -2
  73. qiskit/circuit/library/standard_gates/p.py +20 -12
  74. qiskit/circuit/library/standard_gates/r.py +1 -1
  75. qiskit/circuit/library/standard_gates/rx.py +4 -3
  76. qiskit/circuit/library/standard_gates/rxx.py +2 -2
  77. qiskit/circuit/library/standard_gates/ry.py +4 -3
  78. qiskit/circuit/library/standard_gates/ryy.py +2 -2
  79. qiskit/circuit/library/standard_gates/rz.py +13 -12
  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 +4 -3
  85. qiskit/circuit/library/standard_gates/t.py +2 -2
  86. qiskit/circuit/library/standard_gates/u.py +11 -3
  87. qiskit/circuit/library/standard_gates/u1.py +65 -15
  88. qiskit/circuit/library/standard_gates/u2.py +4 -1
  89. qiskit/circuit/library/standard_gates/u3.py +31 -3
  90. qiskit/circuit/library/standard_gates/x.py +7 -5
  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 +4 -3
  94. qiskit/circuit/library/standard_gates/z.py +3 -3
  95. qiskit/circuit/library/templates/clifford/clifford_2_1.py +9 -8
  96. qiskit/circuit/library/templates/clifford/clifford_2_2.py +10 -9
  97. qiskit/circuit/library/templates/clifford/clifford_2_3.py +9 -7
  98. qiskit/circuit/library/templates/clifford/clifford_2_4.py +9 -8
  99. qiskit/circuit/library/templates/clifford/clifford_3_1.py +9 -8
  100. qiskit/circuit/library/templates/clifford/clifford_4_1.py +10 -9
  101. qiskit/circuit/library/templates/clifford/clifford_4_2.py +10 -9
  102. qiskit/circuit/library/templates/clifford/clifford_4_3.py +10 -9
  103. qiskit/circuit/library/templates/clifford/clifford_4_4.py +10 -9
  104. qiskit/circuit/library/templates/clifford/clifford_5_1.py +10 -9
  105. qiskit/circuit/library/templates/clifford/clifford_6_1.py +10 -9
  106. qiskit/circuit/library/templates/clifford/clifford_6_2.py +10 -9
  107. qiskit/circuit/library/templates/clifford/clifford_6_3.py +10 -9
  108. qiskit/circuit/library/templates/clifford/clifford_6_4.py +9 -8
  109. qiskit/circuit/library/templates/clifford/clifford_6_5.py +10 -9
  110. qiskit/circuit/library/templates/clifford/clifford_8_1.py +10 -9
  111. qiskit/circuit/library/templates/clifford/clifford_8_2.py +10 -9
  112. qiskit/circuit/library/templates/clifford/clifford_8_3.py +10 -9
  113. qiskit/circuit/library/templates/nct/template_nct_2a_1.py +9 -7
  114. qiskit/circuit/library/templates/nct/template_nct_2a_2.py +10 -8
  115. qiskit/circuit/library/templates/nct/template_nct_2a_3.py +12 -10
  116. qiskit/circuit/library/templates/nct/template_nct_4a_1.py +16 -14
  117. qiskit/circuit/library/templates/nct/template_nct_4a_2.py +14 -12
  118. qiskit/circuit/library/templates/nct/template_nct_4a_3.py +12 -10
  119. qiskit/circuit/library/templates/nct/template_nct_4b_1.py +14 -12
  120. qiskit/circuit/library/templates/nct/template_nct_4b_2.py +12 -10
  121. qiskit/circuit/library/templates/nct/template_nct_5a_1.py +12 -10
  122. qiskit/circuit/library/templates/nct/template_nct_5a_2.py +12 -10
  123. qiskit/circuit/library/templates/nct/template_nct_5a_3.py +12 -10
  124. qiskit/circuit/library/templates/nct/template_nct_5a_4.py +11 -9
  125. qiskit/circuit/library/templates/nct/template_nct_6a_1.py +11 -9
  126. qiskit/circuit/library/templates/nct/template_nct_6a_2.py +12 -10
  127. qiskit/circuit/library/templates/nct/template_nct_6a_3.py +12 -10
  128. qiskit/circuit/library/templates/nct/template_nct_6a_4.py +12 -10
  129. qiskit/circuit/library/templates/nct/template_nct_6b_1.py +12 -10
  130. qiskit/circuit/library/templates/nct/template_nct_6b_2.py +12 -10
  131. qiskit/circuit/library/templates/nct/template_nct_6c_1.py +12 -10
  132. qiskit/circuit/library/templates/nct/template_nct_7a_1.py +13 -11
  133. qiskit/circuit/library/templates/nct/template_nct_7b_1.py +13 -11
  134. qiskit/circuit/library/templates/nct/template_nct_7c_1.py +13 -11
  135. qiskit/circuit/library/templates/nct/template_nct_7d_1.py +13 -11
  136. qiskit/circuit/library/templates/nct/template_nct_7e_1.py +13 -11
  137. qiskit/circuit/library/templates/nct/template_nct_9a_1.py +13 -11
  138. qiskit/circuit/library/templates/nct/template_nct_9c_1.py +11 -9
  139. qiskit/circuit/library/templates/nct/template_nct_9c_10.py +12 -10
  140. qiskit/circuit/library/templates/nct/template_nct_9c_11.py +12 -10
  141. qiskit/circuit/library/templates/nct/template_nct_9c_12.py +12 -10
  142. qiskit/circuit/library/templates/nct/template_nct_9c_2.py +12 -10
  143. qiskit/circuit/library/templates/nct/template_nct_9c_3.py +12 -10
  144. qiskit/circuit/library/templates/nct/template_nct_9c_4.py +12 -10
  145. qiskit/circuit/library/templates/nct/template_nct_9c_5.py +12 -10
  146. qiskit/circuit/library/templates/nct/template_nct_9c_6.py +12 -10
  147. qiskit/circuit/library/templates/nct/template_nct_9c_7.py +12 -10
  148. qiskit/circuit/library/templates/nct/template_nct_9c_8.py +12 -10
  149. qiskit/circuit/library/templates/nct/template_nct_9c_9.py +12 -10
  150. qiskit/circuit/library/templates/nct/template_nct_9d_1.py +11 -9
  151. qiskit/circuit/library/templates/nct/template_nct_9d_10.py +12 -10
  152. qiskit/circuit/library/templates/nct/template_nct_9d_2.py +12 -10
  153. qiskit/circuit/library/templates/nct/template_nct_9d_3.py +12 -10
  154. qiskit/circuit/library/templates/nct/template_nct_9d_4.py +12 -10
  155. qiskit/circuit/library/templates/nct/template_nct_9d_5.py +12 -10
  156. qiskit/circuit/library/templates/nct/template_nct_9d_6.py +12 -10
  157. qiskit/circuit/library/templates/nct/template_nct_9d_7.py +12 -10
  158. qiskit/circuit/library/templates/nct/template_nct_9d_8.py +12 -10
  159. qiskit/circuit/library/templates/nct/template_nct_9d_9.py +12 -10
  160. qiskit/circuit/library/templates/rzx/rzx_cy.py +11 -10
  161. qiskit/circuit/library/templates/rzx/rzx_xz.py +16 -15
  162. qiskit/circuit/library/templates/rzx/rzx_yz.py +12 -10
  163. qiskit/circuit/library/templates/rzx/rzx_zz1.py +22 -20
  164. qiskit/circuit/library/templates/rzx/rzx_zz2.py +16 -15
  165. qiskit/circuit/library/templates/rzx/rzx_zz3.py +17 -15
  166. qiskit/circuit/parameter.py +4 -0
  167. qiskit/circuit/parameterexpression.py +167 -34
  168. qiskit/circuit/quantumcircuit.py +162 -126
  169. qiskit/circuit/singleton.py +2 -0
  170. qiskit/circuit/store.py +2 -0
  171. qiskit/circuit/twirling.py +145 -0
  172. qiskit/compiler/assembler.py +17 -4
  173. qiskit/compiler/scheduler.py +2 -0
  174. qiskit/compiler/sequencer.py +2 -0
  175. qiskit/compiler/transpiler.py +81 -26
  176. qiskit/converters/circuit_to_dag.py +2 -2
  177. qiskit/converters/circuit_to_dagdependency.py +1 -1
  178. qiskit/converters/circuit_to_dagdependency_v2.py +1 -1
  179. qiskit/converters/circuit_to_instruction.py +1 -1
  180. qiskit/converters/dag_to_circuit.py +7 -5
  181. qiskit/converters/dag_to_dagdependency.py +1 -1
  182. qiskit/converters/dag_to_dagdependency_v2.py +1 -1
  183. qiskit/converters/dagdependency_to_circuit.py +5 -1
  184. qiskit/converters/dagdependency_to_dag.py +6 -1
  185. qiskit/dagcircuit/collect_blocks.py +3 -3
  186. qiskit/dagcircuit/dagdependency.py +18 -5
  187. qiskit/dagcircuit/dagdependency_v2.py +1 -1
  188. qiskit/dagcircuit/dagnode.py +2 -2
  189. qiskit/passmanager/__init__.py +2 -2
  190. qiskit/primitives/backend_estimator.py +5 -2
  191. qiskit/primitives/backend_sampler_v2.py +61 -18
  192. qiskit/primitives/base/base_estimator.py +2 -2
  193. qiskit/primitives/containers/data_bin.py +9 -1
  194. qiskit/primitives/statevector_sampler.py +1 -1
  195. qiskit/primitives/utils.py +1 -1
  196. qiskit/providers/__init__.py +3 -3
  197. qiskit/providers/backend.py +12 -1
  198. qiskit/providers/backend_compat.py +23 -3
  199. qiskit/providers/basic_provider/basic_simulator.py +12 -2
  200. qiskit/providers/fake_provider/fake_pulse_backend.py +6 -1
  201. qiskit/providers/fake_provider/generic_backend_v2.py +46 -30
  202. qiskit/providers/models/pulsedefaults.py +2 -0
  203. qiskit/pulse/builder.py +59 -18
  204. qiskit/pulse/calibration_entries.py +4 -1
  205. qiskit/pulse/channels.py +2 -0
  206. qiskit/pulse/exceptions.py +2 -0
  207. qiskit/pulse/instruction_schedule_map.py +21 -6
  208. qiskit/pulse/instructions/acquire.py +2 -0
  209. qiskit/pulse/instructions/delay.py +2 -0
  210. qiskit/pulse/instructions/directives.py +8 -0
  211. qiskit/pulse/instructions/frequency.py +3 -0
  212. qiskit/pulse/instructions/instruction.py +2 -0
  213. qiskit/pulse/instructions/phase.py +3 -0
  214. qiskit/pulse/instructions/play.py +2 -0
  215. qiskit/pulse/instructions/reference.py +2 -0
  216. qiskit/pulse/instructions/snapshot.py +2 -0
  217. qiskit/pulse/library/pulse.py +2 -0
  218. qiskit/pulse/library/symbolic_pulses.py +28 -0
  219. qiskit/pulse/library/waveform.py +2 -0
  220. qiskit/pulse/macros.py +1 -1
  221. qiskit/pulse/schedule.py +12 -13
  222. qiskit/pulse/transforms/alignments.py +5 -3
  223. qiskit/pulse/transforms/dag.py +7 -0
  224. qiskit/qasm2/export.py +5 -3
  225. qiskit/qasm2/parse.py +46 -2
  226. qiskit/qasm3/__init__.py +1 -0
  227. qiskit/qasm3/ast.py +123 -15
  228. qiskit/qasm3/exporter.py +103 -77
  229. qiskit/qobj/converters/pulse_instruction.py +6 -4
  230. qiskit/qpy/__init__.py +181 -0
  231. qiskit/qpy/binary_io/circuits.py +20 -5
  232. qiskit/qpy/binary_io/schedules.py +3 -4
  233. qiskit/qpy/binary_io/value.py +310 -13
  234. qiskit/qpy/common.py +46 -2
  235. qiskit/qpy/formats.py +7 -0
  236. qiskit/qpy/interface.py +40 -4
  237. qiskit/quantum_info/__init__.py +4 -0
  238. qiskit/quantum_info/operators/channel/transformations.py +28 -21
  239. qiskit/quantum_info/operators/dihedral/dihedral.py +1 -1
  240. qiskit/quantum_info/operators/operator.py +54 -8
  241. qiskit/quantum_info/operators/symplectic/base_pauli.py +11 -19
  242. qiskit/quantum_info/operators/symplectic/clifford.py +1 -1
  243. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +1 -1
  244. qiskit/quantum_info/operators/symplectic/pauli.py +2 -0
  245. qiskit/quantum_info/operators/symplectic/pauli_list.py +4 -4
  246. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +23 -2
  247. qiskit/quantum_info/states/densitymatrix.py +5 -5
  248. qiskit/quantum_info/states/stabilizerstate.py +1 -1
  249. qiskit/quantum_info/states/statevector.py +6 -6
  250. qiskit/result/mitigation/base_readout_mitigator.py +1 -1
  251. qiskit/result/mitigation/correlated_readout_mitigator.py +9 -1
  252. qiskit/result/mitigation/local_readout_mitigator.py +9 -1
  253. qiskit/result/mitigation/utils.py +57 -0
  254. qiskit/scheduler/config.py +2 -0
  255. qiskit/scheduler/methods/basic.py +3 -0
  256. qiskit/scheduler/schedule_circuit.py +2 -0
  257. qiskit/scheduler/sequence.py +2 -0
  258. qiskit/synthesis/__init__.py +25 -0
  259. qiskit/synthesis/arithmetic/__init__.py +16 -0
  260. qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
  261. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
  262. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
  263. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
  264. qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
  265. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +102 -0
  266. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +99 -0
  267. qiskit/synthesis/clifford/clifford_decompose_bm.py +1 -2
  268. qiskit/synthesis/clifford/clifford_decompose_greedy.py +3 -2
  269. qiskit/synthesis/clifford/clifford_decompose_layers.py +2 -1
  270. qiskit/synthesis/evolution/__init__.py +1 -0
  271. qiskit/synthesis/evolution/lie_trotter.py +16 -42
  272. qiskit/synthesis/evolution/pauli_network.py +80 -0
  273. qiskit/synthesis/evolution/product_formula.py +165 -238
  274. qiskit/synthesis/evolution/qdrift.py +36 -29
  275. qiskit/synthesis/evolution/suzuki_trotter.py +87 -27
  276. qiskit/synthesis/multi_controlled/__init__.py +1 -0
  277. qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
  278. qiskit/synthesis/qft/qft_decompose_full.py +19 -1
  279. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -1
  280. qiskit/synthesis/stabilizer/stabilizer_decompose.py +2 -1
  281. qiskit/synthesis/two_qubit/two_qubit_decompose.py +4 -63
  282. qiskit/synthesis/unitary/qsd.py +5 -5
  283. qiskit/transpiler/__init__.py +21 -14
  284. qiskit/transpiler/basepasses.py +1 -1
  285. qiskit/transpiler/passes/__init__.py +2 -0
  286. qiskit/transpiler/passes/basis/basis_translator.py +9 -565
  287. qiskit/transpiler/passes/basis/decompose.py +45 -12
  288. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  289. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  290. qiskit/transpiler/passes/calibration/pulse_gate.py +4 -2
  291. qiskit/transpiler/passes/calibration/rx_builder.py +11 -7
  292. qiskit/transpiler/passes/calibration/rzx_builder.py +46 -30
  293. qiskit/transpiler/passes/layout/disjoint_utils.py +15 -13
  294. qiskit/transpiler/passes/layout/sabre_layout.py +7 -2
  295. qiskit/transpiler/passes/layout/sabre_pre_layout.py +5 -0
  296. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  297. qiskit/transpiler/passes/optimization/collect_cliffords.py +19 -3
  298. qiskit/transpiler/passes/optimization/collect_linear_functions.py +1 -1
  299. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +2 -2
  300. qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +1 -1
  301. qiskit/transpiler/passes/optimization/consolidate_blocks.py +48 -131
  302. qiskit/transpiler/passes/optimization/echo_rzx_weyl_decomposition.py +4 -2
  303. qiskit/transpiler/passes/optimization/elide_permutations.py +9 -32
  304. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +5 -11
  305. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +1 -1
  306. qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +1 -1
  307. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +69 -0
  308. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +5 -5
  309. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +4 -4
  310. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +2 -2
  311. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +1 -1
  312. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +1 -1
  313. qiskit/transpiler/passes/routing/sabre_swap.py +7 -3
  314. qiskit/transpiler/passes/routing/star_prerouting.py +2 -2
  315. qiskit/transpiler/passes/scheduling/alap.py +1 -1
  316. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +2 -2
  317. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  318. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +2 -0
  319. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +2 -2
  320. qiskit/transpiler/passes/scheduling/asap.py +1 -1
  321. qiskit/transpiler/passes/scheduling/base_scheduler.py +14 -12
  322. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +9 -4
  323. qiskit/transpiler/passes/scheduling/padding/base_padding.py +1 -1
  324. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +16 -5
  325. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +4 -1
  326. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +6 -2
  327. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +9 -4
  328. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +262 -99
  329. qiskit/transpiler/passes/synthesis/hls_plugins.py +637 -7
  330. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +3 -3
  331. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +55 -34
  332. qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +2 -56
  333. qiskit/transpiler/passes/utils/convert_conditions_to_if_ops.py +5 -0
  334. qiskit/transpiler/passes/utils/gate_direction.py +12 -275
  335. qiskit/transpiler/passes/utils/gates_basis.py +7 -30
  336. qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +2 -1
  337. qiskit/transpiler/passmanager_config.py +22 -4
  338. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +40 -14
  339. qiskit/transpiler/preset_passmanagers/common.py +5 -3
  340. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +125 -42
  341. qiskit/transpiler/preset_passmanagers/plugin.py +1 -1
  342. qiskit/transpiler/target.py +74 -16
  343. qiskit/utils/deprecate_pulse.py +119 -0
  344. qiskit/visualization/circuit/_utils.py +2 -2
  345. qiskit/visualization/circuit/circuit_visualization.py +3 -2
  346. qiskit/visualization/circuit/matplotlib.py +1 -1
  347. qiskit/visualization/dag_visualization.py +1 -1
  348. qiskit/visualization/pass_manager_visualization.py +3 -14
  349. qiskit/visualization/pulse_v2/interface.py +3 -1
  350. qiskit/visualization/timeline/core.py +25 -2
  351. qiskit/visualization/timeline/interface.py +12 -0
  352. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/METADATA +9 -8
  353. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/RECORD +357 -346
  354. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/WHEEL +1 -1
  355. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/entry_points.txt +19 -0
  356. qiskit/circuit/library/data_preparation/zz_feature_map.py +0 -118
  357. qiskit/synthesis/two_qubit/weyl.py +0 -97
  358. qiskit/transpiler/passes/synthesis/qubit_tracker.py +0 -132
  359. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.dist-info}/LICENSE.txt +0 -0
  360. {qiskit-1.3.0b1.dist-info → qiskit-1.3.0rc2.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,6 +19,7 @@ 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
22
23
 
23
24
  from .base_builder import CalibrationBuilder
24
25
 
@@ -47,6 +48,7 @@ class PulseGates(CalibrationBuilder):
47
48
  https://arxiv.org/abs/2104.14722
48
49
  """
49
50
 
51
+ @deprecate_pulse_dependency
50
52
  def __init__(
51
53
  self,
52
54
  inst_map: InstructionScheduleMap = None,
@@ -80,7 +82,7 @@ class PulseGates(CalibrationBuilder):
80
82
  Returns:
81
83
  Return ``True`` is calibration can be provided.
82
84
  """
83
- return self.target.has_calibration(node_op.name, tuple(qubits))
85
+ return self.target._has_calibration(node_op.name, tuple(qubits))
84
86
 
85
87
  def get_calibration(self, node_op: CircuitInst, qubits: List) -> Union[Schedule, ScheduleBlock]:
86
88
  """Gets the calibrated schedule for the given instruction and qubits.
@@ -95,4 +97,4 @@ class PulseGates(CalibrationBuilder):
95
97
  Raises:
96
98
  TranspilerError: When node is parameterized and calibration is raw schedule object.
97
99
  """
98
- return self.target.get_calibration(node_op.name, tuple(qubits), *node_op.params)
100
+ return self.target._get_calibration(node_op.name, tuple(qubits), *node_op.params)
@@ -24,6 +24,7 @@ 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
27
28
 
28
29
 
29
30
  class RXCalibrationBuilder(CalibrationBuilder):
@@ -45,7 +46,7 @@ class RXCalibrationBuilder(CalibrationBuilder):
45
46
  from qiskit.circuit.library import QuantumVolume
46
47
  from qiskit.circuit.library.standard_gates import RXGate
47
48
 
48
- from calibration.rx_builder import RXCalibrationBuilder
49
+ from qiskit.transpiler.passes import RXCalibrationBuilder
49
50
 
50
51
  qv = QuantumVolume(4, 4, seed=1004)
51
52
 
@@ -75,6 +76,7 @@ class RXCalibrationBuilder(CalibrationBuilder):
75
76
  `arXiv:2004.11205 <https://arxiv.org/abs/2004.11205>`
76
77
  """
77
78
 
79
+ @deprecate_pulse_dependency
78
80
  def __init__(
79
81
  self,
80
82
  target: Target = None,
@@ -99,13 +101,15 @@ class RXCalibrationBuilder(CalibrationBuilder):
99
101
  """
100
102
  return (
101
103
  isinstance(node_op, RXGate)
102
- and self.target.has_calibration("sx", tuple(qubits))
103
- and (len(self.target.get_calibration("sx", tuple(qubits)).instructions) == 1)
104
+ and self.target._has_calibration("sx", tuple(qubits))
105
+ and (len(self.target._get_calibration("sx", tuple(qubits)).instructions) == 1)
104
106
  and isinstance(
105
- self.target.get_calibration("sx", tuple(qubits)).instructions[0][1].pulse,
107
+ self.target._get_calibration("sx", tuple(qubits)).instructions[0][1].pulse,
106
108
  ScalableSymbolicPulse,
107
109
  )
108
- and self.target.get_calibration("sx", tuple(qubits)).instructions[0][1].pulse.pulse_type
110
+ and self.target._get_calibration("sx", tuple(qubits))
111
+ .instructions[0][1]
112
+ .pulse.pulse_type
109
113
  == "Drag"
110
114
  )
111
115
 
@@ -122,13 +126,13 @@ class RXCalibrationBuilder(CalibrationBuilder):
122
126
  raise QiskitError("Target rotation angle is not assigned.") from ex
123
127
 
124
128
  params = (
125
- self.target.get_calibration("sx", tuple(qubits))
129
+ self.target._get_calibration("sx", tuple(qubits))
126
130
  .instructions[0][1]
127
131
  .pulse.parameters.copy()
128
132
  )
129
133
  new_rx_sched = _create_rx_sched(
130
134
  rx_angle=angle,
131
- channel=self.target.get_calibration("sx", tuple(qubits)).channels[0],
135
+ channel=self.target._get_calibration("sx", tuple(qubits)).channels[0],
132
136
  duration=params["duration"],
133
137
  amp=params["amp"],
134
138
  sigma=params["sigma"],
@@ -36,6 +36,7 @@ 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
39
40
 
40
41
  from .base_builder import CalibrationBuilder
41
42
  from .exceptions import CalibrationNotAvailable
@@ -65,6 +66,7 @@ class RZXCalibrationBuilder(CalibrationBuilder):
65
66
  angle. Additional details can be found in https://arxiv.org/abs/2012.11660.
66
67
  """
67
68
 
69
+ @deprecate_pulse_dependency
68
70
  def __init__(
69
71
  self,
70
72
  instruction_schedule_map: InstructionScheduleMap = None,
@@ -89,7 +91,7 @@ class RZXCalibrationBuilder(CalibrationBuilder):
89
91
  self._inst_map = instruction_schedule_map
90
92
  self._verbose = verbose
91
93
  if target:
92
- self._inst_map = target.instruction_schedule_map()
94
+ self._inst_map = target._instruction_schedule_map()
93
95
  if self._inst_map is None:
94
96
  raise QiskitError("Calibrations can only be added to Pulse-enabled backends")
95
97
 
@@ -202,15 +204,20 @@ class RZXCalibrationBuilder(CalibrationBuilder):
202
204
 
203
205
  # The CR instruction is in the forward (native) direction
204
206
  if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
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)
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)
214
221
  return rzx_theta_native
215
222
 
216
223
  # The direction is not native. Add Hadamard gates to flip the direction.
@@ -297,11 +304,15 @@ class RZXCalibrationBuilderNoEcho(RZXCalibrationBuilder):
297
304
 
298
305
  # RZXCalibrationNoEcho only good for forward CR direction
299
306
  if cal_type in [CRCalType.ECR_CX_FORWARD, CRCalType.ECR_FORWARD]:
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]))
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]))
305
316
  return rzx_theta
306
317
 
307
318
  raise QiskitError("RZXCalibrationBuilderNoEcho only supports hardware-native RZX gates.")
@@ -347,22 +358,27 @@ def _check_calibration_type(
347
358
  QiskitError: Unknown calibration type is detected.
348
359
  """
349
360
  cal_type = None
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
- )
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
+ )
363
379
 
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]
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]
366
382
 
367
383
  if cal_type is None:
368
384
  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.op.label:
110
+ if node.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,28 +125,30 @@ 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[uuid.UUID, DAGOpNode] = {}
128
+ uuid_map: dict[str, DAGOpNode] = {}
129
129
  for node in dag.op_nodes(Barrier):
130
- if node.op.label:
131
- if "_uuid=" in node.op.label:
132
- barrier_uuid = node.op.label
130
+ if node.label:
131
+ if "_uuid=" in node.label:
132
+ barrier_uuid = node.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
- new_op = Barrier(num_qubits, label=barrier_uuid)
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)
139
148
  new_node = dag.replace_block_with_op([node, other_node], new_op, qubit_indices)
140
149
  uuid_map[barrier_uuid] = new_node
141
150
  else:
142
151
  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
150
152
 
151
153
 
152
154
  def require_layout_isolated_to_component(
@@ -101,7 +101,10 @@ class SabreLayout(TransformationPass):
101
101
 
102
102
  **References:**
103
103
 
104
- [1] Li, Gushu, Yufei Ding, and Yuan Xie. "Tackling the qubit mapping problem
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
105
108
  for NISQ-era quantum devices." ASPLOS 2019.
106
109
  `arXiv:1809.02573 <https://arxiv.org/pdf/1809.02573.pdf>`_
107
110
  """
@@ -145,7 +148,9 @@ class SabreLayout(TransformationPass):
145
148
  (and ``routing_pass`` is not set) then the number of local
146
149
  physical CPUs will be used as the default value. This option is
147
150
  mutually exclusive with the ``routing_pass`` argument and an error
148
- will be raised if both are used.
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.
149
154
  skip_routing (bool): If this is set ``True`` and ``routing_pass`` is not used
150
155
  then routing will not be applied to the output circuit. Only the layout
151
156
  will be set in the property set. This is a tradeoff to run custom
@@ -31,6 +31,11 @@ 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>`__
34
39
  """
35
40
 
36
41
  def __init__(
@@ -38,5 +38,6 @@ 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
41
42
  from .split_2q_unitaries import Split2QUnitaries
42
43
  from .collect_and_collapse import CollectAndCollapse
@@ -15,6 +15,7 @@
15
15
 
16
16
  from functools import partial
17
17
 
18
+ from qiskit.exceptions import QiskitError
18
19
  from qiskit.transpiler.passes.optimization.collect_and_collapse import (
19
20
  CollectAndCollapse,
20
21
  collect_using_filter_function,
@@ -37,6 +38,7 @@ class CollectCliffords(CollectAndCollapse):
37
38
  min_block_size=2,
38
39
  split_layers=False,
39
40
  collect_from_back=False,
41
+ matrix_based=False,
40
42
  ):
41
43
  """CollectCliffords initializer.
42
44
 
@@ -51,11 +53,13 @@ class CollectCliffords(CollectAndCollapse):
51
53
  over disjoint qubit subsets.
52
54
  collect_from_back (bool): specifies if blocks should be collected started
53
55
  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).
54
58
  """
55
59
 
56
60
  collect_function = partial(
57
61
  collect_using_filter_function,
58
- filter_function=_is_clifford_gate,
62
+ filter_function=partial(_is_clifford_gate, matrix_based=matrix_based),
59
63
  split_blocks=split_blocks,
60
64
  min_block_size=min_block_size,
61
65
  split_layers=split_layers,
@@ -77,9 +81,21 @@ clifford_gate_names = (
77
81
  )
78
82
 
79
83
 
80
- def _is_clifford_gate(node):
84
+ def _is_clifford_gate(node, matrix_based=False):
81
85
  """Specifies whether a node holds a clifford gate."""
82
- return node.op.name in clifford_gate_names and getattr(node.op, "condition", None) is None
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
83
99
 
84
100
 
85
101
  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.op, "condition", None) is None
74
+ return node.op.name in ("cx", "swap") and getattr(node, "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.op, "condition", None):
52
+ if getattr(node, "condition", None):
53
53
  return True
54
54
  if node.op.is_parameterized():
55
55
  return True
@@ -12,27 +12,26 @@
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
15
16
 
16
- import numpy as np
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
17
  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
18
+ from qiskit.circuit.library.standard_gates import CXGate, CZGate, iSwapGate, ECRGate, RXXGate
19
+
26
20
  from qiskit.transpiler.basepasses import TransformationPass
27
21
  from qiskit.transpiler.passmanager import PassManager
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
22
+ from qiskit._accelerate.consolidate_blocks import consolidate_blocks
32
23
 
33
24
  from .collect_1q_runs import Collect1qRuns
34
25
  from .collect_2q_blocks import Collect2qBlocks
35
26
 
27
+ KAK_GATE_NAMES = {
28
+ "cx": CXGate(),
29
+ "cz": CZGate(),
30
+ "iswap": iSwapGate(),
31
+ "ecr": ECRGate(),
32
+ "rxx": RXXGate(pi / 2),
33
+ }
34
+
36
35
 
37
36
  class ConsolidateBlocks(TransformationPass):
38
37
  """Replace each block of consecutive gates by a single Unitary node.
@@ -74,13 +73,20 @@ class ConsolidateBlocks(TransformationPass):
74
73
  if basis_gates is not None:
75
74
  self.basis_gates = set(basis_gates)
76
75
  self.force_consolidate = force_consolidate
77
-
78
76
  if kak_basis_gate is not None:
79
77
  self.decomposer = TwoQubitBasisDecomposer(kak_basis_gate)
80
78
  elif basis_gates is not None:
81
- self.decomposer = unitary_synthesis._decomposer_2q_from_basis_gates(
82
- basis_gates, approximation_degree=approximation_degree
83
- )
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
84
90
  else:
85
91
  self.decomposer = TwoQubitBasisDecomposer(CXGate())
86
92
 
@@ -93,89 +99,23 @@ class ConsolidateBlocks(TransformationPass):
93
99
  if self.decomposer is None:
94
100
  return dag
95
101
 
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
-
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
+ )
179
119
  dag = self._handle_control_flow_ops(dag)
180
120
 
181
121
  # Clear collected blocks and runs as they are no longer valid after consolidation
@@ -195,38 +135,15 @@ class ConsolidateBlocks(TransformationPass):
195
135
  pass_manager = PassManager()
196
136
  if "run_list" in self.property_set:
197
137
  pass_manager.append(Collect1qRuns())
198
- if "block_list" in self.property_set:
199
138
  pass_manager.append(Collect2qBlocks())
200
139
 
201
140
  pass_manager.append(self)
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
- )
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
+ )
210
149
  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