-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Extend Clifford protocol for 2+ qubit operations through analytical check and falling back to decompose #6332
Conversation
…heck and falling back to decompose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good overall. Left a couple of nits. Thanks!
if qid_shape is None or len(qid_shape) != 1 or not protocols.has_unitary(val): | ||
# qubits is greater than 3 since that would be expensive. | ||
qid_shape = qid_shape_protocol.qid_shape(val, default=None) | ||
if qid_shape is None or len(qid_shape) > 3 or not has_unitary_protocol.has_unitary(val): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we insead check that qid_shape
is either (2,)
or (2, 2)
? For example, what happens if the operation is defined on 2 or less qudits with dimension greater than 2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
res = has_stabilizer_effect(op) | ||
if not res: | ||
return res | ||
return res |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we return True
here instead of res
? res
is defined inside the loop and used outside, which is confusing for the reader.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. good catch
@@ -125,9 +129,20 @@ def test_via_unitary(): | |||
op3 = OpWithUnitary(np.array([[1, 0], [0, np.sqrt(1j)]])) | |||
assert not cirq.has_stabilizer_effect(op3) | |||
|
|||
# 2+ qubit cliffords |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
# 2+ qubit cliffords | |
# 2 qubit cliffords |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it works up to 3 qubit operations like CCNOTs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 3 asserts for cliffords are only for 2 qubit operations, but lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tanujkhattar PTAL
now that has_stabilizer_effect
is more general we need to limit is use in t_complexity
protocol by calling only on single and two qubit operations
@@ -125,9 +129,20 @@ def test_via_unitary(): | |||
op3 = OpWithUnitary(np.array([[1, 0], [0, np.sqrt(1j)]])) | |||
assert not cirq.has_stabilizer_effect(op3) | |||
|
|||
# 2+ qubit cliffords |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it works up to 3 qubit operations like CCNOTs
res = has_stabilizer_effect(op) | ||
if not res: | ||
return res | ||
return res |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done. good catch
if qid_shape is None or len(qid_shape) != 1 or not protocols.has_unitary(val): | ||
# qubits is greater than 3 since that would be expensive. | ||
qid_shape = qid_shape_protocol.qid_shape(val, default=None) | ||
if qid_shape is None or len(qid_shape) > 3 or not has_unitary_protocol.has_unitary(val): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
if cirq.num_qubits(stc) <= 2 and cirq.has_stabilizer_effect(stc): | ||
# Clifford operation. | ||
return TComplexity(clifford=1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this change; it also makes reporting the TComplexity
more accurate since we won't count large cliffords as a single clifford operation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## master #6332 +/- ##
==========================================
- Coverage 97.89% 97.83% -0.07%
==========================================
Files 1108 1108
Lines 96204 96240 +36
==========================================
- Hits 94182 94158 -24
- Misses 2022 2082 +60
☔ View full report in Codecov by Sentry. |
…heck and falling back to decompose (quantumlib#6332)
This implements the check from https://quantumcomputing.stackexchange.com/a/13158 when the unitary is small enough (acting on 3 or less qubits)
Otherwise it falls back to decompose
part of #5906