From a570a6ba6399ca260abf85a4b37d11052bdea7a6 Mon Sep 17 00:00:00 2001 From: Jacob Bohlin Date: Thu, 23 Jan 2025 11:45:48 +0000 Subject: [PATCH] MLBEDSW-10249 Fixed scaling issue with out-of-range shifts When the shift is above 63 it cannot be encoded and would cause an assert. However, a shift larger than 63 would lead to all the bits being shifted away and result in a 0 anyway so the same behaviour can be achieved by setting the scale to 0. Also addressed two minor integer type issues in the python graph optimiser. Change-Id: I5da2b4170f95c4e1cf161c93a932c92ad9c242ea Signed-off-by: Jacob Bohlin --- ethosu/regor/common/scaling.cpp | 18 ++++++++++++++---- ethosu/vela/tflite_graph_optimiser.py | 4 ++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/ethosu/regor/common/scaling.cpp b/ethosu/regor/common/scaling.cpp index fd2c3364..1032a102 100644 --- a/ethosu/regor/common/scaling.cpp +++ b/ethosu/regor/common/scaling.cpp @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: Copyright 2021-2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: Copyright 2021-2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 // @@ -44,10 +44,20 @@ QuantizedScale::QuantizedScale(double scale_, bool reduced) if ( reduced ) scale = ClampToType(scale); shift = leftShift - exponent; // if shift is out of bounds [0,63], try to get back within bounds - if ( shift > 63 && scale > std::exp2(shift - 63) ) + if ( shift > 63 ) { - scale = scale >> (shift - 63); - shift = 63; + if ( scale > std::exp2(shift - 63) ) + { + scale = scale >> (shift - 63); + shift = 63; + } + else + { + // Not possible to get back within bounds, set scale and shift to 0 + // as the shift would shift away all relevant bits anyway. + scale = 0; + shift = 0; + } } else if ( shift < 0 && scale < std::exp2(shift + 32) ) { diff --git a/ethosu/vela/tflite_graph_optimiser.py b/ethosu/vela/tflite_graph_optimiser.py index 3918e847..1834638d 100644 --- a/ethosu/vela/tflite_graph_optimiser.py +++ b/ethosu/vela/tflite_graph_optimiser.py @@ -593,7 +593,7 @@ def convert_argmax_to_depthwise_conv_and_max_pool(op: Operation, arch, nng) -> O # To extract 7 least significant bits and swap reverse index back to real index using a LUT activation, we set # the base value to c-1 and slope to -128. The 16-bit LUT uses a table of 32-bit values where the top 16 bits # represent the slope and bottom 16 bits the base which are used to interpolate the activation value. - slope = (-128 & 0xFFFF) << 16 # Top 16 bits of 32 bit LUT table value + slope = np.uint32((-128 & 0xFFFF) << 16) # Top 16 bits of 32 bit LUT table value base = c - 1 # Bottom 16 bits of the LUT table value lut_tensor = create_const_tensor( "maxpool_LUT_extract_7_LSB", @@ -2535,7 +2535,7 @@ def convert_mean_to_depthwise_conv(op, arch, nng): shift = round_down_log2(num_elements_in_axis) shift = min(shift, 32) shift = min(shift, 31 + output_shift) - output_multiplier = (output_multiplier << shift) // num_elements_in_axis + output_multiplier = np.int32((np.int64(output_multiplier) << shift) // num_elements_in_axis) output_shift = output_shift - shift # Convert to vela representation shift -- GitLab