Skip to content

Commit

Permalink
Fix merge conflicts
Browse files Browse the repository at this point in the history
  • Loading branch information
kt474 committed Oct 17, 2024
2 parents 34bfa0e + 79fb167 commit 16aa250
Show file tree
Hide file tree
Showing 29 changed files with 325 additions and 374 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ jobs:
QISKIT_IBM_TOKEN: ${{ secrets.QISKIT_IBM_TOKEN }}
QISKIT_IBM_URL: ${{ secrets.QISKIT_IBM_URL }}
QISKIT_IBM_INSTANCE: ${{ secrets.QISKIT_IBM_INSTANCE }}
QISKIT_IBM_QPU: ${{ secrets.QISKIT_IBM_QPU }}

LOG_LEVEL: DEBUG
STREAM_LOG: True
QISKIT_IN_PARALLEL: True
Expand Down
4 changes: 3 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ Finally, preview the docs build by following the instructions in
Building The release notes are part of the standard qiskit-ibm-runtime
documentation builds. To check what the rendered html output of the release
notes will look like for the current state of the repo you can run:
`tox -edocs` which will build all the documentation into `docs/_build/html`
`tox -e docs` which will build all the documentation into `docs/_build/html`
and the release notes in particular will be located at
`docs/_build/html/release_notes.html`.

Expand Down Expand Up @@ -206,13 +206,15 @@ Sample configuration for IBM Quantum
QISKIT_IBM_TOKEN=... # IBM Quantum API token
QISKIT_IBM_URL=https://auth.quantum-computing.ibm.com/api # IBM Quantum API URL
QISKIT_IBM_INSTANCE=ibm-q/open/main # IBM Quantum provider to use (hub/group/project)
QISKIT_IBM_QPU=... # IBM Quantum Processing Unit to use
```

Sample configuration for IBM Cloud
```bash
QISKIT_IBM_TOKEN=... # IBM Cloud API key
QISKIT_IBM_URL=https://cloud.ibm.com # Cloud URL
QISKIT_IBM_INSTANCE=crn:v1:bluemix:... # The CRN value of the Quantum service instance
QISKIT_IBM_QPU=... # The Quantum Processing Unit to use
```


Expand Down
4 changes: 4 additions & 0 deletions docs/apidocs/debug_tools.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.. automodule:: qiskit_ibm_runtime.debug_tools
:no-members:
:no-inherited-members:
:no-special-members:
1 change: 1 addition & 0 deletions docs/apidocs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ qiskit-ibm-runtime API reference
qiskit_ibm_runtime.transpiler.passes.scheduling
fake_provider
execution_span
debug_tools
visualization
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
# The short X.Y version
version = ''
# The full version, including alpha/beta/rc tags
release = '0.31.0'
release = '0.32.0'

# -- General configuration ---------------------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.31.0
0.32.0
21 changes: 20 additions & 1 deletion qiskit_ibm_runtime/debug_tools/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,26 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Functions and classes for debugging and analyzing qiskit-ibm-runtime jobs."""
"""
=======================================================
Debugging tools (:mod:`qiskit_ibm_runtime.debug_tools`)
=======================================================
.. currentmodule:: qiskit_ibm_runtime.debug_tools
The tools for debugging and analyzing qiskit-ibm-runtime jobs.
Classes
=======
.. autosummary::
:toctree: ../stubs/
Neat
NeatResult
NeatPubResult
"""

from .neat import Neat
from .neat_results import NeatPubResult, NeatResult
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/fake_provider/fake_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ def _get_noise_model_from_backend_v2( # type: ignore
self._set_props_dict_from_json()

properties = BackendProperties.from_dict(self._props_dict)
basis_gates = self.operation_names
basis_gates = self.configuration().basis_gates
num_qubits = self.num_qubits
dt = self.dt # pylint: disable=invalid-name

Expand Down
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/runtime_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ def backend(self, timeout: Optional[float] = None) -> Optional[Backend]:
def stream_results(
self, callback: Callable, decoder: Optional[Type[ResultDecoder]] = None
) -> None:
"""Start streaming job results.
"""(DEPRECATED) Start streaming job results.
Args:
callback: Callback function to be invoked for any interim results and final result.
Expand Down Expand Up @@ -398,7 +398,7 @@ def stream_results(

@deprecate_function("interim_results()", "0.25", "", stacklevel=1)
def interim_results(self, decoder: Optional[Type[ResultDecoder]] = None) -> Any:
"""Return the interim results of the job.
"""(DEPRECATED) Return the interim results of the job.
Args:
decoder: A :class:`ResultDecoder` subclass used to decode interim results.
Expand Down
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/runtime_job_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ def backend(self, timeout: Optional[float] = None) -> Optional[Backend]:
def stream_results(
self, callback: Callable, decoder: Optional[Type[ResultDecoder]] = None
) -> None:
"""Start streaming job results.
"""(DEPRECATED) Start streaming job results.
Args:
callback: Callback function to be invoked for any interim results and final result.
Expand Down Expand Up @@ -305,7 +305,7 @@ def stream_results(

@deprecate_function("interim_results()", "0.25", "", stacklevel=1)
def interim_results(self, decoder: Optional[Type[ResultDecoder]] = None) -> Any:
"""Return the interim results of the job.
"""(DEPRECATED) Return the interim results of the job.
Args:
decoder: A :class:`ResultDecoder` subclass used to decode interim results.
Expand Down
38 changes: 38 additions & 0 deletions qiskit_ibm_runtime/utils/noise_learner_result.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,11 @@ def draw_map(
embedding: Union[Embedding, BackendV2],
colorscale: str = "Bluered",
color_no_data: str = "lightgray",
color_out_of_scale: str = "lightgreen",
num_edge_segments: int = 16,
edge_width: float = 4,
height: int = 500,
highest_rate: Optional[float] = None,
background_color: str = "white",
radius: float = 0.25,
width: int = 800,
Expand All @@ -238,12 +240,46 @@ def draw_map(
to draw the layer error on, or a backend to generate an :class:`~.Embedding` for.
colorscale: The colorscale used to show the rates of this layer error.
color_no_data: The color used for qubits and edges for which no data is available.
color_out_of_scale: The color used for rates with value greater than ``highest_rate``.
num_edge_segments: The number of equal-sized segments that edges are made of.
edge_width: The line width of the edges in pixels.
height: The height of the returned figure.
highest_rate: The highest rate, used to normalize all other rates before choosing their
colors. If ``None``, it defaults to the highest value found in the ``layer_error``.
background_color: The background color.
radius: The radius of the pie charts representing the qubits.
width: The width of the returned figure.
.. code:: python
from qiskit import QuantumCircuit
from qiskit.quantum_info import PauliList
from qiskit_ibm_runtime.utils.embeddings import Embedding
from qiskit_ibm_runtime.utils.noise_learner_result import LayerError, PauliLindbladError
# A five-qubit 1-D embedding with nearest neighbouring connectivity
coordinates1 = [(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5)]
coupling_map1 = [(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]
embedding1 = Embedding(coordinates1, coupling_map1)
# A six-qubit horseshoe-shaped embedding with nearest neighbouring connectivity
coordinates2 = [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]
coupling_map2 = [(0, 1), (1, 2), (0, 3), (3, 4), (4, 5)]
embedding2 = Embedding(coordinates2, coupling_map2)
# A LayerError object
circuit = QuantumCircuit(4)
qubits = [1, 2, 3, 4]
generators = PauliList(["IIIX", "IIXI", "IXII", "YIII", "ZIII", "XXII", "ZZII"])
rates = [0.01, 0.01, 0.01, 0.005, 0.02, 0.01, 0.01]
error = PauliLindbladError(generators, rates)
layer_error = LayerError(circuit, qubits, error)
# Draw the layer error on embedding1
layer_error.draw_map(embedding1)
# Draw the layer error on embedding2
layer_error.draw_map(embedding2)
"""
# pylint: disable=import-outside-toplevel, cyclic-import

Expand All @@ -254,9 +290,11 @@ def draw_map(
embedding,
colorscale,
color_no_data,
color_out_of_scale,
num_edge_segments,
edge_width,
height,
highest_rate,
background_color,
radius,
width,
Expand Down
46 changes: 32 additions & 14 deletions qiskit_ibm_runtime/visualization/draw_layer_error_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"""Functions to visualize :class:`~.NoiseLearnerResult` objects."""

from __future__ import annotations
from typing import Dict, Tuple, Union, TYPE_CHECKING
from typing import Dict, Optional, Tuple, Union, TYPE_CHECKING

import numpy as np
from qiskit.providers.backend import BackendV2
Expand All @@ -31,9 +31,11 @@ def draw_layer_error_map(
embedding: Union[Embedding, BackendV2],
colorscale: str = "Bluered",
color_no_data: str = "lightgray",
color_out_of_scale: str = "lightgreen",
num_edge_segments: int = 16,
edge_width: float = 4,
height: int = 500,
highest_rate: Optional[float] = None,
background_color: str = "white",
radius: float = 0.25,
width: int = 800,
Expand All @@ -47,9 +49,12 @@ def draw_layer_error_map(
to draw the layer error on, or a backend to generate an :class:`~.Embedding` for.
colorscale: The colorscale used to show the rates of ``layer_error``.
color_no_data: The color used for qubits and edges for which no data is available.
color_out_of_scale: The color used for rates with value greater than ``highest_rate``.
num_edge_segments: The number of equal-sized segments that edges are made of.
edge_width: The line width of the edges in pixels.
height: The height of the returned figure.
highest_rate: The highest rate, used to normalize all other rates before choosing their
colors. If ``None``, it defaults to the highest value found in the ``layer_error``.
background_color: The background color.
radius: The radius of the pie charts representing the qubits.
width: The width of the returned figure.
Expand Down Expand Up @@ -83,24 +88,28 @@ def draw_layer_error_map(
# A set of unique edges ``(i, j)``, with ``i < j``.
edges = set(tuple(sorted(edge)) for edge in list(coupling_map))

# The highest rate, used to normalize all other rates before choosing their colors.
high_scale = 0
# The highest rate
max_rate = 0

# Initialize a dictionary of one-qubit errors
qubits = layer_error.qubits
error_1q = layer_error.error.restrict_num_bodies(1)
rates_1q: Dict[int, Dict[str, float]] = {qubit: {} for qubit in layer_error.qubits}
rates_1q: Dict[int, Dict[str, float]] = {qubit: {} for qubit in qubits}
for pauli, rate in zip(error_1q.generators, error_1q.rates):
qubit = np.where(pauli.x | pauli.z)[0][0]
rates_1q[qubit][str(pauli[qubit])] = rate
high_scale = max(high_scale, rate)
qubit_idx = np.where(pauli.x | pauli.z)[0][0]
rates_1q[qubits[qubit_idx]][str(pauli[qubit_idx])] = rate
max_rate = max(max_rate, rate)

# Initialize a dictionary of two-qubit errors
error_2q = layer_error.error.restrict_num_bodies(2)
rates_2q: Dict[Tuple[int, ...], Dict[str, float]] = {qubits: {} for qubits in edges}
rates_2q: Dict[Tuple[int, ...], Dict[str, float]] = {edge: {} for edge in edges}
for pauli, rate in zip(error_2q.generators, error_2q.rates):
qubits = tuple(sorted([i for i, q in enumerate(pauli) if str(q) != "I"]))
rates_2q[qubits][str(pauli[[qubits[0], qubits[1]]])] = rate
high_scale = max(high_scale, rate)
err_idxs = tuple(sorted([i for i, q in enumerate(pauli) if str(q) != "I"]))
edge = (qubits[err_idxs[0]], qubits[err_idxs[1]])
rates_2q[edge][str(pauli[[err_idxs[0], err_idxs[1]]])] = rate
max_rate = max(max_rate, rate)

highest_rate = highest_rate if highest_rate else max_rate

# A discreet colorscale that contains 1000 hues.
discreet_colorscale = sample_colorscale(colorscale, np.linspace(0, 1, 1000))
Expand All @@ -122,7 +131,10 @@ def draw_layer_error_map(
for i in range(num_edge_segments)
]
color = [
get_rgb_color(discreet_colorscale, v / high_scale, color_no_data) for v in all_vals
get_rgb_color(
discreet_colorscale, v / highest_rate, color_no_data, color_out_of_scale
)
for v in all_vals
]
hoverinfo_2q = ""
for pauli, rate in rates_2q[(q1, q2)].items():
Expand Down Expand Up @@ -172,7 +184,9 @@ def draw_layer_error_map(
hoverinfo = ""
for pauli, angle in [("Z", -30), ("X", 90), ("Y", 210)]:
rate = rates_1q.get(qubit, {}).get(pauli, 0)
fillcolor = get_rgb_color(discreet_colorscale, rate / high_scale, color_no_data)
fillcolor = get_rgb_color(
discreet_colorscale, rate / highest_rate, color_no_data, color_out_of_scale
)
shapes += [
{
"type": "path",
Expand All @@ -191,12 +205,16 @@ def draw_layer_error_map(
fig.add_annotation(x=x + 0.3, y=y + 0.4, text=f"{qubit}", showarrow=False)

# Add the hoverinfo for the pie charts
marker_colors = []
for qubit in rates_1q:
max_qubit_rate = max(rates_1q[qubit].values())
marker_colors.append(max_qubit_rate if max_qubit_rate <= highest_rate else highest_rate)
nodes = go.Scatter(
x=xs,
y=ys,
mode="markers",
marker={
"color": list({qubit: max(rates_1q[qubit].values()) for qubit in rates_1q}.values()),
"color": marker_colors,
"colorscale": colorscale,
"showscale": True,
},
Expand Down
9 changes: 7 additions & 2 deletions qiskit_ibm_runtime/visualization/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ def pie_slice(angle_st: float, angle_end: float, x: float, y: float, radius: flo
return path


def get_rgb_color(discreet_colorscale: List[str], val: float, default: str) -> str:
def get_rgb_color(
discreet_colorscale: List[str], val: float, default: str, color_out_of_scale: str
) -> str:
r"""
Maps a float to an RGB color based on a discreet colorscale that contains
exactly ``1000`` hues.
Expand All @@ -55,14 +57,17 @@ def get_rgb_color(discreet_colorscale: List[str], val: float, default: str) -> s
discreet_colorscale: A discreet colorscale.
val: A value to map to a color.
default: A default color returned when ``val`` is ``0``.
color_out_of_scale: The color that is returned when ``val`` is larger than ``1``.
Raises:
ValueError: If the colorscale contains more or less than ``1000`` hues.
"""
if len(discreet_colorscale) != 1000:
raise ValueError("Invalid ``discreet_colorscale.``")

if val >= 1:
if val > 1:
return color_out_of_scale
if val == 1:
return discreet_colorscale[-1]
if val == 0:
return default
Expand Down
17 changes: 17 additions & 0 deletions release-notes/0.31.0.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
0.31.0 (2024-10-15)
===================

New Features
------------

- Added Noisy Estimator Analyzer Tool (NEAT), a class to help understand the expected performance of Estimator jobs. (`1950 <https://github.com/Qiskit/qiskit-ibm-runtime/pull/1950>`__)
- Updated the ISA check to validate that the ``rzz`` angle is between ``[0, pi/2]``. (`1953 <https://github.com/Qiskit/qiskit-ibm-runtime/pull/1953>`__)

Bug Fixes
---------
- Fixed an issue with ISA validation where a change related to connectivity inside control operations was not
applied correctly. (`1954 <https://github.com/Qiskit/qiskit-ibm-runtime/pull/1954>`__)

Other Notes
-----------
- Fake V1 backends have been removed. (`1946 <https://github.com/Qiskit/qiskit-ibm-runtime/pull/1946>`__)
1 change: 0 additions & 1 deletion release-notes/unreleased/1950.feat.rst

This file was deleted.

Loading

0 comments on commit 16aa250

Please sign in to comment.