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.1k stars 2.34k forks source link

Qiskit’s OpenQASM 3 exporter: not correctly escaping the names of custom gates it’s defining #11761

Closed felicitysplatt closed 2 months ago

felicitysplatt commented 7 months ago

Environment

What is happening?

I submit a job to the IBM Platform, a max cut using QAOA, for very simple circuits (less than 10 nodes, few edges). This will produce a parameterized circuit. The OpenQASM 3 string created cannot be drawn - there's something wrong with the string, likely not correctly escaping the names of custom gates it's defining.

Jake Lishman has requested I submit this bug report.

Here's an example of a string it produces:

""" OPENQASM 3; include "stdgates.inc"; input float[64] _β0; input float[64] _γ0; gate exp(it IZ)(_γ0) _gate_q_0, _gate_q_1 { rz(5.00) _gate_q_0; } gate rzz_140434630696240(_γ0) _gate_q_0, _gate_q_1 { cx _gate_q_0, _gate_q_1; rz(1.00) _gate_q_1; cx _gate_q_0, _gate_q_1; } gate exp(it ZZ)(_γ0) _gate_q_0, _gate_q_1 { rzz_140434630696240(1.0*_γ0) _gate_q_0, _gate_q_1; } gate PauliEvolution(_γ0) _gate_q_0, _gate_q_1 { exp(it IZ)(_γ0) _gate_q_0, _gate_q_1; exp(it ZZ)(_γ0) _gate_q_0, _gate_q_1; } bit[2] meas; qubit[2] q; h q[0]; h q[1]; PauliEvolution(_γ0) q[0], q[1]; PauliEvolution(_β0) q[0], q[1]; barrier q[0], q[1]; meas[0] = measure q[0]; meas[1] = measure q[1]; """

How can we reproduce the issue?

This code will not run for you as it depends on some custom functions and config files.

However, the problem should be reproducible from the concept - we are creating a really straightforward QAOA / maxcut problem.

from docplex.mp.model import Model
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit_optimization.translators import from_docplex_mp
from qiskit_ibm_runtime import QiskitRuntimeService, Session, Sampler, Options
from qiskit_algorithms import QAOA
from qiskit_algorithms.optimizers import COBYLA, SPSA
from qiskit_aer.noise import NoiseModel

from quantum_computing_for_energy_sector.settings import load_config
from quantum_computing_for_energy_sector.utils import root_path, read_args, show_graph
from quantum_computing_for_energy_sector.logging_config import logger

token = load_config(root_path(".venv", "IBMQ-API-token.yml"))
args = read_args()

device_config = load_config(args.device_conf_file)
logger.info(f"Device config: {device_config}")

service = QiskitRuntimeService(
    channel = "ibm_quantum",
    token = token["IBM_Quantum_API_key"]
)

if device_config["device"] == "Simulator":
    backend = service.backend(device_config["simulator"])

backend = service.least_busy(operational=True, simulator=False)
graph_config = load_config(args.graph_conf_file)

number_of_nodes = len(graph_config["nodes"])
edges = [(edge['first_node'], edge['second_node'], edge['weight']) for edge in graph_config["edges"]]

model = Model()

x = model.binary_var_list(number_of_nodes)
model.maximize(model.sum(w * x[i] * (1 - x[j]) + w * (1 - x[i]) * x[j] for i, j, w in edges))

model.add(x[0] == 1)

problem = from_docplex_mp(model)

optimizer = COBYLA(maxiter = device_config["maxiter"])

session = Session(backend = backend)
options = Options()

sampler = Sampler(session = session, options = options)

qaoa = QAOA(sampler=sampler, optimizer=optimizer)
algorithm = MinimumEigenOptimizer(qaoa)
result = algorithm.solve(problem)

What should happen?

The code above will run - that is not the problem.

The problem is the OpenQASM 3 string that qiskit generates on the IBM Quantum Platform - this string has a bug in it. A circuit cannot be drawn from that string.

Any suggestions?

No response

jakelishman commented 7 months ago

Thanks for the report. We have logic that does this in the OpenQASM 2 exporter, so I think we must have forgotten to port over similar behaviour to the OpenQASM 3 exporter.

jakelishman commented 2 months ago

I believe this should be fixed by #12776, but since I can't generate the exact initial circuit to check, I'm not absolutely 100% sure. I'll mark it as "being fixed", and if I'm wrong, feel free to re-open (if it closes).