compiler_abc#

Compiler base and utility classes for Qblox backend.

Module Contents#

Classes#

InstrumentCompiler

Abstract base class that defines a generic instrument compiler.

ControlDeviceCompiler

Abstract class for devices requiring logic for acquisition and playback of pulses.

Sequencer

Class that performs the compilation steps on the sequencer level.

QbloxBaseModule

Qblox specific implementation of

QbloxBasebandModule

Abstract class with all the shared functionality between the QRM and QCM baseband

QbloxRFModule

Abstract class with all the shared functionality between the QRM-RF and QCM-RF

Attributes#

logger

logger[source]#
class InstrumentCompiler(parent, name: str, total_play_time: float, instrument_cfg: Dict[str, Any], latency_corrections: Dict[str, float] | None = None)[source]#

Bases: abc.ABC

Abstract base class that defines a generic instrument compiler.

The subclasses that inherit from this are meant to implement the compilation steps needed to compile the lists of quantify_scheduler.backends.types.qblox.OpInfo representing the pulse and acquisition information to device-specific instructions.

Each device that needs to be part of the compilation process requires an associated InstrumentCompiler.

Parameters:
  • parent (CompilerContainer) – Reference to the parent object.

  • name – Name of the QCoDeS instrument this compiler object corresponds to.

  • total_play_time – Total time execution of the schedule should go on for. This parameter is used to ensure that the different devices, potentially with different clock rates, can work in a synchronized way when performing multiple executions of the schedule.

  • instrument_cfg – The part of the hardware configuration dictionary referring to this device. This is one of the inner dictionaries of the overall hardware config.

  • latency_corrections – Dict containing the delays for each port-clock combination. This is specified in the top layer of hardware config.

prepare() None[source]#

Method that can be overridden to implement logic before the main compilation starts. This step is to extract all settings for the devices that are dependent on settings of other devices. This step happens after instantiation of the compiler object but before the start of the main compilation.

abstract compile(debug_mode: bool, repetitions: int) Any[source]#

An abstract method that should be overridden in a subclass to implement the actual compilation. It should turn the pulses and acquisitions added to the device into device-specific instructions.

Parameters:
  • debug_mode – Debug mode can modify the compilation process, so that debugging of the compilation process is easier.

  • repetitions – Number of times execution of the schedule is repeated.

Returns:

A data structure representing the compiled program. The type is dependent on implementation.

class ControlDeviceCompiler(parent, name: str, total_play_time: float, instrument_cfg: Dict[str, Any], latency_corrections: Dict[str, float] | None = None)[source]#

Bases: InstrumentCompiler

Abstract class for devices requiring logic for acquisition and playback of pulses.

Parameters:
  • parent (CompilerContainer) – Reference to the parent object.

  • name – Name of the QCoDeS instrument this compiler object corresponds to.

  • total_play_time – Total time execution of the schedule should go on for. This parameter is used to ensure that the different devices, potentially with different clock rates, can work in a synchronized way when performing multiple executions of the schedule.

  • instrument_cfg – The part of the hardware configuration dictionary referring to this device. This is one of the inner dictionaries of the overall hardware config.

  • latency_corrections – Dict containing the delays for each port-clock combination. This is specified in the top layer of hardware config.

abstract property supports_acquisition: bool[source]#

Specifies whether the device can perform acquisitions.

Returns:

The maximum amount of sequencers

property _portclocks_with_data: Set[Tuple[str, str]][source]#

All the port-clock combinations associated with at least one pulse and/or acquisition.

Returns:

A set containing all the port-clock combinations that are used by this InstrumentCompiler.

property _portclocks_with_pulses: Set[Tuple[str, str]][source]#

All the port-clock combinations associated with at least one pulse.

Returns:

A set containing all the port-clock combinations that are used by this InstrumentCompiler.

add_pulse(port: str, clock: str, pulse_info: quantify_scheduler.backends.types.qblox.OpInfo)[source]#

Assigns a certain pulse to this device.

Parameters:
  • port – The port the pulse needs to be sent to.

  • clock – The clock for modulation of the pulse. Can be a BasebandClock.

  • pulse_info – Data structure containing all the information regarding this specific pulse operation.

add_acquisition(port: str, clock: str, acq_info: quantify_scheduler.backends.types.qblox.OpInfo)[source]#

Assigns a certain acquisition to this device.

Parameters:
  • port – The port the pulse needs to be sent to.

  • clock – The clock for modulation of the pulse. Can be a BasebandClock.

  • acq_info – Data structure containing all the information regarding this specific acquisition operation.

abstract compile(debug_mode: bool, repetitions: int = 1) Dict[str, Any][source]#

An abstract method that should be overridden by a subclass to implement the actual compilation. Method turns the pulses and acquisitions added to the device into device-specific instructions.

Parameters:
  • debug_mode – Debug mode can modify the compilation process, so that debugging of the compilation process is easier.

  • repetitions – Number of times execution the schedule is repeated.

Returns:

A data structure representing the compiled program.

exception NcoOperationTimingError[source]#

Bases: ValueError

Exception thrown if there are timing errors for NCO operations.

class Sequencer(parent: QbloxBaseModule, index: int, portclock: Tuple[str, str], static_hw_properties: quantify_scheduler.backends.types.qblox.StaticHardwareProperties, channel_name: str, sequencer_cfg: Dict[str, Any], latency_corrections: Dict[str, float], lo_name: str | None = None, downconverter_freq: float | None = None, mix_lo: bool = True, marker_debug_mode_enable: bool = False)[source]#

Class that performs the compilation steps on the sequencer level.

Parameters:
  • parent – A reference to the parent instrument this sequencer belongs to.

  • index – Index of the sequencer.

  • portclock – Tuple that specifies the unique port and clock combination for this sequencer. The first value is the port, second is the clock.

  • channel_name – Specifies the channel identifier of the hardware config (e.g. complex_output_0).

  • sequencer_cfg – Sequencer settings dictionary.

  • latency_corrections – Dict containing the delays for each port-clock combination.

  • lo_name – The name of the local oscillator instrument connected to the same output via an IQ mixer. This is used for frequency calculations.

  • downconverter_freq

    Warning

    Using downconverter_freq requires custom Qblox hardware, do not use otherwise.

    Frequency of the external downconverter if one is being used. Defaults to None, in which case the downconverter is inactive.

  • mix_lo – Boolean flag for IQ mixing with LO. Defaults to True meaning IQ mixing is applied.

  • marker_debug_mode_enable – Boolean flag to indicate if markers should be pulled high at the start of operations. Defaults to False, which means the markers will not be used during the sequence.

class ParseOperationStatus[source]#

Bases: enum.Enum

Return status of the stack.

COMPLETED_ITERATION[source]#

The iterator containing operations is exhausted.

EXITED_CONTROL_FLOW[source]#

The end of a control flow scope is reached.

property connected_output_indices: Tuple[int] | Tuple[int, int] | None[source]#

Return the connected output indices associated with the output name specified in the hardware config.

For the baseband modules, output index ‘n’ corresponds to physical module output ‘n+1’.

For RF modules, output indices ‘0’ and ‘1’ (or: ‘2’ and ‘3’) correspond to ‘path_I’ and ‘path_Q’ of some sequencer, and both these paths are routed to the same physical module output ‘1’ (or: ‘2’).

property connected_input_indices: Tuple[int] | Tuple[int, int] | None[source]#

Return the connected input indices associated with the input name specified in the hardware config.

For the baseband modules, input index ‘n’ corresponds to physical module input ‘n+1’.

For RF modules, input indices ‘0’ and ‘1’ correspond to ‘path_I’ and ‘path_Q’ of some sequencer, and both paths are connected to physical module input ‘1’.

property portclock: Tuple[str, str][source]#

A tuple containing the unique port and clock combination for this sequencer.

Returns:

The portclock.

property settings: quantify_scheduler.backends.types.qblox.SequencerSettings[source]#

Gives the current settings.

Returns:

The settings set to this sequencer.

property name: str[source]#

The name assigned to this specific sequencer.

Returns:

The name.

property has_data: bool[source]#

Whether or not the sequencer has any data (meaning pulses or acquisitions) assigned to it or not.

Returns:

Has data been assigned to this sequencer?

property frequency: float[source]#

The frequency used for modulation of the pulses.

Returns:

The frequency.

qasm_hook_func: Callable | None[source]#

Allows the user to inject custom Q1ASM code into the compilation, just prior to returning the final string.

latency_correction: float[source]#

Latency correction accounted for by delaying the start of the program.

_generate_awg_dict() Dict[str, Any][source]#

Generates the dictionary that contains the awg waveforms in the format accepted by the driver.

Notes

The final dictionary to be included in the json that is uploaded to the module is of the form:

program
awg
    waveform_name
        data
        index
acq
    waveform_name
        data
        index

This function generates the awg dictionary.

Returns:

The awg dictionary.

Raises:
  • ValueError – I or Q amplitude is being set outside of maximum range.

  • RuntimeError – When the total waveform size specified for a port-clock combination exceeds the waveform sample limit of the hardware.

_generate_weights_dict() Dict[str, Any][source]#

Generates the dictionary that corresponds that contains the acq weights waveforms in the format accepted by the driver.

Notes

The final dictionary to be included in the json that is uploaded to the module is of the form:

program
awg
    waveform_name
        data
        index
acq
    waveform_name
        data
        index

This function generates the acq dictionary.

Returns:

The acq dictionary.

Raises:

NotImplementedError – Currently, only two one dimensional waveforms can be used as acquisition weights. This exception is raised when either or both waveforms contain both a real and imaginary part.

_validate_awg_dict(wf_dict: Dict[str, Any]) None[source]#
_prepare_acq_settings(acquisitions: List[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy], acq_metadata: quantify_scheduler.schedules.schedule.AcquisitionMetadata)[source]#

Sets sequencer settings that are specific to certain acquisitions. For example for a TTL acquisition strategy.

Parameters:
  • acquisitions – List of the acquisitions assigned to this sequencer.

  • acq_metadata – Acquisition metadata.

_generate_acq_declaration_dict(repetitions: int, acq_metadata: quantify_scheduler.schedules.schedule.AcquisitionMetadata) Dict[str, Any][source]#

Generates the “acquisitions” entry of the program json. It contains declaration of the acquisitions along with the number of bins and the corresponding index.

For the name of the acquisition (in the hardware), the acquisition channel (cast to str) is used, and is thus identical to the index. Number of bins is taken to be the highest acq_index specified for that channel.

Parameters:
  • repetitions – The number of times to repeat execution of the schedule.

  • acq_metadata – Acquisition metadata.

Returns:

The “acquisitions” entry of the program json as a dict. The keys correspond to the names of the acquisitions (i.e. the acq_channel in the scheduler).

generate_qasm_program(total_sequence_time: float, align_qasm_fields: bool, acq_metadata: quantify_scheduler.schedules.schedule.AcquisitionMetadata | None, repetitions: int) str[source]#

Generates a QASM program for a sequencer. Requires the awg and acq dicts to already have been generated.

Example of a program generated by this function:

        wait_sync     4
        set_mrk       1
        move          10,R0         # iterator for loop with label start
start:
        wait          4
        set_awg_gain  22663,10206  # setting gain for 9056793381316377208
        play          0,1,4
        wait          176
        loop          R0,@start
        set_mrk       0
        upd_param     4
        stop
Parameters:
  • total_sequence_time – Total time the program needs to play for. If the sequencer would be done before this time, a wait is added at the end to ensure synchronization.

  • align_qasm_fields – If True, make QASM program more human-readable by aligning its fields.

  • acq_metadata – Acquisition metadata.

  • repetitions – Number of times to repeat execution of the schedule.

Returns:

The generated QASM program.

Warns:

RuntimeWarning – When number of instructions in the generated QASM program exceeds the maximum supported number of instructions for sequencers in the type of module.

Raises:

RuntimeError – Upon total_sequence_time exceeding QASMProgram.elapsed_time.

_parse_operations(operations_iter: collections.abc.Iterator[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy], qasm: quantify_scheduler.backends.qblox.qasm_program.QASMProgram, acquisition_multiplier: int) bool[source]#

Handle control flow and insert Q1ASM.

_insert_qasm_marker_debug_wrapped(operation: quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy, qasm: quantify_scheduler.backends.qblox.qasm_program.QASMProgram)[source]#
_initialize_append_mode_registers(qasm: quantify_scheduler.backends.qblox.qasm_program.QASMProgram, acquisitions: List[quantify_scheduler.backends.qblox.operation_handling.acquisitions.AcquisitionStrategyPartial])[source]#

Adds the instructions to initialize the registers needed to use the append bin mode to the program. This should be added in the header.

Parameters:
  • qasm – The program to add the instructions to.

  • acquisitions – A list with all the acquisitions to consider.

_get_latency_correction_ns(latency_correction: float) int[source]#
_insert_update_parameters() None[source]#

Insert update parameter instructions to activate offsets, if they are not already activated by a play, acquire or acquire_weighed instruction (see also the Q1ASM reference).

static _any_other_updating_instruction_at_timing_for_parameter_instruction(op_index: int, sorted_pulses_and_acqs: List[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy]) bool[source]#
_get_new_update_parameters(pulses_and_acqs: List[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy]) List[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy][source]#
static _generate_waveforms_and_program_dict(program: str, waveforms_dict: Dict[str, Any], weights_dict: Dict[str, Any] | None = None, acq_decl_dict: Dict[str, Any] | None = None) Dict[str, Any][source]#

Generates the full waveforms and program dict that is to be uploaded to the sequencer from the program string and the awg and acq dicts, by combining them and assigning the appropriate keys.

Parameters:
  • program – The compiled QASM program as a string.

  • waveforms_dict – The dictionary containing all the awg data and indices. This is expected to be of the form generated by the generate_awg_dict method.

  • weights_dict – The dictionary containing all the acq data and indices. This is expected to be of the form generated by the generate_acq_dict method.

  • acq_decl_dict – The dictionary containing all the acq declarations. This is expected to be of the form generated by the generate_acq_decl_dict method.

Returns:

The combined program.

static _dump_waveforms_and_program_json(wf_and_pr_dict: Dict[str, Any], label: str | None = None) str[source]#

Takes a combined waveforms and program dict and dumps it as a json file.

Parameters:
  • wf_and_pr_dict – The dict to dump as a json file.

  • label – A label that is appended to the filename.

Returns:

The full absolute path where the json file is stored.

prepare() None[source]#

Perform necessary operations on this sequencer’s data before compile() is called.

compile(sequence_to_file: bool, align_qasm_fields: bool, repetitions: int = 1) Tuple[Dict[str, Any] | None, quantify_scheduler.schedules.schedule.AcquisitionMetadata | None][source]#

Performs the full sequencer level compilation based on the assigned data and settings. If no data is assigned to this sequencer, the compilation is skipped and None is returned instead.

Parameters:
  • sequence_to_file – Dump waveforms and program dict to JSON file, filename stored in Sequencer.settings.seq_fn.

  • align_qasm_fields – If True, make QASM program more human-readable by aligning its fields.

  • repetitions – Number of times execution the schedule is repeated.

Returns:

The compiled program and the acquisition metadata. If no data is assigned to this sequencer, the compilation is skipped and None is returned instead.

static _replace_marker_pulses(pulse_list: list[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy]) list[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy][source]#

Replaces MarkerPulse operations by explicit high and low operations.

_decide_markers(operation) int[source]#

Helper method to decide what markers should be pulled high when enable_marker is set to True. Checks what module and operation are being processed, then builds a bit string accordingly.

Note that with the current quantify structure a sequencer cannot have connected inputs and outputs simultaneously. Therefore, the QRM baseband module pulls both input or output markers high when doing an operation, as it is impossible during compile time to find out what physical port is being used.

Parameters:
  • sequencer – The sequencer currently in the process of constructing a Q1ASM program.

  • operation – The operation currently being processed by the sequence.

Returns:

A bit string passed on to the set_mrk function of the Q1ASM object.

static _check_nco_operation_timing(sorted_pulses_and_acqs: list[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy]) None[source]#

Check whether this sequencer’s operation adhere to NCO timing restrictions.

class QbloxBaseModule(parent, name: str, total_play_time: float, instrument_cfg: Dict[str, Any], latency_corrections: Dict[str, float] | None = None)[source]#

Bases: ControlDeviceCompiler, abc.ABC

Qblox specific implementation of quantify_scheduler.backends.qblox.compiler_abc.InstrumentCompiler.

This class is defined as an abstract base class since the distinctions between the different devices are defined in subclasses. Effectively, this base class contains the functionality shared by all Qblox devices and serves to avoid repeated code between them.

Parameters:
  • parent (quantify_scheduler.backends.qblox.compiler_container.CompilerContainer) – Reference to the parent object.

  • name – Name of the QCoDeS instrument this compiler object corresponds to.

  • total_play_time – Total time execution of the schedule should go on for. This parameter is used to ensure that the different devices, potentially with different clock rates, can work in a synchronized way when performing multiple executions of the schedule.

  • instrument_cfg – The part of the hardware configuration dictionary referring to this device. This is one of the inner dictionaries of the overall hardware config.

  • latency_corrections – Dict containing the delays for each port-clock combination. This is specified in the top layer of hardware config.

property portclocks: List[Tuple[str, str]][source]#

Returns all the port-clock combinations that this device can target.

abstract property settings_type: quantify_scheduler.backends.types.qblox.BaseModuleSettings[source]#

Specifies the module settings class used by the instrument.

abstract property static_hw_properties: quantify_scheduler.backends.types.qblox.StaticHardwareProperties[source]#

The static properties of the hardware. This effectively gathers all the differences between the different modules.

_construct_sequencers()[source]#

Constructs Sequencer objects for each port and clock combination belonging to this device.

Raises:
  • ValueError – When the output names do not conform to the complex_output_X/real_output_X norm, where X is the index of the output.

  • KeyError – Raised if no ‘portclock_configs’ entry is found in the specific outputs of the hardware config.

  • ValueError – Raised when the same port-clock is multiply assigned in the hardware config.

  • ValueError – Attempting to use more sequencers than available.

distribute_data()[source]#

Distributes the pulses and acquisitions assigned to this module over the different sequencers based on their portclocks. Raises an exception in case the device does not support acquisitions.

abstract assign_frequencies(sequencer: Sequencer)[source]#

An abstract method that should be overridden. Meant to assign an IF frequency to each sequencer, and an LO frequency to each output (if applicable).

_set_lo_interm_freqs(freqs: quantify_scheduler.backends.qblox.helpers.Frequencies, sequencer: Sequencer, compiler_lo_baseband: quantify_scheduler.backends.qblox.instrument_compilers.LocalOscillator | None = None, lo_freq_setting_rf: str | None = None)[source]#

Sets the LO/IF frequencies, for baseband and RF modules.

Parameters:
  • freqs – LO, IF, and clock frequencies, supplied via an helpers.Frequencies object.

  • sequencer – The sequencer for which frequences are to be set.

  • compiler_lo_baseband – For baseband modules, supply the instrument_compilers.LocalOscillator instrument compiler of which the frequency is to be set.

  • lo_freq_setting_rf – For RF modules, supply the name of the LO frequency param from the RFModuleSettings that is to be set.

Raises:
  • ValueError – In case neither LO frequency nor IF has been supplied.

  • ValueError – In case both LO frequency and IF have been supplied and do not adhere to \(f_{RF} = f_{LO} + f_{IF}\).

  • ValueError – In case of RF, when the LO frequency was already set to a different value.

abstract assign_attenuation()[source]#

An abstract method that should be overridden. Meant to assign attenuation settings from the hardware configuration if there is any.

prepare() None[source]#

Performs the logic needed before being able to start the compilation. In effect, this means assigning the pulses and acquisitions to the sequencers and calculating the relevant frequencies in case an external local oscillator is used.

_configure_input_gains()[source]#

Configures input gain of module settings. Loops through all valid channel names and checks for gain values in hw config. Throws a ValueError if a gain value gets modified.

_configure_mixer_offsets()[source]#

Configures offset of input, uses calc_from_units_volt found in helper file. Raises an exception if a value outside the accepted voltage range is given.

_ensure_single_scope_mode_acquisition_sequencer() None[source]#

Raises an error if multiple sequencers use scope mode acquisition, because that’s not supported by the hardware. Also, see _determine_scope_mode_acquisition_sequencer_and_qblox_acq_index() which also ensures the program that gets uploaded to the hardware satisfies this requirement.

Raises:

ValueError – Multiple sequencers have to perform trace acquisition. This is not supported by the hardware.

compile(debug_mode: bool, repetitions: int = 1, sequence_to_file: bool | None = None) Dict[str, Any] | None[source]#

Performs the actual compilation steps for this module, by calling the sequencer level compilation functions and combining them into a single dictionary.

Parameters:
  • debug_mode – Debug mode can modify the compilation process, so that debugging of the compilation process is easier.

  • repetitions – Number of times execution the schedule is repeated.

  • sequence_to_file – Dump waveforms and program dict to JSON file, filename stored in Sequencer.settings.seq_fn.

Returns:

The compiled program corresponding to this module. It contains an entry for every sequencer under the key “sequencers”, and acquisition metadata under the key “acq_metadata”, and the “repetitions” is an integer with the number of times the defined schedule is repeated. All the other generic settings are under the key “settings”. If the device is not actually used, and an empty program is compiled, None is returned instead.

class QbloxBasebandModule(parent, name: str, total_play_time: float, instrument_cfg: Dict[str, Any], latency_corrections: Dict[str, float] | None = None)[source]#

Bases: QbloxBaseModule

Abstract class with all the shared functionality between the QRM and QCM baseband modules.

property settings_type: type[source]#

The settings type used by baseband-type devices.

assign_frequencies(sequencer: Sequencer)[source]#

Determines LO/IF frequencies and assigns them, for baseband modules.

In case of no external local oscillator, the NCO is given the same frequency as the clock – unless NCO was permanently disabled via “interm_freq”: 0 in the hardware config.

In case of an external local oscillator and sequencer.mix_lo is False, the LO is given the same frequency as the clock (via helpers.determine_clock_lo_interm_freqs()).

assign_attenuation()[source]#

Meant to assign attenuation settings from the hardware configuration, if there is any. For baseband modules there is no attenuation parameters currently.

class QbloxRFModule(parent, name: str, total_play_time: float, instrument_cfg: Dict[str, Any], latency_corrections: Dict[str, float] | None = None)[source]#

Bases: QbloxBaseModule

Abstract class with all the shared functionality between the QRM-RF and QCM-RF modules.

property settings_type: type[source]#

The settings type used by RF modules.

assign_frequencies(sequencer: Sequencer)[source]#

Determines LO/IF frequencies and assigns them for RF modules.

static _get_connected_lo_indices(sequencer: Sequencer) Generator[int][source]#

Identify the LO the sequencer is outputting. Use the sequencer output to module output correspondence, and then use the fact that LOX is connected to module output X.

assign_attenuation()[source]#

Assigns attenuation settings from the hardware configuration.

Floats that are a multiple of 1 are converted to ints. This is needed because the quantify_core.measurement.control.grid_setpoints() converts setpoints to floats when using an attenuation as settable.