qiskit 1.0.1__cp38-abi3-win32.whl → 1.1.0__cp38-abi3-win32.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (266) 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/equivalence.py +14 -8
  33. qiskit/circuit/gate.py +20 -7
  34. qiskit/circuit/instruction.py +31 -30
  35. qiskit/circuit/instructionset.py +9 -22
  36. qiskit/circuit/library/__init__.py +3 -13
  37. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  38. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  39. qiskit/circuit/library/blueprintcircuit.py +29 -7
  40. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  41. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  42. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  43. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  44. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  45. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  46. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  47. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  48. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  49. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  50. qiskit/circuit/library/n_local/evolved_operator_ansatz.py +7 -2
  51. qiskit/circuit/library/n_local/n_local.py +100 -49
  52. qiskit/circuit/library/n_local/two_local.py +3 -59
  53. qiskit/circuit/library/overlap.py +3 -3
  54. qiskit/circuit/library/phase_oracle.py +1 -1
  55. qiskit/circuit/library/quantum_volume.py +39 -38
  56. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  57. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  58. qiskit/circuit/library/standard_gates/i.py +1 -2
  59. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  60. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  61. qiskit/circuit/library/standard_gates/p.py +31 -15
  62. qiskit/circuit/library/standard_gates/r.py +4 -3
  63. qiskit/circuit/library/standard_gates/rx.py +7 -4
  64. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  65. qiskit/circuit/library/standard_gates/ry.py +7 -4
  66. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  67. qiskit/circuit/library/standard_gates/rz.py +7 -4
  68. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  69. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  70. qiskit/circuit/library/standard_gates/s.py +4 -8
  71. qiskit/circuit/library/standard_gates/t.py +2 -4
  72. qiskit/circuit/library/standard_gates/u.py +16 -11
  73. qiskit/circuit/library/standard_gates/u1.py +6 -2
  74. qiskit/circuit/library/standard_gates/u2.py +4 -2
  75. qiskit/circuit/library/standard_gates/u3.py +9 -5
  76. qiskit/circuit/library/standard_gates/x.py +22 -11
  77. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  78. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  79. qiskit/circuit/library/standard_gates/z.py +1 -2
  80. qiskit/circuit/measure.py +4 -1
  81. qiskit/circuit/operation.py +13 -8
  82. qiskit/circuit/parameter.py +12 -7
  83. qiskit/circuit/quantumcircuit.py +1910 -260
  84. qiskit/circuit/quantumcircuitdata.py +2 -2
  85. qiskit/circuit/reset.py +5 -2
  86. qiskit/circuit/store.py +95 -0
  87. qiskit/compiler/assembler.py +22 -22
  88. qiskit/compiler/transpiler.py +63 -112
  89. qiskit/converters/__init__.py +17 -2
  90. qiskit/converters/circuit_to_dag.py +7 -0
  91. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  92. qiskit/converters/circuit_to_gate.py +2 -0
  93. qiskit/converters/circuit_to_instruction.py +22 -0
  94. qiskit/converters/dag_to_circuit.py +4 -0
  95. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  96. qiskit/dagcircuit/collect_blocks.py +15 -10
  97. qiskit/dagcircuit/dagcircuit.py +434 -124
  98. qiskit/dagcircuit/dagdependency.py +19 -12
  99. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  100. qiskit/dagcircuit/dagdepnode.py +19 -16
  101. qiskit/dagcircuit/dagnode.py +14 -4
  102. qiskit/passmanager/passmanager.py +11 -11
  103. qiskit/primitives/__init__.py +22 -12
  104. qiskit/primitives/backend_estimator.py +3 -5
  105. qiskit/primitives/backend_estimator_v2.py +410 -0
  106. qiskit/primitives/backend_sampler_v2.py +287 -0
  107. qiskit/primitives/base/base_estimator.py +4 -9
  108. qiskit/primitives/base/base_sampler.py +2 -2
  109. qiskit/primitives/containers/__init__.py +6 -4
  110. qiskit/primitives/containers/bit_array.py +293 -2
  111. qiskit/primitives/containers/data_bin.py +123 -50
  112. qiskit/primitives/containers/estimator_pub.py +11 -4
  113. qiskit/primitives/containers/observables_array.py +2 -4
  114. qiskit/primitives/containers/pub_result.py +1 -1
  115. qiskit/primitives/containers/sampler_pub.py +20 -4
  116. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  117. qiskit/primitives/containers/shape.py +4 -4
  118. qiskit/primitives/statevector_estimator.py +6 -6
  119. qiskit/primitives/statevector_sampler.py +7 -12
  120. qiskit/providers/__init__.py +65 -34
  121. qiskit/providers/backend.py +2 -2
  122. qiskit/providers/backend_compat.py +28 -19
  123. qiskit/providers/basic_provider/__init__.py +2 -23
  124. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  125. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  126. qiskit/providers/fake_provider/__init__.py +1 -1
  127. qiskit/providers/fake_provider/fake_1q.py +1 -1
  128. qiskit/providers/fake_provider/fake_backend.py +3 -408
  129. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  130. qiskit/providers/models/__init__.py +2 -2
  131. qiskit/providers/provider.py +16 -0
  132. qiskit/pulse/builder.py +4 -1
  133. qiskit/pulse/parameter_manager.py +60 -4
  134. qiskit/pulse/schedule.py +29 -13
  135. qiskit/pulse/utils.py +61 -20
  136. qiskit/qasm2/__init__.py +1 -5
  137. qiskit/qasm2/parse.py +1 -4
  138. qiskit/qasm3/__init__.py +42 -5
  139. qiskit/qasm3/ast.py +19 -0
  140. qiskit/qasm3/exporter.py +178 -106
  141. qiskit/qasm3/printer.py +27 -5
  142. qiskit/qobj/converters/pulse_instruction.py +6 -6
  143. qiskit/qpy/__init__.py +299 -67
  144. qiskit/qpy/binary_io/circuits.py +218 -56
  145. qiskit/qpy/binary_io/schedules.py +42 -36
  146. qiskit/qpy/binary_io/value.py +201 -22
  147. qiskit/qpy/common.py +1 -1
  148. qiskit/qpy/exceptions.py +20 -0
  149. qiskit/qpy/formats.py +29 -0
  150. qiskit/qpy/type_keys.py +21 -0
  151. qiskit/quantum_info/analysis/distance.py +3 -3
  152. qiskit/quantum_info/analysis/make_observable.py +2 -1
  153. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  154. qiskit/quantum_info/operators/channel/chi.py +9 -8
  155. qiskit/quantum_info/operators/channel/choi.py +10 -9
  156. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  157. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  158. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  159. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  160. qiskit/quantum_info/operators/channel/superop.py +12 -11
  161. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  162. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  163. qiskit/quantum_info/operators/operator.py +43 -30
  164. qiskit/quantum_info/operators/scalar_op.py +10 -9
  165. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  166. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  167. qiskit/quantum_info/operators/symplectic/pauli.py +53 -6
  168. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  169. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  170. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +61 -36
  171. qiskit/quantum_info/states/densitymatrix.py +13 -13
  172. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  173. qiskit/quantum_info/states/statevector.py +14 -13
  174. qiskit/quantum_info/states/utils.py +5 -3
  175. qiskit/result/__init__.py +6 -0
  176. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  177. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  178. qiskit/result/mitigation/utils.py +3 -2
  179. qiskit/scheduler/__init__.py +10 -1
  180. qiskit/scheduler/methods/__init__.py +1 -8
  181. qiskit/synthesis/__init__.py +3 -6
  182. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  183. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  184. qiskit/synthesis/evolution/qdrift.py +3 -4
  185. qiskit/synthesis/linear/cnot_synth.py +1 -3
  186. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  187. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  188. qiskit/synthesis/permutation/__init__.py +1 -0
  189. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  190. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  191. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  192. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  193. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  194. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  195. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  196. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  197. qiskit/synthesis/unitary/qsd.py +3 -2
  198. qiskit/transpiler/__init__.py +7 -3
  199. qiskit/transpiler/layout.py +140 -61
  200. qiskit/transpiler/passes/__init__.py +10 -2
  201. qiskit/transpiler/passes/basis/basis_translator.py +9 -4
  202. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  203. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  204. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  205. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  206. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  207. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  208. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  209. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  210. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  211. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  212. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  213. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  214. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  215. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  216. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  217. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  218. qiskit/transpiler/passes/routing/__init__.py +1 -0
  219. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  220. qiskit/transpiler/passes/routing/commuting_2q_gate_routing/commuting_2q_gate_router.py +8 -1
  221. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  222. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  223. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  224. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  225. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  226. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  227. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  228. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  229. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  230. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  231. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  232. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  233. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  234. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  235. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  236. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  237. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  238. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  239. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  240. qiskit/transpiler/passmanager.py +44 -1
  241. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  242. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  243. qiskit/transpiler/preset_passmanagers/common.py +9 -8
  244. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  245. qiskit/utils/__init__.py +21 -8
  246. qiskit/utils/optionals.py +9 -5
  247. qiskit/utils/parallel.py +24 -15
  248. qiskit/visualization/array.py +1 -1
  249. qiskit/visualization/bloch.py +2 -3
  250. qiskit/visualization/circuit/matplotlib.py +44 -14
  251. qiskit/visualization/circuit/qcstyle.py +3 -3
  252. qiskit/visualization/circuit/text.py +38 -18
  253. qiskit/visualization/counts_visualization.py +3 -6
  254. qiskit/visualization/dag_visualization.py +6 -7
  255. qiskit/visualization/gate_map.py +9 -1
  256. qiskit/visualization/pulse_v2/interface.py +8 -3
  257. qiskit/visualization/state_visualization.py +3 -2
  258. qiskit/visualization/timeline/interface.py +18 -8
  259. {qiskit-1.0.1.dist-info → qiskit-1.1.0.dist-info}/METADATA +12 -8
  260. {qiskit-1.0.1.dist-info → qiskit-1.1.0.dist-info}/RECORD +264 -254
  261. {qiskit-1.0.1.dist-info → qiskit-1.1.0.dist-info}/WHEEL +1 -1
  262. qiskit/_qasm2.pyd +0 -0
  263. qiskit/_qasm3.pyd +0 -0
  264. {qiskit-1.0.1.dist-info → qiskit-1.1.0.dist-info}/LICENSE.txt +0 -0
  265. {qiskit-1.0.1.dist-info → qiskit-1.1.0.dist-info}/entry_points.txt +0 -0
  266. {qiskit-1.0.1.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,14 +266,8 @@ 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
- if circuit is not None:
229
- qubit_indices = dict(enumerate(circuit.qubits))
230
- clbit_indices = dict(enumerate(circuit.clbits))
231
- else:
232
- qubit_indices = {}
233
- clbit_indices = {}
234
-
235
271
  # Load Arguments
236
272
  if circuit is not None:
237
273
  for _qarg in range(instruction.num_qargs):
@@ -243,7 +279,7 @@ def _read_instruction(
243
279
  )
244
280
  if qarg.type.decode(common.ENCODE) == "c":
245
281
  raise TypeError("Invalid input carg prior to all qargs")
246
- qargs.append(qubit_indices[qarg.size])
282
+ qargs.append(circuit.qubits[qarg.size])
247
283
  for _carg in range(instruction.num_cargs):
248
284
  carg = formats.CIRCUIT_INSTRUCTION_ARG._make(
249
285
  struct.unpack(
@@ -253,20 +289,34 @@ def _read_instruction(
253
289
  )
254
290
  if carg.type.decode(common.ENCODE) == "q":
255
291
  raise TypeError("Invalid input qarg after all qargs")
256
- cargs.append(clbit_indices[carg.size])
292
+ cargs.append(circuit.clbits[carg.size])
257
293
 
258
294
  # Load Parameters
259
295
  for _param in range(instruction.num_parameters):
260
296
  type_key, data_bytes = common.read_generic_typed_data(file_obj)
261
297
  param = _loads_instruction_parameter(
262
- 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,
263
306
  )
264
307
  params.append(param)
265
308
 
266
309
  # Load Gate object
267
310
  if gate_name in {"Gate", "Instruction", "ControlledGate"}:
268
311
  inst_obj = _parse_custom_operation(
269
- 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,
270
320
  )
271
321
  inst_obj.condition = condition
272
322
  if instruction.label_size > 0:
@@ -277,7 +327,14 @@ def _read_instruction(
277
327
  return None
278
328
  elif gate_name in custom_operations:
279
329
  inst_obj = _parse_custom_operation(
280
- 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,
281
338
  )
282
339
  inst_obj.condition = condition
283
340
  if instruction.label_size > 0:
@@ -368,7 +425,14 @@ def _read_instruction(
368
425
 
369
426
 
370
427
  def _parse_custom_operation(
371
- 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,
372
436
  ):
373
437
  if version >= 5:
374
438
  (
@@ -401,7 +465,14 @@ def _parse_custom_operation(
401
465
  if version >= 5 and type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
402
466
  with io.BytesIO(base_gate_raw) as base_gate_obj:
403
467
  base_gate = _read_instruction(
404
- 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,
405
476
  )
406
477
  if ctrl_state < 2**num_ctrl_qubits - 1:
407
478
  # If open controls, we need to discard the control suffix when setting the name.
@@ -420,7 +491,14 @@ def _parse_custom_operation(
420
491
  if version >= 11 and type_key == type_keys.CircuitInstruction.ANNOTATED_OPERATION:
421
492
  with io.BytesIO(base_gate_raw) as base_gate_obj:
422
493
  base_gate = _read_instruction(
423
- 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,
424
502
  )
425
503
  inst_obj = AnnotatedOperation(base_op=base_gate, modifiers=params)
426
504
  return inst_obj
@@ -579,10 +657,12 @@ def _dumps_register(register, index_map):
579
657
  return b"\x00" + str(index_map["c"][register]).encode(common.ENCODE)
580
658
 
581
659
 
582
- 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
+ ):
583
663
  if isinstance(param, QuantumCircuit):
584
664
  type_key = type_keys.Program.CIRCUIT
585
- data_bytes = common.data_to_binary(param, write_circuit)
665
+ data_bytes = common.data_to_binary(param, write_circuit, version=version)
586
666
  elif isinstance(param, Modifier):
587
667
  type_key = type_keys.Value.MODIFIER
588
668
  data_bytes = common.data_to_binary(param, _write_modifier)
@@ -592,7 +672,12 @@ def _dumps_instruction_parameter(param, index_map, use_symengine):
592
672
  elif isinstance(param, tuple):
593
673
  type_key = type_keys.Container.TUPLE
594
674
  data_bytes = common.sequence_to_binary(
595
- 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,
596
681
  )
597
682
  elif isinstance(param, int):
598
683
  # TODO This uses little endian. This should be fixed in next QPY version.
@@ -607,14 +692,26 @@ def _dumps_instruction_parameter(param, index_map, use_symengine):
607
692
  data_bytes = _dumps_register(param, index_map)
608
693
  else:
609
694
  type_key, data_bytes = value.dumps_value(
610
- 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,
611
700
  )
612
701
 
613
702
  return type_key, data_bytes
614
703
 
615
704
 
616
705
  # pylint: disable=too-many-boolean-expressions
617
- 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
+ ):
618
715
  if isinstance(instruction.operation, Instruction):
619
716
  gate_class_name = instruction.operation.base_class.__name__
620
717
  else:
@@ -709,7 +806,13 @@ def _write_instruction(file_obj, instruction, custom_operations, index_map, use_
709
806
  file_obj.write(gate_class_name)
710
807
  file_obj.write(label_raw)
711
808
  if condition_type is type_keys.Condition.EXPRESSION:
712
- 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
+ )
713
816
  else:
714
817
  file_obj.write(condition_register)
715
818
  # Encode instruction args
@@ -725,12 +828,18 @@ def _write_instruction(file_obj, instruction, custom_operations, index_map, use_
725
828
  file_obj.write(instruction_arg_raw)
726
829
  # Encode instruction params
727
830
  for param in instruction_params:
728
- 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
+ )
729
838
  common.write_generic_typed_data(file_obj, type_key, data_bytes)
730
839
  return custom_operations_list
731
840
 
732
841
 
733
- def _write_pauli_evolution_gate(file_obj, evolution_gate):
842
+ def _write_pauli_evolution_gate(file_obj, evolution_gate, version):
734
843
  operator_list = evolution_gate.operator
735
844
  standalone = False
736
845
  if not isinstance(operator_list, list):
@@ -749,7 +858,7 @@ def _write_pauli_evolution_gate(file_obj, evolution_gate):
749
858
  data = common.data_to_binary(operator, _write_elem)
750
859
  pauli_data_buf.write(data)
751
860
 
752
- time_type, time_data = value.dumps_value(evolution_gate.time)
861
+ time_type, time_data = value.dumps_value(evolution_gate.time, version=version)
753
862
  time_size = len(time_data)
754
863
  synth_class = str(type(evolution_gate.synthesis).__name__)
755
864
  settings_dict = evolution_gate.synthesis.settings
@@ -795,7 +904,9 @@ def _write_modifier(file_obj, modifier):
795
904
  file_obj.write(modifier_data)
796
905
 
797
906
 
798
- 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
+ ):
799
910
  type_key = type_keys.CircuitInstruction.assign(operation)
800
911
  has_definition = False
801
912
  size = 0
@@ -809,7 +920,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
809
920
 
810
921
  if type_key == type_keys.CircuitInstruction.PAULI_EVOL_GATE:
811
922
  has_definition = True
812
- data = common.data_to_binary(operation, _write_pauli_evolution_gate)
923
+ data = common.data_to_binary(operation, _write_pauli_evolution_gate, version=version)
813
924
  size = len(data)
814
925
  elif type_key == type_keys.CircuitInstruction.CONTROLLED_GATE:
815
926
  # For ControlledGate, we have to access and store the private `_definition` rather than the
@@ -820,7 +931,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
820
931
  # Build internal definition to support overloaded subclasses by
821
932
  # calling definition getter on object
822
933
  operation.definition # pylint: disable=pointless-statement
823
- data = common.data_to_binary(operation._definition, write_circuit)
934
+ data = common.data_to_binary(operation._definition, write_circuit, version=version)
824
935
  size = len(data)
825
936
  num_ctrl_qubits = operation.num_ctrl_qubits
826
937
  ctrl_state = operation.ctrl_state
@@ -830,7 +941,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
830
941
  base_gate = operation.base_op
831
942
  elif operation.definition is not None:
832
943
  has_definition = True
833
- data = common.data_to_binary(operation.definition, write_circuit)
944
+ data = common.data_to_binary(operation.definition, write_circuit, version=version)
834
945
  size = len(data)
835
946
  if base_gate is None:
836
947
  base_gate_raw = b""
@@ -843,6 +954,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
843
954
  {},
844
955
  use_symengine,
845
956
  version,
957
+ standalone_var_indices=standalone_var_indices,
846
958
  )
847
959
  base_gate_raw = base_gate_buffer.getvalue()
848
960
  name_raw = name.encode(common.ENCODE)
@@ -866,7 +978,7 @@ def _write_custom_operation(file_obj, name, operation, custom_operations, use_sy
866
978
  return new_custom_instruction
867
979
 
868
980
 
869
- def _write_calibrations(file_obj, calibrations, metadata_serializer):
981
+ def _write_calibrations(file_obj, calibrations, metadata_serializer, version):
870
982
  flatten_dict = {}
871
983
  for gate, caldef in calibrations.items():
872
984
  for (qubits, params), schedule in caldef.items():
@@ -890,8 +1002,8 @@ def _write_calibrations(file_obj, calibrations, metadata_serializer):
890
1002
  for qubit in qubits:
891
1003
  file_obj.write(struct.pack("!q", qubit))
892
1004
  for param in params:
893
- value.write_value(file_obj, param)
894
- 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)
895
1007
 
896
1008
 
897
1009
  def _write_registers(file_obj, in_circ_regs, full_bits):
@@ -1101,7 +1213,7 @@ def write_circuit(
1101
1213
  metadata_size = len(metadata_raw)
1102
1214
  num_instructions = len(circuit)
1103
1215
  circuit_name = circuit.name.encode(common.ENCODE)
1104
- 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)
1105
1217
 
1106
1218
  with io.BytesIO() as reg_buf:
1107
1219
  num_qregs = _write_registers(reg_buf, circuit.qregs, circuit.qubits)
@@ -1110,23 +1222,49 @@ def write_circuit(
1110
1222
  num_registers = num_qregs + num_cregs
1111
1223
 
1112
1224
  # Write circuit header
1113
- header_raw = formats.CIRCUIT_HEADER_V2(
1114
- name_size=len(circuit_name),
1115
- global_phase_type=global_phase_type,
1116
- global_phase_size=len(global_phase_data),
1117
- num_qubits=circuit.num_qubits,
1118
- num_clbits=circuit.num_clbits,
1119
- metadata_size=metadata_size,
1120
- num_registers=num_registers,
1121
- num_instructions=num_instructions,
1122
- )
1123
- header = struct.pack(formats.CIRCUIT_HEADER_V2_PACK, *header_raw)
1124
- file_obj.write(header)
1125
- file_obj.write(circuit_name)
1126
- file_obj.write(global_phase_data)
1127
- file_obj.write(metadata_raw)
1128
- # Write header payload
1129
- 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
+
1130
1268
  instruction_buffer = io.BytesIO()
1131
1269
  custom_operations = {}
1132
1270
  index_map = {}
@@ -1134,7 +1272,13 @@ def write_circuit(
1134
1272
  index_map["c"] = {bit: index for index, bit in enumerate(circuit.clbits)}
1135
1273
  for instruction in circuit.data:
1136
1274
  _write_instruction(
1137
- 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,
1138
1282
  )
1139
1283
 
1140
1284
  with io.BytesIO() as custom_operations_buffer:
@@ -1152,6 +1296,7 @@ def write_circuit(
1152
1296
  custom_operations,
1153
1297
  use_symengine,
1154
1298
  version,
1299
+ standalone_var_indices=standalone_var_indices,
1155
1300
  )
1156
1301
  )
1157
1302
 
@@ -1162,7 +1307,7 @@ def write_circuit(
1162
1307
  instruction_buffer.close()
1163
1308
 
1164
1309
  # Write calibrations
1165
- _write_calibrations(file_obj, circuit.calibrations, metadata_serializer)
1310
+ _write_calibrations(file_obj, circuit.calibrations, metadata_serializer, version=version)
1166
1311
  _write_layout(file_obj, circuit)
1167
1312
 
1168
1313
 
@@ -1193,16 +1338,21 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1193
1338
  vectors = {}
1194
1339
  if version < 2:
1195
1340
  header, name, metadata = _read_header(file_obj, metadata_deserializer=metadata_deserializer)
1196
- else:
1341
+ elif version < 12:
1197
1342
  header, name, metadata = _read_header_v2(
1198
1343
  file_obj, version, vectors, metadata_deserializer=metadata_deserializer
1199
1344
  )
1345
+ else:
1346
+ header, name, metadata = _read_header_v12(
1347
+ file_obj, version, vectors, metadata_deserializer=metadata_deserializer
1348
+ )
1200
1349
 
1201
1350
  global_phase = header["global_phase"]
1202
1351
  num_qubits = header["num_qubits"]
1203
1352
  num_clbits = header["num_clbits"]
1204
1353
  num_registers = header["num_registers"]
1205
1354
  num_instructions = header["num_instructions"]
1355
+ num_vars = header.get("num_vars", 0)
1206
1356
  # `out_registers` is two "name: register" maps segregated by type for the rest of QPY, and
1207
1357
  # `all_registers` is the complete ordered list used to construct the `QuantumCircuit`.
1208
1358
  out_registers = {"q": {}, "c": {}}
@@ -1259,6 +1409,7 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1259
1409
  "q": [Qubit() for _ in out_bits["q"]],
1260
1410
  "c": [Clbit() for _ in out_bits["c"]],
1261
1411
  }
1412
+ var_segments, standalone_var_indices = value.read_standalone_vars(file_obj, num_vars)
1262
1413
  circ = QuantumCircuit(
1263
1414
  out_bits["q"],
1264
1415
  out_bits["c"],
@@ -1266,11 +1417,22 @@ def read_circuit(file_obj, version, metadata_deserializer=None, use_symengine=Fa
1266
1417
  name=name,
1267
1418
  global_phase=global_phase,
1268
1419
  metadata=metadata,
1420
+ inputs=var_segments[type_keys.ExprVarDeclaration.INPUT],
1421
+ captures=var_segments[type_keys.ExprVarDeclaration.CAPTURE],
1269
1422
  )
1423
+ for declaration in var_segments[type_keys.ExprVarDeclaration.LOCAL]:
1424
+ circ.add_uninitialized_var(declaration)
1270
1425
  custom_operations = _read_custom_operations(file_obj, version, vectors)
1271
1426
  for _instruction in range(num_instructions):
1272
1427
  _read_instruction(
1273
- 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,
1274
1436
  )
1275
1437
 
1276
1438
  # Read calibrations