Skip to content
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

Transpiler changes circuit semantics #13118

Closed
Bennybenassius opened this issue Sep 10, 2024 · 1 comment · Fixed by #13121
Closed

Transpiler changes circuit semantics #13118

Bennybenassius opened this issue Sep 10, 2024 · 1 comment · Fixed by #13121
Labels
bug Something isn't working

Comments

@Bennybenassius
Copy link

Environment

  • Qiskit version: 1.3.0
  • Python version: 3.10.12
  • Operating system: Ubuntu 22.04 LTS on Windows 11 WSL

What is happening?

Ilan and I have found a possible miscompilation caused by the transpiler.

The resulting state-vector of the circuit after putting it through transpile() changes abruptly after optimization level has been set to above 2, thereby also changing the states of the circuit upon measurement.

How can we reproduce the issue?

from qiskit import QuantumCircuit
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.quantum_info import Statevector
from numpy import vdot

def simulate_circuit(qc : QuantumCircuit):
    state = Statevector.from_int(0, 2**qc.num_qubits)
    state = state.evolve(qc)
    return state

def compare_statevectors(qc : QuantumCircuit):
    # Need to set the seed for consistent transpiler pass results across optimisation levels
    options = {'seed_transpiler': 1235}
    sv0 = simulate_circuit(qc)
    # Code for checking different levels of optimization levels and if they are the same
    for i in range(4):
        pass_manager = generate_preset_pass_manager(optimization_level=i, **options)
        transpiled_circuit = pass_manager.run(qc)
        sv = simulate_circuit(transpiled_circuit)
        # Uncomment to see statevector
        # print(sv) 
        if(sv0 == sv):
            print("Level ", i, " passed")
        else:
            print("Failed level ", i, ". Dot product is: " , abs(vdot(sv0, sv)), "\n")

subcirc2 = QuantumCircuit(2)
subcirc2.z(0)
subcirc2.h(0)
subcirc2.z(0)
subcirc2.s(1)
subcirc2 = subcirc2.to_gate().control(1)

main_circ = QuantumCircuit(4)
main_circ.h(0)
main_circ.append(subcirc2,[0, 2, 3])
main_circ.append(subcirc2,[0, 2, 3])
main_circ.append(subcirc2,[0, 2, 3])
main_circ.h(2)

compare_statevectors(main_circ)

Running the above code will reveal that the state-vectors are different when the optimization level is above 2. The results will also be the same if the circuit was instead run on AerBackend, with optimization levels 2 and 3 producing very different measured states than levels 0 and 1.

This is done on the latest version of qiskit (1.3.0), which we have compiled from source to get the latest fixes. However, it seems like this issue is also present in version 1.2.0.

What should happen?

The circuit should not have a different state-vector after putting it through the transpiler.

Any suggestions?

No response

@Bennybenassius Bennybenassius added the bug Something isn't working label Sep 10, 2024
@Cryoris
Copy link
Contributor

Cryoris commented Sep 10, 2024

It looks like #12704 introduced this bug, after Consolidate2qBlocks it appears the unitary is not correct anymore. Though this is quite fragile to reproduce, e.g. removing the h gate from the subcircuit or from the main_circuit the unitary is still correct.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants