Fix under/overflow issue in requantize and CAST.
Also add tests. requantize is tested in MAXIMUM and MINIMUM.
Bug: 131111895
Test: NeuralNetworksTest_static
Change-Id: I8971966610542feacf188fd729286ca8d285f92c
Merged-In: I8971966610542feacf188fd729286ca8d285f92c
(cherry picked from commit 282f497ebf8a556d5e7c396c3c71b1adec6afac8)
diff --git a/common/OperationsUtils.cpp b/common/OperationsUtils.cpp
index 64cea58..3338493 100644
--- a/common/OperationsUtils.cpp
+++ b/common/OperationsUtils.cpp
@@ -339,7 +339,10 @@
uint8_t requantize(uint8_t value, const Shape& oldShape, const Shape& newShape) {
double doubleValue = (value - oldShape.offset) * oldShape.scale;
- return static_cast<uint8_t>(doubleValue / newShape.scale + newShape.offset);
+ double doubleRet = doubleValue / newShape.scale + newShape.offset;
+ if (doubleRet < 0) return 0;
+ if (doubleRet > 255) return 255;
+ return static_cast<uint8_t>(doubleRet);
}
bool floorPrepare(const Shape& input, Shape* output) {
diff --git a/common/operations/Cast.cpp b/common/operations/Cast.cpp
index 5ca92c8..f569767 100644
--- a/common/operations/Cast.cpp
+++ b/common/operations/Cast.cpp
@@ -27,7 +27,13 @@
template <typename FromT, typename ToT>
void copyCast(const FromT* in, ToT* out, int numElements) {
- std::transform(in, in + numElements, out, [](FromT a) { return static_cast<ToT>(a); });
+ std::transform(in, in + numElements, out, [](FromT a) -> ToT {
+ if constexpr (std::is_same_v<ToT, uint8_t>) {
+ if (a < 0) return 0;
+ if (a > 255) return 255;
+ }
+ return static_cast<ToT>(a);
+ });
}
template <typename FromT>