Program representations
These guides gives an overview of how programs are structured in the Keysight’s Quantum Control System framework.

The figure above depicts the flow of information from a user to a quantum processing
unit. Users specify the program that they want to run via Keysight’s Quantum Control System and then use a
use a Linker
to translate it into
a form that the control hardware can use. The control hardware then acts on the quantum
processing unit according to the (translated) instructions from the user and sends
information back up the stack. Keysight’s Quantum Control System then translates this information back to a form
that is user-friendly.
Targets
Targets
are the objects that operations in a
program act on. Targets
can be
specified as qudits via the Qudits
class or as
virtual channels via the Channels
class.
Mappings between qudits and hardware channels for a given device configuration can be
saved and applied using Linker
objects. See
Introduction to linkers for more information.
Targets are constructed using a set of unique labels and a name.
import keysight.qcs as qcs
# create a Channels object with three labels
channels = qcs.Channels(range(3), "my_channels")
# this object has length 3
assert len(channels) == 3
assert channels.labels == (0, 1, 2)
# channels can be sliced
assert channels[1:].labels == (1, 2)
Qudits
can be constructed in the same fashion, but
can take an optional dim
parameter to specify the qudit dimension.
# create a register of three qubits (dim=2)
qubits = qcs.Qudits(range(3), "my qubits", dim=2)
assert len(qubits) == 3
# dimension is 2
assert qubits.dim == 2
Pulse shapes and acquisitions

While information always enters the workflow in the same way, some users prefer to
design programs with the hardware implementation in mind, i.e. programming at the
abstraction layer closest to the hardware. These users can specify programs in terms
of HardwareOperation
s such as
RFWaveform
s on AWG channels and
Acquisition
s on digitizer channels. See
Waveform representations for details on the available built-in functionality for
specifying pulses.
Gates, parametric gates and measurements

Other users might have a more abstract conceptualization of the program they want to
run. For these users, operations can also be specified in terms of
Gate
s, and
Measure
instructions that act on
Qudits
, as in a circuit diagram. Arbitrary gates
can be compiled into the native gateset of the system, typically using
ParametricGate
s to allow for arbitrary rotations.
Abstraction layers and types of programs
A Program
allows for mixed-layer
programming. That is, instructions can be written using any combination of the
above operations and targets. A circuit-level or mixed-level program can be compiled
into a pulse-level Program
using
BaseLinker
s.
Guides
The following two tutorials step through how to construct programs at different layers of abstraction and how variables can be used to customize how programs are run.

Program Basics
This guide demonstrates how Program
s are
constructed and how the timing between operations can be customized. It also
shows an example of a time-agnostic quantum circuit program.

Controlling execution flow
This guide demonstrates how
ConditionalOperation
s can be used for
real-time decision logic inside a program for applications such as qubit reset.