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

`CollectCliffords` pass ignores Rz's #13138

Closed samanthavbarron closed 1 month ago

samanthavbarron commented 2 months ago

Environment

What is happening?

rz gates are ignored by the CollectCliffords pass (regardless of angle), when it could potentially collect them.

How can we reproduce the issue?

from qiskit import QuantumCircuit
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import CollectCliffords

qc = QuantumCircuit(1)
qc.rz(0, 0)
qc.sx(0)

PassManager([CollectCliffords(min_block_size=1)]).run(qc).draw()

What should happen?

There should be a single instruction in the resulting circuit, however I get

   ┌───────┐┌──────────┐
q: ┤ Rz(0) ├┤ Clifford ├
   └───────┘└──────────┘

Any suggestions?

It seems this function is just looking at _BASIS_1Q which doesn't include rz (and shouldn't, IMO).

Presumably this issue extends to other parameterized gates.

A possible fix would be to instead have an option in CollectCliffords which attempts to cast it as a Clifford. Since this would likely come at a performance hit, it should probably be False by default.

E.g.

def _is_clifford_gate(node, try_harder: bool = False):
    """Specifies whether a node holds a clifford gate."""
    if getattr(node.op, "condition", None) is not None:
        return False
    if node.op.name in clifford_gate_names:
        return True

    if not try_harder:
        return False

    try:
        Clifford(node.op)
        return True
    except:
        return False