-
Notifications
You must be signed in to change notification settings - Fork 157
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
Support local execution on simulators #1243
Conversation
I wrote the basic flow, including a simple test. However, I encountered quite a few problems/questions:
|
I don't believe so, we can just support V2 for now
No, QASM3 is not currently supported on simulators
No, I don't believe so -
No, sessions don't have any meaning when using simulators - jobs on simulators run the same way, independent of whether
Yes, the user must have an account |
…untime into fake_backends
…untime into fake_backends
…untime into fake_backends
On second thought, I am not sure we need to do anything more for executing
Results are:
What do you think? |
from qiskit.providers.provider import ProviderV1 | ||
from qiskit.providers.exceptions import QiskitBackendNotFoundError | ||
from qiskit.providers.fake_provider.fake_backend import FakeBackendV2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have recently opened a PR that migrates the fake provider base classes from qiskit (#1270), should it be merged before this PR, this import path would change to from qiskit_ibm_runtime.fake_provider.fake_backend import FakeBackendV2
. I'm happy to monitor it on my side, but thought it would make sense to bring it to your attention too.
|
||
from qiskit.primitives.primitive_job import PrimitiveJob | ||
from qiskit.providers import JobStatus, JobV1 | ||
from qiskit.providers.fake_provider import FakeBackendV2 as FakeBackend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment as above regarding the import path
qiskit_ibm_runtime/options/utils.py
Outdated
@@ -12,6 +12,7 @@ | |||
|
|||
"""Utility functions for options.""" | |||
|
|||
from qiskit.providers.fake_provider import fake_backend |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too
) -> None: | ||
"""FakeRuntimeJob constructor.""" | ||
super().__init__(backend=backend, job_id=job_id) | ||
# self._service = service # do we need this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need service, but it would be nice to have the other ones - creation_date, user_callback, result_decoder, tags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added creation_date
and tags
.
Removed user_callback
as you wrote below and also because it refers to interim results.
Removed result_decoder
as you wrote below, because results will not be returned encoded.
qiskit_ibm_runtime/base_primitive.py
Outdated
inputs=primitive_inputs, | ||
# are the following relevant for simulators? | ||
# callback=combined.get("environment", {}).get("callback", None), | ||
# result_decoder=DEFAULT_DECODERS.get(self._program_id()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can leave these out for simulators
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of the other options, I think it'd be nice to have the run options like:
{'shots': 400, 'init_qubits': True, 'noise_model': None, 'seed_simulator': None}
and
{'max_execution_time': None, 'log_level': 'WARNING', 'job_tags': []}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shots
andseed_simulator
are already supported.- I couldn't fine
init_qubits
or anything similar in theAerSimulator
, so I don't think there is any point of passing it on. Let me know if you know otherwise. I did find it as a parameter ofassemble_circuits
in Terra, but I am not sure how and if this is called. - Same as above for
max_execution_time
. noise_model
- I think this is only relevant when callingAerSimulator
and not for fake backends, because the latter define their own noise models. For Aer, I pass along all the options that areAerSimulator._default_options()
.- Regarding
log_level
, inTerra
and inAer
, I only found setting thelog_level
globally as an environment variable, so I am not sure what we can do here. job_tags
- I added toFakeRuntimeJob
.
qiskit_ibm_runtime/base_primitive.py
Outdated
@@ -98,6 +101,13 @@ def __init__( | |||
if isinstance(backend, IBMBackend): | |||
self._service = backend.service | |||
self._backend = backend | |||
elif isinstance(backend, AerSimulator): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should check for both Aer and FakeBackend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good comment. I actually only supported FakeBackendV2
when given as a string. I modified here and added to the test TestRunSimulation.test_basic_flow
.
qiskit_ibm_runtime/base_primitive.py
Outdated
@@ -20,10 +20,13 @@ | |||
from dataclasses import asdict | |||
import warnings | |||
|
|||
from qiskit_aer import AerSimulator |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aer is not a required package, so this import be wrapped with try/except
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added try
and raise exception when attempting to run with a simulator and not aer.
Also added skip
for relevant tests.
Please have a look if it is done properly.
primitive_inputs.update(Options._get_program_inputs(combined)) | ||
|
||
if self._backend and combined["transpilation"]["skip_transpilation"]: | ||
if self._backend and combined["transpilation"]["skip_transpilation"] and not run_simulator: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check_faulty
should apply to fake backends as well, if we ever get one that mimics a real backend with faulty edge/qubits
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is currently no check_faulty
method in FakeBackendV2
nor in AerSimulator
. To support this, we would need to add such a method to FakeBackendV2
after it is transferred to Runtime. So I suggest we defer this to a separate issue.
def result(self) -> Any: | ||
"""Return the results of the job.""" | ||
return self._primitive_job.result() | ||
|
||
def cancel(self) -> None: | ||
self._primitive_job.cancel() | ||
|
||
def status(self) -> JobStatus: | ||
return self._primitive_job.status() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just inherit PrimitiveJob
, then you only need to add methods not already supported.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried, but couldn't manage to do that, because I am receiving primitive_job
as an object and couldn't find a way to construct the FakeRuntimeObject
with a pre-constructed super()
object. I would need something like a copy constructor.
I could simply use PrimitiveJob
directly, but then I wouldn't be able to add any fields/methods.
Can you advise how to do this with inheritance?
qiskit_ibm_runtime/options/utils.py
Outdated
is_simulator = ( | ||
isinstance(backend, fake_backend.FakeBackendV2) or backend.configuration().simulator | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is no need to change optimization_level and resilience_level for fake backends. Fake backends should always have noise model (from the real backend it mimics), so one doesn't have to pass it in. And none supports resilience_level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed so we don't apply this to a FakeBackend.
self._service = ( | ||
QiskitRuntimeService() | ||
if QiskitRuntimeService.global_service is None | ||
else QiskitRuntimeService.global_service | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of adding all the local logic into QiskitRuntimeService
, it'd be much cleaner to just create a new LocalRuntimeService
to "mock" any server requests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure I understand your intention in this comment. Do you mean that when running on a simulator, we don't need a real service, and don't need to have a real account?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, so instead of modifying QiskitRuntimeService
, base_primitive
can set self._service
to a mock (local) service. And its run()
method would handle the local operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will try this. Are you also saying that the local run will not need an account? because in a comment above, @kt474 thought it should have an account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can do it this way, without an account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…untime into fake_backends
…on levels as for other simulators
Closing, this was done in #1495 |
Summary
When the
backend
is aFakeBackend
orAerSimulator
, run the program locally, rather than through the IBM Cloud.Details and comments
Fixes #