-
Notifications
You must be signed in to change notification settings - Fork 107
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
In Jupyter notebook, if simulation ended with runtime exception, allocated qubits are not cleared up #1265
Comments
@swernli I can see how the current behavior is by design, and technically, continuing to execute statements after a runtime error is inadvisable -- but this is super common to encounter as you're iterating on code and it's mildly annoying. I think it's simple enough to accommodate. Is it worth fixing this by just calling qsharp/compiler/qsc_eval/src/intrinsic.rs Lines 108 to 113 in f5b4cb5
|
For this specific case of qubits released in a non-zero state, I think that is an excellent solution. We are already in the process of releasing the qubits, and the language makes it hard to continue referring to them to even have a way to clean them up manually, so we should just release unconditionally. Maybe even something like: let is_zero = qubit_is_zero(qubit);
sim.qubit_release(qubit);
if is_zero {
Ok(Value::unit())
} else {
Err(Error::ReleasedQubitNotZero(qubit, arg_span))
} It's worth noting that this would fix a very common problem but not all the problems, so code like: open Microsoft.Quantum.Diagnostics;
operation Demo() : Unit {
use q = Qubit();
X(q);
let _ = 1 / 0;
}
Demo() Would still leak a qubit each time. |
Can we do qubit_release upon any error, as part of error processing? |
There might be mechanisms we can employ, but it's tricky to differentiate between qubits in a contained scope that should be released: {
use q = Qubit();
X(q);
let _ = 1 / 0;
} vs qubits from top-level statements that shouldn't be released: use q = Qubit();
X(q);
let _ = 1 / 0; The evaluator doesn't do any special tracking of qubits to know which ones are in scope, but rather depends on one of the transformation passes that runs during compilation that turns qubit statements into explicit calls to allocate and release. So for example, the first snippet above with the explicit scope will internally be transformed into: {
let q = __quantum__rt__qubit_allocate();
X(q);
let _ = 1 / 0;
__quantum__rt__qubit_release(q);
} That final statement is what performs the release, not any special tracking in the evaluator, and the error short-circuits that statement. |
I think the feature suggestion here is essentially "stack unwinding" - making Currently Another hamfisted suggestion I have is to actually abort the program in Python when a |
Yeah, that's what we'd need, and it would need to be smart enough to know not to deallocate qubits from the top-level/global scope of the notebook.
I think from the users perspective this would look awfully similar to a crash, so if we went this route we'd want to have a very clear message that guides them on how to recuperate their state (rerun appropriate notebook cells but don't rerun all if there's job submissions, for example). |
Describe the bug
In Jupyter notebook, if simulation ended with runtime exception, allocated qubits stay around. They show up in the next
DumpMachine
outputs, even though there's no way to access them or clear them up.To Reproduce
As you re-run this code, it throws an exception each time, and the number of allocated qubits grows by 1 each time, all of them in |1> state.
Expected behavior
I expect the allocated qubits to not show up in consecutive runs.
System information
The text was updated successfully, but these errors were encountered: