Dynamical Decoupling

This document provides overview, reference and demonstration of the Dynamical Decoupling (DD) capability.

DD is a server-side error suppresion capability, available on System Model H2. DD suppress coherent memory errors by adding pulses to change the accumulated sign. Slow varying qubit frequency offsets magnetic fields, reference clocks and finite calibration precision. The typical frequency offset is approximately 75 mHz (3.7e-4 error at 100 ms), but this can very during machine operation. This is consistent with \(\frac{1}{e}\) contrast decay of 3 seconds in Ramsey decay experiments. In Quantum Error Correction (QEC) circuits qubits idle for multiple \(\frac{1}{e}\) time periods.

API options flow for DD

The API options for DD, such as combine_sq, are only used if apply_DD is True.

The following table specifies the API options for DD. These API options must be specified upon job submission to H2.

Note

Quantinuum recommends that users set DD_threshold_times to 0.03 to ensure DD pulses are added to regions of the circuit that would otherwise contribute to coherent memory error accumulation.

Option

Type

Default Value

Description

apply_DD

Boolean

False

If True, applies dynamical decoupling (DD) pulses with multiple passes for each time in the DD_threshold_times list.

combine_rotates

Boolean

False

If True, combines multiple rotate waveforms to reduce circuit time.

combine_SQ

Boolean

False

If True, attempts to combine DD pulses with existing single-qubit (SQ) pulses.

DD_threshold_times

List[float]

[0.3]

A list of threshold times (in seconds). For each threshold, the compiler tries to opportunistically insert DD pulses for qubits with dwell times longer than the threshold. It is recommended to set DD_threshold_time to 0.03.

For a specified DD_threshold_times, the hardware compiler will search for idle times (times where a qubit receives no operation) that are \(\geq\) DD_threshold_times and find DD pulse locations to decouple the coherent memory error.

DD pulse injection

Opportunistically adding DD pulses if the threshold times (specified in DD_threshold_times) exceeds dwell times.

Code Sample

Program synthesis for Log-depth GHZ state-preparation Circuit.

import numpy as np
from pytket.circuit import Circuit


def logarithmic_ghz_circuit(n_qubits):
    n = n_qubits
    circ = Circuit(n, n)
    # construct GHZ prep circuit, optimized for parallel gates
    circ.H(0)
    for i in range(int(np.ceil(np.log2(n)))):
        for j in range(2**i):
            if j + 2**i < n:
                circ.CX(j, j + 2**i)
    circ.measure_all()
    return circ

circuit = logarithmic_ghz_circuit(16)

Create or retrieve a project, and set the project as the active project in the current python session. A suffix is defined using datetime to ensure all jobs and resources have a unique name within the current active project.

import qnexus as qnx
import datetime

project = qnx.projects.get_or_create("dd_prerelease")
qnx.context.set_active_project(project)

name_suffix = datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S")

Upload circuit to the Nexus database and return a References.

ref_circuit = qnx.circuits.upload(circuit=circuit, name=f"GHZ_circuit_{name_suffix}", description="TKET circuit for GHZ State Preparation")

Specify the Quantinuum provider configuration, and additionally, specify compiler options for DD pulses.

compiler_options = {"apply_DD": True, "DD_threshold_times": [0.03]}
config = qnx.QuantinuumConfig(device_name="H1-Emulator", compiler_options=compiler_options)

The GHZ circuit is compiled with qnx.start_compile_job, which includes optimizing the gates and resynthesizing the circuit to Quantinuum’s native gate set.

ref_compile_job = qnx.start_compile_job(
    programs=[ref_circuit],
    optimisation_level=0,
    backend_config=config,
    name=f"compile-job-{name_suffix}"
)
qnx.jobs.wait_for(ref_compile_job, timeout=10000)
ref_compiled_circuit = qnx.jobs.results(ref_compile_job)[0].get_output()

The execute job will apply the DD compiler options prior to job execution. The DD compiler options inform the compiler that DD pulses should be added opportunistically.

n_shots = 100
ref_execute_job = qnx.start_execute_job(
    programs=[ref_compiled_circuit],
    backend_config=config,
    n_shots=[n_shots],
    name=f"execute-job-{name_suffix}"
)
qnx.jobs.wait_for(ref_execute_job)
ref_result = qnx.jobs.results(ref_execute_job)[0]
result = ref_result.download_result()