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.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +27 -16
- qiskit/_accelerate.pyd +0 -0
- qiskit/_numpy_compat.py +73 -0
- qiskit/assembler/disassemble.py +5 -6
- qiskit/circuit/__init__.py +1131 -169
- qiskit/circuit/_classical_resource_map.py +7 -6
- qiskit/circuit/_utils.py +18 -8
- qiskit/circuit/annotated_operation.py +21 -0
- qiskit/circuit/barrier.py +10 -13
- qiskit/circuit/bit.py +0 -1
- qiskit/circuit/classical/__init__.py +2 -2
- qiskit/circuit/classical/expr/__init__.py +39 -5
- qiskit/circuit/classical/expr/constructors.py +84 -1
- qiskit/circuit/classical/expr/expr.py +83 -13
- qiskit/circuit/classical/expr/visitors.py +83 -0
- qiskit/circuit/commutation_checker.py +86 -51
- qiskit/circuit/controlflow/_builder_utils.py +9 -1
- qiskit/circuit/controlflow/break_loop.py +8 -22
- qiskit/circuit/controlflow/builder.py +116 -1
- qiskit/circuit/controlflow/continue_loop.py +8 -22
- qiskit/circuit/controlflow/control_flow.py +47 -8
- qiskit/circuit/controlflow/for_loop.py +8 -23
- qiskit/circuit/controlflow/if_else.py +13 -27
- qiskit/circuit/controlflow/switch_case.py +14 -21
- qiskit/circuit/controlflow/while_loop.py +9 -23
- qiskit/circuit/controlledgate.py +2 -2
- qiskit/circuit/delay.py +7 -5
- qiskit/circuit/gate.py +20 -7
- qiskit/circuit/instruction.py +31 -30
- qiskit/circuit/instructionset.py +9 -22
- qiskit/circuit/library/__init__.py +8 -2
- qiskit/circuit/library/arithmetic/integer_comparator.py +2 -2
- qiskit/circuit/library/arithmetic/quadratic_form.py +3 -2
- qiskit/circuit/library/blueprintcircuit.py +29 -7
- qiskit/circuit/library/data_preparation/state_preparation.py +6 -5
- qiskit/circuit/library/generalized_gates/diagonal.py +5 -4
- qiskit/circuit/library/generalized_gates/isometry.py +51 -254
- qiskit/circuit/library/generalized_gates/pauli.py +2 -2
- qiskit/circuit/library/generalized_gates/permutation.py +4 -1
- qiskit/circuit/library/generalized_gates/rv.py +15 -11
- qiskit/circuit/library/generalized_gates/uc.py +2 -98
- qiskit/circuit/library/generalized_gates/unitary.py +9 -4
- qiskit/circuit/library/hamiltonian_gate.py +11 -5
- qiskit/circuit/library/n_local/efficient_su2.py +5 -5
- qiskit/circuit/library/n_local/n_local.py +100 -49
- qiskit/circuit/library/n_local/two_local.py +3 -59
- qiskit/circuit/library/overlap.py +3 -3
- qiskit/circuit/library/phase_oracle.py +1 -1
- qiskit/circuit/library/quantum_volume.py +39 -38
- qiskit/circuit/library/standard_gates/equivalence_library.py +50 -0
- qiskit/circuit/library/standard_gates/global_phase.py +4 -2
- qiskit/circuit/library/standard_gates/i.py +1 -2
- qiskit/circuit/library/standard_gates/iswap.py +1 -2
- qiskit/circuit/library/standard_gates/multi_control_rotation_gates.py +11 -5
- qiskit/circuit/library/standard_gates/p.py +31 -15
- qiskit/circuit/library/standard_gates/r.py +4 -3
- qiskit/circuit/library/standard_gates/rx.py +7 -4
- qiskit/circuit/library/standard_gates/rxx.py +4 -3
- qiskit/circuit/library/standard_gates/ry.py +7 -4
- qiskit/circuit/library/standard_gates/ryy.py +4 -3
- qiskit/circuit/library/standard_gates/rz.py +7 -4
- qiskit/circuit/library/standard_gates/rzx.py +4 -3
- qiskit/circuit/library/standard_gates/rzz.py +4 -3
- qiskit/circuit/library/standard_gates/s.py +4 -8
- qiskit/circuit/library/standard_gates/t.py +2 -4
- qiskit/circuit/library/standard_gates/u.py +16 -11
- qiskit/circuit/library/standard_gates/u1.py +6 -2
- qiskit/circuit/library/standard_gates/u2.py +4 -2
- qiskit/circuit/library/standard_gates/u3.py +9 -5
- qiskit/circuit/library/standard_gates/x.py +22 -11
- qiskit/circuit/library/standard_gates/xx_minus_yy.py +4 -3
- qiskit/circuit/library/standard_gates/xx_plus_yy.py +7 -5
- qiskit/circuit/library/standard_gates/z.py +1 -2
- qiskit/circuit/measure.py +4 -1
- qiskit/circuit/operation.py +13 -8
- qiskit/circuit/parameter.py +11 -6
- qiskit/circuit/quantumcircuit.py +864 -128
- qiskit/circuit/quantumcircuitdata.py +2 -2
- qiskit/circuit/reset.py +5 -2
- qiskit/circuit/store.py +95 -0
- qiskit/compiler/assembler.py +22 -22
- qiskit/compiler/transpiler.py +63 -112
- qiskit/converters/circuit_to_dag.py +7 -0
- qiskit/converters/circuit_to_dagdependency_v2.py +47 -0
- qiskit/converters/circuit_to_gate.py +2 -0
- qiskit/converters/circuit_to_instruction.py +22 -0
- qiskit/converters/dag_to_circuit.py +4 -0
- qiskit/converters/dag_to_dagdependency_v2.py +44 -0
- qiskit/dagcircuit/collect_blocks.py +15 -10
- qiskit/dagcircuit/dagcircuit.py +434 -124
- qiskit/dagcircuit/dagdependency.py +19 -12
- qiskit/dagcircuit/dagdependency_v2.py +641 -0
- qiskit/dagcircuit/dagdepnode.py +19 -16
- qiskit/dagcircuit/dagnode.py +14 -4
- qiskit/primitives/__init__.py +12 -8
- qiskit/primitives/backend_estimator.py +3 -5
- qiskit/primitives/backend_estimator_v2.py +410 -0
- qiskit/primitives/backend_sampler_v2.py +287 -0
- qiskit/primitives/base/base_estimator.py +4 -9
- qiskit/primitives/base/base_sampler.py +2 -2
- qiskit/primitives/containers/__init__.py +5 -4
- qiskit/primitives/containers/bit_array.py +292 -2
- qiskit/primitives/containers/data_bin.py +123 -50
- qiskit/primitives/containers/estimator_pub.py +10 -3
- qiskit/primitives/containers/observables_array.py +2 -2
- qiskit/primitives/containers/pub_result.py +1 -1
- qiskit/primitives/containers/sampler_pub.py +19 -3
- qiskit/primitives/containers/sampler_pub_result.py +74 -0
- qiskit/primitives/containers/shape.py +1 -1
- qiskit/primitives/statevector_estimator.py +4 -4
- qiskit/primitives/statevector_sampler.py +7 -12
- qiskit/providers/__init__.py +17 -18
- qiskit/providers/backend.py +2 -2
- qiskit/providers/backend_compat.py +8 -10
- qiskit/providers/basic_provider/basic_provider_tools.py +67 -31
- qiskit/providers/basic_provider/basic_simulator.py +81 -21
- qiskit/providers/fake_provider/fake_1q.py +1 -1
- qiskit/providers/fake_provider/fake_backend.py +3 -408
- qiskit/providers/fake_provider/generic_backend_v2.py +26 -14
- qiskit/providers/provider.py +16 -0
- qiskit/pulse/builder.py +4 -1
- qiskit/pulse/parameter_manager.py +60 -4
- qiskit/pulse/schedule.py +29 -13
- qiskit/pulse/utils.py +61 -20
- qiskit/qasm2/__init__.py +1 -5
- qiskit/qasm2/parse.py +1 -4
- qiskit/qasm3/__init__.py +42 -5
- qiskit/qasm3/ast.py +19 -0
- qiskit/qasm3/exporter.py +178 -106
- qiskit/qasm3/printer.py +27 -5
- qiskit/qpy/__init__.py +247 -13
- qiskit/qpy/binary_io/circuits.py +216 -47
- qiskit/qpy/binary_io/schedules.py +42 -36
- qiskit/qpy/binary_io/value.py +201 -22
- qiskit/qpy/common.py +1 -1
- qiskit/qpy/exceptions.py +20 -0
- qiskit/qpy/formats.py +29 -0
- qiskit/qpy/type_keys.py +21 -0
- qiskit/quantum_info/analysis/distance.py +3 -3
- qiskit/quantum_info/analysis/make_observable.py +2 -1
- qiskit/quantum_info/analysis/z2_symmetries.py +2 -1
- qiskit/quantum_info/operators/channel/chi.py +9 -8
- qiskit/quantum_info/operators/channel/choi.py +10 -9
- qiskit/quantum_info/operators/channel/kraus.py +2 -1
- qiskit/quantum_info/operators/channel/ptm.py +10 -9
- qiskit/quantum_info/operators/channel/quantum_channel.py +2 -1
- qiskit/quantum_info/operators/channel/stinespring.py +2 -1
- qiskit/quantum_info/operators/channel/superop.py +12 -11
- qiskit/quantum_info/operators/channel/transformations.py +12 -11
- qiskit/quantum_info/operators/dihedral/dihedral.py +5 -4
- qiskit/quantum_info/operators/operator.py +43 -30
- qiskit/quantum_info/operators/scalar_op.py +10 -9
- qiskit/quantum_info/operators/symplectic/base_pauli.py +70 -59
- qiskit/quantum_info/operators/symplectic/clifford.py +36 -9
- qiskit/quantum_info/operators/symplectic/pauli.py +48 -4
- qiskit/quantum_info/operators/symplectic/pauli_list.py +36 -14
- qiskit/quantum_info/operators/symplectic/random.py +3 -2
- qiskit/quantum_info/operators/symplectic/sparse_pauli_op.py +54 -33
- qiskit/quantum_info/states/densitymatrix.py +13 -13
- qiskit/quantum_info/states/stabilizerstate.py +3 -3
- qiskit/quantum_info/states/statevector.py +14 -13
- qiskit/quantum_info/states/utils.py +5 -3
- qiskit/result/mitigation/correlated_readout_mitigator.py +3 -2
- qiskit/result/mitigation/local_readout_mitigator.py +2 -1
- qiskit/result/mitigation/utils.py +3 -2
- qiskit/synthesis/__init__.py +2 -0
- qiskit/synthesis/discrete_basis/commutator_decompose.py +2 -2
- qiskit/synthesis/evolution/lie_trotter.py +7 -14
- qiskit/synthesis/evolution/qdrift.py +3 -4
- qiskit/synthesis/linear/cnot_synth.py +1 -3
- qiskit/synthesis/linear/linear_circuits_utils.py +1 -1
- qiskit/synthesis/linear_phase/cz_depth_lnn.py +4 -18
- qiskit/synthesis/permutation/__init__.py +1 -0
- qiskit/synthesis/permutation/permutation_reverse_lnn.py +90 -0
- qiskit/synthesis/qft/qft_decompose_lnn.py +2 -6
- qiskit/synthesis/two_qubit/two_qubit_decompose.py +165 -954
- qiskit/synthesis/two_qubit/xx_decompose/circuits.py +13 -12
- qiskit/synthesis/two_qubit/xx_decompose/decomposer.py +7 -1
- qiskit/synthesis/unitary/aqc/__init__.py +1 -1
- qiskit/synthesis/unitary/aqc/cnot_structures.py +2 -1
- qiskit/synthesis/unitary/aqc/fast_gradient/fast_gradient.py +2 -1
- qiskit/synthesis/unitary/qsd.py +3 -2
- qiskit/transpiler/__init__.py +7 -3
- qiskit/transpiler/layout.py +140 -61
- qiskit/transpiler/passes/__init__.py +6 -0
- qiskit/transpiler/passes/basis/basis_translator.py +7 -2
- qiskit/transpiler/passes/basis/unroll_3q_or_more.py +1 -1
- qiskit/transpiler/passes/basis/unroll_custom_definitions.py +1 -1
- qiskit/transpiler/passes/calibration/rzx_builder.py +2 -1
- qiskit/transpiler/passes/layout/apply_layout.py +8 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +15 -3
- qiskit/transpiler/passes/layout/set_layout.py +1 -1
- qiskit/transpiler/passes/optimization/__init__.py +2 -0
- qiskit/transpiler/passes/optimization/commutation_analysis.py +2 -2
- qiskit/transpiler/passes/optimization/commutative_cancellation.py +1 -1
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +1 -1
- qiskit/transpiler/passes/optimization/cx_cancellation.py +10 -0
- qiskit/transpiler/passes/optimization/elide_permutations.py +114 -0
- qiskit/transpiler/passes/optimization/optimize_1q_decomposition.py +9 -3
- qiskit/transpiler/passes/optimization/optimize_annotated.py +248 -12
- qiskit/transpiler/passes/optimization/remove_final_reset.py +37 -0
- qiskit/transpiler/passes/optimization/template_matching/forward_match.py +1 -3
- qiskit/transpiler/passes/routing/__init__.py +1 -0
- qiskit/transpiler/passes/routing/basic_swap.py +13 -2
- qiskit/transpiler/passes/routing/lookahead_swap.py +7 -1
- qiskit/transpiler/passes/routing/sabre_swap.py +10 -6
- qiskit/transpiler/passes/routing/star_prerouting.py +417 -0
- qiskit/transpiler/passes/routing/stochastic_swap.py +24 -8
- qiskit/transpiler/passes/scheduling/__init__.py +1 -1
- qiskit/transpiler/passes/scheduling/alap.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/align_measures.py +1 -2
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +9 -6
- qiskit/transpiler/passes/scheduling/alignments/pulse_gate_validation.py +8 -0
- qiskit/transpiler/passes/scheduling/alignments/reschedule.py +13 -4
- qiskit/transpiler/passes/scheduling/asap.py +1 -2
- qiskit/transpiler/passes/scheduling/base_scheduler.py +21 -2
- qiskit/transpiler/passes/scheduling/dynamical_decoupling.py +26 -4
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +24 -2
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +28 -4
- qiskit/transpiler/passes/synthesis/aqc_plugin.py +2 -2
- qiskit/transpiler/passes/synthesis/high_level_synthesis.py +120 -13
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +162 -55
- qiskit/transpiler/passes/utils/gates_basis.py +3 -3
- qiskit/transpiler/passmanager.py +44 -1
- qiskit/transpiler/preset_passmanagers/__init__.py +3 -3
- qiskit/transpiler/preset_passmanagers/builtin_plugins.py +34 -16
- qiskit/transpiler/preset_passmanagers/common.py +4 -6
- qiskit/transpiler/preset_passmanagers/plugin.py +9 -1
- qiskit/utils/optionals.py +6 -2
- qiskit/visualization/array.py +1 -1
- qiskit/visualization/bloch.py +2 -3
- qiskit/visualization/circuit/matplotlib.py +44 -14
- qiskit/visualization/circuit/text.py +38 -18
- qiskit/visualization/counts_visualization.py +3 -6
- qiskit/visualization/dag_visualization.py +6 -7
- qiskit/visualization/pulse_v2/interface.py +8 -3
- qiskit/visualization/state_visualization.py +3 -2
- qiskit/visualization/timeline/interface.py +18 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/METADATA +12 -8
- {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/RECORD +245 -235
- {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/WHEEL +1 -1
- qiskit/_qasm2.pyd +0 -0
- qiskit/_qasm3.pyd +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/LICENSE.txt +0 -0
- {qiskit-1.0.2.dist-info → qiskit-1.1.0rc1.dist-info}/entry_points.txt +0 -0
- {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
|
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
|
-
|
23
|
-
|
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
|
-
|
29
|
-
|
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
|
-
|
37
|
-
|
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
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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.
|
94
|
+
return len(self._data)
|
95
|
+
|
96
|
+
def __setattr__(self, *_):
|
97
|
+
raise NotImplementedError
|
52
98
|
|
53
99
|
def __repr__(self):
|
54
|
-
vals =
|
55
|
-
|
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
|
59
|
-
|
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
|
-
|
114
|
+
def __iter__(self) -> Iterable[str]:
|
115
|
+
return iter(self._data)
|
64
116
|
|
65
|
-
|
117
|
+
def keys(self) -> KeysView[str]:
|
118
|
+
"""Return a view of field names."""
|
119
|
+
return self._data.keys()
|
66
120
|
|
67
|
-
|
68
|
-
|
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
|
-
|
163
|
+
The :class:`DataBin` type.
|
76
164
|
"""
|
77
|
-
|
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,
|
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
|
@@ -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
|
-
|
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
|
@@ -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
|
-
|
164
|
-
|
165
|
-
return PubResult(
|
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
|
-
|
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[
|
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[
|
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) ->
|
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
|
-
|
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):
|
qiskit/providers/__init__.py
CHANGED
@@ -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
|
21
|
-
provider is anything that provides an external service to
|
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
|
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
|
40
|
-
|
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
|
-
|
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.
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
180
|
+
class MyProvider:
|
182
181
|
|
183
182
|
def __init__(self, token=None):
|
184
183
|
super().__init__()
|
qiskit/providers/backend.py
CHANGED
@@ -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
|
44
|
-
|
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
|
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.
|
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
|
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
|
)
|