Skip to content

Commit 69eeed2

Browse files
authored
NXP backend: use channels-first for reference testing model (pytorch#23308)
### Summary Refactor the testing suite to enable reference testing in channels-first. PR is merged. ### Test plan tests can be manually run using `pytest -c /dev/null backends/nxp/tests/` cc @robert-kalmar @JakeStevens @digantdesai @rascani @roman-janik-nxp
1 parent aee0a33 commit 69eeed2

11 files changed

Lines changed: 229 additions & 125 deletions

‎backends/nxp/tests/generic_tests/test_debug_results.py‎

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,15 @@ def test_nsys_test_debug_results__single_input(caplog, request):
3737

3838
graph_verifier = BaseGraphVerifier(1, [])
3939

40+
# use different reference model dim order so transposed dataset is created
41+
ref_input_spec = ModelInputSpec(input_shape, dim_order=torch.channels_last)
4042
lower_run_compare(
4143
model,
4244
input_shape,
4345
graph_verifier,
4446
request,
4547
remove_quant_io_ops=True,
48+
reference_input_spec=[ref_input_spec],
4649
)
4750

4851
test_name = get_test_name(request)
@@ -70,10 +73,16 @@ def test_nsys_test_debug_results__single_input(caplog, request):
7073

7174
# Check text tensor variants
7275
assert os.path.isfile(
73-
os.path.join(OUTPUTS_DIR, test_name, "dataset", "calibration", "0000.txt")
76+
os.path.join(OUTPUTS_DIR, test_name, "model_dataset", "calibration", "0000.txt")
7477
)
7578
assert os.path.isfile(
76-
os.path.join(OUTPUTS_DIR, test_name, "dataset_quant", "0000.txt")
79+
os.path.join(OUTPUTS_DIR, test_name, "model_dataset_quant", "0000.txt")
80+
)
81+
assert os.path.isfile(
82+
os.path.join(OUTPUTS_DIR, test_name, "ref_dataset", "calibration", "0000.bin")
83+
)
84+
assert os.path.isfile(
85+
os.path.join(OUTPUTS_DIR, test_name, "ref_dataset_quant", "0000.bin")
7786
)
7887
assert os.path.isfile(
7988
os.path.join(OUTPUTS_DIR, test_name, "results_cpu", "0000.bin", "0000.txt")
@@ -140,7 +149,7 @@ def test_nsys_test_debug_results__multiple_input(self, caplog, request):
140149
# Check text tensor variants
141150
assert os.path.isfile(
142151
os.path.join(
143-
OUTPUTS_DIR, test_name, "dataset", "calibration", "0000", "00.txt"
152+
OUTPUTS_DIR, test_name, "model_dataset", "calibration", "0000", "00.txt"
144153
)
145154
)
146155
assert os.path.isfile(

‎backends/nxp/tests/generic_tests/test_quantized_input_data.py‎

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from executorch.backends.nxp.tests.nsys_testing import (
1313
lower_run_compare,
1414
OUTPUTS_DIR,
15-
ReferenceModel,
15+
ReferenceRunner,
1616
)
1717
from executorch.backends.nxp.tests.simple_models import AvgPool2dModule, MulTensorModule
1818

@@ -34,7 +34,7 @@ def test__single_quantized_inputs(mocker, request):
3434
)
3535

3636
test_name = nsys_testing.get_test_name(request)
37-
assert (OUTPUTS_DIR / test_name / "dataset_quant" / "0000.bin").exists()
37+
assert (OUTPUTS_DIR / test_name / "model_dataset_quant" / "0000.bin").exists()
3838

3939
# Check outputs are in quantized int8 format
4040
output_tensor_spec = output_tensor_spec_spy.spy_return
@@ -54,12 +54,12 @@ def test__single_quantized_inputs_edge_python_reference(mocker, request):
5454
[input_spec],
5555
graph_verifier,
5656
request,
57-
reference_model=ReferenceModel.QUANTIZED_EDGE_PYTHON,
57+
reference_runner=ReferenceRunner.QUANTIZED_EDGE_PYTHON,
5858
remove_quant_io_ops=True,
5959
)
6060

6161
test_name = nsys_testing.get_test_name(request)
62-
assert (OUTPUTS_DIR / test_name / "dataset_quant" / "0000.bin").exists()
62+
assert (OUTPUTS_DIR / test_name / "model_dataset_quant" / "0000.bin").exists()
6363

6464
# Check outputs are in quantized int8 format
6565
output_tensor_spec = output_tensor_spec_spy.spy_return
@@ -83,7 +83,9 @@ def test__multiple_quantized_inputs(mocker, request):
8383
)
8484

8585
test_name = nsys_testing.get_test_name(request)
86-
assert (OUTPUTS_DIR / test_name / "dataset_quant" / "0000" / "00.bin").exists()
86+
assert (
87+
OUTPUTS_DIR / test_name / "model_dataset_quant" / "0000" / "00.bin"
88+
).exists()
8789

8890
# Check outputs are in quantized int8 format
8991
output_tensor_spec = output_tensor_spec_spy.spy_return
@@ -103,12 +105,14 @@ def test__multiple_quantized_inputs_edge_python_reference(mocker, request):
103105
[x_input_spec, x_input_spec],
104106
graph_verifier,
105107
request,
106-
reference_model=ReferenceModel.QUANTIZED_EDGE_PYTHON,
108+
reference_runner=ReferenceRunner.QUANTIZED_EDGE_PYTHON,
107109
remove_quant_io_ops=True,
108110
)
109111

110112
test_name = nsys_testing.get_test_name(request)
111-
assert (OUTPUTS_DIR / test_name / "dataset_quant" / "0000" / "00.bin").exists()
113+
assert (
114+
OUTPUTS_DIR / test_name / "model_dataset_quant" / "0000" / "00.bin"
115+
).exists()
112116

113117
# Check outputs are in quantized int8 format
114118
output_tensor_spec = output_tensor_spec_spy.spy_return

‎backends/nxp/tests/ir/converter/node_converter/test_clamp_converter.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test__qat(self, mocker, request, min, max, use_qat):
8989

9090
lower_run_compare(
9191
model=model,
92-
input_spec=[x_input_spec],
92+
model_input_spec=[x_input_spec],
9393
request=request,
9494
dlg_model_verifier=graph_verifier,
9595
)
@@ -132,7 +132,7 @@ def test_convert_clamp__full_pipeline(self, mocker, request, min, max):
132132

133133
lower_run_compare(
134134
model=model,
135-
input_spec=[x_input_spec],
135+
model_input_spec=[x_input_spec],
136136
dlg_model_verifier=graph_verifier,
137137
request=request,
138138
)

‎backends/nxp/tests/ir/converter/node_converter/test_conv_converter.py‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from executorch.backends.nxp.tests.nsys_testing import (
2121
AllCloseOutputComparator,
2222
lower_run_compare,
23-
ReferenceModel,
23+
ReferenceRunner,
2424
)
2525
from executorch.backends.nxp.tests.simple_models import (
2626
Conv2dModule,
@@ -43,7 +43,7 @@ def assert_delegated_and_correct(
4343
use_qat=False,
4444
exp_delegated_ops=None,
4545
exp_non_delegated_ops=None,
46-
et_ref_model=ReferenceModel.QUANTIZED_EXECUTORCH_CPP,
46+
et_ref_model=ReferenceRunner.QUANTIZED_EXECUTORCH_CPP,
4747
):
4848
if exp_delegated_ops is None:
4949
exp_delegated_ops = {Convolution: 1}
@@ -70,7 +70,7 @@ def assert_delegated_and_correct(
7070
comparator,
7171
use_qat=use_qat,
7272
remove_quant_io_ops=remove_quant_io_ops,
73-
reference_model=et_ref_model,
73+
reference_runner=et_ref_model,
7474
)
7575

7676

@@ -198,9 +198,9 @@ def test__tr_unusual(
198198
# Running `conv_transpose2d` with `output_channels = 1` produces errors in Executorch. The issue has been reported:
199199
# https://github.com/pytorch/executorch/issues/20804
200200
ref_model = (
201-
ReferenceModel.QUANTIZED_EXECUTORCH_CPP
201+
ReferenceRunner.QUANTIZED_EXECUTORCH_CPP
202202
if use_et_ref_model
203-
else ReferenceModel.QUANTIZED_EDGE_PYTHON
203+
else ReferenceRunner.QUANTIZED_EDGE_PYTHON
204204
)
205205

206206
assert_delegated_and_correct(

‎backends/nxp/tests/models/test_cifarnet.py‎

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
NumericalStatsOutputComparator,
1818
)
1919

20-
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare, ReferenceModel
20+
from executorch.backends.nxp.tests.nsys_testing import (
21+
lower_run_compare,
22+
ReferenceRunner,
23+
)
2124
from executorch.examples.nxp.experimental.cifar_net.cifar_net import (
2225
CifarNet,
2326
store_test_data,
@@ -69,10 +72,10 @@ def test_cifarnet(mocker, request, cifar_test_files, channels_last):
6972
# Run the channels last reference in PyTorch as the ExecuTorch CPU model contains incorrectly
7073
# lowered channels last convolution weights, which cause incorrect inference results. The issue
7174
# is caused by ExecuTorch (not NXP). https://github.com/pytorch/executorch/issues/16464
72-
reference_model=(
73-
ReferenceModel.QUANTIZED_EDGE_PYTHON
75+
reference_runner=(
76+
ReferenceRunner.QUANTIZED_EDGE_PYTHON
7477
if channels_last
75-
else ReferenceModel.QUANTIZED_EXECUTORCH_CPP
78+
else ReferenceRunner.QUANTIZED_EXECUTORCH_CPP
7679
),
7780
)
7881

‎backends/nxp/tests/models/test_mlperf_tiny_anomaly_detection.py‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
)
2525

2626
BOUNDS_MSE = {
27-
"PTQ": 1.4e-08,
28-
"QAT": 5.205e-06,
27+
"PTQ": 1.0e-8,
28+
"QAT": 1.0e-6,
2929
}
3030

3131

@@ -53,22 +53,26 @@ def test_mlperf_tiny_anomaly_detection_mse_cpu_vs_npu(
5353
dataset, num_examples=num_samples, idx_to_label=labels
5454
)
5555

56-
input_spec = ModelInputSpec(anomaly_detection.input_shape)
56+
model_input_spec = ModelInputSpec(anomaly_detection.input_shape)
5757
quant_type_key = "QAT" if use_qat else "PTQ"
5858

5959
mse = BOUNDS_MSE[quant_type_key]
6060
comparator = NumericalStatsOutputComparator(max_mse_error=mse)
6161
model_verifier = BaseGraphVerifier(1, [])
6262
train_fn = anomaly_detection.train_model_fn if use_qat else None
6363

64+
ref_input_spec = ModelInputSpec(anomaly_detection.input_shape)
65+
ref_input_spec.dim_order = torch.contiguous_format
66+
6467
lower_run_compare(
6568
model,
66-
[input_spec],
69+
[model_input_spec],
6770
model_verifier,
6871
request,
6972
dataset_creator=dataset_creator,
7073
output_comparator=comparator,
7174
mocker=mocker,
75+
reference_input_spec=[ref_input_spec],
7276
use_qat=use_qat,
7377
train_fn=train_fn,
7478
)

‎backends/nxp/tests/models/test_mlperf_tiny_image_classification.py‎

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
from executorch.backends.nxp.tests.model_output_comparator import (
2020
NumericalStatsOutputComparator,
2121
)
22-
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare, ReferenceModel
22+
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare
2323
from executorch.backends.nxp.tests.use_qat import * # noqa F403
2424
from executorch.examples.nxp.models.mlperf_tiny.image_classification.mlperf_tiny_image_classification import (
2525
MLPerfTinyImageClassification,
2626
)
2727

2828
BOUNDS_MSE = {
29-
"PTQ": {"channels-last": 1.859e-05, "channels-first": 7.432e-09},
30-
"QAT": {"channels-last": 2.751e-07, "channels-first": 5.205e-06},
29+
"PTQ": {"channels-last": 1.0e-9, "channels-first": 1.0e-9},
30+
"QAT": {"channels-last": 1.0e-8, "channels-first": 1.0e-7},
3131
}
3232

3333

@@ -54,10 +54,10 @@ def test_mlperf_tiny_classification_mse_cpu_vs_npu(
5454
dataset, num_examples=num_samples, idx_to_label=labels
5555
)
5656

57-
input_spec = ModelInputSpec(img_classification.input_shape)
57+
model_input_spec = ModelInputSpec(img_classification.input_shape)
5858
if channels_last:
5959
model.to(memory_format=torch.channels_last)
60-
input_spec.dim_order = torch.channels_last
60+
model_input_spec.dim_order = torch.channels_last
6161

6262
quant_type_key = "QAT" if use_qat else "PTQ"
6363
format_key = "channels-last" if channels_last else "channels-first"
@@ -73,22 +73,18 @@ def test_mlperf_tiny_classification_mse_cpu_vs_npu(
7373
else None
7474
)
7575

76-
# Portable constant_pad_nd does not support channels-last tensors.
77-
ref_model = (
78-
ReferenceModel.QUANTIZED_EDGE_PYTHON
79-
if channels_last
80-
else ReferenceModel.QUANTIZED_EXECUTORCH_CPP
81-
)
76+
ref_input_spec = ModelInputSpec(img_classification.input_shape)
77+
ref_input_spec.dim_order = torch.contiguous_format
8278

8379
lower_run_compare(
8480
model,
85-
[input_spec],
81+
[model_input_spec],
8682
model_verifier,
8783
request,
8884
dataset_creator=dataset_creator,
8985
output_comparator=comparator,
90-
reference_model=ref_model,
9186
mocker=mocker,
87+
reference_input_spec=[ref_input_spec],
9288
use_qat=use_qat,
9389
train_fn=train_fn,
9490
)

‎backends/nxp/tests/models/test_mlperf_tiny_keyword_spotting.py‎

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,20 @@
1919
from executorch.backends.nxp.tests.model_output_comparator import (
2020
NumericalStatsOutputComparator,
2121
)
22-
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare, ReferenceModel
22+
from executorch.backends.nxp.tests.nsys_testing import lower_run_compare
2323
from executorch.backends.nxp.tests.use_qat import * # noqa F403
2424
from executorch.examples.nxp.models.mlperf_tiny.keyword_spotting.mlperf_tiny_keyword_spotting import (
2525
MLPerfTinyKeywordSpotting,
2626
)
2727

2828
BOUNDS_MSE = {
2929
"PTQ": {
30-
"channels-last": 3.5e-4,
31-
"channels-first": 2.0e-6,
30+
"channels-last": 1.0e-15,
31+
"channels-first": 1.0e-6,
3232
},
3333
"QAT": {
34-
"channels-last": 3.5e-4,
35-
"channels-first": 5.0e-5,
34+
"channels-last": 0.0,
35+
"channels-first": 1.0e-4,
3636
},
3737
}
3838

@@ -58,10 +58,10 @@ def test_mlperf_tiny_kws_mse_cpu_vs_npu(mocker, request, channels_last, use_qat)
5858
dataset, num_examples=num_samples, idx_to_label=labels
5959
)
6060

61-
input_spec = ModelInputSpec(kws.input_shape)
61+
model_input_spec = ModelInputSpec(kws.input_shape)
6262
if channels_last:
6363
model.to(memory_format=torch.channels_last)
64-
input_spec.dim_order = torch.channels_last
64+
model_input_spec.dim_order = torch.channels_last
6565

6666
quant_type_key = "QAT" if use_qat else "PTQ"
6767
format_key = "channels-last" if channels_last else "channels-first"
@@ -74,15 +74,18 @@ def test_mlperf_tiny_kws_mse_cpu_vs_npu(mocker, request, channels_last, use_qat)
7474
partial(kws.train_model_fn, channels_last=channels_last) if use_qat else None
7575
)
7676

77+
ref_input_spec = ModelInputSpec(kws.input_shape)
78+
ref_input_spec.dim_order = torch.contiguous_format
79+
7780
lower_run_compare(
7881
model,
79-
[input_spec],
82+
[model_input_spec],
8083
model_verifier,
8184
request,
8285
dataset_creator=dataset_creator,
8386
output_comparator=comparator,
8487
mocker=mocker,
85-
reference_model=ReferenceModel.QUANTIZED_EXECUTORCH_CPP,
88+
reference_input_spec=[ref_input_spec],
8689
use_qat=use_qat,
8790
train_fn=train_fn,
8891
)

0 commit comments

Comments
 (0)