Skip to content

Commit f5c779e

Browse files
committed
NXP backend: Conversion and quantization of aten.view
1 parent 0e98613 commit f5c779e

File tree

4 files changed

+37
-46
lines changed

4 files changed

+37
-46
lines changed

backends/nxp/quantizer/neutron_quantizer.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ReluPattern,
2626
ReshapePattern,
2727
SoftMaxPattern,
28+
ViewPattern,
2829
)
2930
from executorch.backends.nxp.quantizer.utils import (
3031
find_sequential_partitions_aten,
@@ -200,6 +201,7 @@ def __init__(self):
200201
NeutronAtenQuantizer(ReluPattern(), static_qconfig),
201202
NeutronAtenQuantizer(ReluInPlacePattern(), static_qconfig),
202203
NeutronAtenQuantizer(AvgPoolPattern(), static_qconfig),
204+
NeutronAtenQuantizer(ViewPattern(), static_qconfig),
203205
]
204206
)
205207

backends/nxp/quantizer/patterns.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,15 @@ def partition_types(self):
307307
return [torch.ops.aten.reshape.default]
308308

309309

310+
class ViewPattern(SharedSpecPattern):
311+
"""
312+
Quantizer for View operator.
313+
"""
314+
315+
def partition_types(self):
316+
return [torch.ops.aten.view.default]
317+
318+
310319
class SoftMaxPattern(QuantizationPattern):
311320
"""
312321
Quantizer for Softmax operator.

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

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@
77
import pytest
88
import torch
99

10-
from executorch.backends.nxp.backend.edge_program_converter import (
11-
EdgeProgramToIRConverter,
12-
)
13-
from executorch.backends.nxp.tests.executorch_pipeline import (
14-
to_edge_program,
15-
to_quantized_edge_program,
16-
)
10+
from executorch.backends.nxp.tests.executorch_pipeline import to_edge_program
1711
from executorch.backends.nxp.tests.executors import (
1812
convert_run_compare,
1913
ToNCHWPreprocess,
@@ -22,9 +16,7 @@
2216
from executorch.backends.nxp.tests.models import (
2317
ConstantPadNDConvModule,
2418
ConstantPadNDModule,
25-
Conv2dConstantPadNDModule,
2619
)
27-
from torch.export import ExportedProgram
2820

2921

3022
@pytest.fixture(autouse=True)
@@ -47,37 +39,6 @@ def test_constant_pad_nd_conversion__specific_constant(constant):
4739
convert_run_compare(edge_program, input_data)
4840

4941

50-
@pytest.mark.parametrize("constant", [0.0, 67.28, 42.0, -13.37])
51-
@pytest.mark.skip(reason="Neutron Converter does not fully convert for NPU")
52-
def test_constant_pad_nd_quant_conversion__specific_constant(mocker, constant):
53-
input_shape = (2, 4, 12, 12)
54-
paddings = (2, 2, 2, 2)
55-
56-
converter_spy = mocker.spy(EdgeProgramToIRConverter, "convert_program")
57-
58-
# Run conversion
59-
_ = to_quantized_edge_program(
60-
Conv2dConstantPadNDModule(paddings, constant), input_shape
61-
)
62-
63-
# Capture generated model
64-
tflite_flatbuffers_model, io_formats = converter_spy.spy_return
65-
66-
# Capture converted program
67-
edge_program: ExportedProgram = converter_spy.call_args.args[1]
68-
69-
input_data = (np.random.random(input_shape).astype(np.float32) * 50).astype(np.int8)
70-
71-
convert_run_compare(
72-
edge_program,
73-
input_data,
74-
tfl_model=tflite_flatbuffers_model,
75-
atol=1.0,
76-
tflite_input_preprocess=ToNHWCPreprocess(),
77-
tflite_output_preprocess=ToNCHWPreprocess(),
78-
)
79-
80-
8142
def test_constant_pad_nd_conversion__default_constant():
8243
input_shape = [2, 4, 6, 8]
8344
paddings = [1, 2, 3, 4]

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

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,24 @@ def forward(self, x):
8989
return x
9090

9191

92+
class ConvLinearViewModule(torch.nn.Module):
93+
def __init__(self, channels: int, channels_view_out: int):
94+
super().__init__()
95+
self.conv = nn.Conv2d(channels, channels, 3, 2)
96+
self.linear = nn.Linear(channels_view_out, 32, bias=True)
97+
self.channels_view_out = channels_view_out
98+
self.avg_pool = nn.AvgPool2d(1)
99+
self.relu = nn.ReLU()
100+
101+
def forward(self, x):
102+
x = self.conv(x)
103+
x = self.relu(x)
104+
x = self.avg_pool(x)
105+
x = x.view(-1, self.channels_view_out)
106+
x = self.linear(x)
107+
return x
108+
109+
92110
def test__channels_first_to_2d(mocker):
93111
input_shape = [2, 4, 7, 9]
94112
new_shape = [12, 32] # Mix up the dimensions for a thorough test.
@@ -205,19 +223,20 @@ def test_view_copy_w_linear_quant_conversion(mocker, input_shape, new_shape):
205223

206224

207225
@pytest.mark.parametrize(
208-
"input_shape, new_shape",
226+
"input_shape, channels_view_out",
209227
[
210-
pytest.param((1, 4, 16, 16), (50, 18), id="4D, batch_size=1"),
211-
pytest.param((10, 4, 16, 16), (500, 18), id="4D, , batch_size=10"),
228+
pytest.param((1, 4, 16, 16), 196, id="4D"),
212229
],
213230
)
214-
@pytest.mark.skip(reason="Neutron Converter does not fully convert for NPU")
215-
def test_view_copy_w_conv_quant_conversion(mocker, input_shape, new_shape):
231+
def test_view_w_conv_linear_quant_conversion(mocker, input_shape, channels_view_out):
216232
converter_spy = mocker.spy(EdgeProgramToIRConverter, "convert_program")
217233

218234
# Run conversion
219235
_ = to_quantized_edge_program(
220-
ConvReshapeModule(channels=input_shape[1], new_shape=new_shape), input_shape
236+
ConvLinearViewModule(
237+
channels=input_shape[1], channels_view_out=channels_view_out
238+
),
239+
input_shape,
221240
)
222241

223242
# Capture generated model

0 commit comments

Comments
 (0)