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

Make Instance GateFamily check for equality ignoring global phase #4542

Merged
merged 8 commits into from Oct 13, 2021

Conversation

tanujkhattar
Copy link
Collaborator

@tanujkhattar tanujkhattar commented Oct 1, 2021

The recent adoption of GateFamily across Cirq introduced an unnoticed and unintended change -- i.e. equality comparison of eigen gates now depended upon the global_shift factor as well. For instance, before the adoption of Gatesets, an isinstance check of the form isinstance(op, cirq.XPowGate) and op.exponent == 1 would accept cirq.X and also accept cirq.Rx(rads = np.pi). The latter would get rejected now since GateFamily's started relying only on value equality checks.

Since comparison upto global phase is what is often needed, this PR introduces a configurable option to GateFamily and updates the default behavior of checking value equality via cirq.equal_up_to_global_phase. Also added tests at GateFamily use sites which would have failed in the original implementation.

Part of roadmap item #3243

@CirqBot CirqBot added the size: L 250< lines changed <1000 label Oct 1, 2021
@google-cla google-cla bot added the cla: yes Makes googlebot stop complaining. label Oct 1, 2021
@tanujkhattar tanujkhattar marked this pull request as draft October 1, 2021 01:56
@dstrain115
Copy link
Collaborator

It looks like there is a significant diffbase in here for neutral atoms and the PR is marked as Draft, so I will hold off reviewing for now. Can you ping reviewers when it is ready?

@tanujkhattar tanujkhattar marked this pull request as ready for review October 1, 2021 17:31
@tanujkhattar
Copy link
Collaborator Author

@dstrain115 This is ready for review now -- I had marked it as draft after realizing the git branching issue which included diffbase from the other neutral atoms PR.

@tanujkhattar
Copy link
Collaborator Author

@dstrain115 Gentle reminder. This is ready for review.

Copy link
Collaborator

@MichaelBroughton MichaelBroughton left a comment

Choose a reason for hiding this comment

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

Drive-by review comment: Would this changeover let people do things like ?

my_gateset = cirq.GateSet(X**0.5, ignore_global_phase=True)
cirq.X ** 0.5 in my_gateset # True
cirq.PhasedXPowGate(phase_exponent=0) in my gateset # !True!

my_gateset2 = cirq.GateSet(X**0.5, ignore_global_phase=False)
cirq.X ** 0.5 in my_gateset2 # True
cirq.PhasedXPowGate(phase_exponent=0) in my gateset2 # False

This seems a little scary if true.

cirq-core/cirq/ops/gateset.py Outdated Show resolved Hide resolved
@tanujkhattar
Copy link
Collaborator Author

Drive-by review comment: Would this changeover let people do things like ?

my_gateset = cirq.GateSet(X**0.5, ignore_global_phase=True)
cirq.X ** 0.5 in my_gateset # True
cirq.PhasedXPowGate(phase_exponent=0) in my gateset # !True!

my_gateset2 = cirq.GateSet(X**0.5, ignore_global_phase=False)
cirq.X ** 0.5 in my_gateset2 # True
cirq.PhasedXPowGate(phase_exponent=0) in my gateset2 # False

This seems a little scary if true.

In [2]: cirq.PhasedXPowGate(phase_exponent=0, exponent=0.5) == cirq.X ** 0.5
Out[2]: True

Therefore, the example that you quoted would return true in both the cases. I would also not include an explicit isinstance check when doing approximate equality because it would modify the behavior of already well known concepts in Cirq (i.e. Value Equality and Equality ignoring global phase).

@MichaelBroughton
Copy link
Collaborator

Ahhhh that makes a lot of sense. In my explorations I actually used cirq.PhasedXZGate which does not pass this (I then assumed PhasedX also wouldn't):

>>> cirq.PhasedXZGate(x_exponent=0.5, z_exponent=0, axis_phase_exponent=0) == cirq.X**0.5
False

But I think that's actually a bug having done a bit more exploring lol.

This makes a lot more sense now. My only remaining concern is that I think we should default to having ignore_global_phase=False starting with the strictest requirements and then if a user wants to back it off slightly they can set ignore_global_phase=True.

@tanujkhattar
Copy link
Collaborator Author

tanujkhattar commented Oct 12, 2021

The reason I've chosen the default value to be True is because that's what is being used across the codebase via the legacy checks. Eg: At all the places where cirq.Gateset was used to replace existing isinstance checks, the default value would need to be True. If we set the default to False, it would make the common use case more cumbersome, i.e.

cirq.Gateset(cirq.GateFamily(cirq.X ** 0.5, ignore_global_phase = True))

instead of

cirq.Gateset(cirq.X ** 0.5)

Also, note that accept_global_phase in the Gateset parameter, which accepts global phase operation, is also set to true by default. Ignoring global phase in GateFamily checks would keep things consistent in the sense that global phase is ignored by default when checking for acceptance, be it with individual operations differing in global phase (checked via GateFamily) or two circuits with different GlobalPhaseOperations tagged on (checked via Gateset)

@tanujkhattar
Copy link
Collaborator Author

Now that we are talking about it, I think we should also rename the Gateset parameter accept_global_phase to accept_global_phase_op to make the distinction between the ignore_global_phase parameter on GateFamily a bit less confusing since these two parameters control different behaviors.

@MichaelBroughton MichaelBroughton self-assigned this Oct 12, 2021
@tanujkhattar
Copy link
Collaborator Author

I've renamed accept_global_phase to accept_global_phase_op as well. This would also have been a breaking change but since we haven't released Gatesets yet, we don't need to go through a deprecation cycle.

Copy link
Collaborator

@MichaelBroughton MichaelBroughton left a comment

Choose a reason for hiding this comment

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

After offline sync, LGTM with some nits.

cirq-core/cirq/ops/gateset.py Outdated Show resolved Hide resolved
@@ -295,7 +310,7 @@ def __contains__(self, item: Union[raw_types.Gate, raw_types.Operation]) -> bool
)
return True

return any(item in gate_family for gate_family in self._custom_gate_families)
return any(item in gate_family for gate_family in self._gates)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we add a comment that the above checks will still catch GateFamilys that are typed based and GateFamilys that have ignore_global_phase=False ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Expanded the docstring comment to explain the new code path.

@tanujkhattar
Copy link
Collaborator Author

@MichaelBroughton Thanks for the approval. I've addressed the nits. Merging now.

@tanujkhattar tanujkhattar added the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Oct 12, 2021
@CirqBot
Copy link
Collaborator

CirqBot commented Oct 12, 2021

Automerge cancelled: A required status check is not present.

Missing statuses: ['Pytest Windows (3.7)', 'Pytest Windows (3.8)', 'Pytest Windows (3.9)', 'Typescript lint check', 'Typescript tests', 'Typescript tests coverage']

@CirqBot CirqBot removed the automerge Tells CirqBot to sync and merge this PR. (If it's running.) label Oct 12, 2021
@tanujkhattar tanujkhattar merged commit 888aeb7 into quantumlib:master Oct 13, 2021
@tanujkhattar tanujkhattar deleted the gatesets_exp_bug_fix branch October 13, 2021 00:25
rht pushed a commit to rht/Cirq that referenced this pull request May 1, 2023
…antumlib#4542)

* GateFamily value equality ignoring global phase

* Rename accept_global_phase to accept_global_phase_op
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes Makes googlebot stop complaining. size: L 250< lines changed <1000
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants