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

Feature/add qiskit api options #316

Merged
merged 8 commits into from
Apr 23, 2024
Merged
7 changes: 7 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
~~~~~~~~~

Unreleased
----------

* User can pass an `Options` instance (from `qiskit-ibm-runtime`)
via a keyword argument to both an `IBMQBackend` constructor and
an instance method `IBMQBackend.process_circuits`.
cqc-alec marked this conversation as resolved.
Show resolved Hide resolved

0.53.0 (April 2024)
-------------------

Expand Down
31 changes: 26 additions & 5 deletions pytket/extensions/qiskit/backends/ibm.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ class IBMQBackend(Backend):
:type provider: Optional[IBMProvider]
:param token: Authentication token to use the `QiskitRuntimeService`.
:type token: Optional[str]
:param options: A customised `qiskit_ibm_runtime` `Options` instance.
Passed to the qiskit sampler submission during
`process_circuit` (`process_circuits`). If the `Options` instance is not
specified, both `optimization_level` and `resilience_level` are set to 0,
and `skip_transpilation` is set to True. These default values can be customised
by using the `options` keyword argument.
:type options: Dict[str, int]
"""

_supports_shots = False
Expand All @@ -184,6 +191,7 @@ def __init__(
monitor: bool = True,
provider: Optional["IBMProvider"] = None,
token: Optional[str] = None,
options: Options = None,
):
super().__init__()
self._pytket_config = QiskitConfig.from_default_config_file()
Expand Down Expand Up @@ -214,6 +222,13 @@ def __init__(
# cache of results keyed by job id and circuit index
self._ibm_res_cache: Dict[Tuple[str, int], Counter] = dict()

if options is None:
options = Options()
options.optimization_level = 0
options.resilience_level = 0
options.transpilation.skip_transpilation = True
self._sampler_options = options

self._MACHINE_DEBUG = False

@staticmethod
Expand Down Expand Up @@ -503,7 +518,13 @@ def process_circuits(
apply the pytket ``SimplifyInitial`` pass to improve
fidelity of results assuming all qubits initialized to zero
(bool, default False)
* `options`:
Use a custom qiskit Options instance. This enables application of
error-mitigation and remote transpilation of circuits on
IBMQ Cloud. Values for `resilience_level` can be found
here: https://docs.quantum.ibm.com/run/configure-error-mitigation.
Values for `optimization_level` can be found here:
https://docs.quantum.ibm.com/run/configure-runtime-compilation
"""
circuits = list(circuits)

Expand All @@ -519,6 +540,10 @@ def process_circuits(
postprocess = kwargs.get("postprocess", False)
simplify_initial = kwargs.get("simplify_initial", False)

options: Options = kwargs.get("options")
if options is None:
options = self._sampler_options

batch_id = 0 # identify batches for debug purposes only
for (n_shots, batch), indices in zip(circuit_batches, batch_order):
for chunk in itertools.zip_longest(
Expand Down Expand Up @@ -552,10 +577,6 @@ def process_circuits(
ppcirc_strs[i],
)
else:
options = Options()
options.optimization_level = 0
options.resilience_level = 0
options.transpilation.skip_transpilation = True
options.execution.shots = n_shots
sampler = Sampler(session=self._session, options=options)
job = sampler.run(
Expand Down