Skip to content

Streamline proto serialization of circuits with duplicate operations #6991

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

Merged

Conversation

dstrain115
Copy link
Collaborator

  • Some circuits, such as randomized benchmarking circuits, have many repeated operations.
  • Streamline the proto serialization of these circuits so that these operations are stored only once (in the constants table).

Note that this PR only adds deserialization by default and hides serialization behind a feature flag. Once this is deployed everywhere, then we can enable serialization.

Example serialization of a randomize benchmarking circuit with 70 qubits and 500 cliffords:

Before change:

  • Serialization time; 0.48 s, Deserialization time: 1.08 s
  • Serialization size: 2129715

After change:

  • Serialization time; 0.13 s, Deserialization time: 0.10 s
  • Serialization size: 174852

- Some circuits, such as randomized benchmarking circuits, have many
repeated operations.
- Streamline the proto serialization of these circuits so that these
operations are stored only once (in the constants table).

Note that this PR only adds deserialization by default and hides serialization behind a feature flag. Once this is deployed everywhere, then we can enable serialization.
@dstrain115 dstrain115 requested review from wcourtney, vtomole, verult and a team as code owners January 28, 2025 13:48
@CirqBot CirqBot added the size: L 250< lines changed <1000 label Jan 28, 2025
Copy link

codecov bot commented Jan 28, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 97.89%. Comparing base (6ebc78b) to head (e88ef19).
Report is 1 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6991   +/-   ##
=======================================
  Coverage   97.89%   97.89%           
=======================================
  Files        1085     1085           
  Lines       95098    95121   +23     
=======================================
+ Hits        93096    93119   +23     
  Misses       2002     2002           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

deserialized_constants=deserialized_constants,
)
)
elif which_const == 'moment_value':
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WDYT of adding a catch-all else to handle cases where a new value was added but this block wasn't updated? It looks like we would silently ignore those cases today.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. Done.

],
)
print(serializer.serialize(circuit))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you intend to leave this print statement? I think there's a preference to avoid output noise in the CI due to its monolithic nature. If this is only intended for development, would it work to use a logger with a low severity level (e.g. debug) so that you can enable this only when needed? I'm not sure how logging is set up for cirq/clients.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was purely for debugging. Removed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this was just for debugging. Removed.

@@ -389,8 +389,10 @@ def test_serialize_deserialize_circuit():
assert serializer.deserialize(proto) == circuit


def test_serialize_deserialize_circuit_with_moments_table():
serializer = cg.CircuitSerializer(USE_CONSTANTS_TABLE_FOR_MOMENTS=True)
def test_serialize_deserialize_circuit_with_constants_table():
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: separately test specific behaviors when possible rather than a monolithic block demonstrating multiple behaviors. e.g., prefer tests with titles that can be phased with clear "given", "when", and "then" clauses.

https://testing.googleblog.com/2014/04/testing-on-toilet-test-behaviors-not.html

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure we want to do that in this case. Testing all combinations of feature flags is not really a viable use case, so I am not sure we want to separate them out. Both of these flags are here so that we don't serialize something that cannot be deserialized on the server-side. Once both of these changes are deployed, we will switch the defaults and get rid of the flags. Separating into two tests is just going to mean we will need to clean up more tests later.

(Arguably, we could just have one feature flag I guess, but I think it makes sense to keep them separate even if we will later likely remove both at the same time).

elif which_const == 'moment_value':
# For now, just put in a place holder, since moments
# will be deserialized later.
deserialized_constants.append(None)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a bug that is being resolved? If so, can you add a test that would have have failed without this fix but passes now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The existing tests will catch it. This was a preexisting bug, but it did not appear since the moments would only be at the end of the constants table. In one of the tests, there are multiple moments and operations, which intersperses them in the list, so this test will fail if this is removed.

Copy link
Collaborator

@eliottrosenberg eliottrosenberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, Doug!

@dstrain115 dstrain115 added this pull request to the merge queue Jan 30, 2025
Merged via the queue into quantumlib:main with commit 08b1efb Jan 30, 2025
38 checks passed
@dstrain115 dstrain115 deleted the u/dstrain/operations_identity_protot branch January 30, 2025 13:40
mhucka pushed a commit to mhucka/Cirq that referenced this pull request Jan 30, 2025
…uantumlib#6991)

* Streamline proto serialization of circuits with duplicate operations

- Some circuits, such as randomized benchmarking circuits, have many
repeated operations.
- Streamline the proto serialization of these circuits so that these
operations are stored only once (in the constants table).

Note that this PR only adds deserialization by default and hides serialization behind a feature flag. Once this is deployed everywhere, then we can enable serialization.

* fix type

* Addressed some of the comments.

* coverage
BichengYing pushed a commit to BichengYing/Cirq that referenced this pull request Jun 20, 2025
…uantumlib#6991)

* Streamline proto serialization of circuits with duplicate operations

- Some circuits, such as randomized benchmarking circuits, have many
repeated operations.
- Streamline the proto serialization of these circuits so that these
operations are stored only once (in the constants table).

Note that this PR only adds deserialization by default and hides serialization behind a feature flag. Once this is deployed everywhere, then we can enable serialization.

* fix type

* Addressed some of the comments.

* coverage
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants