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

[FEAT] Handle batches with partial results #707

Merged
merged 10 commits into from
Sep 18, 2024
14 changes: 13 additions & 1 deletion pulser-core/pulser/backend/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import typing
from abc import ABC, abstractmethod
from enum import Enum, auto
from typing import Any, TypedDict
from typing import Any, Mapping, TypedDict

from pulser.backend.abc import Backend
from pulser.devices import Device
Expand Down Expand Up @@ -103,6 +103,14 @@ def get_status(self) -> SubmissionStatus:
"""Gets the status of the remote submission."""
return self._connection._get_submission_status(self._submission_id)

def _get_available_result(self, submission_id: str) -> dict[str, Result]:
HGSilveri marked this conversation as resolved.
Show resolved Hide resolved
"""Return available results and ignore jobs with no results."""
HGSilveri marked this conversation as resolved.
Show resolved Hide resolved
return {
k: v
for k, v in self._connection._query_result(submission_id).items()
HGSilveri marked this conversation as resolved.
Show resolved Hide resolved
if v is not None
}

def __getattr__(self, name: str) -> Any:
MatthieuMoreau0 marked this conversation as resolved.
Show resolved Hide resolved
if name == "_results":
status = self.get_status()
Expand Down Expand Up @@ -139,6 +147,10 @@ def _fetch_result(
"""Fetches the results of a completed submission."""
pass

@abstractmethod
def _query_result(self, submission_id: str) -> Mapping[str, Result | None]:
HGSilveri marked this conversation as resolved.
Show resolved Hide resolved
pass

@abstractmethod
def _get_submission_status(self, submission_id: str) -> SubmissionStatus:
"""Gets the status of a submission from its ID.
Expand Down
37 changes: 22 additions & 15 deletions pulser-pasqal/pulser_pasqal/pasqal_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import copy
import json
from dataclasses import fields
from typing import Any, Type, cast
from typing import Any, Mapping, Type, cast

import backoff
import numpy as np
Expand Down Expand Up @@ -183,37 +183,44 @@ def _fetch_result(
self, submission_id: str, job_ids: list[str] | None
) -> tuple[Result, ...]:
# For now, the results are always sampled results
full_results = self._query_result(submission_id)

if job_ids is None:
job_ids = list(full_results.keys())

results = []
for id in job_ids:
assert full_results[id] is not None, "Failed to fetch the results."
HGSilveri marked this conversation as resolved.
Show resolved Hide resolved
results.append(cast(Result, full_results[id]))

return tuple(results)

def _query_result(self, submission_id: str) -> Mapping[str, Result | None]:
get_batch_fn = backoff_decorator(self._sdk_connection.get_batch)
batch = get_batch_fn(id=submission_id)

seq_builder = Sequence.from_abstract_repr(batch.sequence_builder)
reg = seq_builder.get_register(include_mappable=True)
all_qubit_ids = reg.qubit_ids
meas_basis = seq_builder.get_measurement_basis()

results = []
results: dict[str, Result | None] = {}
sdk_jobs = batch.ordered_jobs
if job_ids is not None:
ind_job_pairs = [
(job_ids.index(job.id), job)
for job in sdk_jobs
if job.id in job_ids
]
ind_job_pairs.sort()
sdk_jobs = [job for _, job in ind_job_pairs]

MatthieuMoreau0 marked this conversation as resolved.
Show resolved Hide resolved
for job in sdk_jobs:
vars = job.variables
size: int | None = None
if vars and "qubits" in vars:
size = len(vars["qubits"])
assert job.result is not None, "Failed to fetch the results."
results.append(
SampledResult(
if job.result is None:
results[job.id] = None
else:
results[job.id] = SampledResult(
atom_order=all_qubit_ids[slice(size)],
meas_basis=meas_basis,
bitstring_counts=job.result,
)
)
return tuple(results)
return results

@backoff_decorator
def _get_submission_status(self, submission_id: str) -> SubmissionStatus:
Expand Down
Loading