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.03k stars 2.32k forks source link

Transpiled circuit with optimization level 3 is not equivalent to the original circuit #7961

Closed pranavm1502 closed 2 years ago

pranavm1502 commented 2 years ago

Informations

What is the current behavior?

Transpiled 2qubit circuit with optimization level 3 is not equivalent to the original circuit

Steps to reproduce the problem

Look at the attached jupyter notebook Qiskit transpiler level 3 investigation.ipynb.zip

What is the expected behavior?

The result outputs should be same (upto shot noise).

Suggested solutions

jakelishman commented 2 years ago

Thanks for the report!

This particular case is the exact same behaviour that causes #7341, where discussion seems to have stalled a little bit. The trick is that the synthesis routines in the transpiler have some approximations turned on by default (whether or not they should be doing that is another question...). You can work around the issue by setting approximation_degree=0 in the call to transpile.

For others, a more minimal reproducer of the error:

import qiskit
from qiskit.test.mock import FakeLagos
import numpy as np

backend = FakeLagos()
circuit = qiskit.QuantumCircuit(2)
for i in range(4):
    circuit.rz(3*np.pi/4, 1)
    circuit.sx(1)
    circuit.cnot(0,1)

approximate = qiskit.transpile(circuit, backend=backend, optimization_level=3, approximation_degree=None)
exact = qiskit.transpile(circuit, backend=backend, optimization_level=3, approximation_degree=0)

def reduce_circuit(circuit):
    """Quick hack to reduce a larger circuit to the minimal set of qubits."""
    active_qubits = set()
    for _, qargs, _ in circuit.data:
        active_qubits.update(qargs)
    bit_map = {bit: i for i, bit in enumerate(active_qubits)}
    out = qiskit.QuantumCircuit(len(bit_map))
    out.global_phase = circuit.global_phase
    for op, qargs, _ in circuit.data:
        out.append(op, [bit_map[q] for q in qargs], [])
    return out

approximate = reduce_circuit(approximate)
exact = reduce_circuit(exact)

You can then see that (using qiskit.quantum_info.Operator to get the matrix form of the circuits) that Operator(circuit) is equal to Operator(exact), but not to Operator(approximate).

pranavm1502 commented 2 years ago

Thanks Jake! Setting the approximation_degree=0 indeed solves the problem.

I would suggest that by default it should always be set to zero until the issue is resolved. Incorrect transpilation on a 5 CNOT 2Q circuit sounds like a bad default setting.

1ucian0 commented 2 years ago

Since this is already tacked by https://github.com/Qiskit/qiskit-terra/issues/8043, closing. Thanks @pranavm1502 !