JaimePSantos / JaimePSantos/Dissertation-Tex-Code

BUG: measurement after transpilation level 3 in Grover circuit

Open
#25 1 comment 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.