Skip to content

Conversation

maliasadi
Copy link
Member

@maliasadi maliasadi commented Sep 25, 2025

Context:
Prototype PL's DecompositionGraph in C++ for integration with the Catalyst core compiler

Benefits:

  • Construct and solve the decomposition graph in MLIR instead of Python
  • Avoid Python/JAX overheads related to the graph across PL/Catalyst (PRs 6966 and 2029)
  • Faster graph construction (we can cache the static part of the graph and reuse it in the core compiler) and solver (it's in C++ avoiding Python/PL overheads)

Possible Drawbacks:

  • Feature parity with PL's DecompositionGraph
  • Support dynamic decomposition rules

Related to:
#2062

maliasadi and others added 22 commits September 18, 2025 13:23
… present in MLIR (#2001)

**Context:**

Introduces a new MLIR pass that enables user-defined decomposition of
quantum gate operations. The pass discovers decomposition functions in
the module and uses MLIR's inlining infrastructure to replace target
quantum operations with their decomposed implementations.

**Description of the Change:**

This PR will **recognize** the `func.func` as decomposition if they have
name start with the pattern `<Gate>_rule[.]*` where the `<Gate>` is a
`quantum.custom` op it expect to replace (It's not what generated from
frontend). Also you can just mark the attributes
`catalyst.decomposition` and `catalyst.decomposition.target_op` at
decomposition function, it still works.

And this pass just **discover** those decomposition functions and
**replace** the target operation with `call` to the function and rely on
the Inliner interface to inline these decomposition function if needed.

The stages of the `--decompose-lowering`:
1. `decompose_lowering.cpp`: Main pass that orchestrates the
decomposition process
2. `DecomposeLoweringPatterns`: Pattern rewriting logic that replaces
`quantum.custom` operations with function call
3. `QuantumInlinerInterface`: Dialect interface that enables MLIR's
inliner to process quantum operations correctly
4. Remove unused decomposition function (if the inliner decide not to
inline the certain function, then it will leave a `func.call`, so the
func is used, shouldn't be removed)

The type signature between decomposition function provided from the
frontend is different to the `quantum.custom` op, `OpSignatureAnalyzer`
does the trick to get the enough information to generate a function call
to decomposition function.

Current right now, frontend choose to generate the decomposition
function with type:
```
(qreg, param*, inWires*, inCtrlWires*?, inCtrlValues*?) -> qreg
```
We need to figure out the information that need to pass to create the
function call: qreg, `in wires indices`, and `in ctrl wires`.

`OpSignatureAnalyzer` will use the target `quantum.custom` op (that one
we need to replace) to traverse the qubit, and find out the qreg, and
wire indices. The traversal logic based on the following assumption for
the quantum dialect:

1. The ordering of qubits is preserved in quantum instructions
2. For other instructions, they will use a register, so will hit an
extract before them

It promise that every gates, the result (qubits) will match to the
operands (qubits) at the same index. That's the important assumptions to
support the traversal logic here. Traverse the qubit, match the index,
keep going up until reach the `qauntum.extract` operation.

After then, we use those information to generate a function call and
rely on the Inliner in MLIR infra to replace it.

**Benefits:**

The decision to use MLIR's inlining infrastructure (`InlinerPass`) is to
provide future-proofing and flexibility.

**Possible Drawbacks:**

**Related GitHub Issues:**
[sc-98593]

---------

Co-authored-by: Ali Asadi <[email protected]>
Base automatically changed from feature/handle_gdecomp_v4 to main September 26, 2025 14:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants