1# Copyright (c) Meta Platforms, Inc. and affiliates. 2# All rights reserved. 3# 4# This source code is licensed under the BSD-style license found in the 5# LICENSE file in the root directory of this source tree. 6 7import unittest 8 9import torch 10from executorch.backends.xnnpack.test.tester import Tester 11from executorch.backends.xnnpack.test.tester.tester import Quantize 12from torchvision import models 13 14 15class TestInceptionV3(unittest.TestCase): 16 ic3 = models.inception_v3(weights="IMAGENET1K_V1").eval() # noqa 17 model_inputs = (torch.randn(1, 3, 224, 224),) 18 19 all_operators = { 20 "executorch_exir_dialects_edge__ops_aten_addmm_default", 21 "executorch_exir_dialects_edge__ops_aten_add_Tensor", 22 "executorch_exir_dialects_edge__ops_aten_cat_default", 23 "executorch_exir_dialects_edge__ops_aten_convolution_default", 24 "executorch_exir_dialects_edge__ops_aten_max_pool2d_with_indices_default", 25 # "executorch.exir.dialects.edge._ops.aten.avg_pool2d.default", Currently do not have avg_pool2d partitioned 26 "executorch_exir_dialects_edge__ops_aten_mean_dim", 27 "executorch_exir_dialects_edge__ops_aten__native_batch_norm_legit_no_training_default", 28 "executorch_exir_dialects_edge__ops_aten_permute_copy_default", 29 "executorch_exir_dialects_edge__ops_aten_relu_default", 30 } 31 32 def test_fp32_ic3(self): 33 34 ( 35 Tester(self.ic3, self.model_inputs) 36 .export() 37 .to_edge_transform_and_lower() 38 .check(["torch.ops.higher_order.executorch_call_delegate"]) 39 .check_not(list(self.all_operators)) 40 .to_executorch() 41 .serialize() 42 .run_method_and_compare_outputs() 43 ) 44 45 @unittest.skip("T187799178: Debugging Numerical Issues with Calibration") 46 def _test_qs8_ic3(self): 47 # Quantization fuses away batchnorm, so it is no longer in the graph 48 ops_after_quantization = self.all_operators - { 49 "executorch_exir_dialects_edge__ops_aten__native_batch_norm_legit_no_training_default", 50 } 51 52 ( 53 Tester(self.ic3, self.model_inputs) 54 .quantize() 55 .export() 56 .to_edge_transform_and_lower() 57 .check(["torch.ops.higher_order.executorch_call_delegate"]) 58 .check_not(list(ops_after_quantization)) 59 .to_executorch() 60 .serialize() 61 .run_method_and_compare_outputs() 62 ) 63 64 # TODO: Delete and only used calibrated test after T187799178 65 def test_qs8_ic3_no_calibration(self): 66 # Quantization fuses away batchnorm, so it is no longer in the graph 67 ops_after_quantization = self.all_operators - { 68 "executorch_exir_dialects_edge__ops_aten__native_batch_norm_legit_no_training_default", 69 } 70 71 ( 72 Tester(self.ic3, self.model_inputs) 73 .quantize(Quantize(calibrate=False)) 74 .export() 75 .to_edge_transform_and_lower() 76 .check(["torch.ops.higher_order.executorch_call_delegate"]) 77 .check_not(list(ops_after_quantization)) 78 .to_executorch() 79 .serialize() 80 .run_method_and_compare_outputs() 81 ) 82