qiskit icon indicating copy to clipboard operation
qiskit copied to clipboard

`ConsolidateBlocks` fails when circuit contains measure and `crx`, `ch`, `rx` combined

Open YaegakiY opened this issue 6 months ago • 2 comments

Environment

  • Qiskit version: 2.1.0
  • Python version: Python 3.13.2
  • Operating system: Ubuntu 20.04.6 LTS

What is happening?

When running a PassManager that includes Collect2qBlocks, TemplateOptimization, and ConsolidateBlocks on a circuit that includes rx, ch, and crx gates and measurements, the optimization fails with a QiskitError: 'Cannot apply Operation: measure'.

How can we reproduce the issue?

To reproduce:

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile
from qiskit_aer import Aer
from qiskit.transpiler.passes import *
from qiskit.transpiler import PassManager


qreg = QuantumRegister(4)
creg = ClassicalRegister(4)
qc = QuantumCircuit(qreg, creg)

qc.rx(0.39269908169872414, 0)
qc.ch(3, 0)
qc.crx(0.7853981633974483, 0, 3)

qc.measure(qreg[0], creg[0])
qc.measure(qreg[1], creg[1])
qc.measure(qreg[2], creg[2])
qc.measure(qreg[3], creg[3])

simulator = Aer.get_backend("aer_simulator")

p = PassManager([Collect2qBlocks(), TemplateOptimization(), ConsolidateBlocks()])
qc = p.run(qc)

compiled_circuit = transpile(qc, backend=simulator)

job = simulator.run(compiled_circuit, shots=500)
result = job.result().get_counts()
print(result)

By the way, removing any one of:

  • The rx, ch, or crx gate
  • The measure operations
  • One of the passes from the PassManager

will make the circuit run successfully.

What should happen?

The circuit should transpile and execute successfully.

Any suggestions?

There is also a longer version of the buggy program that can reliably trigger the error. Interestingly, commenting out any one of the marked lines will make the bug disappear:

from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, transpile
from qiskit_aer import Aer
from qiskit.transpiler.passes import *
from qiskit.circuit.library import *
from qiskit.transpiler import PassManager
import numpy as np

np.random.seed(42)

qreg = QuantumRegister(4)
creg = ClassicalRegister(4)
qc = QuantumCircuit(qreg, creg)

qc.ch(2, 1) # this line
qc.z(2) # this line
qc.rx(0.39269908169872414, 0) # this line
qc.ch(3, 0) # this line
qc.crx(0.7853981633974483, 0, 3) # this line

qr = QuantumRegister(2)
cr = ClassicalRegister(2)
qc.add_register(qr)
qc.add_register(cr)
qc.h(qr[0]) 
qc.cx(qr[0], qr[1]) 
qc.measure(qr[0], cr[0])
qc.measure(qr[1], cr[1])

qc.measure(qreg[0], creg[0])
qc.measure(qreg[1], creg[1])
qc.measure(qreg[2], creg[2])
qc.measure(qreg[3], creg[3])

simulator = Aer.get_backend("aer_simulator")

p = PassManager([Collect2qBlocks(), TemplateOptimization(), ConsolidateBlocks()])
qc = p.run(qc)

compiled_circuit = transpile(qc, backend=simulator)


job = simulator.run(compiled_circuit, shots=500)
result = job.result().get_counts()
print(result)

YaegakiY avatar Jun 19 '25 13:06 YaegakiY

This is most likely the same problem with your code as #14646. You're doing an analysis, invalidating it, then attempting to use the analysis.

jakelishman avatar Jun 19 '25 13:06 jakelishman

Got it — that makes perfect sense, thanks for confirming!

YaegakiY avatar Jun 19 '25 13:06 YaegakiY