Skip to content

Fix: Skip UnitaryGate instances during BasisTranslator#15916

Closed
raynelfss wants to merge 5 commits into
Qiskit:mainfrom
raynelfss:fix-basis-once-again
Closed

Fix: Skip UnitaryGate instances during BasisTranslator#15916
raynelfss wants to merge 5 commits into
Qiskit:mainfrom
raynelfss:fix-basis-once-again

Conversation

@raynelfss

Copy link
Copy Markdown
Contributor

Summary

Fixes #15278
Fixes #15733

  • This aims to fix a well known bug introduced by Make BasisTranslator rust-native. #14659 in which the AerSimulator is known to define UnitaryGate as part of its target basis. However, BasisTranslator should not include UnitaryGate as part of its calculations, it should instead be handled by UnitarySynthesis.
  • To fix this, BasisTranslator skips any UnitaryGate in the circuit by filtering its op_nodes to check for any UnitaryGate instances.

Details and comments

The only question left is whether we should still have the panic condition in name_to_packed_operation because this check is done on a name basis rather than instance.

…slator`.

- A well known bug introduced by Qiskit#14659 in which the `AerSimulator` is known to define `UnitaryGate` as part of its target basis. However, `BasisTranslator` should not include `UnitaryGate` as part of its calculations, it should instead be handled by `UnitarySynthesis`.
- To fix this, `BasisTranslator` skips any `UnitaryGate` in the circuit by filtering its `op_nodes` to check for any `UnitaryGate` instances.
- The only question left is whether we should still have the panic condition in `name_to_packed_operation` because this check is done on a name basis rather than instance.
@raynelfss raynelfss added this to the 2.4.0 milestone Mar 30, 2026
@raynelfss raynelfss requested a review from a team as a code owner March 30, 2026 18:47
@raynelfss raynelfss added bug Something isn't working stable backport potential Make Mergify open a backport PR to the most recent stable branch on merge. Rust This PR or issue is related to Rust code in the repository mod: transpiler Issues and PRs related to Transpiler labels Mar 30, 2026
@qiskit-bot

Copy link
Copy Markdown
Collaborator

One or more of the following people are relevant to this code:

  • @Qiskit/terra-core

@raynelfss

Copy link
Copy Markdown
Contributor Author

The only question left is whether we should still have the panic condition in name_to_packed_operation because this check is done on a name basis rather than instance.

I'd like to bring this up again, in case it is a genuine concern. Since most of this fix might be superseded by #15684, we won't need to even go through Python in the future.

@raynelfss raynelfss changed the title Fix: Skip UnitaryGate instances during BasisTraslator Fix: Skip UnitaryGate instances during BasisTranslator Mar 31, 2026
@mtreinish

Copy link
Copy Markdown
Member

Where specifically is the panic? We shouldn't be panicking in general on the name unitary, that's something that will be used a lot. In general we shouldn't be panicking unless the underlying data structures are completely invalid (as in something corrupted them).

@raynelfss

Copy link
Copy Markdown
Contributor Author

Where specifically is the panic? We shouldn't be panicking in general on the name unitary, that's something that will be used a lot.

I agree with this @mtreinish. I mistakenly added this in the past believing that there was no way we'd end up ever retrieving or querying a UnitaryGate or a gate named "unitary" from an equivalence library.

The panic happens specifically during the compose_transforms method where we would introduce a placeholder gate with the provided name into a dag. However, since we moved most of the infrastructure to rust, to remove ourselves from python, we would create rust native versions of gates. The original implementation included a variant for unitary but after further discussion we agreed that it wouldn't make sense for a unitary to end up there anyway, so I mistakenly made it into an unreachable!() call.

Ideally, it would be best to throw away this panic condition in favor of just going through Python instead since #15684 will modify this to perform all tasks from rust.

@ShellyGarion ShellyGarion added the Changelog: Fixed Add a "Fixed" entry in the GitHub Release changelog. label Jun 14, 2026
@ShellyGarion

Copy link
Copy Markdown
Member

Is this PR still relevant? I checked both issues against the main branch (locally), and I didn't get any failure (there was no panic)?

This is the test added to my main branch:

    @unittest.skipUnless(HAS_AER, "Aer backend required for simulation")
    def test_basis_with_unitary_basis_aer(self):
        """Test that a circuit with a unitary gate in its target basis gets
        skipped by the BasisTranslator"""
        from qiskit_aer import AerSimulator
        from qiskit_aer import QasmSimulator 

        qr = QuantumRegister(3, "q")
        cr = ClassicalRegister(3, "c")
        qc = QuantumCircuit(qr, cr)

        qc.cx(0, 1)
        qc.h(0)
        qc.cx(0, 1)
        qc.sx(0)
        qc.dcx(0, 2)

        backend = AerSimulator()
        pm = generate_preset_pass_manager(
            optimization_level=2, backend=backend, seed_transpiler=134
        )
        transpiled = pm.run(qc)
        print (transpiled)
        self.assertEqual(Operator(qc), Operator(transpiled))

        n_wires = 4
        qc = QuantumCircuit(n_wires, 1)

        qc.cx(2, 3)
        qc.ry(0.1, 3)
        qc.cx(2, 3)
        qc.ry(-0.1, 3)
        qc.cx(2, 3)
        qc.crz(0.3, 3, 1)  
        qc.s(3)
        qc.barrier()
        qc.measure(0, 0)

        backend = QasmSimulator() 
        transpiled_qc = transpile(qc, backend=backend)
        print (transpiled_qc)

and these are the output circuits:


     ┌──────────┐     ┌───┐
q_0: ┤0         ├──■──┤ X ├
     │  Unitary │  │  └─┬─┘
q_1: ┤1         ├──┼────┼──
     └──────────┘┌─┴─┐  │  
q_2: ────────────┤ X ├──■──
                 └───┘     
c: 3/══════════════════════
                           
                                   ░ ┌─┐
q_0: ──────────────────────────────░─┤M├
     ┌──────────┐                  ░ └╥┘
q_1: ┤ Rz(0.15) ├─■────────────────░──╫─
     ├──────────┤ │                ░  ║ 
q_2: ┤0         ├─┼────────────────░──╫─
     │  Unitary │ │ZZ(-0.15) ┌───┐ ░  ║ 
q_3: ┤1         ├─■──────────┤ S ├─░──╫─
     └──────────┘            └───┘ ░  ║ 
c: 1/═════════════════════════════════╩═
                                      0 
ok

@alexanderivrii

alexanderivrii commented Jun 17, 2026

Copy link
Copy Markdown
Member

This and the other issues seem to have been fixed by Ray's PR #15684 with the support of OperationRef::CustomOperation(_) in basis_translator/mod.rs. @raynelfss , does this make sense to you, or you think there might be other problems as well?

@ShellyGarion

Copy link
Copy Markdown
Member

If these issues were fixed in a former PR, it would be better to add a release note as well as a test for this.

@raynelfss

Copy link
Copy Markdown
Contributor Author

I've decided to close this PR as the panic condition no longer exists and this pass may be removed in the future.

@raynelfss raynelfss closed this Jun 17, 2026
@github-project-automation github-project-automation Bot moved this from Ready to Done in Qiskit 2.5 Jun 17, 2026
@ShellyGarion

Copy link
Copy Markdown
Member

I've decided to close this PR as the panic condition no longer exists and this pass may be removed in the future.

so we should also close the two issues?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Changelog: Fixed Add a "Fixed" entry in the GitHub Release changelog. mod: transpiler Issues and PRs related to Transpiler Rust This PR or issue is related to Rust code in the repository stable backport potential Make Mergify open a backport PR to the most recent stable branch on merge.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Rust panic during transpiler basis_translator pass pyo3_runtime.PanicException raised for simple circuit execution

5 participants