-
Notifications
You must be signed in to change notification settings - Fork 33
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
Qubit allocation within _decompose_
is not compatible with current BFS based implementation of cirq.decompose
.
#232
Comments
_decompose_
is not compatible with current implementation of cirq.decompose
. _decompose_
is not compatible with current BFS based implementation of cirq.decompose
.
@tanujkhattar is the goal is to fix |
I think we should also consider inserting dummy operations representing So, within def _decompose_with_qubit_manager_(self, qubits, qm: 'QubitManager') -> cirq.OP_TREE:
ancilla = qm.qalloc(10) # It would be nice if we can also yield here, but I think it'll end up making the this a 2 line statement, which is annoying. Maybe we could "automatically" insert an "Allocation" gate for every new qubit which is part of the returned `cirq.OP_TREE` ?
...
...
yield qm.qfree(ancilla) # This explicitly marks the point where `ancilla` is deallocated; which will be important for a qubit manager. I'm open to suggestions here! |
Another option would be to restrict the use of only This was my original idea because when I initially proposed the design of |
+1 for the SimpleQubitManager restriction replacing the BFS with DFS order in |
First step towards fixing this: quantumlib/Cirq#6116 |
Second PR which should fix this issue. See the test added using mocks as part of the PR: quantumlib/Cirq#6117 |
This is now (theoretically) fixed. Can be closed until we see a bug or exception pop up. |
cirq.decompose(op)
currently works (roughly) as follows:op_tree = cirq.decompose_once(op)
and get the op-tree returned by callingop._decompose_()
.op_tree
; recursively perform step-1.Right now, when implementing
_decompose_
method of an operation; we useqalloc
andqfree
methods to allocate / clean qubits. This pattern assumes that for all operations executed betweenqalloc
andqfree
; the allocated qubits are "in-use" and thus any qubit manager should not reuse the same qubits when recursively decomposing the operations that occur in between these two function calls.For this assumption to be true,
cirq.decompose
should ideally perform aDFS
on the implicit compute graph but it currently performs aBFS
and as a result; before decomposing the operations that occur betweenqalloc
andqfree
function calls; theqfree
call is processed and the allocated ancillas are freed. This results in a situation where only the "trivial" strategy used bySimpleQubitManager
remains valid because there is no qubit reuse and thus the order in whichqalloc
/qfree
is processed does not matter. But, for every other qubit allocation strategy that makes any reuse; the current implementation ofcirq.decompose
can result in reusing "occupied" qubits and thus lead to errors.A simple example is shown below.
Decomposing the above gate with a simple qubit manager strategy outputs the correct expected circuit:
But calling it with a
cq.GreedyQubitManager('ancilla', maximize_reuse=True)
results in a qubit reuse error:cc @NoureldinYosri This is the bug I was talking about in the last resource estimation sync.
The text was updated successfully, but these errors were encountered: