Qiskit / qiskit

Qiskit is an open-source SDK for working with quantum computers at the level of extended quantum circuits, operators, and primitives.
https://www.ibm.com/quantum/qiskit
Apache License 2.0
5.11k stars 2.34k forks source link

result of statevector simulation would be incorrect if there is any qubit permutation during transpilation #2980

Closed chunfuchen closed 5 years ago

chunfuchen commented 5 years ago

Information

What is the current behavior?

the transpiler transpiles the circuits and the result of statevector simulation is incorrect but qasm simulator is okay.

Circuit before transpile image After: image

Steps to reproduce the problem

from qiskit import QuantumCircuit, QuantumRegister, BasicAer, execute
from qiskit.quantum_info import state_fidelity
from qiskit.compiler import transpile

backend = BasicAer.get_backend('statevector_simulator')

qr = QuantumRegister(2)
qc = QuantumCircuit(qr)

qc.y(qr[0])
qc.x(qr[1])
qc.cx(qr[0], qr[1])

t_qc = transpile(qc, coupling_map=[[0, 1]])

print(qc)
print(t_qc)

state_wo_t = execute(qc, backend=backend, optimization_level=0).result().get_statevector()
state_w_t = execute(t_qc, backend=backend).result().get_statevector()
print(state_fidelity(state_wo_t, state_w_t))
the state_fidelity is 0.0 for above example.

What is the expected behavior?

When a coupling map is given, the transpile should assure the quantum state is the same up to global phase (state fidelity should be close to 1.)

Furthermore, why the transpiled circuit generates h gates?

Suggested solutions

I do not know, this issue happened after the DenseLayout is used for default transpiler.

mtreinish commented 5 years ago

The dense layout change is being reverted here: https://github.com/Qiskit/qiskit-terra/pull/2975 Does that fix the issue for you?

nonhermitian commented 5 years ago

How does the dense layout break this? This is having the cx reversed for no reason.

chunfuchen commented 5 years ago

@mtreinish yes, after I pull the newest change, it works. However, dense layout is used for optimizaton level 2, this issue will happen again if a user would like to do more aggressive circuit optimization

for example, the following code won't work

from qiskit import QuantumCircuit, QuantumRegister, BasicAer, execute
from qiskit.quantum_info import state_fidelity
from qiskit.compiler import transpile

backend = BasicAer.get_backend('statevector_simulator')

qr = QuantumRegister(2)
qc = QuantumCircuit(qr)

qc.y(qr[0])
qc.x(qr[1])
qc.cx(qr[0], qr[1])

state_wo_t = execute(qc, backend=backend, coupling_map=[[0, 1]], optimization_level=0).result().get_statevector()
state_w_t = execute(qc, backend=backend, coupling_map=[[0, 1]], optimization_level=2).result().get_statevector()
print(state_fidelity(state_wo_t, state_w_t))
nonhermitian commented 5 years ago

You get the same incorrect answer if you do:

transpile(qc, coupling_map=[[0, 1]], optimization_level=1, initial_layout=[1,0])

because you are not taking into account the permutation due to the differing layouts.

chunfuchen commented 5 years ago

Yes, the transpiler permutates the qubit mapping; however, the statevector always considers the first qubit is qubit 0, then the statevector result is incorrect. Is this users' responsiblity to post-process the statevector?

nonhermitian commented 5 years ago

It is not incorrect, it is not just in the same order as the other one. Just set initial layout to list(range(n_qubits)) and it will work at all optimization levels.

chunfuchen commented 5 years ago

as suggested above, by specifying the initial_layout=list(range(num_qubits)) will disallow the transpiler to perform swapping qubits, which assure the statevector results are correct. I closed this issue since that fixes the issue; however, I wonder that is there any way to warn the users if their setting will result in the qubit swapping when using statevector simulator.