Cross-resonance gate tuneup¶
In this reference notebook, you'll learn how to use LabOne Q's logical signals lines to perform simple tuneup of a cross-resonance two qubit gate. This functionality requires an SHFSG or SHFQC and relies on using the command table instead of playWave
commands.
0. General Imports and Definitions¶
0.1 Python Imports¶
In [ ]:
Copied!
# LabOne Q:
from laboneq.simple import *
# Helpers:
from laboneq.contrib.example_helpers.plotting.plot_helpers import plot_simulation
from laboneq.contrib.example_helpers.generate_example_datastore import (
generate_example_datastore,
get_first_named_entry,
)
# LabOne Q:
from laboneq.simple import *
# Helpers:
from laboneq.contrib.example_helpers.plotting.plot_helpers import plot_simulation
from laboneq.contrib.example_helpers.generate_example_datastore import (
generate_example_datastore,
get_first_named_entry,
)
In [ ]:
Copied!
# Build an in-memory data store with device setup and qubit parameters for the
# example notebooks
setup_db = generate_example_datastore(in_memory=True)
# Build an in-memory data store with device setup and qubit parameters for the
# example notebooks
setup_db = generate_example_datastore(in_memory=True)
1. Define Device Setup and Calibration¶
1.1 Define a Device Setup¶
We'll load a descriptor file to define our device setup and logical signal lines. We could, instead, explicitly include the descriptor here as a string and then use DeviceSetup.from_descriptor()
below. Choose the best method that works for you!
In [ ]:
Copied!
# load a calibrated device setup from the dummy database
device_setup = get_first_named_entry(db=setup_db, name="6_qubit_setup_shfqc_calibrated")
use_emulation = True
# load a calibrated device setup from the dummy database
device_setup = get_first_named_entry(db=setup_db, name="6_qubit_setup_shfqc_calibrated")
use_emulation = True
2. CR Gate Tune-up¶
Sweep the pulse length of a qubit drive pulse at the difference frequency of two qubits to determine the ideal parameters for a CR gate.
2.1 Define the Experiment¶
In [ ]:
Copied!
## define pulses
# qubit pi pulse for first excited state
x90 = pulse_library.drag(uid="x90", length=11e-9, amplitude=0.5, sigma=0.3, beta=0.2)
# pulse to be calibrated for CR gate - length will be swept
cr_pulse = pulse_library.gaussian(
uid="cr_pulse", length=32e-9, amplitude=0.7, sigma=0.3
)
# readout drive pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=400e-9, amplitude=0.2)
# readout integration weights
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=400e-9, amplitude=0.8
)
## define pulses
# qubit pi pulse for first excited state
x90 = pulse_library.drag(uid="x90", length=11e-9, amplitude=0.5, sigma=0.3, beta=0.2)
# pulse to be calibrated for CR gate - length will be swept
cr_pulse = pulse_library.gaussian(
uid="cr_pulse", length=32e-9, amplitude=0.7, sigma=0.3
)
# readout drive pulse
readout_pulse = pulse_library.const(uid="readout_pulse", length=400e-9, amplitude=0.2)
# readout integration weights
readout_weighting_function = pulse_library.const(
uid="readout_weighting_function", length=400e-9, amplitude=0.8
)
In [ ]:
Copied!
# set up sweep parameter - drive pulse length
start = 32e-9
stop = 640e-9
count = 20
length_sweep = LinearSweepParameter(uid="length", start=start, stop=stop, count=count)
# number of averages
average_exponent = 10 # used for 2^n averages, n=average_exponent, maximum: n = 17
# Create Experiment
exp_cr_gate = Experiment(
uid="cr Tuneup",
signals=[
ExperimentSignal("drive_0"),
ExperimentSignal("drive_1"),
ExperimentSignal("drive_cr"),
ExperimentSignal("measure_0"),
ExperimentSignal("acquire_0"),
ExperimentSignal("measure_1"),
ExperimentSignal("acquire_1"),
],
)
## experimental pulse sequence
# outer loop - real-time, cyclic averaging in standard integration mode
with exp_cr_gate.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
):
# inner loop - real-time sweep of qubit drive pulse amplitude
with exp_cr_gate.sweep(uid="sweep", parameter=length_sweep):
with exp_cr_gate.section(
uid="drive", alignment=SectionAlignment.RIGHT, length=stop + 2 * x90.length
):
# qubit excitation - assume something is done to both qubits
with exp_cr_gate.section(
uid="qubit_excitation",
on_system_grid=True,
alignment=SectionAlignment.RIGHT,
):
exp_cr_gate.play(signal="drive_0", pulse=x90)
exp_cr_gate.play(signal="drive_1", pulse=x90, amplitude=0.4)
# play CR pulse and sweep its length
with exp_cr_gate.section(
uid="cr_gate",
play_after="qubit_excitation",
on_system_grid=True,
alignment=SectionAlignment.LEFT,
):
exp_cr_gate.play(signal="drive_cr", pulse=cr_pulse, length=length_sweep)
# qubit readout pulses and data acquisition
with exp_cr_gate.section(uid="qubit_readout", play_after="drive"):
# play readout pulse
exp_cr_gate.play(signal="measure_0", pulse=readout_pulse)
exp_cr_gate.play(signal="measure_1", pulse=readout_pulse)
# signal data acquisition
exp_cr_gate.acquire(
signal="acquire_0",
handle="ac_0",
kernel=readout_weighting_function,
)
# signal data acquisition
exp_cr_gate.acquire(
signal="acquire_1",
handle="ac_1",
kernel=readout_weighting_function,
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_cr_gate.section(uid="relax", play_after="qubit_readout"):
exp_cr_gate.delay(signal="measure_0", time=100e-9)
# set up sweep parameter - drive pulse length
start = 32e-9
stop = 640e-9
count = 20
length_sweep = LinearSweepParameter(uid="length", start=start, stop=stop, count=count)
# number of averages
average_exponent = 10 # used for 2^n averages, n=average_exponent, maximum: n = 17
# Create Experiment
exp_cr_gate = Experiment(
uid="cr Tuneup",
signals=[
ExperimentSignal("drive_0"),
ExperimentSignal("drive_1"),
ExperimentSignal("drive_cr"),
ExperimentSignal("measure_0"),
ExperimentSignal("acquire_0"),
ExperimentSignal("measure_1"),
ExperimentSignal("acquire_1"),
],
)
## experimental pulse sequence
# outer loop - real-time, cyclic averaging in standard integration mode
with exp_cr_gate.acquire_loop_rt(
uid="shots",
count=pow(2, average_exponent),
averaging_mode=AveragingMode.CYCLIC,
acquisition_type=AcquisitionType.INTEGRATION,
):
# inner loop - real-time sweep of qubit drive pulse amplitude
with exp_cr_gate.sweep(uid="sweep", parameter=length_sweep):
with exp_cr_gate.section(
uid="drive", alignment=SectionAlignment.RIGHT, length=stop + 2 * x90.length
):
# qubit excitation - assume something is done to both qubits
with exp_cr_gate.section(
uid="qubit_excitation",
on_system_grid=True,
alignment=SectionAlignment.RIGHT,
):
exp_cr_gate.play(signal="drive_0", pulse=x90)
exp_cr_gate.play(signal="drive_1", pulse=x90, amplitude=0.4)
# play CR pulse and sweep its length
with exp_cr_gate.section(
uid="cr_gate",
play_after="qubit_excitation",
on_system_grid=True,
alignment=SectionAlignment.LEFT,
):
exp_cr_gate.play(signal="drive_cr", pulse=cr_pulse, length=length_sweep)
# qubit readout pulses and data acquisition
with exp_cr_gate.section(uid="qubit_readout", play_after="drive"):
# play readout pulse
exp_cr_gate.play(signal="measure_0", pulse=readout_pulse)
exp_cr_gate.play(signal="measure_1", pulse=readout_pulse)
# signal data acquisition
exp_cr_gate.acquire(
signal="acquire_0",
handle="ac_0",
kernel=readout_weighting_function,
)
# signal data acquisition
exp_cr_gate.acquire(
signal="acquire_1",
handle="ac_1",
kernel=readout_weighting_function,
)
# relax time after readout - for signal processing and qubit relaxation to ground state
with exp_cr_gate.section(uid="relax", play_after="qubit_readout"):
exp_cr_gate.delay(signal="measure_0", time=100e-9)
In [ ]:
Copied!
# define the signal map - playing cr gate pulse on qubit drive 0
map_q0 = {
"drive_0": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"drive_1": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"drive_cr": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"measure_0": device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
],
"acquire_0": device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
],
"measure_1": device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
],
"acquire_1": device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
],
}
# .. and on qubit drive 1
map_q1 = {
"drive_0": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"drive_1": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"drive_cr": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"measure_0": device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
],
"acquire_0": device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
],
"measure_1": device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
],
"acquire_1": device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
],
}
# define the signal map - playing cr gate pulse on qubit drive 0
map_q0 = {
"drive_0": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"drive_1": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"drive_cr": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"measure_0": device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
],
"acquire_0": device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
],
"measure_1": device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
],
"acquire_1": device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
],
}
# .. and on qubit drive 1
map_q1 = {
"drive_0": device_setup.logical_signal_groups["q0"].logical_signals["drive_line"],
"drive_1": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"drive_cr": device_setup.logical_signal_groups["q1"].logical_signals["drive_line"],
"measure_0": device_setup.logical_signal_groups["q0"].logical_signals[
"measure_line"
],
"acquire_0": device_setup.logical_signal_groups["q0"].logical_signals[
"acquire_line"
],
"measure_1": device_setup.logical_signal_groups["q1"].logical_signals[
"measure_line"
],
"acquire_1": device_setup.logical_signal_groups["q1"].logical_signals[
"acquire_line"
],
}
2.2 Run the Experiment and Plot the Pulse Sequence¶
In [ ]:
Copied!
# set signal map to qubit 0
exp_cr_gate.set_signal_map(map_q1)
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run experiment on qubit 0
compiled_exp_cr_gate = session.compile(exp_cr_gate)
cr_gate_results = session.run(compiled_exp_cr_gate)
# set signal map to qubit 0
exp_cr_gate.set_signal_map(map_q1)
# create and connect to session
session = Session(device_setup=device_setup)
session.connect(do_emulation=use_emulation)
# run experiment on qubit 0
compiled_exp_cr_gate = session.compile(exp_cr_gate)
cr_gate_results = session.run(compiled_exp_cr_gate)
In [ ]:
Copied!
# Plot simulated output signals
plot_simulation(compiled_exp_cr_gate, 0, 10e-6)
# Plot simulated output signals
plot_simulation(compiled_exp_cr_gate, 0, 10e-6)
In [ ]:
Copied!