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

Add {Frozen}Circuit.from_moments to construct circuit by moments. #5805

Merged
merged 10 commits into from
Jul 23, 2022

Conversation

maffoo
Copy link
Contributor

@maffoo maffoo commented Jul 21, 2022

In our internal code almost all circuits are constructed with explicit moments rather than using an insertion strategy because we want to control the alignment of ops. Here we add a from_moments classmethod on Circuit and FrozenCircuit which takes any number of OP_TREE args and converts each one to a Moment in the resulting circuit. This gives a convenient way to construct circuits without cluttering the code with multiple calls to Moment.

Also adds special cases in both the Circuit and FrozenCircuit constructors to handle constructing from a single circuit or a sequence of moments.

In our internal code almost all circuits are constructed with explicit
moments rather than using an insertion strategy because we want to
control the alignment of ops. Here we add a `from_moments` classmethod
on `Circuit` and `FrozenCircuit` which takes any number of `OP_TREE`
args and converts each one to a `Moment` in the resulting circuit. This
gives a convenient way to construct circuits without cluttering the code
with multiple calls to `Moment`.
@maffoo maffoo requested review from a team, vtomole and cduck as code owners July 21, 2022 16:57
@maffoo maffoo requested a review from pavoljuhas July 21, 2022 16:57
@CirqBot CirqBot added the size: M 50< lines changed <250 label Jul 21, 2022
Comment on lines 1716 to 1717
if len(contents) == 1 and isinstance(contents[0], AbstractCircuit):
self._moments.extend(contents[0].moments)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This could produce two circuits with shared Moments.
Are Moment immutable? If so this should be OK...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, moments are immutable.

Args:
*moments: Op tree for each moment.
"""
return cls(Moment(moment) for moment in moments)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should it be cls(*(Moment(moment) for moment in moments))?
Right now it is taking the old branch on lines 1722-23.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch. Fixed.

@pavoljuhas
Copy link
Collaborator

On another look, the Circuit and FrozenCircuit constructors work as desired in their initial shape when passed arguments that are all Moment-s. I think we can do this by adding a single from_moments() method to the AbstractCircuit base without adding more branching and an extra mirrored code to Circuit and FrozenCircuit. Please see eba2657...1c3368f.

These can be pulled in with

git pull https://github.com/pavoljuhas/Cirq.git pr5805-move-from_moments-to-AbstractCircuit

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.

I propose to do a shared implementation in AbstractCircuit.
See #5805 (comment).

@maffoo
Copy link
Contributor Author

maffoo commented Jul 22, 2022

I'd like the avoid the constructor overhead associated with using the insertion strategies in these cases. For example, even with #5332 to optimize circuit construction with the EARLIEST strategy, we still have to create dicts to track indexes of qubits, measurement keys, and control keys, iterate over each moment and analyze the moment operations. If we already know we have a sequence of moments, we can avoid all that overhead, and since circuit construction is a very common operation when taking data I think this is worthwhile.

@maffoo
Copy link
Contributor Author

maffoo commented Jul 22, 2022

@pavoljuhas, thanks for the review. I've reverted the constructor changes, and instead implemented this in terms of a _from_moments classmethod which replaces the older _with_sliced_moments. I think this is much cleaner, and avoids cluttering the constructors. The docstring on AbstractCircuit._from_moments explains the reason for having this method. PTAL

@maffoo maffoo requested a review from pavoljuhas July 22, 2022 22:54
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.

Looks nice!

@maffoo maffoo added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Jul 23, 2022
@CirqBot CirqBot added the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Jul 23, 2022
@CirqBot CirqBot merged commit 94f9594 into master Jul 23, 2022
@CirqBot CirqBot removed the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Jul 23, 2022
@CirqBot CirqBot deleted the u/maffoo/circuit-from-moments branch July 23, 2022 07:12
@CirqBot CirqBot removed the front_of_queue_automerge CirqBot uses this label to indicate (and remember) what's being merged next. label Jul 23, 2022
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
…uantumlib#5805)

In our internal code almost all circuits are constructed with explicit moments rather than using an insertion strategy because we want to control the alignment of ops. Here we add a `from_moments` classmethod on `Circuit` and `FrozenCircuit` which takes any number of `OP_TREE` args and converts each one to a `Moment` in the resulting circuit. This gives a convenient way to construct circuits without cluttering the code with multiple calls to `Moment`.

Also adds special cases in both the `Circuit` and `FrozenCircuit` constructors to handle constructing from a single circuit or a sequence of moments.
harry-phasecraft pushed a commit to PhaseCraft/Cirq that referenced this pull request Oct 31, 2024
…uantumlib#5805)

In our internal code almost all circuits are constructed with explicit moments rather than using an insertion strategy because we want to control the alignment of ops. Here we add a `from_moments` classmethod on `Circuit` and `FrozenCircuit` which takes any number of `OP_TREE` args and converts each one to a `Moment` in the resulting circuit. This gives a convenient way to construct circuits without cluttering the code with multiple calls to `Moment`.

Also adds special cases in both the `Circuit` and `FrozenCircuit` constructors to handle constructing from a single circuit or a sequence of moments.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size: M 50< lines changed <250
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants