Skip to content

Conversation

@maliasadi
Copy link
Member

@maliasadi maliasadi commented Nov 20, 2025

Context:
The frontend no longer maintains a hardcoded list of runtime operations, allowing arbitrary PennyLane gates with Quantum dialect-compatible hyperparameters to be captured and represented in MLIR. Users of the legacy compilation pipeline are unaffected, as Catalyst continues to decompose unsupported gates based on device capabilities before lowering to MLIR. Gates that cannot be represented as MLIR operators will temporarily raise a CompileError during program capture. The long-term solution will integrate the new decomposition framework with capture-enabled compilation.

Description of the Change:

  • Remove RUNTIME_OPERATIONS from qjit_device.py
  • Add is_lowering_compatible to check if an operation can be lowered to MLIR using primitives.
  • Update quantum operations capture logic in from_plxpr

Benefits:

  • Lower and represent all gates in the device toml file as long as they can be represented as quantum.custom op
  • Support IR representation of custom gates with compatible hyperparameters at MLIR
  • Users can decompose their custom ops via qml.transforms.decompose for gates w/o runtime support, or just rely on the device decomposition to deal with unsupported ops

Possible Drawbacks:

  • Device developers are responsible to maintain the device toml file based on the QIR QIS

Related GitHub Issues:
[sc-102160]

@codecov
Copy link

codecov bot commented Nov 20, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.57%. Comparing base (51a83ba) to head (ebeba80).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff             @@
##             main    #2215       +/-   ##
===========================================
+ Coverage   78.94%   97.57%   +18.62%     
===========================================
  Files          91       93        +2     
  Lines       10812    11254      +442     
  Branches     1064     1078       +14     
===========================================
+ Hits         8536    10981     +2445     
+ Misses       1919      208     -1711     
+ Partials      357       65      -292     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@maliasadi maliasadi marked this pull request as draft November 21, 2025 22:40
@maliasadi maliasadi marked this pull request as ready for review December 1, 2025 15:33
maliasadi added a commit that referenced this pull request Dec 1, 2025
Revert PR #2215 changes that accidentally merged in PR #2131.

Note that these changes don't break the current functionalities of Catalyst,
but they introduce edge cases with lowering generic PL operators in MLIR
that need to be properly addressed before the merge.
(re: the future Operator class)
@maliasadi maliasadi requested review from dime10 and paul0403 December 2, 2025 16:22
return True

# Accepted hyperparameters for quantum instructions bind calls
_accepted_hyperparams = {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@albi3ro Here's the minimum set of hyperparams that we always need to check for compatibility with the quantum.custom MLIR Op.

Copy link
Contributor

@dime10 dime10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Ali! Main concern is that the criteria is fairly loose compared to before. We should consider two factors in terms of validation:

  • whether a custom operation is supported by the runtime c-api (a fixed set of linkable functions)
    • This PR doesn't actually remove the underlying limitation, so by itself removing the check doesn't seem like an improvement. Are you planning on removing the underlying limitation in an immediate follow-up?
  • whether any operation is supported by the compiler
    • Generally this is a fixed set (all ops defined in the quantum dialect), plus any afforded by an extensibility mechanism (in this case only quantum.custom).
    • Does the implemented verification match these restrictions exactly? In the current state I don't think so.

return op.name in capabilities.operations


def is_lowering_compatible(op: Operator) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not convinced this function is sufficient to guarantee compatibility with the quantum dialect. Looking at the structure of an operator:

Operators are uniquely defined by their name, the wires they act on, their (trainable) parameters,
and their (non-trainable) hyperparameters. The trainable parameters can be tensors of any
supported auto-differentiation framework.

Name and wires are always supported by quantum.custom.

Hyperparameters are being checked below, although I don't know if the check is not too generic (i.e. I don't know if all hyperparameters are supported by all operation types).

The thing that's missing entirely is verifying parameters. Pennylane only requires that they be tensor-like, so this could be an arbitrary sequence of arbitrary tensors. This cannot be mapped to the quantum dialect at the moment. Some special ops support certain tensors (like 2D complex for quantum.unitary), but for the generic quantum.custom we would only support a sequence of scalar floats (or perhaps a single tensor that is flattened into a sequence of floats, but this could get highly inefficient if the tensor is large).

return op.name in capabilities.operations


def is_lowering_compatible(op: Operator) -> bool:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to consider operations like quantum.measure at all, since its signature even has a return value 🤔

Comment on lines +59 to +60
"work_wires",
"work_wire_type",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we handle work wires when mapping to mlir?

}
# A list of custom operations supported by the Catalyst compiler.
# This is useful especially for testing a device with custom operations.
CUSTOM_OPERATIONS = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a point to keep this empty set, considering its entire purpose is to be unioned with something else?

Or is it just for tests? In that case possibly related: #2114

a: Dict[str, OperatorProperties], b: Dict[str, OperatorProperties]
) -> Dict[str, OperatorProperties]:
"""Union of two sets of operator properties"""
return {**a, **b}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why not just

>>> x
{1: 2}
>>> y
{3: 4}
>>> x.update(y)
>>> x
{1: 2, 3: 4}

?

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.

4 participants