Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConsolidateBlocks can collect valid blocks that cannot be resynthesised in optimization_level=3 #11975

Open
jakelishman opened this issue Mar 8, 2024 · 2 comments
Labels
bug Something isn't working mod: transpiler Issues and PRs related to Transpiler

Comments

@jakelishman
Copy link
Member

Environment

  • Qiskit version: 1.0.2 and 0.46.1
  • Python version: 3.10
  • Operating system: macOS

What is happening?

At optimization_level=3, we run a pass to take long 2q runs, and resynthesise them if the run contains more 2q gates than we estimate a full resynthesis will need. This makes a tacit assumption that we will certainly be able to resynthesise any block we collect back to the supported basis set for the particular qubits. If that assumption is violated, ConsolidateBlocks can collect blocks of already valid instructions into a matrix, but then the following UnitarySynthesis run will fail to decompose it, resulting in a pipeline that took a valid circuit and made it invalid.

How can we reproduce the issue?

from qiskit import QuantumCircuit
from qiskit.circuit.library import CXGate
from qiskit.transpiler import PassManager
from qiskit.transpiler.passes import UnitarySynthesis, Collect2qBlocks, ConsolidateBlocks

qc = QuantumCircuit(2)
qc.x(0)
qc.cx(0, 1)
qc.cx(0, 1)
qc.cx(0, 1)
qc.cx(0, 1)

# The relevant subcomponent of the O3 optimisation loop.
pm = PassManager([
    Collect2qBlocks(),
    ConsolidateBlocks(CXGate()),
    UnitarySynthesis(basis_gates=["x", "cx"]),
])
pm.run(qc).draw()
global phase: π/2
     ┌───────────────┐
q_0: ┤ U(π,-π/2,π/2) ├
     └─┬────────────┬┘
q_1: ──┤ U(0,-π,-π) ├─
       └────────────┘

What should happen?

This is how #11974 manifested itself to me, but fixing #11974 to have UnitarySynthesis raise an error would then cause my code block to throw an error. Alone, though, this isn't really UnitarySynthesis's fault - it would have no way of reverting the circuit to its prior state if the synthesis fails.

The result should be that optimization_level=3 should not cause basis-gate failures in its optimisation loop. There's maybe a couple of ways to go about this:

  • have ConsolidateBlocks communicate with UnitarySynthesis somehow to know if it has complete decomposers for the relevant qubits. If not, don't collect those blocks into unitaries.
  • have ConsolidateBlocks store the collected run somewhere, so if resynthesis fails, we can revert to the previous form.

It's potentially also worth considering if the whole "2q resynthesis" logic might be better as an encapsulated single pass, or something like this, if the alternative is making inter-pass communication ever more complex. That of course risks code duplication.

Any suggestions?

No response

@jakelishman jakelishman added bug Something isn't working mod: transpiler Issues and PRs related to Transpiler labels Mar 8, 2024
@jakelishman
Copy link
Member Author

For reference: this problem was the test failure that we encountered in during the release of 0.46.1 (see #11969).

@mtreinish
Copy link
Member

@ajavadia has an open issue proposing something similar with consolidating the passes in #11659 I think we definitely should look at that, it also could improve the efficiency a bit.

In a future world where we have a parallelized rust version of the synthesis default plugin this would make the usage/implementation of that potentially simpler too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working mod: transpiler Issues and PRs related to Transpiler
Projects
None yet
Development

No branches or pull requests

2 participants