Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions qiskit_ionq/ionq_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def _default_options(cls) -> Options:
extra_metadata={},
sampler_seed=None, # simulator-only (harmless on QPU)
noise_model="ideal", # simulator-only
memory=True,
)

@property
Expand Down
12 changes: 6 additions & 6 deletions qiskit_ionq/ionq_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import json
from collections import OrderedDict
from datetime import datetime
from typing import Optional, TYPE_CHECKING
from typing import TYPE_CHECKING
from warnings import warn
import requests

Expand All @@ -55,9 +55,9 @@ class IonQClient:

def __init__(
self,
token: Optional[str] = None,
url: Optional[str] = None,
custom_headers: Optional[dict] = None,
token: str | None = None,
url: str | None = None,
custom_headers: dict | None = None,
):
self._token = token
self._custom_headers = custom_headers or {}
Expand Down Expand Up @@ -251,8 +251,8 @@ def get_calibration_data(
def get_results(
self,
results_url: str,
sharpen: Optional[bool] = None,
extra_query_params: Optional[dict] = None,
sharpen: bool | None = None,
extra_query_params: dict | None = None,
) -> dict:
"""Retrieve job results from the IonQ API.

Expand Down
11 changes: 5 additions & 6 deletions qiskit_ionq/ionq_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

"""Native gateset for IonQ hardware."""

from typing import Optional
import math
import numpy as np
from qiskit.circuit.gate import Gate
Expand All @@ -51,7 +50,7 @@ class GPIGate(Gate):
\end{pmatrix}
"""

def __init__(self, phi: ParameterValueType, label: Optional[str] = None):
def __init__(self, phi: ParameterValueType, label: str | None = None):
"""Create new GPI gate."""
super().__init__("gpi", 1, [phi], label=label)

Expand Down Expand Up @@ -86,7 +85,7 @@ class GPI2Gate(Gate):
\end{pmatrix}
"""

def __init__(self, phi: ParameterValueType, label: Optional[str] = None):
def __init__(self, phi: ParameterValueType, label: str | None = None):
"""Create new GPI2 gate."""
super().__init__("gpi2", 1, [phi], label=label)

Expand Down Expand Up @@ -128,8 +127,8 @@ def __init__(
self,
phi0: ParameterValueType,
phi1: ParameterValueType,
theta: Optional[ParameterValueType] = 0.25,
label: Optional[str] = None,
theta: ParameterValueType = 0.25,
label: str | None = None,
):
"""Create new MS gate."""
super().__init__(
Expand Down Expand Up @@ -179,7 +178,7 @@ class ZZGate(Gate):
\end{pmatrix}
"""

def __init__(self, theta: ParameterValueType, label: Optional[str] = None):
def __init__(self, theta: ParameterValueType, label: str | None = None):
"""Create new ZZ gate."""
super().__init__("zz", 2, [theta], label=label)

Expand Down
38 changes: 29 additions & 9 deletions qiskit_ionq/ionq_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
from qiskit.providers.exceptions import JobTimeoutError
from .ionq_result import IonQResult as Result
from .helpers import decompress_metadata_string, normalize
from .exceptions import IonQBackendError

from . import constants, exceptions

Expand Down Expand Up @@ -180,10 +181,12 @@ def __init__(
if passed_args is not None:
self.extra_query_params = passed_args.pop("extra_query_params", {})
self.extra_metadata = passed_args.pop("extra_metadata", {})
self.memory = passed_args.pop("memory", True)
self._passed_args = passed_args
else:
self.extra_query_params = {}
self.extra_metadata = {}
self.memory = True
self._passed_args = {"shots": 1024, "sampler_seed": None}

# Support single or list-of-circuits submissions
Expand Down Expand Up @@ -244,6 +247,23 @@ def get_counts(self, circuit: Optional[QuantumCircuit] = None) -> dict:
"""
return self.result().get_counts(circuit)

def get_memory(self, circuit=None):
"""
Return the memory for the job.
Args:
circuit (str or QuantumCircuit or int or None): Optional.
Returns:
list: A list of memory strings.
"""
if self.memory:
return self.result().get_memory(circuit)

raise IonQBackendError(
f'No memory for experiment "{circuit.name if circuit else ""}". '
"Please verify that you ran a job with "
'the memory flag set, eg., "memory=True".'
)

def get_probabilities(self, circuit=None): # pylint: disable=unused-argument
"""Return the probabilities (for simulators).

Expand Down Expand Up @@ -309,7 +329,7 @@ def result(
if self._status is jobstatus.JobStatus.DONE:
assert self._job_id is not None
response = self._client.get_results(
results_url=self._results_url,
results_url=self._results_urls.get("probabilities", ""),
sharpen=sharpen,
extra_query_params=extra_query_params,
)
Expand Down Expand Up @@ -371,14 +391,12 @@ def status(self, detailed: bool = False) -> jobstatus.JobStatus | dict:
self._num_circuits = self._first_of(stats, "circuits", default=1)

self._num_qubits = self._first_of(stats, "qubits", default=0)
_results_url = self._first_of(
response, "results", "results_url", default={}
)
self._results_url = (
_results_url
if isinstance(_results_url, str)
else _results_url.get("probabilities", {}).get("url")
)
results = response.get("results", {})
self._results_urls = {
k: v.get("url")
for k, v in results.items()
if isinstance(v, dict) and "url" in v
}

# Classical-bit maps per circuit
def _meas_map_from_header(header_dict, fallback_nq):
Expand Down Expand Up @@ -551,8 +569,10 @@ def _format_result(self, data):
use_sampler=is_ideal_sim,
sampler_seed=sampler_seed,
)
memory = None
job_result[i]["data"] = {
"counts": counts,
"memory": memory,
"probabilities": probabilities,
"metadata": qiskit_header[i] or {},
}
Expand Down
10 changes: 5 additions & 5 deletions qiskit_ionq/ionq_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

import logging

from typing import Callable, Literal, Optional
from typing import Callable, Literal

from qiskit.providers.exceptions import QiskitBackendNotFoundError
from qiskit.providers.providerutils import filter_backends
Expand All @@ -55,9 +55,9 @@ class IonQProvider:

def __init__(
self,
token: Optional[str] = None,
url: Optional[str] = None,
custom_headers: Optional[dict] = None,
token: str | None = None,
url: str | None = None,
custom_headers: dict | None = None,
):
super().__init__()
self.custom_headers = custom_headers
Expand Down Expand Up @@ -112,7 +112,7 @@ def __init__(self, backends: list[ionq_backend.IonQBackend]):
setattr(self, backend.name, backend)

def __call__(
self, name: Optional[str] = None, filters: Optional[Callable] = None, **kwargs
self, name: str | None = None, filters: Callable | None = None, **kwargs
) -> list[ionq_backend.IonQBackend]:
"""A listing of all backends from this provider.

Expand Down
2 changes: 1 addition & 1 deletion qiskit_ionq/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
pkg_parent = pathlib.Path(__file__).parent.parent.absolute()

# major, minor, patch
VERSION_INFO = ".".join(map(str, (1, 0, 2)))
VERSION_INFO = ".".join(map(str, (1, 0, 3)))


def _minimal_ext_cmd(cmd: List[str]) -> bytes:
Expand Down
3 changes: 2 additions & 1 deletion test/ionq_backend/test_base_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import pytest
from qiskit import QuantumCircuit
from qiskit.exceptions import QiskitError

from qiskit_ionq import exceptions, ionq_client, ionq_job
from qiskit_ionq.helpers import get_user_agent
Expand Down Expand Up @@ -312,5 +313,5 @@ def test_backend_memory(
)

job = ionq_job.IonQJob(mock_backend, job_id)
with pytest.raises(AttributeError):
with pytest.raises(QiskitError):
job.get_memory() # pylint: disable=no-member
17 changes: 9 additions & 8 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ commands = make html

[pytest]
filterwarnings =
error::DeprecationWarning
error::PendingDeprecationWarning
ignore:Failed to get qubits .* Using 4:UserWarning:qiskit_ionq\.helpers
ignore:Retrying .* more time\(s\) after .*:UserWarning:qiskit_ionq\.helpers
ignore:TimedOut:UserWarning:qiskit_ionq\.ionq_job
ignore:The parameter\(s\).*not checked by default.*submitted in the request\.:UserWarning:qiskit_ionq\.ionq_client
ignore:Unable to retrieve result for job .* cancelled:UserWarning:qiskit_ionq\.ionq_job
ignore:All qubits are idle, removing all but the first\.:UserWarning:test\.transpile_ionq_gates\.test_transpile_ionq_gates
error::DeprecationWarning
error::PendingDeprecationWarning
ignore:Failed to get qubits .* Using 4:UserWarning:qiskit_ionq\.helpers
ignore:Retrying .* more time\(s\) after .*:UserWarning:qiskit_ionq\.helpers
ignore:TimedOut:UserWarning:qiskit_ionq\.ionq_job
ignore:The parameter\(s\).*not checked by default.*submitted in the request\.:UserWarning:qiskit_ionq\.ionq_client
ignore:Unable to retrieve result for job .* cancelled:UserWarning:qiskit_ionq\.ionq_job
ignore:All qubits are idle, removing all but the first\.:UserWarning:test\.transpile_ionq_gates\.test_transpile_ionq_gates
ignore:Transpiler default optimization_level=2\. IonQ \(QIS\) recommends 0-1.*:Warning:qiskit_ionq\.ionq_backend
Loading