Skip to content
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

tanujkhattar
Copy link
Collaborator

@tanujkhattar tanujkhattar commented Jun 28, 2023

Step towards fixing #6173

Timing before my PR:

'circuit_rev': 0.31624889373779297
'inverse_circuit': 0.5580418109893799
'Merged circuit': 2.517353057861328
transformer for hardware inverse: 3.393893241882324
'cirq.inverse': 0.03910088539123535

Timing after my PR:

'circuit_rev': 0.31432485580444336
'inverse_circuit': 0.5529079437255859
'Merged circuit': 0.6783010959625244
transformer for hardware inverse: 1.5484230518341064
'cirq.inverse': 0.036971092224121094

@tanujkhattar tanujkhattar requested review from a team, vtomole and cduck as code owners June 28, 2023 23:28
@CirqBot CirqBot added the size: S 10< lines changed <50 label Jun 28, 2023
@tanujkhattar tanujkhattar changed the title Speed up execution time of merge_single_qubit_moments_to_phxz transformer by avoiding redundant calls to unitary Speed up execution time of merge_single_qubit_moments_to_phxz transformer by avoiding redundant calls to unitary Jun 28, 2023
@tanujkhattar tanujkhattar changed the title Speed up execution time of merge_single_qubit_moments_to_phxz transformer by avoiding redundant calls to unitary Speed up execution time of merge_single_qubit_moments_to_phxz transformer by avoiding redundant calls to unitary protocol Jun 28, 2023
Copy link
Contributor

@maffoo maffoo left a 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']:?

@tanujkhattar
Copy link
Collaborator Author

That would involve changing the API of cirq.merge_moments primitive, which will be a backwards incompatible change. In future, we can consider adding a new primitive that expects a merge_func(*moments: 'cirq.Moment') instead of merge_func(cirq.Moment, cirq.Moment) but I'd like to punt it for a later PR.

Also, I chatted with @AlMrvn offline and have proposed a different implementation of InverseSycamoreCircuit that does not use these primitives and is much faster and should be enough to unblock him.

@maffoo
Copy link
Contributor

maffoo commented Jun 29, 2023

That would involve changing the API of cirq.merge_moments primitive, which will be a backwards incompatible change. In future, we can consider adding a new primitive that expects a merge_func(*moments: 'cirq.Moment') instead of merge_func(cirq.Moment, cirq.Moment) but I'd like to punt it for a later PR.

Yes, I'd suggest a new function since we don't want to change the interface of merge_moments.

Also, I chatted with @AlMrvn offline and have proposed a different implementation of InverseSycamoreCircuit that does not use these primitives and is much faster and should be enough to unblock him.

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.

Comment on lines +134 to +135
if gate:
ret_ops.append(gate(q))
Copy link
Collaborator

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?

Copy link
Collaborator

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:

if merged_moment is None:
merged_moments.append(current_moment)
else:
merged_moments[-1] = merged_moment

Copy link
Collaborator Author

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.

Copy link
Collaborator

@pavoljuhas pavoljuhas left a 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.

Comment on lines +134 to +135
if gate:
ret_ops.append(gate(q))
Copy link
Collaborator

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:

if merged_moment is None:
merged_moments.append(current_moment)
else:
merged_moments[-1] = merged_moment

@tanujkhattar tanujkhattar merged commit 3fe3438 into quantumlib:master Jul 11, 2023
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/performance size: S 10< lines changed <50
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants