diff --git a/ethosu/regor/architecture/ethosu55/ethos_u55_constraints.cpp b/ethosu/regor/architecture/ethosu55/ethos_u55_constraints.cpp index da197be95af2ec642e1eaa0b5f10f9c2004792a5..55334b5afc4a6f7d8fcc06b2ef4964296d0371be 100644 --- a/ethosu/regor/architecture/ethosu55/ethos_u55_constraints.cpp +++ b/ethosu/regor/architecture/ethosu55/ethos_u55_constraints.cpp @@ -82,8 +82,9 @@ bool EthosU55Constraints::SupportsFusedRescale(OpType opType, TensorUsage tensor DataType rescaleToType, DataType opFromType, DataType opToType, const Quantization &quantization) { auto npuOp = ArchEthosU55::GetHWOp(opType); - bool globalScale = quantization.scales.size() == 1; + bool globalScale = quantization.scales.size() <= 1; bool isUnitScale = quantization.IsUnitScale(); + int64_t zp = quantization.zeroPoints.size() ? quantization.zeroPoints.front() : 0; if ( tensorUsage == TensorUsage::IFM ) { @@ -100,7 +101,6 @@ bool EthosU55Constraints::SupportsFusedRescale(OpType opType, TensorUsage tensor bool scaleSupported = qs.shift == 0 && static_cast(qs.scale) == qs.scale; // Make sure the rescale can be done without clipping - int64_t zp = quantization.zeroPoints.front(); int64_t value = (zp < 0 ? int64_t(IntegerMax(rescaleFromType)) : IntegerMin(rescaleFromType)); value = value - zp; value = (value * qs.scale) >> qs.shift; diff --git a/ethosu/regor/architecture/ethosu85/ethos_u85_constraints.cpp b/ethosu/regor/architecture/ethosu85/ethos_u85_constraints.cpp index 7988eb91e1b40761cc795f565f5e02de258e97f7..2badd56d0f6ad372c1238fd8384581d0c5529063 100644 --- a/ethosu/regor/architecture/ethosu85/ethos_u85_constraints.cpp +++ b/ethosu/regor/architecture/ethosu85/ethos_u85_constraints.cpp @@ -102,8 +102,9 @@ bool EthosU85Constraints::SupportsFusedRescale(OpType opType, TensorUsage tensor DataType rescaleToType, DataType opFromType, DataType opToType, const Quantization &quantization) { auto npuOp = ArchEthosU85::GetHWOp(opType); - bool globalScale = quantization.scales.size() == 1; + bool globalScale = quantization.scales.size() <= 1; bool isUnitScale = quantization.IsUnitScale(); + int64_t zp = quantization.zeroPoints.size() ? quantization.zeroPoints.front() : 0; if ( tensorUsage == TensorUsage::IFM ) { @@ -118,7 +119,6 @@ bool EthosU85Constraints::SupportsFusedRescale(OpType opType, TensorUsage tensor // Make sure shift is valid if ( qs.shift < 0 || qs.shift > 63 ) return false; // Make sure the rescale can be done without clipping - int64_t zp = quantization.zeroPoints.front(); int64_t value = (zp < 0 ? int64_t(IntegerMax(rescaleFromType)) : IntegerMin(rescaleFromType)); value = value - zp; value = (value * qs.scale) >> qs.shift; diff --git a/ethosu/regor/compiler/quantization.hpp b/ethosu/regor/compiler/quantization.hpp index a79212d08f9fb0603c6dee464fe90ebd24645717..dd054078c6b414920316f5a02a7c3b2ddb6f0fee 100644 --- a/ethosu/regor/compiler/quantization.hpp +++ b/ethosu/regor/compiler/quantization.hpp @@ -1,5 +1,5 @@ // -// SPDX-FileCopyrightText: Copyright 2023-2024 Arm Limited and/or its affiliates +// SPDX-FileCopyrightText: Copyright 2023-2025 Arm Limited and/or its affiliates // // SPDX-License-Identifier: Apache-2.0 // @@ -57,7 +57,7 @@ public: { return other.scales == scales && other.zeroPoints == zeroPoints; } - bool IsUnitScale() const { return Quantization::Unit().scales == scales; } + bool IsUnitScale() const { return Quantization::Unit().scales == scales || scales.empty(); } explicit operator bool() const { return IsValid(); } Quantization &operator=(const Quantization &other)