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

QASM exporter producing invalid QASM #9658

Closed
vrpascuzzi opened this issue Feb 24, 2023 · 1 comment · Fixed by #9660
Closed

QASM exporter producing invalid QASM #9658

vrpascuzzi opened this issue Feb 24, 2023 · 1 comment · Fixed by #9660
Assignees
Labels
bug Something isn't working

Comments

@vrpascuzzi
Copy link
Contributor

vrpascuzzi commented Feb 24, 2023

Environment

  • Qiskit Terra version: 0.23.1
  • Python version: 3.10.9
  • Operating system: macOS Ventura 13.1

What is happening?

When a ClassicalRegister is given a name containing curly braces, QASM 3 exporter produces invalid QASM, leading to job failures in the runtime. Note that this behavior is not observed when a QuantumRegister is given a name containing curly braces.

The motivation for using the curly braces in name was to subscript the register name when calling QuantumCircuit.draw(output="mpl"), which does not work ClassicalRegister and does work for QuantumRegister, but only after transpiling (a separate but related issue, I think).

How can we reproduce the issue?

from qiskit import transpile, QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit_ibm_provider import IBMProvider

qreg = QuantumRegister(2, name="qreg")
creg = ClassicalRegister(2, name="c_{reg}")
qc = QuantumCircuit(qreg, creg)
qc.h(qreg[0])
qc.cx(qreg[0], qreg[1])
qc.measure(qreg, creg)

provider = IBMProvider()
backend = provider.get_backend("ibm_peekskill")

transpiled = transpile(qc, backend, optimization_level=0)
job = backend.run(transpiled, shots=1024, dynamic=True)
results = job.result()

Actual output

---------------------------------------------------------------------------
IBMJobFailureError                        Traceback (most recent call last)
Cell In[97], line 2
      1 job = backend.run(transpiled, shots=4096, dynamic=True)
----> 2 results = job.result()

File ~/.venvs/py310-iqx-deprecated/lib/python3.10/site-packages/qiskit_ibm_provider/job/ibm_circuit_job.py:255, in IBMCircuitJob.result(self, timeout, refresh)
    253     if self._status == JobStatus.ERROR:
    254         error_message = self.error_message()
--> 255         raise IBMJobFailureError(f"Job failed: " f"{error_message}")
    256     self._retrieve_result(refresh=refresh)
    257 return self._result

IBMJobFailureError: 'Job failed: Unknown error; Traceback (most recent call last):
2023-02-24T21:56:18.704024473Z   File "/provider/server/main.py", line 75, in execute_program
2023-02-24T21:56:18.704024473Z     starter.execute()
2023-02-24T21:56:18.704024473Z   File "/provider/programruntime/program_starter_wrapper.py", line 99, in execute
2023-02-24T21:56:18.704024473Z     raise ex
2023-02-24T21:56:18.704024473Z   File "/provider/programruntime/program_starter_wrapper.py", line 91, in execute
2023-02-24T21:56:18.704024473Z     final_result = self.main(backend, self.messenger, **self.user_params)
2023-02-24T21:56:18.704024473Z   File "/code/./program.py", line 600, in main
2023-02-24T21:56:18.704024473Z     result = backend.run(payload, **filtered_run_config).result()
2023-02-24T21:56:18.704024473Z   File "/provider/programruntime/runtime_job.py", line 80, in result
2023-02-24T21:56:18.704024473Z     self.set_final_state(raw_result)
2023-02-24T21:56:18.704024473Z   File "/provider/programruntime/runtime_job.py", line 132, in set_final_state
2023-02-24T21:56:18.704024473Z     return final_results
2023-02-24T21:56:18.704024473Z UnboundLocalError: local variable \'final_results\' referenced before assignment
2023-02-24T21:56:18.707519839Z jaeger_tracing - INFO Span publisher exited
2023-02-24T21:56:18.707845266Z webserver-starter - DEBUG Writing job status to termination marker file: \'{"status": "Failed"}\'
2023-02-24T21:56:18.708131533Z /pod-data/ CLOSE_WRITE,CLOSE terminated
2023-02-24T21:56:18.708617041Z Termination marker file found. Kill process (7).
2023-02-24T21:56:18.731898748Z /bin/bash: line 3:     7 Killed                  python -m uvicorn server.main:app --port 8081
2023-02-24T21:56:18.732227067Z Termination signal received, exited.'

QASM output

qreg and c_{reg}

OPENQASM 3;
include "stdgates.inc";
bit[2] c_{reg};
qubit[2] _all_qubits;
let qreg__generated0 = _all_qubits[0:1];
h qreg__generated0[0];
cx qreg__generated0[0], qreg__generated0[1];
c_{reg}[0] = measure qreg__generated0[0];
c_{reg}[1] = measure qreg__generated0[1];

q_{reg} and creg

OPENQASM 3;
include "stdgates.inc";
bit[2] creg__generated0;
qubit[2] _all_qubits;
let q_{reg} = _all_qubits[0:1];
h q_{reg}[0];
cx q_{reg}[0], q_{reg}[1];
creg__generated0[0] = measure q_{reg}[0];
creg__generated0[1] = measure q_{reg}[1];

q_{reg} and c_{reg}

OPENQASM 3;
include "stdgates.inc";
bit[2] c_{reg};
qubit[2] _all_qubits;
let q_{reg} = _all_qubits[0:1];
h q_{reg}[0];
cx q_{reg}[0], q_{reg}[1];
c_{reg}[0] = measure q_{reg}[0];
c_{reg}[1] = measure q_{reg}[1];

qreg and creg

OPENQASM 3;
include "stdgates.inc";
bit[2] creg__generated0;
qubit[2] _all_qubits;
let qreg__generated1 = _all_qubits[0:1];
h qreg__generated1[0];
cx qreg__generated1[0], qreg__generated1[1];
creg__generated0[0] = measure qreg__generated1[0];
creg__generated0[1] = measure qreg__generated1[1];

What should happen?

results should contain expected Result for the given circuit.

Any suggestions?

@jakelishman mentioned, "[it] sounds like there’s some place where the exporter fails to normalise an identifier into something exportable."

@vrpascuzzi vrpascuzzi added the bug Something isn't working label Feb 24, 2023
@jakelishman jakelishman self-assigned this Feb 24, 2023
@jakelishman
Copy link
Member

Now I think about it, I know how this came about: originally, there was no need to test the register names for special symbols because they were constrained to only be valid OQ2 identifiers (i.e. [a-z][a-zA-Z0-9_]*) during the construction of the object, which is a strict subset of valid OQ3 identifiers once extra keywords are removed too. When that restriction was relaxed in #9100 it became possible in the OQ3 exporter to have an invalid register name.

I'm vaguely surprised that it doesn't cause similar problems for quantum registers, but no big deal.

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