Skip to content

Support merging 1-qubit gates in transformers for parameterized circuits #7149

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

Open
wants to merge 19 commits into
base: main
Choose a base branch
from

Conversation

babacry
Copy link
Collaborator

@babacry babacry commented Mar 17, 2025

Input: symbolized_circuit, sweep
Output: new_symbolzied_circuit, new_sweep

@babacry babacry force-pushed the merge_single branch 6 times, most recently from 3dea74b to d5da63a Compare March 18, 2025 02:09
Copy link

codecov bot commented Mar 18, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.67%. Comparing base (5112418) to head (e67e661).

Additional details and impacted files
@@           Coverage Diff            @@
##             main    #7149    +/-   ##
========================================
  Coverage   98.66%   98.67%            
========================================
  Files        1106     1110     +4     
  Lines       96086    96266   +180     
========================================
+ Hits        94808    94987   +179     
- Misses       1278     1279     +1     

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@babacry
Copy link
Collaborator Author

babacry commented Mar 18, 2025

Hi Eliott, Nour, I have added the function to support one use case. Could you PTAL? For the use case of combined input of sweep and parameterized circuit, will be added in the followup PR. Let's first make sure this PR is in the right place and do the right job. Thanks!

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.

I tested it a little bit in this colab, and it doesn't seem to work properly yet, the interface looks good to me.

@eliottrosenberg eliottrosenberg self-requested a review April 4, 2025 00:06
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 so much @babacry!!! I tested it here, and it seems to work!

@eliottrosenberg
Copy link
Collaborator

One small comment: it would be nice if the merged single-qubit gates ended up in the same moment; see this cell of the colab.

@babacry
Copy link
Collaborator Author

babacry commented Apr 4, 2025

Got you, thanks a lot for the manual checks! I will update the pr accordingly and fix checks.

@babacry babacry force-pushed the merge_single branch 11 times, most recently from 33a8233 to 7ac61a5 Compare April 9, 2025 08:09
@babacry babacry marked this pull request as ready for review April 9, 2025 19:22
Copy link
Collaborator

@NoureldinYosri NoureldinYosri left a comment

Choose a reason for hiding this comment

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

there are several useful private methods that should be turned into public transformers



def _values_of_sweep(sweep: Sweep, key: str | sympy.Symbol):
p = sympy.Symbol(key) if isinstance(key, str) else key
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure about this

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed this util func.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's from

def _values(sweep, key):

resolved_circuits: A list of circuits where symbols have been replaced with concrete values.
symbolized_single_tag: The tag applied to single-qubit operations that originally
contained symbols before parameterizations.

Copy link
Collaborator

Choose a reason for hiding this comment

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

some parameters are missing

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

obsolete.


def _merge_single_qubit_gates_to_phxz_symbolized(
resolved_circuits: List['cirq.AbstractCircuit'],
symbolized_single_tag: str,
Copy link
Collaborator

Choose a reason for hiding this comment

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

tags are not necessarily strings

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. all tags type -> Hashable.

return [resolver.value_of(p) for resolver in sweep]


def _merge_single_qubit_gates_to_phxz_symbolized(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this method is useful on its own ... so it should be public

maybe even turn it into a class an split its logic across 2+ methods

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done.

return the_merge_tag.pop().split("_")[-1]


def _map_merged_ops_to_symbolized_phxz(
Copy link
Collaborator

Choose a reason for hiding this comment

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

this should be a public transformer method

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done in symbolize.py .

babacry added 6 commits April 22, 2025 18:20
Note: if users expect update sweeps together with merging, it's not
supported yet. It's a todo item to be supported in the followup PRs.
tag_transformers: remove_tags, index_tags.
symbolize: symbolize_single_qubit_gates_by_indexed_tags
@babacry
Copy link
Collaborator Author

babacry commented Apr 23, 2025

Thanks Nour for the valuable suggestions. I come up with a much better version with your inputs. @NoureldinYosri

I added tag_transformers and symbolize transformers which are some dependencies of merge_single_qubit_gates_symbolzied.

Could you help take another look? (I can split the tag_transformer, symbolize transformers out in different prs if this PR is too huge).

@babacry babacry requested a review from NoureldinYosri April 23, 2025 04:30
Copy link
Collaborator

@NoureldinYosri NoureldinYosri left a comment

Choose a reason for hiding this comment

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

lets split this PR into smaller PRs ... also what is happening with all these tags?

@@ -65,6 +76,7 @@ def merge_single_qubit_gates_to_phxz(
circuit: 'cirq.AbstractCircuit',
*,
context: Optional['cirq.TransformerContext'] = None,
merge_tags_fn: Optional[Callable[['cirq.CircuitOperation'], List[Hashable]]] = None,
Copy link
Collaborator

Choose a reason for hiding this comment

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

I feel like this is a bit too general ... what is the problem with recieving a list of tags ?

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 kind of need a function here as what I need to do is given a circuit op, set the output tags with more rule based tag setters and I believe the flexibility of the function can help users in different use cases.

  • Currently, the merge function do the following mapping in the rewriter

CircuitOperation(X['tag_needed'] -- Y['tag1']) --> phxz(x,z,a) with no tags

  • In my use case, I need a rule based tag setter:

case 1: CircuitOperation(X['tag_needed'] -- Y['tag1']) --'tag_needed' presented--> phxz(...)['phxz_{iter}']
case 2: CircuitOperation(X -- Z) --no 'tags_needed' found --> phxz(...) with no tags

  • Flexibility of merge_tags_fn: e.g., if users want to preserve all the tags in the circuit op, they may do the merges in merge_tags_fn, then the tags can preserve like the following

CircuitOperation(X['tag0'] -- Y['tag1']) --> phxz(...)['tag0', 'tag1']

)
merged_circuits.append(merged_circuit)

if not all(
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think this should happen here ... this should be a test for the correctness of the transformer

Copy link
Collaborator Author

@babacry babacry Apr 29, 2025

Choose a reason for hiding this comment

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

It's to validate the input parameters sweep, basically all the resolvers in sweep shoulld resolve the circuit to the same structure, otherwise, we can't do the merge here.

If we don't check here, Step 2 of parameterization would possibly crash with different kind of errors.

I should probably update the error message as InvalidArgument("Invalid input sweep, different resolvers in sweep resulted in different merged structures.")

@babacry
Copy link
Collaborator Author

babacry commented Apr 30, 2025

Thanks! @NoureldinYosri I will split the PRs =)

@babacry
Copy link
Collaborator Author

babacry commented Apr 30, 2025

Split 2 pre-requisites in #7306 and #7307

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/parameters parameter resolution, parameterized gates, operations area/transformers priority/after-1.5 Leave for after the Cirq 1.5 release size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants