Download

Download this file as Jupyter notebook: parameterized_linker_msmt.ipynb.

Compiling measurements to waveforms and acquisitions

In this guide, we show how to use ParameterizedLinkers to compile measurements to hardware instructions.

Creating the Linker

We first define all the targets in the system, together with the instruction to compile.

[2]:
import keysight.qcs as qcs

# set number of targets
n_targets = 4

# initialize qubit register and virtual channels
qubits = qcs.Qudits(range(n_targets))
readout_channels = qcs.Channels(range(n_targets), "readout_channels")
acquire_channels = qcs.Channels(range(n_targets), "acquire_channels")

# initialize a measurement operation to compile
measure = qcs.Measure()

Next, we define the program specifying the physical implementation of the measurement on hardware.

[3]:
# initialize the replacement program
replacement_program = qcs.Program()

# initialize the frequencies and amplitudes of the readout pulses
# these values will typically be imported from a calibration set
value = [8e9 + 50e6 * n for n in range(n_targets)]
readout_frequencies = qcs.Array("readout_frequencies", value=value, dtype=float)
readout_amplitudes = qcs.Array(
    "readout_amplitudes", value=[0.4] * n_targets, dtype=float
)
readout_plateau_time = qcs.Scalar("readout_plateau_time", value=200e-9, dtype=float)
readout_rise_time = qcs.Scalar("readout_rise_time", value=30e-9, dtype=float)
readout_frequency_detuning = qcs.Scalar(
    "readout_frequency_detuning", value=0, dtype=float
)
readout_phases = qcs.Array("readout_phases", value=[0] * n_targets, dtype=float)
readout_pulse_delay = qcs.Scalar("readout_pulse_delay", value=10e-9, dtype=float)

# initialize readout pulses
# the phases of the pulses are equal to intended axis of rotation
pulse = qcs.RFWaveform(
    duration=2 * readout_rise_time,
    envelope=qcs.GaussianEnvelope(),
    amplitude=readout_amplitudes,
    rf_frequency=readout_frequencies + readout_frequency_detuning,
    instantaneous_phase=readout_phases,
)

delay_pulse = replacement_program.add_waveform(
    qcs.Delay(readout_pulse_delay), readout_channels
)

# add the readout pulses to the readout channels
replacement_program.add_waveform(
    pulse.to_flattop(readout_plateau_time), readout_channels
)

# create the integration filter for the acquisition
integration_envelope = qcs.ConstantEnvelope()
rf_pulse = qcs.RFWaveform(
    500e-9, integration_envelope, 1.0, readout_frequencies + readout_frequency_detuning
)
integration_filter = qcs.IntegrationFilter(rf_pulse)

# create the classifier
iq_ref_pts = qcs.Array("ref_pts", value=[[1 + 1j, 1 - 1j]] * n_targets)
classifiers = [qcs.MinimumDistanceClassifier(iq_ref_pts[qb]) for qb in range(n_targets)]

# specify the offset between AWG and digitizer
acquisition_delay = 10e-9

# add the acquisition concurrent with the readout pulses
replacement_program.add_acquisition(
    integration_filter,
    acquire_channels,
    classifier=classifiers,
    pre_delay=acquisition_delay,
)

replacement_program.draw()
keysight-logo-svg
Program
Program
Duration 510 ns
Layers 1
Targets 8
Repetitions
Layer #0
Layer #0
Duration 510 ns
readout_channels 0
Delay on ('readout_channels', 0)

Parameters
Duration Scalar(name=readout_pulse_delay, value=10 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 0)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.0, end=0.5)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
HOLD
Hold on ('readout_channels', 0)

Parameters
Duration Scalar(name=readout_plateau_time, value=200 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 0)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.5, end=1.0)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
1
Delay on ('readout_channels', 1)

Parameters
Duration Scalar(name=readout_pulse_delay, value=10 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 1)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.0, end=0.5)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
HOLD
Hold on ('readout_channels', 1)

Parameters
Duration Scalar(name=readout_plateau_time, value=200 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 1)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.5, end=1.0)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
2
Delay on ('readout_channels', 2)

Parameters
Duration Scalar(name=readout_pulse_delay, value=10 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 2)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.0, end=0.5)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
HOLD
Hold on ('readout_channels', 2)

Parameters
Duration Scalar(name=readout_plateau_time, value=200 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 2)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.5, end=1.0)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
3
Delay on ('readout_channels', 3)

Parameters
Duration Scalar(name=readout_pulse_delay, value=10 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 3)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.0, end=0.5)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
HOLD
Hold on ('readout_channels', 3)

Parameters
Duration Scalar(name=readout_plateau_time, value=200 ns, dtype=float, unit=s)
RFWaveform on ('readout_channels', 3)

Parameters
Duration Scalar(name=_implicit, value=30 ns, dtype=float, unit=s)
Amplitude Array(name=readout_amplitudes, shape=(4,), dtype=float, unit=none, value=[0.4, 0.4, 0.4, 0.4])
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope MaskEnvelope(base=GaussianEnvelope(2.0), start=0.5, end=1.0)
Instantaneous Phase Array(name=readout_phases, shape=(4,), dtype=float, unit=rad, value=[0 rad, 0 rad, 0 rad, 0 rad])
Post-phase 0 rad
acquire_channels 0
Delay on ('acquire_channels', 0)

Parameters
Duration 10 ns
Acquisition on ('acquire_channels', 0)

Parameters
Duration 500 ns
Integration Filter
RFWaveform

Parameters
Duration 500 ns
Amplitude 1
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope ConstantEnvelope()
Instantaneous Phase 0 rad
Post-phase 0 rad
Classifier Classifier(Array(name=ref_pts, shape=(4, 2), dtype=complex, unit=none))
1
Delay on ('acquire_channels', 1)

Parameters
Duration 10 ns
Acquisition on ('acquire_channels', 1)

Parameters
Duration 500 ns
Integration Filter
RFWaveform

Parameters
Duration 500 ns
Amplitude 1
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope ConstantEnvelope()
Instantaneous Phase 0 rad
Post-phase 0 rad
Classifier Classifier(Array(name=ref_pts, shape=(4, 2), dtype=complex, unit=none))
2
Delay on ('acquire_channels', 2)

Parameters
Duration 10 ns
Acquisition on ('acquire_channels', 2)

Parameters
Duration 500 ns
Integration Filter
RFWaveform

Parameters
Duration 500 ns
Amplitude 1
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope ConstantEnvelope()
Instantaneous Phase 0 rad
Post-phase 0 rad
Classifier Classifier(Array(name=ref_pts, shape=(4, 2), dtype=complex, unit=none))
3
Delay on ('acquire_channels', 3)

Parameters
Duration 10 ns
Acquisition on ('acquire_channels', 3)

Parameters
Duration 500 ns
Integration Filter
RFWaveform

Parameters
Duration 500 ns
Amplitude 1
Frequency Array(name=_implicit, shape=(4,), dtype=float, unit=Hz, value=[8 GHz, 8.05 GHz, 8.1 GHz, 8.15 GHz])
Envelope ConstantEnvelope()
Instantaneous Phase 0 rad
Post-phase 0 rad
Classifier Classifier(Array(name=ref_pts, shape=(4, 2), dtype=complex, unit=none))

We now create a ParameterizedLinker to replace the measurement instruction with replacement_program.

[4]:
# initialize the linker for the measurement instruction
meas_linker = qcs.ParameterizedLinker(measure, qubits, replacement_program)

Using the Linker

We can use meas_linker to replace any measurement in our programs on qubits or on arbitrary subsets of it.

[5]:
# initialize a program that contains a measurement
program = qcs.Program()
program.add_measurement(qubits[[0, 2]])

# apply the linker pass
linker_pass = qcs.LinkerPass(meas_linker)
program_compiled = linker_pass.apply(program)

# apply the sequencer to the ``compiled_program`` and render
program_compiled.render(
    channel_subplots=False,
    lo_frequency=readout_frequencies.value.min() - 20e6,
    sample_rate=qcs.SAMPLE_RATES[qcs.InstrumentEnum.M5300AWG],
)

When using linkers to replace Measures, the measured qudits are mapped to channels. This mapping can be accessed from the qudits() property of the returned program. The corresponding acquisition is added to a list stored in the corresponding key of the channels() property. This allows results of one program to be identified with the results of another.


Download

Download this file as Jupyter notebook: parameterized_linker_msmt.ipynb.

On this page