Skip to content

Commit

Permalink
Don't cache in target_history() (#1957)
Browse files Browse the repository at this point in the history
* Don't cache in target_history()

* Add test

* Remove comment

* formatting

* Update properties()

* Refactor if/else logic

* Fix param logic

* Add comments back

---------

Co-authored-by: ptristan3 <[email protected]>
  • Loading branch information
kt474 and ptristan3 authored Nov 2, 2024
1 parent a287ecb commit 9f2dad5
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 27 deletions.
48 changes: 21 additions & 27 deletions qiskit_ibm_runtime/ibm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def __getattr__(self, name: str) -> Any:
"'{}' object has no attribute '{}'".format(self.__class__.__name__, name)
)
# Lazy load properties and pulse defaults and construct the target object.
self._get_properties()
self.properties()
self._get_defaults()
self._convert_to_target()
# Check if the attribute now is available on IBMBackend class due to above steps
Expand All @@ -239,16 +239,6 @@ def __getattr__(self, name: str) -> Any:
"'{}' object has no attribute '{}'".format(self.__class__.__name__, name)
)

def _get_properties(self, datetime: Optional[python_datetime] = None) -> None:
"""Gets backend properties and decodes it"""
if datetime:
datetime = local_to_utc(datetime)
if datetime or not self._properties:
api_properties = self._api_client.backend_properties(self.name, datetime=datetime)
if api_properties:
backend_properties = properties_from_server_data(api_properties)
self._properties = backend_properties

def _get_defaults(self, refresh: bool = False) -> None:
"""Gets defaults if pulse backend and decodes it"""
if (
Expand All @@ -261,21 +251,16 @@ def _get_defaults(self, refresh: bool = False) -> None:
def _convert_to_target(self, refresh: bool = False) -> None:
"""Converts backend configuration, properties and defaults to Target object"""
if refresh or not self._target:
if self.options.use_fractional_gates is None:
include_control_flow = True
include_fractional_gates = True
else:
# In IBM backend architecture as of today
# these features can be only exclusively supported.
include_control_flow = not self.options.use_fractional_gates
include_fractional_gates = self.options.use_fractional_gates

self._target = convert_to_target(
configuration=self._configuration, # type: ignore[arg-type]
properties=self._properties,
defaults=self._defaults,
include_control_flow=include_control_flow,
include_fractional_gates=include_fractional_gates,
# In IBM backend architecture as of today
# these features can be only exclusively supported.
include_control_flow=self.options.use_fractional_gates is None
or not self.options.use_fractional_gates,
include_fractional_gates=self.options.use_fractional_gates is None
or self.options.use_fractional_gates,
)

@classmethod
Expand Down Expand Up @@ -344,7 +329,7 @@ def target(self) -> Target:
Returns:
Target
"""
self._get_properties()
self.properties()
self._get_defaults()
self._convert_to_target()
return self._target
Expand All @@ -355,10 +340,19 @@ def target_history(self, datetime: Optional[python_datetime] = None) -> Target:
Returns:
Target with properties found on `datetime`
"""
self._get_properties(datetime=datetime)
self._get_defaults()
self._convert_to_target(refresh=True)
return self._target

return convert_to_target(
configuration=self._configuration, # type: ignore[arg-type]
properties=self.properties(datetime=datetime), # pylint: disable=unexpected-keyword-arg
defaults=self._defaults,
# In IBM backend architecture as of today
# these features can be only exclusively supported.
include_control_flow=self.options.use_fractional_gates is None
or not self.options.use_fractional_gates,
include_fractional_gates=self.options.use_fractional_gates
or self.options.use_fractional_gates,
)

def refresh(self) -> None:
"""Retrieve the newest backend configuration and refresh the current backend target."""
Expand All @@ -367,7 +361,7 @@ def refresh(self) -> None:
instance=self._instance,
):
self._configuration = config
self._get_properties(datetime=python_datetime.now())
self.properties(refresh=True) # pylint: disable=unexpected-keyword-arg
self._get_defaults(refresh=True)
self._convert_to_target(refresh=True)

Expand Down
8 changes: 8 additions & 0 deletions test/integration/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ def test_backend_target_history(self):
self.assertIsNotNone(backend.target_history(datetime=datetime.now() - timedelta(30)))

@production_only
def test_properties_not_cached_target_history(self):
"""Check backend properties is not cached in target_history()."""
backend = self.backend
with self.subTest(backend=backend.name):
properties = backend.properties()
backend.target_history(datetime=datetime.now() - timedelta(60))
self.assertEqual(properties, backend.properties())

def test_backend_target_refresh(self):
"""Test refreshing the backend target."""
backend = self.backend
Expand Down

0 comments on commit 9f2dad5

Please sign in to comment.