Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ def interim_result_callback(job_id, interim_result):
from .program.user_messenger import UserMessenger
from .program.program_backend import ProgramBackend
from .program.result_decoder import ResultDecoder
from .utils.runtime import RuntimeEncoder, RuntimeDecoder
from .utils.json import RuntimeEncoder, RuntimeDecoder

# Setup the logger for the IBM Quantum Provider package.
logger = logging.getLogger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/hub_group_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
ibm_backend,
)

from .utils.json_decoder import decode_backend_configuration
from .utils.backend import decode_backend_configuration
from .api.clients import AccountClient
from .credentials import Credentials
from .exceptions import IBMInputValueError
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/ibm_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
from .credentials import Credentials
from .exceptions import IBMBackendApiProtocolError
from .utils.converters import utc_to_local_all, local_to_utc
from .utils.json_decoder import decode_pulse_defaults, decode_backend_properties
from .utils.backend import decode_pulse_defaults, decode_backend_properties
from .utils.backend import convert_reservation_data

logger = logging.getLogger(__name__)
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/program/result_decoder.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import json
from typing import Any

from qiskit_ibm_runtime.utils.runtime import RuntimeDecoder
from qiskit_ibm_runtime.utils import RuntimeDecoder


class ResultDecoder:
Expand Down
2 changes: 1 addition & 1 deletion qiskit_ibm_runtime/program/user_messenger.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import json
from typing import Any, Type

from ..utils.runtime import RuntimeEncoder
from ..utils.json import RuntimeEncoder


class UserMessenger:
Expand Down
4 changes: 2 additions & 2 deletions qiskit_ibm_runtime/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

.. currentmodule:: qiskit_ibm_runtime.utils

Utility functions related to the IBM Quantum Provider.
Utility functions related to the IBM Runtime Services.

Conversion
==========
Expand All @@ -42,4 +42,4 @@
duration_difference,
)
from .utils import to_python_identifier
from .runtime import *
from .json import RuntimeEncoder, RuntimeDecoder, to_base64_string
98 changes: 97 additions & 1 deletion qiskit_ibm_runtime/utils/backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@

"""Utilities for working with IBM Quantum backends."""

from typing import List, Optional
from typing import List, Optional, Dict, Union

import dateutil.parser

from ..backendreservation import BackendReservation
from ..utils.converters import utc_to_local
Expand Down Expand Up @@ -49,3 +51,97 @@ def convert_reservation_data(
)
)
return reservations


def decode_pulse_defaults(defaults: Dict) -> None:
"""Decode pulse defaults data.

Args:
defaults: A ``PulseDefaults`` in dictionary format.
"""
for item in defaults["pulse_library"]:
_decode_pulse_library_item(item)

for cmd in defaults["cmd_def"]:
if "sequence" in cmd:
for instr in cmd["sequence"]:
_decode_pulse_qobj_instr(instr)


def decode_backend_properties(properties: Dict) -> None:
"""Decode backend properties.

Args:
properties: A ``BackendProperties`` in dictionary format.
"""
properties["last_update_date"] = dateutil.parser.isoparse(
properties["last_update_date"]
)
for qubit in properties["qubits"]:
for nduv in qubit:
nduv["date"] = dateutil.parser.isoparse(nduv["date"])
for gate in properties["gates"]:
for param in gate["parameters"]:
param["date"] = dateutil.parser.isoparse(param["date"])
for gen in properties["general"]:
gen["date"] = dateutil.parser.isoparse(gen["date"])


def decode_backend_configuration(config: Dict) -> None:
"""Decode backend configuration.

Args:
config: A ``QasmBackendConfiguration`` or ``PulseBackendConfiguration``
in dictionary format.
"""
config["online_date"] = dateutil.parser.isoparse(config["online_date"])

if "u_channel_lo" in config:
for u_channle_list in config["u_channel_lo"]:
for u_channle_lo in u_channle_list:
u_channle_lo["scale"] = _to_complex(u_channle_lo["scale"])


def _to_complex(value: Union[List[float], complex]) -> complex:
"""Convert the input value to type ``complex``.

Args:
value: Value to be converted.

Returns:
Input value in ``complex``.

Raises:
TypeError: If the input value is not in the expected format.
"""
if isinstance(value, list) and len(value) == 2:
return complex(value[0], value[1])
elif isinstance(value, complex):
return value

raise TypeError("{} is not in a valid complex number format.".format(value))


def _decode_pulse_library_item(pulse_library_item: Dict) -> None:
"""Decode a pulse library item.

Args:
pulse_library_item: A ``PulseLibraryItem`` in dictionary format.
"""
pulse_library_item["samples"] = [
_to_complex(sample) for sample in pulse_library_item["samples"]
]


def _decode_pulse_qobj_instr(pulse_qobj_instr: Dict) -> None:
"""Decode a pulse Qobj instruction.

Args:
pulse_qobj_instr: A ``PulseQobjInstruction`` in dictionary format.
"""
if "val" in pulse_qobj_instr:
pulse_qobj_instr["val"] = _to_complex(pulse_qobj_instr["val"])
if "parameters" in pulse_qobj_instr and "amp" in pulse_qobj_instr["parameters"]:
pulse_qobj_instr["parameters"]["amp"] = _to_complex(
pulse_qobj_instr["parameters"]["amp"]
)
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ def _decode_and_deserialize(
return deserializer(buff)


def deserialize_from_settings(mod_name: str, class_name: str, settings: Dict) -> Any:
def _deserialize_from_settings(mod_name: str, class_name: str, settings: Dict) -> Any:
"""Deserialize an object from its settings.

Args:
Expand Down Expand Up @@ -259,7 +259,7 @@ def object_hook(self, obj: Any) -> Any:
obj_val, qpy_serialization._read_instruction, False
)
if obj_type == "settings":
return deserialize_from_settings(
return _deserialize_from_settings(
mod_name=obj["__module__"],
class_name=obj["__class__"],
settings=_cast_strings_keys_to_int(obj_val),
Expand Down
111 changes: 0 additions & 111 deletions qiskit_ibm_runtime/utils/json_decoder.py

This file was deleted.

39 changes: 0 additions & 39 deletions qiskit_ibm_runtime/utils/json_encoder.py

This file was deleted.

17 changes: 1 addition & 16 deletions test/ibm/test_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,11 @@
# copyright notice, and modified files need to carry a notice indicating
# that they have been altered from the originals.

"""Test serializing and deserializing data sent to the server."""
"""Test deserializing server data."""

from unittest import skipIf
from typing import Any, Dict, Optional

import dateutil.parser
from qiskit.circuit import Parameter
from qiskit.version import VERSION as terra_version

from qiskit_ibm_runtime.utils.json_encoder import IBMJsonEncoder

from ..decorators import requires_provider
from ..ibm_test_case import IBMTestCase
Expand Down Expand Up @@ -135,16 +130,6 @@ def _verify_data(
}
self.assertFalse(suspect_keys)

@skipIf(terra_version < "0.17", "Need Terra >= 0.17")
def test_convert_complex(self):
"""Verify that real and complex ParameterExpressions are supported."""
param = Parameter("test")
self.assertEqual(IBMJsonEncoder().default(param.bind({param: 0.2})), 0.2)

val = IBMJsonEncoder().default(param.bind({param: 0.2 + 0.1j}))
self.assertEqual(val[0], 0.2)
self.assertEqual(val[1], 0.1)


def _find_potential_encoded(data: Any, c_key: str, tally: set) -> None:
"""Find data that may be in JSON serialized format.
Expand Down