Skip to content
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

Can't simulate a repeated CircuitOperation that contains a repeat_until CircuitOperation #6446

Open
vtomole opened this issue Feb 6, 2024 · 4 comments · May be fixed by #6881
Open

Can't simulate a repeated CircuitOperation that contains a repeat_until CircuitOperation #6446

vtomole opened this issue Feb 6, 2024 · 4 comments · May be fixed by #6881
Assignees
Labels
area/classical/control area/classical/measurements area/simulation good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. kind/bug-report Something doesn't seem to work. triage/accepted A consensus emerged that this bug report, feature request, or other action should be worked on

Comments

@vtomole
Copy link
Collaborator

vtomole commented Feb 6, 2024

Description of the issue
Repetitively checking the syndromes of a prepared state before using it to measure stabilizers is an important primitive for fault tolerance. True fault tolerance requires that this procedure happen multiple times.

For a minimum reproducible example, measuring a qubit until it's |0> and then applying an X gate to it multiple times will throw a raise ValueError('Infinite loop: condition is not modified in subcircuit.')

How to reproduce the issue

import cirq
import sympy

sim = cirq.Simulator()
q = cirq.LineQubit(0)
inner_loop = cirq.CircuitOperation(
    cirq.FrozenCircuit(cirq.H(q), cirq.measure(q, key="inner_loop")),
    use_repetition_ids=False,
    repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol("inner_loop"), 0)),
)
outer_loop = cirq.Circuit(inner_loop, cirq.X(q), cirq.measure(q, key="outer_loop"))

circuit = cirq.Circuit(cirq.CircuitOperation(cirq.FrozenCircuit(outer_loop), repetitions=2))
print(circuit)
result = sim.run(circuit, repetitions=1)
print(result)

Will print

ValueError: Infinite loop: condition is not modified in subcircuit.

The alternative is to run the CircuitOperation twice, but this breaks the printing of the result but this will throw
ValueError: Cannot extract 2D measurements for repeated keys

import cirq
import sympy

sim = cirq.Simulator()
q = cirq.LineQubit(0)
inner_loop = cirq.CircuitOperation(
    cirq.FrozenCircuit(cirq.H(q), cirq.measure(q, key="inner_loop0")),
    use_repetition_ids=False,
    repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol("inner_loop0"), 0)),
)
inner_loop1 = cirq.CircuitOperation(
    cirq.FrozenCircuit(cirq.H(q), cirq.measure(q, key="inner_loop1")),
    use_repetition_ids=False,
    repeat_until=cirq.SympyCondition(sympy.Eq(sympy.Symbol("inner_loop1"), 0)),
)


outer_loop = cirq.Circuit(inner_loop, cirq.X(q), cirq.measure(q, key="outer_loop"))
outer_loop1 = cirq.Circuit(inner_loop1, cirq.X(q), cirq.measure(q, key="outer_loop1"))

circuit = cirq.Circuit(outer_loop, outer_loop1)
print(circuit)
result = sim.run(circuit, repetitions=1)
print(result)

Cirq version
1.4.0.dev20240126200039

@daxfohl
Copy link
Contributor

daxfohl commented Feb 7, 2024

I can't for the life of me remember how to set up the dev environment, but looking through the code, it looks like you might be able to work around the first issue by setting use_repetition_ids=False in the outer loop as well.

The bug appears to be in the CircuitOperation._with_rescoped_keys_ implementation, as it rescopes all the measurement keys in the subcircuit but doesn't rescope the repeat_until key, so they no longer align. repeat_until is of type Condition, which has a _with_rescoped_keys_ implementation, so it should just be a matter of forwarding on the call.

It looks like a number of other protocols in CircuitOperation should account for the keys in repeat_until condition too: _with_measurement_key_mapping_, _with_key_path_, _with_key_path_prefix_.

As for the error printing the result, IIRC that was by design, but it wasn't my domain so I can't say for sure. Definitely seems like something to revisit though if it blocks this use case. Some discussion at #4555

@vtomole
Copy link
Collaborator Author

vtomole commented Feb 7, 2024

it looks like you might be able to work around the first issue by setting use_repetition_ids=False in the outer loop as well.

I've confirmed that this workaround will do the trick for now.

As for the error printing the result, IIRC that was by design, but it wasn't my domain so I can't say for sure.

I've created a separate issue to ask about this.

@tanujkhattar tanujkhattar added the triage/discuss Needs decision / discussion, bring these up during Cirq Cynque label Feb 14, 2024
@verult verult added triage/accepted A consensus emerged that this bug report, feature request, or other action should be worked on good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. triage/discuss Needs decision / discussion, bring these up during Cirq Cynque and removed triage/discuss Needs decision / discussion, bring these up during Cirq Cynque triage/accepted A consensus emerged that this bug report, feature request, or other action should be worked on labels Feb 14, 2024
@telescopic
Copy link

@tanujkhattar / @verult I'd like to take this up if possible

@vtomole vtomole assigned vtomole and telescopic and unassigned vtomole Mar 26, 2024
@vtomole
Copy link
Collaborator Author

vtomole commented Mar 26, 2024

Thanks for the offer @telescopic . I've assigned this to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/classical/control area/classical/measurements area/simulation good first issue This issue can be resolved by someone who is not familiar with the codebase. A good starting issue. kind/bug-report Something doesn't seem to work. triage/accepted A consensus emerged that this bug report, feature request, or other action should be worked on
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants