Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Circuits always measure all qubits #189

Open
vbelis opened this issue Feb 18, 2022 · 12 comments
Open

Circuits always measure all qubits #189

vbelis opened this issue Feb 18, 2022 · 12 comments
Labels
enhancement New feature or request

Comments

@vbelis
Copy link

vbelis commented Feb 18, 2022

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:

self._creg = ClassicalRegister(self.num_wires, "c")
and appending measurements:
measure(self._circuit, qr, cr)

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

  • Python version: 3.9.7
  • OS : Red Hat 7.9
  • Versions: qiskit==0.34.2, pennylane==0.20.0, pennylane-qiskit==0.21.0

Additional context
Add any other context about the problem here.

@antalszava
Copy link
Contributor

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
Copy link
Author

vbelis commented Feb 22, 2022

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:

samples = self._current_job.result().get_memory(circuit)
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

result = self._current_job.result()
is not saving the result to an attribute or return value. Is there a reason for that?

@antalszava antalszava added the enhancement New feature or request label Feb 22, 2022
@antalszava
Copy link
Contributor

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. 🙂

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

Oh, interesting. 🤔 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
Copy link
Author

vbelis commented Mar 5, 2022

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
Copy link
Contributor

antalszava commented Mar 7, 2022

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
Copy link
Author

vbelis commented May 3, 2022

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
Copy link

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

@WardGauderis
Copy link

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
Copy link

CatalinaAlbornoz commented Aug 21, 2024

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
Copy link

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
Copy link

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
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants