qiskit 2.0.0rc2__cp39-abi3-win_amd64.whl → 2.0.1__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.
Files changed (52) hide show
  1. qiskit/VERSION.txt +1 -1
  2. qiskit/__init__.py +1 -4
  3. qiskit/_accelerate.pyd +0 -0
  4. qiskit/circuit/__init__.py +11 -5
  5. qiskit/circuit/classical/expr/constructors.py +0 -12
  6. qiskit/circuit/library/__init__.py +449 -163
  7. qiskit/circuit/library/graph_state.py +1 -0
  8. qiskit/circuit/library/n_local/efficient_su2.py +1 -1
  9. qiskit/circuit/library/n_local/excitation_preserving.py +1 -1
  10. qiskit/circuit/library/quantum_volume.py +9 -0
  11. qiskit/circuit/library/standard_gates/r.py +4 -3
  12. qiskit/circuit/library/standard_gates/x.py +1 -2
  13. qiskit/circuit/quantumcircuit.py +405 -80
  14. qiskit/converters/circuit_to_dag.py +2 -2
  15. qiskit/converters/dag_to_circuit.py +2 -3
  16. qiskit/dagcircuit/dagdependency_v2.py +3 -2
  17. qiskit/primitives/statevector_estimator.py +1 -1
  18. qiskit/qpy/__init__.py +21 -0
  19. qiskit/qpy/binary_io/circuits.py +5 -0
  20. qiskit/result/models.py +1 -2
  21. qiskit/result/result.py +10 -8
  22. qiskit/synthesis/discrete_basis/commutator_decompose.py +30 -6
  23. qiskit/synthesis/discrete_basis/gate_sequence.py +10 -4
  24. qiskit/synthesis/discrete_basis/generate_basis_approximations.py +1 -1
  25. qiskit/synthesis/discrete_basis/solovay_kitaev.py +36 -13
  26. qiskit/transpiler/passes/__init__.py +2 -0
  27. qiskit/transpiler/passes/basis/basis_translator.py +1 -1
  28. qiskit/transpiler/passes/layout/full_ancilla_allocation.py +2 -3
  29. qiskit/transpiler/passes/layout/sabre_layout.py +3 -1
  30. qiskit/transpiler/passes/layout/vf2_utils.py +2 -5
  31. qiskit/transpiler/passes/optimization/__init__.py +1 -0
  32. qiskit/transpiler/passes/scheduling/alignments/check_durations.py +1 -1
  33. qiskit/transpiler/passes/scheduling/padding/base_padding.py +2 -2
  34. qiskit/transpiler/passes/scheduling/padding/dynamical_decoupling.py +5 -5
  35. qiskit/transpiler/passes/scheduling/padding/pad_delay.py +1 -1
  36. qiskit/transpiler/passes/scheduling/time_unit_conversion.py +10 -6
  37. qiskit/transpiler/passes/synthesis/solovay_kitaev_synthesis.py +29 -19
  38. qiskit/transpiler/passes/synthesis/unitary_synthesis.py +2 -1
  39. qiskit/transpiler/preset_passmanagers/generate_preset_pass_manager.py +13 -7
  40. qiskit/transpiler/target.py +11 -0
  41. qiskit/visualization/circuit/text.py +1 -1
  42. qiskit/visualization/counts_visualization.py +4 -0
  43. qiskit/visualization/library.py +4 -1
  44. qiskit/visualization/state_visualization.py +13 -2
  45. qiskit/visualization/timeline/core.py +1 -1
  46. qiskit/visualization/timeline/plotters/matplotlib.py +4 -1
  47. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.dist-info}/METADATA +4 -3
  48. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.dist-info}/RECORD +52 -52
  49. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.dist-info}/WHEEL +1 -1
  50. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.dist-info}/entry_points.txt +0 -0
  51. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.dist-info/licenses}/LICENSE.txt +0 -0
  52. {qiskit-2.0.0rc2.dist-info → qiskit-2.0.1.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
- basis_approximations (str | dict):
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
- # we cache an instance of the Solovay-Kitaev class to generate the
229
- # computationally expensive basis approximation of single qubit gates only once
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, which contains
288
- # the basic approximations, do it now
289
- if SolovayKitaevSynthesis._sk is None:
290
- basic_approximations = config.get("basic_approximations", None)
291
- basis_gates = options.get("basis_gates", ["h", "t", "tdg"])
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
- dag_circuit = circuit_to_dag(approximate_circuit)
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 == "unitary" and len(node.qargs) >= self._min_qubits:
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'``, ``'stochastic'``,
132
+ architecture. Valid choices are ``'basic'``, ``'lookahead'``,
133
133
  ``'sabre'``, and ``'none'`` representing :class:`~.BasicSwap`,
134
- :class:`~.LookaheadSwap`, :class:`~.StochasticSwap`, :class:`~.SabreSwap`, and
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. This may introduce inconsistencies in the transpilation target, "
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, use a custom `target` instance instead."
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
- # update loose constraints to populate pm options
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:
@@ -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, flow_wire_map, CF_RIGHT, conditional=False)
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):
@@ -408,6 +408,10 @@ def _plotting_core(
408
408
  if fig:
409
409
  matplotlib_close_if_inline(fig)
410
410
  if filename is None:
411
+ try:
412
+ fig.tight_layout()
413
+ except AttributeError:
414
+ pass
411
415
  return fig
412
416
  else:
413
417
  return fig.savefig(filename)
@@ -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 `y` position is `y=1+title_pad/100`).
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=1.0 + title_pad / 100)
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.duration, self.formatter["margin.minimum_duration"])
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):
@@ -188,5 +188,8 @@ class MplPlotter(BasePlotter):
188
188
 
189
189
  if self.figure and interactive:
190
190
  self.figure.show()
191
-
191
+ try:
192
+ self.figure.tight_layout()
193
+ except AttributeError:
194
+ pass
192
195
  return self.figure
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: qiskit
3
- Version: 2.0.0rc2
3
+ Version: 2.0.1
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["meas"].get_counts()}")
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.