CircuitError: The Program is locked

Hi,

I am a bit confused about how to solve the following error CircuitError: The Program is locked, no more Commands can be appended to it. I think I understand why the error happens but I can’t come up with a way to run the circuit iteratively for a variational algorithm and avoid this error. The answer here for sampling makes sense. But what about the case when you want to run the circuit iteratively with a new parameter? I tried to eng.reset() at the end of for loop but it didn’t help.
I’d appreciate it if you could point out what I am missing here.

import strawberryfields as sf
from strawberryfields.ops import *

shots=2
prog = sf.Program(2)
x1 = 0.4
x2 = 0.5
param=[0.1, 0.4, 0.9]
steps=3


eng = sf.Engine("fock", backend_options={"cutoff_dim": 4})

def run_circuit(param):

    with prog.context as q:

        Squeezed(x1) | q[0]
        Squeezed(x2) | q[1]

        Zgate(-2*param) | q[0]
        CZgate(-2*param) | (q[0],q[1])

        MeasureHomodyne(0.0) | q[0]
    return 

for j in range(steps):
    run_circuit(param[j])
    
    result = eng.run(prog)
    s = result.samples
    
    # check if a condition is fulfilled 
    # update parameter, go to next iteration, re-run the circuit with new parameter and collect measurment results

1 Like

Hey @Rina!

Shuffling the program creation into where it gets populated — the function run_circuit — will do the trick. This will create a new instance of sf.Program every time you call run_circuit, allowing you to feed in different parameters and call it iteratively.

I also took the liberty of shoving a few other things in the run_circuit function :grin:

shots = 2
x1 = 0.4
x2 = 0.5
param = [0.1, 0.4, 0.9]
steps = 3


eng = sf.Engine("fock", backend_options={"cutoff_dim": 4})


def run_circuit(param):
    prog = sf.Program(2)

    with prog.context as q:
        Squeezed(x1) | q[0]
        Squeezed(x2) | q[1]

        Zgate(-2 * param) | q[0]
        CZgate(-2 * param) | (q[0], q[1])

        MeasureHomodyne(0.0) | q[0]

    result = eng.run(prog)
    s = result.samples
    eng.reset()
    return s


for j in range(steps):
    s = run_circuit(param[j])

Hope this helps!

Thanks a lot, @isaacdevlugt :slightly_smiling_face:

I have already tried to return s from inside the run_cisrcuit() but I was getting the same error.

Now that I compare this simplified code with mine I realised, in my code inside run_cisrcuit(), I am looping over registers to apply some gates and do for example initialization like Squeezed(0.5,0) | q[i], and that is the source of the problem.

Nice! So, is your problem solved now?

Yes, thank you! You can close the question. :slight_smile:

2 Likes

Awesome! Glad we could help :slight_smile: