qiskit 1.0.2__cp38-abi3-win_amd64.whl → 1.1.0__cp38-abi3-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (263) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +27 -16
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/_numpy_compat.py +73 -0
  5. qiskit/assembler/__init__.py +5 -10
  6. qiskit/assembler/disassemble.py +5 -6
  7. qiskit/circuit/__init__.py +1061 -232
  8. qiskit/circuit/_classical_resource_map.py +10 -6
  9. qiskit/circuit/_utils.py +18 -8
  10. qiskit/circuit/annotated_operation.py +21 -0
  11. qiskit/circuit/barrier.py +10 -13
  12. qiskit/circuit/bit.py +0 -1
  13. qiskit/circuit/classical/__init__.py +2 -2
  14. qiskit/circuit/classical/expr/__init__.py +39 -5
  15. qiskit/circuit/classical/expr/constructors.py +84 -1
  16. qiskit/circuit/classical/expr/expr.py +83 -13
  17. qiskit/circuit/classical/expr/visitors.py +83 -0
  18. qiskit/circuit/classical/types/__init__.py +5 -4
  19. qiskit/circuit/classicalfunction/__init__.py +1 -0
  20. qiskit/circuit/commutation_checker.py +86 -51
  21. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  22. qiskit/circuit/controlflow/break_loop.py +8 -22
  23. qiskit/circuit/controlflow/builder.py +116 -1
  24. qiskit/circuit/controlflow/continue_loop.py +8 -22
  25. qiskit/circuit/controlflow/control_flow.py +47 -8
  26. qiskit/circuit/controlflow/for_loop.py +8 -23
  27. qiskit/circuit/controlflow/if_else.py +13 -27
  28. qiskit/circuit/controlflow/switch_case.py +14 -21
  29. qiskit/circuit/controlflow/while_loop.py +9 -23
  30. qiskit/circuit/controlledgate.py +2 -2
  31. qiskit/circuit/delay.py +7 -5
  32. qiskit/circuit/gate.py +20 -7
  33. qiskit/circuit/instruction.py +31 -30
  34. qiskit/circuit/instructionset.py +9 -22
  35. qiskit/circuit/library/__init__.py +3 -13
  36. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  37. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  38. qiskit/circuit/library/blueprintcircuit.py +29 -7
  39. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  40. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  41. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  42. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  43. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  44. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  45. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  46. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  47. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  48. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  49. qiskit/circuit/library/n_local/n_local.py +100 -49
  50. qiskit/circuit/library/n_local/two_local.py +3 -59
  51. qiskit/circuit/library/overlap.py +3 -3
  52. qiskit/circuit/library/phase_oracle.py +1 -1
  53. qiskit/circuit/library/quantum_volume.py +39 -38
  54. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  55. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  56. qiskit/circuit/library/standard_gates/i.py +1 -2
  57. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  58. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  59. qiskit/circuit/library/standard_gates/p.py +31 -15
  60. qiskit/circuit/library/standard_gates/r.py +4 -3
  61. qiskit/circuit/library/standard_gates/rx.py +7 -4
  62. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  63. qiskit/circuit/library/standard_gates/ry.py +7 -4
  64. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  65. qiskit/circuit/library/standard_gates/rz.py +7 -4
  66. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  67. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  68. qiskit/circuit/library/standard_gates/s.py +4 -8
  69. qiskit/circuit/library/standard_gates/t.py +2 -4
  70. qiskit/circuit/library/standard_gates/u.py +16 -11
  71. qiskit/circuit/library/standard_gates/u1.py +6 -2
  72. qiskit/circuit/library/standard_gates/u2.py +4 -2
  73. qiskit/circuit/library/standard_gates/u3.py +9 -5
  74. qiskit/circuit/library/standard_gates/x.py +22 -11
  75. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  76. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  77. qiskit/circuit/library/standard_gates/z.py +1 -2
  78. qiskit/circuit/measure.py +4 -1
  79. qiskit/circuit/operation.py +13 -8
  80. qiskit/circuit/parameter.py +11 -6
  81. qiskit/circuit/quantumcircuit.py +1910 -260
  82. qiskit/circuit/quantumcircuitdata.py +2 -2
  83. qiskit/circuit/reset.py +5 -2
  84. qiskit/circuit/store.py +95 -0
  85. qiskit/compiler/assembler.py +22 -22
  86. qiskit/compiler/transpiler.py +63 -112
  87. qiskit/converters/__init__.py +17 -2
  88. qiskit/converters/circuit_to_dag.py +7 -0
  89. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  90. qiskit/converters/circuit_to_gate.py +2 -0
  91. qiskit/converters/circuit_to_instruction.py +22 -0
  92. qiskit/converters/dag_to_circuit.py +4 -0
  93. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  94. qiskit/dagcircuit/collect_blocks.py +15 -10
  95. qiskit/dagcircuit/dagcircuit.py +434 -124
  96. qiskit/dagcircuit/dagdependency.py +19 -12
  97. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  98. qiskit/dagcircuit/dagdepnode.py +19 -16
  99. qiskit/dagcircuit/dagnode.py +14 -4
  100. qiskit/passmanager/passmanager.py +11 -11
  101. qiskit/primitives/__init__.py +22 -12
  102. qiskit/primitives/backend_estimator.py +3 -5
  103. qiskit/primitives/backend_estimator_v2.py +410 -0
  104. qiskit/primitives/backend_sampler_v2.py +287 -0
  105. qiskit/primitives/base/base_estimator.py +4 -9
  106. qiskit/primitives/base/base_sampler.py +2 -2
  107. qiskit/primitives/containers/__init__.py +6 -4
  108. qiskit/primitives/containers/bit_array.py +293 -2
  109. qiskit/primitives/containers/data_bin.py +123 -50
  110. qiskit/primitives/containers/estimator_pub.py +10 -3
  111. qiskit/primitives/containers/observables_array.py +2 -2
  112. qiskit/primitives/containers/pub_result.py +1 -1
  113. qiskit/primitives/containers/sampler_pub.py +19 -3
  114. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  115. qiskit/primitives/containers/shape.py +4 -4
  116. qiskit/primitives/statevector_estimator.py +4 -4
  117. qiskit/primitives/statevector_sampler.py +7 -12
  118. qiskit/providers/__init__.py +65 -34
  119. qiskit/providers/backend.py +2 -2
  120. qiskit/providers/backend_compat.py +8 -10
  121. qiskit/providers/basic_provider/__init__.py +2 -23
  122. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  123. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  124. qiskit/providers/fake_provider/__init__.py +1 -1
  125. qiskit/providers/fake_provider/fake_1q.py +1 -1
  126. qiskit/providers/fake_provider/fake_backend.py +3 -408
  127. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  128. qiskit/providers/models/__init__.py +2 -2
  129. qiskit/providers/provider.py +16 -0
  130. qiskit/pulse/builder.py +4 -1
  131. qiskit/pulse/parameter_manager.py +60 -4
  132. qiskit/pulse/schedule.py +29 -13
  133. qiskit/pulse/utils.py +61 -20
  134. qiskit/qasm2/__init__.py +1 -5
  135. qiskit/qasm2/parse.py +1 -4
  136. qiskit/qasm3/__init__.py +42 -5
  137. qiskit/qasm3/ast.py +19 -0
  138. qiskit/qasm3/exporter.py +178 -106
  139. qiskit/qasm3/printer.py +27 -5
  140. qiskit/qobj/converters/pulse_instruction.py +6 -6
  141. qiskit/qpy/__init__.py +299 -67
  142. qiskit/qpy/binary_io/circuits.py +216 -47
  143. qiskit/qpy/binary_io/schedules.py +42 -36
  144. qiskit/qpy/binary_io/value.py +201 -22
  145. qiskit/qpy/common.py +1 -1
  146. qiskit/qpy/exceptions.py +20 -0
  147. qiskit/qpy/formats.py +29 -0
  148. qiskit/qpy/type_keys.py +21 -0
  149. qiskit/quantum_info/analysis/distance.py +3 -3
  150. qiskit/quantum_info/analysis/make_observable.py +2 -1
  151. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  152. qiskit/quantum_info/operators/channel/chi.py +9 -8
  153. qiskit/quantum_info/operators/channel/choi.py +10 -9
  154. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  155. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  156. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  157. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  158. qiskit/quantum_info/operators/channel/superop.py +12 -11
  159. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  160. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  161. qiskit/quantum_info/operators/operator.py +43 -30
  162. qiskit/quantum_info/operators/scalar_op.py +10 -9
  163. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  164. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  165. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  166. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  167. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  168. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  169. qiskit/quantum_info/states/densitymatrix.py +13 -13
  170. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  171. qiskit/quantum_info/states/statevector.py +14 -13
  172. qiskit/quantum_info/states/utils.py +5 -3
  173. qiskit/result/__init__.py +6 -0
  174. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  175. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  176. qiskit/result/mitigation/utils.py +3 -2
  177. qiskit/scheduler/__init__.py +10 -1
  178. qiskit/scheduler/methods/__init__.py +1 -8
  179. qiskit/synthesis/__init__.py +3 -6
  180. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  181. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  182. qiskit/synthesis/evolution/qdrift.py +3 -4
  183. qiskit/synthesis/linear/cnot_synth.py +1 -3
  184. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  185. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  186. qiskit/synthesis/permutation/__init__.py +1 -0
  187. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  188. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  189. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  190. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  191. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  192. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  193. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  194. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  195. qiskit/synthesis/unitary/qsd.py +3 -2
  196. qiskit/transpiler/__init__.py +7 -3
  197. qiskit/transpiler/layout.py +140 -61
  198. qiskit/transpiler/passes/__init__.py +10 -2
  199. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  200. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  201. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  202. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  203. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  204. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  205. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  206. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  207. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  208. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  209. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  210. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  211. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  212. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  213. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  214. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  215. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  216. qiskit/transpiler/passes/routing/__init__.py +1 -0
  217. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  218. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  219. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  220. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  221. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  222. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  223. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  224. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  225. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  226. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  227. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  228. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  229. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  230. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  231. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  232. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  233. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  234. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  235. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  236. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  237. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  238. qiskit/transpiler/passmanager.py +44 -1
  239. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  240. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  241. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  242. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  243. qiskit/utils/__init__.py +3 -2
  244. qiskit/utils/optionals.py +6 -2
  245. qiskit/utils/parallel.py +24 -15
  246. qiskit/visualization/array.py +1 -1
  247. qiskit/visualization/bloch.py +2 -3
  248. qiskit/visualization/circuit/matplotlib.py +44 -14
  249. qiskit/visualization/circuit/text.py +38 -18
  250. qiskit/visualization/counts_visualization.py +3 -6
  251. qiskit/visualization/dag_visualization.py +6 -7
  252. qiskit/visualization/gate_map.py +9 -1
  253. qiskit/visualization/pulse_v2/interface.py +8 -3
  254. qiskit/visualization/state_visualization.py +3 -2
  255. qiskit/visualization/timeline/interface.py +18 -8
  256. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  257. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/RECORD +261 -251
  258. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  259. qiskit/_qasm2.pyd +0 -0
  260. qiskit/_qasm3.pyd +0 -0
  261. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  262. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  263. {qiskit-1.0.2.dist-info → qiskit-1.1.0.dist-info}/top_level.txt +0 -0
@@ -40,13 +40,39 @@ from qiskit.circuit.annotated_operation import (
40
40
  from qiskit.circuit.instruction import Instruction
41
41
  from qiskit.circuit.quantumcircuit import QuantumCircuit
42
42
  from qiskit.circuit.quantumregister import QuantumRegister, Qubit
43
- from qiskit.qpy import common, formats, type_keys
43
+ from qiskit.qpy import common, formats, type_keys, exceptions
44
44
  from qiskit.qpy.binary_io import value, schedules
45
45
  from qiskit.quantum_info.operators import SparsePauliOp, Clifford
46
46
  from qiskit.synthesis import evolution as evo_synth
47
47
  from qiskit.transpiler.layout import Layout, TranspileLayout
48
48
 
49
49
 
50
+ def _read_header_v12(file_obj, version, vectors, metadata_deserializer=None):
51
+ data = formats.CIRCUIT_HEADER_V12._make(
52
+ struct.unpack(
53
+ formats.CIRCUIT_HEADER_V12_PACK, file_obj.read(formats.CIRCUIT_HEADER_V12_SIZE)
54
+ )
55
+ )
56
+ name = file_obj.read(data.name_size).decode(common.ENCODE)
57
+ global_phase = value.loads_value(
58
+ data.global_phase_type,
59
+ file_obj.read(data.global_phase_size),
60
+ version=version,
61
+ vectors=vectors,
62
+ )
63
+ header = {
64
+ "global_phase": global_phase,
65
+ "num_qubits": data.num_qubits,
66
+ "num_clbits": data.num_clbits,
67
+ "num_registers": data.num_registers,
68
+ "num_instructions": data.num_instructions,
69
+ "num_vars": data.num_vars,
70
+ }
71
+ metadata_raw = file_obj.read(data.metadata_size)
72
+ metadata = json.loads(metadata_raw, cls=metadata_deserializer)
73
+ return header, name, metadata
74
+
75
+
50
76
  def _read_header_v2(file_obj, version, vectors, metadata_deserializer=None):
51
77
  data = formats.CIRCUIT_HEADER_V2._make(
52
78
  struct.unpack(
@@ -133,7 +159,14 @@ def _read_registers(file_obj, num_registers):
133
159
 
134
160
 
135
161
  def _loads_instruction_parameter(
136
- type_key, data_bytes, version, vectors, registers, circuit, use_symengine
162
+ type_key,
163
+ data_bytes,
164
+ version,
165
+ vectors,
166
+ registers,
167
+ circuit,
168
+ use_symengine,
169
+ standalone_vars,
137
170
  ):
138
171
  if type_key == type_keys.Program.CIRCUIT:
139
172
  param = common.data_from_binary(data_bytes, read_circuit, version=version)
@@ -152,6 +185,7 @@ def _loads_instruction_parameter(
152
185
  registers=registers,
153
186
  circuit=circuit,
154
187
  use_symengine=use_symengine,
188
+ standalone_vars=standalone_vars,
155
189
  )
156
190
  )
157
191
  elif type_key == type_keys.Value.INTEGER:
@@ -172,6 +206,7 @@ def _loads_instruction_parameter(
172
206
  clbits=clbits,
173
207
  cregs=registers["c"],
174
208
  use_symengine=use_symengine,
209
+ standalone_vars=standalone_vars,
175
210
  )
176
211
 
177
212
  return param
@@ -186,7 +221,14 @@ def _loads_register_param(data_bytes, circuit, registers):
186
221
 
187
222
 
188
223
  def _read_instruction(
189
- file_obj, circuit, registers, custom_operations, version, vectors, use_symengine
224
+ file_obj,
225
+ circuit,
226
+ registers,
227
+ custom_operations,
228
+ version,
229
+ vectors,
230
+ use_symengine,
231
+ standalone_vars,
190
232
  ):
191
233
  if version < 5:
192
234
  instruction = formats.CIRCUIT_INSTRUCTION._make(
@@ -224,6 +266,7 @@ def _read_instruction(
224
266
  clbits=circuit.clbits,
225
267
  cregs=registers["c"],
226
268
  use_symengine=use_symengine,
269
+ standalone_vars=standalone_vars,
227
270
  )
228
271
  # Load Arguments
229
272
  if circuit is not None:
@@ -252,14 +295,28 @@ def _read_instruction(
252
295
  for _param in range(instruction.num_parameters):
253
296
  type_key, data_bytes = common.read_generic_typed_data(file_obj)
254
297
  param = _loads_instruction_parameter(
255
- type_key, data_bytes, version, vectors, registers, circuit, use_symengine
298
+ type_key,
299
+ data_bytes,
300
+ version,
301
+ vectors,
302
+ registers,
303
+ circuit,
304
+ use_symengine,
305
+ standalone_vars,
256
306
  )
257
307
  params.append(param)
258
308
 
259
309
  # Load Gate object
260
310
  if gate_name in {"Gate", "Instruction", "ControlledGate"}:
261
311
  inst_obj = _parse_custom_operation(
262
- custom_operations, gate_name, params, version, vectors, registers, use_symengine
312
+ custom_operations,
313
+ gate_name,
314
+ params,
315
+ version,
316
+ vectors,
317
+ registers,
318
+ use_symengine,
319
+ standalone_vars,
263
320
  )
264
321
  inst_obj.condition = condition
265
322
  if instruction.label_size > 0:
@@ -270,7 +327,14 @@ def _read_instruction(
270
327
  return None
271
328
  elif gate_name in custom_operations:
272
329
  inst_obj = _parse_custom_operation(
273
- custom_operations, gate_name, params, version, vectors, registers, use_symengine
330
+ custom_operations,
331
+ gate_name,
332
+ params,
333
+ version,
334
+ vectors,
335
+ registers,
336
+ use_symengine,
337
+ standalone_vars,
274
338
  )
275
339
  inst_obj.condition = condition
276
340
  if instruction.label_size > 0:
@@ -361,7 +425,14 @@ def _read_instruction(
361
425
 
362
426
 
363
427
  def _parse_custom_operation(
364
- custom_operations, gate_name, params, version, vectors, registers, use_symengine
428
+ custom_operations,
429
+ gate_name,
430
+ params,
431
+ version,
432
+ vectors,
433
+ registers,
434
+ use_symengine,
435
+ standalone_vars,
365
436
  ):
366
437
  if version >= 5:
367
438
  (
@@ -394,7 +465,14 @@ def _parse_custom_operation(
394
465
  if version >= 5 and type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
395
466
  with io.BytesIO(base_gate_raw) as base_gate_obj:
396
467
  base_gate = _read_instruction(
397
- base_gate_obj, None, registers, custom_operations, version, vectors, use_symengine
468
+ base_gate_obj,
469
+ None,
470
+ registers,
471
+ custom_operations,
472
+ version,
473
+ vectors,
474
+ use_symengine,
475
+ standalone_vars,
398
476
  )
399
477
  if ctrl_state < 2**num_ctrl_qubits - 1:
400
478
  # If open controls, we need to discard the control suffix when setting the name.
@@ -413,7 +491,14 @@ def _parse_custom_operation(
413
491
  if version >= 11 and type_key == type_keys.CircuitInstruction.ANNOTATED_OPERATION:
414
492
  with io.BytesIO(base_gate_raw) as base_gate_obj:
415
493
  base_gate = _read_instruction(
416
- base_gate_obj, None, registers, custom_operations, version, vectors, use_symengine
494
+ base_gate_obj,
495
+ None,
496
+ registers,
497
+ custom_operations,
498
+ version,
499
+ vectors,
500
+ use_symengine,
501
+ standalone_vars,
417
502
  )
418
503
  inst_obj = AnnotatedOperation(base_op=base_gate, modifiers=params)
419
504
  return inst_obj
@@ -572,10 +657,12 @@ def _dumps_register(register, index_map):
572
657
  return b"\x00" + str(index_map["c"][register]).encode(common.ENCODE)
573
658
 
574
659
 
575
- def _dumps_instruction_parameter(param, index_map, use_symengine):
660
+ def _dumps_instruction_parameter(
661
+ param, index_map, use_symengine, *, version, standalone_var_indices
662
+ ):
576
663
  if isinstance(param, QuantumCircuit):
577
664
  type_key = type_keys.Program.CIRCUIT
578
- data_bytes = common.data_to_binary(param, write_circuit)
665
+ data_bytes = common.data_to_binary(param, write_circuit, version=version)
579
666
  elif isinstance(param, Modifier):
580
667
  type_key = type_keys.Value.MODIFIER
581
668
  data_bytes = common.data_to_binary(param, _write_modifier)
@@ -585,7 +672,12 @@ def _dumps_instruction_parameter(param, index_map, use_symengine):
585
672
  elif isinstance(param, tuple):
586
673
  type_key = type_keys.Container.TUPLE
587
674
  data_bytes = common.sequence_to_binary(
588
- param, _dumps_instruction_parameter, index_map=index_map, use_symengine=use_symengine
675
+ param,
676
+ _dumps_instruction_parameter,
677
+ index_map=index_map,
678
+ use_symengine=use_symengine,
679
+ version=version,
680
+ standalone_var_indices=standalone_var_indices,
589
681
  )
590
682
  elif isinstance(param, int):
591
683
  # TODO This uses little endian. This should be fixed in next QPY version.
@@ -600,14 +692,26 @@ def _dumps_instruction_parameter(param, index_map, use_symengine):
600
692
  data_bytes = _dumps_register(param, index_map)
601
693
  else:
602
694
  type_key, data_bytes = value.dumps_value(
603
- param, index_map=index_map, use_symengine=use_symengine
695
+ param,
696
+ index_map=index_map,
697
+ use_symengine=use_symengine,
698
+ standalone_var_indices=standalone_var_indices,
699
+ version=version,
604
700
  )
605
701
 
606
702
  return type_key, data_bytes
607
703
 
608
704
 
609
705
  # pylint: disable=too-many-boolean-expressions
610
- def _write_instruction(file_obj, instruction, custom_operations, index_map, use_symengine, version):
706
+ def _write_instruction(
707
+ file_obj,
708
+ instruction,
709
+ custom_operations,
710
+ index_map,
711
+ use_symengine,
712
+ version,
713
+ standalone_var_indices=None,
714
+ ):
611
715
  if isinstance(instruction.operation, Instruction):
612
716
  gate_class_name = instruction.operation.base_class.__name__
613
717
  else:
@@ -702,7 +806,13 @@ def _write_instruction(file_obj, instruction, custom_operations, index_map, use_
702
806
  file_obj.write(gate_class_name)
703
807
  file_obj.write(label_raw)
704
808
  if condition_type is type_keys.Condition.EXPRESSION:
705
- value.write_value(file_obj, op_condition, index_map=index_map)
809
+ value.write_value(
810
+ file_obj,
811
+ op_condition,
812
+ version=version,
813
+ index_map=index_map,
814
+ standalone_var_indices=standalone_var_indices,
815
+ )
706
816
  else:
707
817
  file_obj.write(condition_register)
708
818
  # Encode instruction args
@@ -718,12 +828,18 @@ def _write_instruction(file_obj, instruction, custom_operations, index_map, use_
718
828
  file_obj.write(instruction_arg_raw)
719
829
  # Encode instruction params
720
830
  for param in instruction_params:
721
- type_key, data_bytes = _dumps_instruction_parameter(param, index_map, use_symengine)
831
+ type_key, data_bytes = _dumps_instruction_parameter(
832
+ param,
833
+ index_map,
834
+ use_symengine,
835
+ version=version,
836
+ standalone_var_indices=standalone_var_indices,
837
+ )
722
838
  common.write_generic_typed_data(file_obj, type_key, data_bytes)
723
839
  return custom_operations_list
724
840
 
725
841
 
726
- def _write_pauli_evolution_gate(file_obj, evolution_gate):
842
+ def _write_pauli_evolution_gate(file_obj, evolution_gate, version):
727
843
  operator_list = evolution_gate.operator
728
844
  standalone = False
729
845
  if not isinstance(operator_list, list):
@@ -742,7 +858,7 @@ def _write_pauli_evolution_gate(file_obj, evolution_gate):
742
858
  data = common.data_to_binary(operator, _write_elem)
743
859
  pauli_data_buf.write(data)
744
860
 
745
- time_type, time_data = value.dumps_value(evolution_gate.time)
861
+ time_type, time_data = value.dumps_value(evolution_gate.time, version=version)
746
862
  time_size = len(time_data)
747
863
  synth_class = str(type(evolution_gate.synthesis).__name__)
748
864
  settings_dict = evolution_gate.synthesis.settings
@@ -788,7 +904,9 @@ def _write_modifier(file_obj, modifier):
788
904
  file_obj.write(modifier_data)
789
905
 
790
906
 
791
- def _write_custom_operation(file_obj, name, operation, custom_operations, use_symengine, version):
907
+ def _write_custom_operation(
908
+ file_obj, name, operation, custom_operations, use_symengine, version, *, standalone_var_indices
909
+ ):
792
910
  type_key = type_keys.CircuitInstruction.assign(operation)
793
911
  has_definition = False
794
912
  size = 0
@@ -802,7 +920,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
802
920
 
803
921
  if type_key == type_keys.CircuitInstruction.PAULI_EVOL_GATE:
804
922
  has_definition = True
805
- data = common.data_to_binary(operation, _write_pauli_evolution_gate)
923
+ data = common.data_to_binary(operation, _write_pauli_evolution_gate, version=version)
806
924
  size = len(data)
807
925
  elif type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
808
926
  # For ControlledGate, we have to access and store the private `_definition` rather than the
@@ -813,7 +931,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
813
931
  # Build internal definition to support overloaded subclasses by
814
932
  # calling definition getter on object
815
933
  operation.definition # pylint: disable=pointless-statement
816
- data = common.data_to_binary(operation._definition, write_circuit)
934
+ data = common.data_to_binary(operation._definition, write_circuit, version=version)
817
935
  size = len(data)
818
936
  num_ctrl_qubits = operation.num_ctrl_qubits
819
937
  ctrl_state = operation.ctrl_state
@@ -823,7 +941,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
823
941
  base_gate = operation.base_op
824
942
  elif operation.definition is not None:
825
943
  has_definition = True
826
- data = common.data_to_binary(operation.definition, write_circuit)
944
+ data = common.data_to_binary(operation.definition, write_circuit, version=version)
827
945
  size = len(data)
828
946
  if base_gate is None:
829
947
  base_gate_raw = b""
@@ -836,6 +954,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
836
954
  {},
837
955
  use_symengine,
838
956
  version,
957
+ standalone_var_indices=standalone_var_indices,
839
958
  )
840
959
  base_gate_raw = base_gate_buffer.getvalue()
841
960
  name_raw = name.encode(common.ENCODE)
@@ -859,7 +978,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
859
978
  return new_custom_instruction
860
979
 
861
980
 
862
- def _write_calibrations(file_obj, calibrations, metadata_serializer):
981
+ def _write_calibrations(file_obj, calibrations, metadata_serializer, version):
863
982
  flatten_dict = {}
864
983
  for gate, caldef in calibrations.items():
865
984
  for (qubits, params), schedule in caldef.items():
@@ -883,8 +1002,8 @@ def _write_calibrations(file_obj, calibrations, metadata_serializer):
883
1002
  for qubit in qubits:
884
1003
  file_obj.write(struct.pack("!q", qubit))
885
1004
  for param in params:
886
- value.write_value(file_obj, param)
887
- schedules.write_schedule_block(file_obj, schedule, metadata_serializer)
1005
+ value.write_value(file_obj, param, version=version)
1006
+ schedules.write_schedule_block(file_obj, schedule, metadata_serializer, version=version)
888
1007
 
889
1008
 
890
1009
  def _write_registers(file_obj, in_circ_regs, full_bits):
@@ -1094,7 +1213,7 @@ def write_circuit(
1094
1213
  metadata_size = len(metadata_raw)
1095
1214
  num_instructions = len(circuit)
1096
1215
  circuit_name = circuit.name.encode(common.ENCODE)
1097
- global_phase_type, global_phase_data = value.dumps_value(circuit.global_phase)
1216
+ global_phase_type, global_phase_data = value.dumps_value(circuit.global_phase, version=version)
1098
1217
 
1099
1218
  with io.BytesIO() as reg_buf:
1100
1219
  num_qregs = _write_registers(reg_buf, circuit.qregs, circuit.qubits)
@@ -1103,23 +1222,49 @@ def write_circuit(
1103
1222
  num_registers = num_qregs + num_cregs
1104
1223
 
1105
1224
  # Write circuit header
1106
- header_raw = formats.CIRCUIT_HEADER_V2(
1107
- name_size=len(circuit_name),
1108
- global_phase_type=global_phase_type,
1109
- global_phase_size=len(global_phase_data),
1110
- num_qubits=circuit.num_qubits,
1111
- num_clbits=circuit.num_clbits,
1112
- metadata_size=metadata_size,
1113
- num_registers=num_registers,
1114
- num_instructions=num_instructions,
1115
- )
1116
- header = struct.pack(formats.CIRCUIT_HEADER_V2_PACK, *header_raw)
1117
- file_obj.write(header)
1118
- file_obj.write(circuit_name)
1119
- file_obj.write(global_phase_data)
1120
- file_obj.write(metadata_raw)
1121
- # Write header payload
1122
- file_obj.write(registers_raw)
1225
+ if version >= 12:
1226
+ header_raw = formats.CIRCUIT_HEADER_V12(
1227
+ name_size=len(circuit_name),
1228
+ global_phase_type=global_phase_type,
1229
+ global_phase_size=len(global_phase_data),
1230
+ num_qubits=circuit.num_qubits,
1231
+ num_clbits=circuit.num_clbits,
1232
+ metadata_size=metadata_size,
1233
+ num_registers=num_registers,
1234
+ num_instructions=num_instructions,
1235
+ num_vars=circuit.num_vars,
1236
+ )
1237
+ header = struct.pack(formats.CIRCUIT_HEADER_V12_PACK, *header_raw)
1238
+ file_obj.write(header)
1239
+ file_obj.write(circuit_name)
1240
+ file_obj.write(global_phase_data)
1241
+ file_obj.write(metadata_raw)
1242
+ # Write header payload
1243
+ file_obj.write(registers_raw)
1244
+ standalone_var_indices = value.write_standalone_vars(file_obj, circuit)
1245
+ else:
1246
+ if circuit.num_vars:
1247
+ raise exceptions.UnsupportedFeatureForVersion(
1248
+ "circuits containing realtime variables", required=12, target=version
1249
+ )
1250
+ header_raw = formats.CIRCUIT_HEADER_V2(
1251
+ name_size=len(circuit_name),
1252
+ global_phase_type=global_phase_type,
1253
+ global_phase_size=len(global_phase_data),
1254
+ num_qubits=circuit.num_qubits,
1255
+ num_clbits=circuit.num_clbits,
1256
+ metadata_size=metadata_size,
1257
+ num_registers=num_registers,
1258
+ num_instructions=num_instructions,
1259
+ )
1260
+ header = struct.pack(formats.CIRCUIT_HEADER_V2_PACK, *header_raw)
1261
+ file_obj.write(header)
1262
+ file_obj.write(circuit_name)
1263
+ file_obj.write(global_phase_data)
1264
+ file_obj.write(metadata_raw)
1265
+ file_obj.write(registers_raw)
1266
+ standalone_var_indices = {}
1267
+
1123
1268
  instruction_buffer = io.BytesIO()
1124
1269
  custom_operations = {}
1125
1270
  index_map = {}
@@ -1127,7 +1272,13 @@ def write_circuit(
1127
1272
  index_map["c"] = {bit: index for index, bit in enumerate(circuit.clbits)}
1128
1273
  for instruction in circuit.data:
1129
1274
  _write_instruction(
1130
- instruction_buffer, instruction, custom_operations, index_map, use_symengine, version
1275
+ instruction_buffer,
1276
+ instruction,
1277
+ custom_operations,
1278
+ index_map,
1279
+ use_symengine,
1280
+ version,
1281
+ standalone_var_indices=standalone_var_indices,
1131
1282
  )
1132
1283
 
1133
1284
  with io.BytesIO() as custom_operations_buffer:
@@ -1145,6 +1296,7 @@ def write_circuit(
1145
1296
  custom_operations,
1146
1297
  use_symengine,
1147
1298
  version,
1299
+ standalone_var_indices=standalone_var_indices,
1148
1300
  )
1149
1301
  )
1150
1302
 
@@ -1155,7 +1307,7 @@ def write_circuit(
1155
1307
  instruction_buffer.close()
1156
1308
 
1157
1309
  # Write calibrations
1158
- _write_calibrations(file_obj, circuit.calibrations, metadata_serializer)
1310
+ _write_calibrations(file_obj, circuit.calibrations, metadata_serializer, version=version)
1159
1311
  _write_layout(file_obj, circuit)
1160
1312
 
1161
1313
 
@@ -1186,16 +1338,21 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1186
1338
  vectors = {}
1187
1339
  if version < 2:
1188
1340
  header, name, metadata = _read_header(file_obj, metadata_deserializer=metadata_deserializer)
1189
- else:
1341
+ elif version < 12:
1190
1342
  header, name, metadata = _read_header_v2(
1191
1343
  file_obj, version, vectors, metadata_deserializer=metadata_deserializer
1192
1344
  )
1345
+ else:
1346
+ header, name, metadata = _read_header_v12(
1347
+ file_obj, version, vectors, metadata_deserializer=metadata_deserializer
1348
+ )
1193
1349
 
1194
1350
  global_phase = header["global_phase"]
1195
1351
  num_qubits = header["num_qubits"]
1196
1352
  num_clbits = header["num_clbits"]
1197
1353
  num_registers = header["num_registers"]
1198
1354
  num_instructions = header["num_instructions"]
1355
+ num_vars = header.get("num_vars", 0)
1199
1356
  # `out_registers` is two "name: register" maps segregated by type for the rest of QPY, and
1200
1357
  # `all_registers` is the complete ordered list used to construct the `QuantumCircuit`.
1201
1358
  out_registers = {"q": {}, "c": {}}
@@ -1252,6 +1409,7 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1252
1409
  "q": [Qubit() for _ in out_bits["q"]],
1253
1410
  "c": [Clbit() for _ in out_bits["c"]],
1254
1411
  }
1412
+ var_segments, standalone_var_indices = value.read_standalone_vars(file_obj, num_vars)
1255
1413
  circ = QuantumCircuit(
1256
1414
  out_bits["q"],
1257
1415
  out_bits["c"],
@@ -1259,11 +1417,22 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1259
1417
  name=name,
1260
1418
  global_phase=global_phase,
1261
1419
  metadata=metadata,
1420
+ inputs=var_segments[type_keys.ExprVarDeclaration.INPUT],
1421
+ captures=var_segments[type_keys.ExprVarDeclaration.CAPTURE],
1262
1422
  )
1423
+ for declaration in var_segments[type_keys.ExprVarDeclaration.LOCAL]:
1424
+ circ.add_uninitialized_var(declaration)
1263
1425
  custom_operations = _read_custom_operations(file_obj, version, vectors)
1264
1426
  for _instruction in range(num_instructions):
1265
1427
  _read_instruction(
1266
- file_obj, circ, out_registers, custom_operations, version, vectors, use_symengine
1428
+ file_obj,
1429
+ circ,
1430
+ out_registers,
1431
+ custom_operations,
1432
+ version,
1433
+ vectors,
1434
+ use_symengine,
1435
+ standalone_var_indices,
1267
1436
  )
1268
1437
 
1269
1438
  # Read calibrations