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.03k stars 2.32k forks source link

Opt. Lvl. 2: commutation analysis `Cannot apply operation with classical bits: measure` #10470

Open MattePalte opened 1 year ago

MattePalte commented 1 year ago

Environment

What is happening?

When I append a circuit (using classical bits) to another circuit, the transpiler fails with an error (optimization level 2).

How can we reproduce the issue?

Run this python script:

from qiskit import QuantumCircuit
from qiskit import QuantumRegister, ClassicalRegister
from qiskit.compiler import transpile
q = QuantumRegister(2,'qubit')
c = ClassicalRegister(2,'classical_bits')
qc = QuantumCircuit(q,c)
qc.h(q[0])
qc1 = QuantumCircuit(q,c)
qc1.measure(q,c)
qc.append(qc1,[q[0], q[1]], [c[0], c[1]])

print(qc.draw())
transpile(qc, optimization_level=2)

Produces this output and error:

                  ┌───┐┌──────────────┐
         qubit_0: ┤ H ├┤0             ├
                  └───┘│              │
         qubit_1: ─────┤1             ├
                       │  circuit-115 │
classical_bits_0: ═════╡0             ╞
                       │              │
classical_bits_1: ═════╡1             ╞
                       └──────────────┘
Traceback (most recent call last):
  File "/my_file.py", line 13, in <module>
    transpile(qc, optimization_level=2)
  File "..qiskit/compiler/transpiler.py", line 380, in transpile
    _serial_transpile_circuit(
  File "..qiskit/compiler/transpiler.py", line 462, in _serial_transpile_circuit
    result = pass_manager.run(circuit, callback=callback, output_name=output_name)
  File "..qiskit/transpiler/passmanager.py", line 537, in run
    return super().run(circuits, output_name, callback)
  File "..qiskit/transpiler/passmanager.py", line 231, in run
    return self._run_single_circuit(circuits, output_name, callback)
  File "..qiskit/transpiler/passmanager.py", line 292, in _run_single_circuit
    result = running_passmanager.run(circuit, output_name=output_name, callback=callback)
  File "..qiskit/transpiler/runningpassmanager.py", line 125, in run
    dag = self._do_pass(pass_, dag, passset.options)
  File "..qiskit/transpiler/runningpassmanager.py", line 169, in _do_pass
    dag = self._do_pass(required_pass, dag, options)
  File "..qiskit/transpiler/runningpassmanager.py", line 173, in _do_pass
    dag = self._run_this_pass(pass_, dag)
  File "..qiskit/transpiler/runningpassmanager.py", line 227, in _run_this_pass
    pass_.run(FencedDAGCircuit(dag))
  File "..qiskit/transpiler/passes/optimization/commutation_analysis.py", line 75, in run
    does_commute = self.comm_checker.commute(
  File "..qiskit/circuit/commutation_checker.py", line 135, in commute
    operator_1 = Operator(op1, input_dims=(2,) * len(qarg1), output_dims=(2,) * len(qarg1))
  File "..qiskit/quantum_info/operators/operator.py", line 85, in __init__
    self._data = self._init_instruction(data).data
  File "..qiskit/quantum_info/operators/operator.py", line 614, in _init_instruction
    op._append_instruction(instruction)
  File "..qiskit/quantum_info/operators/operator.py", line 682, in _append_instruction
    raise QiskitError(
qiskit.exceptions.QiskitError: 'Cannot apply operation with classical bits: measure'

What should happen?

The transpiler should not fail, I would expect a robust behaviour by a transpiler (e.g. just skip the optimization if not possible or simply raise a warning).

Any suggestions?

What about adding a warning in the transpiler, and skipping the optimization pass in such cases?

jakelishman commented 1 year ago

This is a bug in the CommutationAnalysis pass (it should probably just assume that operations that involve classical wires don't commute with things), but just to point out that what you're doing here is kind of an edge case for us: it's not normal to transpile with no particular basis gates or coupling constraints defined.