Add QUANT8_ASYMM_SIGNED support to SELECT op Bug: 143935354 Test: NNTest_static and VTS_1_3 with --gtest_filter="*select*" Change-Id: Ifc8ae06d412d4b50421a4e2dce39b223723a137a Merged-In: Ifc8ae06d412d4b50421a4e2dce39b223723a137a (cherry picked from commit 29c9adde6ec7ea99c98b6d796c5a79c19dea8701)
diff --git a/common/OperationsUtils.cpp b/common/OperationsUtils.cpp index 5c50e3d..5c251a2 100644 --- a/common/OperationsUtils.cpp +++ b/common/OperationsUtils.cpp
@@ -17,12 +17,16 @@ #define LOG_TAG "OperationsUtils" #include "OperationsUtils.h" + +#include <algorithm> +#include <cmath> +#include <limits> +#include <sstream> +#include <vector> + #include "Operations.h" #include "Utils.h" -#include <cmath> -#include <sstream> - namespace android { namespace nn { @@ -355,6 +359,14 @@ return static_cast<uint8_t>(std::round(doubleRet)); } +int8_t requantize(int8_t value, const Shape& oldShape, const Shape& newShape) { + double doubleValue = (value - oldShape.offset) * oldShape.scale; + double doubleRet = doubleValue / newShape.scale + newShape.offset; + if (doubleRet < -128) return -128; + if (doubleRet > 127) return 127; + return static_cast<int8_t>(std::round(doubleRet)); +} + bool floorPrepare(const Shape& input, Shape* output) { return SetShape(input, output); }
diff --git a/common/operations/Select.cpp b/common/operations/Select.cpp index e9b6645..b46e6af 100644 --- a/common/operations/Select.cpp +++ b/common/operations/Select.cpp
@@ -47,7 +47,8 @@ for (uint32_t i = 0; i < size; ++i) { T a = aData[i]; T b = bData[i]; - if (aShape.type == OperandType::TENSOR_QUANT8_ASYMM) { + if (aShape.type == OperandType::TENSOR_QUANT8_ASYMM || + aShape.type == OperandType::TENSOR_QUANT8_ASYMM_SIGNED) { a = requantize(a, aShape, outputShape); b = requantize(b, bShape, outputShape); } @@ -72,9 +73,11 @@ NN_RET_CHECK_EQ(context->getNumInputs(), kNumInputs); NN_RET_CHECK_EQ(context->getNumOutputs(), kNumOutputs); OperandType inputType = context->getInputType(kInputTensor1); - NN_RET_CHECK( - inputType == OperandType::TENSOR_FLOAT16 || inputType == OperandType::TENSOR_FLOAT32 || - inputType == OperandType::TENSOR_INT32 || inputType == OperandType::TENSOR_QUANT8_ASYMM) + NN_RET_CHECK(inputType == OperandType::TENSOR_FLOAT16 || + inputType == OperandType::TENSOR_FLOAT32 || + inputType == OperandType::TENSOR_INT32 || + inputType == OperandType::TENSOR_QUANT8_ASYMM || + inputType == OperandType::TENSOR_QUANT8_ASYMM_SIGNED) << "Unsupported input operand type for select op: " << toString(inputType); NN_RET_CHECK(validateInputTypes(context, {OperandType::TENSOR_BOOL8, inputType, inputType})); NN_RET_CHECK(validateOutputTypes(context, {inputType})); @@ -113,6 +116,8 @@ return executeTyped<int32_t>(context); case OperandType::TENSOR_QUANT8_ASYMM: return executeTyped<uint8_t>(context); + case OperandType::TENSOR_QUANT8_ASYMM_SIGNED: + return executeTyped<int8_t>(context); default: NN_RET_CHECK_FAIL() << "Unsupported tensor type for SELECT op."; }