Source code for quantify_scheduler.device_under_test.device_element

# Repository: https://gitlab.com/quantify-os/quantify-scheduler
# Licensed according to the LICENCE file on the main branch
"""The module contains definitions for device elements."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import ruamel.yaml as ry
from qcodes.instrument.base import Instrument

from quantify_scheduler.helpers.importers import export_python_object_to_path_string
from quantify_scheduler.json_utils import JSONSerializable
from quantify_scheduler.yaml_utils import YAMLSerializable

if TYPE_CHECKING:
    from quantify_scheduler.backends.graph_compilation import DeviceCompilationConfig


[docs] class DeviceElement(YAMLSerializable, JSONSerializable, Instrument): """ Create a device element for managing parameters. The :class:`~DeviceElement` is responsible for compiling operations applied to that specific device element from the quantum-circuit to the quantum-device layer. """ def __init__(self, name: str, **kwargs) -> None: if "-" in name or "_" in name: raise ValueError( f"Invalid DeviceElement name '{name}'. Hyphens and " f"underscores are not allowed due to naming conventions" ) super().__init__(name, **kwargs) def __json_getstate__(self) -> dict[str, Any]: # type: ignore """ Serialize :class:`~DeviceElement` and derived classes. Serialization is performed by converting submodules into a dict containing the name of the device element and a dict for each submodule containing its parameter names and corresponding values. """ snapshot = self.snapshot() element_data: dict[str, Any] = {"name": self.name} for submodule_name, submodule_data in snapshot["submodules"].items(): element_data[submodule_name] = { name: data["value"] for name, data in submodule_data["parameters"].items() } state = { "deserialization_type": export_python_object_to_path_string(self.__class__), "mode": "__init__", "data": element_data, } return state def __getstate__(self) -> dict[str, Any]: # type: ignore[override] """Get the state of :class:`~DeviceElement` (used for YAML serialization).""" snapshot = self.snapshot() element_data: dict[str, Any] = {"name": self.name} for submodule_name, submodule_data in snapshot["submodules"].items(): element_data[submodule_name] = { name: data["value"] for name, data in submodule_data["parameters"].items() } return element_data @classmethod
[docs] def from_yaml(cls, constructor: ry.Constructor, node: ry.MappingNode) -> Instrument: """YAML loading logic.""" if isinstance(constructor, ry.RoundTripConstructor): data = ry.CommentedMap() constructor.construct_mapping(node, maptyp=data, deep=True) else: data = constructor.construct_mapping(node, deep=True) # The name attribute needs to be passed explicitly and separately to this `Instrument`. return cls(name=data.pop("name"), **data)
[docs] def generate_device_config(self) -> DeviceCompilationConfig: """Generate the device configuration.""" raise NotImplementedError