(self)
| 43 | """ |
| 44 | |
| 45 | def test_resnet(self) -> None: |
| 46 | import copy |
| 47 | |
| 48 | with override_quantized_engine("qnnpack"): |
| 49 | torch.backends.quantized.engine = "qnnpack" |
| 50 | example_inputs = (torch.randn(1, 3, 224, 224),) |
| 51 | m = torchvision.models.resnet18().eval() |
| 52 | m_copy = copy.deepcopy(m) |
| 53 | # program capture |
| 54 | m = torch.export.export( |
| 55 | m, copy.deepcopy(example_inputs), strict=True |
| 56 | ).module() |
| 57 | |
| 58 | quantizer = XNNPACKQuantizer() |
| 59 | operator_config = get_symmetric_quantization_config(is_per_channel=True) |
| 60 | quantizer.set_global(operator_config) |
| 61 | m = prepare_pt2e(m, quantizer) # pyre-fixme[6] |
| 62 | self.assertEqual( |
| 63 | id(m.activation_post_process_3), id(m.activation_post_process_2) |
| 64 | ) |
| 65 | after_prepare_result = m(*example_inputs)[0] |
| 66 | m = convert_pt2e(m) |
| 67 | |
| 68 | # TODO: conv, conv_relu, linear delegation |
| 69 | # quantized ops to implement: add_relu |
| 70 | compile_config = EdgeCompileConfig( |
| 71 | _check_ir_validity=False, |
| 72 | ) |
| 73 | m = to_edge( |
| 74 | export(m, example_inputs, strict=True), compile_config=compile_config |
| 75 | ).transform([QuantFusionPass(), SpecPropPass()]) |
| 76 | |
| 77 | after_quant_result = m.exported_program().module()(*example_inputs)[0] |
| 78 | FileCheck().check( |
| 79 | "executorch_exir_dialects_edge__ops_quantized_decomposed_quantize_per_tensor" |
| 80 | ).check( |
| 81 | "executorch_exir_dialects_edge__ops_quantized_decomposed_dequantize_per_tensor" |
| 82 | ).run( |
| 83 | m.exported_program().graph_module.code |
| 84 | ) |
| 85 | # after_quant_fusion_result = m(*example_inputs)[0] |
| 86 | |
| 87 | # TODO: implement torch.ops.quantized_decomposed.add_relu.out |
| 88 | # m = m.to_executorch().dump_graph_module() |
| 89 | # after_to_executorch = m(*example_inputs)[0] |
| 90 | # test the result before and after to_executorch matches |
| 91 | # TODO: debug why this is a mismatch |
| 92 | # self.assertTrue(torch.equal(after_quant_fusion_result, after_to_executorch)) |
| 93 | # self.assertEqual(compute_sqnr(after_quant_fusion_result, after_to_executorch), torch.tensor(float("inf"))) |
| 94 | |
| 95 | # comparing with existing fx graph mode quantization reference flow |
| 96 | qconfig = default_per_channel_symmetric_qnnpack_qconfig |
| 97 | qconfig_mapping = QConfigMapping().set_global(qconfig) |
| 98 | backend_config = get_executorch_backend_config() |
| 99 | m_fx = prepare_fx( |
| 100 | m_copy, qconfig_mapping, example_inputs, backend_config=backend_config |
| 101 | ) |
| 102 | after_prepare_result_fx = m_fx(*example_inputs) |
nothing calls this directly
no test coverage detected