quantumlib / Cirq

A Python framework for creating, editing, and invoking Noisy Intermediate Scale Quantum (NISQ) circuits.
Apache License 2.0
4.23k stars 1.01k forks source link

Computational graph #3586

Closed viathor closed 3 years ago

viathor commented 3 years ago

Is your feature request related to a use case or problem? Please describe.

In many experiments, quantum circuits are built by a classical program and then sent off for execution on the quantum hardware or simulator. Performance is improved significantly by batching many executions together. This is why run has the repetitions parameter and why we have features such as parameter sweeps.

However, in some case, the control flow of the classical algorithm that builds the quantum circuits is disrupted by the need to plan batching. An example of this occurs in Direct Fidelity Estimation where circuits are created based on random numbers drawn from some distribution and so many otherwise unrelated iterations of the algorithm produce identical circuits.

A natural solution is to introduce a data structure to hold an execution plan. This isolates the classical factory of quantum circuits from the concerns of efficient execution on quantum hardware. The execution plan is then processed to optimize batching before sending the circuits off for execution. Execution plan must also maintain information about the origin of each circuit to route measurement results back to the appropriate classical post-processing.

Describe the solution you'd like

I think user experience would be significantly improved if we had a concept of "computational graph" in cirq. This would incorporate classical operations and executions of quantum circuits and that would be responsible for optimal batching of quantum circuits generated by classical processing and for returning measurement results to the appropriate classical code for post-processing. I suppose it could be modeled on tensorflow's computational graph.

Nodes in the graph would represent classical and quantum operations and edges the flow of data. Materializing a value of a quantum node would involve local simulation or remote execution on quantum hardware or cloud sim. Materializing classical node would involve local classical processing.

Materializing the root node of a computational graph with at least one quantum node would result in the computation of an execution plan consisting of a minimum number of sweeps and a table mapping measurement results to quantum nodes in the computational graph. This would be consulted when results from quantum cloud arrived in order to populate all quantum nodes with their corresponding values. This would unblock dependent classical nodes for local execution. The entire process would be repeated until the graph shrinks to one node.

[optional] Describe alternatives/workarounds you've considered

User can write their own execution plan optimizer (which is made easier by frozen circuits that can be used as keys in a dict).

[optional] Additional context (e.g. screenshots)

What is the urgency from your perspective for this issue? Is it blocking important work?

P3 - I'm not really blocked by it, it is an idea I'd like to discuss / suggestion based on principle

zaqqwerty commented 3 years ago

This sounds like the use case TFQ was designed to solve. The Sample and SampledExpectation layers correspond to the idea of a "quantum node", since the backend can be either local simulation or remote execution on a real QPU. Classical nodes are all the other components of TensorFlow.

These components can naturally be composed to address the use case described of generating and executing circuits based on random numbers. As a simple example, we can independently sample bit-flips from a distribution and use these as gate parameters:

import cirq
import sympy
import tensorflow as tf
import tensorflow_probability as tfp
import tensorflow_quantum as tfq

# Probability distribution
num_qubits = 4
prob_heads = 0.2
num_samples = 1000
coins = tfp.distributions.Bernoulli(probs=[prob_heads]*num_qubits)
bitstring_samples = coins.sample(num_samples)

# Build parameterized quantum circuit
qubits = cirq.GridQubit.rect(1, num_qubits)
flip_symbols = [sympy.Symbol("b_{}".format(n)) for n, _ in enumerate(qubits)]
flip_circuit = cirq.Circuit([cirq.X(q)**s for q, s in zip(qubits, flip_symbols)])

# Get results
sample_layer = tfq.layers.Sample(backend=None)
samples = sample_layer(
    flip_circuit, symbol_names=flip_symbols, symbol_values=bitstring_samples,
    repetitions=1000).to_tensor()
tf.shape(samples)

where samples has dimensions [1000, 1000, 4]. The layer constructor takes the backend argument, where None defaults to qsim, but a cirq.sampler can be specified instead to call remote execution on the real QPU.

@MichaelBroughton is there anything I'm missing here? Seems like anything related to hybrid quantum-classical computation or computational graphs has its natural home in TFQ, and as I wrote TFQ seems to already contain the requested features.

MichaelBroughton commented 3 years ago

Hi @viathor what you are describing in this feature is eerily similar to TFQ. If you haven't used it before I'd encourage you to give it a whirl and see if it aligns with your vision of how a computation graph fits in with quantum/cirq. When designing TFQ we wanted to: "incorporate the primitives around running and building circuits into TensorFlow's vast compute graph capabilities". @zaqqwerty 's example is a great demonstration of how a basic compute graph gets built in TFQ. A few other things I will mention is that you can have incredibly intricate quantum + classical back and forth data flows in TFQ. You could pass around and modify circuits, execute them, post-process bitstrings, compute expectations, feed these results into downstream circuit executions etc. Even in our first tutorial you can see this on display. It uses a classical NN to control a quantum circuit, but you could just as easily drop in conditional logic, parity calculation or anything your heart desires anywhere in that computational graph. The only general requirement is that the tensor dimensions line up.

I think user experience would be significantly improved if we had a concept of "computational graph" in cirq. This would incorporate classical operations and executions of quantum circuits and that would be responsible for optimal batching of quantum circuits generated by classical processing and for returning measurement results to the appropriate classical code for post-processing

This is like, everything we do :stuck_out_tongue: . when batching was first being discussed, a big reason we wanted it in is because TF also lets (and in fact encourages) you to operate on batches of inputs/data and in our case quantum circuits too.

Nodes in the graph would represent classical and quantum operations and edges the flow of data. Materializing a value of a quantum node would involve local simulation or remote execution on quantum hardware or cloud sim. Materializing classical node would involve local classical processing.

All is to really say, over in TFQ land, we have thought a LOT about computational graphs, and how quantum features come into play in them, which is something pretty core to our framework. I'd be curios to hear anyone's thoughts on features they'd be interested in seeing supported or in general seeing if there's anything we could add to make it better. Perhaps the issue being raised here is an indication there is more functionality we could support ? Or maybe some computation-graph-like functionality that might belong in Cirq and not TFQ (although it would really surprise me if that was the case) ?

balopat commented 3 years ago

Came up on Cirq Cynque: https://orquestra.io/

balopat commented 3 years ago

Discussed on Cirq Cynque: Adam is working on DFE - will see if it can be rephrased with TFQ. If yes, he'll put a happy note here :)

github-actions[bot] commented 3 years ago

This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 30 days

github-actions[bot] commented 3 years ago

Issue closed due to inactivity.

daxfohl commented 3 years ago

@MichaelBroughton @viathor Did it turn out that TFQ provided a solution here or did the issue just get closed silently?