Skip to content

Commit aae940f

Browse files
authored
Add support for new AQ workspace v2 statuses (#700)
Azure Quantum will be adding new statuses in our next api-version release: "Queued", "Completed", "Cancelling", and "CancellationRequested". For "Queued", this is a replacement for "Waiting" in v2 workspaces. For "Completed", this is a replacement for "Succeeded" in v2 workspaces to better align with concept of completion despite runtime errors at shot level. For "CancellationRequested" and "Cancelling", these will replace the current behavior on GET /job/{id} API to return "isCancelling" as a separate field. In workspaces v2, these statuses will rarely last long unless quantum engine decides to complete shot before cancelling. In most cases, job will immediately cancel for workspace v2 targets.
1 parent 6c46fda commit aae940f

File tree

7 files changed

+35
-15
lines changed

7 files changed

+35
-15
lines changed

azure-quantum/azure/quantum/_client/models/_enums.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,18 @@ class JobStatus(str, Enum, metaclass=CaseInsensitiveEnumMeta):
3333

3434
WAITING = "Waiting"
3535
"""The job is waiting in the queue to be executed."""
36+
QUEUED = "Queued"
37+
"""The job is queued for execution."""
3638
EXECUTING = "Executing"
3739
"""The job is being executed."""
40+
FINISHING = "Finishing"
41+
"""The job is in the process of finishing."""
42+
CANCELLATION_REQUESTED = "CancellationRequested"
43+
"""Cancellation for the job has been requested."""
44+
CANCELLING = "Cancelling"
45+
"""The job is in the process of being cancelled."""
46+
COMPLETED = "Completed"
47+
"""The job has completed execution."""
3848
SUCCEEDED = "Succeeded"
3949
"""The job completed with success."""
4050
FAILED = "Failed"

azure-quantum/azure/quantum/_client/models/_models.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ class JobDetails(ItemDetails, discriminator="Job"):
252252
:vartype input_data_uri: str
253253
:ivar input_data_format: The format of the input data.
254254
:vartype input_data_format: str
255-
:ivar status: The status of the job. Known values are: "Waiting", "Executing", "Succeeded",
256-
"Failed", and "Cancelled".
255+
:ivar status: The status of the job. Known values are: "Waiting", "Queued", "Executing", "Finishing", "Completed",
256+
"Succeeded", "Failed", "Cancelling", "CancellationRequested" and "Cancelled".
257257
:vartype status: str or ~azure.quantum.models.JobStatus
258258
:ivar metadata: The job metadata. Metadata provides client the ability to store client-specific
259259
information.
@@ -289,8 +289,8 @@ class JobDetails(ItemDetails, discriminator="Job"):
289289
input_data_format: Optional[str] = rest_field(name="inputDataFormat", visibility=["read", "create"])
290290
"""The format of the input data."""
291291
status: Optional[Union[str, "_models.JobStatus"]] = rest_field(visibility=["read"])
292-
"""The status of the job. Known values are: \"Waiting\", \"Executing\", \"Succeeded\", \"Failed\",
293-
and \"Cancelled\"."""
292+
"""The status of the job. Known values are: \"Waiting\", \"Queued\", \"Executing\", \"Finishing\", \"Completed\",
293+
\"Succeeded\", \"Failed\", \"Cancelling\", \"CancellationRequested\" and \"Cancelled\"."""
294294
metadata: Optional[Any] = rest_field(visibility=["read", "create", "update"])
295295
"""The job metadata. Metadata provides client the ability to store client-specific information."""
296296
cancellation_time: Optional[datetime.datetime] = rest_field(

azure-quantum/azure/quantum/cirq/targets/ionq.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,15 @@ def __init__(self, workspace: "Workspace"):
3030
def _to_ionq_status(status: str):
3131
from azure.quantum._client.models._enums import JobStatus
3232
_STATUS_DICT = {
33+
JobStatus.COMPLETED: 'completed',
3334
JobStatus.SUCCEEDED: 'completed',
3435
JobStatus.CANCELLED: 'canceled',
3536
JobStatus.FAILED: 'failed',
3637
JobStatus.EXECUTING: 'running',
38+
JobStatus.FINISHING: 'running',
39+
JobStatus.CANCELLATION_REQUESTED: 'running',
40+
JobStatus.CANCELLING: 'running',
41+
JobStatus.QUEUED: 'ready',
3742
JobStatus.WAITING: 'ready'
3843
}
3944
return _STATUS_DICT.get(status, 'submitted')

azure-quantum/azure/quantum/job/job.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ def refresh(self):
5959
def has_completed(self) -> bool:
6060
"""Check if the job has completed."""
6161
return (
62-
self.details.status == "Succeeded"
62+
self.details.status == "Completed"
63+
or self.details.status == "Succeeded"
6364
or self.details.status == "Failed"
6465
or self.details.status == "Cancelled"
6566
)
@@ -124,7 +125,7 @@ def get_results(self, timeout_secs: float = DEFAULT_TIMEOUT):
124125
if not self.has_completed():
125126
self.wait_until_completed(timeout_secs=timeout_secs)
126127

127-
if not self.details.status == "Succeeded":
128+
if not self.details.status == "Succeeded" or self.details.status == "Completed":
128129
if self.details.status == "Failed" and self._allow_failure_results():
129130
job_blob_properties = self.download_blob_properties(self.details.output_data_uri)
130131
if job_blob_properties.size > 0:
@@ -204,7 +205,7 @@ def get_results_histogram(self, timeout_secs: float = DEFAULT_TIMEOUT):
204205
if not self.has_completed():
205206
self.wait_until_completed(timeout_secs=timeout_secs)
206207

207-
if not self.details.status == "Succeeded":
208+
if not self.details.status == "Succeeded" or self.details.status == "Completed":
208209
if self.details.status == "Failed" and self._allow_failure_results():
209210
job_blob_properties = self.download_blob_properties(self.details.output_data_uri)
210211
if job_blob_properties.size > 0:
@@ -287,7 +288,7 @@ def get_results_shots(self, timeout_secs: float = DEFAULT_TIMEOUT):
287288
if not self.has_completed():
288289
self.wait_until_completed(timeout_secs=timeout_secs)
289290

290-
if not self.details.status == "Succeeded":
291+
if not self.details.status == "Succeeded" or self.details.status == "Completed":
291292
if self.details.status == "Failed" and self._allow_failure_results():
292293
job_blob_properties = self.download_blob_properties(self.details.output_data_uri)
293294
if job_blob_properties.size > 0:

azure-quantum/azure/quantum/qiskit/job.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,16 @@
2424
logger = logging.getLogger(__name__)
2525

2626
AzureJobStatusMap = {
27+
"Completed": JobStatus.DONE,
2728
"Succeeded": JobStatus.DONE,
29+
"Queued": JobStatus.QUEUED,
2830
"Waiting": JobStatus.QUEUED,
2931
"Executing": JobStatus.RUNNING,
32+
"Finishing": JobStatus.RUNNING,
33+
"CancellationRequested": JobStatus.RUNNING,
34+
"Cancelling": JobStatus.RUNNING,
3035
"Failed": JobStatus.ERROR,
31-
"Cancelled": JobStatus.CANCELLED,
32-
"Finishing": JobStatus.RUNNING
36+
"Cancelled": JobStatus.CANCELLED
3337
}
3438

3539
# Constants for output data format:
@@ -81,7 +85,7 @@ def result(self, timeout=None, sampler_seed=None):
8185
"""Return the results of the job."""
8286
self._azure_job.wait_until_completed(timeout_secs=timeout)
8387

84-
success = self._azure_job.details.status == "Succeeded"
88+
success = self._azure_job.details.status == "Succeeded" or self._azure_job.details.status == "Completed"
8589
results = self._format_results(sampler_seed=sampler_seed)
8690

8791
result_dict = {
@@ -128,7 +132,7 @@ def _format_results(self, sampler_seed=None) -> Union[List[Dict[str, Any]], Dict
128132
if (self._azure_job.details.output_data_format == MICROSOFT_OUTPUT_DATA_FORMAT_V2):
129133
return self._format_microsoft_v2_results()
130134

131-
success = self._azure_job.details.status == "Succeeded"
135+
success = self._azure_job.details.status == "Succeeded" or self._azure_job.details.status == "Completed"
132136

133137
job_result = {
134138
"data": {},
@@ -332,7 +336,7 @@ def tryParseJSON(header):
332336

333337

334338
def _format_microsoft_v2_results(self) -> List[Dict[str, Any]]:
335-
success = self._azure_job.details.status == "Succeeded"
339+
success = self._azure_job.details.status == "Succeeded" or self._azure_job.details.status == "Completed"
336340

337341
if not success:
338342
return [{

azure-quantum/azure/quantum/target/pasqal/result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def __init__(self, job: Job) -> None:
3838
RuntimeError: if the job has not completed successfully
3939
"""
4040

41-
if job.details.status != "Succeeded":
41+
if job.details.status != "Succeeded" and job.details.status != "Completed":
4242
raise RuntimeError(
4343
"Cannot retrieve results as job execution failed "
4444
f"(status: {job.details.status}."

azure-quantum/azure/quantum/target/rigetti/result.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def __init__(self, job: Job) -> None:
4343
RuntimeError: if the job has not completed successfully
4444
"""
4545

46-
if job.details.status != "Succeeded":
46+
if job.details.status != "Succeeded" and job.details.status != "Completed":
4747
raise RuntimeError(
4848
"Cannot retrieve results as job execution failed "
4949
f"(status: {job.details.status}."

0 commit comments

Comments
 (0)