From 1a048c5e745d8bf6fcf2265b76f3a7e9b565bcc1 Mon Sep 17 00:00:00 2001 From: Nitin Jain Date: Thu, 28 Aug 2025 23:42:49 -0700 Subject: [PATCH] Add 16A8W support and test for tanh operation Add 16A8W quantization support and test for the tanh operation in ExecutorTorch ARM backend. This follows the pattern established for linear, mul, and sigmoid operations, extending int16 support to tanh operations. Changes: - Add INT16 dtype validation support in op_tanh.py - Add test_tanh_tensor_16a8w_tosa_INT test function - Enable test_tanh.py in test targets configuration The 16A8W configuration uses 16-bit activations with 8-bit weights, enabling higher precision for activations while maintaining weight efficiency. Differential Revision: [D80510815](https://our.internmc.facebook.com/intern/diff/D80510815/) [ghstack-poisoned] --- backends/arm/test/ops/test_tanh.py | 108 ++++++++++++++++++++++++++++- 1 file changed, 107 insertions(+), 1 deletion(-) diff --git a/backends/arm/test/ops/test_tanh.py b/backends/arm/test/ops/test_tanh.py index 098d878addc..6e6943f1f52 100644 --- a/backends/arm/test/ops/test_tanh.py +++ b/backends/arm/test/ops/test_tanh.py @@ -6,9 +6,14 @@ from typing import Tuple +import pytest import torch +from executorch.backends.arm.quantizer.arm_quantizer import ( + get_symmetric_a16w8_quantization_config, + TOSAQuantizer, +) -from executorch.backends.arm.test import common +from executorch.backends.arm.test import common, conftest from executorch.backends.arm.test.tester.test_pipeline import ( EthosU55PipelineINT, EthosU85PipelineINT, @@ -16,6 +21,8 @@ TosaPipelineINT, VgfPipeline, ) +from executorch.backends.arm.tosa_specification import TosaSpecification +from executorch.backends.xnnpack.test.tester import Quantize aten_op = "torch.ops.aten.tanh.default" input_t1 = Tuple[torch.Tensor] # Input x @@ -105,3 +112,102 @@ def test_tanh_vgf_INT(test_data: Tuple): tosa_version="TOSA-1.0+INT", ) pipeline.run() + + +def get_symmetric_a16w8_tanh_quantizer(per_channel_quantization=False): + tosa_version = conftest.get_option("tosa_version") + tosa_profiles = { + "1.0": TosaSpecification.create_from_string("TOSA-1.0+INT+int16"), + } + + quantizer = TOSAQuantizer(tosa_profiles[tosa_version]) + quantizer.set_global( + get_symmetric_a16w8_quantization_config(is_per_channel=per_channel_quantization) + ) + + return Quantize( + quantizer, + get_symmetric_a16w8_quantization_config( + is_per_channel=per_channel_quantization + ), + ) + + +@common.parametrize("test_data", test_data_suite) +def test_tanh_16a8w_tosa_INT(test_data: torch.Tensor): + """Test tanh operation with 16A8W quantization (16-bit activations, 8-bit weights)""" + per_channel_quantization = False + + pipeline = TosaPipelineINT[input_t1]( + Tanh(), + (test_data(),), + aten_op, + exir_op=[], + per_channel_quantization=per_channel_quantization, + use_to_edge_transform_and_lower=True, + tosa_extensions=["int16"], + ) + + pipeline.change_args( + "quantize", + get_symmetric_a16w8_tanh_quantizer( + per_channel_quantization=per_channel_quantization + ), + ) + pipeline.run() + + +@common.parametrize("test_data", test_data_suite) +@common.XfailIfNoCorstone300 +@pytest.mark.xfail( + reason="Vela compilation fails with 'Invalid arguments' for int16 tanh operations" +) +def test_tanh_16a8w_u55_INT16(test_data: torch.Tensor): + """Test tanh operation with 16A8W quantization on U55 (16-bit activations, 8-bit weights)""" + per_channel_quantization = False + + pipeline = EthosU55PipelineINT[input_t1]( + Tanh(), + (test_data(),), + aten_op, + exir_ops=[], + per_channel_quantization=per_channel_quantization, + use_to_edge_transform_and_lower=True, + run_on_fvp=True, + ) + + pipeline.change_args( + "quantize", + get_symmetric_a16w8_tanh_quantizer( + per_channel_quantization=per_channel_quantization + ), + ) + pipeline.run() + + +@common.parametrize("test_data", test_data_suite) +@common.XfailIfNoCorstone320 +@pytest.mark.xfail( + reason="Vela compilation fails with 'Invalid arguments' for int16 tanh operations" +) +def test_tanh_16a8w_u85_INT16(test_data: torch.Tensor): + """Test tanh operation with 16A8W quantization on U85 (16-bit activations, 8-bit weights)""" + per_channel_quantization = False + + pipeline = EthosU85PipelineINT[input_t1]( + Tanh(), + (test_data(),), + aten_op, + exir_ops=[], + per_channel_quantization=per_channel_quantization, + use_to_edge_transform_and_lower=True, + run_on_fvp=True, + ) + + pipeline.change_args( + "quantize", + get_symmetric_a16w8_tanh_quantizer( + per_channel_quantization=per_channel_quantization + ), + ) + pipeline.run()