Kraus protocol restructured and serial concatenation implemented
As mentioned #4822, the kraus protocol has been re-structured. The original task (https://github.com/quantumlib/Cirq/pull/4486) has been split into two tasks to handle serial concatenation for kraus and mixture protocol.
The serial concatenation is handled by converting the decomposed operations into their superoperator form with the help of cirq.Moment().expand().kraus (https://github.com/quantumlib/Cirq/pull/4550).
With the newly proposed structure of kraus and has_kraus, some issues are required to be handled.
- Re-structuring of
has_krausresults in the protocol taking alternative methods rather than returning the first answer. Pairing this fact withallow_decompose = True, it returnsTruefor moments with a large number of qubits. -
kraususes superoperator intermediate, which means that a large number of qubits could lead toMemoryErrordue to the exponential size of superoperators. - Handling a large number of qubits in
_has_kraus_is overwritten in this new flow. - Example test case that fails due to above reason:
cirq-core/cirq/ops/moment_test.py::test_kraus_too_big
Possible approaches
- Explicit check on the size of the resulting superoperator in
has_krausandkraus. The example that causesMemoryErrorhas 9 qubits. - Check for the number of qubits in the simulation each
krauscalls. - Changing the flow or setting
allow_decomposeto beFalsewould fix this issue but would make recursive decomposition less obvious
Discussion from Cirq sync:
- We should not use superoperator representations for unitaries
- We should remove the check that the limit is on 10 qubits because it miscommunicates that this is something we check for when in reality, we can't assume how much memory a user's machine has.
To complete the restructuring, #4876 must be merged.