From 9f2dad538e9165d43bf9a6796eafeb85e963bb20 Mon Sep 17 00:00:00 2001 From: Kevin Tian Date: Fri, 1 Nov 2024 22:30:27 -0400 Subject: [PATCH] Don't cache in target_history() (#1957) * 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 <44805021+ptristan3@users.noreply.github.com> --- qiskit_ibm_runtime/ibm_backend.py | 48 ++++++++++++++----------------- test/integration/test_backend.py | 8 ++++++ 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/qiskit_ibm_runtime/ibm_backend.py b/qiskit_ibm_runtime/ibm_backend.py index c3443153b..3215312df 100644 --- a/qiskit_ibm_runtime/ibm_backend.py +++ b/qiskit_ibm_runtime/ibm_backend.py @@ -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 @@ -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 ( @@ -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 @@ -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 @@ -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.""" @@ -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) diff --git a/test/integration/test_backend.py b/test/integration/test_backend.py index 03f428e57..bcd9c83a6 100644 --- a/test/integration/test_backend.py +++ b/test/integration/test_backend.py @@ -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