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

Raise exception when number of circuits exceeds maximum circuits allowed on backendkend max_circuits #939

Merged
merged 7 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
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
15 changes: 13 additions & 2 deletions qiskit_ibm_runtime/base_primitive.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from qiskit.providers.options import Options as TerraOptions

from qiskit_ibm_runtime.exceptions import IBMInputValueError
from .options import Options
from .options.utils import set_default_error_levels
from .runtime_job import RuntimeJob
Expand Down Expand Up @@ -136,7 +137,6 @@ def __init__(
raise ValueError(
"A backend or session must be specified when not using ibm_cloud channel."
)

# self._first_run = True
# self._circuits_map = {}
# if self.circuits:
Expand Down Expand Up @@ -174,8 +174,19 @@ def _run_primitive(self, primitive_inputs: Dict, user_kwargs: Dict) -> RuntimeJo
self._validate_options(combined)
primitive_inputs.update(Options._get_program_inputs(combined))

circuits = primitive_inputs["circuits"]
if (
self._backend
and isinstance(self._backend, IBMBackend)
and len(circuits) > self._backend.max_circuits
):
raise IBMInputValueError(
f"Number of circuits, {len(circuits)} exceeds the "
f"maximum for this backend, {self._backend.max_circuits})"
)

if self._backend and combined["transpilation"]["skip_transpilation"]:
for circ in primitive_inputs["circuits"]:
for circ in circuits:
self._backend.check_faulty(circ)

logger.info("Submitting job using options %s", combined)
Expand Down
6 changes: 6 additions & 0 deletions releasenotes/notes/max_circuits-b773c860f8df1cf4.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
features:
- |
Raise an exception if the number of circuits passed to BasePrimitive._run_primitive()
exceeds the number of circuits supported on the backend.

44 changes: 39 additions & 5 deletions test/unit/test_ibm_primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
from qiskit_ibm_runtime.ibm_backend import IBMBackend
import qiskit_ibm_runtime.session as session_pkg
from qiskit_ibm_runtime.utils.utils import _hash
from qiskit_ibm_runtime.exceptions import IBMInputValueError

from ..ibm_test_case import IBMTestCase
from ..utils import (
Expand Down Expand Up @@ -190,7 +191,10 @@ def test_init_with_backend_instance(self):
"""Test initializing a primitive with a backend instance."""
primitives = [Sampler, Estimator]
service = MagicMock()
backend = IBMBackend(configuration=MagicMock(), service=service, api_client=MagicMock())
model_backend = FakeManila()
backend = IBMBackend(
configuration=model_backend.configuration(), service=service, api_client=MagicMock()
)
backend.name = "ibm_gotham"

for cls in primitives:
Expand Down Expand Up @@ -266,12 +270,14 @@ def test_default_session_cm_new_backend(self):
"""Test using a different backend within context manager."""
cm_backend = "ibm_metropolis"
primitives = [Sampler, Estimator]

model_backend = FakeManila()
for cls in primitives:
with self.subTest(primitive=cls):
service = MagicMock()
backend = IBMBackend(
configuration=MagicMock(), service=service, api_client=MagicMock()
configuration=model_backend.configuration(),
service=service,
api_client=MagicMock(),
)
backend.name = "ibm_gotham"

Expand All @@ -286,12 +292,14 @@ def test_default_session_cm_new_backend(self):
def test_no_session(self):
"""Test running without session."""
primitives = [Sampler, Estimator]

model_backend = FakeManila()
for cls in primitives:
with self.subTest(primitive=cls):
service = MagicMock()
backend = IBMBackend(
configuration=MagicMock(), service=service, api_client=MagicMock()
configuration=model_backend.configuration(),
service=service,
api_client=MagicMock(),
)
inst = cls(backend)
inst.run(self.qx, observables=self.obs)
Expand Down Expand Up @@ -945,3 +953,29 @@ def _assert_dict_partially_equal(self, dict1, dict2):
dict_paritally_equal(dict1, dict2),
f"{dict1} and {dict2} not partially equal.",
)

def test_too_many_circuits(self):
"""Test exception when number of circuits exceeds backend._max_circuits"""
model_backend = FakeManila()
backend = IBMBackend(
configuration=model_backend.configuration(),
service=MagicMock(),
api_client=None,
instance=None,
)
primitives = [Sampler, Estimator]
max_circs = backend.configuration().max_experiments
circs = []
observables = []
for _ in range(max_circs + 1):
circs.append(self.qx)
observables.append(self.obs)
for cls in primitives:
with self.subTest(primitive=cls):
inst = cls(backend=backend)
with self.assertRaises(IBMInputValueError) as err:
inst.run(circs, observables=observables)
self.assertIn(
f"Number of circuits, {max_circs + 1} exceeds the maximum for this backend, {max_circs}",
str(err.exception),
)