Skip to content

Cross Resonance calibration - #1414

Merged
lballerio merged 87 commits into
mainfrom
cancellation_pulse
Jun 22, 2026
Merged

Cross Resonance calibration#1414
lballerio merged 87 commits into
mainfrom
cancellation_pulse

Conversation

@lballerio

@lballerio lballerio commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

This PR contains the whole calibration of the Cross Resonance gate as described by the CR IBM paper.

The main method exploited is the so called Hamltonian Tomography, defined as the process of inferring a quantum system’s Hamiltonian from observed dynamics. The algorithm is quite simple: after preparing known states, we let them evolve, then measure outcomes, and fit a model to estimate the terms in the theoretical Hamiltonian model.
This PR gives the freedom of the user to calibrate the CR in different levels of accuracy:

  • Simple CR calibration: by simply sweeping over time (or control qubit amplitude) we determine the pulse parameters; the sequence is composed by simply one pulse applied on the control qubit with the frequency of the target one.

  • Echo CR sequence calibration: simply in this case the pulse sequence is more convoluted, since it consists on two CR pulses out-of-phase interleaved by two $\pi$-pulses on the control qubit; this pulse sequence improves the performances of the whole gate since it refocuses specific sources of noise.

  • CR with Cancellation calibration: we add to the echo sequence two out-of phase pulses to the target qubit which are synched to the CR pulses; this calibration refocuses the remaining sources of noise, but additional parameters (i.e. cancellation and CR pulses phases and cancellation amplitude) have to be calibrated.

Here is a scheme of the different calibrations:

  • the simple CR calibration is simply the first green pulse
  • the echo calibration is the sum of the green and the blue pulses
  • the complete calibration is the whole picture
Screenshot From 2026-03-31 17-11-40

this is a followup of PR #1131.
In addition, this PR requires a new emulator version from Qibolab #1416, Qibolab #1412 and Qibolab #1401.

Some suggestions for eventual improvements:

Comment thread src/qibocal/result.py Outdated
Comment thread src/qibocal/update.py Outdated
@lballerio

Copy link
Copy Markdown
Contributor Author

@alecandido in this PR I think we can delete the following files, which were inherited from #1131:

  • src/qibocal/protocols/two_qubit_interaction/cross_resonance/amplitude.py
  • src/qibocal/protocols/two_qubit_interaction/cross_resonance/length.py

then maybe we can move all files from src/qibocal/protocols/two_qubit_interaction/cross_resonance/hamiltonian_tomography in the upstream folder, and eventually merge the two utils.py files

@alecandido

Copy link
Copy Markdown
Member

What were the two files doing? And where is it done now?

@lballerio

Copy link
Copy Markdown
Contributor Author

What were the two files doing? And where is it done now?

They were simply doing the CR calibration by either sweeping CR pulse duration or CR amplitude, but there was not implemented Hamiltonian Tomography, simply evaluating the 'distance' of the two trajectories (i.e. when control in 0 or in 1) only along Z.
For me these are deprecated, but I'll leave you the final decision.

@alecandido

Copy link
Copy Markdown
Member

For me these are deprecated, but I'll leave you the final decision.

Ok, I agree. We definitely have a better option.

It's true that the better option requires some more measurements, but it is still always affordable, and it's a fair price to pay for the accuracy.

@lballerio
lballerio force-pushed the cancellation_pulse branch 2 times, most recently from def830e to 9cdb9d3 Compare April 3, 2026 15:31
@alecandido alecandido linked an issue Apr 4, 2026 that may be closed by this pull request
@codecov

codecov Bot commented Apr 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.07516% with 325 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.02%. Comparing base (73806ae) to head (7f39c41).
⚠️ Report is 46 commits behind head on main.

Files with missing lines Patch % Lines
...nteraction/cross_resonance/ham_tomography_utils.py 44.40% 159 Missing ⚠️
..._interaction/cross_resonance/cancellation_phase.py 39.51% 75 Missing ⚠️
...eraction/cross_resonance/cancellation_amplitude.py 40.33% 71 Missing ⚠️
...ols/two_qubit_interaction/cross_resonance/utils.py 88.97% 14 Missing ⚠️
src/qibocal/protocols/utils.py 94.11% 3 Missing ⚠️
...s/two_qubit_interaction/cross_resonance/fitting.py 88.88% 2 Missing ⚠️
...t_interaction/cross_resonance/cr_parent_classes.py 98.14% 1 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1414      +/-   ##
==========================================
- Coverage   94.41%   92.02%   -2.40%     
==========================================
  Files         136      145       +9     
  Lines       10636    11569     +933     
==========================================
+ Hits        10042    10646     +604     
- Misses        594      923     +329     
Flag Coverage Δ
unittests 92.02% <66.07%> (-2.40%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/qibocal/auto/transpile.py 91.96% <100.00%> (ø)
src/qibocal/protocols/rabi/amplitude.py 96.87% <100.00%> (ø)
src/qibocal/protocols/rabi/utils.py 100.00% <100.00%> (ø)
src/qibocal/protocols/ramsey/processing.py 100.00% <100.00%> (ø)
...ibocal/protocols/two_qubit_interaction/__init__.py 100.00% <100.00%> (ø)
.../two_qubit_interaction/cross_resonance/__init__.py 100.00% <100.00%> (ø)
...ction/cross_resonance/cross_resonance_amplitude.py 100.00% <100.00%> (ø)
...eraction/cross_resonance/cross_resonance_length.py 100.00% <100.00%> (ø)
src/qibocal/result.py 85.18% <100.00%> (ø)
src/qibocal/update.py 90.09% <100.00%> (+0.46%) ⬆️
... and 7 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@lballerio
lballerio marked this pull request as ready for review April 6, 2026 07:58
@lballerio
lballerio requested review from a team April 6, 2026 07:58
Comment thread src/qibocal/protocols/utils.py Outdated
Comment thread src/qibocal/protocols/utils.py Outdated

@alecandido alecandido left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very first batch.

Still missing all the protocols and Quinn-Fernandes

Comment thread src/qibocal/update.py Outdated
Comment thread src/qibocal/result.py Outdated
Comment thread src/qibocal/result.py Outdated
Comment thread doc/source/protocols/cross_resonance/amplitude.png
Comment thread doc/source/protocols/cross_resonance/length.png

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given this is more a "protocol suite" than a single protocol, we should put some care in documenting it properly, to avoid confusion about the roles of the various protocols.

In this sense, this page is quite fundamental.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I'll keep doc updating as last fix.

Comment on lines +44 to +92
Sweeping the duration of the CR pulse
-------------------------------------

In a first experiment we can sweep the duration of the CR pulse and measure both the
target and control qubit. The measurement is performed while preparing the control
qubit in state :math:`\ket{0}` and :math:`\ket{1}`.

Parameters
^^^^^^^^^^

.. autoclass:: qibocal.protocols.two_qubit_interaction.cross_resonance.length.CrossResonanceLengthParameters
:noindex:

Example
^^^^^^^

A possible runcard to launch the experiment could be the following:

.. code-block:: yaml

- id: CR length
operation: cross_resonance_length
parameters:
targets: [[0,1]]
pulse_duration_start: 10
pulse_duration_end: 200
pulse_duration_step: 10
flux_pulse_amplitude: 0.1
nshots: 2000
relaxation_time: 50000


The expected output is the following:

.. image:: length.png

Post-processing
^^^^^^^^^^^^^^^

The probability of the target qubit is fitted in both cases to a dumped cosine functions.
It is possible to extract the effective coupling as

.. math::

\text{J}_\text{eff}/ 2 \pi = \frac{f^{\pi}_\text{Rabi} - f_\text{Rabi}}{2}


where :math:`f^{\pi}_\text{Rabi}` and :math:`f_\text{Rabi}` are the frequencies of the
fitted Rabi oscillations on the target qubit.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This protocol does not exist any longer (to the best of my knowledge) since it has been replaced by hamiltonian_tomography_cr_length (unless it is cr_crosstalk_length, I'm still confused about that).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually there was already a first implementation of the hamiltonian tomography, but yeah we are no longer relying on that. I think documentation will be the last thing I'll fix before merging.

Comment on lines +94 to +133
Sweeping amplitude of the CR pulse
----------------------------------

Similarly it is possible to sweep the amplitude of the CR pulse and measure both the
target and control qubit.


Parameters
^^^^^^^^^^

.. autoclass:: qibocal.protocols.two_qubit_interaction.cross_resonance.length.CrossResonanceLengthParameters
:noindex:

Example
^^^^^^^

A possible runcard to launch the experiment could be the following:

.. code-block:: yaml

- id: CR amplitude
operation: cross_resonance_amplitude
parameters:
targets: [[0,1]]
max_amp: 0.05
min_amp: 0.01
step_amp: 0.005
pulse_duration: 100
nshots: 2000
relaxation_time: 50000


The expected output is the following:

.. image:: amplitude.png

Post-processing
^^^^^^^^^^^^^^^

The probability of the target qubit is fitted in both cases to a cosine function.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

Comment on lines +9 to +12
"hamiltonian_tomography_cr_amplitude",
"hamiltonian_tomography_cr_length",
"hamiltonian_tomography_canc_phase",
"hamiltonian_tomography_canc_amplitude",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we decide to only provide the Hamiltonian tomography variant of these protocols, prepending them by hamiltonian_tomography_ is just redundant.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moreover, we may consider to disable the X and Y components in the basic amplitude and length, for a faster calibration (not sure if useful at any time). However, it may still be more convenient to have them as flags limiting the full protocol (seen as a performance tradeoff), rather than fully separate protocols.

Even if agreed, this would be just a performance improvement, and it should be addressed in a separate PR (in case, let's just open an issue).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do only Z we cannot then tune the cancellation pulse, then we are essentially doing the Cross Rabi experiment.
We could create a wrapper protocol calling the general rabi protocols.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, you're right. It would be just cross-Rabi, but a conditional one, i.e. with the extra feature of toggling the qubit related to the drive channel, producing two series of data.

So, it is somewhere in between cross-Rabi and an actual CR

Comment on lines +165 to +180
.. code-block:: yaml

- id: Hamiltonian tomography CR
operation: cross_resonance_amplitude
parameters:
targets: [[0,1]]
nshots: 2000
pulse_amplitude: 0.1
pulse_duration_end: 400
pulse_duration_start: 10
pulse_duration_step: 20


The expected output is the following:

.. image:: tomography_length.png

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is definitely inconsistent. If nothing else, at least the operation: key

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is it inconsistent?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe inconsistent was misleading, as a word. Let's say outdated

@alecandido alecandido left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still missing 5 protocols and 3 utils files.

Not even sure why we have 5 protocols, since I only expected 4 (amplitude, length, cancellation phase, cancellation amplitude). But I already wrote this somewhere else, and I will eventually figure out what are the off_res* ones

Comment thread src/qibocal/protocols/rabi/utils.py Outdated

pi_pulse_parameter = popt[2] / 2 * period_correction_factor(phase=popt[3])
return popt, perr, pi_pulse_parameter
return popt.tolist(), perr.tolist(), pi_pulse_parameter

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

popt seems to be a list if coming from the if branch. In which case, it would raise an error for .tolist(). The LSP should tell you about this

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're right, silly error

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw do you know why perr is manipulated only for signal==False?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be fair, that's a good point. It doesn't seem meaningful, since we want to extract the variances.

However, even that is wrong: we care about covariances, since we are not just using popt, but we are actually turning it into another popt (which is shadowing, and changing the meaning of the variable - we truly need a different name for the variable assigned with the if: ... else: ... branch). So, we need error propagation, and the distributions of popt are not at all independent.

Right now, perr is just outright wrong

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, so do you have any plan for that?

Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/control_amplitude.py Outdated
Comment on lines +73 to +76
control_phase: float = 0.0
"""Phase of the CR pulse on the control qubit"""
target_phase: float = 0.0
"""Phase of the Cancellation pulse on the target qubit"""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In a sense, better more parameters than less. But... what do we need these for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it depend how do you interpret these package of experiments...
In fact, if we consider them as Hamiltonian Tomography, where then we estimate the contributions of each Hamiltonian term, then we should be as most flexible in the parameters as possible. Otherwise, if we only consider them for calibrating from scratch the CR pulse, then I agree with you and can be deleted, also with target_amplitude I would say.

Or maybe can be used in maintaining the calibration?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's discuss about this

Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/control_amplitude.py Outdated
Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/fitting.py Outdated
Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/fitting.py Outdated
Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/fitting.py Outdated
Comment thread src/qibocal/protocols/two_qubit_interaction/cross_resonance/fitting.py Outdated
lballerio and others added 24 commits June 22, 2026 18:19
…f cancellation amplitude calibration protocol
…g) - succeeding tests plus refactoring of parameters extraction
…older.

Also creating Parent sharedf classed for Data, Results and Parametrers used for each Hamiltonian Tomography experiment.
@lballerio
lballerio force-pushed the cancellation_pulse branch from 7f39c41 to 6319a26 Compare June 22, 2026 15:24
@lballerio
lballerio added this pull request to the merge queue Jun 22, 2026
Merged via the queue into main with commit 135aa58 Jun 22, 2026
37 checks passed
@lballerio
lballerio deleted the cancellation_pulse branch June 22, 2026 15:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Cross Resonance Routine

6 participants