From 66aaefcd80800dc7ff588ba2d67451d0f3dd937b Mon Sep 17 00:00:00 2001 From: ptristan Date: Wed, 26 Jun 2024 17:14:14 -0300 Subject: [PATCH 1/6] improvements from https://github.com/Qiskit/qiskit-ibm-runtime/pull/1740 --- .../fake_provider/fake_backend.py | 59 ++++++++++--------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/qiskit_ibm_runtime/fake_provider/fake_backend.py b/qiskit_ibm_runtime/fake_provider/fake_backend.py index 69ea4c5e8..903d519dd 100644 --- a/qiskit_ibm_runtime/fake_provider/fake_backend.py +++ b/qiskit_ibm_runtime/fake_provider/fake_backend.py @@ -481,7 +481,6 @@ def refresh(self, service: QiskitRuntimeService) -> None: Exception: If the real target doesn't exist or can't be accessed """ - version = self.backend_version prod_name = self.backend_name.replace("fake", "ibm") try: backends = service.backends(prod_name) @@ -491,35 +490,39 @@ def refresh(self, service: QiskitRuntimeService) -> None: real_config = real_backend.configuration() real_defs = real_backend.defaults() - if real_props: - new_version = real_props.backend_version - - if new_version > version: - props_path = os.path.join(self.dirname, self.props_filename) - with open(props_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(real_props.to_dict(), cls=BackendEncoder)) - - if real_config: - config_path = os.path.join(self.dirname, self.conf_filename) - config_dict = real_config.to_dict() - with open(config_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(config_dict, cls=BackendEncoder)) - - if real_defs: - defs_path = os.path.join(self.dirname, self.defs_filename) - with open(defs_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(real_defs.to_dict(), cls=BackendEncoder)) - - logger.info( - "The backend %s has been updated from {version} to %s version.", - self.backend_name, - real_props.backend_version, - ) - else: - logger.info("There are no available new updates for %s.", self.backend_name) + if real_config: + config_path = os.path.join(self.dirname, self.conf_filename) + with open(config_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_config.to_dict(), cls=BackendEncoder)) + if real_props: + props_path = os.path.join(self.dirname, self.props_filename) + with open(props_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_props.to_dict(), cls=BackendEncoder)) + + if real_defs: + defs_path = os.path.join(self.dirname, self.defs_filename) + with open(defs_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_defs.to_dict(), cls=BackendEncoder)) + + if self._target: + self._conf_dict = self._get_conf_dict_from_json() + self._props_dict = real_props.to_dict() + self._defs_dict = real_defs.to_dict() + + updated_configuration = BackendConfiguration.from_dict(self._conf_dict) + updated_properties = BackendProperties.from_dict(self._props_dict) # type: ignore + updated_defaults = PulseDefaults.from_dict(self._defs_dict) # type: ignore + + self._target = convert_to_target( + configuration=updated_configuration, + properties=updated_properties, + defaults=updated_defaults, + include_control_flow=True, + include_fractional_gates=True, + ) except Exception as ex: # pylint: disable=broad-except - logger.info("The refreshing of %s has failed: %s", self.backend_name, str(ex)) + logger.warning("The refreshing of %s has failed: %s", self.backend_name, str(ex)) class FakeBackend(BackendV1): From a6918098e470c22d95b428abd5bbcedf90bdc380 Mon Sep 17 00:00:00 2001 From: ptristan Date: Thu, 27 Jun 2024 11:10:00 -0300 Subject: [PATCH 2/6] updated tests --- test/integration/test_fake_backends.py | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/test/integration/test_fake_backends.py b/test/integration/test_fake_backends.py index e55f6183f..0b260fcf8 100644 --- a/test/integration/test_fake_backends.py +++ b/test/integration/test_fake_backends.py @@ -183,8 +183,27 @@ def setUpClass(cls): def test_refresh_method(self): """Test refresh method""" + # to verify the data files will be updated old_backend = FakeSherbrooke() - with self.assertLogs("qiskit_ibm_runtime", level="INFO"): + # change some configuration + old_backend.backend_version = 'fake_version' + with self.assertLogs("qiskit_ibm_runtime", level="INFO") as logs: old_backend.refresh(self.service) + self.assertIn("The backend fake_sherbrooke has been updated", logs.output[0]) + + # to verify the data files are currently updated that there is nothing to refresh + # create another instance of FakeSherbrooke updated above new_backend = FakeSherbrooke() - self.assertGreaterEqual(old_backend.backend_version, new_backend.backend_version) + with self.assertLogs("qiskit_ibm_runtime", level="INFO") as logs: + new_backend.refresh(self.service) + self.assertIn("There are no available new updates for fake_sherbrooke", logs.output[0]) + + # to verify the refresh can't be done + wrong_backend = FakeSherbrooke() + # set a non-existent backend name + wrong_backend.backend_name = 'wrong_fake_sherbrooke' + with self.assertLogs("qiskit_ibm_runtime", level="WARNING") as logs: + wrong_backend.refresh(self.service) + self.assertIn("The refreshing of wrong_fake_sherbrooke has failed", logs.output[0]) + + From 363158b983754d9295f49d693e60f2d6ab1af902 Mon Sep 17 00:00:00 2001 From: ptristan Date: Thu, 27 Jun 2024 14:03:50 -0300 Subject: [PATCH 3/6] updated refresh condition --- .../fake_provider/fake_backend.py | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/qiskit_ibm_runtime/fake_provider/fake_backend.py b/qiskit_ibm_runtime/fake_provider/fake_backend.py index 903d519dd..51f6d1e79 100644 --- a/qiskit_ibm_runtime/fake_provider/fake_backend.py +++ b/qiskit_ibm_runtime/fake_provider/fake_backend.py @@ -480,7 +480,7 @@ def refresh(self, service: QiskitRuntimeService) -> None: Raises: Exception: If the real target doesn't exist or can't be accessed """ - + old_version = self.backend_version prod_name = self.backend_name.replace("fake", "ibm") try: backends = service.backends(prod_name) @@ -490,37 +490,51 @@ def refresh(self, service: QiskitRuntimeService) -> None: real_config = real_backend.configuration() real_defs = real_backend.defaults() - if real_config: - config_path = os.path.join(self.dirname, self.conf_filename) - with open(config_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(real_config.to_dict(), cls=BackendEncoder)) - - if real_props: - props_path = os.path.join(self.dirname, self.props_filename) - with open(props_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(real_props.to_dict(), cls=BackendEncoder)) - - if real_defs: - defs_path = os.path.join(self.dirname, self.defs_filename) - with open(defs_path, "w", encoding="utf-8") as fd: - fd.write(json.dumps(real_defs.to_dict(), cls=BackendEncoder)) - - if self._target: - self._conf_dict = self._get_conf_dict_from_json() - self._props_dict = real_props.to_dict() - self._defs_dict = real_defs.to_dict() - - updated_configuration = BackendConfiguration.from_dict(self._conf_dict) - updated_properties = BackendProperties.from_dict(self._props_dict) # type: ignore - updated_defaults = PulseDefaults.from_dict(self._defs_dict) # type: ignore - - self._target = convert_to_target( - configuration=updated_configuration, - properties=updated_properties, - defaults=updated_defaults, - include_control_flow=True, - include_fractional_gates=True, + updated_config = real_config.to_dict() + updated_config['backend_name'] = self.backend_name + + if updated_config != self._conf_dict: + + if real_config: + config_path = os.path.join(self.dirname, self.conf_filename) + with open(config_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_config.to_dict(), cls=BackendEncoder)) + + if real_props: + props_path = os.path.join(self.dirname, self.props_filename) + with open(props_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_props.to_dict(), cls=BackendEncoder)) + + if real_defs: + defs_path = os.path.join(self.dirname, self.defs_filename) + with open(defs_path, "w", encoding="utf-8") as fd: + fd.write(json.dumps(real_defs.to_dict(), cls=BackendEncoder)) + + if self._target is not None: + self._conf_dict = self._get_conf_dict_from_json() + self._set_props_dict_from_json() + self._set_defs_dict_from_json() + + updated_configuration = BackendConfiguration.from_dict(self._conf_dict) + updated_properties = BackendProperties.from_dict(self._props_dict) # type: ignore + updated_defaults = PulseDefaults.from_dict(self._defs_dict) # type: ignore + + self._target = convert_to_target( + configuration=updated_configuration, + properties=updated_properties, + defaults=updated_defaults, + include_control_flow=True, + include_fractional_gates=True, + ) + + logger.info( + "The backend %s has been updated from version %s to %s version.", + self.backend_name, + old_version, + real_props.backend_version, ) + else: + logger.info("There are no available new updates for %s.", self.backend_name) except Exception as ex: # pylint: disable=broad-except logger.warning("The refreshing of %s has failed: %s", self.backend_name, str(ex)) From 7ee64889a68f0746ccb279b539046f2e05aadefb Mon Sep 17 00:00:00 2001 From: ptristan Date: Thu, 27 Jun 2024 14:13:29 -0300 Subject: [PATCH 4/6] style fixes --- qiskit_ibm_runtime/fake_provider/fake_backend.py | 2 +- test/integration/test_fake_backends.py | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/qiskit_ibm_runtime/fake_provider/fake_backend.py b/qiskit_ibm_runtime/fake_provider/fake_backend.py index 51f6d1e79..64d099480 100644 --- a/qiskit_ibm_runtime/fake_provider/fake_backend.py +++ b/qiskit_ibm_runtime/fake_provider/fake_backend.py @@ -491,7 +491,7 @@ def refresh(self, service: QiskitRuntimeService) -> None: real_defs = real_backend.defaults() updated_config = real_config.to_dict() - updated_config['backend_name'] = self.backend_name + updated_config["backend_name"] = self.backend_name if updated_config != self._conf_dict: diff --git a/test/integration/test_fake_backends.py b/test/integration/test_fake_backends.py index 0b260fcf8..f8d28b1ea 100644 --- a/test/integration/test_fake_backends.py +++ b/test/integration/test_fake_backends.py @@ -186,7 +186,7 @@ def test_refresh_method(self): # to verify the data files will be updated old_backend = FakeSherbrooke() # change some configuration - old_backend.backend_version = 'fake_version' + old_backend.backend_version = "fake_version" with self.assertLogs("qiskit_ibm_runtime", level="INFO") as logs: old_backend.refresh(self.service) self.assertIn("The backend fake_sherbrooke has been updated", logs.output[0]) @@ -201,9 +201,7 @@ def test_refresh_method(self): # to verify the refresh can't be done wrong_backend = FakeSherbrooke() # set a non-existent backend name - wrong_backend.backend_name = 'wrong_fake_sherbrooke' + wrong_backend.backend_name = "wrong_fake_sherbrooke" with self.assertLogs("qiskit_ibm_runtime", level="WARNING") as logs: wrong_backend.refresh(self.service) self.assertIn("The refreshing of wrong_fake_sherbrooke has failed", logs.output[0]) - - From 9876537543cf422ffb646372d4a84921c9a36ae6 Mon Sep 17 00:00:00 2001 From: ptristan Date: Thu, 27 Jun 2024 14:36:21 -0300 Subject: [PATCH 5/6] mypy warning --- qiskit_ibm_runtime/fake_provider/fake_backend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qiskit_ibm_runtime/fake_provider/fake_backend.py b/qiskit_ibm_runtime/fake_provider/fake_backend.py index 64d099480..ae89c3095 100644 --- a/qiskit_ibm_runtime/fake_provider/fake_backend.py +++ b/qiskit_ibm_runtime/fake_provider/fake_backend.py @@ -511,13 +511,13 @@ def refresh(self, service: QiskitRuntimeService) -> None: fd.write(json.dumps(real_defs.to_dict(), cls=BackendEncoder)) if self._target is not None: - self._conf_dict = self._get_conf_dict_from_json() + self._conf_dict = self._get_conf_dict_from_json() # type: ignore[unreachable] self._set_props_dict_from_json() self._set_defs_dict_from_json() updated_configuration = BackendConfiguration.from_dict(self._conf_dict) - updated_properties = BackendProperties.from_dict(self._props_dict) # type: ignore - updated_defaults = PulseDefaults.from_dict(self._defs_dict) # type: ignore + updated_properties = BackendProperties.from_dict(self._props_dict) + updated_defaults = PulseDefaults.from_dict(self._defs_dict) self._target = convert_to_target( configuration=updated_configuration, From 20b9b578dc4777d90102e3b4105d158ac8be8e41 Mon Sep 17 00:00:00 2001 From: ptristan Date: Fri, 28 Jun 2024 12:26:34 -0300 Subject: [PATCH 6/6] update name --- qiskit_ibm_runtime/fake_provider/fake_backend.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qiskit_ibm_runtime/fake_provider/fake_backend.py b/qiskit_ibm_runtime/fake_provider/fake_backend.py index 9e3ea6e5a..f0976504e 100644 --- a/qiskit_ibm_runtime/fake_provider/fake_backend.py +++ b/qiskit_ibm_runtime/fake_provider/fake_backend.py @@ -484,7 +484,7 @@ def refresh(self, service: QiskitRuntimeService) -> None: Raises: Exception: If the real target doesn't exist or can't be accessed """ - old_version = self.backend_version + version = self.backend_version prod_name = self.backend_name.replace("fake", "ibm") try: backends = service.backends(prod_name) @@ -534,7 +534,7 @@ def refresh(self, service: QiskitRuntimeService) -> None: logger.info( "The backend %s has been updated from version %s to %s version.", self.backend_name, - old_version, + version, real_props.backend_version, ) else: