Source code for quantify_scheduler.backends.qblox_backend

# Repository: https://gitlab.com/quantify-os/quantify-scheduler
# Licensed according to the LICENCE file on the main branch
"""Compiler backend for Qblox hardware."""
from __future__ import annotations

import warnings
from typing import Any, Dict

from quantify_scheduler import CompiledSchedule, Schedule
from quantify_scheduler.backends.corrections import apply_distortion_corrections
from quantify_scheduler.backends.qblox import compiler_container, helpers


[docs]def hardware_compile( schedule: Schedule, hardware_cfg: Dict[str, Any] ) -> CompiledSchedule: """ Main function driving the compilation. The principle behind the overall compilation works as follows: For every instrument in the hardware configuration, we instantiate a compiler object. Then we assign all the pulses/acquisitions that need to be played by that instrument to the compiler, which then compiles for each instrument individually. This function then returns all the compiled programs bundled together in a dictionary with the QCoDeS name of the instrument as key. Parameters ---------- schedule The schedule to compile. It is assumed the pulse and acquisition info is already added to the operation. Otherwise an exception is raised. hardware_cfg The hardware configuration of the setup. Returns ------- : The compiled schedule. """ converted_hw_config = helpers.convert_hw_config_to_portclock_configs_spec( hardware_cfg ) # Directly comparing dictionaries that contain numpy arrays raises a # ValueError. It is however sufficient to compare all the keys of nested # dictionaries. def _get_flattened_keys_from_dictionary( dictionary, parent_key: str = "", sep: str = "." ): flattened_keys = set() for key, value in dictionary.items(): new_key = parent_key + sep + key if parent_key else key if isinstance(value, dict): flattened_keys = flattened_keys.union( _get_flattened_keys_from_dictionary(value, new_key, sep=sep) ) else: flattened_keys = flattened_keys.union({new_key}) return flattened_keys hw_config_keys = _get_flattened_keys_from_dictionary(hardware_cfg) converted_hw_config_keys = _get_flattened_keys_from_dictionary(converted_hw_config) if hw_config_keys != converted_hw_config_keys: warnings.warn( "The provided hardware config adheres to a specification " "that is now deprecated. Please learn about the new " "Qblox hardware config specification at:\n" "https://gitlab.com/quantify-os/quantify-scheduler/-/wikis/" "Qblox-backend:-Dynamic-Sequencer-Allocation \n" "You may upgrade an old config to the new specification using the " "'quantify_scheduler.backends.qblox.helpers." "convert_hw_config_to_portclock_configs_spec' function.", DeprecationWarning, ) hardware_cfg = converted_hw_config schedule = apply_distortion_corrections(schedule, hardware_cfg) container = compiler_container.CompilerContainer.from_hardware_cfg( schedule, hardware_cfg ) helpers.assign_pulse_and_acq_info_to_devices( schedule=schedule, hardware_cfg=hardware_cfg, device_compilers=container.instrument_compilers, ) container.prepare() compiled_instructions = container.compile(repetitions=schedule.repetitions) # add the compiled instructions to the schedule data structure schedule["compiled_instructions"] = compiled_instructions # Mark the schedule as a compiled schedule return CompiledSchedule(schedule)