qiskit 2.0.0rc2__cp39-abi3-win_amd64.whl → 2.0.2__cp39-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qiskit/VERSION.txt +1 -1
- qiskit/__init__.py +1 -4
- qiskit/_accelerate.pyd +0 -0
- qiskit/circuit/__init__.py +11 -5
- qiskit/circuit/classical/expr/constructors.py +0 -12
- qiskit/circuit/library/__init__.py +449 -163
- qiskit/circuit/library/boolean_logic/quantum_or.py +2 -2
- qiskit/circuit/library/graph_state.py +1 -0
- qiskit/circuit/library/n_local/efficient_su2.py +1 -1
- qiskit/circuit/library/n_local/evolved_operator_ansatz.py +3 -1
- qiskit/circuit/library/n_local/excitation_preserving.py +1 -1
- qiskit/circuit/library/quantum_volume.py +9 -0
- qiskit/circuit/library/standard_gates/r.py +4 -3
- qiskit/circuit/library/standard_gates/x.py +1 -2
- qiskit/circuit/quantumcircuit.py +405 -80
- qiskit/converters/circuit_to_dag.py +2 -2
- qiskit/converters/dag_to_circuit.py +2 -3
- qiskit/dagcircuit/dagdependency_v2.py +3 -2
- qiskit/primitives/statevector_estimator.py +1 -1
- qiskit/qpy/__init__.py +21 -0
- qiskit/qpy/binary_io/circuits.py +5 -0
- qiskit/result/models.py +1 -2
- qiskit/result/result.py +10 -8
- qiskit/synthesis/discrete_basis/commutator_decompose.py +30 -6
- qiskit/synthesis/discrete_basis/gate_sequence.py +10 -4
- qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
- qiskit/synthesis/discrete_basis/solovay_kitaev.py +36 -13
- qiskit/transpiler/passes/__init__.py +2 -0
- qiskit/transpiler/passes/basis/basis_translator.py +1 -1
- qiskit/transpiler/passes/layout/full_ancilla_allocation.py +2 -3
- qiskit/transpiler/passes/layout/sabre_layout.py +3 -1
- qiskit/transpiler/passes/layout/vf2_utils.py +2 -5
- qiskit/transpiler/passes/optimization/__init__.py +1 -0
- qiskit/transpiler/passes/optimization/consolidate_blocks.py +6 -1
- qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
- qiskit/transpiler/passes/scheduling/padding/base_padding.py +2 -2
- qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +5 -5
- qiskit/transpiler/passes/scheduling/padding/pad_delay.py +1 -1
- qiskit/transpiler/passes/scheduling/time_unit_conversion.py +10 -6
- qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +29 -19
- qiskit/transpiler/passes/synthesis/unitary_synthesis.py +2 -1
- qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +13 -7
- qiskit/transpiler/target.py +11 -0
- qiskit/visualization/circuit/text.py +1 -1
- qiskit/visualization/counts_visualization.py +4 -0
- qiskit/visualization/library.py +4 -1
- qiskit/visualization/state_visualization.py +13 -2
- qiskit/visualization/timeline/core.py +1 -1
- qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info}/METADATA +4 -3
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info}/RECORD +55 -55
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info}/WHEEL +1 -1
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info}/entry_points.txt +0 -0
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info/licenses}/LICENSE.txt +0 -0
- {qiskit-2.0.0rc2.dist-info → qiskit-2.0.2.dist-info}/top_level.txt +0 -0
@@ -207,7 +207,7 @@ class SolovayKitaevSynthesis(UnitarySynthesisPlugin):
|
|
207
207
|
|
208
208
|
Supported parameters in the dictionary:
|
209
209
|
|
210
|
-
|
210
|
+
basic_approximations (str | dict):
|
211
211
|
The basic approximations for the finding the best discrete decomposition at the root of the
|
212
212
|
recursion. If a string, it specifies the ``.npy`` file to load the approximations from.
|
213
213
|
If a dictionary, it contains ``{label: SO(3)-matrix}`` pairs. If None, a default based on
|
@@ -215,19 +215,31 @@ class SolovayKitaevSynthesis(UnitarySynthesisPlugin):
|
|
215
215
|
|
216
216
|
basis_gates (list):
|
217
217
|
A list of strings specifying the discrete basis gates to decompose to. If None,
|
218
|
-
defaults to ``["h", "t", "tdg"]``.
|
218
|
+
it defaults to ``["h", "t", "tdg"]``. If ``basic_approximations`` is not None,
|
219
|
+
``basis_set`` is required to correspond to the basis set that was used to
|
220
|
+
generate it.
|
219
221
|
|
220
222
|
depth (int):
|
221
223
|
The gate-depth of the basic approximations. All possible, unique combinations of the
|
222
224
|
basis gates up to length ``depth`` are considered. If None, defaults to 10.
|
225
|
+
If ``basic_approximations`` is not None, ``depth`` is required to correspond to the
|
226
|
+
depth that was used to generate it.
|
223
227
|
|
224
228
|
recursion_degree (int):
|
225
229
|
The number of times the decomposition is recursively improved. If None, defaults to 3.
|
226
230
|
"""
|
227
231
|
|
228
|
-
#
|
229
|
-
#
|
232
|
+
# Generating basic approximations of single-qubit gates is computationally expensive.
|
233
|
+
# We cache the instance of the Solovay-Kitaev class (which contains the approximations),
|
234
|
+
# as well as the basis gates and the depth (used to generate it).
|
235
|
+
# When the plugin is called again, we check if the specified basis gates and depth are
|
236
|
+
# the same as before. If so, the stored basic approximations are reused, and if not, the
|
237
|
+
# approximations are re-generated. In practice (when the plugin is run as a part of the
|
238
|
+
# UnitarySynthesis transpiler pass), the basis gates and the depth do not change, and
|
239
|
+
# basic approximations are not re-generated.
|
230
240
|
_sk = None
|
241
|
+
_basis_gates = None
|
242
|
+
_depth = None
|
231
243
|
|
232
244
|
@property
|
233
245
|
def max_qubits(self):
|
@@ -277,27 +289,25 @@ class SolovayKitaevSynthesis(UnitarySynthesisPlugin):
|
|
277
289
|
return False
|
278
290
|
|
279
291
|
def run(self, unitary, **options):
|
292
|
+
"""Run the SolovayKitaevSynthesis synthesis plugin on the given unitary."""
|
280
293
|
|
281
|
-
# Runtime imports to avoid the overhead of these imports for
|
282
|
-
# plugin discovery and only use them if the plugin is run/used
|
283
294
|
config = options.get("config") or {}
|
284
|
-
|
295
|
+
basis_gates = options.get("basis_gates", ["h", "t", "tdg"])
|
296
|
+
depth = config.get("depth", 10)
|
297
|
+
basic_approximations = config.get("basic_approximations", None)
|
285
298
|
recursion_degree = config.get("recursion_degree", 3)
|
286
299
|
|
287
|
-
# if we didn't yet construct the Solovay-Kitaev instance
|
288
|
-
# the basic approximations
|
289
|
-
if SolovayKitaevSynthesis._sk is None
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
# if the basic approximations are not generated and not given,
|
294
|
-
# try to generate them if the basis set is specified
|
300
|
+
# Check if we didn't yet construct the Solovay-Kitaev instance (which contains the basic
|
301
|
+
# approximations) or if the basic approximations need need to be recomputed.
|
302
|
+
if (SolovayKitaevSynthesis._sk is None) or (
|
303
|
+
(basis_gates != SolovayKitaevSynthesis._basis_gates)
|
304
|
+
or (depth != SolovayKitaevSynthesis._depth)
|
305
|
+
):
|
295
306
|
if basic_approximations is None:
|
296
|
-
depth = config.get("depth", 10)
|
297
307
|
basic_approximations = generate_basic_approximations(basis_gates, depth)
|
298
308
|
|
309
|
+
SolovayKitaevSynthesis._basis_gates = basis_gates
|
310
|
+
SolovayKitaevSynthesis._depth = depth
|
299
311
|
SolovayKitaevSynthesis._sk = SolovayKitaevDecomposition(basic_approximations)
|
300
|
-
|
301
312
|
approximate_circuit = SolovayKitaevSynthesis._sk.run(unitary, recursion_degree)
|
302
|
-
|
303
|
-
return dag_circuit
|
313
|
+
return circuit_to_dag(approximate_circuit)
|
@@ -223,6 +223,7 @@ class UnitarySynthesis(TransformationPass):
|
|
223
223
|
self._min_qubits,
|
224
224
|
self._target,
|
225
225
|
self._basis_gates,
|
226
|
+
self._synth_gates,
|
226
227
|
_coupling_edges,
|
227
228
|
self._approximation_degree,
|
228
229
|
self._natural_direction,
|
@@ -294,7 +295,7 @@ class UnitarySynthesis(TransformationPass):
|
|
294
295
|
|
295
296
|
out_dag = dag.copy_empty_like()
|
296
297
|
for node in dag.topological_op_nodes():
|
297
|
-
if node.name
|
298
|
+
if node.name in self._synth_gates and len(node.qargs) >= self._min_qubits:
|
298
299
|
synth_dag = None
|
299
300
|
unitary = node.matrix
|
300
301
|
n_qubits = len(node.qargs)
|
@@ -13,7 +13,7 @@
|
|
13
13
|
"""
|
14
14
|
Preset pass manager generation function
|
15
15
|
"""
|
16
|
-
|
16
|
+
import copy
|
17
17
|
import warnings
|
18
18
|
|
19
19
|
from qiskit.circuit.controlflow import CONTROL_FLOW_OP_NAMES, get_control_flow_name_mapping
|
@@ -129,9 +129,9 @@ def generate_preset_pass_manager(
|
|
129
129
|
:class:`~.StagedPassManager`. You can see a list of installed plugins by using
|
130
130
|
:func:`~.list_stage_plugins` with ``"layout"`` for the ``stage_name`` argument.
|
131
131
|
routing_method (str): The pass to use for routing qubits on the
|
132
|
-
architecture. Valid choices are ``'basic'``, ``'lookahead'``,
|
132
|
+
architecture. Valid choices are ``'basic'``, ``'lookahead'``,
|
133
133
|
``'sabre'``, and ``'none'`` representing :class:`~.BasicSwap`,
|
134
|
-
:class:`~.LookaheadSwap`, :class:`~.
|
134
|
+
:class:`~.LookaheadSwap`, :class:`~.SabreSwap`, and
|
135
135
|
erroring if routing is required respectively. This can also be the external plugin
|
136
136
|
name to use for the ``routing`` stage of the output :class:`~.StagedPassManager`.
|
137
137
|
You can see a list of installed plugins by using :func:`~.list_stage_plugins` with
|
@@ -200,12 +200,14 @@ def generate_preset_pass_manager(
|
|
200
200
|
# If there are no loose constraints => use backend target if available
|
201
201
|
_no_loose_constraints = basis_gates is None and coupling_map is None and dt is None
|
202
202
|
|
203
|
+
# If the only loose constraint is dt => use backend target and modify dt
|
204
|
+
_adjust_dt = backend is not None and dt is not None
|
205
|
+
|
203
206
|
# Warn about inconsistencies in backend + loose constraints path (dt shouldn't be a problem)
|
204
207
|
if backend is not None and (coupling_map is not None or basis_gates is not None):
|
205
208
|
warnings.warn(
|
206
209
|
"Providing `coupling_map` and/or `basis_gates` along with `backend` is not "
|
207
|
-
"recommended
|
208
|
-
"leading to potential errors.",
|
210
|
+
"recommended, as this will invalidate the backend's gate durations and error rates.",
|
209
211
|
category=UserWarning,
|
210
212
|
stacklevel=2,
|
211
213
|
)
|
@@ -226,13 +228,17 @@ def generate_preset_pass_manager(
|
|
226
228
|
raise ValueError(
|
227
229
|
f"Gates with 3 or more qubits ({gate}) in `basis_gates` or `backend` are "
|
228
230
|
"incompatible with a custom `coupling_map`. To include 3-qubit or larger "
|
229
|
-
" gates in the transpilation basis,
|
231
|
+
" gates in the transpilation basis, provide a custom `target` instead."
|
230
232
|
)
|
231
233
|
|
232
234
|
if target is None:
|
233
235
|
if backend is not None and _no_loose_constraints:
|
234
236
|
# If a backend is specified without loose constraints, use its target directly.
|
235
237
|
target = backend.target
|
238
|
+
elif _adjust_dt:
|
239
|
+
# If a backend is specified with loose dt, use its target and adjust the dt value.
|
240
|
+
target = copy.deepcopy(backend.target)
|
241
|
+
target.dt = dt
|
236
242
|
else:
|
237
243
|
if basis_gates is not None:
|
238
244
|
# Build target from constraints.
|
@@ -255,7 +261,7 @@ def generate_preset_pass_manager(
|
|
255
261
|
dt=dt,
|
256
262
|
)
|
257
263
|
|
258
|
-
#
|
264
|
+
# Update loose constraints to populate pm options
|
259
265
|
if coupling_map is None:
|
260
266
|
coupling_map = target.build_coupling_map()
|
261
267
|
if basis_gates is None and len(target.operation_names) > 0:
|
qiskit/transpiler/target.py
CHANGED
@@ -270,6 +270,17 @@ class Target(BaseTarget):
|
|
270
270
|
self._instruction_durations = None
|
271
271
|
self._instruction_schedule_map = None
|
272
272
|
|
273
|
+
@property
|
274
|
+
def dt(self):
|
275
|
+
"""Return dt."""
|
276
|
+
return self._dt
|
277
|
+
|
278
|
+
@dt.setter
|
279
|
+
def dt(self, dt):
|
280
|
+
"""Set dt and invalidate instruction duration cache"""
|
281
|
+
self._dt = dt
|
282
|
+
self._instruction_durations = None
|
283
|
+
|
273
284
|
def add_instruction(self, instruction, properties=None, name=None):
|
274
285
|
"""Add a new instruction to the :class:`~qiskit.transpiler.Target`
|
275
286
|
|
@@ -1396,7 +1396,7 @@ class TextDrawing:
|
|
1396
1396
|
layers.append(flow_layer2.full_layer)
|
1397
1397
|
|
1398
1398
|
# Draw the right box for End
|
1399
|
-
flow_layer = self.draw_flow_box(node,
|
1399
|
+
flow_layer = self.draw_flow_box(node, wire_map, CF_RIGHT, conditional=False)
|
1400
1400
|
layers.append(flow_layer.full_layer)
|
1401
1401
|
|
1402
1402
|
def draw_flow_box(self, node, flow_wire_map, section, circ_num=0, conditional=False):
|
qiskit/visualization/library.py
CHANGED
@@ -23,15 +23,18 @@ def _generate_circuit_library_visualization(circuit: QuantumCircuit):
|
|
23
23
|
import matplotlib.pyplot as plt
|
24
24
|
|
25
25
|
circuit = circuit.decompose()
|
26
|
+
global_phase, circuit.global_phase = circuit.global_phase, 0
|
26
27
|
ops = circuit.count_ops()
|
27
28
|
num_nl = circuit.num_nonlocal_gates()
|
28
|
-
_fig, (ax0, ax1) = plt.subplots(2, 1)
|
29
|
+
_fig, (ax0, ax1) = plt.subplots(2, 1, figsize=(6.4, 9.6))
|
29
30
|
circuit.draw("mpl", ax=ax0)
|
31
|
+
circuit.global_phase = global_phase
|
30
32
|
ax1.axis("off")
|
31
33
|
ax1.grid(visible=None)
|
32
34
|
ax1.table(
|
33
35
|
[[circuit.name], [circuit.width()], [circuit.depth()], [sum(ops.values())], [num_nl]],
|
34
36
|
rowLabels=["Circuit Name", "Width", "Depth", "Total Gates", "Non-local Gates"],
|
37
|
+
loc="top",
|
35
38
|
)
|
36
39
|
plt.tight_layout()
|
37
40
|
plt.show()
|
@@ -281,7 +281,8 @@ def plot_bloch_multivector(
|
|
281
281
|
reverse_bits (bool): If True, plots qubits following Qiskit's convention [Default:False].
|
282
282
|
font_size (float): Font size for the Bloch ball figures.
|
283
283
|
title_font_size (float): Font size for the title.
|
284
|
-
title_pad (float): Padding for the title (suptitle
|
284
|
+
title_pad (float): Padding for the title (suptitle ``y`` position is ``0.98``
|
285
|
+
and the image height will be extended by ``1 + title_pad/100``).
|
285
286
|
|
286
287
|
Returns:
|
287
288
|
:class:`matplotlib:matplotlib.figure.Figure` :
|
@@ -345,6 +346,8 @@ def plot_bloch_multivector(
|
|
345
346
|
width *= num
|
346
347
|
else:
|
347
348
|
width, height = plt.figaspect(1 / num)
|
349
|
+
if len(title) > 0:
|
350
|
+
height += 1 + title_pad / 100 # additional space for the title
|
348
351
|
default_title_font_size = font_size if font_size is not None else 16
|
349
352
|
title_font_size = title_font_size if title_font_size is not None else default_title_font_size
|
350
353
|
fig = plt.figure(figsize=(width, height))
|
@@ -354,9 +357,13 @@ def plot_bloch_multivector(
|
|
354
357
|
plot_bloch_vector(
|
355
358
|
bloch_data[i], "qubit " + str(pos), ax=ax, figsize=figsize, font_size=font_size
|
356
359
|
)
|
357
|
-
fig.suptitle(title, fontsize=title_font_size, y=
|
360
|
+
fig.suptitle(title, fontsize=title_font_size, y=0.98)
|
358
361
|
matplotlib_close_if_inline(fig)
|
359
362
|
if filename is None:
|
363
|
+
try:
|
364
|
+
fig.tight_layout()
|
365
|
+
except AttributeError:
|
366
|
+
pass
|
360
367
|
return fig
|
361
368
|
else:
|
362
369
|
return fig.savefig(filename)
|
@@ -726,6 +733,10 @@ def plot_state_paulivec(state, title="", figsize=None, color=None, ax=None, *, f
|
|
726
733
|
if return_fig:
|
727
734
|
matplotlib_close_if_inline(fig)
|
728
735
|
if filename is None:
|
736
|
+
try:
|
737
|
+
fig.tight_layout()
|
738
|
+
except AttributeError:
|
739
|
+
pass
|
729
740
|
return fig
|
730
741
|
else:
|
731
742
|
return fig.savefig(filename)
|
@@ -260,7 +260,7 @@ class DrawerCanvas:
|
|
260
260
|
self.add_data(datum)
|
261
261
|
|
262
262
|
# update time range
|
263
|
-
t_end = max(program.
|
263
|
+
t_end = max(program._duration, self.formatter["margin.minimum_duration"])
|
264
264
|
self.set_time_range(t_start=0, t_end=t_end)
|
265
265
|
|
266
266
|
def set_time_range(self, t_start: int, t_end: int):
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: qiskit
|
3
|
-
Version: 2.0.
|
3
|
+
Version: 2.0.2
|
4
4
|
Summary: An open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
|
5
5
|
Author-email: Qiskit Development Team <qiskit@us.ibm.com>
|
6
6
|
License: Apache 2.0
|
@@ -51,6 +51,7 @@ Provides-Extra: csp-layout-pass
|
|
51
51
|
Requires-Dist: python-constraint>=1.4; extra == "csp-layout-pass"
|
52
52
|
Provides-Extra: all
|
53
53
|
Requires-Dist: qiskit[crosstalk-pass,csp-layout-pass,qasm3-import,visualization]; extra == "all"
|
54
|
+
Dynamic: license-file
|
54
55
|
|
55
56
|
# Qiskit
|
56
57
|
|
@@ -121,7 +122,7 @@ from qiskit.primitives import StatevectorSampler
|
|
121
122
|
sampler = StatevectorSampler()
|
122
123
|
job = sampler.run([qc_measured], shots=1000)
|
123
124
|
result = job.result()
|
124
|
-
print(f" > Counts: {result[0].data[
|
125
|
+
print(f" > Counts: {result[0].data['meas'].get_counts()}")
|
125
126
|
```
|
126
127
|
Running this will give an outcome similar to `{'000': 497, '111': 503}` which is `000` 50% of the time and `111` 50% of the time up to statistical fluctuations.
|
127
128
|
To illustrate the power of the Estimator, we now use the quantum information toolbox to create the operator $XXY+XYX+YXX-YYY$ and pass it to the `run()` function, along with our quantum circuit. Note that the Estimator requires a circuit _**without**_ measurements, so we use the `qc` circuit we created earlier.
|