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

Classical Control: Loops/Branches/Conditions #3234

Closed
balopat opened this issue Aug 19, 2020 · 18 comments
Closed

Classical Control: Loops/Branches/Conditions #3234

balopat opened this issue Aug 19, 2020 · 18 comments
Assignees
Labels
area/classical kind/roadmap-item for higher level roadmap items to capture conversations and feedback (not for project tracking)

Comments

@balopat
Copy link
Contributor

balopat commented Aug 19, 2020

Problem: Cirq currently only supports a single unrolled circuit. In Feedforward above a simple example of a flow control primitive, a simple conditional is considered. This feature is to expand the set of flow control primitives. Examples of these primitives could be count-controlled loops (for loops), condition-controlled loops (while blocks), collection-controlled loops (for loops for collections), early exit from loops, skipping from loops, case statements. In addition to the flow controls themselves, specification of what can be done with the data that is consumed and produced by these flow controls needs to be specified.

Depends on feature: Classical data (#3231)

Rough requirements:

  • Allow users to use flow control statements in their programs
  • Specify how execution unrolls.
  • Support serialization of the specification of flow control.
  • Fit in with the specification of data in the Classical Data feature
@daxfohl
Copy link
Collaborator

daxfohl commented Jan 14, 2021

Could we turn this inside out? I would think the flow control could remain in Python. To do this, the only thing that would be necessary is ensuring that the quantum device was able to retain state between runs.

device.run_then_wait(circuit1, (q1, q2, q3), outputs)
if outputs['m']:
  device.run(circuit2, (q1, q3))
else:
  device.run(circuit3, (q2, q3))

That gives us all the power of Python to run the classical part, which is what it does best, and leaves the quantum part specific to the quantum circuits.

This would remove the need to build a serializable flow control and calculation language into cirq itself.

@95-martin-orion
Copy link
Collaborator

Could we turn this inside out? I would think the flow control could remain in Python. {...}

This runs up against a fundamental issue with the current state of quantum computing: waiting for any significant period in the middle of a circuit introduces additional error, as the qubits gradually decohere. Given that these decoherence times are often measured in microseconds, taking the time to pass results out of the control layer to Python and back isn't an option.

@daxfohl
Copy link
Collaborator

daxfohl commented Jan 14, 2021

I see, makes sense. Maybe the solution is something like opengl shaders where there's a C-like language that you code the classical pieces in, and they can reference the quantum circuits somehow.

The thing I'd want to avoid is putting the whole control flow as cirq objects. e.g.

mixed_cicuit =
  cirq.if(
    cirq.ref(circuit1, (q1, q2, q3)),
    'm', 
    cirq.ref(circuit2, (q1, q3)),
    cirq.ref(circuit3, (q2, q3)))

Not too hard to follow for that simple case, but making a whole program from that format: named functions, scopes, complex calculations, seems like it would be a challenge. (Though now that I've typed it out it seems not too bad; just looks like lisp, and it's just an AST so it should be possible to convert back and forth between the two syntaxes and compile onto the device however we want, so who knows).

@daxfohl
Copy link
Collaborator

daxfohl commented Jan 14, 2021

Also allowing users to upload arbitrary Python code to run on google's quantum engine probably isn't the greatest idea from a security standpoint. :)

@daxfohl
Copy link
Collaborator

daxfohl commented Jan 14, 2021

Maybe Web Assembly for the control flow? Similar to how fastly does it for their web workers. So a "package" to run on the quantum device would contain all the circuits plus a wasm file that is the control flow. We can then compile that to native to run on the device's CPU. Since it's WASM, that gives a nice security boundary (which is why fastly uses it), and since we're precompiling it, it should run at native CPU speed. Also it should be portable across devices.

UX would be, user creates quantum circuits in cirq, writes control flow in AssemblyScript, Rust, or whatever that compiles to WASM. Then they call a function in cirq that packages those all up. Simulation should work easily too, as Python already has a wasm interpreter we could run for the control flow code.

This would allow us to use existing languages easily and safely rather than having to create our own "shader language" or build our own AST builders. (Though it doesn't prevent us from doing either of those things -- they could both compile into WASM too. Besides, either of those options will have to compile into something anyway, so may as well go with a standard). I wonder if this provides motivation to create some hybrid QWASM representation at the bottom.

Plenty of details to work through, a lot of it probably depends on how the devices actually work under the hood, just thinking out loud.

@daxfohl
Copy link
Collaborator

daxfohl commented Jan 16, 2021

I'm more thinking this could be a key differentiator. Real world quantum algorithms will require a mixed flow, and being able to standardize a low-level IL for this would be nice. Quantum machines would then take this format to produce the mixed-mode executable.

@daxfohl
Copy link
Collaborator

daxfohl commented Jan 18, 2021

There is also a mature pyverilog library for working with FPGA logic, if we decide FPGA is the better choice due to timings. This may be the more natural choice if all we are doing is feeding forward simple calculations from measurement gates. If we are doing more complex calculations or generating subcircuits on the fly, we'd probably be better off with a software driven solution though, if it can meet the latency constraints. Maybe we end up with a little bit of both.

Also, on second thought the security concerns probably aren't that important, as surely we'll be running these on isolated and hardened environments.

@daxfohl
Copy link
Collaborator

daxfohl commented Jul 28, 2021

@daxfohl
Copy link
Collaborator

daxfohl commented Aug 9, 2021

Ignore the above draft for now. I think it went too deep into one alternative without highlighting the various options. https://tinyurl.com/cirq-flow-control-options is more high-level. (And it may even be too early for this, as we haven't even really talked about requirements in detail yet). @95-martin-orion @smitsanghavi @MichaelBroughton @balopat

@daxfohl
Copy link
Collaborator

daxfohl commented Aug 11, 2021

Only a bit more code and there's an IfElseOp that is compatible with subcircuits w/ measurement key mappings and also allows boolean sympy expressions that can contain multiple measurement keys in the conditions. https://github.com/daxfohl/Cirq/compare/classical...daxfohl:ifelse?expand=1. I think this should be pretty doable.

@vcatherine vcatherine changed the title Flow control Classical Control Sep 3, 2021
@vcatherine vcatherine changed the title Classical Control Classical Control Flow Sep 3, 2021
@vcatherine vcatherine changed the title Classical Control Flow Classical Control: Loops/Branches/Conditions Sep 3, 2021
@tanujkhattar
Copy link
Collaborator

We have no immediate plans to support this in the near future.

@95-martin-orion
Copy link
Collaborator

I disagree with closing this issue; while it is true that we do not plan to support this in Cirq 1.0, it remains an interesting feature for us to continue tracking beyond that release.

@vcatherine
Copy link
Collaborator

We are trying to clean up vague overly broad or hard to action issues. We could perhaps open new more actionable issues and close this one, wdyt?

@95-martin-orion
Copy link
Collaborator

That seems okay to me - the language in the first comment is far more vague than I remembered - but let's hold off on closing this issue until we've opened the replacement issues, and link those back to this issue to preserve the discussion.

@daxfohl
Copy link
Collaborator

daxfohl commented Sep 16, 2021

I've done some initial investigation on this and I believe the main thing we'd still need is a CircuitOperation.repeat_until(key: MeasurementKey), and possibly #4274. If we have those, then I believe we can reconstruct most if not all QASM 3.0 flow control functionality in terms of this and the feedforward primitives.

Should we add that function as one issue, and then perhaps OpenQASM 3.0 support as the stretch item that includes parsing and conversion, etc?

@vtomole
Copy link
Collaborator

vtomole commented Sep 16, 2021

OpenQASM 3.0 support as the stretch item that includes parsing and conversion

Independent OpenQASM support sounds like so much to me. What are your thoughts on @balopat's idea #3560 (comment) about adding a package qiksit-cirq that leans hard on the existing OpenQASM support in Qiskit?

@daxfohl
Copy link
Collaborator

daxfohl commented Sep 16, 2021

I don't see a big difference one way or the other. If we have qiskit-cirq, then that would do the parsing, but we'd still have to do the mapping from qiskit primitives to cirq primitives, which if their structures are much different from cirq's that may be no easier than parsing raw QASM. But of course either way it requires the corresponding cirq primitives to exist in the first place, which is the more important thing.

But regarding qiskit-cirq, I can see both sides of that one. It saves us from having to write and maintain our own parsing code and gives us additional runtime compatibility with qiskit libraries, so that's pretty nice. But it's a fairly heavy dependency, in beta state, and could add a bunch of maintenance cost and user confusion about what qiskit features are supported.

If I had to make the call I'd say probably try to do the parsing manually first, because parsing shouldn't be that hard (though I say this after only a brief perusal of the spec from a while ago), and it's something we can do incrementally. And adding qiskit is something we can always do later if we need to. But I'd defer to anyone who has been in this space for longer than myself.

@MichaelBroughton
Copy link
Collaborator

Going to close for now since it looks like we've hit all of the bigger milestones for this issue. @daxfohl let's open any more specific follow ons as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/classical kind/roadmap-item for higher level roadmap items to capture conversations and feedback (not for project tracking)
Projects
None yet
Development

No branches or pull requests

7 participants