Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add get_partial_result #135

Merged
merged 5 commits into from
May 9, 2023
Merged
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 docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Changelog
* cost function now takes the same kwargs as process_circuits
* add check for the number of classical registers to the backend
* Updated pytket version requirement to 1.14.1rc0
* add ``get_partial_result`` method to ``QuantinuumBackend``.

0.15.0 (April 2023)
-------------------
Expand Down
28 changes: 27 additions & 1 deletion pytket/extensions/quantinuum/backends/quantinuum.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from dataclasses import dataclass
import json
from http import HTTPStatus
from typing import Dict, List, Set, Optional, Sequence, Union, Any, cast
from typing import Dict, List, Set, Optional, Sequence, Union, Any, cast, Tuple
import warnings

import numpy as np
Expand Down Expand Up @@ -773,6 +773,32 @@ def circuit_status(
)
return circ_status

def get_partial_result(
self, handle: ResultHandle
) -> Tuple[Optional[BackendResult], CircuitStatus]:
"""
Retrieve partial results for a given job, regardless of its current state.

:param handle: handle to results
:type handle: ResultHandle

:return: A tuple containing the results and circuit status.
If no results are available, the first element is None.
:rtype: Tuple[Optional[BackendResult], CircuitStatus]
"""
job_id = str(handle[0])
jr = self.api_handler.retrieve_job_status(job_id)
if not jr:
raise QuantinuumAPIError(f"Unable to retrive job {job_id}")
res = jr.get("results")
circ_status = _parse_status(jr)
if res is None:
return None, circ_status
ppcirc_rep = json.loads(cast(str, handle[1]))
ppcirc = Circuit.from_dict(ppcirc_rep) if ppcirc_rep is not None else None
backres = _convert_result(res, ppcirc)
return backres, circ_status

def get_result(self, handle: ResultHandle, **kwargs: KwargTypes) -> BackendResult:
"""
See :py:meth:`pytket.backends.Backend.get_result`.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
packages=find_namespace_packages(include=["pytket.*"]),
include_package_data=True,
install_requires=[
"pytket == 1.14.1rc0",
"pytket == 1.15.0rc0",
"requests >= 2.2",
"types-requests",
"websockets >= 7.0",
Expand Down
36 changes: 36 additions & 0 deletions tests/api1_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import requests
from requests_mock.mocker import Mocker

from pytket.backends import ResultHandle, StatusEnum
from pytket.extensions.quantinuum.backends.api_wrappers import QuantinuumAPI
from pytket.extensions.quantinuum.backends import QuantinuumBackend
from pytket.circuit import Circuit # type: ignore
Expand Down Expand Up @@ -513,3 +514,38 @@ def test_submit_qasm_api(

assert submitted_json["program"] == qasm
assert submitted_json["count"] == 10


def test_get_partial_result(
requests_mock: Mocker,
mock_quum_api_handler: QuantinuumAPI,
) -> None:
queued_job_id = "abc-123"
requests_mock.register_uri(
"GET",
f"https://qapi.quantinuum.com/v1/job/{queued_job_id}?websocket=true",
json={"job": "abc-123", "name": "job", "status": "queued"},
headers={"Content-Type": "application/json"},
)
running_job_id = "abc-456"
requests_mock.register_uri(
"GET",
f"https://qapi.quantinuum.com/v1/job/{running_job_id}?websocket=true",
json={
"job": "abc-123",
"name": "job",
"status": "running",
"results": {"c": ["10110", "10000", "10110", "01100", "10000"]},
},
headers={"Content-Type": "application/json"},
)
backend = QuantinuumBackend(device_name="H1-2SC", api_handler=mock_quum_api_handler)
h1 = ResultHandle(queued_job_id, "null")
res, status = backend.get_partial_result(h1)
assert res is None
assert status.status == StatusEnum.QUEUED

h2 = ResultHandle(running_job_id, "null")
res, status = backend.get_partial_result(h2)
assert res is not None
assert status.status == StatusEnum.RUNNING