qiskit 1.0.2__cp38-abi3-win32.whl → 1.1.0rc1__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 (247) 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/disassemble.py +5 -6
  6. qiskit/circuit/__init__.py +1131 -169
  7. qiskit/circuit/_classical_resource_map.py +7 -6
  8. qiskit/circuit/_utils.py +18 -8
  9. qiskit/circuit/annotated_operation.py +21 -0
  10. qiskit/circuit/barrier.py +10 -13
  11. qiskit/circuit/bit.py +0 -1
  12. qiskit/circuit/classical/__init__.py +2 -2
  13. qiskit/circuit/classical/expr/__init__.py +39 -5
  14. qiskit/circuit/classical/expr/constructors.py +84 -1
  15. qiskit/circuit/classical/expr/expr.py +83 -13
  16. qiskit/circuit/classical/expr/visitors.py +83 -0
  17. qiskit/circuit/commutation_checker.py +86 -51
  18. qiskit/circuit/controlflow/_builder_utils.py +9 -1
  19. qiskit/circuit/controlflow/break_loop.py +8 -22
  20. qiskit/circuit/controlflow/builder.py +116 -1
  21. qiskit/circuit/controlflow/continue_loop.py +8 -22
  22. qiskit/circuit/controlflow/control_flow.py +47 -8
  23. qiskit/circuit/controlflow/for_loop.py +8 -23
  24. qiskit/circuit/controlflow/if_else.py +13 -27
  25. qiskit/circuit/controlflow/switch_case.py +14 -21
  26. qiskit/circuit/controlflow/while_loop.py +9 -23
  27. qiskit/circuit/controlledgate.py +2 -2
  28. qiskit/circuit/delay.py +7 -5
  29. qiskit/circuit/gate.py +20 -7
  30. qiskit/circuit/instruction.py +31 -30
  31. qiskit/circuit/instructionset.py +9 -22
  32. qiskit/circuit/library/__init__.py +8 -2
  33. qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
  34. qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
  35. qiskit/circuit/library/blueprintcircuit.py +29 -7
  36. qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
  37. qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
  38. qiskit/circuit/library/generalized_gates/isometry.py +51 -254
  39. qiskit/circuit/library/generalized_gates/pauli.py +2 -2
  40. qiskit/circuit/library/generalized_gates/permutation.py +4 -1
  41. qiskit/circuit/library/generalized_gates/rv.py +15 -11
  42. qiskit/circuit/library/generalized_gates/uc.py +2 -98
  43. qiskit/circuit/library/generalized_gates/unitary.py +9 -4
  44. qiskit/circuit/library/hamiltonian_gate.py +11 -5
  45. qiskit/circuit/library/n_local/efficient_su2.py +5 -5
  46. qiskit/circuit/library/n_local/n_local.py +100 -49
  47. qiskit/circuit/library/n_local/two_local.py +3 -59
  48. qiskit/circuit/library/overlap.py +3 -3
  49. qiskit/circuit/library/phase_oracle.py +1 -1
  50. qiskit/circuit/library/quantum_volume.py +39 -38
  51. qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
  52. qiskit/circuit/library/standard_gates/global_phase.py +4 -2
  53. qiskit/circuit/library/standard_gates/i.py +1 -2
  54. qiskit/circuit/library/standard_gates/iswap.py +1 -2
  55. qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
  56. qiskit/circuit/library/standard_gates/p.py +31 -15
  57. qiskit/circuit/library/standard_gates/r.py +4 -3
  58. qiskit/circuit/library/standard_gates/rx.py +7 -4
  59. qiskit/circuit/library/standard_gates/rxx.py +4 -3
  60. qiskit/circuit/library/standard_gates/ry.py +7 -4
  61. qiskit/circuit/library/standard_gates/ryy.py +4 -3
  62. qiskit/circuit/library/standard_gates/rz.py +7 -4
  63. qiskit/circuit/library/standard_gates/rzx.py +4 -3
  64. qiskit/circuit/library/standard_gates/rzz.py +4 -3
  65. qiskit/circuit/library/standard_gates/s.py +4 -8
  66. qiskit/circuit/library/standard_gates/t.py +2 -4
  67. qiskit/circuit/library/standard_gates/u.py +16 -11
  68. qiskit/circuit/library/standard_gates/u1.py +6 -2
  69. qiskit/circuit/library/standard_gates/u2.py +4 -2
  70. qiskit/circuit/library/standard_gates/u3.py +9 -5
  71. qiskit/circuit/library/standard_gates/x.py +22 -11
  72. qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
  73. qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
  74. qiskit/circuit/library/standard_gates/z.py +1 -2
  75. qiskit/circuit/measure.py +4 -1
  76. qiskit/circuit/operation.py +13 -8
  77. qiskit/circuit/parameter.py +11 -6
  78. qiskit/circuit/quantumcircuit.py +864 -128
  79. qiskit/circuit/quantumcircuitdata.py +2 -2
  80. qiskit/circuit/reset.py +5 -2
  81. qiskit/circuit/store.py +95 -0
  82. qiskit/compiler/assembler.py +22 -22
  83. qiskit/compiler/transpiler.py +63 -112
  84. qiskit/converters/circuit_to_dag.py +7 -0
  85. qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
  86. qiskit/converters/circuit_to_gate.py +2 -0
  87. qiskit/converters/circuit_to_instruction.py +22 -0
  88. qiskit/converters/dag_to_circuit.py +4 -0
  89. qiskit/converters/dag_to_dagdependency_v2.py +44 -0
  90. qiskit/dagcircuit/collect_blocks.py +15 -10
  91. qiskit/dagcircuit/dagcircuit.py +434 -124
  92. qiskit/dagcircuit/dagdependency.py +19 -12
  93. qiskit/dagcircuit/dagdependency_v2.py +641 -0
  94. qiskit/dagcircuit/dagdepnode.py +19 -16
  95. qiskit/dagcircuit/dagnode.py +14 -4
  96. qiskit/primitives/__init__.py +12 -8
  97. qiskit/primitives/backend_estimator.py +3 -5
  98. qiskit/primitives/backend_estimator_v2.py +410 -0
  99. qiskit/primitives/backend_sampler_v2.py +287 -0
  100. qiskit/primitives/base/base_estimator.py +4 -9
  101. qiskit/primitives/base/base_sampler.py +2 -2
  102. qiskit/primitives/containers/__init__.py +5 -4
  103. qiskit/primitives/containers/bit_array.py +292 -2
  104. qiskit/primitives/containers/data_bin.py +123 -50
  105. qiskit/primitives/containers/estimator_pub.py +10 -3
  106. qiskit/primitives/containers/observables_array.py +2 -2
  107. qiskit/primitives/containers/pub_result.py +1 -1
  108. qiskit/primitives/containers/sampler_pub.py +19 -3
  109. qiskit/primitives/containers/sampler_pub_result.py +74 -0
  110. qiskit/primitives/containers/shape.py +1 -1
  111. qiskit/primitives/statevector_estimator.py +4 -4
  112. qiskit/primitives/statevector_sampler.py +7 -12
  113. qiskit/providers/__init__.py +17 -18
  114. qiskit/providers/backend.py +2 -2
  115. qiskit/providers/backend_compat.py +8 -10
  116. qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
  117. qiskit/providers/basic_provider/basic_simulator.py +81 -21
  118. qiskit/providers/fake_provider/fake_1q.py +1 -1
  119. qiskit/providers/fake_provider/fake_backend.py +3 -408
  120. qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
  121. qiskit/providers/provider.py +16 -0
  122. qiskit/pulse/builder.py +4 -1
  123. qiskit/pulse/parameter_manager.py +60 -4
  124. qiskit/pulse/schedule.py +29 -13
  125. qiskit/pulse/utils.py +61 -20
  126. qiskit/qasm2/__init__.py +1 -5
  127. qiskit/qasm2/parse.py +1 -4
  128. qiskit/qasm3/__init__.py +42 -5
  129. qiskit/qasm3/ast.py +19 -0
  130. qiskit/qasm3/exporter.py +178 -106
  131. qiskit/qasm3/printer.py +27 -5
  132. qiskit/qpy/__init__.py +247 -13
  133. qiskit/qpy/binary_io/circuits.py +216 -47
  134. qiskit/qpy/binary_io/schedules.py +42 -36
  135. qiskit/qpy/binary_io/value.py +201 -22
  136. qiskit/qpy/common.py +1 -1
  137. qiskit/qpy/exceptions.py +20 -0
  138. qiskit/qpy/formats.py +29 -0
  139. qiskit/qpy/type_keys.py +21 -0
  140. qiskit/quantum_info/analysis/distance.py +3 -3
  141. qiskit/quantum_info/analysis/make_observable.py +2 -1
  142. qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
  143. qiskit/quantum_info/operators/channel/chi.py +9 -8
  144. qiskit/quantum_info/operators/channel/choi.py +10 -9
  145. qiskit/quantum_info/operators/channel/kraus.py +2 -1
  146. qiskit/quantum_info/operators/channel/ptm.py +10 -9
  147. qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
  148. qiskit/quantum_info/operators/channel/stinespring.py +2 -1
  149. qiskit/quantum_info/operators/channel/superop.py +12 -11
  150. qiskit/quantum_info/operators/channel/transformations.py +12 -11
  151. qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
  152. qiskit/quantum_info/operators/operator.py +43 -30
  153. qiskit/quantum_info/operators/scalar_op.py +10 -9
  154. qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
  155. qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
  156. qiskit/quantum_info/operators/symplectic/pauli.py +48 -4
  157. qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
  158. qiskit/quantum_info/operators/symplectic/random.py +3 -2
  159. qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +54 -33
  160. qiskit/quantum_info/states/densitymatrix.py +13 -13
  161. qiskit/quantum_info/states/stabilizerstate.py +3 -3
  162. qiskit/quantum_info/states/statevector.py +14 -13
  163. qiskit/quantum_info/states/utils.py +5 -3
  164. qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
  165. qiskit/result/mitigation/local_readout_mitigator.py +2 -1
  166. qiskit/result/mitigation/utils.py +3 -2
  167. qiskit/synthesis/__init__.py +2 -0
  168. qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
  169. qiskit/synthesis/evolution/lie_trotter.py +7 -14
  170. qiskit/synthesis/evolution/qdrift.py +3 -4
  171. qiskit/synthesis/linear/cnot_synth.py +1 -3
  172. qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
  173. qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
  174. qiskit/synthesis/permutation/__init__.py +1 -0
  175. qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
  176. qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
  177. qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
  178. qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
  179. qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
  180. qiskit/synthesis/unitary/aqc/__init__.py +1 -1
  181. qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
  182. qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
  183. qiskit/synthesis/unitary/qsd.py +3 -2
  184. qiskit/transpiler/__init__.py +7 -3
  185. qiskit/transpiler/layout.py +140 -61
  186. qiskit/transpiler/passes/__init__.py +6 -0
  187. qiskit/transpiler/passes/basis/basis_translator.py +7 -2
  188. qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
  189. qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
  190. qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
  191. qiskit/transpiler/passes/layout/apply_layout.py +8 -3
  192. qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
  193. qiskit/transpiler/passes/layout/set_layout.py +1 -1
  194. qiskit/transpiler/passes/optimization/__init__.py +2 -0
  195. qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
  196. qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
  197. qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
  198. qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
  199. qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
  200. qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
  201. qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
  202. qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
  203. qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
  204. qiskit/transpiler/passes/routing/__init__.py +1 -0
  205. qiskit/transpiler/passes/routing/basic_swap.py +13 -2
  206. qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
  207. qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
  208. qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
  209. qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
  210. qiskit/transpiler/passes/scheduling/__init__.py +1 -1
  211. qiskit/transpiler/passes/scheduling/alap.py +1 -2
  212. qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
  213. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
  214. qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
  215. qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
  216. qiskit/transpiler/passes/scheduling/asap.py +1 -2
  217. qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
  218. qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
  219. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
  220. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
  221. qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
  222. qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
  223. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
  224. qiskit/transpiler/passes/utils/gates_basis.py +3 -3
  225. qiskit/transpiler/passmanager.py +44 -1
  226. qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
  227. qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
  228. qiskit/transpiler/preset_passmanagers/common.py +4 -6
  229. qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
  230. qiskit/utils/optionals.py +6 -2
  231. qiskit/visualization/array.py +1 -1
  232. qiskit/visualization/bloch.py +2 -3
  233. qiskit/visualization/circuit/matplotlib.py +44 -14
  234. qiskit/visualization/circuit/text.py +38 -18
  235. qiskit/visualization/counts_visualization.py +3 -6
  236. qiskit/visualization/dag_visualization.py +6 -7
  237. qiskit/visualization/pulse_v2/interface.py +8 -3
  238. qiskit/visualization/state_visualization.py +3 -2
  239. qiskit/visualization/timeline/interface.py +18 -8
  240. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/METADATA +12 -8
  241. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/RECORD +245 -235
  242. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/WHEEL +1 -1
  243. qiskit/_qasm2.pyd +0 -0
  244. qiskit/_qasm3.pyd +0 -0
  245. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/LICENSE.txt +0 -0
  246. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/entry_points.txt +0 -0
  247. {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/top_level.txt +0 -0
@@ -15,78 +15,151 @@ Dataclass tools for data namespaces (bins)
15
15
  """
16
16
  from __future__ import annotations
17
17
 
18
- from collections.abc import Iterable
19
- from dataclasses import make_dataclass
18
+ from typing import Any, ItemsView, Iterable, KeysView, ValuesView
20
19
 
20
+ import numpy as np
21
21
 
22
- class DataBinMeta(type):
23
- """Metaclass for :class:`DataBin` that adds the shape to the type name.
22
+ from .shape import ShapedMixin, ShapeInput, shape_tuple
23
+
24
+
25
+ def _value_repr(value: Any) -> str:
26
+ """Helper function for :meth:`DataBin.__repr__`."""
27
+ if isinstance(value, np.ndarray):
28
+ return f"np.ndarray(<shape={value.shape}, dtype={value.dtype}>)"
29
+ return repr(value)
24
30
 
25
- This is so that the class has a custom repr with DataBin<*shape> notation.
26
- """
27
31
 
28
- def __repr__(cls):
29
- name = cls.__name__
30
- if cls._SHAPE is None:
31
- return name
32
- shape = ",".join(map(str, cls._SHAPE))
33
- return f"{name}<{shape}>"
32
+ class DataBin(ShapedMixin):
33
+ """Namespace for storing data.
34
34
 
35
+ .. code-block:: python
36
+
37
+ data = DataBin(
38
+ alpha=BitArray.from_bitstrings(["0010"]),
39
+ beta=np.array([1.2])
40
+ )
35
41
 
36
- class DataBin(metaclass=DataBinMeta):
37
- """Base class for data bin containers.
42
+ print("alpha data:", data.alpha)
43
+ print("beta data:", data.beta)
38
44
 
39
- Subclasses are typically made via :class:`~make_data_bin`, which is a specialization of
40
- :class:`make_dataclass`.
41
45
  """
42
46
 
43
- _RESTRICTED_NAMES = ("_RESTRICTED_NAMES", "_SHAPE", "_FIELDS", "_FIELD_TYPES")
44
- _SHAPE: tuple[int, ...] | None = None
45
- _FIELDS: tuple[str, ...] = ()
46
- """The fields allowed in this data bin."""
47
- _FIELD_TYPES: tuple[type, ...] = ()
48
- """The types of each field."""
47
+ __slots__ = ("_data", "_shape")
48
+
49
+ _RESTRICTED_NAMES = frozenset(
50
+ {
51
+ "_RESTRICTED_NAMES",
52
+ "_SHAPE",
53
+ "_FIELDS",
54
+ "_FIELD_TYPES",
55
+ "_data",
56
+ "_shape",
57
+ "keys",
58
+ "values",
59
+ "items",
60
+ "shape",
61
+ "ndim",
62
+ "size",
63
+ }
64
+ )
65
+
66
+ def __init__(self, *, shape: ShapeInput = (), **data):
67
+ """
68
+ Args:
69
+ data: Name/value data to place in the data bin.
70
+ shape: The leading shape common to all entries in the data bin. This defaults to
71
+ the trivial leading shape of ``()`` that is compatible with all objects.
72
+
73
+ Raises:
74
+ ValueError: If a name overlaps with a method name on this class.
75
+ ValueError: If some value is inconsistent with the provided shape.
76
+ """
77
+ if not self._RESTRICTED_NAMES.isdisjoint(data):
78
+ bad_names = sorted(self._RESTRICTED_NAMES.intersection(data))
79
+ raise ValueError(f"Cannot assign with these field names: {bad_names}")
80
+
81
+ _setattr = super().__setattr__
82
+ _setattr("_shape", shape_tuple(shape))
83
+ _setattr("_data", data)
84
+
85
+ ndim = len(self._shape)
86
+ for name, value in data.items():
87
+ if getattr(value, "shape", shape)[:ndim] != shape:
88
+ raise ValueError(f"The value of '{name}' does not lead with the shape {shape}.")
89
+ _setattr(name, value)
90
+
91
+ super().__init__()
49
92
 
50
93
  def __len__(self):
51
- return len(self._FIELDS)
94
+ return len(self._data)
95
+
96
+ def __setattr__(self, *_):
97
+ raise NotImplementedError
52
98
 
53
99
  def __repr__(self):
54
- vals = (f"{name}={getattr(self, name)}" for name in self._FIELDS if hasattr(self, name))
55
- return f"{type(self)}({', '.join(vals)})"
100
+ vals = [f"{name}={_value_repr(val)}" for name, val in self.items()]
101
+ if self.ndim:
102
+ vals.append(f"shape={self.shape}")
103
+ return f"{type(self).__name__}({', '.join(vals)})"
56
104
 
105
+ def __getitem__(self, key: str) -> Any:
106
+ try:
107
+ return self._data[key]
108
+ except KeyError as ex:
109
+ raise KeyError(f"Key ({key}) does not exist in this data bin.") from ex
57
110
 
58
- def make_data_bin(
59
- fields: Iterable[tuple[str, type]], shape: tuple[int, ...] | None = None
60
- ) -> DataBinMeta:
61
- """Return a new subclass of :class:`~DataBin` with the provided fields and shape.
111
+ def __contains__(self, key: str) -> bool:
112
+ return key in self._data
62
113
 
63
- .. code-block:: python
114
+ def __iter__(self) -> Iterable[str]:
115
+ return iter(self._data)
64
116
 
65
- my_bin = make_data_bin([("alpha", np.NDArray[np.float64])], shape=(20, 30))
117
+ def keys(self) -> KeysView[str]:
118
+ """Return a view of field names."""
119
+ return self._data.keys()
66
120
 
67
- # behaves like a dataclass
68
- my_bin(alpha=np.empty((20, 30)))
121
+ def values(self) -> ValuesView[Any]:
122
+ """Return a view of values."""
123
+ return self._data.values()
124
+
125
+ def items(self) -> ItemsView[str, Any]:
126
+ """Return a view of field names and values"""
127
+ return self._data.items()
128
+
129
+ # The following properties exist to provide support to legacy private class attributes which
130
+ # gained widespread prior to qiskit 1.1. These properties will be removed once the internal
131
+ # projects have made the appropriate changes.
132
+
133
+ @property
134
+ def _FIELDS(self) -> tuple[str, ...]: # pylint: disable=invalid-name
135
+ return tuple(self._data)
136
+
137
+ @property
138
+ def _FIELD_TYPES(self) -> tuple[Any, ...]: # pylint: disable=invalid-name
139
+ return tuple(map(type, self.values()))
140
+
141
+ @property
142
+ def _SHAPE(self) -> tuple[int, ...]: # pylint: disable=invalid-name
143
+ return self.shape
144
+
145
+
146
+ # pylint: disable=unused-argument
147
+ def make_data_bin(
148
+ fields: Iterable[tuple[str, type]], shape: tuple[int, ...] | None = None
149
+ ) -> type[DataBin]:
150
+ """Return the :class:`~DataBin` type.
151
+
152
+ .. note::
153
+ This class used to return a subclass of :class:`~DataBin`. However, that caused confusion
154
+ and didn't have a useful purpose. Several internal projects made use of this internal
155
+ function prior to qiskit 1.1. This function will be removed once these internal projects
156
+ have made the appropriate changes.
69
157
 
70
158
  Args:
71
159
  fields: Tuples ``(name, type)`` specifying the attributes of the returned class.
72
160
  shape: The intended shape of every attribute of this class.
73
161
 
74
162
  Returns:
75
- A new class.
163
+ The :class:`DataBin` type.
76
164
  """
77
- field_names, field_types = zip(*fields) if fields else ([], [])
78
- for name in field_names:
79
- if name in DataBin._RESTRICTED_NAMES:
80
- raise ValueError(f"'{name}' is a restricted name for a DataBin.")
81
- cls = make_dataclass(
82
- "DataBin",
83
- dict(zip(field_names, field_types)),
84
- bases=(DataBin,),
85
- frozen=True,
86
- unsafe_hash=True,
87
- repr=False,
88
- )
89
- cls._SHAPE = shape
90
- cls._FIELDS = field_names
91
- cls._FIELD_TYPES = field_types
92
- return cls
165
+ return DataBin
@@ -132,6 +132,15 @@ class EstimatorPub(ShapedMixin):
132
132
  validate=False, # Assume Pub is already validated
133
133
  )
134
134
  return pub
135
+
136
+ if isinstance(pub, QuantumCircuit):
137
+ raise ValueError(
138
+ f"An invalid Estimator pub-like was given ({type(pub)}). "
139
+ "If you want to run a single pub, you need to wrap it with `[]` like "
140
+ "`estimator.run([(circuit, observables, param_values)])` "
141
+ "instead of `estimator.run((circuit, observables, param_values))`."
142
+ )
143
+
135
144
  if len(pub) not in [2, 3, 4]:
136
145
  raise ValueError(
137
146
  f"The length of pub must be 2, 3 or 4, but length {len(pub)} is given."
@@ -208,8 +217,6 @@ estimator, if ``precision=None`` the estimator will determine the target precisi
208
217
  An Estimator Pub can also be initialized in the following formats which
209
218
  will be converted to the full Pub tuple:
210
219
 
211
- * ``circuit
212
- * ``(circuit,)``
213
220
  * ``(circuit, observables)``
214
- * ``(circuit, observalbes, parameter_values)``
221
+ * ``(circuit, observables, parameter_values)``
215
222
  """
@@ -101,10 +101,10 @@ class ObservablesArray(ShapedMixin):
101
101
  """Convert to a nested list"""
102
102
  return self._array.tolist()
103
103
 
104
- def __array__(self, dtype=None):
104
+ def __array__(self, dtype=None, copy=None):
105
105
  """Convert to an Numpy.ndarray"""
106
106
  if dtype is None or dtype == object:
107
- return self._array
107
+ return self._array.copy() if copy else self._array
108
108
  raise ValueError("Type must be 'None' or 'object'")
109
109
 
110
110
  @overload
@@ -11,7 +11,7 @@
11
11
  # that they have been altered from the originals.
12
12
 
13
13
  """
14
- Base Pub class
14
+ Base Pub result class
15
15
  """
16
16
 
17
17
  from __future__ import annotations
@@ -18,10 +18,11 @@ Sampler Pub class
18
18
  from __future__ import annotations
19
19
 
20
20
  from collections.abc import Mapping
21
- from typing import Tuple, Union
22
21
  from numbers import Integral
22
+ from typing import Tuple, Union
23
23
 
24
24
  from qiskit import QuantumCircuit
25
+ from qiskit.circuit import CircuitInstruction
25
26
 
26
27
  from .bindings_array import BindingsArray, BindingsArrayLike
27
28
  from .shape import ShapedMixin
@@ -113,6 +114,14 @@ class SamplerPub(ShapedMixin):
113
114
  if isinstance(pub, QuantumCircuit):
114
115
  return cls(circuit=pub, shots=shots, validate=True)
115
116
 
117
+ if isinstance(pub, CircuitInstruction):
118
+ raise ValueError(
119
+ f"An invalid Sampler pub-like was given ({type(pub)}). "
120
+ "If you want to run a single circuit, "
121
+ "you need to wrap it with `[]` like `sampler.run([circuit])` "
122
+ "instead of `sampler.run(circuit)`."
123
+ )
124
+
116
125
  if len(pub) not in [1, 2, 3]:
117
126
  raise ValueError(
118
127
  f"The length of pub must be 1, 2 or 3, but length {len(pub)} is given."
@@ -147,10 +156,17 @@ class SamplerPub(ShapedMixin):
147
156
  # Cross validate circuits and parameter values
148
157
  num_parameters = self.parameter_values.num_parameters
149
158
  if num_parameters != self.circuit.num_parameters:
150
- raise ValueError(
159
+ message = (
151
160
  f"The number of values ({num_parameters}) does not match "
152
161
  f"the number of parameters ({self.circuit.num_parameters}) for the circuit."
153
162
  )
163
+ if num_parameters == 0:
164
+ message += (
165
+ " Note that if you want to run a single pub, you need to wrap it with `[]` like "
166
+ "`sampler.run([(circuit, param_values)])` instead of "
167
+ "`sampler.run((circuit, param_values))`."
168
+ )
169
+ raise ValueError(message)
154
170
 
155
171
 
156
172
  SamplerPubLike = Union[
@@ -171,7 +187,7 @@ if ``shots=None`` the number of run shots is determined by the sampler.
171
187
  A Sampler Pub can also be initialized in the following formats which
172
188
  will be converted to the full Pub tuple:
173
189
 
174
- * ``circuit
190
+ * ``circuit``
175
191
  * ``(circuit,)``
176
192
  * ``(circuit, parameter_values)``
177
193
  """
@@ -0,0 +1,74 @@
1
+ # This code is part of Qiskit.
2
+ #
3
+ # (C) Copyright IBM 2024.
4
+ #
5
+ # This code is licensed under the Apache License, Version 2.0. You may
6
+ # obtain a copy of this license in the LICENSE.txt file in the root directory
7
+ # of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
8
+ #
9
+ # Any modifications or derivative works of this code must retain this
10
+ # copyright notice, and modified files need to carry a notice indicating
11
+ # that they have been altered from the originals.
12
+
13
+ """
14
+ Sampler Pub result class
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from typing import Iterable
20
+
21
+ import numpy as np
22
+
23
+ from .bit_array import BitArray
24
+ from .pub_result import PubResult
25
+
26
+
27
+ class SamplerPubResult(PubResult):
28
+ """Result of Sampler Pub."""
29
+
30
+ def join_data(self, names: Iterable[str] | None = None) -> BitArray | np.ndarray:
31
+ """Join data from many registers into one data container.
32
+
33
+ Data is joined along the bits axis. For example, for :class:`~.BitArray` data, this corresponds
34
+ to bitstring concatenation.
35
+
36
+ Args:
37
+ names: Which registers to join. Their order is maintained, for example, given
38
+ ``["alpha", "beta"]``, the data from register ``alpha`` is placed to the left of the
39
+ data from register ``beta``. When ``None`` is given, this value is set to the
40
+ ordered list of register names, which will have been preserved from the input circuit
41
+ order.
42
+
43
+ Returns:
44
+ Joint data.
45
+
46
+ Raises:
47
+ ValueError: If specified names are empty.
48
+ ValueError: If specified name does not exist.
49
+ TypeError: If specified data comes from incompatible types.
50
+ """
51
+ if names is None:
52
+ names = list(self.data)
53
+ if not names:
54
+ raise ValueError("No entry exists in the data bin.")
55
+ else:
56
+ names = list(names)
57
+ if not names:
58
+ raise ValueError("An empty name list is given.")
59
+ for name in names:
60
+ if name not in self.data:
61
+ raise ValueError(f"Name '{name}' does not exist.")
62
+
63
+ data = [self.data[name] for name in names]
64
+ if isinstance(data[0], BitArray):
65
+ if not all(isinstance(datum, BitArray) for datum in data):
66
+ raise TypeError("Data comes from incompatible types.")
67
+ joint_data = BitArray.concatenate_bits(data)
68
+ elif isinstance(data[0], np.ndarray):
69
+ if not all(isinstance(datum, np.ndarray) for datum in data):
70
+ raise TypeError("Data comes from incompatible types.")
71
+ joint_data = np.concatenate(data, axis=-1)
72
+ else:
73
+ raise TypeError("Data comes from incompatible types.")
74
+ return joint_data
@@ -85,7 +85,7 @@ def array_coerce(arr: ArrayLike | Shaped) -> NDArray | Shaped:
85
85
  """
86
86
  if isinstance(arr, Shaped):
87
87
  return arr
88
- return np.array(arr, copy=False)
88
+ return np.asarray(arr)
89
89
 
90
90
 
91
91
  def _flatten_to_ints(arg: ShapeInput) -> Iterable[int]:
@@ -22,7 +22,7 @@ import numpy as np
22
22
  from qiskit.quantum_info import SparsePauliOp, Statevector
23
23
 
24
24
  from .base import BaseEstimatorV2
25
- from .containers import EstimatorPubLike, PrimitiveResult, PubResult
25
+ from .containers import DataBin, EstimatorPubLike, PrimitiveResult, PubResult
26
26
  from .containers.estimator_pub import EstimatorPub
27
27
  from .primitive_job import PrimitiveJob
28
28
  from .utils import bound_circuit_to_instruction
@@ -160,6 +160,6 @@ class StatevectorEstimator(BaseEstimatorV2):
160
160
  raise ValueError("Given operator is not Hermitian and noise cannot be added.")
161
161
  expectation_value = rng.normal(expectation_value, precision)
162
162
  evs[index] = expectation_value
163
- data_bin_cls = self._make_data_bin(pub)
164
- data_bin = data_bin_cls(evs=evs, stds=stds)
165
- return PubResult(data_bin, metadata={"precision": precision})
163
+
164
+ data = DataBin(evs=evs, stds=stds, shape=evs.shape)
165
+ return PubResult(data, metadata={"precision": precision})
@@ -15,9 +15,9 @@ Statevector Sampler class
15
15
 
16
16
  from __future__ import annotations
17
17
 
18
+ import warnings
18
19
  from dataclasses import dataclass
19
20
  from typing import Iterable
20
- import warnings
21
21
 
22
22
  import numpy as np
23
23
  from numpy.typing import NDArray
@@ -30,10 +30,10 @@ from .base import BaseSamplerV2
30
30
  from .base.validation import _has_measure
31
31
  from .containers import (
32
32
  BitArray,
33
+ DataBin,
33
34
  PrimitiveResult,
34
- PubResult,
35
+ SamplerPubResult,
35
36
  SamplerPubLike,
36
- make_data_bin,
37
37
  )
38
38
  from .containers.sampler_pub import SamplerPub
39
39
  from .containers.bit_array import _min_num_bytes
@@ -154,7 +154,7 @@ class StatevectorSampler(BaseSamplerV2):
154
154
 
155
155
  def run(
156
156
  self, pubs: Iterable[SamplerPubLike], *, shots: int | None = None
157
- ) -> PrimitiveJob[PrimitiveResult[PubResult]]:
157
+ ) -> PrimitiveJob[PrimitiveResult[SamplerPubResult]]:
158
158
  if shots is None:
159
159
  shots = self._default_shots
160
160
  coerced_pubs = [SamplerPub.coerce(pub, shots) for pub in pubs]
@@ -169,11 +169,11 @@ class StatevectorSampler(BaseSamplerV2):
169
169
  job._submit()
170
170
  return job
171
171
 
172
- def _run(self, pubs: Iterable[SamplerPub]) -> PrimitiveResult[PubResult]:
172
+ def _run(self, pubs: Iterable[SamplerPub]) -> PrimitiveResult[SamplerPubResult]:
173
173
  results = [self._run_pub(pub) for pub in pubs]
174
174
  return PrimitiveResult(results)
175
175
 
176
- def _run_pub(self, pub: SamplerPub) -> PubResult:
176
+ def _run_pub(self, pub: SamplerPub) -> SamplerPubResult:
177
177
  circuit, qargs, meas_info = _preprocess_circuit(pub.circuit)
178
178
  bound_circuits = pub.parameter_values.bind_all(circuit)
179
179
  arrays = {
@@ -194,15 +194,10 @@ class StatevectorSampler(BaseSamplerV2):
194
194
  ary = _samples_to_packed_array(samples_array, item.num_bits, item.qreg_indices)
195
195
  arrays[item.creg_name][index] = ary
196
196
 
197
- data_bin_cls = make_data_bin(
198
- [(item.creg_name, BitArray) for item in meas_info],
199
- shape=bound_circuits.shape,
200
- )
201
197
  meas = {
202
198
  item.creg_name: BitArray(arrays[item.creg_name], item.num_bits) for item in meas_info
203
199
  }
204
- data_bin = data_bin_cls(**meas)
205
- return PubResult(data_bin, metadata={"shots": pub.shots})
200
+ return SamplerPubResult(DataBin(**meas, shape=pub.shape), metadata={"shots": pub.shots})
206
201
 
207
202
 
208
203
  def _preprocess_circuit(circuit: QuantumCircuit):
@@ -17,13 +17,13 @@ Providers Interface (:mod:`qiskit.providers`)
17
17
 
18
18
  .. currentmodule:: qiskit.providers
19
19
 
20
- This module contains the classes used to build external providers for Terra. A
21
- provider is anything that provides an external service to Terra. The typical
20
+ This module contains the classes used to build external providers for Qiskit. A
21
+ provider is anything that provides an external service to Qiskit. The typical
22
22
  example of this is a Backend provider which provides
23
23
  :class:`~qiskit.providers.Backend` objects which can be used for executing
24
24
  :class:`~qiskit.circuit.QuantumCircuit` and/or :class:`~qiskit.pulse.Schedule`
25
25
  objects. This module contains the abstract classes which are used to define the
26
- interface between a provider and terra.
26
+ interface between a provider and Qiskit.
27
27
 
28
28
  Version Support
29
29
  ===============
@@ -36,17 +36,17 @@ backwards compatible between versions.
36
36
  Version Changes
37
37
  ----------------
38
38
 
39
- Each minor version release of qiskit-terra **may** increment the version of any
40
- providers interface a single version number. It will be an aggregate of all
39
+ Each minor version release of ``qiskit`` **may** increment the version of any
40
+ backend interface a single version number. It will be an aggregate of all
41
41
  the interface changes for that release on that interface.
42
42
 
43
43
  Version Support Policy
44
44
  ----------------------
45
45
 
46
46
  To enable providers to have time to adjust to changes in this interface
47
- Terra will support multiple versions of each class at once. Given the
47
+ Qiskit will support multiple versions of each class at once. Given the
48
48
  nature of one version per release the version deprecation policy is a bit
49
- more conservative than the standard deprecation policy. Terra will support a
49
+ more conservative than the standard deprecation policy. Qiskit will support a
50
50
  provider interface version for a minimum of 3 minor releases or the first
51
51
  release after 6 months from the release that introduced a version, whichever is
52
52
  longer, prior to a potential deprecation. After that the standard deprecation
@@ -57,17 +57,17 @@ the release of 0.19.0 we release 0.20.0, 0.21.0, and 0.22.0, then 7 months after
57
57
  0.19.0 we release 0.23.0. In 0.23.0 we can deprecate BackendV2, and it needs to
58
58
  still be supported and can't be removed until the deprecation policy completes.
59
59
 
60
- It's worth pointing out that Terra's version support policy doesn't mean
60
+ It's worth pointing out that Qiskit's version support policy doesn't mean
61
61
  providers themselves will have the same support story, they can (and arguably
62
62
  should) update to newer versions as soon as they can, the support window is
63
- just for Terra's supported versions. Part of this lengthy window prior to
63
+ just for Qiskit's supported versions. Part of this lengthy window prior to
64
64
  deprecation is to give providers enough time to do their own deprecation of a
65
65
  potential end user impacting change in a user facing part of the interface
66
66
  prior to bumping their version. For example, let's say we changed the signature
67
67
  to ``Backend.run()`` in ``BackendV34`` in a backwards incompatible way. Before
68
68
  Aer could update its :class:`~qiskit_aer.AerSimulator` class
69
69
  to be based on version 34 they'd need to deprecate the old signature prior to switching
70
- over. The changeover for Aer is not guaranteed to be lockstep with Terra so we
70
+ over. The changeover for Aer is not guaranteed to be lockstep with Qiskit, so we
71
71
  need to ensure there is a sufficient amount of time for Aer to complete its
72
72
  deprecation cycle prior to removing version 33 (ie making version 34
73
73
  mandatory/the minimum version).
@@ -131,12 +131,13 @@ Exceptions
131
131
  .. autoexception:: JobTimeoutError
132
132
  .. autoexception:: BackendConfigurationError
133
133
 
134
- ======================
135
- Writing a New Provider
136
- ======================
134
+ =====================
135
+ Writing a New Backend
136
+ =====================
137
137
 
138
138
  If you have a quantum device or simulator that you would like to integrate with
139
- Qiskit you will need to write a provider. A provider will provide Terra with a
139
+ Qiskit you will need to write a backend. A provider is a collection of backends
140
+ and will provide Qiskit with a
140
141
  method to get available :class:`~qiskit.providers.BackendV2` objects. The
141
142
  :class:`~qiskit.providers.BackendV2` object provides both information describing
142
143
  a backend and its operation for the :mod:`~qiskit.transpiler` so that circuits
@@ -149,8 +150,7 @@ executing circuits on devices in a standard
149
150
  fashion regardless of how the backend is implemented. At a high level the basic
150
151
  steps for writing a provider are:
151
152
 
152
- * Implement a :class:`~qiskit.providers.ProviderV1` subclass that handles
153
- access to the backend(s).
153
+ * Implement a ``Provider`` class that handles access to the backend(s).
154
154
  * Implement a :class:`~qiskit.providers.BackendV2` subclass and its
155
155
  :meth:`~qiskit.providers.BackendV2.run` method.
156
156
 
@@ -173,12 +173,11 @@ of a provider object. The provider object will then provide a list of backends,
173
173
  and methods to filter and acquire backends (using the provided credentials if
174
174
  required). An example provider class looks like::
175
175
 
176
- from qiskit.providers import ProviderV1 as Provider
177
176
  from qiskit.providers.providerutils import filter_backends
178
177
 
179
178
  from .backend import MyBackend
180
179
 
181
- class MyProvider(Provider):
180
+ class MyProvider:
182
181
 
183
182
  def __init__(self, token=None):
184
183
  super().__init__()
@@ -40,8 +40,8 @@ class Backend:
40
40
  class BackendV1(Backend, ABC):
41
41
  """Abstract class for Backends
42
42
 
43
- This abstract class is to be used for all Backend objects created by a
44
- provider. There are several classes of information contained in a Backend.
43
+ This abstract class is to be used for Backend objects.
44
+ There are several classes of information contained in a Backend.
45
45
  The first are the attributes of the class itself. These should be used to
46
46
  defined the immutable characteristics of the backend. The ``options``
47
47
  attribute of the backend is used to contain the dynamic user configurable
@@ -1,6 +1,6 @@
1
1
  # This code is part of Qiskit.
2
2
  #
3
- # (C) Copyright IBM 2020.
3
+ # (C) Copyright IBM 2020, 2024.
4
4
  #
5
5
  # This code is licensed under the Apache License, Version 2.0. You may
6
6
  # obtain a copy of this license in the LICENSE.txt file in the root directory
@@ -57,7 +57,7 @@ def convert_to_target(
57
57
  A ``Target`` instance.
58
58
  """
59
59
 
60
- # importing pacakges where they are needed, to avoid cyclic-import.
60
+ # importing packages where they are needed, to avoid cyclic-import.
61
61
  # pylint: disable=cyclic-import
62
62
  from qiskit.transpiler.target import (
63
63
  Target,
@@ -82,7 +82,7 @@ def convert_to_target(
82
82
  "switch_case": SwitchCaseOp,
83
83
  }
84
84
 
85
- in_data = {"num_qubits": configuration.n_qubits}
85
+ in_data = {"num_qubits": configuration.num_qubits}
86
86
 
87
87
  # Parse global configuration properties
88
88
  if hasattr(configuration, "dt"):
@@ -97,7 +97,6 @@ def convert_to_target(
97
97
  all_instructions = set.union(
98
98
  basis_gates, set(required), supported_instructions.intersection(CONTROL_FLOW_OP_NAMES)
99
99
  )
100
-
101
100
  inst_name_map = {} # type: Dict[str, Instruction]
102
101
 
103
102
  faulty_ops = set()
@@ -244,10 +243,8 @@ def convert_to_target(
244
243
 
245
244
  for name in inst_sched_map.instructions:
246
245
  for qubits in inst_sched_map.qubits_with_instruction(name):
247
-
248
246
  if not isinstance(qubits, tuple):
249
247
  qubits = (qubits,)
250
-
251
248
  if (
252
249
  name not in all_instructions
253
250
  or name not in prop_name_map
@@ -267,17 +264,18 @@ def convert_to_target(
267
264
  continue
268
265
 
269
266
  entry = inst_sched_map._get_calibration_entry(name, qubits)
270
-
271
267
  try:
272
268
  prop_name_map[name][qubits].calibration = entry
273
269
  except AttributeError:
270
+ # if instruction properties are "None", add entry
271
+ prop_name_map[name].update({qubits: InstructionProperties(None, None, entry)})
274
272
  logger.info(
275
273
  "The PulseDefaults payload received contains an instruction %s on "
276
- "qubits %s which is not present in the configuration or properties payload.",
274
+ "qubits %s which is not present in the configuration or properties payload."
275
+ "A new properties entry will be added to include the new calibration data.",
277
276
  name,
278
277
  qubits,
279
278
  )
280
-
281
279
  # Add parsed properties to target
282
280
  target = Target(**in_data)
283
281
  for inst_name in all_instructions:
@@ -384,7 +382,7 @@ class BackendV2Converter(BackendV2):
384
382
  super().__init__(
385
383
  provider=backend.provider,
386
384
  name=backend.name(),
387
- description=self._config.description,
385
+ description=getattr(self._config, "description", None),
388
386
  online_date=getattr(self._config, "online_date", None),
389
387
  backend_version=self._config.backend_version,
390
388
  )