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

Implement IBMBackendWrapper.run_batch method #231

Closed
ryanhill1 opened this issue May 19, 2023 · 9 comments · Fixed by #246
Closed

Implement IBMBackendWrapper.run_batch method #231

ryanhill1 opened this issue May 19, 2023 · 9 comments · Fixed by #246
Assignees
Labels
api 📡 Requests to qBraid API devices 💻 Concerning quantum backends duplicate 👥 This issue or pull request already exists unitaryhack Dedicated issue for UF open-source hackathon

Comments

@ryanhill1
Copy link
Member

Sub-issue to #228: implement IBMBackend component

@ryanhill1 ryanhill1 added duplicate 👥 This issue or pull request already exists devices 💻 Concerning quantum backends api 📡 Requests to qBraid API unitaryhack Dedicated issue for UF open-source hackathon labels May 19, 2023
@TheGupta2012
Copy link
Collaborator

@ryanhill1 can I work on this issue too?

@ryanhill1
Copy link
Member Author

@TheGupta2012 yep!

@TheGupta2012
Copy link
Collaborator

Hi @ryanhill1, could you provide an example of how I can test this method? I am trying to use the following script to test but getting the below-mentioned error.

Script :

from qbraid import get_devices
from qbraid.devices.ibm import ibm_least_busy_qpu
from qbraid import device_wrapper
from qbraid.interface import random_circuit
from qbraid import get_jobs

circuit = random_circuit("qiskit", num_qubits=1, measure=True)
circ_batch = [circuit, circuit, circuit]

least_busy = ibm_least_busy_qpu()
qdevice = device_wrapper(least_busy)
qjob = qdevice.run_batch(circ_batch)

get_jobs(filters={"numResults": 2})

Error :

Traceback (most recent call last):
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/../test_ibm_batch.py", line 13, in <module>
    qjob = qdevice.run_batch(circ_batch)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/devices/ibm/device.py", line 145, in run_batch
    qbraid_job_id = init_job(qiskit_job_id, self, qbraid_circuit_batch, shots)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/job_api.py", line 92, in init_job
    return session.post("/init-job", data=init_data).json()
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/requests/sessions.py", line 635, in post
    return self.request("POST", url, data=data, json=json, **kwargs)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/session.py", line 275, in request
    raise RequestsApiError(message) from ex
qbraid.api.exceptions.RequestsApiError: 400 Client Error: Bad Request for url: https://api.qbraid.com/api/init-job. "If you don't specify an idToken, you must specify both an email and refreshToken"

@ryanhill1
Copy link
Member Author

@TheGupta2012 yes, it seems like you need to add your API credentials to populate your qbraidrc file.

See instructions in README local account setup

@TheGupta2012
Copy link
Collaborator

Hi @ryanhill1 , I am still experiencing the same error after setting up the API token. This was the script I was using -

from qbraid.api import QbraidSession
from qbraid import device_wrapper
from qbraid.interface import random_circuit

circuit = random_circuit("qiskit", num_qubits=1, measure=True)
circ_batch = [circuit, circuit, circuit]
MY_KEY = # key here
session = QbraidSession(api_key=MY_KEY)
session.save_config()

qdevice = device_wrapper("ibm_q_qasm_simulator")
qjob = qdevice.run_batch(circ_batch)
status = qjob.status()

I also tried running this after using export as stated in the README but no luck :/

@ryanhill1
Copy link
Member Author

@TheGupta2012 That's so weird!

So just to confirm, it's failing on the qdevice.run_batch() line with the 400 Client Error from the /init-job route? And second, what type of OS are you working on? If it's Windows, it could be an issue with where the qbraidrc file is being written.

Here are a couple tests to help debug and some troubleshooting tips:

  • After running session.save_config(), please run
>>> from qbraid.api.session import DEFAULT_CONFIG_PATH
>>> f = open(DEFAULT_CONFIG_PATH, 'r')
>>> print(f.read())

and let me know if that file is found, and if entries for both your user email and API key are listed. If your email is not contained in the file, try doing

...
>>> session = QbraidSession(user_email=YOUR_EMAIL, api_key=YOUR_KEY)
>>> session.save_config()

and run the above again, and let me know if that output differs.

  • If there are problems with either of the above, the best work-around, is to use the environment variables approach. You mentioned you already tried this, but I'll have you run the following test to make sure it is set up correctly. From your python shell, please run:
>>> import os
>>> os.getenv("JUPYTERHUB_USER")
>>> os.getenv("QBRAID_API_KEY")

and make sure that you are getting values back for both. Usually, only the API key is necessary because the save_config() function writes the email into your qbraidrc automatically. But if there is an issue with that process, then setting the email value in the environment variable may fix it.

If you are not getting values back for both, (re)set both environment variables with the correct values, restart your terminal, and make sure that the commands above return the expected ouput. Once that's working, please run

>>> from qbraid.api import QbraidSession
>>> session = QbraidSession() # no args
>>> session.user_email
>>> session.api_key
>>> session.get('/identity')

If the environment variables were set correctly, you should get values back for both the user_email and api_key attributes, and get a <Response [200]> after the request to the identity route. Once this is working, try running your qdevice.run_batch method again, and let me know if there are any further issues.

  • If none of the above is working, while we continue to try to diagnose the problem, you can develop on lab.qbraid.com which will have all of your qBraid credentials already setup.

@TheGupta2012
Copy link
Collaborator

Hey @ryanhill1 , this is the output of the following code -

>>> from qbraid.api import QbraidSession
>>> session = QbraidSession() # no args
>>> session.user_email
>>> session.api_key
>>> session.get('/identity')
In [2]: session.user_email
Out[2]: 'harshit.11235@gmail.com'

In [3]: session.api_key
Out[3]: 'py5vkypsvd'

In [4]: session.get('/identity')
Out[4]: <Response [200]>

It seems that the configuration files are set up correctly. I still continue to get the error that I mentioned. I even tried with the main branch without any of my changes, and used the following script with just the run method -

from qbraid.api import QbraidSession
from qbraid import device_wrapper
from qbraid.interface import random_circuit

circuit = random_circuit("qiskit", num_qubits=1, measure=True)
# circ_batch = [circuit]
session = QbraidSession()

qdevice = device_wrapper("ibm_q_qasm_simulator")
qjob = qdevice.run(run_input=circuit)
status = qjob.status()

which resulted in the following exception -

Traceback (most recent call last):
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/session.py", line 257, in request
    response.raise_for_status()
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/requests/models.py", line 1021, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 400 Client Error: Bad Request for url: https://api.qbraid.com/api/init-job

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/../test_ibm_batch.py", line 10, in <module>
    qjob = qdevice.run(run_input=circuit)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/devices/ibm/device.py", line 105, in run
    qbraid_job_id = init_job(qiskit_job_id, self, qbraid_circuit, shots)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/job_api.py", line 93, in init_job
    return session.post("/init-job", data=init_data).json()
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/requests/sessions.py", line 635, in post
    return self.request("POST", url, data=data, json=json, **kwargs)
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/session.py", line 275, in request
    raise RequestsApiError(message) from ex
qbraid.api.exceptions.RequestsApiError: 400 Client Error: Bad Request for url: https://api.qbraid.com/api/init-job. "If you don't specify an idToken, you must specify both an email and refreshToken"
Exception ignored in: <function QbraidSession.__del__ at 0x7fab37ef6ef0>
Traceback (most recent call last):
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qBraid/qbraid/api/session.py", line 74, in __del__
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/requests/sessions.py", line 797, in close
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/requests/adapters.py", line 366, in close
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/urllib3/poolmanager.py", line 223, in clear
  File "/home/harshit/Desktop/college/quantum/Unitary Fund/Unitary-Hack/qbraid-env/lib/python3.10/site-packages/urllib3/_collections.py", line 95, in clear
TypeError: 'NoneType' object is not callable

Maybe there is some way I could test the changes you mentioned in the PR locally without hitting the API?

@ryanhill1
Copy link
Member Author

Hi @TheGupta2012. If you push your changes and let me know which branch of your fork to test on, I can try to recreate the error. I'm guessing the request is being rejected by our API based on type mismatches e.g. getting lists when it expects objects. If you get me that info and I can test from your branch, then I can confirm if it is a compatibility issue with the API, and fix if necessary.

In the meantime, yes, you can feel free to bypass the init_job function to accommodate local testing. The purpose of this function is to generate a qBraid ID for the job, and put store the job info in our cloud database. So instead, you can comment out the line that makes the init_job call, and just hard-code a placeholder job_id instead.

This hacky fix should work for creating the IBMJobWrapper, but the dummy variable qBraid ID may propagate errors in different places as a result such as the .status() method, or get_jobs method.

When you can, send me a link to your updated fork branch and I can try to make any necessary updates on the API side!

@TheGupta2012
Copy link
Collaborator

Hi @ryanhill1 , I am using this branch to test my code. The script I am using is the following -

Script

from qbraid.api import QbraidSession
from qbraid import device_wrapper
from qbraid.interface import random_circuit

circuit = random_circuit("qiskit", num_qubits=1, measure=True)
circ_batch = [circuit, circuit, circuit]

qdevice = device_wrapper("ibm_q_qasm_simulator")
qjob = qdevice.run_batch(circ_batch)
status = qjob.status()

print(status)

Error

qbraid.api.exceptions.RequestsApiError: 400 Client Error: Bad Request for url: https://api.qbraid.com/api/init-job. "If you don't specify an idToken, you must specify both an email and refreshToken"

I also tried using the main branch from upstream with just the run method and a single circuit instance but the error remains the same.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api 📡 Requests to qBraid API devices 💻 Concerning quantum backends duplicate 👥 This issue or pull request already exists unitaryhack Dedicated issue for UF open-source hackathon
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants