qiskit 1.0.2__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 (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
@@ -328,7 +328,7 @@ def _read_element(file_obj, version, metadata_deserializer, use_symengine):
328
328
  return instance
329
329
 
330
330
 
331
- def _loads_reference_item(type_key, data_bytes, version, metadata_deserializer):
331
+ def _loads_reference_item(type_key, data_bytes, metadata_deserializer, version):
332
332
  if type_key == type_keys.Value.NULL:
333
333
  return None
334
334
  if type_key == type_keys.Program.SCHEDULE_BLOCK:
@@ -346,13 +346,13 @@ def _loads_reference_item(type_key, data_bytes, version, metadata_deserializer):
346
346
  )
347
347
 
348
348
 
349
- def _write_channel(file_obj, data):
349
+ def _write_channel(file_obj, data, version):
350
350
  type_key = type_keys.ScheduleChannel.assign(data)
351
351
  common.write_type_key(file_obj, type_key)
352
- value.write_value(file_obj, data.index)
352
+ value.write_value(file_obj, data.index, version=version)
353
353
 
354
354
 
355
- def _write_waveform(file_obj, data):
355
+ def _write_waveform(file_obj, data, version):
356
356
  samples_bytes = common.data_to_binary(data.samples, np.save)
357
357
 
358
358
  header = struct.pack(
@@ -363,39 +363,43 @@ def _write_waveform(file_obj, data):
363
363
  )
364
364
  file_obj.write(header)
365
365
  file_obj.write(samples_bytes)
366
- value.write_value(file_obj, data.name)
366
+ value.write_value(file_obj, data.name, version=version)
367
367
 
368
368
 
369
- def _dumps_obj(obj):
369
+ def _dumps_obj(obj, version):
370
370
  """Wraps `value.dumps_value` to serialize dictionary and list objects
371
371
  which are not supported by `value.dumps_value`.
372
372
  """
373
373
  if isinstance(obj, dict):
374
374
  with BytesIO() as container:
375
- common.write_mapping(file_obj=container, mapping=obj, serializer=_dumps_obj)
375
+ common.write_mapping(
376
+ file_obj=container, mapping=obj, serializer=_dumps_obj, version=version
377
+ )
376
378
  binary_data = container.getvalue()
377
379
  return b"D", binary_data
378
380
  elif isinstance(obj, list):
379
381
  with BytesIO() as container:
380
- common.write_sequence(file_obj=container, sequence=obj, serializer=_dumps_obj)
382
+ common.write_sequence(
383
+ file_obj=container, sequence=obj, serializer=_dumps_obj, version=version
384
+ )
381
385
  binary_data = container.getvalue()
382
386
  return b"l", binary_data
383
387
  else:
384
- return value.dumps_value(obj)
388
+ return value.dumps_value(obj, version=version)
385
389
 
386
390
 
387
- def _write_kernel(file_obj, data):
391
+ def _write_kernel(file_obj, data, version):
388
392
  name = data.name
389
393
  params = data.params
390
- common.write_mapping(file_obj=file_obj, mapping=params, serializer=_dumps_obj)
391
- value.write_value(file_obj, name)
394
+ common.write_mapping(file_obj=file_obj, mapping=params, serializer=_dumps_obj, version=version)
395
+ value.write_value(file_obj, name, version=version)
392
396
 
393
397
 
394
- def _write_discriminator(file_obj, data):
398
+ def _write_discriminator(file_obj, data, version):
395
399
  name = data.name
396
400
  params = data.params
397
- common.write_mapping(file_obj=file_obj, mapping=params, serializer=_dumps_obj)
398
- value.write_value(file_obj, name)
401
+ common.write_mapping(file_obj=file_obj, mapping=params, serializer=_dumps_obj, version=version)
402
+ value.write_value(file_obj, name, version=version)
399
403
 
400
404
 
401
405
  def _dumps_symbolic_expr(expr, use_symengine):
@@ -410,7 +414,7 @@ def _dumps_symbolic_expr(expr, use_symengine):
410
414
  return zlib.compress(expr_bytes)
411
415
 
412
416
 
413
- def _write_symbolic_pulse(file_obj, data, use_symengine):
417
+ def _write_symbolic_pulse(file_obj, data, use_symengine, version):
414
418
  class_name_bytes = data.__class__.__name__.encode(common.ENCODE)
415
419
  pulse_type_bytes = data.pulse_type.encode(common.ENCODE)
416
420
  envelope_bytes = _dumps_symbolic_expr(data.envelope, use_symengine)
@@ -436,52 +440,51 @@ def _write_symbolic_pulse(file_obj, data, use_symengine):
436
440
  file_obj,
437
441
  mapping=data._params,
438
442
  serializer=value.dumps_value,
443
+ version=version,
439
444
  )
440
- value.write_value(file_obj, data.duration)
441
- value.write_value(file_obj, data.name)
445
+ value.write_value(file_obj, data.duration, version=version)
446
+ value.write_value(file_obj, data.name, version=version)
442
447
 
443
448
 
444
- def _write_alignment_context(file_obj, context):
449
+ def _write_alignment_context(file_obj, context, version):
445
450
  type_key = type_keys.ScheduleAlignment.assign(context)
446
451
  common.write_type_key(file_obj, type_key)
447
452
  common.write_sequence(
448
- file_obj,
449
- sequence=context._context_params,
450
- serializer=value.dumps_value,
453
+ file_obj, sequence=context._context_params, serializer=value.dumps_value, version=version
451
454
  )
452
455
 
453
456
 
454
- def _dumps_operand(operand, use_symengine):
457
+ def _dumps_operand(operand, use_symengine, version):
455
458
  if isinstance(operand, library.Waveform):
456
459
  type_key = type_keys.ScheduleOperand.WAVEFORM
457
- data_bytes = common.data_to_binary(operand, _write_waveform)
460
+ data_bytes = common.data_to_binary(operand, _write_waveform, version=version)
458
461
  elif isinstance(operand, library.SymbolicPulse):
459
462
  type_key = type_keys.ScheduleOperand.SYMBOLIC_PULSE
460
463
  data_bytes = common.data_to_binary(
461
- operand, _write_symbolic_pulse, use_symengine=use_symengine
464
+ operand, _write_symbolic_pulse, use_symengine=use_symengine, version=version
462
465
  )
463
466
  elif isinstance(operand, channels.Channel):
464
467
  type_key = type_keys.ScheduleOperand.CHANNEL
465
- data_bytes = common.data_to_binary(operand, _write_channel)
468
+ data_bytes = common.data_to_binary(operand, _write_channel, version=version)
466
469
  elif isinstance(operand, str):
467
470
  type_key = type_keys.ScheduleOperand.OPERAND_STR
468
471
  data_bytes = operand.encode(common.ENCODE)
469
472
  elif isinstance(operand, Kernel):
470
473
  type_key = type_keys.ScheduleOperand.KERNEL
471
- data_bytes = common.data_to_binary(operand, _write_kernel)
474
+ data_bytes = common.data_to_binary(operand, _write_kernel, version=version)
472
475
  elif isinstance(operand, Discriminator):
473
476
  type_key = type_keys.ScheduleOperand.DISCRIMINATOR
474
- data_bytes = common.data_to_binary(operand, _write_discriminator)
477
+ data_bytes = common.data_to_binary(operand, _write_discriminator, version=version)
475
478
  else:
476
- type_key, data_bytes = value.dumps_value(operand)
479
+ type_key, data_bytes = value.dumps_value(operand, version=version)
477
480
 
478
481
  return type_key, data_bytes
479
482
 
480
483
 
481
- def _write_element(file_obj, element, metadata_serializer, use_symengine):
484
+ def _write_element(file_obj, element, metadata_serializer, use_symengine, version):
482
485
  if isinstance(element, ScheduleBlock):
483
486
  common.write_type_key(file_obj, type_keys.Program.SCHEDULE_BLOCK)
484
- write_schedule_block(file_obj, element, metadata_serializer, use_symengine)
487
+ write_schedule_block(file_obj, element, metadata_serializer, use_symengine, version=version)
485
488
  else:
486
489
  type_key = type_keys.ScheduleInstruction.assign(element)
487
490
  common.write_type_key(file_obj, type_key)
@@ -490,11 +493,12 @@ def _write_element(file_obj, element, metadata_serializer, use_symengine):
490
493
  sequence=element.operands,
491
494
  serializer=_dumps_operand,
492
495
  use_symengine=use_symengine,
496
+ version=version,
493
497
  )
494
- value.write_value(file_obj, element.name)
498
+ value.write_value(file_obj, element.name, version=version)
495
499
 
496
500
 
497
- def _dumps_reference_item(schedule, metadata_serializer):
501
+ def _dumps_reference_item(schedule, metadata_serializer, version):
498
502
  if schedule is None:
499
503
  type_key = type_keys.Value.NULL
500
504
  data_bytes = b""
@@ -504,6 +508,7 @@ def _dumps_reference_item(schedule, metadata_serializer):
504
508
  obj=schedule,
505
509
  serializer=write_schedule_block,
506
510
  metadata_serializer=metadata_serializer,
511
+ version=version,
507
512
  )
508
513
  return type_key, data_bytes
509
514
 
@@ -576,7 +581,7 @@ def read_schedule_block(file_obj, version, metadata_deserializer=None, use_symen
576
581
 
577
582
  def write_schedule_block(
578
583
  file_obj, block, metadata_serializer=None, use_symengine=False, version=common.QPY_VERSION
579
- ): # pylint: disable=unused-argument
584
+ ):
580
585
  """Write a single ScheduleBlock object in the file like object.
581
586
 
582
587
  Args:
@@ -610,11 +615,11 @@ def write_schedule_block(
610
615
  file_obj.write(block_name)
611
616
  file_obj.write(metadata)
612
617
 
613
- _write_alignment_context(file_obj, block.alignment_context)
618
+ _write_alignment_context(file_obj, block.alignment_context, version=version)
614
619
  for block_elm in block._blocks:
615
620
  # Do not call block.blocks. This implicitly assigns references to instruction.
616
621
  # This breaks original reference structure.
617
- _write_element(file_obj, block_elm, metadata_serializer, use_symengine)
622
+ _write_element(file_obj, block_elm, metadata_serializer, use_symengine, version=version)
618
623
 
619
624
  # Write references
620
625
  flat_key_refdict = {}
@@ -627,4 +632,5 @@ def write_schedule_block(
627
632
  mapping=flat_key_refdict,
628
633
  serializer=_dumps_reference_item,
629
634
  metadata_serializer=metadata_serializer,
635
+ version=version,
630
636
  )
@@ -53,7 +53,7 @@ def _write_parameter_vec(file_obj, obj):
53
53
  file_obj.write(name_bytes)
54
54
 
55
55
 
56
- def _write_parameter_expression(file_obj, obj, use_symengine):
56
+ def _write_parameter_expression(file_obj, obj, use_symengine, *, version):
57
57
  if use_symengine:
58
58
  expr_bytes = obj._symbol_expr.__reduce__()[1][0]
59
59
  else:
@@ -81,7 +81,7 @@ def _write_parameter_expression(file_obj, obj, use_symengine):
81
81
  value_key = symbol_key
82
82
  value_data = bytes()
83
83
  else:
84
- value_key, value_data = dumps_value(value, use_symengine=use_symengine)
84
+ value_key, value_data = dumps_value(value, version=version, use_symengine=use_symengine)
85
85
 
86
86
  elem_header = struct.pack(
87
87
  formats.PARAM_EXPR_MAP_ELEM_V3_PACK,
@@ -95,11 +95,13 @@ def _write_parameter_expression(file_obj, obj, use_symengine):
95
95
 
96
96
 
97
97
  class _ExprWriter(expr.ExprVisitor[None]):
98
- __slots__ = ("file_obj", "clbit_indices")
98
+ __slots__ = ("file_obj", "clbit_indices", "standalone_var_indices", "version")
99
99
 
100
- def __init__(self, file_obj, clbit_indices):
100
+ def __init__(self, file_obj, clbit_indices, standalone_var_indices, version):
101
101
  self.file_obj = file_obj
102
102
  self.clbit_indices = clbit_indices
103
+ self.standalone_var_indices = standalone_var_indices
104
+ self.version = version
103
105
 
104
106
  def visit_generic(self, node, /):
105
107
  raise exceptions.QpyError(f"unhandled Expr object '{node}'")
@@ -107,7 +109,15 @@ class _ExprWriter(expr.ExprVisitor[None]):
107
109
  def visit_var(self, node, /):
108
110
  self.file_obj.write(type_keys.Expression.VAR)
109
111
  _write_expr_type(self.file_obj, node.type)
110
- if isinstance(node.var, Clbit):
112
+ if node.standalone:
113
+ self.file_obj.write(type_keys.ExprVar.UUID)
114
+ self.file_obj.write(
115
+ struct.pack(
116
+ formats.EXPR_VAR_UUID_PACK,
117
+ *formats.EXPR_VAR_UUID(self.standalone_var_indices[node]),
118
+ )
119
+ )
120
+ elif isinstance(node.var, Clbit):
111
121
  self.file_obj.write(type_keys.ExprVar.CLBIT)
112
122
  self.file_obj.write(
113
123
  struct.pack(
@@ -172,14 +182,30 @@ class _ExprWriter(expr.ExprVisitor[None]):
172
182
  self.file_obj.write(type_keys.Expression.BINARY)
173
183
  _write_expr_type(self.file_obj, node.type)
174
184
  self.file_obj.write(
175
- struct.pack(formats.EXPRESSION_BINARY_PACK, *formats.EXPRESSION_UNARY(node.op.value))
185
+ struct.pack(formats.EXPRESSION_BINARY_PACK, *formats.EXPRESSION_BINARY(node.op.value))
176
186
  )
177
187
  node.left.accept(self)
178
188
  node.right.accept(self)
179
189
 
190
+ def visit_index(self, node, /):
191
+ if self.version < 12:
192
+ raise exceptions.UnsupportedFeatureForVersion(
193
+ "the 'Index' expression", required=12, target=self.version
194
+ )
195
+ self.file_obj.write(type_keys.Expression.INDEX)
196
+ _write_expr_type(self.file_obj, node.type)
197
+ node.target.accept(self)
198
+ node.index.accept(self)
180
199
 
181
- def _write_expr(file_obj, node: expr.Expr, clbit_indices: collections.abc.Mapping[Clbit, int]):
182
- node.accept(_ExprWriter(file_obj, clbit_indices))
200
+
201
+ def _write_expr(
202
+ file_obj,
203
+ node: expr.Expr,
204
+ clbit_indices: collections.abc.Mapping[Clbit, int],
205
+ standalone_var_indices: collections.abc.Mapping[expr.Var, int],
206
+ version: int,
207
+ ):
208
+ node.accept(_ExprWriter(file_obj, clbit_indices, standalone_var_indices, version))
183
209
 
184
210
 
185
211
  def _write_expr_type(file_obj, type_: types.Type):
@@ -315,12 +341,18 @@ def _read_expr(
315
341
  file_obj,
316
342
  clbits: collections.abc.Sequence[Clbit],
317
343
  cregs: collections.abc.Mapping[str, ClassicalRegister],
344
+ standalone_vars: collections.abc.Sequence[expr.Var],
318
345
  ) -> expr.Expr:
319
346
  # pylint: disable=too-many-return-statements
320
347
  type_key = file_obj.read(formats.EXPRESSION_DISCRIMINATOR_SIZE)
321
348
  type_ = _read_expr_type(file_obj)
322
349
  if type_key == type_keys.Expression.VAR:
323
350
  var_type_key = file_obj.read(formats.EXPR_VAR_DISCRIMINATOR_SIZE)
351
+ if var_type_key == type_keys.ExprVar.UUID:
352
+ payload = formats.EXPR_VAR_UUID._make(
353
+ struct.unpack(formats.EXPR_VAR_UUID_PACK, file_obj.read(formats.EXPR_VAR_UUID_SIZE))
354
+ )
355
+ return standalone_vars[payload.var_index]
324
356
  if var_type_key == type_keys.ExprVar.CLBIT:
325
357
  payload = formats.EXPR_VAR_CLBIT._make(
326
358
  struct.unpack(
@@ -360,14 +392,20 @@ def _read_expr(
360
392
  payload = formats.EXPRESSION_CAST._make(
361
393
  struct.unpack(formats.EXPRESSION_CAST_PACK, file_obj.read(formats.EXPRESSION_CAST_SIZE))
362
394
  )
363
- return expr.Cast(_read_expr(file_obj, clbits, cregs), type_, implicit=payload.implicit)
395
+ return expr.Cast(
396
+ _read_expr(file_obj, clbits, cregs, standalone_vars), type_, implicit=payload.implicit
397
+ )
364
398
  if type_key == type_keys.Expression.UNARY:
365
399
  payload = formats.EXPRESSION_UNARY._make(
366
400
  struct.unpack(
367
401
  formats.EXPRESSION_UNARY_PACK, file_obj.read(formats.EXPRESSION_UNARY_SIZE)
368
402
  )
369
403
  )
370
- return expr.Unary(expr.Unary.Op(payload.opcode), _read_expr(file_obj, clbits, cregs), type_)
404
+ return expr.Unary(
405
+ expr.Unary.Op(payload.opcode),
406
+ _read_expr(file_obj, clbits, cregs, standalone_vars),
407
+ type_,
408
+ )
371
409
  if type_key == type_keys.Expression.BINARY:
372
410
  payload = formats.EXPRESSION_BINARY._make(
373
411
  struct.unpack(
@@ -376,11 +414,17 @@ def _read_expr(
376
414
  )
377
415
  return expr.Binary(
378
416
  expr.Binary.Op(payload.opcode),
379
- _read_expr(file_obj, clbits, cregs),
380
- _read_expr(file_obj, clbits, cregs),
417
+ _read_expr(file_obj, clbits, cregs, standalone_vars),
418
+ _read_expr(file_obj, clbits, cregs, standalone_vars),
419
+ type_,
420
+ )
421
+ if type_key == type_keys.Expression.INDEX:
422
+ return expr.Index(
423
+ _read_expr(file_obj, clbits, cregs, standalone_vars),
424
+ _read_expr(file_obj, clbits, cregs, standalone_vars),
381
425
  type_,
382
426
  )
383
- raise exceptions.QpyError("Invalid classical-expression Expr key '{type_key}'")
427
+ raise exceptions.QpyError(f"Invalid classical-expression Expr key '{type_key}'")
384
428
 
385
429
 
386
430
  def _read_expr_type(file_obj) -> types.Type:
@@ -395,11 +439,92 @@ def _read_expr_type(file_obj) -> types.Type:
395
439
  raise exceptions.QpyError(f"Invalid classical-expression Type key '{type_key}'")
396
440
 
397
441
 
398
- def dumps_value(obj, *, index_map=None, use_symengine=False):
442
+ def read_standalone_vars(file_obj, num_vars):
443
+ """Read the ``num_vars`` standalone variable declarations from the file.
444
+
445
+ Args:
446
+ file_obj (File): a file-like object to read from.
447
+ num_vars (int): the number of variables to read.
448
+
449
+ Returns:
450
+ tuple[dict, list]: the first item is a mapping of the ``ExprVarDeclaration`` type keys to
451
+ the variables defined by that type key, and the second is the total order of variable
452
+ declarations.
453
+ """
454
+ read_vars = {
455
+ type_keys.ExprVarDeclaration.INPUT: [],
456
+ type_keys.ExprVarDeclaration.CAPTURE: [],
457
+ type_keys.ExprVarDeclaration.LOCAL: [],
458
+ }
459
+ var_order = []
460
+ for _ in range(num_vars):
461
+ data = formats.EXPR_VAR_DECLARATION._make(
462
+ struct.unpack(
463
+ formats.EXPR_VAR_DECLARATION_PACK,
464
+ file_obj.read(formats.EXPR_VAR_DECLARATION_SIZE),
465
+ )
466
+ )
467
+ type_ = _read_expr_type(file_obj)
468
+ name = file_obj.read(data.name_size).decode(common.ENCODE)
469
+ var = expr.Var(uuid.UUID(bytes=data.uuid_bytes), type_, name=name)
470
+ read_vars[data.usage].append(var)
471
+ var_order.append(var)
472
+ return read_vars, var_order
473
+
474
+
475
+ def _write_standalone_var(file_obj, var, type_key):
476
+ name = var.name.encode(common.ENCODE)
477
+ file_obj.write(
478
+ struct.pack(
479
+ formats.EXPR_VAR_DECLARATION_PACK,
480
+ *formats.EXPR_VAR_DECLARATION(var.var.bytes, type_key, len(name)),
481
+ )
482
+ )
483
+ _write_expr_type(file_obj, var.type)
484
+ file_obj.write(name)
485
+
486
+
487
+ def write_standalone_vars(file_obj, circuit):
488
+ """Write the standalone variables out from a circuit.
489
+
490
+ Args:
491
+ file_obj (File): the file-like object to write to.
492
+ circuit (QuantumCircuit): the circuit to take the variables from.
493
+
494
+ Returns:
495
+ dict[expr.Var, int]: a mapping of the variables written to the index that they were written
496
+ at.
497
+ """
498
+ index = 0
499
+ out = {}
500
+ for var in circuit.iter_input_vars():
501
+ _write_standalone_var(file_obj, var, type_keys.ExprVarDeclaration.INPUT)
502
+ out[var] = index
503
+ index += 1
504
+ for var in circuit.iter_captured_vars():
505
+ _write_standalone_var(file_obj, var, type_keys.ExprVarDeclaration.CAPTURE)
506
+ out[var] = index
507
+ index += 1
508
+ for var in circuit.iter_declared_vars():
509
+ _write_standalone_var(file_obj, var, type_keys.ExprVarDeclaration.LOCAL)
510
+ out[var] = index
511
+ index += 1
512
+ return out
513
+
514
+
515
+ def dumps_value(
516
+ obj,
517
+ *,
518
+ version,
519
+ index_map=None,
520
+ use_symengine=False,
521
+ standalone_var_indices=None,
522
+ ):
399
523
  """Serialize input value object.
400
524
 
401
525
  Args:
402
526
  obj (any): Arbitrary value object to serialize.
527
+ version (int): the target QPY version for the dump.
403
528
  index_map (dict): Dictionary with two keys, "q" and "c". Each key has a value that is a
404
529
  dictionary mapping :class:`.Qubit` or :class:`.Clbit` instances (respectively) to their
405
530
  integer indices.
@@ -407,6 +532,8 @@ def dumps_value(obj, *, index_map=None, use_symengine=False):
407
532
  native mechanism. This is a faster serialization alternative, but not supported in all
408
533
  platforms. Please check that your target platform is supported by the symengine library
409
534
  before setting this option, as it will be required by qpy to deserialize the payload.
535
+ standalone_var_indices (dict): Dictionary that maps standalone :class:`.expr.Var` entries to
536
+ the index that should be used to refer to them.
410
537
 
411
538
  Returns:
412
539
  tuple: TypeKey and binary data.
@@ -434,23 +561,33 @@ def dumps_value(obj, *, index_map=None, use_symengine=False):
434
561
  binary_data = common.data_to_binary(obj, _write_parameter)
435
562
  elif type_key == type_keys.Value.PARAMETER_EXPRESSION:
436
563
  binary_data = common.data_to_binary(
437
- obj, _write_parameter_expression, use_symengine=use_symengine
564
+ obj, _write_parameter_expression, use_symengine=use_symengine, version=version
438
565
  )
439
566
  elif type_key == type_keys.Value.EXPRESSION:
440
567
  clbit_indices = {} if index_map is None else index_map["c"]
441
- binary_data = common.data_to_binary(obj, _write_expr, clbit_indices=clbit_indices)
568
+ standalone_var_indices = {} if standalone_var_indices is None else standalone_var_indices
569
+ binary_data = common.data_to_binary(
570
+ obj,
571
+ _write_expr,
572
+ clbit_indices=clbit_indices,
573
+ standalone_var_indices=standalone_var_indices,
574
+ version=version,
575
+ )
442
576
  else:
443
577
  raise exceptions.QpyError(f"Serialization for {type_key} is not implemented in value I/O.")
444
578
 
445
579
  return type_key, binary_data
446
580
 
447
581
 
448
- def write_value(file_obj, obj, *, index_map=None, use_symengine=False):
582
+ def write_value(
583
+ file_obj, obj, *, version, index_map=None, use_symengine=False, standalone_var_indices=None
584
+ ):
449
585
  """Write a value to the file like object.
450
586
 
451
587
  Args:
452
588
  file_obj (File): A file like object to write data.
453
589
  obj (any): Value to write.
590
+ version (int): the target QPY version for the dump.
454
591
  index_map (dict): Dictionary with two keys, "q" and "c". Each key has a value that is a
455
592
  dictionary mapping :class:`.Qubit` or :class:`.Clbit` instances (respectively) to their
456
593
  integer indices.
@@ -458,13 +595,29 @@ def write_value(file_obj, obj, *, index_map=None, use_symengine=False):
458
595
  native mechanism. This is a faster serialization alternative, but not supported in all
459
596
  platforms. Please check that your target platform is supported by the symengine library
460
597
  before setting this option, as it will be required by qpy to deserialize the payload.
598
+ standalone_var_indices (dict): Dictionary that maps standalone :class:`.expr.Var` entries to
599
+ the index that should be used to refer to them.
461
600
  """
462
- type_key, data = dumps_value(obj, index_map=index_map, use_symengine=use_symengine)
601
+ type_key, data = dumps_value(
602
+ obj,
603
+ version=version,
604
+ index_map=index_map,
605
+ use_symengine=use_symengine,
606
+ standalone_var_indices=standalone_var_indices,
607
+ )
463
608
  common.write_generic_typed_data(file_obj, type_key, data)
464
609
 
465
610
 
466
611
  def loads_value(
467
- type_key, binary_data, version, vectors, *, clbits=(), cregs=None, use_symengine=False
612
+ type_key,
613
+ binary_data,
614
+ version,
615
+ vectors,
616
+ *,
617
+ clbits=(),
618
+ cregs=None,
619
+ use_symengine=False,
620
+ standalone_vars=(),
468
621
  ):
469
622
  """Deserialize input binary data to value object.
470
623
 
@@ -479,6 +632,8 @@ def loads_value(
479
632
  native mechanism. This is a faster serialization alternative, but not supported in all
480
633
  platforms. Please check that your target platform is supported by the symengine library
481
634
  before setting this option, as it will be required by qpy to deserialize the payload.
635
+ standalone_vars (Sequence[Var]): standalone :class:`.expr.Var` nodes in the order that they
636
+ were declared by the circuit header.
482
637
 
483
638
  Returns:
484
639
  any: Deserialized value object.
@@ -520,12 +675,27 @@ def loads_value(
520
675
  use_symengine=use_symengine,
521
676
  )
522
677
  if type_key == type_keys.Value.EXPRESSION:
523
- return common.data_from_binary(binary_data, _read_expr, clbits=clbits, cregs=cregs or {})
678
+ return common.data_from_binary(
679
+ binary_data,
680
+ _read_expr,
681
+ clbits=clbits,
682
+ cregs=cregs or {},
683
+ standalone_vars=standalone_vars,
684
+ )
524
685
 
525
686
  raise exceptions.QpyError(f"Serialization for {type_key} is not implemented in value I/O.")
526
687
 
527
688
 
528
- def read_value(file_obj, version, vectors, *, clbits=(), cregs=None, use_symengine=False):
689
+ def read_value(
690
+ file_obj,
691
+ version,
692
+ vectors,
693
+ *,
694
+ clbits=(),
695
+ cregs=None,
696
+ use_symengine=False,
697
+ standalone_vars=(),
698
+ ):
529
699
  """Read a value from the file like object.
530
700
 
531
701
  Args:
@@ -538,6 +708,8 @@ def read_value(file_obj, version, vectors, *, clbits=(), cregs=None, use_symengi
538
708
  native mechanism. This is a faster serialization alternative, but not supported in all
539
709
  platforms. Please check that your target platform is supported by the symengine library
540
710
  before setting this option, as it will be required by qpy to deserialize the payload.
711
+ standalone_vars (Sequence[expr.Var]): standalone variables in the order they were defined in
712
+ the QPY payload.
541
713
 
542
714
  Returns:
543
715
  any: Deserialized value object.
@@ -545,5 +717,12 @@ def read_value(file_obj, version, vectors, *, clbits=(), cregs=None, use_symengi
545
717
  type_key, data = common.read_generic_typed_data(file_obj)
546
718
 
547
719
  return loads_value(
548
- type_key, data, version, vectors, clbits=clbits, cregs=cregs, use_symengine=use_symengine
720
+ type_key,
721
+ data,
722
+ version,
723
+ vectors,
724
+ clbits=clbits,
725
+ cregs=cregs,
726
+ use_symengine=use_symengine,
727
+ standalone_vars=standalone_vars,
549
728
  )
qiskit/qpy/common.py CHANGED
@@ -20,7 +20,7 @@ import struct
20
20
 
21
21
  from qiskit.qpy import formats
22
22
 
23
- QPY_VERSION = 11
23
+ QPY_VERSION = 12
24
24
  QPY_COMPATIBILITY_VERSION = 10
25
25
  ENCODE = "utf8"
26
26
 
qiskit/qpy/exceptions.py CHANGED
@@ -28,6 +28,26 @@ class QpyError(QiskitError):
28
28
  return repr(self.message)
29
29
 
30
30
 
31
+ class UnsupportedFeatureForVersion(QpyError):
32
+ """QPY error raised when the target dump version is too low for a feature that is present in the
33
+ object to be serialized."""
34
+
35
+ def __init__(self, feature: str, required: int, target: int):
36
+ """
37
+ Args:
38
+ feature: a description of the problematic feature.
39
+ required: the minimum version of QPY that would be required to represent this
40
+ feature.
41
+ target: the version of QPY that is being used in the serialization.
42
+ """
43
+ self.feature = feature
44
+ self.required = required
45
+ self.target = target
46
+ super().__init__(
47
+ f"Dumping QPY version {target}, but version {required} is required for: {feature}."
48
+ )
49
+
50
+
31
51
  class QPYLoadingDeprecatedFeatureWarning(QiskitWarning):
32
52
  """Visible deprecation warning for QPY loading functions without
33
53
  a stable point in the call stack."""
qiskit/qpy/formats.py CHANGED
@@ -42,6 +42,24 @@ FILE_HEADER = namedtuple(
42
42
  FILE_HEADER_PACK = "!6sBBBBQ"
43
43
  FILE_HEADER_SIZE = struct.calcsize(FILE_HEADER_PACK)
44
44
 
45
+
46
+ CIRCUIT_HEADER_V12 = namedtuple(
47
+ "HEADER",
48
+ [
49
+ "name_size",
50
+ "global_phase_type",
51
+ "global_phase_size",
52
+ "num_qubits",
53
+ "num_clbits",
54
+ "metadata_size",
55
+ "num_registers",
56
+ "num_instructions",
57
+ "num_vars",
58
+ ],
59
+ )
60
+ CIRCUIT_HEADER_V12_PACK = "!H1cHIIQIQI"
61
+ CIRCUIT_HEADER_V12_SIZE = struct.calcsize(CIRCUIT_HEADER_V12_PACK)
62
+
45
63
  # CIRCUIT_HEADER_V2
46
64
  CIRCUIT_HEADER_V2 = namedtuple(
47
65
  "HEADER",
@@ -309,6 +327,13 @@ INITIAL_LAYOUT_BIT = namedtuple("INITIAL_LAYOUT_BIT", ["index", "register_size"]
309
327
  INITIAL_LAYOUT_BIT_PACK = "!ii"
310
328
  INITIAL_LAYOUT_BIT_SIZE = struct.calcsize(INITIAL_LAYOUT_BIT_PACK)
311
329
 
330
+ # EXPR_VAR_DECLARATION
331
+
332
+ EXPR_VAR_DECLARATION = namedtuple("EXPR_VAR_DECLARATION", ["uuid_bytes", "usage", "name_size"])
333
+ EXPR_VAR_DECLARATION_PACK = "!16scH"
334
+ EXPR_VAR_DECLARATION_SIZE = struct.calcsize(EXPR_VAR_DECLARATION_PACK)
335
+
336
+
312
337
  # EXPRESSION
313
338
 
314
339
  EXPRESSION_DISCRIMINATOR_SIZE = 1
@@ -351,6 +376,10 @@ EXPR_VAR_REGISTER = namedtuple("EXPR_VAR_REGISTER", ["reg_name_size"])
351
376
  EXPR_VAR_REGISTER_PACK = "!H"
352
377
  EXPR_VAR_REGISTER_SIZE = struct.calcsize(EXPR_VAR_REGISTER_PACK)
353
378
 
379
+ EXPR_VAR_UUID = namedtuple("EXPR_VAR_UUID", ["var_index"])
380
+ EXPR_VAR_UUID_PACK = "!H"
381
+ EXPR_VAR_UUID_SIZE = struct.calcsize(EXPR_VAR_UUID_PACK)
382
+
354
383
 
355
384
  # EXPR_VALUE
356
385