Extend Clifford protocol for 2+ qubit operations through analytical check and falling back to decompose#6332
Conversation
…heck and falling back to decompose
tanujkhattar
left a comment
There was a problem hiding this comment.
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.
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?
| res = has_stabilizer_effect(op) | ||
| if not res: | ||
| return res | ||
| return res |
There was a problem hiding this comment.
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.
done. good catch
| 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.
| # 2+ qubit cliffords | |
| # 2 qubit cliffords |
There was a problem hiding this comment.
it works up to 3 qubit operations like CCNOTs
There was a problem hiding this comment.
The 3 asserts for cliffords are only for 2 qubit operations, but lgtm
NoureldinYosri
left a comment
There was a problem hiding this comment.
@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
| 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.
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.
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): |
| 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.
I like this change; it also makes reporting the TComplexity more accurate since we won't count large cliffords as a single clifford operation.
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