Graph decompose frontend#2568
Conversation
| from catalyst.compiler import _options_to_cli_flags, _quantum_opt | ||
| from catalyst.passes.pass_api import PassPipelineWrapper | ||
| from catalyst.utils.exceptions import CompileError | ||
| from catalyst.utils.precompile_decomposition_rules import BYTECODE_FILE_NAME, DEFAULT_RULE_DIR |
There was a problem hiding this comment.
could we create and import BYTECODE_FILE_PATH instead of BYTECODE_FILE_NAME, DEFAULT_RULE_DIR?
There was a problem hiding this comment.
This is more related to this PR, but I'll implement it there so that we can sync it up the branches. I think it makes sense to do this after merging this branch though, to reduce the amount of syncing required.
| gate_set: Iterable, | ||
| fixed_decomps: dict | None = None, | ||
| alt_decomps: dict | None = None, | ||
| rule_path: Path = DEFAULT_RULE_DIR / BYTECODE_FILE_NAME, |
There was a problem hiding this comment.
Probably add builtin, standard or something else to the name of this optional kwarg to better convey the use case:
| rule_path: Path = DEFAULT_RULE_DIR / BYTECODE_FILE_NAME, | |
| builtin_rule_path: Path = DEFAULT_RULE_DIR / BYTECODE_FILE_NAME, |
There was a problem hiding this comment.
This is also a dev utility and it's not supposed to be used by users.
There was a problem hiding this comment.
I changed the name to _builtin_rule_path here - I think having this parameter around for a bit longer to allow different rule caches in development and testing might be useful, but I'm open to removing it if you think it should not be exposed at all.
| ) | ||
|
|
||
| if not isinstance(gate_set, dict): | ||
| gate_set = {op.__name__: 1.0 for op in gate_set} |
There was a problem hiding this comment.
Need to update the logic to support string gates too. From PL, users can provide a mix of PL Op types and Op strings: https://github.com/PennyLaneAI/pennylane/blob/494cd943c4ce675f8c392a9b8fb98626d1b78c02/pennylane/decomposition/gate_set.py#L24
There was a problem hiding this comment.
updated to use the to_name utility from PL, so we should have near-identical support. I've also added some tests for this.
|
Hello. You may have forgotten to update the changelog!
|
| def graph_decomposition( | ||
| qnode=None, | ||
| *, | ||
| gate_set: Iterable, |
There was a problem hiding this comment.
valid types for gate_set for the reference: https://github.com/PennyLaneAI/pennylane/blob/494cd943c4ce675f8c392a9b8fb98626d1b78c02/pennylane/transforms/decompose.py#L378
long-term, we need compatibility with Gateset.
There was a problem hiding this comment.
I updated the types here, not sure about supporting Gateset at the moment but it looks as though adding a __dict__ method to gateset that we can use internally here would be quite reasonable.
|
Note that CI won't pass here since it's currently broken in mlirbc-decomp-rules, which is upstream of this branch. |
maliasadi
left a comment
There was a problem hiding this comment.
Happy to approve! We can address the remaining updates in the pass PR.
| with pytest.raises(check=ValueError, match="Requested specs levels 2, 3"): | ||
| qml.specs(no_passes, level=[2, 3])() | ||
|
|
||
| @pytest.mark.xfail(reason="pending on specs fix") |
There was a problem hiding this comment.
It's good practice to provide a pr, issue, or ticket reference so that anyone can check later whether the referenced fix has been completed or not
There was a problem hiding this comment.
The plan is to check the file into the git tree now?
| _builtin_rule_path: Path = DEFAULT_RULE_DIR / BYTECODE_FILE_NAME, | ||
| ): | ||
| R""" | ||
| Specify that the ``-graph-decomposition`` MLIR compiler pass for applying optimal gate |
There was a problem hiding this comment.
Optimality is a strong claim, imo we should be careful with such language. Maybe "optimal gate decompositions" could be interpreted in different ways, but I don't think our rules themselves are necessary optimal, the only thing we can guarantee is that we choose the optimal path from the given set of rules.
| To instead view the optimized circuit, the MLIR must be viewed | ||
| after the ``"QuantumCompilationStage"`` stage via the | ||
| :func:`~.get_compilation_stage` function. |
There was a problem hiding this comment.
We have inspection tools now beyond just looking at the MLIR, including qml.specs and catalyst.draw_graph
**Context:** The objective is to develop a high-performance, hybrid decomposition framework that further migrates the graph-decomposition logic from Python to the native MLIR compiler. The new framework needs to adhere to four pillars: 1. We will migrate the `GraphDecomposition` build and solver logic from Python into C++ #2578. By co-locating the solver with the decomposition-rule rewrite MLIR pass into a `graph-decomposition` system at MLIR, we enable late-stage circuit rewrites and multi-pass optimization cycles that were previously inaccessible in the frontend-only framework. 2. To minimize runtime latency, PL’s standard and built-in decomposition rules will be precompiled for release, and lazily re-compiled if necessary on import #2531 #2539. By treating built-in rules as static compiler assets rather than dynamic JIT targets, we try to eliminate the redundant capture and compilation overhead typically incurred during every workflow execution. 2. To maintain the flexibility of PL, the system will need to still support JIT compilation of rules. While standard rules are handled by the AOT backend, custom user-defined device rules will be resolved via a JIT fallback mechanism #2568. This is to ensure that researcher-defined gatesets and rules remain fully supported without requiring a full compiler re-build. 4. Short-term, a "PLxPR Guard" stage will handle edge cases before MLIR lowering, acting as a fallback until the C++ system offers full support. Compiler-incompatible operators and complex high-level templates (e.g., Subroutine/Template work) will continue to be handled/decomposed at the PLxPR level; so that the backend receives a valid, lowerable MLIR representation while deferring hardware-specific passes to MLIR/C++. This step is temporary and will be revisited aligned with the updates in the Operator class and the program capture mechanism for Symbolic Ops. **Benefits:** - Enable "late-stage" and iterative decomposition passes at MLIR with a C++ decomposition graph - Eliminate redundant compilation overhead of built-in decomposition rules during JIT compilation of workflows **Possible Drawbacks:** **Related GitHub Issues:** [sc-113535] [sc-113537] [sc-115445] --------- Co-authored-by: River McCubbin <river.mccubbin@xanadu.ai> Co-authored-by: Hong-Sheng Zheng <mathan0203@gmail.com> Co-authored-by: David Ittah <dime10@users.noreply.github.com>
Context:
Description of the Change:
Provides the interface for the
graph-decomposepass.Benefits:
graph decomposition occurs in C++ at runtime, using precompiled builtin rules and jit compiled user rules.
Possible Drawbacks:
N/A
Related GitHub Issues:
[sc-113641]
[sc-101036]