-
Notifications
You must be signed in to change notification settings - Fork 2.3k
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
Pauli measurement #5311
Pauli measurement #5311
Conversation
add initial attempt at measurements
implement BasisTransformationMeasurement
its probably safer to wrap the Measure instruction if the basis is Z instead of the PauliMeasure to mimic the Measure instruction. Otherwise we might run into unforeseen issues since Measure might be used as primitive somewhere down in Terra
Move to PauliMeasure
* use clifford gates only * apply inverse post rotations for correct statevector simulations * make basis argument required * change to uppercase labels (but support lowercase still)
Apply Chris' suggestions
A few comments:
|
Pull Request Test Coverage Report for Build 1489887938
💛 - Coveralls |
Is there any reason for creating |
@1ucian0 I'm not sure, but to get the answer it's important to emphasize:
|
I found this PR is very helpful to cleanly write many calibration sequences in the experiments. I think now post rotations are okey since most backends support gate after measurement. |
I'd like to draw the attention of the reviewers to my comments #5311 (comment). |
Actually, this is a a bad idea. Each basis is, in essence, a different instructions with different decompositions and backends (such as IBM Quantum provider) and plugins (such as QASM2) might support a subset of them. Taking this suggestion back. |
@@ -36,3 +39,62 @@ def broadcast_arguments(self, qargs, cargs): | |||
yield qarg, [each_carg] | |||
else: | |||
raise CircuitError("register size error") | |||
|
|||
|
|||
class MeasurePauli(Measure): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://github.com/Qiskit/qiskit-terra/pull/5311/files#r810538319
class MeasurePauli(Measure): | |
class MeasurePauli(Instruction): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Strong +1. MeasurePauli should not be a subclass of Measure.
Quantum measurement in the computational basis. | ||
Quantum measurement |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would leave this file as it is and move measure_pauli
to its own file.
if isinstance(op, (Measure, MeasurePauli)): | ||
if isinstance(op, Measure): | ||
basis = "Z" | ||
else: | ||
basis = op.params | ||
self._measure(node, basis=basis) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is an example of a bug mentioned in https://github.com/Qiskit/qiskit-terra/pull/5311/files#r810538319 (it always get basis = "Z"
and the basis = op.params
branch is never taken).
A possible work around for this case might look something like this:
if isinstance(op, (Measure, MeasurePauli)): | |
if isinstance(op, Measure): | |
basis = "Z" | |
else: | |
basis = op.params | |
self._measure(node, basis=basis) | |
if isinstance(op, MeasurePauli): | |
self._measure(node, basis=''.join(op.params)) | |
elif isinstance(op, Measure): | |
self._measure(node, basis='Z') |
if isinstance(op, (Measure, MeasurePauli)): | ||
if isinstance(op, Measure): | ||
gate = MeasureFrom() | ||
else: | ||
basis = op.params.upper() | ||
gate = MeasureFrom(basis) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a very similar situation than here: https://github.com/Qiskit/qiskit-terra/pull/5311/files#r810540202
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeap.. same situation (this might need a test)
circuit = QuantumCircuit(6, 6)
circuit.measure_pauli("x", [0], [0])
circuit.barrier()
circuit.measure_pauli("y", [1], [1])
circuit.barrier()
circuit.measure_pauli("z", [2], [2])
circuit.barrier()
circuit.measure_pauli("xyz", [3, 4, 5], [3, 4, 5])
print(circuit)
┌─┐ ░ ░ ░
q_0: ┤M├─░─────░─────░────
└╥┘ ░ ┌─┐ ░ ░
q_1: ─╫──░─┤M├─░─────░────
║ ░ └╥┘ ░ ┌─┐ ░
q_2: ─╫──░──╫──░─┤M├─░────
║ ░ ║ ░ └╥┘ ░ ┌─┐
q_3: ─╫──░──╫──░──╫──░─┤M├
║ ░ ║ ░ ║ ░ └╥┘
q_4: ─╫──░──╫──░──╫──░──╫─
║ ░ ║ ░ ║ ░ ║
q_5: ─╫──░──╫──░──╫──░──╫─
║ ░ ║ ░ ║ ░ ║
c: 6/═╩═════╩═════╩═════╩═
0 1 2 3
So, same workaround?
if isinstance(op, (Measure, MeasurePauli)): | |
if isinstance(op, Measure): | |
gate = MeasureFrom() | |
else: | |
basis = op.params.upper() | |
gate = MeasureFrom(basis) | |
if isinstance(op, (Measure, MeasurePauli)): | |
if isinstance(op, MeasurePauli): | |
gate = MeasureFrom(''.join(op.params)) | |
elif isinstance(op, Measure): | |
gate = MeasureFrom() |
The multi-qubits feature makes this PR a bit tricky. My main red flag is that multi-qubits, in this context, implies multi-clbit Considering that and since it seems kinda trivial for a backend to detect a sequence of measures, is this feature worthy? If we are okey with removing it, then we just need to add the instructions |
Sounds fine for me. |
Single qubit measure is okey with me -- as current measurement instruction does. User can write a macro for mutiqubit measure if they really want. The important point for me is pauli measure instruction will add more context to the circuit and they make the code and visualized circuit more readable. |
As I said, I agree with the move to single-qubit. However I recommend to read a bit of discussion about it in #4024, which remained without conclusions. What's everybody's opinion:
|
Sorry to cut in, what about an idea in the middle? That is introducing |
closing in favor of #7716 |
I thought some qiskit-application developers may want a general PauliMeasure interface (but I myself had no concrete use case), while there is a clear need for single-qubit Measures from qiskit-experiments. So it makes sense to introduce single-qubit Measures at this moment. Provided we introduce single-qubit Measures, I think we should not introduce |
Multi-qubit Pauli measurements are essential for lattice surgery fault-tolerant QC (for example https://arxiv.org/pdf/1808.02892). While it is not relevant for current hardwares, Qiskit supporting multi-qubit Pauli measurements would be nice for those who are interested in making a compiler for FTQC. I hope this feature is integrated into Qiskit soon. |
Reviving #4024.
Fixes #3967
The conversation of #4024 dealt with the addition of gates after measurement. When does the removal of such gates, after final measurements, occur? The output of
transpile
still contains the gates after the final measurement.To do items:
Allow also measurement in theI
basis (no measurement).