PennyLaneAI / pennylane-qiskit

The PennyLane-Qiskit plugin integrates the Qiskit quantum computing framework and IBM Q with PennyLane.
https://docs.pennylane.ai/projects/qiskit
Apache License 2.0
181 stars 66 forks source link

Circuits always measure all qubits #189

Open vbelis opened 2 years ago

vbelis commented 2 years ago

Describe the bug It seems that the circuits are always compiled to qiskit.QuantumCircuit with measurements on all qubits. This can be checked in the definition of registers: https://github.com/PennyLaneAI/pennylane-qiskit/blob/12c00ad2d34ca4be1db3266e0d38543db7ec286f/pennylane_qiskit/qiskit_device.py#L209 and appending measurements: https://github.com/PennyLaneAI/pennylane-qiskit/blob/12c00ad2d34ca4be1db3266e0d38543db7ec286f/pennylane_qiskit/qiskit_device.py#L240

To Reproduce A simplified example that demonstrates the behavior (i.e. measuring all qubits) of the source code referenced above is the following.

import pennylane as pnl

qdev_hardware = pnl.device(
    "qiskit.ibmq",
    wires=4,
    backend="ibmq_bogota",
    ibmqx_token=private_api_token,
    )

@pnl.qnode(qdev_hardware)
def circuit(params):
    pnl.RX(params[0], wires=0)
    pnl.RY(params[1], wires=1)
    return pnl.expval(pnl.PauliZ(0))

print(circuit([0.54,0.1]))

My goal is to train a variational classifier on an real hardware IBMQ backend. Using a quantum circuit function, implemented in pennylanewith the return value: pennylane.expval(pnl.PauliZ(0)) the transpiled circuit that appears under the corresponding job in IBMQ has measurements on all qubits (see screenshot section below).

Expected behavior To transpile and send a circuit to the IBMQ backend with the same measurement operator as the one defined in the pennylane circuit function.

Screenshots Example of IBMQ backend transpiled circuit job generated by the above code snippet:

image

Environment

Additional context Add any other context about the problem here.

antalszava commented 2 years ago

Hi @vbelis, thanks for the report! Indeed, this is something that the plugin is doing under the hood, as such, it's a historical behaviour. Have you come across any downsides to having a measurement on all qubits?

vbelis commented 2 years ago

Hi @antalszava thanks for the response. In general, I was expecting that the "translation" of a pennylane.qnode circuit to qiskit.QuantumCircuitwould be exact both in terms of the gates and in terms of the measurements. Operators that are not diagonal in the Z-basis, e.g., qml.expval(qml.PauliΧ(0)) or custom Hermitian operators qml.Hermitian, seem to be propagated from pennylane to qiskit. Nevertheless, all qubits on the IBMQ are measured even though wire=0 was specified. Some downsides that come to mind, apart from the in principle non one-to-one translation of the circuit, are the following.

If we are interested only in the outcome of the first qubit, we could read only that and discard the other measurement outcomes. However, in practice, measuring all of them might have different noise effects on real hardware. Additionally, measuring all the qubits means that the qiskit.QuantumCircuit returns a bit-string of 2^{n_qubits} after the execution of the job on the IBMQ backend: https://github.com/PennyLaneAI/pennylane-qiskit/blob/12c00ad2d34ca4be1db3266e0d38543db7ec286f/pennylane_qiskit/qiskit_device.py#L384 which from my understanding calls this qiskit function. It is not clear to me how this array containing the output of the measurements of all qubits is transformed back to the operator expectation value that was defined in the initial qml.qnode, e.g. qml.expval(qml.PauliΧ(0)).

Apart from the above, I would be greatful if you could also inform me about the following. It seems that run https://github.com/PennyLaneAI/pennylane-qiskit/blob/12c00ad2d34ca4be1db3266e0d38543db7ec286f/pennylane_qiskit/qiskit_device.py#L337 is not saving the result to an attribute or return value. Is there a reason for that?

antalszava commented 2 years ago

Thanks for the details @vbelis! Indeed, the result that we get will be a larger bitstring that has to then be post-processed. The change you suggest could indeed tidy up the internals of the plugin and bring an enhanced simulation experience. Based on our internal plans providing a solution might have to come later down the line. Let us know if you'd be interested in having a try with it, we could help with guidance if required. :slightly_smiling_face:

in practice, measuring all of them might have different noise effects on real hardware

Oh, interesting. :thinking: Would you suggest that measuring one qubit may introduce noise that affects the measurement outcome of another qubit with IBMQ?

It seems that run is not saving the result to an attribute or return value. Is there a reason for that?

The reason here is simply just that for PennyLane's internals, saving it is not necessary. Having said that, if it helps, storing it as an instance attribute should be doable.

vbelis commented 2 years ago

Hi @antalszava!

Oh, interesting. 🤔 Would you suggest that measuring one qubit may introduce noise that affects the measurement outcome of another qubit with IBMQ?

From my understanding, yes this is true, especially for superconducting qubits.

Could you, please, point me to the source code where the post-processing of the bitstring occurs? I would like to do some sanity and consistency checks, beyond the potential noise effects specified above. That is, to understand how the results from the IBMQ backend (or Aer simulator) are transformed back to the pennylane measurement operator, specified by the provided quantum function.

antalszava commented 2 years ago

Hi @vbelis,

That occurs in the QubitDevice.statistics and is done by more specific methods like QubitDevice.expval in the PennyLane repository.

Note that QubitDevice.sample will use the underlying samples stored in self._samples that have been generated by the device.

Further to that, here is the step within QubitDevice.execute where samples are being generated and stored and another step where samples are post-processed using the QubitDevice.statistics method.

Generally, the logic for devices is contained in the QubitDevice class, unless certain methods (such as the previously linked generate_samples) method are overwritten.

vbelis commented 2 years ago

Hi @antalszava,

Apologies for the late reply. Thanks a lot for the informative message.

I think it is OK to measure all the qubits and just read the output of the one qubit we are interested in. This should give the same results as measuring only that qubit. However, this is true only in the ideal case, disregarding the different noise effects of the two setups.

I can come back to this thread if I encounter issues regarding the all-qubit measurements in the future. So, I propose that we leave this issue open, since it still the case that the plugin always produces qiskit circuits with measurements on all the qubits. Unless you of course judge otherwise 😄

CatalinaAlbornoz commented 2 years ago

Thank you for you insight @vbelis! We will leave the issue open and feel free to add any additional information you find.

WardGauderis commented 3 weeks ago

Hello,

Are there any updates on this issue? I'm experiencing a similar problem where measuring all qubits seems to increase the noise in the results for the qubits I care about. Is there a way to ensure consistent measurements when my Pennylane circuit is sent to the IBM backend?

Alternatively, is there a method to automatically post-process the longer bitstrings in the same way when retrieving old job results from QiskitRuntimeService? This would allow me to reuse old job results.

Thank you for your help!

CatalinaAlbornoz commented 3 weeks ago

Hi @WardGauderis, thanks for your question! We have made a ton of updates to our PennyLane-Qiskit plugin so I think some of these issues might be resolved already. Let me check with the team.

CatalinaAlbornoz commented 2 weeks ago

Hi @WardGauderis

I checked with the team and they have indeed discussed these issues. For expval and var with the Estimator primitive, measurements are handled by Qiskit so there shouldn't be issues the on PennyLane's side.

Some of the features you mention haven't made it into the plugin, but its very helpful to hear which things people would be most interested in seeing in future releases. We don't know when they would (potentially) be added to the roadmap, but we'll consider adding them to the roadmap based on your feedback.

Thanks so much for your feedback!

WardGauderis commented 2 weeks ago

Thank you for the quick reply, @CatalinaAlbornoz.

To clarify, my use case involves needing the probability of a specific computational base state over a subset of qubits, which I currently extract using qml.probs, where the issue still seems to occur. So far, I am not aware of another measurement function that achieves this.

isaacdevlugt commented 2 weeks ago

@WardGauderis thanks! Indeed, there aren't any measurement processes that do what you're trying to do explicitly, other than post-processing qml.probs.