Skip to content

CollectCliffords pass fails for circuit with large PauliLindbladError #13457

@aeddins-ibm

Description

@aeddins-ibm

Environment

  • Qiskit version: 1.3.0rc1
  • Python version: 3.11
  • Operating system: macos

What is happening?

qiskit.transpiler.passes.CollectCliffords goes through a circuit and merges recognized clifford gates into combined Clifford operations.

However, this fails if we've appended a many-qubit PauliLindbladError (qiskit_aer.noise.errors.PauliLindbladError) to the circuit. The PauliLindbladError is represented in the circuit as a quantum_channel instruction. At some point, CollectCliffords attempts to convert this channel to a Kraus object, which involves creating a many-qubit SuperOp which naturally crashes with this error:
ValueError: array is too big; `arr.size * arr.dtype.itemsize` is larger than the maximum possible size.

The attempt to convert to a Kraus object apparently happens here:

self._in_degree[suc] -= 1

It looks like it encounters the PauliLindbladError (as a quantum_channel) as a successor node (of something), and tries to use that quantum_channel as a dictionary key (suc). Attempting to check for equality with other dict keys apparently involves converting the quantum_channel to a many-qubit SuperOp, which fails.

How can we reproduce the issue?

from qiskit import QuantumCircuit
from qiskit.transpiler.passes import CollectCliffords
from qiskit.transpiler.passmanager import PassManager
from qiskit_aer.noise.errors import PauliLindbladError

pm = PassManager(CollectCliffords(
    do_commutative_analysis = False,
    split_blocks = False,
    split_layers = False,
    collect_from_back = False,
))

qc = QuantumCircuit(20)
qc.cx(0,1)
qc.cx(0,1)
qc.append(PauliLindbladError(generators=['X'+'I'*19],rates=[0.1]),range(20))

qc_transpiled = pm.run(qc)

What should happen?

Personally I don't want CollectCliffords to attempt to do anything with the quantum_channel instructions. It should leave those instructions unchanged, without raising any errors.

Any suggestions?

It looks like internally, the low-level collect functions use a filter_fn in order to ignore some instructions, avoiding the dictionary lookup:

if filter_fn(node):
current_block.append(node)
# update the _in_degree of node's successors
for suc in self._direct_succs(node):
self._in_degree[suc] -= 1
if self._in_degree[suc] == 0:
new_pending_nodes.append(suc)
else:
self._pending_nodes.append(node)

Can we modify the existing filter_fn used by CollectCliffords so that it ignores quantum_channel instructions?

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions