Circuits always measure all qubits
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:

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.
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?
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?
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.
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.
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.
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 😄
Thank you for you insight @vbelis! We will leave the issue open and feel free to add any additional information you find.