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
4.72k stars 2.26k forks source link

Something weird happening in transpile after 1.1 release #12425

Closed nkanazawa1989 closed 1 week ago

nkanazawa1989 commented 2 weeks ago

Environment

What is happening?

I noticed Qiskit Experiments tests relying on Qiskit Aer are now all failing, for example 1414. According to the error log the aer simulator backend reports basis gates which is a subset of what it can actually support. This is not a bug in Qiskit Aer.

How can we reproduce the issue?

For example

from qiskit_aer import AerSimulator
from qiskit_experiments.library import StateTomography
import qiskit.quantum_info as qi

seed = 1234
shots = 5000
f_threshold = 0.99

num_qubits = 1

# Generate tomography data without analysis
backend = AerSimulator(seed_simulator=seed, shots=shots)
target = qi.random_statevector(2**num_qubits, seed=seed)

exp = StateTomography(target)
expdata = exp.run(backend, analysis=None)

This code works okey with qiskit==1.0.2. However with 1.1.0 I get this error

TranspilerError: "Unable to translate the operations in the circuit: ['measure', 'h', 'initialize', 'barrier'] to the backend's (or manually specified) target basis: ['store', 'initialize', 'measure', 'barrier', 'snapshot']. This likely means the target basis is not universal or there are additional equivalence rules needed in the EquivalenceLibrary being used. For more details on this error see: https://docs.quantum.ibm.com/api/qiskit/transpiler_passes.BasisTranslator#translation-errors"

What should happen?

Transpile should work as before.

Any suggestions?

I don't know. I'll investigate.

nkanazawa1989 commented 2 weeks ago

Maybe due to this change https://github.com/Qiskit/qiskit/pull/12410? After this PR, outside parallel environment we bypass PM serialization but this means every run share the same state. I confirmed

transpile(exp.circuits()[0], backend=backend, initial_layout=[0])

works okey

transpile(exp.circuits(), backend=backend, initial_layout=[0])

errors.

This makes me think some compiler pass unexpectedly mutate Target information or some stateful pass is not reset after run.

nkanazawa1989 commented 2 weeks ago

Also confirmed the backend target is not mutated. So this is likely due to pass state issue.

t-imamichi commented 2 weeks ago

It's interesting. It works with BasicSimulator but fails with AerSimulator. I made a simple case to reproduce it.

macOS 14.5 arm qiskit 1.1.0 qiskit-aer 0.14.1

from qiskit import QuantumCircuit, transpile
from qiskit.providers.basic_provider import BasicSimulator
from qiskit_aer import AerSimulator

qc = [QuantumCircuit(1) for _ in range(2)]
qc[0].rx(0, 0)
qc[1].p(0, 0)

# OK
backend = BasicSimulator()
_ = transpile(qc, backend=backend)

# NG
backend = AerSimulator()
_ = transpile(qc, backend=backend)

# qiskit.transpiler.exceptions.TranspilerError: "Unable to translate the operations in the circuit: ['p'] to the backend's (or manually specified) target basis: ['measure', 'barrier', 'store', 'snapshot', 'rx']. This likely means the target basis is not universal or there are additional equivalence rules needed in the EquivalenceLibrary being used. For more details on this error see: https://docs.quantum.ibm.com/api/qiskit/transpiler_passes.BasisTranslator#translation-errors"
nkanazawa1989 commented 2 weeks ago

I also confirmed. Then this should NOT be the pass state issue. I found another behavior.

# OK
backend = AerSimulator()
_ = transpile(qc, target=backend.target)

So this is due to weird interaction between Qiskit and QiskitAer. Perhaps this is why our unit test doesn't catch this serious problem.

mtreinish commented 2 weeks ago

I expect this is an aer bug stemming from their custom translation stage pass: https://github.com/Qiskit/qiskit-aer/blob/main/qiskit_aer/backends/plugin/aer_backend_plugin.py . That pass mutates it's own Target using explicit internal private attributes, which was always unsound, but likely was never caught because of the serialization that was changed in #12410 because the target was essentially always deepcopied between runs before.

You can probably confirm by either setting ignore_backend_supplied_default_methods=True or running translation_method=translator on the transpile call which will disable aer's custom pass.

nkanazawa1989 commented 2 weeks ago

Ah I see this is why https://github.com/Qiskit/qiskit/issues/12425#issuecomment-2116945093 runs without error. Indeed there is no Aer backend that injects that custom pass.

t-imamichi commented 2 weeks ago

Thank you for investigating this issue, Matthew. We then need to transfer this issue to Aer.

mtreinish commented 1 week ago

I'm going to close this because the underlying issue in aer was marked as closed and fixed by https://github.com/Qiskit/qiskit-aer/pull/2142. It is still waiting on a new aer release though.