# quantify_scheduler.backends.qblox.compiler_abc

Compiler base and utility classes for Qblox backend.

## Module Contents

### Classes

 InstrumentCompiler Abstract base class that defines a generic instrument compiler. The subclasses that ControlDeviceCompiler Abstract class for any device requiring logic for acquisition and playback of 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[source]
class InstrumentCompiler(parent, name: str, total_play_time: float, hw_mapping: Dict[str, Any], latency_corrections: Optional[Dict[str, float]] = 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.

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(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

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, hw_mapping: Dict[str, Any], latency_corrections: Optional[Dict[str, float]] = None)[source]

Abstract class for any device requiring logic for acquisition and playback of pulses.

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(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

repetitions – Number of times execution the schedule is repeated.

Returns

A data structure representing the compiled program.

class Sequencer(parent: QbloxBaseModule, index: int, portclock: Tuple[str, str], static_hw_properties: quantify_scheduler.backends.types.qblox.StaticHardwareProperties, connected_outputs: Union[Tuple[int], Tuple[int, int]], seq_settings: Dict[str, Any], latency_corrections: Dict[str, float], lo_name: Optional[str] = None, downconverter_freq: float = 0)[source]

Class that performs the compilation steps on the sequencer level.

property connected_outputs: Union[Tuple[int], Tuple[int, int]][source]

The indices of the output paths that this sequencer is producing awg data for.

For the baseband modules, these indices correspond directly to a physical output (e.g. index 0 corresponds to output 1 etc.).

For the RF modules, indexes 0 and 1 correspond to path0 and path1 of output 1, respectively, while indexes 2 and 3 correspond to path0 and path1 of output 2.

property output_mode: Literal[complex, real, imag][source]

Specifies whether the sequencer is using only path0 (real), path1 (imag) or both (complex).

If real or imag, the sequencer is restricted to only using real valued data.

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 :Optional[Callable][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.

_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.

_generate_acq_declaration_dict(acquisitions: , repetitions: int) 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
• acquisitions – List of the acquisitions assigned to this sequencer.

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

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).

update_settings()[source]

Updates the sequencer settings to set all parameters that are determined by the compiler.

generate_qasm_program(total_sequence_time: float, repetitions: Optional[int] = 1) 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.

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

Returns

The generated QASM program.

_initialize_append_mode_registers(qasm: quantify_scheduler.backends.qblox.qasm_program.QASMProgram, acquisitions: )[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]
static _generate_waveforms_and_program_dict(program: str, waveforms_dict: Dict[str, Any], weights_dict: Optional[Dict[str, Any]] = None, acq_decl_dict: Optional[Dict[str, Any]] = 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.

Returns

The combined program.

static _dump_waveforms_and_program_json(wf_and_pr_dict: Dict[str, Any], label: Optional[str] = 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.

compile(repetitions: int = 1) Optional[Dict[str, Any]][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

repetitions – Number of times execution the schedule is repeated.

Returns

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

class QbloxBaseModule(parent, name: str, total_play_time: float, hw_mapping: Dict[str, Any], latency_corrections: Optional[Dict[str, float]] = None)[source]

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.

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.PulsarSettings[source]

Specifies the PulsarSettings 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.

is_pulsar :bool = True[source]

Specifies if it is a standalone Pulsar or a cluster module. To be overridden by the cluster compiler if needed.

_construct_sequencers() Dict[str, Sequencer][source]

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

Returns

A dictionary containing the sequencer objects, the keys correspond to the names of the sequencers.

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, or an LO frequency to each output (if applicable). For each sequencer, the following relation is obeyed: $$f_{RF} = f_{LO} + f_{IF}$$.

In this step it is thus expected that either the IF and/or the LO frequency has been set during instantiation. Otherwise an error is thrown. If the frequency is overconstraint (i.e. multiple values are somehow specified) an error is thrown during assignment.

Raises

ValueError – Neither the LO nor the IF frequency has been set and thus contain None values.

abstract assign_attenuation()[source]

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

static downconvert_clock(downconverter_freq: float, clock_freq: float)[source]

Downconverts clock frequency.

Parameters
• downconverter_freq – Frequency of the downconverter.

• clock_freq – clock frequency that is being downconverted.

Raises
• ValueError – When downconverter frequency is negative.

• ValueError – When downconverter frequency is less than the clock frequency.

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_mixer_offsets_and_gains(settings: quantify_scheduler.backends.types.qblox.BaseModuleSettings, hw_mapping: Dict[str, Any]) [source]

We configure the mixer offsets, gains, attenuations after initializing the settings such we can account for the differences in the hardware. e.g. the V vs mV encountered here.

Parameters
• settings – The settings dataclass to which to add the dc offsets and gains.

• hw_mapping – The hardware configuration.

Returns

The settings dataclass after adding the normalized offsets and gains.

Raises

ValueError – An offset was used outside of the allowed range.

abstract update_settings()[source]

Updates the settings to set all parameters that are determined by the compiler.

_determine_scope_mode_acquisition_sequencer() None[source]

Finds which sequencer has to perform raw trace acquisitions and adds it to the scope_mode_sequencer of the settings.

Raises

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

compile(repetitions: int = 1) Optional[Dict[str, Any]][source]

Performs the actual compilation steps for this module, by calling the sequencer level compilation functions and combining them into a single dictionary. The compiled program has a settings key, and keys for every sequencer.

Parameters

repetitions – Number of times execution the schedule is repeated.

Returns

The compiled program corresponding to this module. It contains an entry for every sequencer and general “settings”. If the device is not actually used, and an empty program is compiled, None is returned instead.

_get_acquisition_mapping() Optional[dict][source]

Generates a mapping of acq_channel, acq_index to sequencer name, protocol.

Returns

A dictionary containing tuple(acq_channel, acq_index) as keys and tuple(sequencer name, protocol) as value.

class QbloxBasebandModule(parent, name: str, total_play_time: float, hw_mapping: Dict[str, Any], latency_corrections: Optional[Dict[str, float]] = None)[source]

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.

update_settings()[source]

Updates the settings to set all parameters that are determined by the compiler.

assign_frequencies(sequencer: Sequencer)[source]

Assigns frequencies for baseband modules.

static assign_frequency_with_ext_lo(sequencer: Sequencer, container)[source]

Meant to assign an IF frequency to each sequencer, or an LO frequency to each output (if applicable). For each sequencer, the following relation is obeyed: $$f_{RF} = f_{LO} + f_{IF}$$.

In this step it is thus expected that either the IF and/or the LO frequency has been set during instantiation. Otherwise an error is thrown. If the frequency is overconstraint (i.e. multiple values are somehow specified) an error is thrown during assignment.

Raises

ValueError – Neither the LO nor the IF frequency has been set and thus contain None values.

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, hw_mapping: Dict[str, Any], latency_corrections: Optional[Dict[str, float]] = None)[source]

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-type devices

update_settings()[source]

Updates the settings to set all parameters that are determined by the compiler.

assign_frequencies(sequencer: Sequencer)[source]

Meant to assign an IF frequency to each sequencer, or an LO frequency to each output (if applicable). For each sequencer, the following relation is obeyed: $$f_{RF} = f_{LO} + f_{IF}$$.

In this step it is thus expected that either the IF and/or the LO frequency has been set during instantiation. Otherwise an error is thrown. If the frequency is overconstraint (i.e. multiple values are somehow specified) an error is thrown during assignment.

Raises

ValueError – Neither the LO nor the IF frequency has been set and thus contain None values.

assign_attenuation()[source]

Assigns attenuation settings from the hardware configuration.

classmethod _validate_output_mode(sequencer: Sequencer)[source]