From 3aed481f94176d1259a343a48c7336b9ecc4d0a6 Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Fri, 3 Jul 2026 10:03:41 -0400 Subject: [PATCH 1/4] Add `adjoint` and `n_ctrls` args to Operator2 primitive --- .dep-versions | 2 +- doc/requirements.txt | 2 +- .../catalyst/from_plxpr/qfunc_interpreter.py | 20 ++++++++++++++----- .../from_plxpr/qref_operator2_primitives.py | 2 ++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.dep-versions b/.dep-versions index eff2c832ec..f57e1fa127 100644 --- a/.dep-versions +++ b/.dep-versions @@ -8,7 +8,7 @@ enzyme=v0.0.238 # For a custom PL version, update the package version here and at # 'doc/requirements.txt' -pennylane=0.46.0.dev38 +pennylane=0.46.0.dev46 # For a custom LQ/LK version, update the package version here and at # 'doc/requirements.txt' diff --git a/doc/requirements.txt b/doc/requirements.txt index 3459767b3b..2681748025 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -34,4 +34,4 @@ lxml_html_clean --extra-index-url https://test.pypi.org/simple/ pennylane-lightning-kokkos==0.46.0-dev10 pennylane-lightning==0.46.0-dev10 -pennylane==0.46.0.dev38 +pennylane==0.46.0.dev46 diff --git a/frontend/catalyst/from_plxpr/qfunc_interpreter.py b/frontend/catalyst/from_plxpr/qfunc_interpreter.py index 0d51ee2705..a11294baa6 100644 --- a/frontend/catalyst/from_plxpr/qfunc_interpreter.py +++ b/frontend/catalyst/from_plxpr/qfunc_interpreter.py @@ -210,16 +210,24 @@ def _check_measurement_with_dynamic_allocation(self, measurement): """Check some constraints regarding dynamic allocation.""" if self.has_dynamic_allocation: if len(measurement.wires) == 0 and not isinstance(measurement, qp.measurements.StateMP): - raise CompileError(textwrap.dedent(""" + raise CompileError( + textwrap.dedent( + """ Terminal measurements must take in an explicit list of wires when dynamically allocated wires are present in the program. - """)) + """ + ) + ) if any(is_abstract_qubit(w) for w in measurement.wires): - raise CompileError(textwrap.dedent(""" + raise CompileError( + textwrap.dedent( + """ Terminal measurements cannot take in dynamically allocated wires since they must be temporary. - """)) + """ + ) + ) # pylint: disable=too-many-branches def interpret_measurement(self, measurement): @@ -293,7 +301,7 @@ def __call__(self, jaxpr, *args): @PLxPRToQuantumJaxprInterpreter.register_primitive(operator_p) -def _handle_operator(self, *args, op_cls, hybrid_lens, hybrid_trees, **kwargs): +def _handle_operator(self, *args, op_cls, hybrid_lens, hybrid_trees, adjoint, n_ctrls, **kwargs): if hybrid_lens or hybrid_trees or op_cls.static_argnames: # only support compilable_argnames for the moment @@ -310,6 +318,8 @@ def _handle_operator(self, *args, op_cls, hybrid_lens, hybrid_trees, **kwargs): op_cls=op_cls, hybrid_lens=hybrid_lens, hybrid_trees=hybrid_trees, + adjoint=adjoint, + n_ctrls=n_ctrls, **kwargs, ) return [] diff --git a/frontend/catalyst/from_plxpr/qref_operator2_primitives.py b/frontend/catalyst/from_plxpr/qref_operator2_primitives.py index 2b5e0697db..047b288e12 100644 --- a/frontend/catalyst/from_plxpr/qref_operator2_primitives.py +++ b/frontend/catalyst/from_plxpr/qref_operator2_primitives.py @@ -112,6 +112,8 @@ def _qref_operator_p_lowering( # will be used in future improvements hybrid_lens = kwargs.pop("hybrid_lens") # pylint: disable=unused-variable hybrid_trees = kwargs.pop("hybrid_trees") # pylint: disable=unused-variable + adjoint = kwargs.pop("adjoint") # pylint: disable=unused-variable + n_ctrls = kwargs.pop("n_ctrls") # pylint: disable=unused-variable wire_lens = kwargs.pop("wire_lens") params = args[: len(op_cls.dynamic_argnames)] qubits = args[len(op_cls.dynamic_argnames) :] From 6c41c94f6e56d711e732e60b78c980561a8f333a Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Fri, 3 Jul 2026 10:05:13 -0400 Subject: [PATCH 2/4] Changelog --- doc/releases/changelog-dev.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md index 490f1c5bdb..1dbf592335 100644 --- a/doc/releases/changelog-dev.md +++ b/doc/releases/changelog-dev.md @@ -10,6 +10,7 @@ where applicable, unlocking compilation and execution for these cases. [(#2979)](https://github.com/PennyLaneAI/catalyst/pull/2979) [(#2969)](https://github.com/PennyLaneAI/catalyst/pull/2969/) + [(#2990)](https://github.com/PennyLaneAI/catalyst/pull/2990) * The `ResourceAnalysis` pass now reports each loop body and each subroutine as its own entry instead of folding their gate counts into the caller. Loops with constant bounds appear as `for_loop_` From ce22ca2122a139bc20b95ad235bdd3fea181dfea Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Fri, 3 Jul 2026 10:07:23 -0400 Subject: [PATCH 3/4] format --- .../catalyst/from_plxpr/qfunc_interpreter.py | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/frontend/catalyst/from_plxpr/qfunc_interpreter.py b/frontend/catalyst/from_plxpr/qfunc_interpreter.py index a11294baa6..954d6c0cc7 100644 --- a/frontend/catalyst/from_plxpr/qfunc_interpreter.py +++ b/frontend/catalyst/from_plxpr/qfunc_interpreter.py @@ -210,24 +210,16 @@ def _check_measurement_with_dynamic_allocation(self, measurement): """Check some constraints regarding dynamic allocation.""" if self.has_dynamic_allocation: if len(measurement.wires) == 0 and not isinstance(measurement, qp.measurements.StateMP): - raise CompileError( - textwrap.dedent( - """ + raise CompileError(textwrap.dedent(""" Terminal measurements must take in an explicit list of wires when dynamically allocated wires are present in the program. - """ - ) - ) + """)) if any(is_abstract_qubit(w) for w in measurement.wires): - raise CompileError( - textwrap.dedent( - """ + raise CompileError(textwrap.dedent(""" Terminal measurements cannot take in dynamically allocated wires since they must be temporary. - """ - ) - ) + """)) # pylint: disable=too-many-branches def interpret_measurement(self, measurement): From 871b9e08fd392e114f44accc05c047556ddda2c9 Mon Sep 17 00:00:00 2001 From: Mudit Pandey Date: Fri, 3 Jul 2026 10:11:51 -0400 Subject: [PATCH 4/4] pylint --- frontend/catalyst/from_plxpr/qfunc_interpreter.py | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/catalyst/from_plxpr/qfunc_interpreter.py b/frontend/catalyst/from_plxpr/qfunc_interpreter.py index 954d6c0cc7..bb7520065f 100644 --- a/frontend/catalyst/from_plxpr/qfunc_interpreter.py +++ b/frontend/catalyst/from_plxpr/qfunc_interpreter.py @@ -292,6 +292,7 @@ def __call__(self, jaxpr, *args): return self.eval(jaxpr.jaxpr, jaxpr.consts, *args) +# pylint: disable=too-many-arguments @PLxPRToQuantumJaxprInterpreter.register_primitive(operator_p) def _handle_operator(self, *args, op_cls, hybrid_lens, hybrid_trees, adjoint, n_ctrls, **kwargs):