qasm_program#

QASM program class for Qblox backend.

Module Contents#

Classes#

QASMProgram

Class that holds the compiled Q1ASM program that is to be executed by the sequencer.

Functions#

get_marker_binary(→ int)

Sets the marker from a string representing a binary number. Each digit

get_marker_binary(marker_setting: str | int) int[source]#

Sets the marker from a string representing a binary number. Each digit corresponds to a marker e.g. ‘0010’ sets the second marker to True.

If the marker setting is already an integer, the function checks whether it is a 4-bit integer.

Parameters:

marker_setting – The string representing a binary number.

class QASMProgram(static_hw_properties: quantify_scheduler.backends.types.qblox.StaticHardwareProperties, register_manager: quantify_scheduler.backends.qblox.register_manager.RegisterManager, align_fields: bool, acq_metadata: quantify_scheduler.schedules.schedule.AcquisitionMetadata | None)[source]#

Class that holds the compiled Q1ASM program that is to be executed by the sequencer.

Apart from this the class holds some convenience functions that auto generate certain instructions with parameters, as well as update the elapsed time.

Parameters:
  • static_hw_properties – Dataclass holding the properties of the hardware that this program is to be played on.

  • register_manager – The register manager that keeps track of the occupied/available registers.

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

  • acq_metadata – Provides a summary of the used acquisition protocol, bin mode, acquisition channels, acquisition indices per channel, and repetitions.

static_hw_properties[source]#

Dataclass holding the properties of the hardware that this program is to be played on.

register_manager[source]#

The register manager that keeps track of the occupied/available registers.

align_fields[source]#

If true, all labels, instructions, arguments and comments in the string representation of the program are printed on the same indention level. This worsens performance.

acq_metadata[source]#

Provides a summary of the used acquisition protocol, bin mode, acquisition channels, acquisition indices per channel, and repetitions.

time_last_acquisition_triggered: int | None = None[source]#

Time on which the last acquisition was triggered. Is None if no previous acquisition was triggered.

time_last_pulse_triggered: int | None = None[source]#

Time on which the last operation was triggered. Is None if no previous operation was triggered.

instructions: list[list] = [][source]#

A list containing the instructions added to the program. The instructions added are in turn a list of the instruction string with arguments.

conditional_manager[source]#

The conditional manager that keeps track of the conditionals.

_lock_conditional: bool = False[source]#

A lock to prevent nested conditionals.

_elapsed_times_in_loops: list[int] = [0][source]#

The time elapsed in its current form. This is used to keep track of the overall and nested loop timing and necessary waits.

property elapsed_time: int[source]#

Current elapsed time of all the instructions in ns. It needs to be manually adjusted after each modifications of the QASM program. If the QASM program is in a loop, only one repetition’s worth of elapsed time should be registered. After a loop is ended, QASMProgram will automatically adjust the correct elapsed time with all repetitions.

_find_qblox_acq_index(acq_channel: Hashable) int[source]#

Finds the Qblox acq_index corresponding to acq_channel in the acq_metadata.

static get_instruction_as_list(instruction: str, *args: int | str, label: str | None = None, comment: str | None = None) list[str | int][source]#

Takes an instruction with arguments, label and comment and turns it into the list required by the class.

Parameters:
  • instruction – The instruction to use. This should be one specified in q1asm_instructions or the assembler will raise an exception.

  • args – Arguments to be passed.

  • label – Adds a label to the line. Used for jumps and loops.

  • comment – Optionally add a comment to the instruction.

Returns:

List that contains all the passed information in the valid format for the program.

Raises:

SyntaxError – More arguments passed than the sequencer allows.

emit(*args, **kwargs) list[str | int][source]#

Wrapper around the get_instruction_as_list which adds it to this program.

Parameters:
  • args – All arguments to pass to get_instruction_as_list.

  • **kwargs – All keyword arguments to pass to get_instruction_as_list.

Returns:

A list containing instructions.

set_latch(op_strategies: Sequence[quantify_scheduler.backends.qblox.operation_handling.base.IOperationStrategy]) None[source]#

Set the latch that is needed for conditional playback.

This assumes that the latch address is present inside the pulses’ operation_info. If no latch address is found, nothing is emitted.

Parameters:

op_strategies – The op_strategies containing the pulses to search the latch address in.

auto_wait(wait_time: int, count_as_elapsed_time: bool = True, comment: str | None = None) None[source]#

Automatically emits a correct wait command. If the wait time is longer than allowed by the sequencer it correctly breaks it up into multiple wait instructions. If the number of wait instructions is too high (>4), a loop will be used.

Parameters:
  • wait_time – Time to wait in ns.

  • count_as_elapsed_time – If true, this wait time is taken into account when keeping track of timing. Otherwise, the wait instructions are added but this wait time is ignored in the timing calculations in the rest of the program.

  • comment – Allows to override the default comment.

Raises:

ValueError – If wait_time <= 0.

wait_till_start_operation(operation: quantify_scheduler.backends.types.qblox.OpInfo) None[source]#

Waits until the start of a pulse or acquisition.

Parameters:

operation – The pulse or acquisition that we want to wait for.

Raises:

ValueError – If wait time < 0.

set_gain_from_amplitude(amplitude_path_I: float, amplitude_path_Q: float, operation: quantify_scheduler.backends.types.qblox.OpInfo | None) None[source]#

Sets the gain such that a 1.0 in waveform memory corresponds to the full awg gain.

Parameters:
  • amplitude_path_I – Voltage to set on path_I.

  • amplitude_path_Q – Voltage to set on path_Q.

  • operation – The operation for which this is done. Used for the exception messages.

static expand_awg_from_normalised_range(val: float, immediate_size: int, param: str | None = None, operation: quantify_scheduler.backends.types.qblox.OpInfo | None = None) float[source]#

Takes the value of an awg gain or offset parameter in normalized form (abs(param) <= 1.0), and expands it to an integer in the appropriate range required by the sequencer.

Parameters:
  • val – The value of the parameter to expand.

  • immediate_size – The size of the immediate. Used to find the max int value.

  • param – The name of the parameter, to make a possible exception message more descriptive.

  • operation – The operation this value is expanded for, to make a possible exception message more descriptive.

Returns:

The expanded value of the parameter.

Raises:

ValueError – Parameter is not in the normalized range.

conditional(operation: quantify_scheduler.backends.qblox.operation_handling.virtual.ConditionalStrategy) Generator[None, None, None][source]#

Defines a conditional block in the QASM program.

When this context manager is entered/exited it will insert additional set_cond QASM instructions in the program that specify the conditionality of a set of instructions.

The following example should make it clear what is happening.

set_cond set_enable=1, mask=0, operator=OR, else_duration=4
<50 ns duration of instructions that contains 3 real time instructions>

set_cond set_enable=1, mask=0, operator=NOR, else_duration=4
wait 50-3*4+4 = 42 ns # adding an additional 4 ns to make math work out

set_cond set_enable=0, mask=0, operator=OR, else_duration=4

The else_duration is the wait time per real time instruction in the conditional block. If a trigger happened, the first block runs normally for 50 ns, the second block runs for 4 ns. If there is no trigger, the first block runs for 3*4 = 12 ns, second block for 42 ns. So the duration in both cases is 42 ns. Note that set_cond itself has zero duration.

The exact values that need to be passed to the set_cond instructions are determined while the qasm program is generated with the help of FeedbackTriggerCondition and ConditionalManager.

Parameters:

operation (ConditionalStrategy) – The conditional strategy that defines the start of a conditional block.

loop(label: str, repetitions: int = 1) Generator[str, None, None][source]#

Defines a context manager that can be used to generate a loop in the QASM program.

Parameters:
  • label – The label to use for the jump.

  • repetitions – The amount of iterations to perform.

Yields:

The register used as loop counter.

Examples

This adds a loop to the program that loops 10 times over a wait of 100 ns.

from quantify_scheduler.backends.qblox.qasm_program import QASMProgram
from quantify_scheduler.backends.qblox.instrument_compilers import QCMCompiler
from quantify_scheduler.backends.qblox import register_manager, constants
from quantify_scheduler.backends.types.qblox import (
    StaticAnalogModuleProperties,
    BoundedParameter
)

qasm = QASMProgram(
    static_hw_properties=QCMCompiler.static_hw_properties,
    register_manager=register_manager.RegisterManager(),
    align_fields=True,
    acq_metadata=None,
)

with qasm.loop(label="repeat", repetitions=10):
    qasm.auto_wait(100)

qasm.instructions
[['', 'move', '10,R0', '# iterator for loop with label repeat'],
 ['repeat:', '', '', ''],
 ['', 'wait', '100', '# auto generated wait (100 ns)'],
 ['', 'loop', 'R0,@repeat', '']]
temp_registers(amount: int = 1) Iterator[list[str]][source]#

Context manager for using a register temporarily. Frees up the register afterwards.

Parameters:

amount – The amount of registers to temporarily use.

Yields:

Either a single register or a list of registers.