-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: Kevin Krsulich <[email protected]> Co-authored-by: Ali Javadi <[email protected]>
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 11685932835Warning: 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
if len(closed_delay.active_qubits) > 0: | ||
raise RuntimeError("Failed remove active qubits on closed delays.") | ||
|
||
if validate: |
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 are several validation checks across the code. I suggest enabling and using them in test_context_aware_dd.py
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?
min_joinable_duration: Do not join delays with others below this duration. This | ||
can be useful, e.g. if a big delay block would be interrupted and split into | ||
smaller blocks due to a very short, adjacent delay. |
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.
I would find it very helpful if the documentation mentioned something that could be linked easier to "minimal delay time" and what units are used, something like (I still find it a bit clunky):
min_joinable_duration: Do not join delays with others below this duration. This | |
can be useful, e.g. if a big delay block would be interrupted and split into | |
smaller blocks due to a very short, adjacent delay. | |
min_joinable_duration: Minimal duration to join delays (in dt units). Do not join delays with | |
others below this duration . This can be useful, e.g. if a big delay block would be interrupted | |
and split into smaller blocks due to a very short, adjacent delay. |
can be useful, e.g. if a big delay block would be interrupted and split into | ||
smaller blocks due to a very short, adjacent delay. | ||
skip_reset_qubits: Skip initial delays and delays after a reset. | ||
skip_dd_threshold: Skip dynamical decoupling on an idle qubit, if the duration of |
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.
In what units is skip_dd_threshold
? I have noticed that min_joinable_duration
is an int but this one is a float, so maybe it's not dt?
pulse_alignment: The hardware constraints for gate timing allocation. | ||
This is usually provided om ``backend.configuration().timing_constraints``. | ||
If provided, the delay length, i.e. ``spacing``, is implicitly adjusted to | ||
satisfy this constraint. If ``None``, this is extracted from the ``target``. |
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.
Same comment about units
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
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 🙂