| 
10 | 10 | from typing import Tuple  | 
11 | 11 | 
 
  | 
12 | 12 | import torch  | 
 | 13 | +from executorch.backends.arm.quantizer.arm_quantizer import (  | 
 | 14 | +    get_symmetric_a16w8_quantization_config,  | 
 | 15 | +    TOSAQuantizer,  | 
 | 16 | +)  | 
13 | 17 | 
 
  | 
14 |  | -from executorch.backends.arm.test import common  | 
 | 18 | +from executorch.backends.arm.test import common, conftest  | 
15 | 19 | from executorch.backends.arm.test.tester.test_pipeline import (  | 
16 | 20 |     EthosU55PipelineINT,  | 
17 | 21 |     EthosU85PipelineINT,  | 
18 | 22 |     TosaPipelineFP,  | 
19 | 23 |     TosaPipelineINT,  | 
20 | 24 |     VgfPipeline,  | 
21 | 25 | )  | 
 | 26 | +from executorch.backends.arm.tosa import TosaSpecification  | 
 | 27 | +from executorch.backends.xnnpack.test.tester import Quantize  | 
22 | 28 | 
 
  | 
23 | 29 | aten_op = "torch.ops.aten.sub.Tensor"  | 
24 | 30 | exir_op = "executorch_exir_dialects_edge__ops_aten_sub_Tensor"  | 
@@ -242,3 +248,96 @@ def test_sub_tensor_vgf_INT_2(test_data: Tuple[torch.Tensor, torch.Tensor]):  | 
242 | 248 |         tosa_version="TOSA-1.0+INT",  | 
243 | 249 |     )  | 
244 | 250 |     pipeline.run()  | 
 | 251 | + | 
 | 252 | + | 
 | 253 | +def get_symmetric_a16w8_sub_quantizer(per_channel_quantization=False):  | 
 | 254 | +    tosa_version = conftest.get_option("tosa_version")  | 
 | 255 | +    tosa_profiles = {  | 
 | 256 | +        "1.0": TosaSpecification.create_from_string("TOSA-1.0+INT+int16"),  | 
 | 257 | +    }  | 
 | 258 | + | 
 | 259 | +    quantizer = TOSAQuantizer(tosa_profiles[tosa_version])  | 
 | 260 | +    quantizer.set_global(  | 
 | 261 | +        get_symmetric_a16w8_quantization_config(is_per_channel=per_channel_quantization)  | 
 | 262 | +    )  | 
 | 263 | + | 
 | 264 | +    return Quantize(  | 
 | 265 | +        quantizer,  | 
 | 266 | +        get_symmetric_a16w8_quantization_config(  | 
 | 267 | +            is_per_channel=per_channel_quantization  | 
 | 268 | +        ),  | 
 | 269 | +    )  | 
 | 270 | + | 
 | 271 | + | 
 | 272 | +@common.parametrize("test_data", sub_test_data)  | 
 | 273 | +def test_sub_tensor_16a8w_tosa_INT(test_data: input_t1):  | 
 | 274 | +    """Test sub operation with 16A8W quantization (16-bit activations, 8-bit weights)"""  | 
 | 275 | +    per_channel_quantization = False  | 
 | 276 | + | 
 | 277 | +    pipeline = TosaPipelineINT[input_t1](  | 
 | 278 | +        Sub(),  | 
 | 279 | +        test_data(),  | 
 | 280 | +        aten_op,  | 
 | 281 | +        exir_op=[],  | 
 | 282 | +        per_channel_quantization=per_channel_quantization,  | 
 | 283 | +        use_to_edge_transform_and_lower=True,  | 
 | 284 | +        tosa_extensions=["int16"],  | 
 | 285 | +    )  | 
 | 286 | + | 
 | 287 | +    pipeline.change_args(  | 
 | 288 | +        "quantize",  | 
 | 289 | +        get_symmetric_a16w8_sub_quantizer(  | 
 | 290 | +            per_channel_quantization=per_channel_quantization  | 
 | 291 | +        ),  | 
 | 292 | +    )  | 
 | 293 | +    pipeline.run()  | 
 | 294 | + | 
 | 295 | + | 
 | 296 | +@common.parametrize("test_data", sub_test_data)  | 
 | 297 | +@common.XfailIfNoCorstone300  | 
 | 298 | +def test_sub_tensor_16a8w_u55_INT16(test_data: input_t1):  | 
 | 299 | +    """Test sub operation with 16A8W quantization on U55 (16-bit activations, 8-bit weights)"""  | 
 | 300 | +    per_channel_quantization = False  | 
 | 301 | + | 
 | 302 | +    pipeline = EthosU55PipelineINT[input_t1](  | 
 | 303 | +        Sub(),  | 
 | 304 | +        test_data(),  | 
 | 305 | +        aten_op,  | 
 | 306 | +        exir_op,  | 
 | 307 | +        per_channel_quantization=per_channel_quantization,  | 
 | 308 | +        use_to_edge_transform_and_lower=True,  | 
 | 309 | +        run_on_fvp=True,  | 
 | 310 | +    )  | 
 | 311 | + | 
 | 312 | +    pipeline.change_args(  | 
 | 313 | +        "quantize",  | 
 | 314 | +        get_symmetric_a16w8_sub_quantizer(  | 
 | 315 | +            per_channel_quantization=per_channel_quantization  | 
 | 316 | +        ),  | 
 | 317 | +    )  | 
 | 318 | +    pipeline.run()  | 
 | 319 | + | 
 | 320 | + | 
 | 321 | +@common.parametrize("test_data", sub_test_data)  | 
 | 322 | +@common.XfailIfNoCorstone320  | 
 | 323 | +def test_sub_tensor_16a8w_u85_INT16(test_data: input_t1):  | 
 | 324 | +    """Test sub operation with 16A8W quantization on U85 (16-bit activations, 8-bit weights)"""  | 
 | 325 | +    per_channel_quantization = False  | 
 | 326 | + | 
 | 327 | +    pipeline = EthosU85PipelineINT[input_t1](  | 
 | 328 | +        Sub(),  | 
 | 329 | +        test_data(),  | 
 | 330 | +        aten_op,  | 
 | 331 | +        exir_op,  | 
 | 332 | +        per_channel_quantization=per_channel_quantization,  | 
 | 333 | +        use_to_edge_transform_and_lower=True,  | 
 | 334 | +        run_on_fvp=True,  | 
 | 335 | +    )  | 
 | 336 | + | 
 | 337 | +    pipeline.change_args(  | 
 | 338 | +        "quantize",  | 
 | 339 | +        get_symmetric_a16w8_sub_quantizer(  | 
 | 340 | +            per_channel_quantization=per_channel_quantization  | 
 | 341 | +        ),  | 
 | 342 | +    )  | 
 | 343 | +    pipeline.run()  | 
0 commit comments