JaimePSantos / JaimePSantos/Dissertation-Tex-Code
BUG: measurement after transpilation level 3 in Grover circuit
- Dominant language
- Jupyter Notebook
- Stars
- 0
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
Description
# Environment
- **qiskit.__version__**: 0.22.0
- **Python version**: 3.8.0
- **Operating system**: Ubuntu 18.04
# What is happening?
The quantum circuit in file [groverFuncs.py](https://github.com/JaimePSantos/Dissertation-Tex-Code/blob/15544a4334f61e670d1eeee9849fd168c468863d/Coding/Qiskit/AllSearch/groverFuncs.py#L52) is transpiled and then gets the measurement gate added to it.
Unfortunately, the transpilation is done with the `optimization_level=3` option, which means that the measurements plays an important role in the optimization.
For example, `OptimizeSwapBeforeMeasure` is a pass that removes the swap gates before the measurement, leading to a non-equivalent circuit (See the doc regarding this level 3: [here](https://qiskit.org/documentation/_modules/qiskit/transpiler/preset_passmanagers/level3.html)).
# How can we reproduce the issue?
If you run this code, you can see whether the result is affected by the mistake of adding the measurement after the transpilation.
```python
import numpy as np
from qiskit import *
def markedListGrover(markedList,N):
oracleList = np.ones(2**N)
for element in markedList:
oracleList[element] = -1
return oracleList.tolist()
def getOracle(markedList,N):
oracleList = np.eye(2**N)
for element in markedList:
oracleList[element][element] = -1
return oracleList
def oracleGrover(markedList,N):
qreg = QuantumRegister(N)
qc = QuantumCircuit(qreg,name='Oracle')
qc.diagonal(markedList,qreg)
qc=transpile(qc,optimization_level=3)
return qc
def diffusionGrover(N):
qreg = QuantumRegister(N)
difCirc = QuantumCircuit(qreg,name='Diffusion')
difCirc.h(qreg)
aux = markedListGrover([0],N)
qcAux = oracleGrover(aux,N)
difCirc.append(qcAux,range(N))
difCirc.h(qreg)
difCirc=transpile(difCirc,optimization_level=3)
return difCirc
def grover(marked,N,backend,steps):
qc = QuantumCircuit(N,N)
qcOracle = oracleGrover(markedListGrover(marked,N),N)
qcDiffusion = diffusionGrover(N)
qc.h(range(N))
for i in range(steps):
qc.append(qcOracle,range(N))
qc.barrier()
qc.append(qcDiffusion,range(N))
qc.barrier()
qc = transpile(qc,basis_gates=['cx','u3','u2','u1','id'],backend=backend,optimization_level=3)
qc.barrier()
qc.measure(range(N),range(N))
return qc
def grover_transpile_after_measurement(marked,N,backend,steps):
qc = QuantumCircuit(N,N)
qcOracle = oracleGrover(markedListGrover(marked,N),N)
qcDiffusion = diffusionGrover(N)
qc.h(range(N))
for i in range(steps):
qc.append(qcOracle,range(N))
qc.barrier()
qc.append(qcDiffusion,range(N))
qc.barrier()
qc.barrier()
qc.measure(range(N),range(N))
qc = transpile(qc,basis_gates=['cx','u3','u2','u1','id'],backend=backend,optimization_level=3)
return qc
def simul(qc):
backend = Aer.get_backend('qasm_simulator')
result = execute(qc,backend,shots=3000).result().get_counts()
return result
N = 4
n = N-1
backend = Aer.get_backend('qasm_simulator')
qcG_w_transpile = grover([1],N,backend,2)
qcG_w_transpile_after_measurement = grover_transpile_after_measurement([1],N,backend,2)
gQasm_w_transpile = simul(qcG_w_transpile)
gQasm_w_transpile_after_measurement = simul(qcG_w_transpile_after_measurement)
print("Grover size (transpiled): ", qcG_w_transpile.size())
print("Grover size (transpiled after measurement): ", qcG_w_transpile_after_measurement.size())
assert qcG_w_transpile.qasm() != qcG_w_transpile_after_measurement.qasm(), 'the two qasm files are identical'
```
Output:
```
Grover size (transpiled): 135
Grover size (transpiled after measurement): 135
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
/home/user/Test.ipynb Cell 19 in 1
109 print("Grover size (transpiled): ", qcG_w_transpile.size())
110 print("Grover size (transpiled after measurement): ", qcG_w_transpile_after_measurement.size())
--> 111 assert qcG_w_transpile.qasm() != qcG_w_transpile_after_measurement.qasm(), 'the two qasm files are identical'
AssertionError: the two qasm files are identical
```
In this case, luckily the optimization did not affected the result, but it might have happened.
# What should happen?
I would have expected the version with transpilation as last step, since it is more robust.
# Any suggestions?
I would recommend to move the measurement before the transpilation. Following the recommendation of Qiskit developers. See [here](https://github.com/Qiskit/qiskit-terra/issues/7642#issuecomment-1049280234)
Contributor guide
No contributing guide indexed for this repository
Research direction
Inspect Coding/Qiskit/AllSearch/groverFuncs.py around the circuit construction and transpile calls. Compare grover with grover_transpile_after_measurement using the supplied reproduction and Qiskit’s level-3 transpiler documentation. Done means the measurement ordering is corrected and the Grover circuits no longer rely on transpiling before measurement.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- quantum-computing
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 38/100