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

IonQConnection verbosity and wait time for job_results #225

Merged
merged 1 commit into from
Oct 6, 2022
Merged
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
25 changes: 19 additions & 6 deletions tangelo/linq/qpu_connection/ionq_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@
class IonQConnection(QpuConnection):
""" Wrapper about the IonQ REST API, to facilitate job submission and automated post-processing of results """

def __init__(self):
def __init__(self, verbose=False):
self.endpoint = "https://api.ionq.co" + "/v0.2" # Update endpoint or version number here if needed
self.api_key = None
self._login()
self.verbose = verbose

@property
def header(self):
Expand Down Expand Up @@ -154,7 +155,8 @@ def job_submit(self, target_backend, abs_circuit, n_shots, job_name, **job_specs
return_dict = json.loads(job_request.text)

self._catch_request_error(return_dict)
print(f"Job submission \tID :: {return_dict['id']} \t status :: {return_dict['status']}")
if self.verbose:
print(f"Job submission \tID :: {return_dict['id']} \t status :: {return_dict['status']}")
return return_dict['id']

def job_get_history(self):
Expand Down Expand Up @@ -186,21 +188,30 @@ def job_status(self, job_id):
job_status = rq.get(self.endpoint + "/jobs/" + job_id, headers=self.header)
job_status = json.loads(job_status.text)
self._catch_request_error(job_status)
print(f"Job info \tID:: {job_id} \t status :: {job_status['status']} {job_status.get('error', '')}")

return job_status

def job_results(self, job_id):
def job_results(self, job_id, wait_time=60):
""" Blocking call querying the REST API at a given frequency, until job results are available.

Args:
job_id (str): string representing the job id
wait_time (int): Number of seconds between consecutive queries to
the IonQ API. If the verbosity is set to True, the status is
printed if it changed since the last query.

Returns:
dict: status response from the REST API
"""

old_job_status = str()
while True:
job_status = self.job_status(job_id)

if self.verbose and job_status != old_job_status:
print(f"Job info \tID:: {job_id} \t status :: {job_status['status']} {job_status.get('error', '')}")
old_job_status = job_status

if job_status['status'] == 'completed' and 'data' in job_status:
hist = job_status['data']['histogram']
h = dict()
Expand All @@ -209,7 +220,7 @@ def job_results(self, job_id):
h[("0"*(job_status['qubits']-len(bs)) + bs)[::-1]] = v
return h
elif job_status['status'] in {'ready', 'running', 'submitted'}:
time.sleep(5)
time.sleep(wait_time)
else:
raise RuntimeError(f'Unexpected job status :: \n {job_status}')

Expand All @@ -225,5 +236,7 @@ def job_cancel(self, job_id):
job_cancel = rq.delete(self.endpoint+"/jobs/"+job_id, headers=self.header)
job_cancel = json.loads(job_cancel.text)
self._catch_request_error(job_cancel)
print(f"Job cancel \tID :: {job_id} \t status :: {job_cancel['status']} {job_cancel.get('error', '')}")

if self.verbose:
print(f"Job cancel \tID :: {job_id} \t status :: {job_cancel['status']} {job_cancel.get('error', '')}")
return job_cancel