# Calibration: Overview and API

This tutorial provides an introductory overview of calibration. By the end, you will understand the high-level calibration process, how to run calibrations through the API, and how to choose which calibration technique to use.

## Setup

try:
import cirq
except ImportError:
print("installing cirq...")
!pip install cirq --pre --quiet
print("installed cirq.")

import numpy as np

import cirq


No project_id provided and environment variable GOOGLE_CLOUD_PROJECT not set.
Using a noisy simulator.


## Overview

Floquet and XEB calibration are tools to characterize a family of gates including $\sqrt{\text{iSWAP} }$ gates on a particular processor and compensate for errors. The family of gates is represented by the cirq.PhasedFSimGate, a two-qubit gate with five angles $\theta$, $\zeta$, $\chi$, $\gamma$, $\phi$ given by the following unitary matrix:

$$U(\theta, \zeta, \chi, \gamma, \phi) := \left[ \begin{matrix} 1 & 0 & 0 & 0 \\ 0 & \exp(-i \gamma - i \zeta) \cos( \theta ) & -i \exp(-i \gamma + i \chi) \sin( \theta ) & 0 \\ 0 & -i \exp(-i \gamma - i \chi) \sin( \theta ) & \exp(-i \gamma + i \zeta) \cos( \theta) & 0 \\ 0 & 0 & 0 & \exp(-2 i \gamma -i \phi ) \end{matrix} \right]$$

The $\sqrt{\text{iSWAP} }$ gate corresponds to angles $\theta=-\pi / 4$ and $\zeta = \chi = \gamma = \phi = 0$.

Characterization is done by the Quantum Engine and compensation (currently the insertion of $Z$ gates around $\sqrt{\text{iSWAP} }$ gates) is completely client-side with the help of Cirq utilities. At the highest level, each calibration tool inputs one or more quantum circuits of interest as well as a processor to run on, and outputs the calibrated circuit(s) for this processor.

Both calibrations are primarily focused on decreasing the effects of two sources of coherent errors: calibration drifts and cross-talk errors. These errors are not uniform across the chip and vary in magnitude between qubits and device calibrations. The circuit-specific calibrations should be used in situations when achieving the best performance is more important than using extra time on the device for the characterizations.

## Calibration techniques and API

To run calibration, define your circuit or circuits below. For sake of example we use a simple circuit with a single $\sqrt{\text{iSWAP} }$ gate.

"""Define your circuit(s) here."""
qubits = cg.line_on_device(device, length=2)
circuit = cirq.Circuit(cirq.ISWAP.on(*qubits) ** 0.5)

print("Example circuit:", circuit, sep="\n\n")

Example circuit:

(0, 5): ───iSwap───────
│
(0, 6): ───iSwap^0.5───


### Floquet calibration

Floquet calibration returns fast, accurate estimates for every angle of the cirq.PhasedFSimGate except $\chi$ (chi).

The first step to Floquet calibration is defining the angles to characterize.

# Define calibration options.
floquet_options = cg.FloquetPhasedFSimCalibrationOptions(
characterize_theta=True,
characterize_zeta=True,
characterize_chi=False,
characterize_gamma=True,
characterize_phi=True,
)


Next, use these options to get characterization requests - i.e., cirq.Moments to characterize on the Quantum Engine - then characterize them.

# Get characterization requests.
floquet_characterization_requests = cg.prepare_characterization_for_operations(
circuit, options=floquet_options
)

# Characterize the requests on the engine.
floquet_characterizations = cg.run_calibrations(
floquet_characterization_requests, sampler
)


The last step is to compensate for offsets using the cirq_google.make_zeta_chi_gamma_compensation_for_moments function.

# Compensate your circuit based on the characterizations.
floquet_calibrated_circuit = cg.make_zeta_chi_gamma_compensation_for_moments(
circuit, floquet_characterizations
).circuit

print("Floquet calibrated circuit:", floquet_calibrated_circuit, sep="\n\n")

Floquet calibrated circuit:

(0, 5): ───Rz(-0.515π)───FSim(0.25π, 0)───Rz(0.485π)────
│
(0, 6): ───Rz(0.509π)────FSim(0.25π, 0)───Rz(-0.491π)───


Note the addition of cirq.Rz gates to compensate for characterized errors. This calibrated circuit can now be run on the processor.

### XEB calibration

XEB calibration works by executing a library of random circuits both on a noiseless simulator and on a noisy processor, then comparing results. In principle it can characterize any two-qubit gate, but compensation is currently only for $\zeta$, $\chi$, and $\gamma$. For more details about how XEB calibration works, see the Parallel XEB tutorial.

Like Floquet calibration, the first step to using XEB calibration is defining options. Unlike Floquet calibration, XEB calibration requires significant classical processing to characterize angles. In addition to the angles to characterize, we also need to define the cycle_depths of the random circuits. The number of processes n_processes is a parallelization option for the classical processing.

# Define calibration options.
cycle_depths=(5, 25, 50, 100)

xeb_options = cg.LocalXEBPhasedFSimCalibrationOptions(
cycle_depths=cycle_depths,
n_processes=1,
# Note that all angles below are set to True by default.
fsim_options=cirq.experiments.XEBPhasedFSimCharacterizationOptions(
characterize_theta=False,
characterize_zeta=True,
characterize_chi=True,
characterize_gamma=True,
characterize_phi=False,
),
)


The remaining steps are identical to Floquet calibration: first getting characterization requests then characterizing them on the engine.

# Get characterization requests.
xeb_characterization_requests = cg.prepare_characterization_for_operations(
circuit, options=xeb_options
)

# Characterize the requests on the engine.
xeb_characterizations = cg.run_calibrations(
xeb_characterization_requests, sampler
)

100%|██████████| 45/45 [00:05<00:00,  7.95it/s]


Making compensations is also identical to the Floquet calibration example.

xeb_calibrated_circuit = cg.make_zeta_chi_gamma_compensation_for_moments(
circuit, xeb_characterizations,
).circuit

print("XEB calibrated circuit:", xeb_calibrated_circuit, sep="\n\n")

XEB calibrated circuit:

(0, 5): ───Rz(-0.53π)───FSim(0.25π, 0)───Rz(0.478π)────
│
(0, 6): ───Rz(0.519π)───FSim(0.25π, 0)───Rz(-0.489π)───


Again note the addition of cirq.Rz gates to compensate for errors. This calibrated circuit can now be run on the processor.

## Which calibration should I use?

This question is very dependent on the particular type of circuit, but some guidelines exist. XEB calibration is generally more applicable to circuits that alternate single-qubit and two-qubit layers due to the similarity between the random XEB circuits and executed circuits. Floquet calibration may be more applicable to circuits with two-qubit gates and $Z$ gates only.

## Summary and notes

Floquet calibration XEB calibration
FSim angles characterized 4 / 5 (all but χ) 5 / 5
FSim angles compensated 2 / 5 (ζ and γ) 3 / 5 (ζ, χ, and γ)
Relative runtime 1 ~10x Floquet calibration runtime
Robust to SPAM errors? Yes Yes
Experiments used in Fermi-Hubbard OTOC
• The ζ, χ and γ parameters of the cirq.PhasedFSimGate are subject to drifts that range in frequency from seconds to hours.
• Neither calibration technique attempts to correct the misaligned iSWAP rotation or the additional two-qubit phase. This is a non-trivial task and we do currently have simple tools to achieve this. It is up to the user to correct for these in experiments as best as possible.
• Floquet calibration does not yet support microwave gates.

## Next steps

Try running Floquet and/or XEB calibration on your circuit(s). See the following tutorials for detailed examples and benchmarks.

[{ "type": "thumb-down", "id": "missingTheInformationINeed", "label":"Missing the information I need" },{ "type": "thumb-down", "id": "tooComplicatedTooManySteps", "label":"Too complicated / too many steps" },{ "type": "thumb-down", "id": "outOfDate", "label":"Out of date" },{ "type": "thumb-down", "id": "samplesCodeIssue", "label":"Samples / code issue" },{ "type": "thumb-down", "id": "otherDown", "label":"Other" }]
[{ "type": "thumb-up", "id": "easyToUnderstand", "label":"Easy to understand" },{ "type": "thumb-up", "id": "solvedMyProblem", "label":"Solved my problem" },{ "type": "thumb-up", "id": "otherUp", "label":"Other" }]