quil-lang / qvm

The high-performance and featureful Quil simulator.
Other
411 stars 57 forks source link

Memory is not reset between trials #313

Open MarquessV opened 1 year ago

MarquessV commented 1 year ago

While experimenting with dynamic control flow, I noticed that the QVM server doesn't reset memory between trials.

Consider a program where we create a bell pair out of Q0 and Q1, measure Q0 to ro[0] and only measure Q1 to ro[1] if Q0 was measured out to 1.

DECLARE ro BIT[2]
H 0
CNOT 0 1
MEASURE 0 ro[0]
JUMP-WHEN @IS_ONE ro[0]
JUMP @END
LABEL @IS_ONE
MEASURE 1 ro[1]
LABEL @END

There are two possible states of ro at the end of this program. [0, 0] if Q0 measured to 0 or [1, 1] if Q0 measured to 1. The QVM produces these results consistently when the program is run as a single trial.

However, if you run this program with multiple trials, you'll get states for ro that should be impossible.

With the QVM server running in the background, if we run this program with 4 trials:

curl -X POST http://127.0.0.1:5000 \
  -H "Content-Type: application/json" \
  -d '{"type": "multishot", "compiled-quil": "DECLARE ro BIT[2]\nRESET\nH 0\nCNOT 0 1\nMEASURE 0 ro[0]\nJUMP-WHEN @IS_ONE ro[0]\nJUMP @END\nLABEL @IS_ONE\nMEASURE 1 ro[1]\nLABEL @END\n", "addresses": {"ro": [0, 1]}, "trials": 4}'

We get a result that looks like this:

{
  "ro":[
    [1,1],
    [0,1],
    [0,1],
    [0,1]]
}

Notice the [0, 1] state, which should impossible for the given program. What I believe is happening is that memory isn't being reset between trials. In this case, we got [1, 1] for the first trial because Q0 measured out to 1, resulting in a measure of 1 to ro[1]. In the following trials, Q0 measured to 0, which means they didn't measure to ro[1], but since memory wasn't reset, the 1 from the first trial remained.

Should memory be reset between trials? Or is this intended behavior?