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.28k stars 2.37k forks source link

Wrong operation names when loading/exporting circuits using QASM2 #13166

Open cbjuan opened 2 months ago

cbjuan commented 2 months ago

Environment

What is happening?

Loading/exporting QASM2 code gives sometimes wrong operation names for gates like ECR or RZX, leading to errors like

qiskit.qasm2.exceptions.QASM2ParseError: "<input>:11,39: 'rzx_4520860432_5206602512' is not defined in this scope"

or showing gate name patterns like ecr_.* or rzx_.* when listing the operations available in the circuit.

How can we reproduce the issue?

QASM2

from qiskit.circuit import QuantumCircuit
from qiskit import qasm2, transpile
from qiskit_ibm_runtime import QiskitRuntimeService

num_qubits = 16
circuit = QuantumCircuit(num_qubits)
for i in range(num_qubits-1):
    circuit.ecr(i,i+1)

runtime_service = QiskitRuntimeService(channel="ibm_quantum")
backend = runtime_service.backend("ibm_sherbrooke")

def transpile_qasm(qc):
    qc = qasm2.loads(qasm2.dumps(qc), custom_instructions=qasm2.LEGACY_CUSTOM_INSTRUCTIONS)
    tqc = transpile(qc, backend=backend, optimization_level=3, seed_transpiler=123)
    tqc = qasm2.loads(qasm2.dumps(tqc), custom_instructions=qasm2.LEGACY_CUSTOM_INSTRUCTIONS)
    return tqc

transpiled_circuit = transpile_qasm(circuit)
print({data.name for data in transpiled_circuit.data})

What should happen?

Get the expected names for the different operations ("ecr", "rzx", etc) instead of names like "rzx_4520860432_5206602512" or "ecr_140645991950416"

Any suggestions?

No response

cbjuan commented 2 months ago

Related to https://github.com/Qiskit/qiskit-ibm-transpiler/issues/73

jakelishman commented 2 months ago

The integer suffixes are expected for now, and are correct (safe) behaviour - the fault here lies in the line qc = qasm2.loads(...) in the function. As mentioned offline, neither rzx nor ecr are gate that are known to OpenQASM 2, and are not present in qelib1.inc, so the exporter must define them. On re-import, we cannot assume that a gate statement actually corresponds precisely to Qiskit's gate of the same name. It's doable for us to determine if an ecr definition matches, but not in general for us to determine if some specification of a parametric gate is compatible with Qiskit's version (and any magic inference like this is rather expensive from a performance perspective).

qasm2.LEGACY_CUSTOM_INSTRUCTIONS is explained in the documentation - it doesn't contain ecr or rzx (https://docs.quantum.ibm.com/api/qiskit/qasm2#legacy-compatibility) and won't be updated to include them because it's a backwards-compatibility object only. We don't currently have a data object available that supplies all of the Qiskit standard gates (see #10737), but you can easily add ecr and rzx to the list you're passing there, using CustomInstruction. Since this issue keeps being raised, here's explicitly how you do it:

from qiskit.circuit import library
from qiskit import qasm2

custom = list(qasm2.LEGACY_CUSTOM_INSTRUCTIONS) + [
    qasm2.CustomInstruction("ecr", 0, 2, library.ECRGate),
    qasm2.CustomInstruction("rzx", 1, 2, library.RZXGate),
]

def roundtrip(qc):
    dumped = qasm2.dumps(qc)
    return qasm2.loads(dumped, custom_instructions=custom)

The way to "fix" the integer suffixes so they don't appear by default is for us to define new library files that are specific to Qiskit. Then we won't have any of the problems of needing to make assumptions about arbitrary user input, because we supply the header files. We've got the design in #10737, but as I've mentioned before, we haven't had the time or priority to implement it yet.


Within the presence of the integer suffixes, there is a bug here on the second export (which I thought I'd fixed before) - the ordering of the gate statements in the second dump is somehow coming out out of order. I don't know precisely why that is right now, but I'll look into it, thanks.