unitaryfund / mitiq

Mitiq is an open source toolkit for implementing error mitigation techniques on most current intermediate-scale quantum computers.
https://mitiq.readthedocs.io
GNU General Public License v3.0
358 stars 157 forks source link

Passing a Qiskit circuit to mitiq digital dynamic decoupling method triggers error in Qiskit #1396

Closed epelofske-LANL closed 2 years ago

epelofske-LANL commented 2 years ago

Issue Description

Passing a specific Qiskit circuit to ddd.insert_ddd_sequences() throws an error qiskit.circuit.exceptions.CircuitError

Code Snippet

example.qasm.txt

from qiskit import QuantumCircuit
from mitiq import ddd

xx_rule = ddd.rules.xx
qc = QuantumCircuit.from_qasm_file("example.qasm.txt")
circuit_with_ddd = ddd.insert_ddd_sequences(qc, rule=xx_rule)

It is possible to get around this error by using the following code instead:

from qiskit import QuantumCircuit
from mitiq import ddd
from mitiq.interface.mitiq_qiskit.conversions import from_qiskit
from mitiq.interface.mitiq_qiskit.conversions import to_qiskit

xx_rule = ddd.rules.xx
qc = QuantumCircuit.from_qasm_file("example.qasm.txt")

qc = from_qiskit(qc)
circuit_with_ddd = ddd.insert_ddd_sequences(qc, rule=xx_rule)
circuit_with_ddd = to_qiskit(circuit_with_ddd)

Error Output

Traceback (most recent call last):
  File "/Users/user/test.py", line 6, in <module>
    circuit_with_ddd = ddd.insert_ddd_sequences(qc, rule=xx_rule)
  File "//anaconda3/envs/env/lib/python3.9/site-packages/mitiq/ddd/insertion.py", line 107, in insert_ddd_sequences
    return _insert_ddd_sequences(circuit, rule)
  File "//anaconda3/envs/env/lib/python3.9/site-packages/mitiq/interface/conversions.py", line 304, in new_scaling_function
    scaled_circuit.measure(q, c)
  File "//anaconda3/envs/env/lib/python3.9/site-packages/qiskit/circuit/quantumcircuit.py", line 2173, in measure
    return self.append(Measure(), [qubit], [cbit])
  File "//anaconda3/envs/env/lib/python3.9/site-packages/qiskit/circuit/quantumcircuit.py", line 1205, in append
    expanded_cargs = [self.cbit_argument_conversion(carg) for carg in cargs or []]
  File "//anaconda3/envs/env/lib/python3.9/site-packages/qiskit/circuit/quantumcircuit.py", line 1205, in <listcomp>
    expanded_cargs = [self.cbit_argument_conversion(carg) for carg in cargs or []]
  File "//anaconda3/envs/env/lib/python3.9/site-packages/qiskit/circuit/quantumcircuit.py", line 1117, in cbit_argument_conversion
    return _bit_argument_conversion(
  File "//anaconda3/envs/env/lib/python3.9/site-packages/qiskit/circuit/quantumcircuit.py", line 4811, in _bit_argument_conversion
    raise CircuitError(f"Bit '{specifier}' is not in the circuit.")
qiskit.circuit.exceptions.CircuitError: "Bit 'Clbit(ClassicalRegister(7, 'meas'), 0)' is not in the circuit."

Environment Context

Mitiq about():

Mitiq: A Python toolkit for implementing error mitigation on quantum computers
==============================================================================
Authored by: Mitiq team, 2020 & later (https://github.com/unitaryfund/mitiq)

Mitiq Version:  0.17.0

Core Dependencies
-----------------
Cirq Version:   0.14.1
NumPy Version:  1.20.3
SciPy Version:  1.7.3

Optional Dependencies
---------------------
PyQuil Version: 3.0.1
Qiskit Version: 0.36.2
Braket Version: 1.23.2

Python Version: 3.9.7
Platform Info:  Darwin (x86_64)

Additional Python Environment Details:

`conda list` output:

mitiq                     0.17.0                   pypi_0    pypi
pennylane-qiskit          0.18.0                   pypi_0    pypi
qiskit                    0.36.2                   pypi_0    pypi
qiskit-aer                0.10.4                   pypi_0    pypi
qiskit-aqua               0.9.2                    pypi_0    pypi
qiskit-experiments        0.2.0                    pypi_0    pypi
qiskit-ibmq-provider      0.19.1                   pypi_0    pypi
qiskit-ignis              0.7.1                    pypi_0    pypi
qiskit-rigetti            0.4.5                    pypi_0    pypi
qiskit-terra              0.20.2                   pypi_0    pypi
qiskit-textbook           0.1.0                    pypi_0    pypi
cirq                      0.14.1                   pypi_0    pypi
cirq-aqt                  0.14.1                   pypi_0    pypi
cirq-core                 0.14.1                   pypi_0    pypi
cirq-google               0.14.1                   pypi_0    pypi
cirq-ionq                 0.14.1                   pypi_0    pypi
cirq-pasqal               0.14.1                   pypi_0    pypi
cirq-rigetti              0.14.1                   pypi_0    pypi
cirq-web                  0.14.1                   pypi_0    pypi
github-actions[bot] commented 2 years ago

Hello @epelofske-LANL, thank you for your interest in Mitiq! If this is a bug report, please provide screenshots and/or minimum viable code to reproduce your issue, so we can do our best to help get it fixed. If you have any questions in the meantime, you can also ask us on the Unitary Fund Discord.

andreamari commented 2 years ago

Thanks @epelofske-LANL for the bug report. I think there are problems with the current code of mitiq.ddd in the case in which there are measurements in the circuit.

This could be fixed by changing the code of insert_ddd_equences and maybe also in the code of _get_circuit_mask as follows:

Aaron-Robertson commented 2 years ago

Thanks for finding this one @epelofske-LANL! I'm happy to fix it up, collaborate on a fix, or hand it off to you. I'll assign myself for now, but just let me know if you have a different preference.

epelofske-LANL commented 2 years ago

@Aaron-Robertson Feel free to go ahead if you have a fix; I am not sure how to implement a fix (largely because I am not terribly familiar with mitiq).

andreamari commented 2 years ago

Thanks @Aaron-Robertson !

andreamari commented 2 years ago

Hi @Aaron-Robertson, any update on this?

In general I think many DDD problems that we currently have are related to the presence of measurement gates in the middle of the circuits. In these cases, Mitiq erroneously tries to insert DDD gates in idle windows that are present after the measurement gates.

I think the bug may be fixed using cirq.synchronize_terminal_measurements() somewhere in the Mitiq noise_scaling_converter or in the insert_ddd_sequences function (or both).

It is fine to always enforce/assume that measurements are all terminal and in the same moment. We could raise an error if it is not so.

Not sure if you are doing similar things, so I don't want to overlap. Maybe we can have a call on Discord when you have time.