Skip to content

laboneq.openqasm3

LabOne Q OpenQASM

What is supported?

LabOne Q currently aims to support OpenQASM 3.0 and the corresponding version of OpenPulse.

The list below outlines the features of OpenQASM. It follows the top-level headings of the OpenQASM specification for ease of reference. Unless otherwise mentioned, features are supported. Unsupported features and caveats are noted explicitly.

OpenQASM and OpenPulse feature support

  • Comments
  • Version string
  • Included files
    • Caveats:
      • Only stdgates.inc may be imported.
    • Notes:
      • Importing stdgates.inc does not implement any gates. Implementations are supplied via the QuantumOperations.
  • Types and Casting
    • Quantum types
      • Qubits
      • Qubit aliasing (let)
      • Physical qubits
    • Classical types
      • Bool
      • Integer
      • Float
      • Complex
      • Duration
      • Discrete sets
      • Literal values for the above types
      • Constants
      • Angle (unsupported)
      • Array (unsupported)
      • Bit (unsupported)
      • Stretch (unsupported)
      • Caveats:
        • The classical type system is rudimentary. Types behave like equivalent Python types.
        • The built-in constants (pi, etc) and constant functions (arccos, arcsin, etc) are not implemented.
    • Operations:
      • Arithmetic (+, -, *, /)
      • Logical (||, &&)
      • Comparison (==, !=, <, <=, >, >=)
      • Unitary (-, !)
      • Indexing (e.g. q[1])
      • Concatenation (++)
      • Other operations (unsupported)
  • Gates
    • Applying gates
      • Caveats:
        • Gate modifiers are not supported.
        • Gate durations are not yet supported.
        • Broadcasting is not yet supported.
    • Defining gates (unsupported)
      • Caveats:
        • The built-in gates U(θ, ϕ, λ) and gphase(γ) are not automatically implemented.
  • Built-in quantum instructions
    • Initialization
      • reset supported via a user-supplied gate.
    • Measurement
      • measure supported via a user-supplied gate.
      • Caveats:
        • OpenQASM measurements return LabOne Q measurement handles. These handles can be used in externally defined functions and gates but cannot yet be used in branching statements within OpenQASM or assigned to arrays.
  • Classical instructions
    • Low-level classical instructions
      • See the notes on classical types above.
    • Looping and branching
      • If-else statements
        • Caveats:
          • Branching is only supported on values known at compile time. This includes constants, inputs and expressions derived from them.
          • Branching on loop variables is not yet supported.
      • For loops
        • Caveats:
          • Only range declarations are currently supported for specifying the values to loop over.
          • Loop variables may typically only be used in places where a LabOne Q sweep parameter could be.
      • While loops (unsupported)
      • Breaking and continuing loops (unsupported)
      • Terminating the program early (unsupported)
    • The Switch statement (unsupported)
    • Extern function calls
      • In addition to returning values, extern functions may as a side-effect also return a LabOne Q section to be used within the experiment.
  • Subroutines (unsupported)
  • Scoping of variables
    • Global scope
    • Subroutine and gate scope
    • Block scope
    • Caveats:
      • The scope system is a simple hierarchical system and does not closely follow the scoping rules in the OpenQASM specification.
  • Directives
    • Pragmas
      • See the section below for a list of LabOne Q specific pragmas.
    • Annotations (unsupported)
  • Input/output
  • Standard library
    • Caveats:
      • Importing stdgates.inc does not automatically define any gates.
  • Circuit timing
    • Duration and stretch types
      • See notes on classical types above.
    • Operations on durations
      • See notes on classical types above.
    • Delays
    • Boxed expressions
    • Barrier instruction
  • Pulse-level descriptions of gates and measurement
    • Inline calibration blocks
    • Restrictions on defcal bodies
    • Calibrations in practice
  • OpenPulse Grammar
    • Ports
    • Frames
      • Frame Initialization (unsupported)
      • Frame Manipulation (partially supported)
    • Waveforms
    • Play instruction
    • Capture Instruction

Pragmas

LabOne Q specific pragmas all start with the prefix zi.. All other pragmas are ignored.

There is currently only a single pragma available:

  • pragma zi.acquisition_type VALUE

    This sets the experiment AcquisitionType when an OpenQASM program is compiled to a LabOne Q experiment by exp_from_qasm. The value is case-insensitive and should match one of the acquisition type names (e.g. integration, spectroscopy, discrimination, raw).

    Example: pragma zi.acquisition_type spectroscopy

laboneq.openqasm3

OpenQASMTranspiler(qpu)

OpenQASM transpiler for LabOne Q.

Translates OpenQASM program(s) to LabOne Q constructs. Does not perform any optimization steps.

Parameters:

Name Type Description Default
qpu QPU

Quantum processing unit for which the programs are transpiled to.

Qubits and quantum operations used within the programs must exist in the qpu.

required

qpu = qpu instance-attribute

section(program, qubit_map, inputs=None, externs=None)

Transpile a program into an experiment section.

Useful when only the OpenQASM program part is needed as an Section.

To create a full Experiment, use either .experiment() or .batch_experiment().

Parameters:

Name Type Description Default
program str

OpenQASM program.

required
qubit_map dict[str, QuantumElement | list[QuantumElement]]

A map from OpenQASM qubit names to LabOne Q DSL Qubit objects in the QPU.

The qubit values can be either be qubit uids or direct qubit objects. Mapped qubit registers must be a list of qubits.

When QuantumElement is supplied, it is used directly as long as the matching uid exists in QPU.

required
inputs dict[str, Any] | None

Inputs to the program.

Supports also OpenPulse implicit input waveforms.

Input waveforms declared in the legacy API exp_from_qasm(waveforms=...) are also treated as inputs.

None
externs dict[str, Callable | Port] | None

A mapping for program extern definitions.

Externs may be either functions (Python callables) or ports on qubit signals.

None

Returns:

Type Description
Section

a Section which contains the operations in the program.

Raises:

Type Description
ValueError

Supplied qubit(s) or mapped ports does not exists in the QPU.

OpenQasmException

The program cannot be transpiled.

TypeError

Extern value is not of type callable or Port.

experiment(program, qubit_map, inputs=None, externs=None, options=None)

Transpile QASM program into an LabOne Q experiment.

Parameters:

Name Type Description Default
program str

OpenQASM program.

required
qubit_map dict[str, str | list[str] | QuantumElement | list[QuantumElement]]

A map from OpenQASM qubit names to LabOne Q DSL Qubit objects in the QPU.

The qubit values can be either be qubit uids or direct qubit objects. Mapped qubit registers must be a list of qubits.

When QuantumElement is supplied, it is used directly as long as the matching uid exists in QPU.

required
inputs dict[str, Any] | None

Inputs to the program.

Supports also OpenPulse implicit input waveforms.

Input waveforms declared in the legacy API exp_from_qasm(waveforms=...) are also treated as inputs.

None
externs dict[str, Callable | Port] | None

A mapping for program extern definitions.

Externs may be either functions (Python callables) or ports on qubit signals.

None
options SingleProgramOptions | dict | None

Optional settings for the LabOne Q Experiment.

Default: SingleProgramOptions

Accepts also a dictionary with following items:

count: The number of acquire iterations.

acquisition_mode: The mode of how to average the acquired data.

acquisition_type: The type of acquisition to perform. The acquisition type may also be specified within the OpenQASM program using pragma zi.acqusition_type raw, for example. If an acquisition type is passed here, it overrides any value set by a pragma. If the acquisition type is not specified, it defaults to enums.AcquisitionType.INTEGRATION.

reset_oscillator_phase: When true, reset all oscillators at the start of every acquisition loop iteration.

None

Returns:

Type Description
Experiment

A LabOne Q Experiment.

Raises:

Type Description
ValueError

Supplied qubit(s) or mapped ports does not exists in the QPU.

OpenQasmException

The program cannot be transpiled.

TypeError

Extern value is not of type callable or Port.

batch_experiment(programs, qubit_map, inputs=None, externs=None, options=None)

Batch a list of OpenQASM programs into a LabOne Q experiment.

The list of programs are processed into a single LabOne Q experiment that executes them sequentially.

At this time, the QASM programs should not include any measurements. By default, we automatically append a measurement of all qubits to the end of each program. This can be controlled via add_measurement option.

Note: Using set_frequency or specifying the acquisition type via a pragma zi.acquisition_type statement within an OpenQASM program is not supported in batch mode. It will log a warning if these are encountered.

The supplied mapping parameters for OpenQASM definitions are shared among the programs. Individual parameter mapping per program cannot be done.

Parameters:

Name Type Description Default
programs list[str]

List of OpenQASM program.

required
qubit_map dict[str, str | list[str], QuantumElement | list[QuantumElement]]

A map from OpenQASM qubit names to LabOne Q DSL Qubit objects in the QPU.

The qubit values can be either be qubit uids or direct qubit objects. Mapped qubit registers must be a list of qubits.

When QuantumElement is supplied, it is used directly as long as the matching uid exists in QPU.

required
inputs dict[str, Any] | None

Inputs to the program.

Supports also OpenPulse implicit input waveforms.

Input waveforms declared in the legacy API exp_from_qasm(waveforms=...) are also treated as inputs.

None
externs dict[str, Callable | Port] | None

A mapping for program extern definitions.

Externs may be either functions (Python callables) or ports on qubit signals.

None
options MultiProgramOptions | dict | None

Optional settings for the LabOne Q Experiment.

Default: MultiProgramOptions

Accepts also a dictionary with the following items:

count: The number of acquire iterations.

acquisition_mode: The mode of how to average the acquired data.

acquisition_type: The type of acquisition to perform. The acquisition type may also be specified within the OpenQASM program using pragma zi.acqusition_type raw, for example. If an acquisition type is passed here, it overrides any value set by a pragma. If the acquisition type is not specified, it defaults to enums.AcquisitionType.INTEGRATION.

reset_oscillator_phase: When true, reset all oscillators at the start of every acquisition loop iteration.

repetition_time: The length that any single program is padded to. The duration between the reset and the final readout is fixed and must be specified as repetition_time. It must be chosen large enough to accommodate the longest of the programs. The repetition_time parameter is also required if the resets are disabled. In a future version we hope to make an explicit repetition_time optional.

batch_execution_mode: The execution mode for the sequence of programs. Can be any of the following.

  • nt: The individual programs are dispatched by software.
  • pipeline: The individual programs are dispatched by the sequence pipeliner.
  • rt: All the programs are combined into a single real-time program.

rt offers the fastest execution, but is limited by device memory. In comparison, pipeline introduces non-deterministic delays between programs of up to a few 100 microseconds. nt is the slowest.

add_reset: If True, an active reset operation is added to the beginning of each program.

Note: Requires reset(qubit) operation to be defined for each qubit.

add_measurement: If True, add measurement at the end of each program for all qubits used.

Note: Requires measure(qubit, handle: str) operation to be defined for each qubit, where handle is the key specified for the qubit in the qubit_map parameter (e.g. q0) or <key>[N] in the case of an qubit register as a list of qubits (e.g. q[0], q[1], ..., q[N], where N represents the qubit index in the supplied register).

pipeline_chunk_count: The number of pipeline chunks to divide the experiment into.

None

Returns:

Type Description
Experiment

A LabOne Q Experiment.

Raises:

Type Description
ValueError

Supplied qubit(s) or mapped ports does not exists in the QPU.

OpenQasmException

The program cannot be transpiled.

TypeError

Extern value is not of type callable or Port.

SingleProgramOptions

LabOne Q Experiment options for a single OpenQASM program.

Attributes:

Name Type Description
count int

The number of acquire iterations.

averaging_mode AveragingMode

The mode of how to average the acquired data.

acquisition_type AcquisitionType

The type of acquisition to perform.

The acquisition type may also be specified within the OpenQASM program using pragma zi.acqusition_type raw, for example.

If an acquisition type is passed here, it overrides any value set by a pragma.

If the acquisition type is not specified, it defaults to AcquisitionType.INTEGRATION.

reset_oscillator_phase bool

When true, reset all oscillators at the start of every acquisition loop iteration.

count: int = attrs.field(default=1) class-attribute instance-attribute

averaging_mode: AveragingMode = attrs.field(default=AveragingMode.CYCLIC, converter=AveragingMode) class-attribute instance-attribute

acquisition_type: AcquisitionType = attrs.field(default=None, converter=lambda x: AcquisitionType(x) if x is not None else x) class-attribute instance-attribute

reset_oscillator_phase: bool = attrs.field(default=False) class-attribute instance-attribute

MultiProgramOptions

Bases: SingleProgramOptions

LabOne Q Experiment options for multiple OpenQASM programs.

Attributes:

Name Type Description
count

The number of acquire iterations.

averaging_mode

The mode of how to average the acquired data.

acquisition_type

The type of acquisition to perform.

The acquisition type may also be specified within the OpenQASM program using pragma zi.acqusition_type raw, for example.

If an acquisition type is passed here, it overrides any value set by a pragma.

If the acquisition type is not specified, it defaults to AcquisitionType.INTEGRATION.

reset_oscillator_phase

When true, reset all oscillators at the start of every acquisition loop iteration.

repetition_time float

The length that any single program is padded to.

batch_execution_mode str

The execution mode for the sequence of programs. Can be any of the following:

  • "nt": The individual programs are dispatched by software.
  • "pipeline": The individual programs are dispatched by the sequence pipeliner.
  • "rt": All the programs are combined into a single real-time program.

"rt" offers the fastest execution, but is limited by device memory. In comparison, "pipeline" introduces non-deterministic delays between programs of up to a few 100 microseconds. "nt" is the slowest.

add_reset bool

If True, an active reset operation is added to the beginning of each program.

add_measurement bool

If True, add measurement at the end for all qubits used.

pipeline_chunk_count int | None

The number of pipeline chunks to divide the experiment into.

repetition_time: float = attrs.field(default=0.001, validator=attrs.validators.instance_of(float)) class-attribute instance-attribute

batch_execution_mode: str = attrs.field(default='pipeline', validator=attrs.validators.in_(('pipeline', 'nt', 'rt'))) class-attribute instance-attribute

add_reset: bool = attrs.field(default=False, validator=attrs.validators.instance_of(bool)) class-attribute instance-attribute

add_measurement: bool = attrs.field(default=True, validator=attrs.validators.instance_of(bool)) class-attribute instance-attribute

pipeline_chunk_count: int | None = attrs.field(default=None, validator=attrs.validators.optional(attrs.validators.instance_of(int))) class-attribute instance-attribute

ExternResult(result=None, handle=None, section=None)

A class for holding the result of an extern function that needs to play a section, perform a measurement or other operations in addition to returning a result.


result:
    The result returned by the extern function.
handle:
    The measurement handle that holds the result returned by
    the extern function. Only one of handle or result
    may be specified.
section:
    The section the extern function would like to have played at the
    point in the OpenQASM function where it is called. Sections cannot
    be played inside an expression -- the call to the extern must be
    directly a statement or the right-hand side of an assignment.

result (Any):
    The result returned by the extern function.
handle (str | None):
    The measurement handle holding the result.
section (Section | None):
    The section the extern function wishes to play.

result = result instance-attribute

handle = handle instance-attribute

section = section instance-attribute

OpenQasmException(msg=None, mark=None, source=None)

Bases: Exception

An exception class for OpenQASM related errors in LabOne Q.

The exception can highlight the issue in the source text.

If the source or the mark are not provided, it defaults to the usual behaviour of just printing the message.

Unknown identifier 'frame0'
|          play(frame0, 10ns);
           ^

mark = mark instance-attribute

source = source instance-attribute

GateStore()

A mapping store between OpenQASM statements and LabOne Q.

Deprecated in version 2.43.0

Use OpenQASMTranspiler and quantum.QuantumOperations instead.

gates: Dict[Tuple[str, Tuple[str, ...]], Callable[..., Section]] = {} instance-attribute

gate_map: Dict[str, str] = {} instance-attribute

waveforms: Dict[str, Callable] = {} instance-attribute

ports = {} instance-attribute

lookup_gate(name, qubits, args=None, kwargs=None)

map_gate(qasm_name, labone_q_name)

Define mapping from qasm gate name to LabOne Q gate name.

register_port(qasm_port, signal_line)

register_gate_section(name, qubit_names, section_factory)

Register a LabOne Q section factory as a gate.

register_gate(name, qubit_name, pulse, signal, phase=None, id=None)

Register a pulse as a single-qubit gate.

lookup_waveform(name)

register_waveform(name, pulse)

port(qubit, signal)

Create a port to qubit signal line.

Parameters:

Name Type Description Default
qubit str

UID of the qubit.

required
signal str

Name of the signal line.

required

Returns:

Type Description
Port

A port.

exp_from_qasm(program, qubits, gate_store, inputs=None, externs=None, count=1, averaging_mode=AveragingMode.CYCLIC, acquisition_type=None, reset_oscillator_phase=False)

Deprecated in version 2.43.0

Use OpenQASMTranspiler instead.

Create an experiment from an OpenQASM program.

Parameters:

Name Type Description Default
program str

OpenQASM program

required
qubits dict[str, QuantumElement]

Map from OpenQASM qubit names to LabOne Q DSL Qubit objects

required
gate_store GateStore

Map from OpenQASM gate names to LabOne Q DSL Gate objects

required
inputs dict[str, Any] | None

Inputs to the OpenQASM program.

None
externs dict[str, Callable[..., ExternResult | Any]] | None

Extern functions for the OpenQASM program.

None
count int

The number of acquire iterations.

1
averaging_mode AveragingMode

The mode of how to average the acquired data.

CYCLIC
acquisition_type AcquisitionType | None

The type of acquisition to perform.

The acquisition type may also be specified within the OpenQASM program using pragma zi.acquisition_type raw, for example.

If an acquisition type is passed here, it overrides any value set by a pragma.

If the acquisition type is not specified, it defaults to AcquisitionType.INTEGRATION.

None
reset_oscillator_phase bool

When true, reset all oscillators at the start of every acquisition loop iteration.

False

Returns:

Type Description
Experiment

The experiment generated from the OpenQASM program.

exp_from_qasm_list(programs, qubits, gate_store, inputs=None, externs=None, count=1, averaging_mode=AveragingMode.CYCLIC, acquisition_type=AcquisitionType.INTEGRATION, reset_oscillator_phase=False, repetition_time=0.001, batch_execution_mode='pipeline', do_reset=False, add_measurement=True, pipeline_chunk_count=None)

Deprecated in version 2.43.0

Use OpenQASMTranspiler instead.

Process a list of openQASM programs into a single LabOne Q experiment that executes the QASM snippets sequentially.

At this time, the QASM programs should not include any measurements. By default, we automatically append a measurement of all qubits to the end of each program. This behavior may be changed by specifying add_measurement=False.

The measurement results for each qubit are stored in a handle named f'meas{qasm_qubit_name}' where qasm_qubit_name is the key specified for the qubit in the qubits parameter.

Optionally, a reset operation on all qubits is prepended to each program. The duration between the reset and the final readout is fixed and must be specified as repetition_time. It must be chosen large enough to accommodate the longest of the programs. The repetition_time parameter is also required if the resets are disabled. In a future version we hope to make an explicit repetition_time optional.

For the measurement we require the gate store to be loaded with a measurement gate. Similarly, the optional reset requires a reset gate to be available.

Note that using set_frequency or specifying the acquisition type via a pragma zi.acquisition_type statement within an OpenQASM program is not supported by exp_from_qasm_list. It will log a warning if these are encountered.

Parameters:

Name Type Description Default
programs list[str]

the list of the QASM snippets

required
qubits dict[str, QuantumElement]

Map from OpenQASM qubit names to LabOne Q DSL Qubit objects

required
gate_store GateStore

Map from OpenQASM gate names to LabOne Q DSL Gate objects

required
inputs dict[str, Any] | None

Inputs to the OpenQASM program.

None
externs dict[str, Callable[..., ExternResult | Any]] | None

Extern functions for the OpenQASM program.

None
count int

The number of acquire iterations.

1
averaging_mode AveragingMode

The mode of how to average the acquired data.

CYCLIC
acquisition_type AcquisitionType

The type of acquisition to perform.

INTEGRATION
reset_oscillator_phase bool

When true, reset all oscillators at the start of every acquisition loop iteration.

False
repetition_time float

The length that any single program is padded to.

0.001
batch_execution_mode str

The execution mode for the sequence of programs. Can be any of the following:

  • "nt": The individual programs are dispatched by software.
  • "pipeline": The individual programs are dispatched by the sequence pipeliner.
  • "rt": All the programs are combined into a single real-time program.

"rt" offers the fastest execution, but is limited by device memory. In comparison, "pipeline" introduces non-deterministic delays between programs of up to a few 100 microseconds. "nt" is the slowest.

'pipeline'
do_reset bool

If True, an active reset operation is added to the beginning of each program.

False
add_measurement bool

If True, add measurement at the end for all qubits used.

True
pipeline_chunk_count int | None

The number of pipeline chunks to divide the experiment into.

The default chunk count is equal to the number of programs, so that there is one program per pipeliner chunk. Future versions of LabOne Q may use a more sophisticated default based on the program sizes.

Currently the number of programs must be a multiple of the chunk count so that there are the same number of programs in each chunk. This limitation will be removed in a future release of LabOne Q.

A ValueError is raised if the number of programs is not a multiple of the chunk count.

None

Returns:

Type Description
Experiment

The experiment generated from the OpenQASM programs.