qiskit 2.0.3__cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.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 (690) hide show
  1. qiskit/VERSION.txt +1 -0
  2. qiskit/__init__.py +141 -0
  3. qiskit/_accelerate.abi3.so +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/circuit/__init__.py +1343 -0
  6. qiskit/circuit/_add_control.py +312 -0
  7. qiskit/circuit/_classical_resource_map.py +150 -0
  8. qiskit/circuit/_standard_gates_commutations.py +3849 -0
  9. qiskit/circuit/_utils.py +167 -0
  10. qiskit/circuit/annotated_operation.py +279 -0
  11. qiskit/circuit/barrier.py +46 -0
  12. qiskit/circuit/classical/__init__.py +41 -0
  13. qiskit/circuit/classical/expr/__init__.py +266 -0
  14. qiskit/circuit/classical/expr/constructors.py +764 -0
  15. qiskit/circuit/classical/expr/expr.py +498 -0
  16. qiskit/circuit/classical/expr/visitors.py +375 -0
  17. qiskit/circuit/classical/types/__init__.py +113 -0
  18. qiskit/circuit/classical/types/ordering.py +229 -0
  19. qiskit/circuit/classical/types/types.py +153 -0
  20. qiskit/circuit/commutation_checker.py +133 -0
  21. qiskit/circuit/commutation_library.py +20 -0
  22. qiskit/circuit/controlflow/__init__.py +59 -0
  23. qiskit/circuit/controlflow/_builder_utils.py +211 -0
  24. qiskit/circuit/controlflow/box.py +163 -0
  25. qiskit/circuit/controlflow/break_loop.py +56 -0
  26. qiskit/circuit/controlflow/builder.py +791 -0
  27. qiskit/circuit/controlflow/continue_loop.py +56 -0
  28. qiskit/circuit/controlflow/control_flow.py +94 -0
  29. qiskit/circuit/controlflow/for_loop.py +218 -0
  30. qiskit/circuit/controlflow/if_else.py +498 -0
  31. qiskit/circuit/controlflow/switch_case.py +411 -0
  32. qiskit/circuit/controlflow/while_loop.py +166 -0
  33. qiskit/circuit/controlledgate.py +274 -0
  34. qiskit/circuit/delay.py +157 -0
  35. qiskit/circuit/duration.py +80 -0
  36. qiskit/circuit/equivalence.py +94 -0
  37. qiskit/circuit/equivalence_library.py +18 -0
  38. qiskit/circuit/exceptions.py +19 -0
  39. qiskit/circuit/gate.py +261 -0
  40. qiskit/circuit/instruction.py +564 -0
  41. qiskit/circuit/instructionset.py +132 -0
  42. qiskit/circuit/library/__init__.py +984 -0
  43. qiskit/circuit/library/arithmetic/__init__.py +40 -0
  44. qiskit/circuit/library/arithmetic/adders/__init__.py +18 -0
  45. qiskit/circuit/library/arithmetic/adders/adder.py +235 -0
  46. qiskit/circuit/library/arithmetic/adders/cdkm_ripple_carry_adder.py +123 -0
  47. qiskit/circuit/library/arithmetic/adders/draper_qft_adder.py +129 -0
  48. qiskit/circuit/library/arithmetic/adders/vbe_ripple_carry_adder.py +95 -0
  49. qiskit/circuit/library/arithmetic/exact_reciprocal.py +131 -0
  50. qiskit/circuit/library/arithmetic/functional_pauli_rotations.py +114 -0
  51. qiskit/circuit/library/arithmetic/integer_comparator.py +200 -0
  52. qiskit/circuit/library/arithmetic/linear_amplitude_function.py +363 -0
  53. qiskit/circuit/library/arithmetic/linear_pauli_rotations.py +243 -0
  54. qiskit/circuit/library/arithmetic/multipliers/__init__.py +17 -0
  55. qiskit/circuit/library/arithmetic/multipliers/hrs_cumulative_multiplier.py +145 -0
  56. qiskit/circuit/library/arithmetic/multipliers/multiplier.py +201 -0
  57. qiskit/circuit/library/arithmetic/multipliers/rg_qft_multiplier.py +108 -0
  58. qiskit/circuit/library/arithmetic/piecewise_chebyshev.py +502 -0
  59. qiskit/circuit/library/arithmetic/piecewise_linear_pauli_rotations.py +387 -0
  60. qiskit/circuit/library/arithmetic/piecewise_polynomial_pauli_rotations.py +493 -0
  61. qiskit/circuit/library/arithmetic/polynomial_pauli_rotations.py +389 -0
  62. qiskit/circuit/library/arithmetic/quadratic_form.py +364 -0
  63. qiskit/circuit/library/arithmetic/weighted_adder.py +409 -0
  64. qiskit/circuit/library/basis_change/__init__.py +15 -0
  65. qiskit/circuit/library/basis_change/qft.py +316 -0
  66. qiskit/circuit/library/bit_flip_oracle.py +130 -0
  67. qiskit/circuit/library/blueprintcircuit.py +316 -0
  68. qiskit/circuit/library/boolean_logic/__init__.py +18 -0
  69. qiskit/circuit/library/boolean_logic/inner_product.py +157 -0
  70. qiskit/circuit/library/boolean_logic/quantum_and.py +204 -0
  71. qiskit/circuit/library/boolean_logic/quantum_or.py +206 -0
  72. qiskit/circuit/library/boolean_logic/quantum_xor.py +167 -0
  73. qiskit/circuit/library/data_preparation/__init__.py +57 -0
  74. qiskit/circuit/library/data_preparation/_z_feature_map.py +115 -0
  75. qiskit/circuit/library/data_preparation/_zz_feature_map.py +150 -0
  76. qiskit/circuit/library/data_preparation/initializer.py +107 -0
  77. qiskit/circuit/library/data_preparation/pauli_feature_map.py +656 -0
  78. qiskit/circuit/library/data_preparation/state_preparation.py +336 -0
  79. qiskit/circuit/library/fourier_checking.py +160 -0
  80. qiskit/circuit/library/generalized_gates/__init__.py +30 -0
  81. qiskit/circuit/library/generalized_gates/diagonal.py +159 -0
  82. qiskit/circuit/library/generalized_gates/gms.py +175 -0
  83. qiskit/circuit/library/generalized_gates/gr.py +219 -0
  84. qiskit/circuit/library/generalized_gates/isometry.py +370 -0
  85. qiskit/circuit/library/generalized_gates/linear_function.py +318 -0
  86. qiskit/circuit/library/generalized_gates/mcg_up_to_diagonal.py +143 -0
  87. qiskit/circuit/library/generalized_gates/mcmt.py +316 -0
  88. qiskit/circuit/library/generalized_gates/pauli.py +84 -0
  89. qiskit/circuit/library/generalized_gates/permutation.py +198 -0
  90. qiskit/circuit/library/generalized_gates/rv.py +96 -0
  91. qiskit/circuit/library/generalized_gates/uc.py +303 -0
  92. qiskit/circuit/library/generalized_gates/uc_pauli_rot.py +164 -0
  93. qiskit/circuit/library/generalized_gates/ucrx.py +32 -0
  94. qiskit/circuit/library/generalized_gates/ucry.py +32 -0
  95. qiskit/circuit/library/generalized_gates/ucrz.py +32 -0
  96. qiskit/circuit/library/generalized_gates/unitary.py +217 -0
  97. qiskit/circuit/library/graph_state.py +172 -0
  98. qiskit/circuit/library/grover_operator.py +583 -0
  99. qiskit/circuit/library/hamiltonian_gate.py +142 -0
  100. qiskit/circuit/library/hidden_linear_function.py +163 -0
  101. qiskit/circuit/library/iqp.py +180 -0
  102. qiskit/circuit/library/n_local/__init__.py +45 -0
  103. qiskit/circuit/library/n_local/efficient_su2.py +282 -0
  104. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +520 -0
  105. qiskit/circuit/library/n_local/excitation_preserving.py +303 -0
  106. qiskit/circuit/library/n_local/n_local.py +1477 -0
  107. qiskit/circuit/library/n_local/pauli_two_design.py +246 -0
  108. qiskit/circuit/library/n_local/qaoa_ansatz.py +367 -0
  109. qiskit/circuit/library/n_local/real_amplitudes.py +312 -0
  110. qiskit/circuit/library/n_local/two_local.py +289 -0
  111. qiskit/circuit/library/overlap.py +183 -0
  112. qiskit/circuit/library/pauli_evolution.py +201 -0
  113. qiskit/circuit/library/phase_estimation.py +177 -0
  114. qiskit/circuit/library/phase_oracle.py +239 -0
  115. qiskit/circuit/library/quantum_volume.py +180 -0
  116. qiskit/circuit/library/standard_gates/__init__.py +141 -0
  117. qiskit/circuit/library/standard_gates/dcx.py +77 -0
  118. qiskit/circuit/library/standard_gates/ecr.py +129 -0
  119. qiskit/circuit/library/standard_gates/equivalence_library.py +1800 -0
  120. qiskit/circuit/library/standard_gates/global_phase.py +84 -0
  121. qiskit/circuit/library/standard_gates/h.py +253 -0
  122. qiskit/circuit/library/standard_gates/i.py +76 -0
  123. qiskit/circuit/library/standard_gates/iswap.py +133 -0
  124. qiskit/circuit/library/standard_gates/p.py +422 -0
  125. qiskit/circuit/library/standard_gates/r.py +114 -0
  126. qiskit/circuit/library/standard_gates/rx.py +293 -0
  127. qiskit/circuit/library/standard_gates/rxx.py +180 -0
  128. qiskit/circuit/library/standard_gates/ry.py +286 -0
  129. qiskit/circuit/library/standard_gates/ryy.py +180 -0
  130. qiskit/circuit/library/standard_gates/rz.py +307 -0
  131. qiskit/circuit/library/standard_gates/rzx.py +226 -0
  132. qiskit/circuit/library/standard_gates/rzz.py +193 -0
  133. qiskit/circuit/library/standard_gates/s.py +419 -0
  134. qiskit/circuit/library/standard_gates/swap.py +281 -0
  135. qiskit/circuit/library/standard_gates/sx.py +310 -0
  136. qiskit/circuit/library/standard_gates/t.py +178 -0
  137. qiskit/circuit/library/standard_gates/u.py +395 -0
  138. qiskit/circuit/library/standard_gates/u1.py +490 -0
  139. qiskit/circuit/library/standard_gates/u2.py +145 -0
  140. qiskit/circuit/library/standard_gates/u3.py +428 -0
  141. qiskit/circuit/library/standard_gates/x.py +1481 -0
  142. qiskit/circuit/library/standard_gates/xx_minus_yy.py +202 -0
  143. qiskit/circuit/library/standard_gates/xx_plus_yy.py +236 -0
  144. qiskit/circuit/library/standard_gates/y.py +257 -0
  145. qiskit/circuit/library/standard_gates/z.py +338 -0
  146. qiskit/circuit/library/templates/__init__.py +92 -0
  147. qiskit/circuit/library/templates/clifford/__init__.py +33 -0
  148. qiskit/circuit/library/templates/clifford/clifford_2_1.py +34 -0
  149. qiskit/circuit/library/templates/clifford/clifford_2_2.py +35 -0
  150. qiskit/circuit/library/templates/clifford/clifford_2_3.py +34 -0
  151. qiskit/circuit/library/templates/clifford/clifford_2_4.py +34 -0
  152. qiskit/circuit/library/templates/clifford/clifford_3_1.py +35 -0
  153. qiskit/circuit/library/templates/clifford/clifford_4_1.py +38 -0
  154. qiskit/circuit/library/templates/clifford/clifford_4_2.py +37 -0
  155. qiskit/circuit/library/templates/clifford/clifford_4_3.py +38 -0
  156. qiskit/circuit/library/templates/clifford/clifford_4_4.py +37 -0
  157. qiskit/circuit/library/templates/clifford/clifford_5_1.py +40 -0
  158. qiskit/circuit/library/templates/clifford/clifford_6_1.py +40 -0
  159. qiskit/circuit/library/templates/clifford/clifford_6_2.py +40 -0
  160. qiskit/circuit/library/templates/clifford/clifford_6_3.py +40 -0
  161. qiskit/circuit/library/templates/clifford/clifford_6_4.py +38 -0
  162. qiskit/circuit/library/templates/clifford/clifford_6_5.py +40 -0
  163. qiskit/circuit/library/templates/clifford/clifford_8_1.py +42 -0
  164. qiskit/circuit/library/templates/clifford/clifford_8_2.py +42 -0
  165. qiskit/circuit/library/templates/clifford/clifford_8_3.py +41 -0
  166. qiskit/circuit/library/templates/nct/__init__.py +67 -0
  167. qiskit/circuit/library/templates/nct/template_nct_2a_1.py +34 -0
  168. qiskit/circuit/library/templates/nct/template_nct_2a_2.py +35 -0
  169. qiskit/circuit/library/templates/nct/template_nct_2a_3.py +37 -0
  170. qiskit/circuit/library/templates/nct/template_nct_4a_1.py +43 -0
  171. qiskit/circuit/library/templates/nct/template_nct_4a_2.py +41 -0
  172. qiskit/circuit/library/templates/nct/template_nct_4a_3.py +39 -0
  173. qiskit/circuit/library/templates/nct/template_nct_4b_1.py +41 -0
  174. qiskit/circuit/library/templates/nct/template_nct_4b_2.py +39 -0
  175. qiskit/circuit/library/templates/nct/template_nct_5a_1.py +40 -0
  176. qiskit/circuit/library/templates/nct/template_nct_5a_2.py +40 -0
  177. qiskit/circuit/library/templates/nct/template_nct_5a_3.py +40 -0
  178. qiskit/circuit/library/templates/nct/template_nct_5a_4.py +39 -0
  179. qiskit/circuit/library/templates/nct/template_nct_6a_1.py +40 -0
  180. qiskit/circuit/library/templates/nct/template_nct_6a_2.py +41 -0
  181. qiskit/circuit/library/templates/nct/template_nct_6a_3.py +41 -0
  182. qiskit/circuit/library/templates/nct/template_nct_6a_4.py +41 -0
  183. qiskit/circuit/library/templates/nct/template_nct_6b_1.py +41 -0
  184. qiskit/circuit/library/templates/nct/template_nct_6b_2.py +41 -0
  185. qiskit/circuit/library/templates/nct/template_nct_6c_1.py +41 -0
  186. qiskit/circuit/library/templates/nct/template_nct_7a_1.py +43 -0
  187. qiskit/circuit/library/templates/nct/template_nct_7b_1.py +43 -0
  188. qiskit/circuit/library/templates/nct/template_nct_7c_1.py +43 -0
  189. qiskit/circuit/library/templates/nct/template_nct_7d_1.py +43 -0
  190. qiskit/circuit/library/templates/nct/template_nct_7e_1.py +43 -0
  191. qiskit/circuit/library/templates/nct/template_nct_9a_1.py +45 -0
  192. qiskit/circuit/library/templates/nct/template_nct_9c_1.py +43 -0
  193. qiskit/circuit/library/templates/nct/template_nct_9c_10.py +44 -0
  194. qiskit/circuit/library/templates/nct/template_nct_9c_11.py +44 -0
  195. qiskit/circuit/library/templates/nct/template_nct_9c_12.py +44 -0
  196. qiskit/circuit/library/templates/nct/template_nct_9c_2.py +44 -0
  197. qiskit/circuit/library/templates/nct/template_nct_9c_3.py +44 -0
  198. qiskit/circuit/library/templates/nct/template_nct_9c_4.py +44 -0
  199. qiskit/circuit/library/templates/nct/template_nct_9c_5.py +44 -0
  200. qiskit/circuit/library/templates/nct/template_nct_9c_6.py +44 -0
  201. qiskit/circuit/library/templates/nct/template_nct_9c_7.py +44 -0
  202. qiskit/circuit/library/templates/nct/template_nct_9c_8.py +44 -0
  203. qiskit/circuit/library/templates/nct/template_nct_9c_9.py +44 -0
  204. qiskit/circuit/library/templates/nct/template_nct_9d_1.py +43 -0
  205. qiskit/circuit/library/templates/nct/template_nct_9d_10.py +44 -0
  206. qiskit/circuit/library/templates/nct/template_nct_9d_2.py +44 -0
  207. qiskit/circuit/library/templates/nct/template_nct_9d_3.py +44 -0
  208. qiskit/circuit/library/templates/nct/template_nct_9d_4.py +44 -0
  209. qiskit/circuit/library/templates/nct/template_nct_9d_5.py +44 -0
  210. qiskit/circuit/library/templates/nct/template_nct_9d_6.py +44 -0
  211. qiskit/circuit/library/templates/nct/template_nct_9d_7.py +44 -0
  212. qiskit/circuit/library/templates/nct/template_nct_9d_8.py +44 -0
  213. qiskit/circuit/library/templates/nct/template_nct_9d_9.py +44 -0
  214. qiskit/circuit/library/templates/rzx/__init__.py +25 -0
  215. qiskit/circuit/library/templates/rzx/rzx_cy.py +47 -0
  216. qiskit/circuit/library/templates/rzx/rzx_xz.py +54 -0
  217. qiskit/circuit/library/templates/rzx/rzx_yz.py +45 -0
  218. qiskit/circuit/library/templates/rzx/rzx_zz1.py +69 -0
  219. qiskit/circuit/library/templates/rzx/rzx_zz2.py +59 -0
  220. qiskit/circuit/library/templates/rzx/rzx_zz3.py +59 -0
  221. qiskit/circuit/measure.py +53 -0
  222. qiskit/circuit/operation.py +68 -0
  223. qiskit/circuit/parameter.py +179 -0
  224. qiskit/circuit/parameterexpression.py +703 -0
  225. qiskit/circuit/parametertable.py +119 -0
  226. qiskit/circuit/parametervector.py +140 -0
  227. qiskit/circuit/quantumcircuit.py +7540 -0
  228. qiskit/circuit/quantumcircuitdata.py +136 -0
  229. qiskit/circuit/random/__init__.py +15 -0
  230. qiskit/circuit/random/utils.py +366 -0
  231. qiskit/circuit/reset.py +37 -0
  232. qiskit/circuit/singleton.py +600 -0
  233. qiskit/circuit/store.py +89 -0
  234. qiskit/circuit/tools/__init__.py +16 -0
  235. qiskit/circuit/tools/pi_check.py +193 -0
  236. qiskit/circuit/twirling.py +145 -0
  237. qiskit/compiler/__init__.py +27 -0
  238. qiskit/compiler/transpiler.py +375 -0
  239. qiskit/converters/__init__.py +74 -0
  240. qiskit/converters/circuit_to_dag.py +80 -0
  241. qiskit/converters/circuit_to_dagdependency.py +49 -0
  242. qiskit/converters/circuit_to_dagdependency_v2.py +46 -0
  243. qiskit/converters/circuit_to_gate.py +107 -0
  244. qiskit/converters/circuit_to_instruction.py +142 -0
  245. qiskit/converters/dag_to_circuit.py +79 -0
  246. qiskit/converters/dag_to_dagdependency.py +54 -0
  247. qiskit/converters/dag_to_dagdependency_v2.py +43 -0
  248. qiskit/converters/dagdependency_to_circuit.py +40 -0
  249. qiskit/converters/dagdependency_to_dag.py +48 -0
  250. qiskit/dagcircuit/__init__.py +55 -0
  251. qiskit/dagcircuit/collect_blocks.py +407 -0
  252. qiskit/dagcircuit/dagcircuit.py +24 -0
  253. qiskit/dagcircuit/dagdependency.py +612 -0
  254. qiskit/dagcircuit/dagdependency_v2.py +566 -0
  255. qiskit/dagcircuit/dagdepnode.py +160 -0
  256. qiskit/dagcircuit/dagnode.py +188 -0
  257. qiskit/dagcircuit/exceptions.py +42 -0
  258. qiskit/exceptions.py +153 -0
  259. qiskit/passmanager/__init__.py +258 -0
  260. qiskit/passmanager/base_tasks.py +230 -0
  261. qiskit/passmanager/compilation_status.py +74 -0
  262. qiskit/passmanager/exceptions.py +19 -0
  263. qiskit/passmanager/flow_controllers.py +116 -0
  264. qiskit/passmanager/passmanager.py +353 -0
  265. qiskit/primitives/__init__.py +490 -0
  266. qiskit/primitives/backend_estimator_v2.py +530 -0
  267. qiskit/primitives/backend_sampler_v2.py +339 -0
  268. qiskit/primitives/base/__init__.py +20 -0
  269. qiskit/primitives/base/base_estimator.py +247 -0
  270. qiskit/primitives/base/base_primitive_job.py +78 -0
  271. qiskit/primitives/base/base_primitive_v1.py +45 -0
  272. qiskit/primitives/base/base_result_v1.py +65 -0
  273. qiskit/primitives/base/base_sampler.py +196 -0
  274. qiskit/primitives/base/estimator_result_v1.py +46 -0
  275. qiskit/primitives/base/sampler_result_v1.py +45 -0
  276. qiskit/primitives/base/validation_v1.py +250 -0
  277. qiskit/primitives/containers/__init__.py +26 -0
  278. qiskit/primitives/containers/bindings_array.py +391 -0
  279. qiskit/primitives/containers/bit_array.py +764 -0
  280. qiskit/primitives/containers/data_bin.py +175 -0
  281. qiskit/primitives/containers/estimator_pub.py +222 -0
  282. qiskit/primitives/containers/object_array.py +94 -0
  283. qiskit/primitives/containers/observables_array.py +296 -0
  284. qiskit/primitives/containers/primitive_result.py +53 -0
  285. qiskit/primitives/containers/pub_result.py +51 -0
  286. qiskit/primitives/containers/sampler_pub.py +193 -0
  287. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  288. qiskit/primitives/containers/shape.py +129 -0
  289. qiskit/primitives/primitive_job.py +81 -0
  290. qiskit/primitives/statevector_estimator.py +175 -0
  291. qiskit/primitives/statevector_sampler.py +290 -0
  292. qiskit/primitives/utils.py +72 -0
  293. qiskit/providers/__init__.py +677 -0
  294. qiskit/providers/backend.py +364 -0
  295. qiskit/providers/basic_provider/__init__.py +47 -0
  296. qiskit/providers/basic_provider/basic_provider.py +121 -0
  297. qiskit/providers/basic_provider/basic_provider_job.py +65 -0
  298. qiskit/providers/basic_provider/basic_provider_tools.py +218 -0
  299. qiskit/providers/basic_provider/basic_simulator.py +693 -0
  300. qiskit/providers/basic_provider/exceptions.py +30 -0
  301. qiskit/providers/exceptions.py +33 -0
  302. qiskit/providers/fake_provider/__init__.py +69 -0
  303. qiskit/providers/fake_provider/generic_backend_v2.py +374 -0
  304. qiskit/providers/fake_provider/utils/__init__.py +15 -0
  305. qiskit/providers/job.py +147 -0
  306. qiskit/providers/jobstatus.py +30 -0
  307. qiskit/providers/options.py +273 -0
  308. qiskit/providers/providerutils.py +110 -0
  309. qiskit/qasm/libs/dummy/stdgates.inc +75 -0
  310. qiskit/qasm/libs/qelib1.inc +266 -0
  311. qiskit/qasm/libs/stdgates.inc +82 -0
  312. qiskit/qasm2/__init__.py +669 -0
  313. qiskit/qasm2/exceptions.py +27 -0
  314. qiskit/qasm2/export.py +364 -0
  315. qiskit/qasm2/parse.py +438 -0
  316. qiskit/qasm3/__init__.py +372 -0
  317. qiskit/qasm3/ast.py +782 -0
  318. qiskit/qasm3/exceptions.py +27 -0
  319. qiskit/qasm3/experimental.py +70 -0
  320. qiskit/qasm3/exporter.py +1340 -0
  321. qiskit/qasm3/printer.py +608 -0
  322. qiskit/qpy/__init__.py +1965 -0
  323. qiskit/qpy/binary_io/__init__.py +35 -0
  324. qiskit/qpy/binary_io/circuits.py +1455 -0
  325. qiskit/qpy/binary_io/parse_sympy_repr.py +121 -0
  326. qiskit/qpy/binary_io/schedules.py +308 -0
  327. qiskit/qpy/binary_io/value.py +1165 -0
  328. qiskit/qpy/common.py +353 -0
  329. qiskit/qpy/exceptions.py +53 -0
  330. qiskit/qpy/formats.py +442 -0
  331. qiskit/qpy/interface.py +344 -0
  332. qiskit/qpy/type_keys.py +409 -0
  333. qiskit/quantum_info/__init__.py +162 -0
  334. qiskit/quantum_info/analysis/__init__.py +17 -0
  335. qiskit/quantum_info/analysis/average.py +47 -0
  336. qiskit/quantum_info/analysis/distance.py +104 -0
  337. qiskit/quantum_info/analysis/make_observable.py +44 -0
  338. qiskit/quantum_info/analysis/z2_symmetries.py +484 -0
  339. qiskit/quantum_info/operators/__init__.py +28 -0
  340. qiskit/quantum_info/operators/base_operator.py +145 -0
  341. qiskit/quantum_info/operators/channel/__init__.py +29 -0
  342. qiskit/quantum_info/operators/channel/chi.py +191 -0
  343. qiskit/quantum_info/operators/channel/choi.py +218 -0
  344. qiskit/quantum_info/operators/channel/kraus.py +337 -0
  345. qiskit/quantum_info/operators/channel/ptm.py +204 -0
  346. qiskit/quantum_info/operators/channel/quantum_channel.py +348 -0
  347. qiskit/quantum_info/operators/channel/stinespring.py +296 -0
  348. qiskit/quantum_info/operators/channel/superop.py +373 -0
  349. qiskit/quantum_info/operators/channel/transformations.py +490 -0
  350. qiskit/quantum_info/operators/custom_iterator.py +48 -0
  351. qiskit/quantum_info/operators/dihedral/__init__.py +18 -0
  352. qiskit/quantum_info/operators/dihedral/dihedral.py +511 -0
  353. qiskit/quantum_info/operators/dihedral/dihedral_circuits.py +216 -0
  354. qiskit/quantum_info/operators/dihedral/polynomial.py +313 -0
  355. qiskit/quantum_info/operators/dihedral/random.py +64 -0
  356. qiskit/quantum_info/operators/linear_op.py +25 -0
  357. qiskit/quantum_info/operators/measures.py +418 -0
  358. qiskit/quantum_info/operators/mixins/__init__.py +52 -0
  359. qiskit/quantum_info/operators/mixins/adjoint.py +52 -0
  360. qiskit/quantum_info/operators/mixins/group.py +171 -0
  361. qiskit/quantum_info/operators/mixins/linear.py +84 -0
  362. qiskit/quantum_info/operators/mixins/multiply.py +62 -0
  363. qiskit/quantum_info/operators/mixins/tolerances.py +72 -0
  364. qiskit/quantum_info/operators/op_shape.py +525 -0
  365. qiskit/quantum_info/operators/operator.py +869 -0
  366. qiskit/quantum_info/operators/operator_utils.py +76 -0
  367. qiskit/quantum_info/operators/predicates.py +183 -0
  368. qiskit/quantum_info/operators/random.py +154 -0
  369. qiskit/quantum_info/operators/scalar_op.py +254 -0
  370. qiskit/quantum_info/operators/symplectic/__init__.py +23 -0
  371. qiskit/quantum_info/operators/symplectic/base_pauli.py +719 -0
  372. qiskit/quantum_info/operators/symplectic/clifford.py +1032 -0
  373. qiskit/quantum_info/operators/symplectic/clifford_circuits.py +558 -0
  374. qiskit/quantum_info/operators/symplectic/pauli.py +755 -0
  375. qiskit/quantum_info/operators/symplectic/pauli_list.py +1242 -0
  376. qiskit/quantum_info/operators/symplectic/pauli_utils.py +40 -0
  377. qiskit/quantum_info/operators/symplectic/random.py +117 -0
  378. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +1239 -0
  379. qiskit/quantum_info/operators/utils/__init__.py +20 -0
  380. qiskit/quantum_info/operators/utils/anti_commutator.py +36 -0
  381. qiskit/quantum_info/operators/utils/commutator.py +36 -0
  382. qiskit/quantum_info/operators/utils/double_commutator.py +76 -0
  383. qiskit/quantum_info/quaternion.py +156 -0
  384. qiskit/quantum_info/random.py +26 -0
  385. qiskit/quantum_info/states/__init__.py +28 -0
  386. qiskit/quantum_info/states/densitymatrix.py +857 -0
  387. qiskit/quantum_info/states/measures.py +288 -0
  388. qiskit/quantum_info/states/quantum_state.py +503 -0
  389. qiskit/quantum_info/states/random.py +157 -0
  390. qiskit/quantum_info/states/stabilizerstate.py +805 -0
  391. qiskit/quantum_info/states/statevector.py +977 -0
  392. qiskit/quantum_info/states/utils.py +247 -0
  393. qiskit/result/__init__.py +61 -0
  394. qiskit/result/counts.py +189 -0
  395. qiskit/result/distributions/__init__.py +17 -0
  396. qiskit/result/distributions/probability.py +100 -0
  397. qiskit/result/distributions/quasi.py +154 -0
  398. qiskit/result/exceptions.py +40 -0
  399. qiskit/result/models.py +241 -0
  400. qiskit/result/postprocess.py +239 -0
  401. qiskit/result/result.py +385 -0
  402. qiskit/result/sampled_expval.py +74 -0
  403. qiskit/result/utils.py +294 -0
  404. qiskit/synthesis/__init__.py +240 -0
  405. qiskit/synthesis/arithmetic/__init__.py +18 -0
  406. qiskit/synthesis/arithmetic/adders/__init__.py +17 -0
  407. qiskit/synthesis/arithmetic/adders/cdkm_ripple_carry_adder.py +154 -0
  408. qiskit/synthesis/arithmetic/adders/draper_qft_adder.py +103 -0
  409. qiskit/synthesis/arithmetic/adders/vbe_ripple_carry_adder.py +161 -0
  410. qiskit/synthesis/arithmetic/comparators/__init__.py +16 -0
  411. qiskit/synthesis/arithmetic/comparators/compare_2s.py +112 -0
  412. qiskit/synthesis/arithmetic/comparators/compare_greedy.py +66 -0
  413. qiskit/synthesis/arithmetic/multipliers/__init__.py +16 -0
  414. qiskit/synthesis/arithmetic/multipliers/hrs_cumulative_multiplier.py +103 -0
  415. qiskit/synthesis/arithmetic/multipliers/rg_qft_multiplier.py +100 -0
  416. qiskit/synthesis/arithmetic/weighted_sum.py +155 -0
  417. qiskit/synthesis/boolean/__init__.py +13 -0
  418. qiskit/synthesis/boolean/boolean_expression.py +231 -0
  419. qiskit/synthesis/boolean/boolean_expression_synth.py +124 -0
  420. qiskit/synthesis/boolean/boolean_expression_visitor.py +96 -0
  421. qiskit/synthesis/clifford/__init__.py +19 -0
  422. qiskit/synthesis/clifford/clifford_decompose_ag.py +178 -0
  423. qiskit/synthesis/clifford/clifford_decompose_bm.py +46 -0
  424. qiskit/synthesis/clifford/clifford_decompose_full.py +64 -0
  425. qiskit/synthesis/clifford/clifford_decompose_greedy.py +58 -0
  426. qiskit/synthesis/clifford/clifford_decompose_layers.py +447 -0
  427. qiskit/synthesis/cnotdihedral/__init__.py +17 -0
  428. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_full.py +52 -0
  429. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_general.py +141 -0
  430. qiskit/synthesis/cnotdihedral/cnotdihedral_decompose_two_qubits.py +266 -0
  431. qiskit/synthesis/discrete_basis/__init__.py +16 -0
  432. qiskit/synthesis/discrete_basis/commutator_decompose.py +265 -0
  433. qiskit/synthesis/discrete_basis/gate_sequence.py +421 -0
  434. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +165 -0
  435. qiskit/synthesis/discrete_basis/solovay_kitaev.py +240 -0
  436. qiskit/synthesis/evolution/__init__.py +21 -0
  437. qiskit/synthesis/evolution/evolution_synthesis.py +48 -0
  438. qiskit/synthesis/evolution/lie_trotter.py +120 -0
  439. qiskit/synthesis/evolution/matrix_synthesis.py +47 -0
  440. qiskit/synthesis/evolution/pauli_network.py +80 -0
  441. qiskit/synthesis/evolution/product_formula.py +313 -0
  442. qiskit/synthesis/evolution/qdrift.py +130 -0
  443. qiskit/synthesis/evolution/suzuki_trotter.py +224 -0
  444. qiskit/synthesis/linear/__init__.py +26 -0
  445. qiskit/synthesis/linear/cnot_synth.py +69 -0
  446. qiskit/synthesis/linear/linear_circuits_utils.py +128 -0
  447. qiskit/synthesis/linear/linear_depth_lnn.py +61 -0
  448. qiskit/synthesis/linear/linear_matrix_utils.py +27 -0
  449. qiskit/synthesis/linear_phase/__init__.py +17 -0
  450. qiskit/synthesis/linear_phase/cnot_phase_synth.py +206 -0
  451. qiskit/synthesis/linear_phase/cx_cz_depth_lnn.py +61 -0
  452. qiskit/synthesis/linear_phase/cz_depth_lnn.py +58 -0
  453. qiskit/synthesis/multi_controlled/__init__.py +25 -0
  454. qiskit/synthesis/multi_controlled/mcmt_vchain.py +52 -0
  455. qiskit/synthesis/multi_controlled/mcx_synthesis.py +359 -0
  456. qiskit/synthesis/multi_controlled/multi_control_rotation_gates.py +206 -0
  457. qiskit/synthesis/one_qubit/__init__.py +15 -0
  458. qiskit/synthesis/one_qubit/one_qubit_decompose.py +288 -0
  459. qiskit/synthesis/permutation/__init__.py +18 -0
  460. qiskit/synthesis/permutation/permutation_full.py +78 -0
  461. qiskit/synthesis/permutation/permutation_lnn.py +54 -0
  462. qiskit/synthesis/permutation/permutation_reverse_lnn.py +93 -0
  463. qiskit/synthesis/permutation/permutation_utils.py +16 -0
  464. qiskit/synthesis/qft/__init__.py +16 -0
  465. qiskit/synthesis/qft/qft_decompose_full.py +97 -0
  466. qiskit/synthesis/qft/qft_decompose_lnn.py +79 -0
  467. qiskit/synthesis/stabilizer/__init__.py +16 -0
  468. qiskit/synthesis/stabilizer/stabilizer_circuit.py +149 -0
  469. qiskit/synthesis/stabilizer/stabilizer_decompose.py +194 -0
  470. qiskit/synthesis/two_qubit/__init__.py +20 -0
  471. qiskit/synthesis/two_qubit/local_invariance.py +63 -0
  472. qiskit/synthesis/two_qubit/two_qubit_decompose.py +583 -0
  473. qiskit/synthesis/two_qubit/xx_decompose/__init__.py +19 -0
  474. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +300 -0
  475. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +324 -0
  476. qiskit/synthesis/two_qubit/xx_decompose/embodiments.py +163 -0
  477. qiskit/synthesis/two_qubit/xx_decompose/paths.py +412 -0
  478. qiskit/synthesis/two_qubit/xx_decompose/polytopes.py +262 -0
  479. qiskit/synthesis/two_qubit/xx_decompose/utilities.py +40 -0
  480. qiskit/synthesis/two_qubit/xx_decompose/weyl.py +133 -0
  481. qiskit/synthesis/unitary/__init__.py +13 -0
  482. qiskit/synthesis/unitary/aqc/__init__.py +177 -0
  483. qiskit/synthesis/unitary/aqc/approximate.py +116 -0
  484. qiskit/synthesis/unitary/aqc/aqc.py +175 -0
  485. qiskit/synthesis/unitary/aqc/cnot_structures.py +300 -0
  486. qiskit/synthesis/unitary/aqc/cnot_unit_circuit.py +103 -0
  487. qiskit/synthesis/unitary/aqc/cnot_unit_objective.py +299 -0
  488. qiskit/synthesis/unitary/aqc/elementary_operations.py +108 -0
  489. qiskit/synthesis/unitary/aqc/fast_gradient/__init__.py +164 -0
  490. qiskit/synthesis/unitary/aqc/fast_gradient/fast_grad_utils.py +237 -0
  491. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +226 -0
  492. qiskit/synthesis/unitary/aqc/fast_gradient/layer.py +370 -0
  493. qiskit/synthesis/unitary/aqc/fast_gradient/pmatrix.py +312 -0
  494. qiskit/synthesis/unitary/qsd.py +288 -0
  495. qiskit/transpiler/__init__.py +1345 -0
  496. qiskit/transpiler/basepasses.py +190 -0
  497. qiskit/transpiler/coupling.py +500 -0
  498. qiskit/transpiler/exceptions.py +59 -0
  499. qiskit/transpiler/instruction_durations.py +281 -0
  500. qiskit/transpiler/layout.py +740 -0
  501. qiskit/transpiler/passes/__init__.py +276 -0
  502. qiskit/transpiler/passes/analysis/__init__.py +23 -0
  503. qiskit/transpiler/passes/analysis/count_ops.py +30 -0
  504. qiskit/transpiler/passes/analysis/count_ops_longest_path.py +26 -0
  505. qiskit/transpiler/passes/analysis/dag_longest_path.py +24 -0
  506. qiskit/transpiler/passes/analysis/depth.py +33 -0
  507. qiskit/transpiler/passes/analysis/num_qubits.py +26 -0
  508. qiskit/transpiler/passes/analysis/num_tensor_factors.py +26 -0
  509. qiskit/transpiler/passes/analysis/resource_estimation.py +41 -0
  510. qiskit/transpiler/passes/analysis/size.py +36 -0
  511. qiskit/transpiler/passes/analysis/width.py +27 -0
  512. qiskit/transpiler/passes/basis/__init__.py +19 -0
  513. qiskit/transpiler/passes/basis/basis_translator.py +138 -0
  514. qiskit/transpiler/passes/basis/decompose.py +137 -0
  515. qiskit/transpiler/passes/basis/translate_parameterized.py +175 -0
  516. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +84 -0
  517. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +110 -0
  518. qiskit/transpiler/passes/layout/__init__.py +26 -0
  519. qiskit/transpiler/passes/layout/_csp_custom_solver.py +65 -0
  520. qiskit/transpiler/passes/layout/apply_layout.py +128 -0
  521. qiskit/transpiler/passes/layout/csp_layout.py +132 -0
  522. qiskit/transpiler/passes/layout/dense_layout.py +177 -0
  523. qiskit/transpiler/passes/layout/disjoint_utils.py +219 -0
  524. qiskit/transpiler/passes/layout/enlarge_with_ancilla.py +49 -0
  525. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +116 -0
  526. qiskit/transpiler/passes/layout/layout_2q_distance.py +77 -0
  527. qiskit/transpiler/passes/layout/sabre_layout.py +506 -0
  528. qiskit/transpiler/passes/layout/sabre_pre_layout.py +225 -0
  529. qiskit/transpiler/passes/layout/set_layout.py +69 -0
  530. qiskit/transpiler/passes/layout/trivial_layout.py +66 -0
  531. qiskit/transpiler/passes/layout/vf2_layout.py +256 -0
  532. qiskit/transpiler/passes/layout/vf2_post_layout.py +376 -0
  533. qiskit/transpiler/passes/layout/vf2_utils.py +235 -0
  534. qiskit/transpiler/passes/optimization/__init__.py +42 -0
  535. qiskit/transpiler/passes/optimization/_gate_extension.py +80 -0
  536. qiskit/transpiler/passes/optimization/collect_1q_runs.py +31 -0
  537. qiskit/transpiler/passes/optimization/collect_2q_blocks.py +35 -0
  538. qiskit/transpiler/passes/optimization/collect_and_collapse.py +117 -0
  539. qiskit/transpiler/passes/optimization/collect_cliffords.py +109 -0
  540. qiskit/transpiler/passes/optimization/collect_linear_functions.py +85 -0
  541. qiskit/transpiler/passes/optimization/collect_multiqubit_blocks.py +242 -0
  542. qiskit/transpiler/passes/optimization/commutation_analysis.py +44 -0
  543. qiskit/transpiler/passes/optimization/commutative_cancellation.py +82 -0
  544. qiskit/transpiler/passes/optimization/commutative_inverse_cancellation.py +140 -0
  545. qiskit/transpiler/passes/optimization/consolidate_blocks.py +176 -0
  546. qiskit/transpiler/passes/optimization/contract_idle_wires_in_control_flow.py +104 -0
  547. qiskit/transpiler/passes/optimization/elide_permutations.py +91 -0
  548. qiskit/transpiler/passes/optimization/hoare_opt.py +420 -0
  549. qiskit/transpiler/passes/optimization/inverse_cancellation.py +95 -0
  550. qiskit/transpiler/passes/optimization/light_cone.py +135 -0
  551. qiskit/transpiler/passes/optimization/optimize_1q_commutation.py +267 -0
  552. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +250 -0
  553. qiskit/transpiler/passes/optimization/optimize_1q_gates.py +384 -0
  554. qiskit/transpiler/passes/optimization/optimize_annotated.py +449 -0
  555. qiskit/transpiler/passes/optimization/optimize_cliffords.py +89 -0
  556. qiskit/transpiler/passes/optimization/optimize_swap_before_measure.py +71 -0
  557. qiskit/transpiler/passes/optimization/remove_diagonal_gates_before_measure.py +41 -0
  558. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  559. qiskit/transpiler/passes/optimization/remove_identity_equiv.py +70 -0
  560. qiskit/transpiler/passes/optimization/remove_reset_in_zero_state.py +37 -0
  561. qiskit/transpiler/passes/optimization/reset_after_measure_simplification.py +50 -0
  562. qiskit/transpiler/passes/optimization/split_2q_unitaries.py +63 -0
  563. qiskit/transpiler/passes/optimization/template_matching/__init__.py +19 -0
  564. qiskit/transpiler/passes/optimization/template_matching/backward_match.py +749 -0
  565. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +452 -0
  566. qiskit/transpiler/passes/optimization/template_matching/maximal_matches.py +77 -0
  567. qiskit/transpiler/passes/optimization/template_matching/template_matching.py +370 -0
  568. qiskit/transpiler/passes/optimization/template_matching/template_substitution.py +639 -0
  569. qiskit/transpiler/passes/optimization/template_optimization.py +158 -0
  570. qiskit/transpiler/passes/routing/__init__.py +21 -0
  571. qiskit/transpiler/passes/routing/algorithms/__init__.py +33 -0
  572. qiskit/transpiler/passes/routing/algorithms/token_swapper.py +105 -0
  573. qiskit/transpiler/passes/routing/algorithms/types.py +46 -0
  574. qiskit/transpiler/passes/routing/algorithms/util.py +103 -0
  575. qiskit/transpiler/passes/routing/basic_swap.py +166 -0
  576. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/__init__.py +25 -0
  577. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_block.py +60 -0
  578. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +397 -0
  579. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/pauli_2q_evolution_commutation.py +145 -0
  580. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/swap_strategy.py +306 -0
  581. qiskit/transpiler/passes/routing/layout_transformation.py +119 -0
  582. qiskit/transpiler/passes/routing/lookahead_swap.py +390 -0
  583. qiskit/transpiler/passes/routing/sabre_swap.py +463 -0
  584. qiskit/transpiler/passes/routing/star_prerouting.py +408 -0
  585. qiskit/transpiler/passes/routing/utils.py +35 -0
  586. qiskit/transpiler/passes/scheduling/__init__.py +21 -0
  587. qiskit/transpiler/passes/scheduling/alignments/__init__.py +79 -0
  588. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +70 -0
  589. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +251 -0
  590. qiskit/transpiler/passes/scheduling/padding/__init__.py +16 -0
  591. qiskit/transpiler/passes/scheduling/padding/base_padding.py +284 -0
  592. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +415 -0
  593. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +90 -0
  594. qiskit/transpiler/passes/scheduling/scheduling/__init__.py +17 -0
  595. qiskit/transpiler/passes/scheduling/scheduling/alap.py +93 -0
  596. qiskit/transpiler/passes/scheduling/scheduling/asap.py +100 -0
  597. qiskit/transpiler/passes/scheduling/scheduling/base_scheduler.py +88 -0
  598. qiskit/transpiler/passes/scheduling/scheduling/set_io_latency.py +64 -0
  599. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +237 -0
  600. qiskit/transpiler/passes/synthesis/__init__.py +20 -0
  601. qiskit/transpiler/passes/synthesis/aqc_plugin.py +153 -0
  602. qiskit/transpiler/passes/synthesis/default_unitary_synth_plugin.py +653 -0
  603. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +429 -0
  604. qiskit/transpiler/passes/synthesis/hls_plugins.py +1963 -0
  605. qiskit/transpiler/passes/synthesis/linear_functions_synthesis.py +41 -0
  606. qiskit/transpiler/passes/synthesis/plugin.py +738 -0
  607. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +313 -0
  608. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +425 -0
  609. qiskit/transpiler/passes/utils/__init__.py +32 -0
  610. qiskit/transpiler/passes/utils/barrier_before_final_measurements.py +41 -0
  611. qiskit/transpiler/passes/utils/check_gate_direction.py +60 -0
  612. qiskit/transpiler/passes/utils/check_map.py +78 -0
  613. qiskit/transpiler/passes/utils/contains_instruction.py +45 -0
  614. qiskit/transpiler/passes/utils/control_flow.py +61 -0
  615. qiskit/transpiler/passes/utils/dag_fixed_point.py +36 -0
  616. qiskit/transpiler/passes/utils/error.py +69 -0
  617. qiskit/transpiler/passes/utils/filter_op_nodes.py +66 -0
  618. qiskit/transpiler/passes/utils/fixed_point.py +48 -0
  619. qiskit/transpiler/passes/utils/gate_direction.py +93 -0
  620. qiskit/transpiler/passes/utils/gates_basis.py +51 -0
  621. qiskit/transpiler/passes/utils/merge_adjacent_barriers.py +163 -0
  622. qiskit/transpiler/passes/utils/minimum_point.py +118 -0
  623. qiskit/transpiler/passes/utils/remove_barriers.py +50 -0
  624. qiskit/transpiler/passes/utils/remove_final_measurements.py +121 -0
  625. qiskit/transpiler/passes/utils/unroll_forloops.py +81 -0
  626. qiskit/transpiler/passmanager.py +503 -0
  627. qiskit/transpiler/passmanager_config.py +151 -0
  628. qiskit/transpiler/preset_passmanagers/__init__.py +93 -0
  629. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +993 -0
  630. qiskit/transpiler/preset_passmanagers/common.py +672 -0
  631. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +437 -0
  632. qiskit/transpiler/preset_passmanagers/level0.py +104 -0
  633. qiskit/transpiler/preset_passmanagers/level1.py +108 -0
  634. qiskit/transpiler/preset_passmanagers/level2.py +109 -0
  635. qiskit/transpiler/preset_passmanagers/level3.py +110 -0
  636. qiskit/transpiler/preset_passmanagers/plugin.py +346 -0
  637. qiskit/transpiler/target.py +905 -0
  638. qiskit/transpiler/timing_constraints.py +59 -0
  639. qiskit/user_config.py +266 -0
  640. qiskit/utils/__init__.py +90 -0
  641. qiskit/utils/classtools.py +146 -0
  642. qiskit/utils/deprecation.py +382 -0
  643. qiskit/utils/lazy_tester.py +363 -0
  644. qiskit/utils/optionals.py +354 -0
  645. qiskit/utils/parallel.py +318 -0
  646. qiskit/utils/units.py +146 -0
  647. qiskit/version.py +84 -0
  648. qiskit/visualization/__init__.py +290 -0
  649. qiskit/visualization/array.py +207 -0
  650. qiskit/visualization/bloch.py +778 -0
  651. qiskit/visualization/circuit/__init__.py +15 -0
  652. qiskit/visualization/circuit/_utils.py +675 -0
  653. qiskit/visualization/circuit/circuit_visualization.py +735 -0
  654. qiskit/visualization/circuit/latex.py +661 -0
  655. qiskit/visualization/circuit/matplotlib.py +2019 -0
  656. qiskit/visualization/circuit/qcstyle.py +278 -0
  657. qiskit/visualization/circuit/styles/__init__.py +13 -0
  658. qiskit/visualization/circuit/styles/bw.json +202 -0
  659. qiskit/visualization/circuit/styles/clifford.json +202 -0
  660. qiskit/visualization/circuit/styles/iqp-dark.json +214 -0
  661. qiskit/visualization/circuit/styles/iqp.json +214 -0
  662. qiskit/visualization/circuit/styles/textbook.json +202 -0
  663. qiskit/visualization/circuit/text.py +1849 -0
  664. qiskit/visualization/circuit_visualization.py +19 -0
  665. qiskit/visualization/counts_visualization.py +487 -0
  666. qiskit/visualization/dag_visualization.py +318 -0
  667. qiskit/visualization/exceptions.py +21 -0
  668. qiskit/visualization/gate_map.py +1424 -0
  669. qiskit/visualization/library.py +40 -0
  670. qiskit/visualization/pass_manager_visualization.py +312 -0
  671. qiskit/visualization/state_visualization.py +1546 -0
  672. qiskit/visualization/timeline/__init__.py +21 -0
  673. qiskit/visualization/timeline/core.py +495 -0
  674. qiskit/visualization/timeline/drawings.py +260 -0
  675. qiskit/visualization/timeline/generators.py +506 -0
  676. qiskit/visualization/timeline/interface.py +444 -0
  677. qiskit/visualization/timeline/layouts.py +115 -0
  678. qiskit/visualization/timeline/plotters/__init__.py +16 -0
  679. qiskit/visualization/timeline/plotters/base_plotter.py +58 -0
  680. qiskit/visualization/timeline/plotters/matplotlib.py +195 -0
  681. qiskit/visualization/timeline/stylesheet.py +301 -0
  682. qiskit/visualization/timeline/types.py +148 -0
  683. qiskit/visualization/transition_visualization.py +369 -0
  684. qiskit/visualization/utils.py +49 -0
  685. qiskit-2.0.3.dist-info/METADATA +220 -0
  686. qiskit-2.0.3.dist-info/RECORD +690 -0
  687. qiskit-2.0.3.dist-info/WHEEL +6 -0
  688. qiskit-2.0.3.dist-info/entry_points.txt +82 -0
  689. qiskit-2.0.3.dist-info/licenses/LICENSE.txt +203 -0
  690. qiskit-2.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1963 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2022, 2023.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+
13
+
14
+ """
15
+
16
+ High Level Synthesis Plugins
17
+ -----------------------------
18
+
19
+ Clifford Synthesis
20
+ ''''''''''''''''''
21
+
22
+ .. list-table:: Plugins for :class:`qiskit.quantum_info.Clifford` (key = ``"clifford"``)
23
+ :header-rows: 1
24
+
25
+ * - Plugin name
26
+ - Plugin class
27
+ - Targeted connectivity
28
+ - Description
29
+ * - ``"ag"``
30
+ - :class:`~.AGSynthesisClifford`
31
+ - all-to-all
32
+ - greedily optimizes CX-count
33
+ * - ``"bm"``
34
+ - :class:`~.BMSynthesisClifford`
35
+ - all-to-all
36
+ - optimal count for `n=2,3`; used in ``"default"`` for `n=2,3`
37
+ * - ``"greedy"``
38
+ - :class:`~.GreedySynthesisClifford`
39
+ - all-to-all
40
+ - greedily optimizes CX-count; used in ``"default"`` for `n>=4`
41
+ * - ``"layers"``
42
+ - :class:`~.LayerSynthesisClifford`
43
+ - all-to-all
44
+ -
45
+ * - ``"lnn"``
46
+ - :class:`~.LayerLnnSynthesisClifford`
47
+ - linear
48
+ - many CX-gates but guarantees CX-depth of at most `7*n+2`
49
+ * - ``"default"``
50
+ - :class:`~.DefaultSynthesisClifford`
51
+ - all-to-all
52
+ - usually best for optimizing CX-count (and optimal CX-count for `n=2,3`)
53
+
54
+ .. autosummary::
55
+ :toctree: ../stubs/
56
+
57
+ AGSynthesisClifford
58
+ BMSynthesisClifford
59
+ GreedySynthesisClifford
60
+ LayerSynthesisClifford
61
+ LayerLnnSynthesisClifford
62
+ DefaultSynthesisClifford
63
+
64
+
65
+ Linear Function Synthesis
66
+ '''''''''''''''''''''''''
67
+
68
+ .. list-table:: Plugins for :class:`.LinearFunction` (key = ``"linear"``)
69
+ :header-rows: 1
70
+
71
+ * - Plugin name
72
+ - Plugin class
73
+ - Targeted connectivity
74
+ - Description
75
+ * - ``"kms"``
76
+ - :class:`~.KMSSynthesisLinearFunction`
77
+ - linear
78
+ - many CX-gates but guarantees CX-depth of at most `5*n`
79
+ * - ``"pmh"``
80
+ - :class:`~.PMHSynthesisLinearFunction`
81
+ - all-to-all
82
+ - greedily optimizes CX-count; used in ``"default"``
83
+ * - ``"default"``
84
+ - :class:`~.DefaultSynthesisLinearFunction`
85
+ - all-to-all
86
+ - best for optimizing CX-count
87
+
88
+ .. autosummary::
89
+ :toctree: ../stubs/
90
+
91
+ KMSSynthesisLinearFunction
92
+ PMHSynthesisLinearFunction
93
+ DefaultSynthesisLinearFunction
94
+
95
+
96
+ Permutation Synthesis
97
+ '''''''''''''''''''''
98
+
99
+ .. list-table:: Plugins for :class:`.PermutationGate` (key = ``"permutation"``)
100
+ :header-rows: 1
101
+
102
+ * - Plugin name
103
+ - Plugin class
104
+ - Targeted connectivity
105
+ - Description
106
+ * - ``"basic"``
107
+ - :class:`~.BasicSynthesisPermutation`
108
+ - all-to-all
109
+ - optimal SWAP-count; used in ``"default"``
110
+ * - ``"acg"``
111
+ - :class:`~.ACGSynthesisPermutation`
112
+ - all-to-all
113
+ - guarantees SWAP-depth of at most `2`
114
+ * - ``"kms"``
115
+ - :class:`~.KMSSynthesisPermutation`
116
+ - linear
117
+ - many SWAP-gates, but guarantees SWAP-depth of at most `n`
118
+ * - ``"token_swapper"``
119
+ - :class:`~.TokenSwapperSynthesisPermutation`
120
+ - any
121
+ - greedily optimizes SWAP-count for arbitrary connectivity
122
+ * - ``"default"``
123
+ - :class:`~.BasicSynthesisPermutation`
124
+ - all-to-all
125
+ - best for optimizing SWAP-count
126
+
127
+ .. autosummary::
128
+ :toctree: ../stubs/
129
+
130
+ BasicSynthesisPermutation
131
+ ACGSynthesisPermutation
132
+ KMSSynthesisPermutation
133
+ TokenSwapperSynthesisPermutation
134
+
135
+
136
+ QFT Synthesis
137
+ '''''''''''''
138
+
139
+ .. list-table:: Plugins for :class:`.QFTGate` (key = ``"qft"``)
140
+ :header-rows: 1
141
+
142
+ * - Plugin name
143
+ - Plugin class
144
+ - Targeted connectivity
145
+ * - ``"full"``
146
+ - :class:`~.QFTSynthesisFull`
147
+ - all-to-all
148
+ * - ``"line"``
149
+ - :class:`~.QFTSynthesisLine`
150
+ - linear
151
+ * - ``"default"``
152
+ - :class:`~.QFTSynthesisFull`
153
+ - all-to-all
154
+
155
+ .. autosummary::
156
+ :toctree: ../stubs/
157
+
158
+ QFTSynthesisFull
159
+ QFTSynthesisLine
160
+
161
+
162
+ MCX Synthesis
163
+ '''''''''''''
164
+
165
+ The following table lists synthesis plugins available for an :class:`.MCXGate` gate
166
+ with `k` control qubits. If the available number of clean/dirty auxiliary qubits is
167
+ not sufficient, the corresponding synthesis method will return `None`.
168
+
169
+ .. list-table:: Plugins for :class:`.MCXGate` (key = ``"mcx"``)
170
+ :header-rows: 1
171
+
172
+ * - Plugin name
173
+ - Plugin class
174
+ - Number of clean ancillas
175
+ - Number of dirty ancillas
176
+ - Description
177
+ * - ``"gray_code"``
178
+ - :class:`~.MCXSynthesisGrayCode`
179
+ - `0`
180
+ - `0`
181
+ - exponentially many CX gates; use only for small values of `k`
182
+ * - ``"noaux_v24"``
183
+ - :class:`~.MCXSynthesisNoAuxV24`
184
+ - `0`
185
+ - `0`
186
+ - quadratic number of CX gates; use instead of ``"gray_code"`` for large values of `k`
187
+ * - ``"n_clean_m15"``
188
+ - :class:`~.MCXSynthesisNCleanM15`
189
+ - `k-2`
190
+ - `0`
191
+ - at most `6*k-6` CX gates
192
+ * - ``"n_dirty_i15"``
193
+ - :class:`~.MCXSynthesisNDirtyI15`
194
+ - `0`
195
+ - `k-2`
196
+ - at most `8*k-6` CX gates
197
+ * - ``"1_clean_b95"``
198
+ - :class:`~.MCXSynthesis1CleanB95`
199
+ - `1`
200
+ - `0`
201
+ - at most `16*k-8` CX gates
202
+ * - ``"default"``
203
+ - :class:`~.MCXSynthesisDefault`
204
+ - any
205
+ - any
206
+ - chooses the best algorithm based on the ancillas available
207
+
208
+ .. autosummary::
209
+ :toctree: ../stubs/
210
+
211
+ MCXSynthesisGrayCode
212
+ MCXSynthesisNoAuxV24
213
+ MCXSynthesisNCleanM15
214
+ MCXSynthesisNDirtyI15
215
+ MCXSynthesis1CleanB95
216
+ MCXSynthesisDefault
217
+
218
+
219
+ MCMT Synthesis
220
+ ''''''''''''''
221
+
222
+ .. list-table:: Plugins for :class:`.MCMTGate` (key = ``"mcmt"``)
223
+ :header-rows: 1
224
+
225
+ * - Plugin name
226
+ - Plugin class
227
+ - Number of clean ancillas
228
+ - Number of dirty ancillas
229
+ - Description
230
+ * - ``"vchain"``
231
+ - :class:`.MCMTSynthesisVChain`
232
+ - `k-1`
233
+ - `0`
234
+ - uses a linear number of Toffoli gates
235
+ * - ``"noaux"``
236
+ - :class:`~.MCMTSynthesisNoAux`
237
+ - `0`
238
+ - `0`
239
+ - uses Qiskit's standard control mechanism
240
+ * - ``"default"``
241
+ - :class:`~.MCMTSynthesisDefault`
242
+ - any
243
+ - any
244
+ - chooses the best algorithm based on the ancillas available
245
+
246
+ .. autosummary::
247
+ :toctree: ../stubs/
248
+
249
+ MCMTSynthesisVChain
250
+ MCMTSynthesisNoAux
251
+ MCMTSynthesisDefault
252
+
253
+
254
+ Integer comparators
255
+ '''''''''''''''''''
256
+
257
+ .. list-table:: Plugins for :class:`.IntegerComparatorGate` (key = ``"IntComp"``)
258
+ :header-rows: 1
259
+
260
+ * - Plugin name
261
+ - Plugin class
262
+ - Description
263
+ - Auxiliary qubits
264
+ * - ``"twos"``
265
+ - :class:`~.IntComparatorSynthesis2s`
266
+ - use addition with two's complement
267
+ - ``n - 1`` clean
268
+ * - ``"noaux"``
269
+ - :class:`~.IntComparatorSynthesisNoAux`
270
+ - flip the target controlled on all :math:`O(2^l)` allowed integer values
271
+ - none
272
+ * - ``"default"``
273
+ - :class:`~.IntComparatorSynthesisDefault`
274
+ - use the best algorithm depending on the available auxiliary qubits
275
+ - any
276
+
277
+ .. autosummary::
278
+ :toctree: ../stubs/
279
+
280
+ IntComparatorSynthesis2s
281
+ IntComparatorSynthesisNoAux
282
+ IntComparatorSynthesisDefault
283
+
284
+
285
+ Sums
286
+ ''''
287
+
288
+ .. list-table:: Plugins for :class:`.WeightedSumGate` (key = ``"WeightedSum"``)
289
+ :header-rows: 1
290
+
291
+ * - Plugin name
292
+ - Plugin class
293
+ - Description
294
+ - Auxiliary qubits
295
+ * - ``"default"``
296
+ - :class:`.WeightedSumSynthesisDefault`
297
+ - use a V-chain based synthesis
298
+ - given ``s`` sum qubits, used ``s - 1 + int(s > 2)`` clean auxiliary qubits
299
+
300
+ .. autosummary::
301
+ :toctree: ../stubs/
302
+
303
+ WeightedSumSynthesisDefault
304
+
305
+
306
+ Pauli Evolution Synthesis
307
+ '''''''''''''''''''''''''
308
+
309
+ .. list-table:: Plugins for :class:`.PauliEvolutionGate` (key = ``"PauliEvolution"``)
310
+ :header-rows: 1
311
+
312
+ * - Plugin name
313
+ - Plugin class
314
+ - Description
315
+ - Targeted connectivity
316
+ * - ``"rustiq"``
317
+ - :class:`~.PauliEvolutionSynthesisRustiq`
318
+ - use the synthesis method from `Rustiq circuit synthesis library
319
+ <https://github.com/smartiel/rustiq-core>`_
320
+ - all-to-all
321
+ * - ``"default"``
322
+ - :class:`~.PauliEvolutionSynthesisDefault`
323
+ - use a diagonalizing Clifford per Pauli term
324
+ - all-to-all
325
+
326
+ .. autosummary::
327
+ :toctree: ../stubs/
328
+
329
+ PauliEvolutionSynthesisDefault
330
+ PauliEvolutionSynthesisRustiq
331
+
332
+
333
+ Modular Adder Synthesis
334
+ '''''''''''''''''''''''
335
+
336
+ .. list-table:: Plugins for :class:`.ModularAdderGate` (key = ``"ModularAdder"``)
337
+ :header-rows: 1
338
+
339
+ * - Plugin name
340
+ - Plugin class
341
+ - Number of clean ancillas
342
+ - Description
343
+ * - ``"ripple_cdkm"``
344
+ - :class:`.ModularAdderSynthesisC04`
345
+ - 1
346
+ - a ripple-carry adder
347
+ * - ``"ripple_vbe"``
348
+ - :class:`.ModularAdderSynthesisV95`
349
+ - :math:`n-1`, for :math:`n`-bit numbers
350
+ - a ripple-carry adder
351
+ * - ``"qft"``
352
+ - :class:`.ModularAdderSynthesisD00`
353
+ - 0
354
+ - a QFT-based adder
355
+ * - ``"default"``
356
+ - :class:`~.ModularAdderSynthesisDefault`
357
+ - any
358
+ - chooses the best algorithm based on the ancillas available
359
+
360
+ .. autosummary::
361
+ :toctree: ../stubs/
362
+
363
+ ModularAdderSynthesisC04
364
+ ModularAdderSynthesisD00
365
+ ModularAdderSynthesisV95
366
+ ModularAdderSynthesisDefault
367
+
368
+ Half Adder Synthesis
369
+ ''''''''''''''''''''
370
+
371
+ .. list-table:: Plugins for :class:`.HalfAdderGate` (key = ``"HalfAdder"``)
372
+ :header-rows: 1
373
+
374
+ * - Plugin name
375
+ - Plugin class
376
+ - Number of clean ancillas
377
+ - Description
378
+ * - ``"ripple_cdkm"``
379
+ - :class:`.HalfAdderSynthesisC04`
380
+ - 1
381
+ - a ripple-carry adder
382
+ * - ``"ripple_vbe"``
383
+ - :class:`.HalfAdderSynthesisV95`
384
+ - :math:`n-1`, for :math:`n`-bit numbers
385
+ - a ripple-carry adder
386
+ * - ``"qft"``
387
+ - :class:`.HalfAdderSynthesisD00`
388
+ - 0
389
+ - a QFT-based adder
390
+ * - ``"default"``
391
+ - :class:`~.HalfAdderSynthesisDefault`
392
+ - any
393
+ - chooses the best algorithm based on the ancillas available
394
+
395
+ .. autosummary::
396
+ :toctree: ../stubs/
397
+
398
+ HalfAdderSynthesisC04
399
+ HalfAdderSynthesisD00
400
+ HalfAdderSynthesisV95
401
+ HalfAdderSynthesisDefault
402
+
403
+ Full Adder Synthesis
404
+ ''''''''''''''''''''
405
+
406
+ .. list-table:: Plugins for :class:`.FullAdderGate` (key = ``"FullAdder"``)
407
+ :header-rows: 1
408
+
409
+ * - Plugin name
410
+ - Plugin class
411
+ - Number of clean ancillas
412
+ - Description
413
+ * - ``"ripple_cdkm"``
414
+ - :class:`.FullAdderSynthesisC04`
415
+ - 0
416
+ - a ripple-carry adder
417
+ * - ``"ripple_vbe"``
418
+ - :class:`.FullAdderSynthesisV95`
419
+ - :math:`n-1`, for :math:`n`-bit numbers
420
+ - a ripple-carry adder
421
+ * - ``"default"``
422
+ - :class:`~.FullAdderSynthesisDefault`
423
+ - any
424
+ - chooses the best algorithm based on the ancillas available
425
+
426
+ .. autosummary::
427
+ :toctree: ../stubs/
428
+
429
+ FullAdderSynthesisC04
430
+ FullAdderSynthesisV95
431
+ FullAdderSynthesisDefault
432
+
433
+
434
+ Multiplier Synthesis
435
+ ''''''''''''''''''''
436
+
437
+ .. list-table:: Plugins for :class:`.MultiplierGate` (key = ``"Multiplier"``)
438
+ :header-rows: 1
439
+
440
+ * - Plugin name
441
+ - Plugin class
442
+ - Number of clean ancillas
443
+ - Description
444
+ * - ``"cumulative"``
445
+ - :class:`.MultiplierSynthesisH18`
446
+ - depending on the :class:`.AdderGate` used
447
+ - a cumulative adder based on controlled adders
448
+ * - ``"qft"``
449
+ - :class:`.MultiplierSynthesisR17`
450
+ - 0
451
+ - a QFT-based multiplier
452
+
453
+ .. autosummary::
454
+ :toctree: ../stubs/
455
+
456
+ MultiplierSynthesisH18
457
+ MultiplierSynthesisR17
458
+
459
+ """
460
+
461
+ from __future__ import annotations
462
+
463
+ import warnings
464
+ import numpy as np
465
+ import rustworkx as rx
466
+
467
+ from qiskit.circuit.quantumcircuit import QuantumCircuit
468
+ from qiskit.circuit.operation import Operation
469
+ from qiskit.circuit.library import (
470
+ LinearFunction,
471
+ QFTGate,
472
+ MCXGate,
473
+ C3XGate,
474
+ C4XGate,
475
+ PauliEvolutionGate,
476
+ PermutationGate,
477
+ MCMTGate,
478
+ ModularAdderGate,
479
+ HalfAdderGate,
480
+ FullAdderGate,
481
+ MultiplierGate,
482
+ WeightedSumGate,
483
+ GlobalPhaseGate,
484
+ )
485
+ from qiskit.circuit.annotated_operation import (
486
+ AnnotatedOperation,
487
+ Modifier,
488
+ ControlModifier,
489
+ InverseModifier,
490
+ PowerModifier,
491
+ )
492
+ from qiskit.transpiler.coupling import CouplingMap
493
+
494
+ from qiskit.synthesis.arithmetic import (
495
+ synth_integer_comparator_2s,
496
+ synth_integer_comparator_greedy,
497
+ synth_weighted_sum_carry,
498
+ )
499
+ from qiskit.synthesis.clifford import (
500
+ synth_clifford_full,
501
+ synth_clifford_layers,
502
+ synth_clifford_depth_lnn,
503
+ synth_clifford_greedy,
504
+ synth_clifford_ag,
505
+ synth_clifford_bm,
506
+ )
507
+ from qiskit.synthesis.linear import (
508
+ synth_cnot_count_full_pmh,
509
+ synth_cnot_depth_line_kms,
510
+ calc_inverse_matrix,
511
+ )
512
+ from qiskit.synthesis.linear.linear_circuits_utils import transpose_cx_circ
513
+ from qiskit.synthesis.permutation import (
514
+ synth_permutation_basic,
515
+ synth_permutation_acg,
516
+ synth_permutation_depth_lnn_kms,
517
+ )
518
+ from qiskit.synthesis.qft import (
519
+ synth_qft_full,
520
+ synth_qft_line,
521
+ )
522
+ from qiskit.synthesis.multi_controlled import (
523
+ synth_mcx_n_dirty_i15,
524
+ synth_mcx_n_clean_m15,
525
+ synth_mcx_1_clean_b95,
526
+ synth_mcx_gray_code,
527
+ synth_mcx_noaux_v24,
528
+ synth_mcmt_vchain,
529
+ )
530
+ from qiskit.synthesis.evolution import ProductFormula, synth_pauli_network_rustiq
531
+ from qiskit.synthesis.arithmetic import (
532
+ adder_ripple_c04,
533
+ adder_qft_d00,
534
+ adder_ripple_v95,
535
+ multiplier_qft_r17,
536
+ multiplier_cumulative_h18,
537
+ )
538
+ from qiskit.quantum_info.operators import Clifford
539
+ from qiskit.transpiler.passes.routing.algorithms import ApproximateTokenSwapper
540
+ from qiskit.transpiler.exceptions import TranspilerError
541
+
542
+ from qiskit._accelerate.high_level_synthesis import synthesize_operation
543
+ from .plugin import HighLevelSynthesisPlugin
544
+
545
+
546
+ class DefaultSynthesisClifford(HighLevelSynthesisPlugin):
547
+ """The default clifford synthesis plugin.
548
+
549
+ For N <= 3 qubits this is the optimal CX cost decomposition by Bravyi, Maslov.
550
+ For N > 3 qubits this is done using the general non-optimal greedy compilation
551
+ routine from reference by Bravyi, Hu, Maslov, Shaydulin.
552
+
553
+ This plugin name is :``clifford.default`` which can be used as the key on
554
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
555
+ """
556
+
557
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
558
+ """Run synthesis for the given Clifford."""
559
+ if not isinstance(high_level_object, Clifford):
560
+ return None
561
+
562
+ decomposition = synth_clifford_full(high_level_object)
563
+ return decomposition
564
+
565
+
566
+ class AGSynthesisClifford(HighLevelSynthesisPlugin):
567
+ """Clifford synthesis plugin based on the Aaronson-Gottesman method.
568
+
569
+ This plugin name is :``clifford.ag`` which can be used as the key on
570
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
571
+ """
572
+
573
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
574
+ """Run synthesis for the given Clifford."""
575
+ if not isinstance(high_level_object, Clifford):
576
+ return None
577
+
578
+ decomposition = synth_clifford_ag(high_level_object)
579
+ return decomposition
580
+
581
+
582
+ class BMSynthesisClifford(HighLevelSynthesisPlugin):
583
+ """Clifford synthesis plugin based on the Bravyi-Maslov method.
584
+
585
+ The method only works on Cliffords with at most 3 qubits, for which it
586
+ constructs the optimal CX cost decomposition.
587
+
588
+ This plugin name is :``clifford.bm`` which can be used as the key on
589
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
590
+ """
591
+
592
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
593
+ """Run synthesis for the given Clifford."""
594
+ if not isinstance(high_level_object, Clifford):
595
+ return None
596
+
597
+ if high_level_object.num_qubits <= 3:
598
+ decomposition = synth_clifford_bm(high_level_object)
599
+ else:
600
+ decomposition = None
601
+
602
+ return decomposition
603
+
604
+
605
+ class GreedySynthesisClifford(HighLevelSynthesisPlugin):
606
+ """Clifford synthesis plugin based on the greedy synthesis
607
+ Bravyi-Hu-Maslov-Shaydulin method.
608
+
609
+ This plugin name is :``clifford.greedy`` which can be used as the key on
610
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
611
+ """
612
+
613
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
614
+ """Run synthesis for the given Clifford."""
615
+ if not isinstance(high_level_object, Clifford):
616
+ return None
617
+
618
+ decomposition = synth_clifford_greedy(high_level_object)
619
+ return decomposition
620
+
621
+
622
+ class LayerSynthesisClifford(HighLevelSynthesisPlugin):
623
+ """Clifford synthesis plugin based on the Bravyi-Maslov method
624
+ to synthesize Cliffords into layers.
625
+
626
+ This plugin name is :``clifford.layers`` which can be used as the key on
627
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
628
+ """
629
+
630
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
631
+ """Run synthesis for the given Clifford."""
632
+ if not isinstance(high_level_object, Clifford):
633
+ return None
634
+
635
+ decomposition = synth_clifford_layers(high_level_object)
636
+ return decomposition
637
+
638
+
639
+ class LayerLnnSynthesisClifford(HighLevelSynthesisPlugin):
640
+ """Clifford synthesis plugin based on the Bravyi-Maslov method
641
+ to synthesize Cliffords into layers, with each layer synthesized
642
+ adhering to LNN connectivity.
643
+
644
+ This plugin name is :``clifford.lnn`` which can be used as the key on
645
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
646
+ """
647
+
648
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
649
+ """Run synthesis for the given Clifford."""
650
+ if not isinstance(high_level_object, Clifford):
651
+ return None
652
+
653
+ decomposition = synth_clifford_depth_lnn(high_level_object)
654
+ return decomposition
655
+
656
+
657
+ class DefaultSynthesisLinearFunction(HighLevelSynthesisPlugin):
658
+ """The default linear function synthesis plugin.
659
+
660
+ This plugin name is :``linear_function.default`` which can be used as the key on
661
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
662
+ """
663
+
664
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
665
+ """Run synthesis for the given LinearFunction."""
666
+ if not isinstance(high_level_object, LinearFunction):
667
+ return None
668
+
669
+ decomposition = synth_cnot_count_full_pmh(high_level_object.linear)
670
+ return decomposition
671
+
672
+
673
+ class KMSSynthesisLinearFunction(HighLevelSynthesisPlugin):
674
+ """Linear function synthesis plugin based on the Kutin-Moulton-Smithline method.
675
+
676
+ This plugin name is :``linear_function.kms`` which can be used as the key on
677
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
678
+
679
+ The plugin supports the following plugin-specific options:
680
+
681
+ * use_inverted: Indicates whether to run the algorithm on the inverse matrix
682
+ and to invert the synthesized circuit.
683
+ In certain cases this provides a better decomposition than the direct approach.
684
+ * use_transposed: Indicates whether to run the algorithm on the transposed matrix
685
+ and to invert the order of CX gates in the synthesized circuit.
686
+ In certain cases this provides a better decomposition than the direct approach.
687
+
688
+ """
689
+
690
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
691
+ """Run synthesis for the given LinearFunction."""
692
+ if not isinstance(high_level_object, LinearFunction):
693
+ return None
694
+
695
+ use_inverted = options.get("use_inverted", False)
696
+ use_transposed = options.get("use_transposed", False)
697
+
698
+ mat = high_level_object.linear.astype(bool, copy=False)
699
+
700
+ if use_transposed:
701
+ mat = np.transpose(mat)
702
+ if use_inverted:
703
+ mat = calc_inverse_matrix(mat)
704
+
705
+ decomposition = synth_cnot_depth_line_kms(mat)
706
+
707
+ if use_transposed:
708
+ decomposition = transpose_cx_circ(decomposition)
709
+ if use_inverted:
710
+ decomposition = decomposition.inverse()
711
+
712
+ return decomposition
713
+
714
+
715
+ class PMHSynthesisLinearFunction(HighLevelSynthesisPlugin):
716
+ """Linear function synthesis plugin based on the Patel-Markov-Hayes method.
717
+
718
+ This plugin name is :``linear_function.pmh`` which can be used as the key on
719
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
720
+
721
+ The plugin supports the following plugin-specific options:
722
+
723
+ * section size: The size of each section used in the Patel–Markov–Hayes algorithm [1].
724
+ * use_inverted: Indicates whether to run the algorithm on the inverse matrix
725
+ and to invert the synthesized circuit.
726
+ In certain cases this provides a better decomposition than the direct approach.
727
+ * use_transposed: Indicates whether to run the algorithm on the transposed matrix
728
+ and to invert the order of CX gates in the synthesized circuit.
729
+ In certain cases this provides a better decomposition than the direct approach.
730
+
731
+ References:
732
+ 1. Patel, Ketan N., Igor L. Markov, and John P. Hayes,
733
+ *Optimal synthesis of linear reversible circuits*,
734
+ Quantum Information & Computation 8.3 (2008): 282-294.
735
+ `arXiv:quant-ph/0302002 [quant-ph] <https://arxiv.org/abs/quant-ph/0302002>`_
736
+ """
737
+
738
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
739
+ """Run synthesis for the given LinearFunction."""
740
+ if not isinstance(high_level_object, LinearFunction):
741
+ return None
742
+
743
+ section_size = options.get("section_size", 2)
744
+ use_inverted = options.get("use_inverted", False)
745
+ use_transposed = options.get("use_transposed", False)
746
+
747
+ mat = high_level_object.linear.astype(bool, copy=False)
748
+
749
+ if use_transposed:
750
+ mat = np.transpose(mat)
751
+ if use_inverted:
752
+ mat = calc_inverse_matrix(mat)
753
+
754
+ decomposition = synth_cnot_count_full_pmh(mat, section_size=section_size)
755
+
756
+ if use_transposed:
757
+ decomposition = transpose_cx_circ(decomposition)
758
+ if use_inverted:
759
+ decomposition = decomposition.inverse()
760
+
761
+ return decomposition
762
+
763
+
764
+ class KMSSynthesisPermutation(HighLevelSynthesisPlugin):
765
+ """The permutation synthesis plugin based on the Kutin, Moulton, Smithline method.
766
+
767
+ This plugin name is :``permutation.kms`` which can be used as the key on
768
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
769
+ """
770
+
771
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
772
+ """Run synthesis for the given Permutation."""
773
+ if not isinstance(high_level_object, PermutationGate):
774
+ return None
775
+
776
+ decomposition = synth_permutation_depth_lnn_kms(high_level_object.pattern)
777
+ return decomposition
778
+
779
+
780
+ class BasicSynthesisPermutation(HighLevelSynthesisPlugin):
781
+ """The permutation synthesis plugin based on sorting.
782
+
783
+ This plugin name is :``permutation.basic`` which can be used as the key on
784
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
785
+ """
786
+
787
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
788
+ """Run synthesis for the given Permutation."""
789
+ if not isinstance(high_level_object, PermutationGate):
790
+ return None
791
+
792
+ decomposition = synth_permutation_basic(high_level_object.pattern)
793
+ return decomposition
794
+
795
+
796
+ class ACGSynthesisPermutation(HighLevelSynthesisPlugin):
797
+ """The permutation synthesis plugin based on the Alon, Chung, Graham method.
798
+
799
+ This plugin name is :``permutation.acg`` which can be used as the key on
800
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
801
+ """
802
+
803
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
804
+ """Run synthesis for the given Permutation."""
805
+ if not isinstance(high_level_object, PermutationGate):
806
+ return None
807
+
808
+ decomposition = synth_permutation_acg(high_level_object.pattern)
809
+ return decomposition
810
+
811
+
812
+ class QFTSynthesisFull(HighLevelSynthesisPlugin):
813
+ """Synthesis plugin for QFT gates using all-to-all connectivity.
814
+
815
+ This plugin name is :``qft.full`` which can be used as the key on
816
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
817
+
818
+ Note that the plugin mechanism is not applied if the gate is called ``qft`` but
819
+ is not an instance of ``QFTGate``. This allows users to create custom gates with
820
+ name ``qft``.
821
+
822
+ The plugin supports the following additional options:
823
+
824
+ * reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
825
+ which is the default) or the "QFT-with-reversal" operation (if ``True``).
826
+ Some implementation of the ``QFTGate`` include a layer of swap gates at the end
827
+ of the synthesized circuit, which can in principle be dropped if the ``QFTGate``
828
+ itself is the last gate in the circuit.
829
+ * approximation_degree (int): The degree of approximation (0 for no approximation).
830
+ It is possible to implement the QFT approximately by ignoring
831
+ controlled-phase rotations with the angle beneath a threshold. This is discussed
832
+ in more detail in [1] or [2].
833
+ * insert_barriers (bool): If True, barriers are inserted as visualization improvement.
834
+ * inverse (bool): If True, the inverse Fourier transform is constructed.
835
+ * name (str): The name of the circuit.
836
+
837
+ References:
838
+ 1. Adriano Barenco, Artur Ekert, Kalle-Antti Suominen, and Päivi Törmä,
839
+ *Approximate Quantum Fourier Transform and Decoherence*,
840
+ Physical Review A (1996).
841
+ `arXiv:quant-ph/9601018 [quant-ph] <https://arxiv.org/abs/quant-ph/9601018>`_
842
+ 2. Donny Cheung,
843
+ *Improved Bounds for the Approximate QFT* (2004),
844
+ `arXiv:quant-ph/0403071 [quant-ph] <https://https://arxiv.org/abs/quant-ph/0403071>`_
845
+ """
846
+
847
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
848
+ """Run synthesis for the given QFTGate."""
849
+
850
+ # Even though the gate is called "qft", it's not a QFTGate,
851
+ # and we should not synthesize it using the plugin.
852
+ if not isinstance(high_level_object, QFTGate):
853
+ return None
854
+
855
+ reverse_qubits = options.get("reverse_qubits", False)
856
+ approximation_degree = options.get("approximation_degree", 0)
857
+ insert_barriers = options.get("insert_barriers", False)
858
+ inverse = options.get("inverse", False)
859
+ name = options.get("name", None)
860
+
861
+ decomposition = synth_qft_full(
862
+ num_qubits=high_level_object.num_qubits,
863
+ do_swaps=not reverse_qubits,
864
+ approximation_degree=approximation_degree,
865
+ insert_barriers=insert_barriers,
866
+ inverse=inverse,
867
+ name=name,
868
+ )
869
+ return decomposition
870
+
871
+
872
+ class QFTSynthesisLine(HighLevelSynthesisPlugin):
873
+ """Synthesis plugin for QFT gates using linear connectivity.
874
+
875
+ This plugin name is :``qft.line`` which can be used as the key on
876
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
877
+
878
+ Note that the plugin mechanism is not applied if the gate is called ``qft`` but
879
+ is not an instance of ``QFTGate``. This allows users to create custom gates with
880
+ name ``qft``.
881
+
882
+ The plugin supports the following additional options:
883
+
884
+ * reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
885
+ which is the default) or the "QFT-with-reversal" operation (if ``True``).
886
+ Some implementation of the ``QFTGate`` include a layer of swap gates at the end
887
+ of the synthesized circuit, which can in principle be dropped if the ``QFTGate``
888
+ itself is the last gate in the circuit.
889
+ * approximation_degree (int): the degree of approximation (0 for no approximation).
890
+ It is possible to implement the QFT approximately by ignoring
891
+ controlled-phase rotations with the angle beneath a threshold. This is discussed
892
+ in more detail in [1] or [2].
893
+
894
+ References:
895
+ 1. Adriano Barenco, Artur Ekert, Kalle-Antti Suominen, and Päivi Törmä,
896
+ *Approximate Quantum Fourier Transform and Decoherence*,
897
+ Physical Review A (1996).
898
+ `arXiv:quant-ph/9601018 [quant-ph] <https://arxiv.org/abs/quant-ph/9601018>`_
899
+ 2. Donny Cheung,
900
+ *Improved Bounds for the Approximate QFT* (2004),
901
+ `arXiv:quant-ph/0403071 [quant-ph] <https://https://arxiv.org/abs/quant-ph/0403071>`_
902
+ """
903
+
904
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
905
+ """Run synthesis for the given QFTGate."""
906
+
907
+ # Even though the gate is called "qft", it's not a QFTGate,
908
+ # and we should not synthesize it using the plugin.
909
+ if not isinstance(high_level_object, QFTGate):
910
+ return None
911
+
912
+ reverse_qubits = options.get("reverse_qubits", False)
913
+ approximation_degree = options.get("approximation_degree", 0)
914
+
915
+ decomposition = synth_qft_line(
916
+ num_qubits=high_level_object.num_qubits,
917
+ do_swaps=not reverse_qubits,
918
+ approximation_degree=approximation_degree,
919
+ )
920
+ return decomposition
921
+
922
+
923
+ class TokenSwapperSynthesisPermutation(HighLevelSynthesisPlugin):
924
+ """The permutation synthesis plugin based on the token swapper algorithm.
925
+
926
+ This plugin name is :``permutation.token_swapper`` which can be used as the key on
927
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
928
+
929
+ In more detail, this plugin is used to synthesize objects of type `PermutationGate`.
930
+ When synthesis succeeds, the plugin outputs a quantum circuit consisting only of swap
931
+ gates. When synthesis does not succeed, the plugin outputs `None`.
932
+
933
+ If either `coupling_map` or `qubits` is None, then the synthesized circuit
934
+ is not required to adhere to connectivity constraints, as is the case
935
+ when the synthesis is done before layout/routing.
936
+
937
+ On the other hand, if both `coupling_map` and `qubits` are specified, the synthesized
938
+ circuit is supposed to adhere to connectivity constraints. At the moment, the
939
+ plugin only creates swap gates between qubits in `qubits`, i.e. it does not use
940
+ any other qubits in the coupling map (if such synthesis is not possible, the
941
+ plugin outputs `None`).
942
+
943
+ The plugin supports the following plugin-specific options:
944
+
945
+ * trials: The number of trials for the token swapper to perform the mapping. The
946
+ circuit with the smallest number of SWAPs is returned.
947
+ * seed: The argument to the token swapper specifying the seed for random trials.
948
+ * parallel_threshold: The argument to the token swapper specifying the number of nodes
949
+ in the graph beyond which the algorithm will use parallel processing.
950
+
951
+ For more details on the token swapper algorithm, see to the paper:
952
+ `arXiv:1902.09102 <https://arxiv.org/abs/1902.09102>`__.
953
+ """
954
+
955
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
956
+ """Run synthesis for the given Permutation."""
957
+
958
+ if not isinstance(high_level_object, PermutationGate):
959
+ return None
960
+
961
+ trials = options.get("trials", 5)
962
+ seed = options.get("seed", 0)
963
+ parallel_threshold = options.get("parallel_threshold", 50)
964
+
965
+ pattern = high_level_object.pattern
966
+ pattern_as_dict = {j: i for i, j in enumerate(pattern)}
967
+
968
+ # When the plugin is called from the HighLevelSynthesis transpiler pass,
969
+ # the coupling map already takes target into account.
970
+ if coupling_map is None or qubits is None:
971
+ # The abstract synthesis uses a fully connected coupling map, allowing
972
+ # arbitrary connections between qubits.
973
+ used_coupling_map = CouplingMap.from_full(len(pattern))
974
+ else:
975
+ # The concrete synthesis uses the coupling map restricted to the set of
976
+ # qubits over which the permutation gate is defined. If we allow using other
977
+ # qubits in the coupling map, replacing the node in the DAGCircuit that
978
+ # defines this PermutationGate by the DAG corresponding to the constructed
979
+ # decomposition becomes problematic. Note that we allow the reduced
980
+ # coupling map to be disconnected.
981
+ used_coupling_map = coupling_map.reduce(qubits, check_if_connected=False)
982
+
983
+ graph = used_coupling_map.graph.to_undirected()
984
+ swapper = ApproximateTokenSwapper(graph, seed=seed)
985
+
986
+ try:
987
+ swapper_result = swapper.map(
988
+ pattern_as_dict, trials, parallel_threshold=parallel_threshold
989
+ )
990
+ except rx.InvalidMapping:
991
+ swapper_result = None
992
+
993
+ if swapper_result is not None:
994
+ decomposition = QuantumCircuit(len(graph.node_indices()))
995
+ for swap in swapper_result:
996
+ decomposition.swap(*swap)
997
+ return decomposition
998
+
999
+ return None
1000
+
1001
+
1002
+ class MCXSynthesisNDirtyI15(HighLevelSynthesisPlugin):
1003
+ r"""Synthesis plugin for a multi-controlled X gate based on the paper
1004
+ by Iten et al. (2016).
1005
+
1006
+ See [1] for details.
1007
+
1008
+ This plugin name is :``mcx.n_dirty_i15`` which can be used as the key on
1009
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1010
+
1011
+ For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis
1012
+ method requires :math:`k - 2` additional dirty auxiliary qubits. The synthesized
1013
+ circuit consists of :math:`2 * k - 1` qubits and at most :math:`8 * k - 6` CX gates.
1014
+
1015
+ The plugin supports the following plugin-specific options:
1016
+
1017
+ * num_clean_ancillas: The number of clean auxiliary qubits available.
1018
+ * num_dirty_ancillas: The number of dirty auxiliary qubits available.
1019
+ * relative_phase: When set to ``True``, the method applies the optimized multi-controlled
1020
+ X gate up to a relative phase, in a way that, by lemma 8 of [1], the relative
1021
+ phases of the ``action part`` cancel out with the phases of the ``reset part``.
1022
+ * action_only: when set to ``True``, the method applies only the ``action part``
1023
+ of lemma 8 of [1].
1024
+
1025
+ References:
1026
+ 1. Iten et. al., *Quantum Circuits for Isometries*, Phys. Rev. A 93, 032318 (2016),
1027
+ `arXiv:1501.06911 <http://arxiv.org/abs/1501.06911>`_
1028
+ """
1029
+
1030
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1031
+ """Run synthesis for the given MCX gate."""
1032
+
1033
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1034
+ # Unfortunately we occasionally have custom instructions called "mcx"
1035
+ # which get wrongly caught by the plugin interface. A simple solution is
1036
+ # to return None in this case, since HLS would proceed to examine
1037
+ # their definition as it should.
1038
+ return None
1039
+
1040
+ num_ctrl_qubits = high_level_object.num_ctrl_qubits
1041
+ num_clean_ancillas = options.get("num_clean_ancillas", 0)
1042
+ num_dirty_ancillas = options.get("num_dirty_ancillas", 0)
1043
+ relative_phase = options.get("relative_phase", False)
1044
+ action_only = options.get("actions_only", False)
1045
+
1046
+ if num_ctrl_qubits >= 3 and num_dirty_ancillas + num_clean_ancillas < num_ctrl_qubits - 2:
1047
+ # This synthesis method is not applicable as there are not enough ancilla qubits
1048
+ return None
1049
+
1050
+ decomposition = synth_mcx_n_dirty_i15(num_ctrl_qubits, relative_phase, action_only)
1051
+ return decomposition
1052
+
1053
+
1054
+ class MCXSynthesisNCleanM15(HighLevelSynthesisPlugin):
1055
+ r"""Synthesis plugin for a multi-controlled X gate based on the paper by
1056
+ Maslov (2016).
1057
+
1058
+ See [1] for details.
1059
+
1060
+ This plugin name is :``mcx.n_clean_m15`` which can be used as the key on
1061
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1062
+
1063
+ For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis
1064
+ method requires :math:`k - 2` additional clean auxiliary qubits. The synthesized
1065
+ circuit consists of :math:`2 * k - 1` qubits and at most :math:`6 * k - 6` CX gates.
1066
+
1067
+ The plugin supports the following plugin-specific options:
1068
+
1069
+ * num_clean_ancillas: The number of clean auxiliary qubits available.
1070
+
1071
+ References:
1072
+ 1. Maslov., Phys. Rev. A 93, 022311 (2016),
1073
+ `arXiv:1508.03273 <https://arxiv.org/pdf/1508.03273>`_
1074
+ """
1075
+
1076
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1077
+ """Run synthesis for the given MCX gate."""
1078
+
1079
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1080
+ # Unfortunately we occasionally have custom instructions called "mcx"
1081
+ # which get wrongly caught by the plugin interface. A simple solution is
1082
+ # to return None in this case, since HLS would proceed to examine
1083
+ # their definition as it should.
1084
+ return None
1085
+
1086
+ num_ctrl_qubits = high_level_object.num_ctrl_qubits
1087
+ num_clean_ancillas = options.get("num_clean_ancillas", 0)
1088
+
1089
+ if num_ctrl_qubits >= 3 and num_clean_ancillas < num_ctrl_qubits - 2:
1090
+ # This synthesis method is not applicable as there are not enough ancilla qubits
1091
+ return None
1092
+
1093
+ decomposition = synth_mcx_n_clean_m15(num_ctrl_qubits)
1094
+ return decomposition
1095
+
1096
+
1097
+ class MCXSynthesis1CleanB95(HighLevelSynthesisPlugin):
1098
+ r"""Synthesis plugin for a multi-controlled X gate based on the paper by
1099
+ Barenco et al. (1995).
1100
+
1101
+ See [1] for details.
1102
+
1103
+ This plugin name is :``mcx.1_clean_b95`` which can be used as the key on
1104
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1105
+
1106
+ For a multi-controlled X gate with :math:`k\ge 5` control qubits this synthesis
1107
+ method requires a single additional clean auxiliary qubit. The synthesized
1108
+ circuit consists of :math:`k + 2` qubits and at most :math:`16 * k - 8` CX gates.
1109
+
1110
+ The plugin supports the following plugin-specific options:
1111
+
1112
+ * num_clean_ancillas: The number of clean auxiliary qubits available.
1113
+
1114
+ References:
1115
+ 1. Barenco et. al., Phys.Rev. A52 3457 (1995),
1116
+ `arXiv:quant-ph/9503016 <https://arxiv.org/abs/quant-ph/9503016>`_
1117
+ """
1118
+
1119
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1120
+ """Run synthesis for the given MCX gate."""
1121
+
1122
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1123
+ # Unfortunately we occasionally have custom instructions called "mcx"
1124
+ # which get wrongly caught by the plugin interface. A simple solution is
1125
+ # to return None in this case, since HLS would proceed to examine
1126
+ # their definition as it should.
1127
+ return None
1128
+
1129
+ num_ctrl_qubits = high_level_object.num_ctrl_qubits
1130
+
1131
+ if num_ctrl_qubits <= 2:
1132
+ # The method requires at least 3 control qubits
1133
+ return None
1134
+
1135
+ num_clean_ancillas = options.get("num_clean_ancillas", 0)
1136
+
1137
+ if num_ctrl_qubits >= 5 and num_clean_ancillas == 0:
1138
+ # This synthesis method is not applicable as there are not enough ancilla qubits
1139
+ return None
1140
+
1141
+ decomposition = synth_mcx_1_clean_b95(num_ctrl_qubits)
1142
+ return decomposition
1143
+
1144
+
1145
+ class MCXSynthesisGrayCode(HighLevelSynthesisPlugin):
1146
+ r"""Synthesis plugin for a multi-controlled X gate based on the Gray code.
1147
+
1148
+ This plugin name is :``mcx.gray_code`` which can be used as the key on
1149
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1150
+
1151
+ For a multi-controlled X gate with :math:`k` control qubits this synthesis
1152
+ method requires no additional clean auxiliary qubits. The synthesized
1153
+ circuit consists of :math:`k + 1` qubits.
1154
+
1155
+ It is not recommended to use this method for large values of :math:`k + 1`
1156
+ as it produces exponentially many gates.
1157
+ """
1158
+
1159
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1160
+ """Run synthesis for the given MCX gate."""
1161
+
1162
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1163
+ # Unfortunately we occasionally have custom instructions called "mcx"
1164
+ # which get wrongly caught by the plugin interface. A simple solution is
1165
+ # to return None in this case, since HLS would proceed to examine
1166
+ # their definition as it should.
1167
+ return None
1168
+
1169
+ num_ctrl_qubits = high_level_object.num_ctrl_qubits
1170
+ decomposition = synth_mcx_gray_code(num_ctrl_qubits)
1171
+ return decomposition
1172
+
1173
+
1174
+ class MCXSynthesisNoAuxV24(HighLevelSynthesisPlugin):
1175
+ r"""Synthesis plugin for a multi-controlled X gate based on the
1176
+ implementation for MCPhaseGate, which is in turn based on the
1177
+ paper by Vale et al. (2024).
1178
+
1179
+ See [1] for details.
1180
+
1181
+ This plugin name is :``mcx.noaux_v24`` which can be used as the key on
1182
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1183
+
1184
+ For a multi-controlled X gate with :math:`k` control qubits this synthesis
1185
+ method requires no additional clean auxiliary qubits. The synthesized
1186
+ circuit consists of :math:`k + 1` qubits.
1187
+
1188
+ References:
1189
+ 1. Vale et. al., *Circuit Decomposition of Multicontrolled Special Unitary
1190
+ Single-Qubit Gates*, IEEE TCAD 43(3) (2024),
1191
+ `arXiv:2302.06377 <https://arxiv.org/abs/2302.06377>`_
1192
+ """
1193
+
1194
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1195
+ """Run synthesis for the given MCX gate."""
1196
+
1197
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1198
+ # Unfortunately we occasionally have custom instructions called "mcx"
1199
+ # which get wrongly caught by the plugin interface. A simple solution is
1200
+ # to return None in this case, since HLS would proceed to examine
1201
+ # their definition as it should.
1202
+ return None
1203
+
1204
+ num_ctrl_qubits = high_level_object.num_ctrl_qubits
1205
+ decomposition = synth_mcx_noaux_v24(num_ctrl_qubits)
1206
+ return decomposition
1207
+
1208
+
1209
+ class MCXSynthesisDefault(HighLevelSynthesisPlugin):
1210
+ r"""The default synthesis plugin for a multi-controlled X gate.
1211
+
1212
+ This plugin name is :``mcx.default`` which can be used as the key on
1213
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1214
+ """
1215
+
1216
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1217
+ """Run synthesis for the given MCX gate."""
1218
+
1219
+ if not isinstance(high_level_object, (MCXGate, C3XGate, C4XGate)):
1220
+ # Unfortunately we occasionally have custom instructions called "mcx"
1221
+ # which get wrongly caught by the plugin interface. A simple solution is
1222
+ # to return None in this case, since HLS would proceed to examine
1223
+ # their definition as it should.
1224
+ return None
1225
+
1226
+ # Iteratively run other synthesis methods available
1227
+
1228
+ if (
1229
+ decomposition := MCXSynthesisNCleanM15().run(
1230
+ high_level_object, coupling_map, target, qubits, **options
1231
+ )
1232
+ ) is not None:
1233
+ return decomposition
1234
+
1235
+ if (
1236
+ decomposition := MCXSynthesisNDirtyI15().run(
1237
+ high_level_object, coupling_map, target, qubits, **options
1238
+ )
1239
+ ) is not None:
1240
+ return decomposition
1241
+
1242
+ if (
1243
+ decomposition := MCXSynthesis1CleanB95().run(
1244
+ high_level_object, coupling_map, target, qubits, **options
1245
+ )
1246
+ ) is not None:
1247
+ return decomposition
1248
+
1249
+ return MCXSynthesisNoAuxV24().run(
1250
+ high_level_object, coupling_map, target, qubits, **options
1251
+ )
1252
+
1253
+
1254
+ class MCMTSynthesisDefault(HighLevelSynthesisPlugin):
1255
+ """A default decomposition for MCMT gates."""
1256
+
1257
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1258
+ # first try to use the V-chain synthesis if enough auxiliary qubits are available
1259
+ if not isinstance(high_level_object, MCMTGate):
1260
+ return None
1261
+
1262
+ if (
1263
+ decomposition := MCMTSynthesisVChain().run(
1264
+ high_level_object, coupling_map, target, qubits, **options
1265
+ )
1266
+ ) is not None:
1267
+ return decomposition
1268
+
1269
+ return MCMTSynthesisNoAux().run(high_level_object, coupling_map, target, qubits, **options)
1270
+
1271
+
1272
+ class MCMTSynthesisNoAux(HighLevelSynthesisPlugin):
1273
+ """A V-chain based synthesis for ``MCMTGate``."""
1274
+
1275
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1276
+ if not isinstance(high_level_object, MCMTGate):
1277
+ return None
1278
+
1279
+ base_gate = high_level_object.base_gate
1280
+ ctrl_state = options.get("ctrl_state", None)
1281
+
1282
+ if high_level_object.num_target_qubits == 1:
1283
+ # no broadcasting needed (makes for better circuit diagrams)
1284
+ circuit = QuantumCircuit(high_level_object.num_qubits)
1285
+ circuit.append(
1286
+ base_gate.control(high_level_object.num_ctrl_qubits, ctrl_state=ctrl_state),
1287
+ circuit.qubits,
1288
+ )
1289
+
1290
+ else:
1291
+ base = QuantumCircuit(high_level_object.num_target_qubits, name=high_level_object.label)
1292
+ for i in range(high_level_object.num_target_qubits):
1293
+ base.append(base_gate, [i], [])
1294
+
1295
+ circuit = base.control(high_level_object.num_ctrl_qubits, ctrl_state=ctrl_state)
1296
+
1297
+ return circuit.decompose()
1298
+
1299
+
1300
+ class MCMTSynthesisVChain(HighLevelSynthesisPlugin):
1301
+ """A V-chain based synthesis for ``MCMTGate``."""
1302
+
1303
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1304
+ if not isinstance(high_level_object, MCMTGate):
1305
+ return None
1306
+
1307
+ if options.get("num_clean_ancillas", 0) < high_level_object.num_ctrl_qubits - 1:
1308
+ return None # insufficient number of auxiliary qubits
1309
+
1310
+ ctrl_state = options.get("ctrl_state", None)
1311
+
1312
+ return synth_mcmt_vchain(
1313
+ high_level_object.base_gate,
1314
+ high_level_object.num_ctrl_qubits,
1315
+ high_level_object.num_target_qubits,
1316
+ ctrl_state,
1317
+ )
1318
+
1319
+
1320
+ class IntComparatorSynthesisDefault(HighLevelSynthesisPlugin):
1321
+ """The default synthesis for ``IntegerComparatorGate``.
1322
+
1323
+ Currently this is only supporting an ancilla-based decomposition.
1324
+ """
1325
+
1326
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1327
+ num_state_qubits = high_level_object.num_qubits - 1
1328
+ num_aux = num_state_qubits - 1
1329
+ if options.get("num_clean_ancillas", 0) < num_aux:
1330
+ return synth_integer_comparator_greedy(
1331
+ num_state_qubits, high_level_object.value, high_level_object.geq
1332
+ )
1333
+
1334
+ return synth_integer_comparator_2s(
1335
+ num_state_qubits, high_level_object.value, high_level_object.geq
1336
+ )
1337
+
1338
+
1339
+ class IntComparatorSynthesisNoAux(HighLevelSynthesisPlugin):
1340
+ """A potentially exponentially expensive comparison w/o auxiliary qubits."""
1341
+
1342
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1343
+ return synth_integer_comparator_greedy(
1344
+ high_level_object.num_state_qubits, high_level_object.value, high_level_object.geq
1345
+ )
1346
+
1347
+
1348
+ class IntComparatorSynthesis2s(HighLevelSynthesisPlugin):
1349
+ """An integer comparison based on 2s complement."""
1350
+
1351
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1352
+ num_aux = high_level_object.num_state_qubits - 1
1353
+ if options.get("num_clean_ancillas", 0) < num_aux:
1354
+ return None
1355
+
1356
+ return synth_integer_comparator_2s(
1357
+ high_level_object.num_state_qubits, high_level_object.value, high_level_object.geq
1358
+ )
1359
+
1360
+
1361
+ class ModularAdderSynthesisDefault(HighLevelSynthesisPlugin):
1362
+ """The default modular adder (no carry in, no carry out qubit) synthesis.
1363
+
1364
+ This plugin name is:``ModularAdder.default`` which can be used as the key on
1365
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1366
+
1367
+ If at least one clean auxiliary qubit is available, the :class:`ModularAdderSynthesisC04`
1368
+ is used, otherwise :class:`ModularAdderSynthesisD00`.
1369
+
1370
+ The plugin supports the following plugin-specific options:
1371
+
1372
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1373
+
1374
+ """
1375
+
1376
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1377
+ if not isinstance(high_level_object, ModularAdderGate):
1378
+ return None
1379
+
1380
+ # For up to 5 qubits, the QFT-based adder is best
1381
+ if high_level_object.num_state_qubits <= 5:
1382
+ decomposition = ModularAdderSynthesisD00().run(
1383
+ high_level_object, coupling_map, target, qubits, **options
1384
+ )
1385
+ if decomposition is not None:
1386
+ return decomposition
1387
+
1388
+ # Otherwise, the following decomposition is best (if there are enough ancillas)
1389
+ if (
1390
+ decomposition := ModularAdderSynthesisC04().run(
1391
+ high_level_object, coupling_map, target, qubits, **options
1392
+ )
1393
+ ) is not None:
1394
+ return decomposition
1395
+
1396
+ # Otherwise, use the QFT-adder again
1397
+ return ModularAdderSynthesisD00().run(
1398
+ high_level_object, coupling_map, target, qubits, **options
1399
+ )
1400
+
1401
+
1402
+ class ModularAdderSynthesisC04(HighLevelSynthesisPlugin):
1403
+ r"""A ripple-carry adder, modulo :math:`2^n`.
1404
+
1405
+ This plugin name is:``ModularAdder.ripple_c04`` which can be used as the key on
1406
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1407
+
1408
+ This plugin requires at least one clean auxiliary qubit.
1409
+
1410
+ The plugin supports the following plugin-specific options:
1411
+
1412
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1413
+
1414
+ """
1415
+
1416
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1417
+ if not isinstance(high_level_object, ModularAdderGate):
1418
+ return None
1419
+
1420
+ # unless we implement the full adder, this implementation needs an ancilla qubit
1421
+ if options.get("num_clean_ancillas", 0) < 1:
1422
+ return None
1423
+
1424
+ return adder_ripple_c04(high_level_object.num_state_qubits, kind="fixed")
1425
+
1426
+
1427
+ class ModularAdderSynthesisV95(HighLevelSynthesisPlugin):
1428
+ r"""A ripple-carry adder, modulo :math:`2^n`.
1429
+
1430
+ This plugin name is:``ModularAdder.ripple_v95`` which can be used as the key on
1431
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1432
+
1433
+ For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
1434
+ least :math:`n-1` clean auxiliary qubit.
1435
+
1436
+ The plugin supports the following plugin-specific options:
1437
+
1438
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1439
+
1440
+ """
1441
+
1442
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1443
+ if not isinstance(high_level_object, ModularAdderGate):
1444
+ return None
1445
+
1446
+ num_state_qubits = high_level_object.num_state_qubits
1447
+
1448
+ # The synthesis method needs n-1 clean ancilla qubits
1449
+ if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
1450
+ return None
1451
+
1452
+ return adder_ripple_v95(num_state_qubits, kind="fixed")
1453
+
1454
+
1455
+ class ModularAdderSynthesisD00(HighLevelSynthesisPlugin):
1456
+ r"""A QFT-based adder, modulo :math:`2^n`.
1457
+
1458
+ This plugin name is:``ModularAdder.qft_d00`` which can be used as the key on
1459
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1460
+ """
1461
+
1462
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1463
+ if not isinstance(high_level_object, ModularAdderGate):
1464
+ return None
1465
+
1466
+ return adder_qft_d00(high_level_object.num_state_qubits, kind="fixed")
1467
+
1468
+
1469
+ class HalfAdderSynthesisDefault(HighLevelSynthesisPlugin):
1470
+ r"""The default half-adder (no carry in, but a carry out qubit) synthesis.
1471
+
1472
+ If we have an auxiliary qubit available, the Cuccaro ripple-carry adder uses
1473
+ :math:`O(n)` CX gates and 1 auxiliary qubit, whereas the Vedral ripple-carry uses more CX
1474
+ and :math:`n-1` auxiliary qubits. The QFT-based adder uses no auxiliary qubits, but
1475
+ :math:`O(n^2)`, hence it is only used if no auxiliary qubits are available.
1476
+
1477
+ This plugin name is:``HalfAdder.default`` which can be used as the key on
1478
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1479
+
1480
+ If at least one clean auxiliary qubit is available, the :class:`HalfAdderSynthesisC04`
1481
+ is used, otherwise :class:`HalfAdderSynthesisD00`.
1482
+
1483
+ The plugin supports the following plugin-specific options:
1484
+
1485
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1486
+
1487
+ """
1488
+
1489
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1490
+ if not isinstance(high_level_object, HalfAdderGate):
1491
+ return None
1492
+
1493
+ # For up to 3 qubits, ripple_v95 is better (if there are enough ancilla qubits)
1494
+ if high_level_object.num_state_qubits <= 3:
1495
+ decomposition = HalfAdderSynthesisV95().run(
1496
+ high_level_object, coupling_map, target, qubits, **options
1497
+ )
1498
+ if decomposition is not None:
1499
+ return decomposition
1500
+
1501
+ # The next best option is to use ripple_c04 (if there are enough ancilla qubits)
1502
+ if (
1503
+ decomposition := HalfAdderSynthesisC04().run(
1504
+ high_level_object, coupling_map, target, qubits, **options
1505
+ )
1506
+ ) is not None:
1507
+ return decomposition
1508
+
1509
+ # The QFT-based adder does not require ancilla qubits and should always succeed
1510
+ return HalfAdderSynthesisD00().run(
1511
+ high_level_object, coupling_map, target, qubits, **options
1512
+ )
1513
+
1514
+
1515
+ class HalfAdderSynthesisC04(HighLevelSynthesisPlugin):
1516
+ """A ripple-carry adder with a carry-out bit.
1517
+
1518
+ This plugin name is:``HalfAdder.ripple_c04`` which can be used as the key on
1519
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1520
+
1521
+ This plugin requires at least one clean auxiliary qubit.
1522
+
1523
+ The plugin supports the following plugin-specific options:
1524
+
1525
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1526
+
1527
+ """
1528
+
1529
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1530
+ if not isinstance(high_level_object, HalfAdderGate):
1531
+ return None
1532
+
1533
+ # unless we implement the full adder, this implementation needs an ancilla qubit
1534
+ if options.get("num_clean_ancillas", 0) < 1:
1535
+ return None
1536
+
1537
+ return adder_ripple_c04(high_level_object.num_state_qubits, kind="half")
1538
+
1539
+
1540
+ class HalfAdderSynthesisV95(HighLevelSynthesisPlugin):
1541
+ """A ripple-carry adder with a carry-out bit.
1542
+
1543
+ This plugin name is:``HalfAdder.ripple_v95`` which can be used as the key on
1544
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1545
+
1546
+ For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
1547
+ least :math:`n-1` clean auxiliary qubit.
1548
+
1549
+ The plugin supports the following plugin-specific options:
1550
+
1551
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1552
+ """
1553
+
1554
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1555
+ if not isinstance(high_level_object, HalfAdderGate):
1556
+ return None
1557
+
1558
+ num_state_qubits = high_level_object.num_state_qubits
1559
+
1560
+ # The synthesis method needs n-1 clean ancilla qubits
1561
+ if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
1562
+ return None
1563
+
1564
+ return adder_ripple_v95(num_state_qubits, kind="half")
1565
+
1566
+
1567
+ class HalfAdderSynthesisD00(HighLevelSynthesisPlugin):
1568
+ """A QFT-based adder with a carry-in and a carry-out bit.
1569
+
1570
+ This plugin name is:``HalfAdder.qft_d00`` which can be used as the key on
1571
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1572
+ """
1573
+
1574
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1575
+ if not isinstance(high_level_object, HalfAdderGate):
1576
+ return None
1577
+
1578
+ return adder_qft_d00(high_level_object.num_state_qubits, kind="half")
1579
+
1580
+
1581
+ class FullAdderSynthesisDefault(HighLevelSynthesisPlugin):
1582
+ """A ripple-carry adder with a carry-in and a carry-out bit.
1583
+
1584
+ This plugin name is:``FullAdder.default`` which can be used as the key on
1585
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1586
+ """
1587
+
1588
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1589
+ if not isinstance(high_level_object, FullAdderGate):
1590
+ return None
1591
+
1592
+ # FullAdderSynthesisC04 requires no ancilla qubits and returns better results
1593
+ # than FullAdderSynthesisV95 in all cases except for n=1.
1594
+ if high_level_object.num_state_qubits == 1:
1595
+ decomposition = FullAdderSynthesisV95().run(
1596
+ high_level_object, coupling_map, target, qubits, **options
1597
+ )
1598
+ if decomposition is not None:
1599
+ return decomposition
1600
+
1601
+ return FullAdderSynthesisC04().run(
1602
+ high_level_object, coupling_map, target, qubits, **options
1603
+ )
1604
+
1605
+
1606
+ class FullAdderSynthesisC04(HighLevelSynthesisPlugin):
1607
+ """A ripple-carry adder with a carry-in and a carry-out bit.
1608
+
1609
+ This plugin name is:``FullAdder.ripple_c04`` which can be used as the key on
1610
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1611
+
1612
+ This plugin requires no auxiliary qubits.
1613
+ """
1614
+
1615
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1616
+ if not isinstance(high_level_object, FullAdderGate):
1617
+ return None
1618
+
1619
+ return adder_ripple_c04(high_level_object.num_state_qubits, kind="full")
1620
+
1621
+
1622
+ class FullAdderSynthesisV95(HighLevelSynthesisPlugin):
1623
+ """A ripple-carry adder with a carry-in and a carry-out bit.
1624
+
1625
+ This plugin name is:``FullAdder.ripple_v95`` which can be used as the key on
1626
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1627
+
1628
+ For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
1629
+ least :math:`n-1` clean auxiliary qubits.
1630
+
1631
+ The plugin supports the following plugin-specific options:
1632
+
1633
+ * ``num_clean_ancillas``: The number of clean auxiliary qubits available.
1634
+ """
1635
+
1636
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1637
+ if not isinstance(high_level_object, FullAdderGate):
1638
+ return None
1639
+
1640
+ num_state_qubits = high_level_object.num_state_qubits
1641
+
1642
+ # The synthesis method needs n-1 clean ancilla qubits
1643
+ if num_state_qubits - 1 > options.get("num_clean_ancillas", 0):
1644
+ return None
1645
+
1646
+ return adder_ripple_v95(num_state_qubits, kind="full")
1647
+
1648
+
1649
+ class MultiplierSynthesisH18(HighLevelSynthesisPlugin):
1650
+ """A cumulative multiplier based on controlled adders.
1651
+
1652
+ This plugin name is:``Multiplier.cumulative_h18`` which can be used as the key on
1653
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1654
+ """
1655
+
1656
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1657
+ if not isinstance(high_level_object, MultiplierGate):
1658
+ return None
1659
+
1660
+ return multiplier_cumulative_h18(
1661
+ high_level_object.num_state_qubits, high_level_object.num_result_qubits
1662
+ )
1663
+
1664
+
1665
+ class MultiplierSynthesisR17(HighLevelSynthesisPlugin):
1666
+ """A QFT-based multiplier.
1667
+
1668
+ This plugin name is:``Multiplier.qft_r17`` which can be used as the key on
1669
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1670
+ """
1671
+
1672
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1673
+ if not isinstance(high_level_object, MultiplierGate):
1674
+ return None
1675
+
1676
+ return multiplier_qft_r17(
1677
+ high_level_object.num_state_qubits, high_level_object.num_result_qubits
1678
+ )
1679
+
1680
+
1681
+ class PauliEvolutionSynthesisDefault(HighLevelSynthesisPlugin):
1682
+ """Synthesize a :class:`.PauliEvolutionGate` using the default synthesis algorithm.
1683
+
1684
+ This plugin name is:``PauliEvolution.default`` which can be used as the key on
1685
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1686
+
1687
+ The following plugin option can be set:
1688
+
1689
+ * preserve_order: If ``False``, allow re-ordering the Pauli terms in the Hamiltonian to
1690
+ reduce the circuit depth of the decomposition.
1691
+
1692
+ """
1693
+
1694
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1695
+ if not isinstance(high_level_object, PauliEvolutionGate):
1696
+ # Don't do anything if a gate is called "evolution" but is not an
1697
+ # actual PauliEvolutionGate
1698
+ return None
1699
+ algo = high_level_object.synthesis
1700
+
1701
+ original_preserve_order = algo.preserve_order
1702
+ if "preserve_order" in options and isinstance(algo, ProductFormula):
1703
+ algo.preserve_order = options["preserve_order"]
1704
+
1705
+ synth_object = algo.synthesize(high_level_object)
1706
+ algo.preserve_order = original_preserve_order
1707
+ return synth_object
1708
+
1709
+
1710
+ class PauliEvolutionSynthesisRustiq(HighLevelSynthesisPlugin):
1711
+ """Synthesize a :class:`.PauliEvolutionGate` using Rustiq.
1712
+
1713
+ This plugin name is :``PauliEvolution.rustiq`` which can be used as the key on
1714
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1715
+
1716
+ The Rustiq synthesis algorithm is described in [1], and is implemented in
1717
+ Rust-based quantum circuit synthesis library available at
1718
+ https://github.com/smartiel/rustiq-core.
1719
+
1720
+ On large circuits the plugin may take a significant runtime.
1721
+
1722
+ The plugin supports the following additional options:
1723
+
1724
+ * optimize_count (bool): if `True` the synthesis algorithm will try to optimize
1725
+ the 2-qubit gate count; and if `False` then the 2-qubit depth.
1726
+ * preserve_order (bool): whether the order of paulis should be preserved, up to
1727
+ commutativity.
1728
+ * upto_clifford (bool): if `True`, the final Clifford operator is not synthesized.
1729
+ * upto_phase (bool): if `True`, the global phase of the returned circuit may
1730
+ differ from the global phase of the given pauli network.
1731
+ * resynth_clifford_method (int): describes the strategy to synthesize the final
1732
+ Clifford operator. Allowed values are `0` (naive approach), `1` (qiskit
1733
+ greedy synthesis), `2` (rustiq isometry synthesis).
1734
+
1735
+ References:
1736
+ 1. Timothée Goubault de Brugière and Simon Martiel,
1737
+ *Faster and shorter synthesis of Hamiltonian simulation circuits*,
1738
+ `arXiv:2404.03280 [quant-ph] <https://arxiv.org/abs/2404.03280>`_
1739
+
1740
+ """
1741
+
1742
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1743
+ if not isinstance(high_level_object, PauliEvolutionGate):
1744
+ # Don't do anything if a gate is called "evolution" but is not an
1745
+ # actual PauliEvolutionGate
1746
+ return None
1747
+
1748
+ algo = high_level_object.synthesis
1749
+
1750
+ if not isinstance(algo, ProductFormula):
1751
+ warnings.warn(
1752
+ "Cannot apply Rustiq if the evolution synthesis does not implement ``expand``. ",
1753
+ stacklevel=2,
1754
+ category=RuntimeWarning,
1755
+ )
1756
+ return None
1757
+
1758
+ original_preserve_order = algo.preserve_order
1759
+ if "preserve_order" in options:
1760
+ algo.preserve_order = options["preserve_order"]
1761
+
1762
+ num_qubits = high_level_object.num_qubits
1763
+ pauli_network = algo.expand(high_level_object)
1764
+
1765
+ optimize_count = options.get("optimize_count", True)
1766
+ preserve_order = options.get("preserve_order", True)
1767
+ upto_clifford = options.get("upto_clifford", False)
1768
+ upto_phase = options.get("upto_phase", False)
1769
+ resynth_clifford_method = options.get("resynth_clifford_method", 1)
1770
+
1771
+ synth_object = synth_pauli_network_rustiq(
1772
+ num_qubits=num_qubits,
1773
+ pauli_network=pauli_network,
1774
+ optimize_count=optimize_count,
1775
+ preserve_order=preserve_order,
1776
+ upto_clifford=upto_clifford,
1777
+ upto_phase=upto_phase,
1778
+ resynth_clifford_method=resynth_clifford_method,
1779
+ )
1780
+ algo.preserve_order = original_preserve_order
1781
+ return synth_object
1782
+
1783
+
1784
+ class AnnotatedSynthesisDefault(HighLevelSynthesisPlugin):
1785
+ """Synthesize an :class:`.AnnotatedOperation` using the default synthesis algorithm.
1786
+
1787
+ This plugin name is:``annotated.default`` which can be used as the key on
1788
+ an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1789
+ """
1790
+
1791
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1792
+ if not isinstance(high_level_object, AnnotatedOperation):
1793
+ return None
1794
+
1795
+ operation = high_level_object
1796
+ modifiers = high_level_object.modifiers
1797
+
1798
+ # The plugin needs additional information that is not yet passed via the run's method
1799
+ # arguments: namely high-level-synthesis data and options, the global qubits over which
1800
+ # the operation is defined, and the initial state of each global qubit.
1801
+ tracker = options.get("qubit_tracker", None)
1802
+ data = options.get("hls_data", None)
1803
+ input_qubits = options.get("input_qubits", None)
1804
+
1805
+ if data is None or input_qubits is None:
1806
+ raise TranspilerError(
1807
+ "The AnnotatedSynthesisDefault plugin should receive data and input_qubits via options."
1808
+ )
1809
+
1810
+ if len(modifiers) > 0:
1811
+ num_ctrl = sum(
1812
+ mod.num_ctrl_qubits for mod in modifiers if isinstance(mod, ControlModifier)
1813
+ )
1814
+ power = sum(mod.power for mod in modifiers if isinstance(mod, PowerModifier))
1815
+ is_inverted = sum(1 for mod in modifiers if isinstance(mod, InverseModifier)) % 2
1816
+
1817
+ # First, synthesize the base operation of this annotated operation.
1818
+ # As this step cannot use any control qubits as auxiliary qubits, we use a dedicated
1819
+ # tracker (annotated_tracker).
1820
+ # The logic is as follows:
1821
+ # - annotated_tracker.disable control qubits
1822
+ # - if have power or inverse modifiers, annotated_tracker.set_dirty(base_qubits)
1823
+ # - synthesize the base operation using annotated tracker
1824
+ # - main_tracker.set_dirty(base_qubits)
1825
+ #
1826
+ # Note that we need to set the base_qubits to dirty if we have power or inverse
1827
+ # modifiers. For power: even if the power is a positive integer (that is, we need
1828
+ # to repeat the same circuit multiple times), even if the target is initially at |0>,
1829
+ # it will generally not be at |0> after one iteration. For inverse: as we
1830
+ # flip the order of operations, we cannot exploit which qubits are at |0> as "viewed from
1831
+ # the back of the circuit". If we just have control modifiers, we can use the state
1832
+ # of base qubits when synthesizing the controlled operation.
1833
+ #
1834
+ # In addition, all of the other global qubits that are not a part of the annotated
1835
+ # operation can be used as they are in all cases, since we are assuming that all of
1836
+ # the synthesis methods preserve the states of ancilla qubits.
1837
+ annotated_tracker = tracker.copy()
1838
+ control_qubits = input_qubits[:num_ctrl]
1839
+ base_qubits = input_qubits[num_ctrl:]
1840
+ annotated_tracker.disable(control_qubits) # do not access control qubits
1841
+ if power != 0 or is_inverted:
1842
+ annotated_tracker.set_dirty(base_qubits)
1843
+
1844
+ # Note that synthesize_operation also returns the output qubits on which the
1845
+ # operation is defined, however currently the plugin mechanism has no way
1846
+ # to return these (and instead the upstream code greedily grabs some ancilla
1847
+ # qubits from the circuit). We should refactor the plugin "run" iterface to
1848
+ # return the actual ancilla qubits used.
1849
+ synthesized_base_op_result = synthesize_operation(
1850
+ operation.base_op, input_qubits[num_ctrl:], data, annotated_tracker
1851
+ )
1852
+
1853
+ # The base operation does not need to be synthesized.
1854
+ # For simplicity, we wrap the instruction into a circuit. Note that
1855
+ # this should not deteriorate the quality of the result.
1856
+ if synthesized_base_op_result is None:
1857
+ synthesized_base_op = self._instruction_to_circuit(operation.base_op)
1858
+ else:
1859
+ synthesized_base_op = QuantumCircuit._from_circuit_data(
1860
+ synthesized_base_op_result[0]
1861
+ )
1862
+ tracker.set_dirty(base_qubits)
1863
+
1864
+ # This step currently does not introduce ancilla qubits. However it makes
1865
+ # a lot of sense to allow this in the future.
1866
+ synthesized = self._apply_annotations(synthesized_base_op, operation.modifiers)
1867
+
1868
+ return synthesized
1869
+
1870
+ return None
1871
+
1872
+ @staticmethod
1873
+ def _apply_annotations(circuit: QuantumCircuit, modifiers: list[Modifier]) -> QuantumCircuit:
1874
+ """
1875
+ Applies modifiers to a quantum circuit.
1876
+ """
1877
+ for modifier in modifiers:
1878
+ if isinstance(modifier, InverseModifier):
1879
+ circuit = circuit.inverse()
1880
+
1881
+ elif isinstance(modifier, ControlModifier):
1882
+ if circuit.num_clbits > 0:
1883
+ raise TranspilerError(
1884
+ "AnnotatedSynthesisDefault: cannot control a circuit with classical bits."
1885
+ )
1886
+
1887
+ # Apply the control modifier to each gate in the circuit.
1888
+ controlled_circuit = QuantumCircuit(modifier.num_ctrl_qubits + circuit.num_qubits)
1889
+ if circuit.global_phase != 0:
1890
+ controlled_op = GlobalPhaseGate(circuit.global_phase).control(
1891
+ num_ctrl_qubits=modifier.num_ctrl_qubits,
1892
+ label=None,
1893
+ ctrl_state=modifier.ctrl_state,
1894
+ annotated=False,
1895
+ )
1896
+ controlled_qubits = list(range(0, modifier.num_ctrl_qubits))
1897
+ controlled_circuit.append(controlled_op, controlled_qubits)
1898
+ for inst in circuit:
1899
+ inst_op = inst.operation
1900
+ inst_qubits = inst.qubits
1901
+ controlled_op = inst_op.control(
1902
+ num_ctrl_qubits=modifier.num_ctrl_qubits,
1903
+ label=None,
1904
+ ctrl_state=modifier.ctrl_state,
1905
+ annotated=False,
1906
+ )
1907
+ controlled_qubits = list(range(0, modifier.num_ctrl_qubits)) + [
1908
+ modifier.num_ctrl_qubits + circuit.find_bit(q).index for q in inst_qubits
1909
+ ]
1910
+ controlled_circuit.append(controlled_op, controlled_qubits)
1911
+
1912
+ circuit = controlled_circuit
1913
+
1914
+ if isinstance(circuit, AnnotatedOperation):
1915
+ raise TranspilerError(
1916
+ "AnnotatedSynthesisDefault: failed to synthesize the control modifier."
1917
+ )
1918
+
1919
+ elif isinstance(modifier, PowerModifier):
1920
+ circuit = circuit.power(modifier.power)
1921
+
1922
+ else:
1923
+ raise TranspilerError(f"AnnotatedSynthesisDefault: Unknown modifier {modifier}.")
1924
+
1925
+ return circuit
1926
+
1927
+ @staticmethod
1928
+ def _instruction_to_circuit(op: Operation) -> QuantumCircuit:
1929
+ """Wraps a single operation into a quantum circuit."""
1930
+ circuit = QuantumCircuit(op.num_qubits, op.num_clbits)
1931
+ circuit.append(op, circuit.qubits, circuit.clbits)
1932
+ return circuit
1933
+
1934
+
1935
+ class WeightedSumSynthesisDefault(HighLevelSynthesisPlugin):
1936
+ """Synthesize a :class:`.WeightedSumGate` using the default synthesis algorithm.
1937
+
1938
+ This plugin name is:``WeightedSum.default`` which can be used as the key on
1939
+ an :class:`.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
1940
+
1941
+ .. note::
1942
+
1943
+ This default plugin requires auxiliary qubits. There is currently no implementation
1944
+ available without auxiliary qubits.
1945
+
1946
+ """
1947
+
1948
+ def run(self, high_level_object, coupling_map=None, target=None, qubits=None, **options):
1949
+ if not isinstance(high_level_object, WeightedSumGate):
1950
+ return None
1951
+
1952
+ required_auxiliaries = (
1953
+ high_level_object.num_sum_qubits - 1 + int(high_level_object.num_sum_qubits > 2)
1954
+ )
1955
+ if (num_clean := options.get("num_clean_ancillas", 0)) < required_auxiliaries:
1956
+ warnings.warn(
1957
+ f"Cannot synthesize a WeightedSumGate on {high_level_object.num_state_qubits} state "
1958
+ f"qubits with less than {required_auxiliaries} clean auxiliary qubits. Only "
1959
+ f"{num_clean} are available. This will likely lead to a error in HighLevelSynthesis."
1960
+ )
1961
+ return None
1962
+
1963
+ return synth_weighted_sum_carry(high_level_object)