-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Context-aware dynamical decoupling #12825
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Context-aware dynamical decoupling #12825
Conversation
Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com> Co-authored-by: Ali Javadi <ajavadia@princeton.edu>
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 15410851778Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
done as the functions use data already available in the class-context, so we can avoid redundant passing of variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Julien, overall seems well written and documented. I didn't read the paper so the review is not about the actual algorithmic part of the DD method itself. I suggest getting input from Kevin or Ali if you want another pair of eyes on this aspect.
I've left line comments, most of which are minor but still require addressing.
In terms of performence - do you have a sense about the overhead of the block collection and manipulation (e.g. _collect_adjacenet_delay_blocks
)?
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Cryoris, as you know I have ran this pass and noticed a few painpoints I wanted to point out. In addition to the documentation suggestions, I have noticed that min_joinable_duration
is a key parameter to avoid 1q gate explosion in some circuits, I wonder if you had considered setting it no a non-0 default value?
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another comment, I believe there is a bug in the instruction duration assignation, because the timeline drawer fails after running this pass complaining about missing gate durations:
Traceback (most recent call last):
File "/Users/ept/qiskit_workspace/qiskit/debug_dd.py", line 84, in <module>
timeline_drawer(bound_scheduled_circuit, filename="out.png")
File "/Users/ept/qiskit_workspace/qiskit/qiskit/utils/deprecation.py", line 183, in wrapper
return func(*args, **kwargs)
File "/Users/ept/qiskit_workspace/qiskit/qiskit/utils/deprecation.py", line 183, in wrapper
return func(*args, **kwargs)
File "/Users/ept/qiskit_workspace/qiskit/qiskit/visualization/timeline/interface.py", line 379, in draw
canvas.load_program(program=program)
File "/Users/ept/qiskit_workspace/qiskit/qiskit/visualization/timeline/core.py", line 193, in load_program
for datum in gen(gate_source, formatter=self.formatter):
File "/Users/ept/qiskit_workspace/qiskit/qiskit/visualization/timeline/generators.py", line 158, in gen_sched_gate
if gate.duration > 0:
TypeError: '>' not supported between instances of 'NoneType' and 'int'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine from my side. Please address the remaining comments from @ElePT
#12825 (review) is a very good catch -- the newly added gates that implement the DD sequences didn't have a |
Just so you know I'm working on removing per instruction durations in #13506 so we probably don't need to change this now. It would have been important for 1.3, but in case 2.0 we just making extra work for both of us. |
Hi @Cryoris are you planning to benchmark the new |
…yoris/qiskit-terra into context-aware-dynamical-decoupling
Yep, it's good from my side now 🙂 The number of X gates is rather large though, per design of the algorithm, I think that was just surprising to see. E.g. for an N-local circuit with linear entanglement on |
Overall this looks in good shape to me both from code and testing perspectives. I haven't reviewed the algorithm in depth against the paper, but I ran several examples and the results look OK. Still, I'd like to look into some of the algorithmic aspects a bit more. In the meantime, I have a couple questions and possible suggestions, both not major: The rationale behind the default value for 'cz' is included in the calculation of the 2q gate length variance in |
Re: Re: CZ -- The paper only investigates CX/ECR. CZ would probably require a different spectator qubit handling, but this is not explained in the paper and hence not supported in the code. We can add an argument that allows to turn off the spectator-specific logic for CX/ECR. |
The reason I treated this is as a knob to control the amount of DD is because of this check: if (
node.op.name == "delay"
and not is_after_reset(node)
and self._duration(node, qubit_map) > self._min_joinable_duration
) in |
Fair point, let's rename it 👍🏻 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Cryoris for the patience with the final review. I only have 2 minor docs comments, otherwise this looks very good!
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Show resolved
Hide resolved
qiskit/transpiler/passes/scheduling/padding/context_aware_dynamical_decoupling.py
Outdated
Show resolved
Hide resolved
Thanks Eli! Co-authored-by: Eli Arbel <46826214+eliarbel@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work - good to go! 🚀
* Context aware DD Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com> Co-authored-by: Ali Javadi <ajavadia@princeton.edu> * add reno * fix import * fix test by using GenericBackendV2 * use class method instead of standalones done as the functions use data already available in the class-context, so we can avoid redundant passing of variables * Eli's review comments * Elena's review comments * add details about time units * add gate.durations for inserted sequences * smarter default for min_joinable_durations this needs some benchmarking on real devices * lint + undo unwanted changes * don't use deprecated op.duration * fix tests after merge * handle `dt` none case * Fix tests after min duration default update * rename min_(joinable)_duration * Apply suggestions from code review Thanks Eli! Co-authored-by: Eli Arbel <46826214+eliarbel@users.noreply.github.com> --------- Co-authored-by: Kevin Krsulich <kevin.krsulich@ibm.com> Co-authored-by: Ali Javadi <ajavadia@princeton.edu> Co-authored-by: Eli Arbel <46826214+eliarbel@users.noreply.github.com>
Summary
Implement context-aware dynamical decoupling (DD) from arXiv:2403.06852.
Details and comments
When selecting decoupling sequences for an idle qubit, context-aware DD takes into account what actions are occuring on neighboring qubits. It ensures that neighboring sequences are mutually orthogonal (to avoid collisions, like in staggered DD) but also whether the qubit is a CX or ECR target/control spectator. This is nicely summarized in a figure of the paper, where the different wire colors denote different decoupling sequences:
This particularly leads to improvement if a lot of qubits are idle at the same time or if they are next to ECR/CX gates. One important category of circuits in this class are the layers in twirled circuits. This pass also works best if the ECR/CX gate times are the same for all connections, which is almost always the case on IBM devices.
Some simple experiments show that this pass performs better than the current standard in Qiskit,
PadDynamicaDecoupling
with anX-X
sequence. Here's some basic benchmarks, see the paper for more:This code is based off @kdk and @ajavadia 🙂