-
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
Add align measure pass #6673
Add align measure pass #6673
Conversation
Co-authored-by: Toshinari Itoko <itoko@jp.ibm.com>
This is the result of integration test from qiskit import IBMQ, circuit, transpile
import matplotlib.pyplot as plt
import numpy as np
IBMQ.load_account()
backend = IBMQ.get_provider(hub='ibm-q', group='open', project='main').get_backend("ibmq_armonk")
p_delay = circuit.Parameter("Δt")
delays = np.linspace(0, 100, 20)
qc = circuit.QuantumCircuit(1, 1)
qc.x(0)
qc.delay(p_delay, 0, unit="us")
qc.measure(0, 0)
qc.draw() #
┌───┐┌───────────────┐┌─┐
q_0: ┤ X ├┤ Delay(Δt[us]) ├┤M├
└───┘└───────────────┘└╥┘
c: 1/═══════════════════════╩═
0
exp_qcs = [qc.assign_parameters({p_delay: delay}, inplace=False) for delay in delays]
result = backend.run(transpile(exp_qcs, backend), shots=256).result()
plt.plot(delays, [count.get("1", 0)/256 for count in result.get_counts()])
plt.xlabel("delay, us") |
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.
partial review before i look at the actual pass algorithm
def test_t1_experiment_type(self): | ||
"""Test T1 experiment type circuit.""" |
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.
for the circuits in this file do you mind drawing the circuits before/after alignment, in the doctstring, so it's easier to know what's happening? See e.g. the tests in #6619
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.
This is awesome idea! done in 92163d4 (I also added description for how the test works)
|
||
if len(dag.op_nodes(Delay)) == 0 or len(dag.op_nodes(Measure)) == 0: | ||
# delay is only instruction that induce misalignment | ||
# other instructions cannot be arbitrarily stretched |
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.
is this true? what if I define a pulse gate with a duration of 100dt? I think this pass should look at the measurement start times, and not make assumptions about the rest of the instructions.
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.
This instruction cannot be accepted by the backend because this already violate chunk size constraint. I was thinking to add chunk size validation for pulse gate later but I can add this check in this PR too.
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.
Just added custom gate validation example in this commit 72821a3
I'll revert this commit and can move to separate PR if you wish.
# if circuit is not yet scheduled, schedule with ALAP method | ||
if dag.duration is None: | ||
scheduler = ALAPSchedule(durations=self.durations) | ||
scheduler.property_set["time_unit"] = time_unit | ||
# run ALAP schedule to find measurement times | ||
for required_pass in scheduler.requires: | ||
dag = required_pass.run(dag) | ||
dag = scheduler.run(dag) |
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.
A pass shouldn't really call another pass. See discussion here: #6580 (comment)
I think there are two alternate ways here:
1- just make the pass raise an error if the circuit is not scheduled. This is what I did for DD. The passmanager will be built in a way that scheduling is always called before this pass.
2- If you really want to do this then leave a TODO. Because what you really want is to "declare that the circuit must be scheduled, otherwise instruct the pass manager to insert an ALAPSchedule right before this pass". There is a requires
field right now in the passes, but they only declare that a certain pass must have been run before them, not that a certain property must have been set. I think @1ucian0 has been meaning to implement this.
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. I took the approach 1 with slight improvement of the logic. Because we want to reduce breaking change as much as possible, so new logic has validation of delay duration to trigger pass execution. If all delays are multiple of 16 this pass is not executed, thus calling transpile without scheduling option doesn't cause an error.
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 know, in general, we should not call another pass internally. I just want to note that we are accepting to break some existing codes using delays without scheduling, e.g. T1/T2 experiments, if requiring the external call of ALAP pass. They can be fixed only by supplying scheduling_method
to transpile
though. I'm wondering if this cost is allowable. What do you think? @ajavadia
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 think the existence of alignment
should tell the transpiler to do scheduling, even if scheduling_method
is not supplied. There is a similar issue here #6667
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.
but they only declare that a certain pass must have been run before them, not that a certain property must have been set. I think @1ucian0 has been meaning to implement this.
it is not possible to do "require a property" right now. However, you can conditionally run a pass based on the existence of a property which, if I understand this correctly, is the case in this situation.
- change argment ordering - update docstring - move pass adding to each level function - add circuit drawings to test - avoid calling other passes from pass
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
…kit-terra into fix/issue-6666_tempfix
Thanks for the quick review. I updated the code according to your comments. The major changes are
The logic is almost the copy of |
releasenotes/notes/add-alignment-management-passes-650b8172e1426a73.yaml
Outdated
Show resolved
Hide resolved
Instead of copying ASAPScheduling, isn't it easier to just iterate over all I think this will be much shorter in terms of lines of code. |
…26a73.yaml Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
Yes this is what I wanted to implement, however we cannot do this because DAGNode doesn't have information of t0 even after scheduled. Perhaps we need to allow a node to have t0 after this release. I just removed redundant validations from the ASAPScheduling implementation. ie we are assuming already scheduled DAG input in this pass: 291a1a5 This reduces lines of code. |
In addition, if we have a mid measurement, the insertion of delay in front of the measurement affects the start times of the following instructions globally, suggesting local changes on measurements would not work for circuits with mid measurements. |
Co-authored-by: Toshinari Itoko <itoko@jp.ibm.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.
ok this looks good to me now. thanks for the explanations and making the updates.
Co-authored-by: Ali Javadi-Abhari <ajavadia@users.noreply.github.com>
…kit-terra into fix/issue-6666_tempfix
Summary
This pass fixes the strange behavior of IBM Quantum backends when a circuit with length not multiple of 16 is provided. This behavior has been reported multiple times so far, especially some experiments requiring arbitrary delay between instructions, such as inversion recovery or Ramsey experiment.
This malfunction is caused by the misalignment of acquire instruction from the clock boundary of 16dt, which causes a phase error in measurement channels, yielding the drift of blob position in the measurement IQ plane (you can check this behavior with level1 measurement).
Fix #6666
Details and comments
Instead of fixing the rotation error, this PR adds a pass that shift the start time of measurement instruction to match with the 16dt clocks. This number will be provided by backend as
alignment
. The pass is currently called by the transpiler, but we can call this also from the IBMQ backend object via run method (in this case legacy backend can still cause the error).This needs Qiskit/qiskit-ibmq-provider#983
TODO