microsoft / qsharp-runtime

Runtime components for Q#
https://docs.microsoft.com/quantum
MIT License
286 stars 93 forks source link

Noisy simulation in Q# #504

Open crazy4pi314 opened 3 years ago

crazy4pi314 commented 3 years ago

Please describe what you would like the feature to accomplish.
I would like a way to simulate real/noisy hardware in Q#.

Describe the solution you'd like
I am working now full time developing Mitiq, a Python library for doing error mitigation techniques for quantum programs. The reason we have gone with Python and other tools like Circ and Qiskit to date is because they have built-in ways to simulate the noise we are trying to mitigate. I am running into other situations where I would rather try and implement these techniques in Q# (one such being compiling to QIR) but without a noisy simulator it would be pretty much impossible.

Describe alternatives you've considered
I could try and write my own noisy simulator backend for Q#, or try and hook it up to other existing noisy simulators via the simulator interface. This is a well explored area and basically I don't want to duplicate effort on.

Additional context
The reason doing this in Q# is really interesting to me is that I need to design experiments where sending an entire program that can generate random characterization gate sequences on the device is essential. I am constantly fighting other APIs where I can only send individual quantum circuits and are thus limited in how much data I can get per request.

cgranade commented 3 years ago

Thanks for the suggestion, @crazy4pi314! If you're interested, I've been working on an experimental and untested approach at https://github.com/microsoft/qsharp-runtime/tree/cgranade/experimental/opensim. This experiment may not go anywhere in particular, and there's currently not a working build for it, but I'd be very interested in your feedback on whether something along those rough lines would be useful to you in your work on Mitiq.

I'll keep you posted here if and when there's an experimental alpha build you can try, but until then, thanks again for the feature request!

cgranade commented 3 years ago

OK, here's an experimental build for Q# standalone and Q# + C# (no IQ# or Python support yet) that should be able to run some simple Q# applications (e.g.: only CNOT as far as two-qubit gates go, no single-qubit rotations, so forth):

<!-- example.csproj -->
<Project Sdk="Microsoft.Quantum.Sdk/0.15.210223293-alpha">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <DefaultSimulator>Microsoft.Quantum.Experimental.OpenSystemsSimulator</DefaultSimulator>
  </PropertyGroup>
</Project>
<!-- NuGet.Config -->
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="alpha" value="https://pkgs.dev.azure.com/ms-quantum-public/9af4e09e-a436-4aca-9559-2094cfe8d80c/_packaging/alpha/nuget/v3/index.json" />
  </packageSources>
</configuration>

Please let us know if you have any feedback you'd like to share. Thanks for kicking the tires on this one!

crazy4pi314 commented 3 years ago

Thanks so much @cgranade! I have been able to use this and from a console Q# app get the simulator working πŸŽ‰ I'm excited to look ate configuring the noise models, how does that work?

crazy4pi314 commented 3 years ago

I have been working on testing this out in a repo here: https://github.com/crazy4pi314/qsharp-zne , and just made a PR to fix a bug I ran into (https://github.com/microsoft/iqsharp/pull/412). I am trying to put together a Jupyter notebook demonstrating setting all different kinds of noise models now, and will let you know if I run into any other issues πŸ’―

cgranade commented 3 years ago

Thanks for putting this through it's paces, @crazy4pi314! If you're interested, a new alpha should be up as 0.15.210223451-alpha, including better support for DumpMachine, %experimental.noise_model, and %config support from within Jupyter Notebook.

crazy4pi314 commented 3 years ago

This is great, the ability to change the number of qubits in the simulator was something I was trying to figure out how to do, so having it as a %config option with qsharp.config['opensim.nQubits'] was great! The dump machine display encoders are also πŸ”₯πŸ”₯πŸ”₯ Maybe once I build up some more common-ish noise models they could even be parameterized config options as well (with full specification directly always being an option)?

image image

RolfHuisman commented 3 years ago

Interesting. So how are the noise patterns represented ? and can you also modify the noise model to create certain specific biasses ?

cgranade commented 3 years ago

Interesting. So how are the noise patterns represented ?

Great question! This is still experimental, so gathering feedback on that, actually. My initial thoughts are mainly with respect to the data model at https://github.com/microsoft/qsharp-runtime/blob/cgranade/experimental/opensim/src/Simulation/OpenSystems/runtime/src/noise_model.rs#L14, with each different built-in operation being represented in a noise model by a different channel, represented either as a unitary or as as a Kraus decomposition. If there's something else that would be helpful, please let me know and I can take a look at how to modify the design! πŸ’•

and can you also modify the noise model to create certain specific biasses ?

My thought on that was to modify the Python interoperability piece to add a set_noise_model function that accepts a dictionary of QuTiP objects, and that then serializes that noise model so that the C# and Rust parts of the simulation runtime can use it. That way, you can use QuTiP functions like to_super to build up a noise model quickly from exactly those kinds of biases:

image

guenp commented 3 years ago

@cgranade I just tried this out, thanks for sharing this experimental feature! It would be great if there were a way to specify the configuration for the noisy simulator via the .csproj file rather than via C#, IQ# or Python such that I can run it from the command line.

cgranade commented 3 years ago

@guenp: Thanks for raising that, yeah. At the moment, we don't have a good general mechanism for setting simulator configuration options from standalone projects, but I completely agree that that would be a good thing to have, especially in this case. @samarsha, do you have any suggestions for how we could pass configuration options from the csproj side through to simulators? Thanks!

cgranade commented 3 years ago

@samarsha, @bettinaheim: Wanted to ping quickly about the question on configuring via csproj files. Thanks!

joabnd7 commented 3 years ago

Just a few comments. From what I can gather, many of these noise models under development for the Sims seem to be presently limited in the types of gates where noise can be applied. So the first question is if all gates are equal offenders for being noise sources? I would imagine that depends on the hardware. Honeywell makes a claim of having high resolution rotation gates "pi/500". Based on the IONq documentation of their hardware, they mention that specifying a single gate rotation has a limit to useful precision. On the Best Practices link provided by MS Azure Quantum there is a quote "Rotation precision for RX and RY is about 10-3 * Ο€. There’s no benefit to supplying gates with angles much smaller than this." It is my understanding that this is the precision to which the incident laser can set a rotation of the trapped ion state (to within a small tolerance of over and under rotation). So then perhaps this is the order of magnitude of the potential noise? I am not sure if I am understanding it all correctly so any guidance is appreciated.

joabnd7 commented 3 years ago

@guenp:

Not sure if this is what you are after, but I had some good luck. It is probably all wrong or something someone already tried, but it did seem to work...and was called from the command line - so not exactly from the .csproj file like you asked,

image

where you can specify the level of noise in terms of counts (nex,ney,nez) per 1000 in radians for the X, Y, and Z axes. Then after each gate, you do a RX,RY,RZ with jitter on the qubits involved with that particular gate. The jitter is based on a set of three ghost qubits and might be +/- . I included a few examples of "Noisy" gates. And I had some good luck with this compared to the ION Q qpu shown below. I hope this is helpful?

noise_maincode Jnoise_code

And here are some examples of "noisy" gates where it is just an RX,RY,RZ using the random jitter for each qubit involved in the gate. These "noisy" gates would be found in the Qcirc() operation of a particular circuit under study. Note that the Jitter is changing randomly at +/- the specified amplitude from shot to shot. I imagine someone could make this a guassian or other desired distribution, but this actually worked...

noise_examp_code

And a few more examples...

image

And then the nex,ney,nez values can be explored and after a little bit of tuning, here is an example result for a generic test circuit of 3 qubits with two of them having Y rotations (Theta_1 and Theta_2). The plot shows the probability of getting a <111> state as one of the rotation angle parameters is swept and the other one is held constant. Everything in the plot used 1000 shots, including the IONq qpu.

image