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

Fake backend refresh method improvements #1777

Merged
merged 12 commits into from
Jul 10, 2024
61 changes: 39 additions & 22 deletions qiskit_ibm_runtime/fake_provider/fake_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,6 @@ def refresh(self, service: QiskitRuntimeService) -> None:
Raises:
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:
Expand All @@ -588,35 +587,53 @@ 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
updated_config = real_config.to_dict()
updated_config["backend_name"] = self.backend_name

if updated_config != self._conf_dict:

if new_version > version:
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_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,
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() # 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)
updated_defaults = PulseDefaults.from_dict(self._defs_dict)

self._target = convert_to_target(
configuration=updated_configuration,
properties=updated_properties,
defaults=updated_defaults,
include_control_flow=True,
include_fractional_gates=True,
)
else:
logger.info("There are no available new updates for %s.", self.backend_name)

logger.info(
"The backend %s has been updated from version %s to %s version.",
self.backend_name,
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.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):
Expand Down
21 changes: 19 additions & 2 deletions test/integration/test_fake_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,25 @@ 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])
kt474 marked this conversation as resolved.
Show resolved Hide resolved