quil-lang / qvm

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

Revisiting QVM Noise Models #175

Open sophiaponte opened 5 years ago

sophiaponte commented 5 years ago

Currently, we use the QVM to simulate noise by either:

We would like more straightforward, expressive, and uniform ways to handle noise in the QVM. We also want to be explicitly clear in how exactly how and where noise is being simulated. Here are three qvm classes to address these issues.

  1. approximate noise QVM: This qvm is meant to approximately simulate a QPU, for the user who wants to quickly spin up a QVM with standard sources of noise found on QPUs. The qvm will be constructed with one or more keys [‘T1’, ‘T2’, 'DEPOLARIZING', ...] which specify the noise source/s to be simulated. For example, to simulate only T1 and T2 noise the qvm will get keys = [T1, T2], which would trigger the QVM to simulate relaxation and dephasing noise by applying the corresponding noise maps after each gate instruction.
  2. general noise QVM: simulates a QPU as closely as possible at the gate level. This QVM constructs pauli noise models that are representative of one and two qubit gate level noise by requiring users to provide a 'noisy version' of each gate, which will replace the ideal gates in the program. There could also be an option to compile programs into native gates and require that the noise models be defined for native gates.
  3. kraus QVM: a fully customizable and explicit noisy qvm. This qvm allows the user to explicitly and completely define a noise model. The parameters for this qvm would look something like a map of {rules -> kraus operators}, where the kraus operators define how the state is transformed, and the rules express where in the program the transformation happens.

Some questions to consider :

appleby commented 5 years ago

As far as qvm-app goes, I think the main concern will be the serialization format, especially for (3).

It would also be PrettySweet if qvm-app didn't have to peek inside the Quil program to extract the Kraus ops, but I guess even if we move away from that, qvm-app will need to continue to support it for some time.

sophiaponte commented 4 years ago

I think this could be an opportunity to shift the decision about which type of qvm to build away from the qvm-app. Here's how I have been envisioning the qvm app + the new qvm noise models working together:

So the qvm-app just passes along data. It doesn't have to make decisions about which type of qvm to build -- the user makes that decision by specifying the simulation-mode or some related parameter.

appleby commented 4 years ago

^ This would simplify qvm-app, and what's good for qvm-app in this respect is good for any code that wants to use qvm as a library.

From qvm-app's perspective, it would also be nice if whatever high-level interface is created also handles allocation modes, so that the caller can just say "I want native/foreign/shared" allocation, rather than having to provide an allocation descriptor (which needs to the know the size of the allocation, which is dependent on qvm type). Allocation modes aren't directly related to the noise models work, of course, but it is related to this idea of pushing the decision about how to instantiate a user-requested qvm out of qvm-app and down into the qvm package. Note that some (but not all) of the existing qvm types provide a make[-type]-qvm function. Extending and/or homogenizing those interfaces might be a good starting point.

braised-babbage commented 4 years ago

I think it's also worth being explicit about the object representing the simulated state, and this is somewhat orthogonal to questions of how noise is to be expressed.

For example, depolarizing-qvm and noisy-qvm both track a wavefunction, and perform quantum operations (e.g. the application of a noisy gate) by choosing one among several possible state transitions. On the other hand, the density-qvm tracks a density matrix, which encodes a full, probabilistic description of the resulting state. The result here is deterministic: given a program some "noisy quantum operations", it will always produce the same density matrix**.

This is relevant because the two approaches represent different tradeoffs. A density matrix simulation of n qubits takes as much memory as a pure state simulation of 2n qubits. However, a density matrix simulation need only be run once to obtain all sorts of useful information (e.g. operator expectations). A pure state simulation would need to be some number of times, with relevant results averaged, since each run reflects a different sequence of probabilistic outcomes (sometimes the coin comes out heads, sometimes tails).

** One caveat: since measurement to classical memory is supported, and future control flow could depend on these outcomes, MEASURE instructions still do introduce nondeterminism in the density-qvm. So the statement here is really: for straight-line quil (i.e. without measurement or control flow, but perhaps with "noisy operations" expressed via kraus maps or whatnot), the results of simulation are deterministic.

sophiaponte commented 4 years ago

There are a few different ways I can think of taking into account the state representation (pure state qvm vs. density state qvm).

appleby commented 4 years ago

Without knowing too much about how the qvm actually simulates noise, these all look like reasonable options to me.

Option 1 sounds like it's the closest to the current implementation (i.e. single density-qvm class that expects kraus ops). If density matrix simulation only makes sense with kraus operators, maybe that's the way to go.

On the other hand, if choice of simulation method is orthogonal to the choice of noise model, maybe 2 or 3 make more sense.