pasqal-io / qadence

Digital-analog quantum programming interface
https://pasqal-io.github.io/qadence/latest/
Apache License 2.0
71 stars 21 forks source link

[Refactoring] Noise protocols #584

Closed chMoussa closed 4 weeks ago

chMoussa commented 1 month ago

Solves #583.

The idea would be to introduce three types of Noise: PulseNoise, PostProcessingNoise and BlockNoise.

There are two approaches to the interface I can think of.

  1. The first easier option would be to keep the Noise dataclass, just adding a type to it, so this does not modify much the current codebase. We can introduce the three types as children. Noise would only serve the purpose of holding options and protocol name besides for PostProcessingNoise where we extract a method add_noise from a module to be used in apply_noise which is called in a few backends.

  2. The second one would require more changes as it means making consistent which noises can be used at the backend level and the method called. For instance, the pulser backend can only accept a PulseNoise in the run method, and all backends can accept a PostProcessingNoise in the sample method. A problem we can foresee is consistent typing with base/abstract classes. Serialization may be also challenging.

chMoussa commented 1 month ago

Thanks @chMoussa :)

IMO, my feeling is that this separation could create some confusion. For example:

  • You suggest BlockNoise to represent the noise models that go to PyQ, but the Qadence design principle is that all programs are composed of "blocks", even ones that compile to the Pulser backend (or will compile in the future).
  • The PulseNoise is defined as specifically creating a SimConfig, but we also have time-dependent blocks that go to PyQ, and in principle this PulseNoise could also have an implementation there.
  • PostProcessingNoise -- There's not really post processing going on yet right? I feel like post-processing is what you would do then for noise mitigation.

Maybe something like:

  • DigitalNoise: for noise protocols described as discrete events acting on a block (that also represents a discrete operation). In PyQ it's essentially what is already implemented. In the future when we have digital operations in other backends (including pulser or a pulser-like backend), these can have an implementation there as well.
  • AnalogNoise: for noise protocols described as a continuous effect that affects some other continuous operation. For Pulser it can plug into the SimConfig like you said, while for PyQ we still need to implement it, but from my understanding this would be about including some extra terms in the Hamiltonian evolution right?
  • ReadoutNoise: what you called the "post processing" one

In principle, I think the set_noise function could be available for both, but it would fail if we try to do set_noise of a AnalogNoise on a digital gate, and possibly fail if we try to set a digital noise on a time-dependent hamiltonian evolution.

Wdyt?

Hi @jpmoutinho,

Thanks for these clarifications. It helps. On analog noise, indeed it would be just setting an option in the solvers with the list of operators. For Postprocessing (only happening in the sample methods of the backends), I thought that one could add modules if there was a need for it later. But right now we can restrict to ReadoutNoise. I'll try to adapt your suggestions rn

RolandMacDoland commented 1 month ago

I agree with @jpmoutinho on this. It makes more sense to talk about digital and analog noises in this context. As for the readout noise, I tend to think this should go in the backends too but it is currently not supported in Pulser unless I'm wrong. This is why it still remains in Qadence and induces confusion and difficulties in having a clean interface. Maybe this is something we can ask the Pulser people to implement ? It'll make our life much easier though. Wdyt ?

chMoussa commented 1 month ago

I agree with @jpmoutinho on this. It makes more sense to talk about digital and analog noises in this context. As for the readout noise, I tend to think this should go in the backends too but it is currently not supported in Pulser unless I'm wrong. This is why it still remains in Qadence and induces confusion and difficulties in having a clean interface. Maybe this is something we can ask the Pulser people to implement ? It'll make our life much easier though. Wdyt ?

If it is possible for them to work on this feature on their side, then I am fine by it and to put it in Pyqtorch. It would be a matter of instantiating the right object.

chMoussa commented 4 weeks ago

Closes as #591 supersedes this.