Skip to content

Add extended support from new Neutron C flow for Clamp operator#19510

Open
StrycekSimon wants to merge 4 commits into
pytorch:mainfrom
nxp-upstream:feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow
Open

Add extended support from new Neutron C flow for Clamp operator#19510
StrycekSimon wants to merge 4 commits into
pytorch:mainfrom
nxp-upstream:feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow

Conversation

@StrycekSimon
Copy link
Copy Markdown
Collaborator

@StrycekSimon StrycekSimon commented May 12, 2026

Summary

  • Moves flag indicating use of the new Neutron C flow from CustomCompileConfig to NeutronTargetSpec
  • Adds new Neutron C flow support for Clamp operator

Test plan

New test cases for Clamp are introduced. The relocation of new flag is covered by already existing unit tests.

cc @robert-kalmar @JakeStevens @digantdesai @rascani

@pytorch-bot
Copy link
Copy Markdown

pytorch-bot Bot commented May 12, 2026

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/19510

Note: Links to docs will display an error until the docs builds have been completed.

✅ No Failures

As of commit 54e327d with merge base b04cc65 (image):
💚 Looks good so far! There are no failures yet. 💚

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label May 12, 2026
@StrycekSimon StrycekSimon added module: nxp Issues related to NXP Neutron NPU delegation and code under backends/nxp/ release notes: nxp Changes to the NXP Neutron backend delegate labels May 12, 2026
@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch 2 times, most recently from 3a90b03 to f65fe45 Compare May 15, 2026 07:50
@StrycekSimon StrycekSimon changed the title Draft: Add extended support from new Neutron C flow for Clamp operator Add extended support from new Neutron C flow for Clamp operator May 15, 2026
@StrycekSimon StrycekSimon marked this pull request as ready for review May 15, 2026 08:20
Copilot AI review requested due to automatic review settings May 15, 2026 08:20
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR moves the use_new_flow_neutron_c flag from CustomDelegationOptions onto NeutronTargetSpec so it can be threaded through the quantizer and converters as part of target configuration, and extends the new Neutron‑C flow's clamp support beyond Relu‑shaped bounds by emitting Maximum/Minimum ops with quantized constants.

Changes:

  • Move use_new_flow_neutron_c from CustomDelegationOptions to NeutronTargetSpec, updating all call sites and converters that read the flag.
  • Extend ClampConverter to lower arbitrary clamp bounds to a Max+Min sequence under the new flow, factoring _is_convertible_to_relu out as a helper used by both the converter and the new ClampPattern.get_anchors.
  • Refactor QuantizationPattern to require neutron_quantizer in the base constructor, propagate this through all subclasses, and rework ClampPattern to use a shared‑spec anchor under the new flow.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
backends/nxp/backend/custom_delegation_options.py Removes use_new_flow_neutron_c from CustomDelegationOptions.
backends/nxp/backend/neutron_target_spec.py Adds use_new_flow_neutron_c constructor argument and attribute.
backends/nxp/nxp_backend.py Threads flag into NeutronTargetSpec constructions; drops it from CustomDelegationOptions.
backends/nxp/backend/ir/converter/node_converters/ops_converters/abs_converter.py Reads new flag from target spec instead of delegation options.
backends/nxp/backend/ir/converter/node_converters/ops_converters/avg_pool_2d_converter.py Same flag-source switch.
backends/nxp/backend/ir/converter/node_converters/ops_converters/max_pool2d_with_indices_converter.py Same flag-source switch.
backends/nxp/backend/ir/converter/node_converters/ops_converters/mul_tensor_converter.py Same flag-source switch.
backends/nxp/backend/ir/converter/node_converters/ops_converters/clamp_converter.py Adds Max/Min lowering for non‑Relu clamp bounds under new flow; introduces _is_convertible_to_relu.
backends/nxp/quantizer/patterns.py QuantizationPattern now takes neutron_quantizer; ClampPattern adds shared‑spec anchors when new flow is on.
backends/nxp/quantizer/neutron_quantizer.py Passes self into all pattern constructors.
backends/nxp/tests/executorch_pipeline.py Construct NeutronTargetSpec with the new flag; minor formatting.
backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py Adds parameterized tests for clamp under the new Neutron‑C flow.
examples/nxp/aot_neutron_compile.py Forwards CLI flag into NeutronTargetSpec.
Comments suppressed due to low confidence (1)

backends/nxp/backend/ir/converter/node_converters/ops_converters/clamp_converter.py:169

  • The min/max constant tensors are hard-coded to np.int8, but _is_supported_on_target returns True unconditionally when use_new_flow_neutron_c is set, with no dtype filter. If the input is uint8 (which is listed as a supported type by other converters in this flow, e.g. abs_converter.py, avg_pool_2d_converter.py), values >127 will silently overflow when stored as int8, producing incorrect outputs. The dtype passed to np.array should be derived from the dequant node's dtype (or from quant_min/quant_max).
        min_tensor = self.builder.create_tensor_for_data(
            np.array([min_value], np.int8), "min"
        )
        self.propagate_quantization(x, min_tensor)
        max_tensor = self.builder.create_tensor_for_data(
            np.array([max_value], np.int8), "max"
        )

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread backends/nxp/quantizer/patterns.py Outdated
Comment thread backends/nxp/backend/neutron_target_spec.py Outdated
Comment thread backends/nxp/quantizer/patterns.py

# Make sure the `clamp` was NOT delegated.
assert graph_contains_any_of_ops(delegated_ep.graph, [Clamp])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Please add the new tests inside a class. It's a new convention we have started with the new flow:
class TestClampNewNeutronFlow:
We can then use shorter test names with improved clarity.

Please draw inspiration from other open PRs which enable new ops (e.g. here). The TestClampNewNeutronFlow class should test all aspects of the operator with the new flow, because eventually we will remove the old tests with the old flow. So please add more tests.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The tests are now inside a class. Also, added a broader set of test cases + more robust testing including verification of producing ReLU vs. Min/Max. I had to resort to spying on TFlite builder itself. Can you have a look?

Comment thread backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py Outdated
pytest.param(10, 17, id="min = 10, max = 17 (Max/Min)"),
pytest.param(0, 1, id="min = 0, max = 1 (Relu0To1)"),
pytest.param(-1, 1, id="min = -1, max = 1 (ReluN1To1)"),
pytest.param(0, None, id="min = 0, max = None (Relu)"),
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would be nice to see some assertions that the node is indeed converted to a Relu variant when possible.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Added checking in TFLite. (See my response in your other comment.)

Copy link
Copy Markdown
Collaborator

@roman-janik-nxp roman-janik-nxp left a comment

Choose a reason for hiding this comment

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

Needs a rework.

@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch from f65fe45 to f3c4576 Compare May 21, 2026 15:10
Copilot AI review requested due to automatic review settings May 25, 2026 06:38
@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch from f3c4576 to 2708c0c Compare May 25, 2026 06:38
@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 25, 2026

CLA Not Signed

@StrycekSimon
Copy link
Copy Markdown
Collaborator Author

Here we go again with Copilot... 😄

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comments suppressed due to low confidence (2)

backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py:37

  • exir_ops is imported but not used anywhere in this test module, which will fail unused-import linting (F401). Remove this import to keep the test file lint-clean.
)
from executorch.exir.dialects._ops import ops as exir_ops
from executorch.backends.nxp.tests.use_qat import *

backends/nxp/backend/ir/converter/node_converters/ops_converters/clamp_converter.py:210

  • max_tensor is created with a hard-coded np.int8 dtype. If the clamp IO quantization dtype is uint8, this will produce an incorrect constant tensor type/value. Create the constant using the same dtype as the clamp input/output quantization.
        if max_value is not None:
            max_value = self._quantize_value(max_value, zp, scale, quant_min, quant_max)
            max_tensor = self.builder.create_tensor_for_data(
                np.array([max_value], np.int8), "max"
            )

Comment thread backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py Outdated
@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch from 2708c0c to 3ddb14b Compare May 25, 2026 07:34
dequant_node = list(intermediate_ep.graph.nodes)[-4]
tflite_internal_ops = list(
op.builtin_code for op in tflite_spy.spy_return.operator_codes.vector
)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Well done 👍🏻

Copilot AI review requested due to automatic review settings May 25, 2026 14:40
@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch from 3ddb14b to 7b06dec Compare May 25, 2026 14:40
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 14 out of 14 changed files in this pull request and generated 4 comments.

Comment thread backends/nxp/quantizer/patterns.py
Comment thread backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py Outdated
@StrycekSimon StrycekSimon force-pushed the feature/nxg10272/EIEX-864-add-clamp-support-using-new-neutron-flow branch from 7b06dec to 54e327d Compare May 25, 2026 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. module: nxp Issues related to NXP Neutron NPU delegation and code under backends/nxp/ release notes: nxp Changes to the NXP Neutron backend delegate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants