Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

Commit

Permalink
Use POST /sessions endpoint (#817)
Browse files Browse the repository at this point in the history
* Use POST /sessions

* Update open_session, get params right

* unit tests

* Fix scheduler unit test
  • Loading branch information
kt474 authored Feb 20, 2024
1 parent 2d3cfe1 commit d945d5e
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 33 deletions.
19 changes: 19 additions & 0 deletions qiskit_ibm_provider/api/clients/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,25 @@ def update_tags(self, job_id: str, tags: list) -> Response:
"""
return self._api.program_job(job_id).update_tags(tags)

def create_session(
self,
backend: Optional[str] = None,
instance: Optional[str] = None,
max_time: Optional[int] = None,
mode: Optional[str] = None,
) -> Dict[str, Any]:
"""Create a new runtime session.
Args:
backend: The name of the backend to use.
instance: The instance to use.
mode: The mode to use.
Returns:
The created session.
"""
return self._api.runtime_session().create(backend, instance, max_time, mode)

def close_session(self, session_id: str) -> None:
"""Close session
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_provider/api/rest/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def program_job(self, job_id: str) -> "ProgramJob":
"""
return ProgramJob(self.session, job_id)

def runtime_session(self, session_id: str) -> "RuntimeSession":
def runtime_session(self, session_id: str = None) -> "RuntimeSession":
"""Return an adapter for the session.
Args:
Expand Down
27 changes: 25 additions & 2 deletions qiskit_ibm_provider/api/rest/runtime_session.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

"""Runtime Session REST adapter."""


from typing import Dict, Any, Optional
from qiskit_ibm_provider.api.rest.base import RestAdapterBase
from qiskit_ibm_provider.exceptions import IBMApiError
from ..exceptions import RequestsApiError
Expand All @@ -37,7 +37,30 @@ def __init__(
session_id: Job ID of the first job in a runtime session.
url_prefix: Prefix to use in the URL.
"""
super().__init__(session, "{}/sessions/{}".format(url_prefix, session_id))
if not session_id:
super().__init__(session, "{}/sessions".format(url_prefix))
else:
super().__init__(session, "{}/sessions/{}".format(url_prefix, session_id))

def create(
self,
backend: Optional[str] = None,
instance: Optional[str] = None,
max_time: Optional[int] = None,
mode: Optional[str] = None,
) -> Dict[str, Any]:
"""Create a session"""
url = self.get_url("self")
payload = {}
if mode:
payload["mode"] = mode
if backend:
payload["backend"] = backend
if instance:
payload["instance"] = instance
if max_time:
payload["max_session_ttl"] = max_time # type: ignore[assignment]
return self.session.post(url, json=payload).json()

def close(self) -> None:
"""Set accepting_jobs flag to false, so no more jobs can be submitted."""
Expand Down
31 changes: 13 additions & 18 deletions qiskit_ibm_provider/ibm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,18 +511,11 @@ def _runtime_run(
"""Runs the runtime program and returns the corresponding job object"""
hgp_name = self._instance or self.provider._get_hgp().name

session = self._session

if session:
if not session.active:
raise RuntimeError(f"The session {session.session_id} is closed.")
session_id = session.session_id
session_time = session._max_time
start_session = session_id is None
else:
session_id = None
session_time = None
start_session = False
session_id = None
if self._session:
if not self._session.active:
raise RuntimeError(f"The session {self._session.session_id} is closed.")
session_id = self._session.session_id

try:
response = self.provider._runtime_client.program_run(
Expand All @@ -532,15 +525,11 @@ def _runtime_run(
hgp=hgp_name,
job_tags=job_tags,
session_id=session_id,
start_session=start_session,
session_time=session_time,
start_session=False,
image=image,
)
except RequestsApiError as ex:
raise IBMBackendApiError("Error submitting job: {}".format(str(ex))) from ex
session_id = response.get("session_id")
if self._session:
self._session._session_id = session_id
try:
job = IBMCircuitJob(
backend=self,
Expand Down Expand Up @@ -873,7 +862,13 @@ def _check_faulty(self, circuit: QuantumCircuit) -> None:

def open_session(self, max_time: Optional[Union[int, str]] = None) -> Session:
"""Open session"""
self._session = Session(max_time)
if not self._configuration.simulator:
new_session = self.provider._runtime_client.create_session(
self.name, self._instance, max_time
)
self._session = Session(max_time=max_time, session_id=new_session.get("id"))
else:
self._session = Session()
return self._session

@property
Expand Down
3 changes: 2 additions & 1 deletion qiskit_ibm_provider/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Session:
def __init__(
self,
max_time: Optional[Union[int, str]] = None,
session_id: Optional[str] = None,
):
"""Session constructor.
Expand All @@ -78,7 +79,7 @@ def __init__(
ValueError: If an input value is invalid.
"""
self._instance = None
self._session_id: Optional[str] = None
self._session_id = session_id
self._active = True

self._max_time = (
Expand Down
3 changes: 2 additions & 1 deletion test/unit/mock/fake_account_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class FakeApiBackend:
def __init__(self, config_update=None, status_update=None):
fake_backend = Fake5QV1()
self.properties = fake_backend.properties().to_dict()
self.defaults = fake_backend.defaults().to_dict()
if hasattr(fake_backend, "defaults"):
self.defaults = fake_backend.defaults().to_dict()

self.configuration = fake_backend.configuration().to_dict()
self.configuration["online_date"] = python_datetime.now().isoformat()
Expand Down
17 changes: 7 additions & 10 deletions test/unit/transpiler/passes/scheduling/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@
from qiskit.transpiler.passmanager import PassManager
from qiskit.transpiler.exceptions import TranspilerError

try:
from qiskit.providers.fake_provider import Fake7QPulseV1
except ImportError:
from qiskit.providers.fake_provider import FakeJakarta as Fake7QPulseV1
from qiskit_ibm_runtime.fake_provider import FakeJakarta

from qiskit_ibm_provider.transpiler.passes.scheduling.pad_delay import PadDelay
from qiskit_ibm_provider.transpiler.passes.scheduling.scheduler import (
Expand Down Expand Up @@ -850,12 +847,12 @@ def test_c_if_plugin_conversion_with_transpile(self):
after transpilation with the plugin."""
# Patch the test backend with the plugin
with patch.object(
Fake7QPulseV1,
FakeJakarta,
"get_translation_stage_plugin",
return_value="ibm_dynamic_circuits",
create=True,
):
backend = Fake7QPulseV1()
backend = FakeJakarta()
# Temporary workaround for mock backends. For real backends this is not required.
backend.configuration().basis_gates.append("if_else")

Expand Down Expand Up @@ -1867,7 +1864,7 @@ def test_for_loop(self):

def test_transpile_mock_backend(self):
"""Test scheduling works with transpilation."""
backend = Fake7QPulseV1()
backend = FakeJakarta()
# Temporary workaround for mock backends. For real backends this is not required.
backend.configuration().basis_gates.append("if_else")
backend.configuration().basis_gates.append("while_loop")
Expand Down Expand Up @@ -1915,7 +1912,7 @@ def test_transpile_mock_backend(self):

def test_transpile_both_paths(self):
"""Test scheduling works with both fast- and standard path after transpiling."""
backend = Fake7QPulseV1()
backend = FakeJakarta()
# Temporary workaround for mock backends. For real backends this is not required.
backend.configuration().basis_gates.append("if_else")

Expand Down Expand Up @@ -1957,12 +1954,12 @@ def test_c_if_plugin_conversion_with_transpile(self):
transpilation with the plugin."""
# Patch the test backend with the plugin
with patch.object(
Fake7QPulseV1,
FakeJakarta,
"get_translation_stage_plugin",
return_value="ibm_dynamic_circuits",
create=True,
):
backend = Fake7QPulseV1()
backend = FakeJakarta()
# Temporary workaround for mock backends. For real backends this is not required.
backend.configuration().basis_gates.append("if_else")

Expand Down

0 comments on commit d945d5e

Please sign in to comment.