Skip to content

Commit b73df0b

Browse files
NXP backend: Enable Sub Tensor with new Neutron flow (#19588)
### Summary Add tests verifying correct support for sub.tensor by the Neutron backend using the new Neutron MLIR flow. ### Test plan Unit tests provided. cc @robert-kalmar @JakeStevens @digantdesai @rascani
1 parent ee4c90a commit b73df0b

6 files changed

Lines changed: 289 additions & 33 deletions

File tree

backends/nxp/backend/ir/converter/node_converters/ops_converters/sub_tensor_converter.py

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
# This source code is licensed under the BSD-style license found in the
44
# LICENSE file in the root directory of this source tree.
55

6+
import torch
7+
8+
from executorch.backends.nxp.backend.data_format import NXP_NODE_FORMAT
69
from executorch.backends.nxp.backend.ir.converter.node_converter import (
710
CustomDelegationOptions,
811
NodeConverter,
@@ -23,11 +26,33 @@ def _is_supported_on_target(
2326
parameters_mapping: dict[str, Parameter],
2427
custom_delegation_options: CustomDelegationOptions,
2528
) -> bool:
26-
if NodeConverter.uses_shape_broadcasting(node):
27-
# Shape broadcasting may require the addition of `Transpose` ops during conversion.
28-
return False
29+
if custom_delegation_options.use_new_flow_neutron_c:
30+
if not NodeConverter.at_least_one_input_shape_matches_the_output_shape(
31+
node
32+
):
33+
return False
2934

30-
return True
35+
# If one input is in channel first and ranks of input tensors are not equal, we need to add Transposes
36+
# Transpose is currently not supported for new flow
37+
if any(
38+
input_node.meta[NXP_NODE_FORMAT].is_channels_first()
39+
for input_node in node.all_input_nodes
40+
) and NodeConverter._node_inputs_ranks_not_equal(node):
41+
return False
42+
43+
supported_types = [torch.int8, torch.uint8]
44+
if not NodeConverter.uses_quantization_type_for_io(
45+
node, supported_types, [0, 1], [0]
46+
):
47+
return False
48+
49+
return True
50+
else:
51+
if NodeConverter.uses_shape_broadcasting(node):
52+
# Shape broadcasting may require the addition of `Transpose` ops during conversion.
53+
return False
54+
55+
return True
3156

3257
@staticmethod
3358
def _is_supported_in_IR(
@@ -45,9 +70,12 @@ def _is_supported_in_IR(
4570

4671
return True
4772

48-
# sub.Tensor Node format: (Tensor self, Tensor other, *, Scalar alpha=1)
4973
def convert(self, node: Node):
50-
"""Convert 'sub_tensor' operator to NeutronIR 'Sub'."""
74+
"""Convert 'sub_tensor' operator to NeutronIR 'Sub'.
75+
The ExecuTorch schema is:
76+
sub.Tensor(Tensor self, Tensor other, *, Scalar alpha=1)
77+
"""
78+
5179
self.assert_convertible(node)
5280

5381
t_op = self._create_tflite_op_with_io_tensors(node)

backends/nxp/tests/ir/converter/node_converter/test_avg_pool2d_converter.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import numpy as np
77
import pytest
88
import torch
9+
910
from executorch.backends.nxp.backend.edge_program_converter import (
1011
EdgeProgramToIRConverter,
1112
)
@@ -29,13 +30,8 @@
2930
ToNHWCPreprocess,
3031
)
3132
from executorch.backends.nxp.tests.graph_verifier import DetailedGraphVerifier
32-
from executorch.backends.nxp.tests.model_output_comparator import (
33-
NumericalStatsOutputComparator,
34-
)
3533
from executorch.backends.nxp.tests.models import AvgPool2dConvModule, AvgPool2dModule
36-
3734
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare
38-
3935
from executorch.backends.nxp.tests.ops_aliases import (
4036
AvgPool2D,
4137
ExecutorchDelegateCall,
@@ -45,6 +41,7 @@
4541
Unsqueeze,
4642
ViewCopy,
4743
)
44+
4845
from torch.export import ExportedProgram
4946
from executorch.backends.nxp.tests.use_qat import * # noqa F403
5047

@@ -320,7 +317,6 @@ def test__basic_nsys_inference(self, mocker):
320317
def test__basic_nsys_inference_qat(self, mocker):
321318
input_shape = (2, 9, 6, 15)
322319
model = AvgPool2dModule(False, 0)
323-
comparator = NumericalStatsOutputComparator()
324320
graph_verifier = DetailedGraphVerifier(
325321
mocker, expected_delegated_ops={AvgPool2D: 1}, expected_non_delegated_ops={}
326322
)
@@ -329,7 +325,6 @@ def test__basic_nsys_inference_qat(self, mocker):
329325
model,
330326
input_shape,
331327
graph_verifier,
332-
output_comparator=comparator,
333328
use_new_flow_neutron_c=True,
334329
use_qat=True,
335330
)

backends/nxp/tests/ir/converter/node_converter/test_max_pool_2d_converter.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# LICENSE file in the root directory of this source tree.
55

66
import numpy as np
7+
import pytest
78
import torch
89

910
from executorch.backends.nxp.backend.edge_program_converter import (
@@ -17,9 +18,6 @@
1718
ToChannelLastPreprocess,
1819
)
1920
from executorch.backends.nxp.tests.graph_verifier import DetailedGraphVerifier
20-
from executorch.backends.nxp.tests.model_output_comparator import (
21-
NumericalStatsOutputComparator,
22-
)
2321
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare
2422
from executorch.backends.nxp.tests.ops_aliases import (
2523
ExecutorchDelegateCall,
@@ -32,7 +30,6 @@
3230
ViewCopy,
3331
)
3432
from executorch.backends.nxp.tests.use_qat import * # noqa F403
35-
import pytest
3633

3734

3835
class MaxPool1DModule(torch.nn.Module):
@@ -286,7 +283,6 @@ def test__basic_nsys_inference(self, mocker):
286283
def test__basic_nsys_inference_qat(self, mocker):
287284
input_shape = (2, 11, 7, 16) # The old flow limited the batch size to 1.
288285
model = MaxPool2dModule()
289-
comparator = NumericalStatsOutputComparator()
290286
graph_verifier = DetailedGraphVerifier(
291287
mocker,
292288
expected_delegated_ops={MaxPool2DWithIndices: 1, GetItem: 1},
@@ -297,7 +293,6 @@ def test__basic_nsys_inference_qat(self, mocker):
297293
model,
298294
input_shape,
299295
graph_verifier,
300-
output_comparator=comparator,
301296
use_new_flow_neutron_c=True,
302297
use_qat=True,
303298
)

backends/nxp/tests/ir/converter/node_converter/test_mul_tensor_converter.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@
2121
ToChannelLastPreprocess,
2222
)
2323
from executorch.backends.nxp.tests.graph_verifier import DetailedGraphVerifier
24-
from executorch.backends.nxp.tests.model_output_comparator import (
25-
NumericalStatsOutputComparator,
26-
)
2724
from executorch.backends.nxp.tests.models import (
2825
MulTensorConvModule,
2926
MulTensorModule,
@@ -256,7 +253,6 @@ def test__basic_nsys_inference(self, x_input_shape, mocker):
256253
def test__basic_nsys_inference_qat(self, x_input_shape, mocker):
257254
x_input_spec = ModelInputSpec(x_input_shape)
258255
model = MulTensorModule()
259-
comparator = NumericalStatsOutputComparator()
260256
graph_verifier = DetailedGraphVerifier(
261257
mocker, expected_delegated_ops={MulTensor: 1}, expected_non_delegated_ops={}
262258
)
@@ -265,7 +261,6 @@ def test__basic_nsys_inference_qat(self, x_input_shape, mocker):
265261
model,
266262
[x_input_spec, x_input_spec],
267263
graph_verifier,
268-
output_comparator=comparator,
269264
use_new_flow_neutron_c=True,
270265
use_qat=True,
271266
)

0 commit comments

Comments
 (0)