-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Speed up execution time of merge_single_qubit_moments_to_phxz
transformer by avoiding redundant calls to unitary protocol
#6174
Conversation
…rmer by avoiding redundant calls to unitary
merge_single_qubit_moments_to_phxz
transformer by avoiding redundant calls to unitary
merge_single_qubit_moments_to_phxz
transformer by avoiding redundant calls to unitarymerge_single_qubit_moments_to_phxz
transformer by avoiding redundant calls to unitary protocol
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 will still be slower than it needs to be if there are more than two single-qubit moments in a row. Could we change it to instead collect runs of mergeable moments, then call the merge func with any number of moments: def merge_func(*moments: 'cirq.Moment') -> Optional['cirq.Moment']:
?
That would involve changing the API of Also, I chatted with @AlMrvn offline and have proposed a different implementation of |
Yes, I'd suggest a new function since we don't want to change the interface of
Glad to hear it. This is what I suggested to him as well, that he'd probably be better off eschewing the standard transformers and writing something custom. In particular if it can avoid creating lots of intermediate circuits. |
if gate: | ||
ret_ops.append(gate(q)) |
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.
It seems that this can return an empty moment if this condition and another at line 145 are False.
Does the merge_moments
function below handle such case and keeps the original moments unchanged?
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.
It seems merge_moments
expects merge_func
returns None when moments cannot be merged, please correct the return value below.
Ref:
Cirq/cirq-core/cirq/transformers/transformer_primitives.py
Lines 543 to 546 in 7b753f6
if merged_moment is None: | |
merged_moments.append(current_moment) | |
else: | |
merged_moments[-1] = merged_moment |
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.
single_qubit_matrix_to_phxz
returns None
when the matrix
corresponds to an identity gate (it doesn't represent a failure to construct a PhasedXZGate).
If all merged operations correspond to identity, it is perfectly reasonable to return an empty moment corresponding to the "merged" moment from the merge_func
and thus replace two moments containing single qubit gates with a single empty moment in the circuit.
Note that we already check whether the two moments m1
and m2
are merge-able or not in the can_merge_moment
condition at the beginning of merge_func
. Thus, no additional changes are needed here and the behavior is as intended.
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.
IIUC, merge_func needs to return None instead of an empty Moment.
if gate: | ||
ret_ops.append(gate(q)) |
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.
It seems merge_moments
expects merge_func
returns None when moments cannot be merged, please correct the return value below.
Ref:
Cirq/cirq-core/cirq/transformers/transformer_primitives.py
Lines 543 to 546 in 7b753f6
if merged_moment is None: | |
merged_moments.append(current_moment) | |
else: | |
merged_moments[-1] = merged_moment |
…former by avoiding redundant calls to unitary protocol (quantumlib#6174)
Step towards fixing #6173
Timing before my PR:
Timing after my PR: