From 1bcd7170293e834af0d4e6b3baae867f78ba7546 Mon Sep 17 00:00:00 2001 From: Stephen Jia Date: Mon, 6 Jul 2026 14:59:21 -0700 Subject: [PATCH] Update [ghstack-poisoned] --- backends/arm/runtime/VGFSetup.cpp | 6 ++++ backends/arm/scripts/vulkan_utils.sh | 12 +++---- .../models/Qwen3_VL/test_qwen3_vl_layers.py | 24 ++++++++++++++ .../arm/test/models/phi3/test_phi3_layers.py | 22 ++++++++----- .../arm/test/models/test_mobilenet_v2_arm.py | 20 ++++++++++++ backends/arm/test/models/test_resnet18.py | 17 ++++++++++ backends/arm/test/ops/test_abs.py | 5 ++- backends/arm/test/ops/test_add.py | 4 ++- backends/arm/test/ops/test_alias_copy.py | 5 ++- backends/arm/test/ops/test_amax.py | 8 +++-- backends/arm/test/ops/test_amin.py | 8 +++-- backends/arm/test/ops/test_avg_pool2d.py | 17 +++++++++- backends/arm/test/ops/test_cat.py | 5 ++- backends/arm/test/ops/test_ceil.py | 2 +- backends/arm/test/ops/test_clamp.py | 9 ++++-- backends/arm/test/ops/test_constant_pad_nd.py | 4 ++- backends/arm/test/ops/test_conv2d.py | 13 ++++++-- backends/arm/test/ops/test_conv3d.py | 11 ++++++- backends/arm/test/ops/test_cos.py | 16 ++++++++-- backends/arm/test/ops/test_depthwise_conv.py | 15 ++++++++- backends/arm/test/ops/test_eq.py | 8 +++-- backends/arm/test/ops/test_erf.py | 16 ++++++++-- backends/arm/test/ops/test_exp.py | 6 ++-- backends/arm/test/ops/test_floor.py | 2 +- backends/arm/test/ops/test_gather.py | 2 +- backends/arm/test/ops/test_ge.py | 8 +++-- backends/arm/test/ops/test_gelu.py | 4 ++- backends/arm/test/ops/test_gt.py | 8 +++-- backends/arm/test/ops/test_index_put.py | 6 +++- backends/arm/test/ops/test_index_select.py | 2 +- backends/arm/test/ops/test_log.py | 16 ++++++++-- backends/arm/test/ops/test_matmul.py | 2 +- backends/arm/test/ops/test_max_pool.py | 4 ++- backends/arm/test/ops/test_maximum.py | 7 +++- backends/arm/test/ops/test_minimum.py | 7 +++- backends/arm/test/ops/test_mul.py | 1 + backends/arm/test/ops/test_permute.py | 4 ++- backends/arm/test/ops/test_pow.py | 11 +++++-- backends/arm/test/ops/test_reciprocal.py | 16 ++++++++-- backends/arm/test/ops/test_repeat.py | 4 ++- backends/arm/test/ops/test_round.py | 2 +- backends/arm/test/ops/test_rsqrt.py | 17 ++++++++-- backends/arm/test/ops/test_select_scatter.py | 2 +- backends/arm/test/ops/test_sigmoid.py | 16 ++++++++-- backends/arm/test/ops/test_sin.py | 16 ++++++++-- backends/arm/test/ops/test_slice.py | 4 ++- backends/arm/test/ops/test_slice_scatter.py | 6 +++- backends/arm/test/ops/test_sub.py | 8 +++-- backends/arm/test/ops/test_sum.py | 17 ++++++++-- backends/arm/test/ops/test_tanh.py | 16 ++++++++-- backends/arm/test/ops/test_to_copy.py | 13 +++++++- .../arm/test/ops/test_transpose_conv2d.py | 5 ++- backends/arm/test/ops/test_unfold_copy.py | 2 +- .../arm/test/ops/test_upsample_bilinear2d.py | 32 ++++++++++++++++--- .../arm/test/ops/test_upsample_nearest2d.py | 14 +++++--- backends/arm/test/ops/test_where.py | 2 +- backends/arm/test/runner_utils.py | 3 +- backends/arm/test/tester/test_pipeline.py | 14 ++++---- 58 files changed, 448 insertions(+), 98 deletions(-) diff --git a/backends/arm/runtime/VGFSetup.cpp b/backends/arm/runtime/VGFSetup.cpp index 88ed1758163..dd92af1d15b 100644 --- a/backends/arm/runtime/VGFSetup.cpp +++ b/backends/arm/runtime/VGFSetup.cpp @@ -66,6 +66,7 @@ enum class FormatScalarKind { Uint, Sint, Float, + BFloat, }; struct FormatInfo { @@ -157,6 +158,7 @@ static uint32_t get_format_component_count(VkFormat format) { case VK_FORMAT_R16_UINT: case VK_FORMAT_R16_SINT: case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16_SFLOAT_FPENCODING_BFLOAT16_ARM: case VK_FORMAT_R32_UINT: case VK_FORMAT_R32_SINT: case VK_FORMAT_R32_SFLOAT: @@ -209,6 +211,9 @@ static bool get_format_info(VkFormat format, FormatInfo* info) { case VK_FORMAT_R16_SFLOAT: *info = FormatInfo{1, 2, FormatScalarKind::Float}; return true; + case VK_FORMAT_R16_SFLOAT_FPENCODING_BFLOAT16_ARM: + *info = FormatInfo{1, 2, FormatScalarKind::BFloat}; + return true; case VK_FORMAT_R32_UINT: *info = FormatInfo{1, 4, FormatScalarKind::Uint}; return true; @@ -3696,6 +3701,7 @@ static uint32_t get_format_size(VkFormat format) { case VK_FORMAT_R16_UINT: case VK_FORMAT_R16_SINT: case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16_SFLOAT_FPENCODING_BFLOAT16_ARM: case VK_FORMAT_R8G8_UINT: case VK_FORMAT_R8G8_SINT: return 2; diff --git a/backends/arm/scripts/vulkan_utils.sh b/backends/arm/scripts/vulkan_utils.sh index f81a0cd0468..e99693f2b17 100644 --- a/backends/arm/scripts/vulkan_utils.sh +++ b/backends/arm/scripts/vulkan_utils.sh @@ -26,21 +26,21 @@ vulkan_sdk_arch="${ARCH}" # macOS and Linux x86_64 use the official LunarG SDK tarballs. Linux ARM64 # uses a separately repackaged mirror of the same SDK version. if [[ "${os_name}" == "Darwin" ]]; then - vulkan_sdk_version="1.4.341.1" + vulkan_sdk_version="1.4.350.0" vulkan_sdk_arch="macOS" vulkan_sdk_url="https://sdk.lunarg.com/sdk/download/${vulkan_sdk_version}/mac/vulkansdk-macos-${vulkan_sdk_version}.zip" - vulkan_sdk_sha256="632cbe96c8ed6ed00c6ce25e3a7738c466134f76586e1c51f1419410d7f9042e" + vulkan_sdk_sha256="7acc181b8fd9b4781bf51ed086222ec95d22004b85b3d0a6683a7e48ca5a1679" elif [[ "${os_name}" == "Linux" ]] && [[ "${ARCH}" == "x86_64" ]]; then - vulkan_sdk_version="1.4.341.1" + vulkan_sdk_version="1.4.350.0" vulkan_sdk_url="https://sdk.lunarg.com/sdk/download/${vulkan_sdk_version}/linux/vulkansdk-linux-x86_64-${vulkan_sdk_version}.tar.xz" - vulkan_sdk_sha256="3bf0f762afb6c79bc6a9d9fb5998745ccff928800a29619b501ed9de7fd9789b" + vulkan_sdk_sha256="b65f068ab36263559da49d7cacd7e7b9df23824ca8b68ccc522a2b06f5725df2" elif [[ "${os_name}" == "Linux" ]] && ([[ "${ARCH}" == "aarch64" ]] || [[ "${ARCH}" == "arm64" ]]); then - vulkan_sdk_version="1.4.341.1" + vulkan_sdk_version="1.4.350.0" if [[ "${vulkan_sdk_arch}" == "arm64" ]]; then vulkan_sdk_arch="aarch64" fi vulkan_sdk_url="https://github.com/jakoch/vulkan-sdk-arm/releases/download/${vulkan_sdk_version}/vulkansdk-ubuntu-22.04-arm-${vulkan_sdk_version}.tar.xz" - vulkan_sdk_sha256="345312aee2c835e128b30653278593f899a659a7ba287c571cafb22acb708b8f" + vulkan_sdk_sha256="9e403d444219bb7c17e9231b580d704453e2afa30a1c2fdd568d1776dc68790b" else log_step "vulkan" "Error: only macOS and Linux are supported (detected ${os_name}); architecture must be x86-64 or aarch64/arm64" exit 1 diff --git a/backends/arm/test/models/Qwen3_VL/test_qwen3_vl_layers.py b/backends/arm/test/models/Qwen3_VL/test_qwen3_vl_layers.py index 6573371bb78..0be23f4dbc2 100644 --- a/backends/arm/test/models/Qwen3_VL/test_qwen3_vl_layers.py +++ b/backends/arm/test/models/Qwen3_VL/test_qwen3_vl_layers.py @@ -474,6 +474,8 @@ class Qwen3VLTestCase: "qk_norm": TOSA_FP_TEST_CASES["qk_norm"], } +VGF_NO_QUANT_BF16_TEST_CASES: dict[str, Qwen3VLTestCase] = TOSA_BF16_TEST_CASES + TOSA_MXFP8_TEST_CASES: dict[str, Qwen3VLTestCase] = { "text_attention": Qwen3VLTestCase( @@ -602,3 +604,25 @@ def test_qwen3_vl_vgf_no_quant(test_case: Qwen3VLTestCase): transform_passes=list(test_case.transform_passes), ) pipeline.run() + + +@common.SkipIfNoModelConverter +@common.parametrize( + "test_case", + VGF_NO_QUANT_BF16_TEST_CASES, +) +def test_qwen3_vl_vgf_no_quant_bf16(test_case: Qwen3VLTestCase): + model, inputs = test_case.model_cls.prepare_model_and_inputs() + model, inputs = _to_bfloat16(model, inputs) + with torch.no_grad(): + pipeline = VgfPipeline[input_t]( + model, + inputs, + aten_op=[], + exir_op=[], + quantize=False, + transform_passes=list(test_case.transform_passes), + atol=5e-2, + rtol=5e-2, + ) + pipeline.run() diff --git a/backends/arm/test/models/phi3/test_phi3_layers.py b/backends/arm/test/models/phi3/test_phi3_layers.py index c598ff2f664..34e3a25a304 100644 --- a/backends/arm/test/models/phi3/test_phi3_layers.py +++ b/backends/arm/test/models/phi3/test_phi3_layers.py @@ -180,14 +180,16 @@ def _dtype_cases() -> list: ] -def _vgf_dtype_cases() -> list: +def _vgf_no_quant_dtype_cases() -> list: + return [ + pytest.param(torch.float32, id="fp32"), + pytest.param(torch.bfloat16, id="bf16"), + ] + + +def _vgf_quant_dtype_cases() -> list: return [ pytest.param(torch.float32, id="fp32"), - pytest.param( - torch.bfloat16, - marks=pytest.mark.xfail(reason="BF16 runtime support not ready for VGF."), - id="bf16", - ), ] @@ -233,12 +235,14 @@ def test_phi3_tosa_INT_layers(name, module_factory, input_factory): @common.SkipIfNoModelConverter -@pytest.mark.parametrize("dtype", _vgf_dtype_cases()) +@pytest.mark.parametrize("dtype", _vgf_no_quant_dtype_cases()) @pytest.mark.parametrize("name,module_factory,input_factory", _module_cases()) def test_phi3_vgf_no_quant_layers(name, module_factory, input_factory, dtype): config = _phi3_config() module = module_factory(config).to(dtype) inputs = input_factory(config, dtype) + atol = 1e-02 if dtype == torch.bfloat16 else 1e-03 + rtol = 1e-02 if dtype == torch.bfloat16 else 1e-03 pipeline = VgfPipeline[input_t1 if len(inputs) == 1 else input_t2]( module, @@ -250,12 +254,14 @@ def test_phi3_vgf_no_quant_layers(name, module_factory, input_factory, dtype): InsertInt32CastsAfterInt64PlaceholdersPass(), ], quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() @common.SkipIfNoModelConverter -@pytest.mark.parametrize("dtype", _vgf_dtype_cases()) +@pytest.mark.parametrize("dtype", _vgf_quant_dtype_cases()) @pytest.mark.parametrize("name,module_factory,input_factory", _module_cases()) def test_phi3_vgf_quant_layers(name, module_factory, input_factory, dtype): config = _phi3_config() diff --git a/backends/arm/test/models/test_mobilenet_v2_arm.py b/backends/arm/test/models/test_mobilenet_v2_arm.py index fb624f3eb3f..0616d34c90b 100644 --- a/backends/arm/test/models/test_mobilenet_v2_arm.py +++ b/backends/arm/test/models/test_mobilenet_v2_arm.py @@ -191,6 +191,26 @@ def test_mv2_vgf_no_quant(): pipeline.run() +@common.SkipIfNoModelConverter +def test_mv2_vgf_no_quant_bf16(): + bf16_model = models.mobilenetv2.mobilenet_v2( + weights=MobileNet_V2_Weights.DEFAULT + ).eval() + bf16_model = bf16_model.to(torch.bfloat16) + bf16_input = normalize(torch.rand((1, 3, 224, 224))).to(torch.bfloat16) + pipeline = VgfPipeline[input_t]( + bf16_model, + (bf16_input,), + aten_op=[], + exir_op=[], + use_to_edge_transform_and_lower=True, + quantize=False, + atol=2.5e-01, + rtol=2.5e-01, + ) + pipeline.run() + + def test_mv2_tosa_INT_FP_partial_quant(): pipeline = TosaPipelineINT[input_t]( mv2, diff --git a/backends/arm/test/models/test_resnet18.py b/backends/arm/test/models/test_resnet18.py index db1e021461a..0430873246f 100644 --- a/backends/arm/test/models/test_resnet18.py +++ b/backends/arm/test/models/test_resnet18.py @@ -14,6 +14,7 @@ EthosU85PipelineINT, TosaPipelineFP, TosaPipelineINT, + VgfPipeline, ) from torchvision import transforms # type: ignore[import-untyped] @@ -65,6 +66,22 @@ def test_resnet_18_tosa_FP_bf16(): pipeline.run() +@common.SkipIfNoModelConverter +def test_resnet_18_vgf_no_quant_bf16(): + bf16_model = resnet18(weights=ResNet18_Weights).eval() + bf16_model = bf16_model.to(torch.bfloat16) + bf16_input = normalize(torch.rand((1, 3, 224, 224)) * 2 - 1).to(torch.bfloat16) + pipeline = VgfPipeline[input_t]( + bf16_model, + (bf16_input,), + aten_op=[], + quantize=False, + atol=6e-01, + rtol=6e-01, + ) + pipeline.run() + + @common.parametrize("per_channel_quantization", quant_test_data) def test_resnet_18_tosa_INT(per_channel_quantization): pipeline = TosaPipelineINT[input_t]( diff --git a/backends/arm/test/ops/test_abs.py b/backends/arm/test/ops/test_abs.py index 956b0b12697..c9297b27b55 100644 --- a/backends/arm/test/ops/test_abs.py +++ b/backends/arm/test/ops/test_abs.py @@ -88,7 +88,10 @@ def test_abs_u85_INT(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", Abs.test_parameters | Abs.test_parameters_fp16) +@common.parametrize( + "test_data", + Abs.test_parameters | Abs.test_parameters_bf16 | Abs.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_abs_vgf_no_quant(test_data: input_t1): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_add.py b/backends/arm/test/ops/test_add.py index 632de5e999a..3e4a5510005 100644 --- a/backends/arm/test/ops/test_add.py +++ b/backends/arm/test/ops/test_add.py @@ -263,7 +263,9 @@ def test_add_tensor_u85_INT_2(test_data: input_t2): pipeline.run() -@common.parametrize("test_data", Add.test_data | Add.test_data_fp16) +@common.parametrize( + "test_data", Add.test_data | Add.test_data_fp16 | Add.test_data_bf16 +) @common.SkipIfNoModelConverter def test_add_tensor_vgf_no_quant(test_data: input_t1): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_alias_copy.py b/backends/arm/test/ops/test_alias_copy.py index d57fffd15d6..a345b4d3b9e 100644 --- a/backends/arm/test/ops/test_alias_copy.py +++ b/backends/arm/test/ops/test_alias_copy.py @@ -98,7 +98,10 @@ def test_alias_u85_INT(test_data: input_t1): ).run() -@common.parametrize("test_data", AliasCopy.test_data | AliasCopy.test_data_fp16) +@common.parametrize( + "test_data", + AliasCopy.test_data | AliasCopy.test_data_bf16 | AliasCopy.test_data_fp16, +) @common.SkipIfNoModelConverter def test_alias_vgf_no_quant(test_data: input_t1): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_amax.py b/backends/arm/test/ops/test_amax.py index c1d8e047ac7..28f1627eed5 100644 --- a/backends/arm/test/ops/test_amax.py +++ b/backends/arm/test/ops/test_amax.py @@ -212,7 +212,9 @@ def test_max_dim_tosa_FP_not_delegated(): pipeline.run() -@common.parametrize("test_data", Amax.test_data | Amax.test_data_fp16) +@common.parametrize( + "test_data", Amax.test_data | Amax.test_data_fp16 | Amax.test_data_bf16 +) @common.SkipIfNoModelConverter def test_amax_vgf_no_quant(test_data: Amax.input_t): data, dim, keep_dims = test_data() @@ -240,7 +242,9 @@ def test_amax_vgf_quant(test_data: Amax.input_t): pipeline.run() -@common.parametrize("test_data", Max.test_data | Max.test_data_fp16) +@common.parametrize( + "test_data", Max.test_data | Max.test_data_fp16 | Max.test_data_bf16 +) @common.SkipIfNoModelConverter def test_max_dim_vgf_no_quant_to_amax(test_data: Max.input_t): data, dim = test_data() diff --git a/backends/arm/test/ops/test_amin.py b/backends/arm/test/ops/test_amin.py index 9068feceaf6..14ea58e0d2c 100644 --- a/backends/arm/test/ops/test_amin.py +++ b/backends/arm/test/ops/test_amin.py @@ -224,7 +224,9 @@ def test_min_dim_tosa_FP_not_delegated(): pipeline.run() -@common.parametrize("test_data", Amin.test_data | Amin.test_data_fp16) +@common.parametrize( + "test_data", Amin.test_data | Amin.test_data_fp16 | Amin.test_data_bf16 +) @common.SkipIfNoModelConverter def test_amin_vgf_no_quant(test_data: Amin.input_t): data, dim, keep_dims = test_data() @@ -250,7 +252,9 @@ def test_amin_vgf_quant(test_data: Amin.input_t): pipeline.run() -@common.parametrize("test_data", Min.test_data | Min.test_data_fp16) +@common.parametrize( + "test_data", Min.test_data | Min.test_data_fp16 | Min.test_data_bf16 +) @common.SkipIfNoModelConverter def test_min_dim_vgf_no_quant_to_amin(test_data: Min.input_t): data, dim = test_data() diff --git a/backends/arm/test/ops/test_avg_pool2d.py b/backends/arm/test/ops/test_avg_pool2d.py index 36b3d3983fc..0eb59f8d2b9 100644 --- a/backends/arm/test/ops/test_avg_pool2d.py +++ b/backends/arm/test/ops/test_avg_pool2d.py @@ -286,16 +286,31 @@ def test_avg_pool2d_16a8w_u85_INT(test_module): pipeline.run() -@common.parametrize("test_module", test_modules | test_modules_fp16) +@common.parametrize( + "test_module", + test_modules | test_modules_bf16 | test_modules_fp16, + xfails={ + "kernel_3x3_stride_1_pad_1_bf16": "'Unsupported BF16 PAD constant encoding' in emulation layer. MLCE-1887." + }, +) @common.SkipIfNoModelConverter def test_avg_pool2d_vgf_no_quant(test_module): model, input_tensor = test_module() + match input_tensor[0].dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t]( model, input_tensor, aten_op, exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_cat.py b/backends/arm/test/ops/test_cat.py index 29738ddbe32..1286435ec89 100644 --- a/backends/arm/test/ops/test_cat.py +++ b/backends/arm/test/ops/test_cat.py @@ -201,7 +201,10 @@ def test_cat_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", Cat.test_parameters | Cat.test_parameters_fp16) +@common.parametrize( + "test_data", + Cat.test_parameters | Cat.test_parameters_bf16 | Cat.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_cat_vgf_no_quant(test_data: Tuple): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_ceil.py b/backends/arm/test/ops/test_ceil.py index 7332d0f40ce..d5c8e3a3f09 100644 --- a/backends/arm/test/ops/test_ceil.py +++ b/backends/arm/test/ops/test_ceil.py @@ -122,7 +122,7 @@ def test_ceil_u85_INT(test_data: input_t1): pipeline.run() -@common.parametrize("test_data", test_data | test_data_fp16) +@common.parametrize("test_data", test_data | test_data_bf16 | test_data_fp16) @common.SkipIfNoModelConverter def test_ceil_vgf_no_quant(test_data: input_t1): module, data = test_data() diff --git a/backends/arm/test/ops/test_clamp.py b/backends/arm/test/ops/test_clamp.py index 0d7033df52e..61ee5361678 100644 --- a/backends/arm/test/ops/test_clamp.py +++ b/backends/arm/test/ops/test_clamp.py @@ -230,7 +230,9 @@ def test_clamp_u85_INT_16a8w(test_data): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_clamp_vgf_no_quant(test_data): input_tensor, min_val, max_val = test_data() @@ -546,7 +548,10 @@ def test_clamp_u85_INT_16a8w_tensor(test_data): @common.parametrize( - "test_data", test_data_suite_tensor_FP | test_data_suite_tensor_fp16 + "test_data", + test_data_suite_tensor_FP + | test_data_suite_tensor_bf16 + | test_data_suite_tensor_fp16, ) @common.SkipIfNoModelConverter def test_clamp_vgf_no_quant_tensor(test_data): diff --git a/backends/arm/test/ops/test_constant_pad_nd.py b/backends/arm/test/ops/test_constant_pad_nd.py index 96d829851ed..d465c21e6b8 100644 --- a/backends/arm/test/ops/test_constant_pad_nd.py +++ b/backends/arm/test/ops/test_constant_pad_nd.py @@ -344,7 +344,9 @@ def test_constant_pad_nd_tosa_INT_a16w8(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_constant_pad_nd_vgf_no_quant(test_data: Tuple): inp, padding, value, mode = test_data() diff --git a/backends/arm/test/ops/test_conv2d.py b/backends/arm/test/ops/test_conv2d.py index db8a7c6b323..91898b8c32c 100644 --- a/backends/arm/test/ops/test_conv2d.py +++ b/backends/arm/test/ops/test_conv2d.py @@ -718,18 +718,25 @@ def test_convolution_2d_u85_INT_a8w4(test_data): pipeline.run() -@common.parametrize("test_data", test_data_FP | test_data_FP_fp16) +@common.parametrize("test_data", test_data_FP | test_data_FP_bf16 | test_data_FP_fp16) @common.SkipIfNoModelConverter def test_convolution_2d_vgf_no_quant(test_data): model = test_data() + match model.dtype: + case torch.bfloat16: + atol = 2e-2 + rtol = 2e-2 + case _: + atol = 3e-3 + rtol = 3e-3 pipeline = VgfPipeline[input_t]( model, model.get_inputs(), aten_op, exir_op, quantize=False, - atol=3e-3, - rtol=3e-3, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_conv3d.py b/backends/arm/test/ops/test_conv3d.py index a1418f77b53..09cd44525c5 100644 --- a/backends/arm/test/ops/test_conv3d.py +++ b/backends/arm/test/ops/test_conv3d.py @@ -772,16 +772,25 @@ def test_convolution_3d_u85_INT_a8w4(test_data): pipeline.run() -@common.parametrize("test_data", test_data_FP | test_data_FP_fp16) +@common.parametrize("test_data", test_data_FP | test_data_FP_bf16 | test_data_FP_fp16) @common.SkipIfNoModelConverter def test_convolution_3d_vgf_no_quant(test_data): model = test_data() + match model.dtype: + case torch.bfloat16: + atol = 1e-2 + rtol = 1e-2 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t]( model, model.get_inputs(), aten_op, exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_cos.py b/backends/arm/test/ops/test_cos.py index e020c3de971..e3702d4caf3 100644 --- a/backends/arm/test/ops/test_cos.py +++ b/backends/arm/test/ops/test_cos.py @@ -98,15 +98,27 @@ def test_cos_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_cos_vgf_no_quant(test_data: Tuple): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Cos(), - (test_data(),), + (data,), aten_op, exir_op=[], quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_depthwise_conv.py b/backends/arm/test/ops/test_depthwise_conv.py index 95fe3b01826..a81a656017f 100644 --- a/backends/arm/test/ops/test_depthwise_conv.py +++ b/backends/arm/test/ops/test_depthwise_conv.py @@ -340,17 +340,30 @@ def test_convolution_2d_tosa_INT_a8w4_depthwise(test_data): @common.parametrize( - "test_data", test_data_conv1d_FP | test_data_conv2d_FP | test_data_conv2d_FP_fp16 + "test_data", + test_data_conv1d_FP + | test_data_conv2d_FP + | test_data_conv2d_FP_bf16 + | test_data_conv2d_FP_fp16, ) @common.SkipIfNoModelConverter def test_convolution_2d_vgf_no_quant_depthwise(test_data: torch.nn.Module): model = test_data() + match model.dtype: + case torch.bfloat16: + atol = 2e-2 + rtol = 2e-2 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t]( model, model.get_inputs(), aten_op=[], exir_op=exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_eq.py b/backends/arm/test/ops/test_eq.py index 3a28a8a061c..094f2ce7f45 100644 --- a/backends/arm/test/ops/test_eq.py +++ b/backends/arm/test/ops/test_eq.py @@ -285,7 +285,9 @@ def test_eq_scalar_u85_INT_16a8w(test_module): pipeline.run() -@common.parametrize("test_module", test_data_tensor | test_data_tensor_fp16) +@common.parametrize( + "test_module", test_data_tensor | test_data_tensor_bf16 | test_data_tensor_fp16 +) @common.SkipIfNoModelConverter def test_eq_scalar_vgf_no_quant_tensor(test_module): pipeline = VgfPipeline[input_t]( @@ -298,7 +300,9 @@ def test_eq_scalar_vgf_no_quant_tensor(test_module): pipeline.run() -@common.parametrize("test_module", test_data_scalar | test_data_scalar_fp16) +@common.parametrize( + "test_module", test_data_scalar | test_data_scalar_bf16 | test_data_scalar_fp16 +) @common.SkipIfNoModelConverter def test_eq_scalar_vgf_no_quant(test_module): pipeline = VgfPipeline[input_t]( diff --git a/backends/arm/test/ops/test_erf.py b/backends/arm/test/ops/test_erf.py index a5501fbe87d..1d3c5d5e79b 100644 --- a/backends/arm/test/ops/test_erf.py +++ b/backends/arm/test/ops/test_erf.py @@ -83,15 +83,27 @@ def test_erf_u85_INT(test_data: input_t1): pipeline.run() -@common.parametrize("test_data", Erf.test_data | Erf.test_data_fp16) +@common.parametrize( + "test_data", Erf.test_data | Erf.test_data_bf16 | Erf.test_data_fp16 +) @common.SkipIfNoModelConverter def test_erf_vgf_no_quant(test_data: input_t1): + data = test_data() + match data[0].dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Erf(), - test_data(), + data, aten_op, exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_exp.py b/backends/arm/test/ops/test_exp.py index 1661e5f5e79..300d5fc8a56 100644 --- a/backends/arm/test/ops/test_exp.py +++ b/backends/arm/test/ops/test_exp.py @@ -96,11 +96,13 @@ def test_exp_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_exp_vgf_no_quant(test_data: Tuple): data = test_data() - if data.dtype == torch.float16: + if data.dtype in (torch.float16, torch.bfloat16): atol = 2e-2 rtol = 2e-2 else: diff --git a/backends/arm/test/ops/test_floor.py b/backends/arm/test/ops/test_floor.py index 736f2e5d3ee..606a61a2ff5 100644 --- a/backends/arm/test/ops/test_floor.py +++ b/backends/arm/test/ops/test_floor.py @@ -118,7 +118,7 @@ def test_floor_u85_INT(test_data: input_t1): pipeline.run() -@common.parametrize("test_data", test_data | test_data_fp16) +@common.parametrize("test_data", test_data | test_data_bf16 | test_data_fp16) @common.SkipIfNoModelConverter def test_floor_vgf_no_quant(test_data: input_t1): module, data = test_data() diff --git a/backends/arm/test/ops/test_gather.py b/backends/arm/test/ops/test_gather.py index 22eada92c07..08112e39667 100644 --- a/backends/arm/test/ops/test_gather.py +++ b/backends/arm/test/ops/test_gather.py @@ -230,7 +230,7 @@ def test_gather_u85_INT(test_data: input_params): pipeline.run() -@common.parametrize("test_data", test_data_fp | test_data_int) +@common.parametrize("test_data", test_data_fp | test_data_fp_bf16 | test_data_int) @common.SkipIfNoModelConverter def test_gather_vgf_no_quant(test_data: input_params): pipeline = VgfPipeline[input_params]( diff --git a/backends/arm/test/ops/test_ge.py b/backends/arm/test/ops/test_ge.py index 454e8e4269c..130727a0a56 100644 --- a/backends/arm/test/ops/test_ge.py +++ b/backends/arm/test/ops/test_ge.py @@ -293,7 +293,9 @@ def test_ge_scalar_16a8w_u85_INT(test_module): pipeline.run() -@common.parametrize("test_module", test_data_tensor | test_data_tensor_fp16) +@common.parametrize( + "test_module", test_data_tensor | test_data_tensor_bf16 | test_data_tensor_fp16 +) @common.SkipIfNoModelConverter def test_ge_tensor_vgf_no_quant(test_module): pipeline = VgfPipeline[input_t]( @@ -319,7 +321,9 @@ def test_ge_tensor_vgf_quant(test_module): pipeline.run() -@common.parametrize("test_module", test_data_scalar | test_data_scalar_fp16) +@common.parametrize( + "test_module", test_data_scalar | test_data_scalar_bf16 | test_data_scalar_fp16 +) @common.SkipIfNoModelConverter def test_ge_scalar_vgf_no_quant(test_module): pipeline = VgfPipeline[input_t]( diff --git a/backends/arm/test/ops/test_gelu.py b/backends/arm/test/ops/test_gelu.py index 84626c70b4d..12a6cf49974 100644 --- a/backends/arm/test/ops/test_gelu.py +++ b/backends/arm/test/ops/test_gelu.py @@ -151,7 +151,7 @@ def test_gelu_u85_INT(test_data: input_t1): ).run() -@common.parametrize("test_data", Gelu.test_data) +@common.parametrize("test_data", Gelu.test_data | Gelu.test_data_bf16) @common.SkipIfNoModelConverter def test_gelu_vgf_no_quant(test_data: input_t1): approximate, data = test_data() @@ -162,6 +162,8 @@ def test_gelu_vgf_no_quant(test_data: input_t1): Gelu.exir_op, quantize=False, ) + if data.dtype == torch.bfloat16: + pipeline.change_args("run_method_and_compare_outputs", atol=1e-2, rtol=1e-2) pipeline.run() diff --git a/backends/arm/test/ops/test_gt.py b/backends/arm/test/ops/test_gt.py index bd07407d0af..963f9d427b8 100644 --- a/backends/arm/test/ops/test_gt.py +++ b/backends/arm/test/ops/test_gt.py @@ -298,7 +298,9 @@ def test_gt_scalar_16a8w_u85_INT(test_module): pipeline.run() -@common.parametrize("test_module", test_data_tensor | test_data_tensor_fp16) +@common.parametrize( + "test_module", test_data_tensor | test_data_tensor_bf16 | test_data_tensor_fp16 +) @common.SkipIfNoModelConverter def test_gt_tensor_vgf_no_quant(test_module): pipeline = VgfPipeline[input_t]( @@ -311,7 +313,9 @@ def test_gt_tensor_vgf_no_quant(test_module): pipeline.run() -@common.parametrize("test_module", test_data_scalar | test_data_scalar_fp16) +@common.parametrize( + "test_module", test_data_scalar | test_data_scalar_bf16 | test_data_scalar_fp16 +) @common.SkipIfNoModelConverter def test_gt_scalar_vgf_no_quant(test_module): pipeline = VgfPipeline[input_t]( diff --git a/backends/arm/test/ops/test_index_put.py b/backends/arm/test/ops/test_index_put.py index 5d6bc10e2af..93b2262d6fc 100644 --- a/backends/arm/test/ops/test_index_put.py +++ b/backends/arm/test/ops/test_index_put.py @@ -463,7 +463,11 @@ def test_index_put_u85_INT(test_module: input_t): @common.SkipIfNoModelConverter -@common.parametrize("test_module", test_data_suite_fp | test_data_int, xfails=xfails) +@common.parametrize( + "test_module", + test_data_suite_fp | test_data_suite_bf16 | test_data_int, + xfails=xfails, +) def test_index_put_vgf_no_quant(test_module: input_t): pipeline = VgfPipeline[input_t]( IndexPut(), diff --git a/backends/arm/test/ops/test_index_select.py b/backends/arm/test/ops/test_index_select.py index 110b3429d75..5410bc09a4e 100644 --- a/backends/arm/test/ops/test_index_select.py +++ b/backends/arm/test/ops/test_index_select.py @@ -205,7 +205,7 @@ def test_index_select_u85_INT(test_data: input_params): pipeline.run() -@common.parametrize("test_data", test_data_fp | test_data_int) +@common.parametrize("test_data", test_data_fp | test_data_fp_bf16 | test_data_int) @common.SkipIfNoModelConverter def test_index_select_vgf_no_quant(test_data: input_params): pipeline = VgfPipeline[input_params]( diff --git a/backends/arm/test/ops/test_log.py b/backends/arm/test/ops/test_log.py index e5fb4bacdc5..1a37610b082 100644 --- a/backends/arm/test/ops/test_log.py +++ b/backends/arm/test/ops/test_log.py @@ -88,15 +88,27 @@ def test_log_u85_INT(test_data: input_t1): ).run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_log_vgf_no_quant(test_data: input_t1): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 2e-2 + rtol = 2e-2 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Log(), - (test_data(),), + (data,), aten_op, exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_matmul.py b/backends/arm/test/ops/test_matmul.py index 9fc93bfd9b2..4b9ab93ad56 100644 --- a/backends/arm/test/ops/test_matmul.py +++ b/backends/arm/test/ops/test_matmul.py @@ -455,7 +455,7 @@ def test_matmul_u85_INT(test_case: test_case_t): pipeline.run() -@common.parametrize("test_case", test_suite | test_suite_fp16) +@common.parametrize("test_case", test_suite | test_suite_fp16 | test_suite_bf16) @common.SkipIfNoModelConverter def test_matmul_vgf_no_quant(test_case: test_case_t): test_data = test_case() diff --git a/backends/arm/test/ops/test_max_pool.py b/backends/arm/test/ops/test_max_pool.py index eed12eac06e..22dfe09b070 100644 --- a/backends/arm/test/ops/test_max_pool.py +++ b/backends/arm/test/ops/test_max_pool.py @@ -373,7 +373,9 @@ def test_max_pool2d_tosa_INT_dilation(test_data): # VGF tests -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_max_pool2d_vgf_no_quant(test_data: torch.Tensor): test_data, model_params = test_data() diff --git a/backends/arm/test/ops/test_maximum.py b/backends/arm/test/ops/test_maximum.py index 0ee3ead794f..c9ef999f86b 100644 --- a/backends/arm/test/ops/test_maximum.py +++ b/backends/arm/test/ops/test_maximum.py @@ -100,7 +100,12 @@ def test_maximum_u85_INT(test_data: Tuple): ).run() -@common.parametrize("test_data", Maximum.test_parameters | Maximum.test_parameters_fp16) +@common.parametrize( + "test_data", + Maximum.test_parameters + | Maximum.test_parameters_bf16 + | Maximum.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_maximum_vgf_no_quant(test_data: Tuple): pipeline = VgfPipeline[test_t]( diff --git a/backends/arm/test/ops/test_minimum.py b/backends/arm/test/ops/test_minimum.py index 4cf8744975b..b3df52e227f 100644 --- a/backends/arm/test/ops/test_minimum.py +++ b/backends/arm/test/ops/test_minimum.py @@ -100,7 +100,12 @@ def test_minimum_u85_INT(test_data: Tuple): ).run() -@common.parametrize("test_data", Minimum.test_parameters | Minimum.test_parameters_fp16) +@common.parametrize( + "test_data", + Minimum.test_parameters + | Minimum.test_parameters_bf16 + | Minimum.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_minimum_vgf_no_quant(test_data: test_t): pipeline = VgfPipeline[test_t]( diff --git a/backends/arm/test/ops/test_mul.py b/backends/arm/test/ops/test_mul.py index a9fce9f2e91..adfcb1f6d58 100644 --- a/backends/arm/test/ops/test_mul.py +++ b/backends/arm/test/ops/test_mul.py @@ -263,6 +263,7 @@ def test_mul_tensor_u85_INT_int32(test_data: torch.Tensor): @common.parametrize( "test_data", test_data_suite + | test_data_suite_bf16 | test_data_suite_fp16 | test_data_suite_2 | test_data_int32_without_broadcasting, diff --git a/backends/arm/test/ops/test_permute.py b/backends/arm/test/ops/test_permute.py index 6819929104e..29e134e464b 100644 --- a/backends/arm/test/ops/test_permute.py +++ b/backends/arm/test/ops/test_permute.py @@ -161,7 +161,9 @@ def test_permute_u85_INT(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_permute_vgf_no_quant(test_data): test_data, dims = test_data() diff --git a/backends/arm/test/ops/test_pow.py b/backends/arm/test/ops/test_pow.py index 28f95f2c622..2cde848c7ef 100644 --- a/backends/arm/test/ops/test_pow.py +++ b/backends/arm/test/ops/test_pow.py @@ -128,7 +128,12 @@ def test_pow_tensor_tensor_tosa_FP(test_data: Pow_TensorTensor.input_t): pipeline.run() -@common.parametrize("test_data", Pow_TensorTensor.test_data, x_fail, strict=False) +@common.parametrize( + "test_data", + Pow_TensorTensor.test_data | Pow_TensorTensor.test_data_bf16, + x_fail, + strict=False, +) @common.SkipIfNoModelConverter def test_pow_tensor_tensor_vgf_no_quant(test_data: Pow_TensorTensor.input_t): pipeline = VgfPipeline[Pow_TensorTensor.input_t]( @@ -199,7 +204,9 @@ def test_pow_tensor_scalar_u85_INT(test_data: Pow_TensorScalar.input_t): @common.parametrize( "test_data", - Pow_TensorScalar.test_data | Pow_TensorScalar.test_data_fp16, + Pow_TensorScalar.test_data + | Pow_TensorScalar.test_data_bf16 + | Pow_TensorScalar.test_data_fp16, ) @common.SkipIfNoModelConverter def test_pow_tensor_scalar_vgf_no_quant(test_data: Pow_TensorScalar.input_t): diff --git a/backends/arm/test/ops/test_reciprocal.py b/backends/arm/test/ops/test_reciprocal.py index b49d5913034..1344f86ac1e 100644 --- a/backends/arm/test/ops/test_reciprocal.py +++ b/backends/arm/test/ops/test_reciprocal.py @@ -101,14 +101,26 @@ def test_reciprocal_u85_INT(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_reciprocal_vgf_no_quant(test_data: torch.Tensor): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 5e-2 + rtol = 5e-2 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Reciprocal(), - (test_data(),), + (data,), aten_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_repeat.py b/backends/arm/test/ops/test_repeat.py index 3368864564d..cedf9f739d4 100644 --- a/backends/arm/test/ops/test_repeat.py +++ b/backends/arm/test/ops/test_repeat.py @@ -179,7 +179,9 @@ def test_repeat_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_repeat_vgf_no_quant(test_data: Tuple): module, args = test_data() diff --git a/backends/arm/test/ops/test_round.py b/backends/arm/test/ops/test_round.py index bcc71b70725..1f4470cebb3 100644 --- a/backends/arm/test/ops/test_round.py +++ b/backends/arm/test/ops/test_round.py @@ -88,7 +88,7 @@ def test_round_u85_INT(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite) +@common.parametrize("test_data", test_data_suite | test_data_suite_bf16) @common.SkipIfNoModelConverter def test_round_vgf_no_quant(test_data: torch.Tensor): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_rsqrt.py b/backends/arm/test/ops/test_rsqrt.py index 3d7a51a99a0..4fd8442ba4a 100644 --- a/backends/arm/test/ops/test_rsqrt.py +++ b/backends/arm/test/ops/test_rsqrt.py @@ -107,14 +107,27 @@ def test_rsqrt_u85_INT(test_tensor: torch.Tensor): pipeline.run() -@common.parametrize("test_tensor", Rsqrt.test_parameters | Rsqrt.test_parameters_fp16) +@common.parametrize( + "test_tensor", + Rsqrt.test_parameters | Rsqrt.test_parameters_bf16 | Rsqrt.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_rsqrt_vgf_no_quant(test_tensor: torch.Tensor): + data = test_tensor() + match data[0].dtype: + case torch.bfloat16: + atol = 5e-2 + rtol = 5e-2 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Rsqrt(), - test_tensor(), + data, aten_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_select_scatter.py b/backends/arm/test/ops/test_select_scatter.py index 04c9c5d8422..6f3c08bce80 100644 --- a/backends/arm/test/ops/test_select_scatter.py +++ b/backends/arm/test/ops/test_select_scatter.py @@ -163,7 +163,7 @@ def test_select_scatter_u85_INT(test_module: input_t): @common.SkipIfNoModelConverter -@common.parametrize("test_module", test_data_suite) +@common.parametrize("test_module", test_data_suite | test_data_suite_bf16) def test_select_scatter_vgf_no_quant(test_module: input_t): pipeline = VgfPipeline[input_t]( SelectScatter(), diff --git a/backends/arm/test/ops/test_sigmoid.py b/backends/arm/test/ops/test_sigmoid.py index 33d8659472a..5f88728ce7d 100644 --- a/backends/arm/test/ops/test_sigmoid.py +++ b/backends/arm/test/ops/test_sigmoid.py @@ -176,15 +176,27 @@ def test_sigmoid_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_sigmoid_vgf_no_quant(test_data: Tuple): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Sigmoid(), - (test_data(),), + (data,), aten_op, exir_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_sin.py b/backends/arm/test/ops/test_sin.py index f9b3c2585e6..38afee6a31b 100644 --- a/backends/arm/test/ops/test_sin.py +++ b/backends/arm/test/ops/test_sin.py @@ -94,14 +94,26 @@ def test_sin_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_sin_vgf_no_quant(test_data: Tuple): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Sin(), - (test_data(),), + (data,), aten_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_slice.py b/backends/arm/test/ops/test_slice.py index 28c9731a6aa..94a69130893 100644 --- a/backends/arm/test/ops/test_slice.py +++ b/backends/arm/test/ops/test_slice.py @@ -144,7 +144,9 @@ def test_slice_tensor_u85_INT(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_slice_tensor_vgf_no_quant(test_data: torch.Tensor): pipeline = VgfPipeline[input_t1]( diff --git a/backends/arm/test/ops/test_slice_scatter.py b/backends/arm/test/ops/test_slice_scatter.py index ae3ceadadac..d367adc8622 100644 --- a/backends/arm/test/ops/test_slice_scatter.py +++ b/backends/arm/test/ops/test_slice_scatter.py @@ -299,7 +299,11 @@ def test_slice_scatter_u85_INT_stepN(test_module: input_t): @common.SkipIfNoModelConverter @common.parametrize( "test_module", - test_data_int_step1 | test_data_int_stepN | test_data_fp_step1 | test_data_fp_stepN, + test_data_int_step1 + | test_data_int_stepN + | test_data_fp_step1 + | test_data_fp_stepN + | test_data_bf16, ) def test_slice_scatter_vgf_no_quant(test_module: input_t): pipeline = VgfPipeline[input_t]( diff --git a/backends/arm/test/ops/test_sub.py b/backends/arm/test/ops/test_sub.py index 88b2816b503..c7127de645c 100644 --- a/backends/arm/test/ops/test_sub.py +++ b/backends/arm/test/ops/test_sub.py @@ -257,7 +257,9 @@ def test_sub_tensor_u85_INT(test_data: Tuple[torch.Tensor, torch.Tensor]): pipeline.run() -@common.parametrize("test_data", sub_test_data | sub_test_data_fp16) +@common.parametrize( + "test_data", sub_test_data | sub_test_data_bf16 | sub_test_data_fp16 +) @common.SkipIfNoModelConverter def test_sub_tensor_vgf_no_quant(test_data: Tuple[torch.Tensor]): """Test Subtraction (VGF FP)""" @@ -271,7 +273,9 @@ def test_sub_tensor_vgf_no_quant(test_data: Tuple[torch.Tensor]): pipeline.run() -@common.parametrize("test_data", sub2_test_data | sub2_test_data_fp16) +@common.parametrize( + "test_data", sub2_test_data | sub2_test_data_bf16 | sub2_test_data_fp16 +) @common.SkipIfNoModelConverter def test_sub_tensor_vgf_no_quant_2(test_data: Tuple[torch.Tensor, torch.Tensor]): """Test Two-Operand Subtraction (VGF FP)""" diff --git a/backends/arm/test/ops/test_sum.py b/backends/arm/test/ops/test_sum.py index d727eb0408a..71af0d4014b 100644 --- a/backends/arm/test/ops/test_sum.py +++ b/backends/arm/test/ops/test_sum.py @@ -131,15 +131,28 @@ def test_sum_u85_INT_1_0(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", Sum.test_parameters | Sum.test_parameters_fp16) +@common.parametrize( + "test_data", + Sum.test_parameters | Sum.test_parameters_bf16 | Sum.test_parameters_fp16, +) @common.SkipIfNoModelConverter def test_sum_dim_intlist_vgf_no_quant(test_data: input_t1): + data = test_data() + match data[0].dtype: + case torch.bfloat16: + atol = 1e-1 + rtol = 1e-1 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Sum(), - test_data(), + data, aten_op, run_on_vulkan_runtime=True, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_tanh.py b/backends/arm/test/ops/test_tanh.py index b3931f73389..7543cd20526 100644 --- a/backends/arm/test/ops/test_tanh.py +++ b/backends/arm/test/ops/test_tanh.py @@ -97,14 +97,26 @@ def test_tanh_u85_INT(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_tanh_vgf_no_quant(test_data: Tuple): + data = test_data() + match data.dtype: + case torch.bfloat16: + atol = 5e-3 + rtol = 5e-3 + case _: + atol = 1e-3 + rtol = 1e-3 pipeline = VgfPipeline[input_t1]( Tanh(), - (test_data(),), + (data,), aten_op, quantize=False, + atol=atol, + rtol=rtol, ) pipeline.run() diff --git a/backends/arm/test/ops/test_to_copy.py b/backends/arm/test/ops/test_to_copy.py index 77e08a7995c..699e1f6460b 100644 --- a/backends/arm/test/ops/test_to_copy.py +++ b/backends/arm/test/ops/test_to_copy.py @@ -104,6 +104,17 @@ def forward(self, x: torch.Tensor, y: torch.Tensor): ), } +_TO_COPY_TEST_DATA_VGF_BF16 = { + "rand_fp32_bf16": lambda: ( + torch.rand((1, 2, 3, 4), dtype=torch.float32), + torch.bfloat16, + ), + "rand_bf16_fp32": lambda: ( + torch.rand((1, 2, 3, 4), dtype=torch.bfloat16), + torch.float32, + ), +} + @common.parametrize("test_data", _TO_COPY_TEST_DATA_FP) def test_to_tosa_FP(test_data: Tuple): @@ -275,7 +286,7 @@ def test_to_tosa_FP_bf16_fp8_with_extensions(test_data: Tuple): pipeline.run() -@common.parametrize("test_data", _TO_COPY_TEST_DATA_FP) +@common.parametrize("test_data", _TO_COPY_TEST_DATA_FP | _TO_COPY_TEST_DATA_VGF_BF16) @common.SkipIfNoModelConverter def test_to_vgf_no_quant(test_data: Tuple): test_tensor, new_dtype = test_data() diff --git a/backends/arm/test/ops/test_transpose_conv2d.py b/backends/arm/test/ops/test_transpose_conv2d.py index d34679f4bcb..9c53e59464b 100644 --- a/backends/arm/test/ops/test_transpose_conv2d.py +++ b/backends/arm/test/ops/test_transpose_conv2d.py @@ -537,12 +537,15 @@ def test_conv_transpose2d_tosa_INT_a16w8(test_data): pipeline.run() -@common.parametrize("test_data", test_data_FP | test_data_FP_fp16) +@common.parametrize("test_data", test_data_FP | test_data_BF16 | test_data_FP_fp16) @common.SkipIfNoModelConverter def test_conv_transpose2d_vgf_no_quant(test_data): model = test_data() inputs = model.get_inputs() match inputs[0].dtype: + case torch.bfloat16: + atol = 1e-2 + rtol = 1e-2 case torch.float16: atol = 5e-3 rtol = 5e-3 diff --git a/backends/arm/test/ops/test_unfold_copy.py b/backends/arm/test/ops/test_unfold_copy.py index 446575d92ff..4b235ffa720 100644 --- a/backends/arm/test/ops/test_unfold_copy.py +++ b/backends/arm/test/ops/test_unfold_copy.py @@ -236,7 +236,7 @@ def test_unfold_copy_u85_INT(test_data: input_params): pipeline.run() -@common.parametrize("test_data", test_data_fp | test_data_int) +@common.parametrize("test_data", test_data_fp | test_data_bf16 | test_data_int) @common.SkipIfNoModelConverter def test_unfold_copy_vgf_no_quant(test_data: input_params): pipeline = VgfPipeline[input_params]( diff --git a/backends/arm/test/ops/test_upsample_bilinear2d.py b/backends/arm/test/ops/test_upsample_bilinear2d.py index 705f9ba4d20..1ebb38c2368 100644 --- a/backends/arm/test/ops/test_upsample_bilinear2d.py +++ b/backends/arm/test/ops/test_upsample_bilinear2d.py @@ -502,31 +502,47 @@ def test_upsample_bilinear2d_vec_u85_INT_a16w8( pipeline.run() -@common.parametrize("test_data", test_data_suite_tosa | test_data_suite_tosa_fp16) +@common.parametrize( + "test_data", + test_data_suite_tosa | test_data_suite_tosa_bf16 | test_data_suite_tosa_fp16, +) @common.SkipIfNoModelConverter def test_upsample_bilinear2d_vec_vgf_no_quant_UpsamplingBilinear2d( test_data: torch.Tensor, ): data, size, scale_factor, compare = test_data() + match data.dtype: + case torch.bfloat16: + atol = 1e-2 + rtol = 1e-2 + case _: + atol = 2e-3 + rtol = 2e-3 pipeline = VgfPipeline[input_t1]( UpsamplingBilinear2d(size, scale_factor), (data,), aten_op, exir_op, quantize=False, - atol=2e-3, - rtol=2e-3, + atol=atol, + rtol=rtol, ) if not compare: pipeline.pop_stage(-1) pipeline.run() -@common.parametrize("test_data", test_data_suite_tosa | test_data_suite_tosa_fp16) +@common.parametrize( + "test_data", + test_data_suite_tosa | test_data_suite_tosa_bf16 | test_data_suite_tosa_fp16, +) @common.SkipIfNoModelConverter def test_upsample_bilinear2d_vec_vgf_no_quant_Upsample(test_data: torch.Tensor): data, size, scale_factor, compare = test_data() match data.dtype: + case torch.bfloat16: + atol = 1e-2 + rtol = 1e-2 case torch.float16: atol = 1e-2 rtol = 1e-2 @@ -547,11 +563,17 @@ def test_upsample_bilinear2d_vec_vgf_no_quant_Upsample(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite_tosa | test_data_suite_tosa_fp16) +@common.parametrize( + "test_data", + test_data_suite_tosa | test_data_suite_tosa_bf16 | test_data_suite_tosa_fp16, +) @common.SkipIfNoModelConverter def test_upsample_bilinear2d_vec_vgf_no_quant_Interpolate(test_data: torch.Tensor): data, size, scale_factor, compare = test_data() match data.dtype: + case torch.bfloat16: + atol = 1e-2 + rtol = 1e-2 case torch.float16: atol = 1e-2 rtol = 1e-2 diff --git a/backends/arm/test/ops/test_upsample_nearest2d.py b/backends/arm/test/ops/test_upsample_nearest2d.py index d8bf4d7dbd5..ea17175221e 100644 --- a/backends/arm/test/ops/test_upsample_nearest2d.py +++ b/backends/arm/test/ops/test_upsample_nearest2d.py @@ -282,7 +282,9 @@ def test_upsample_nearest2d_vec_tosa_INT_a16w8(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_upsample_nearest2d_vec_vgf_no_quant(test_data: torch.Tensor): data, size, scale_factor, compare = test_data() @@ -298,7 +300,9 @@ def test_upsample_nearest2d_vec_vgf_no_quant(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_upsample_nearest2d_vec_vgf_no_quant_nearest(test_data: torch.Tensor): data, size, scale_factor, compare = test_data() @@ -314,7 +318,9 @@ def test_upsample_nearest2d_vec_vgf_no_quant_nearest(test_data: torch.Tensor): pipeline.run() -@common.parametrize("test_data", test_data_suite | test_data_suite_fp16) +@common.parametrize( + "test_data", test_data_suite | test_data_suite_bf16 | test_data_suite_fp16 +) @common.SkipIfNoModelConverter def test_upsample_nearest2d_vec_vgf_no_quant_interpolate(test_data: torch.Tensor): data, size, scale_factor, compare = test_data() @@ -325,7 +331,7 @@ def test_upsample_nearest2d_vec_vgf_no_quant_interpolate(test_data: torch.Tensor exir_op, quantize=False, # Override tosa version to test FP-only path - tosa_version="TOSA-1.0+FP", + tosa_version="TOSA-1.0+FP+bf16", ) if not compare: pipeline.pop_stage(-1) diff --git a/backends/arm/test/ops/test_where.py b/backends/arm/test/ops/test_where.py index 234203f1cc4..b5c201931cb 100644 --- a/backends/arm/test/ops/test_where.py +++ b/backends/arm/test/ops/test_where.py @@ -292,7 +292,7 @@ def test_where_self_u85_INT(test_module): pipeline.run() -@common.parametrize("test_module", test_modules_FP) +@common.parametrize("test_module", test_modules_FP | test_modules_FP_bf16) @common.SkipIfNoModelConverter def test_where_self_vgf_no_quant(test_module): module = test_module() diff --git a/backends/arm/test/runner_utils.py b/backends/arm/test/runner_utils.py index 9a63452e325..b59fab917fc 100644 --- a/backends/arm/test/runner_utils.py +++ b/backends/arm/test/runner_utils.py @@ -243,8 +243,7 @@ def is_concrete_shape(shape_like) -> bool: return all(isinstance(dim, numbers.Integral) for dim in shape_like) def to_torch_tensor() -> torch.Tensor: - if array.dtype.type is np.void: - # If dtype is void, "cheat" and use the output_tensor dtype. + if output_tensor.dtype == torch.bfloat16 or array.dtype.type is np.void: return torch.frombuffer(array, dtype=output_tensor.dtype) return torch.from_numpy(array) diff --git a/backends/arm/test/tester/test_pipeline.py b/backends/arm/test/tester/test_pipeline.py index 589c0a851a3..6538f80cc28 100644 --- a/backends/arm/test/tester/test_pipeline.py +++ b/backends/arm/test/tester/test_pipeline.py @@ -1258,13 +1258,15 @@ def __init__( ): if tosa_spec is None: if tosa_version is None: - tosa_spec = VgfCompileSpec().tosa_spec - else: - if tosa_extensions is None: + tosa_version = str(VgfCompileSpec().tosa_spec) + if tosa_extensions is None: + if "FP" in tosa_version: + tosa_extensions = ["bf16"] + else: tosa_extensions = [] - tosa_spec = TosaSpecification.create_from_string( - tosa_version + "".join([f"+{ext}" for ext in tosa_extensions]) - ) + tosa_spec = TosaSpecification.create_from_string( + tosa_version + "".join([f"+{ext}" for ext in tosa_extensions]) + ) elif isinstance(tosa_spec, str): tosa_spec = TosaSpecification.create_from_string(tosa_spec) compile_spec = common.get_vgf_compile_spec(