Modify RoiPooling to use OperationResolver and support float16.
Bug: 118608492
Test: NeuralNetworksTest_static
Change-Id: I164c58c8105ef8ceed23144423b472d586faa8c9
Merged-In: I164c58c8105ef8ceed23144423b472d586faa8c9
(cherry picked from commit b14b6166078db0092eff2d46ee4a7ee0c63c7d8c)
diff --git a/common/Android.bp b/common/Android.bp
index 2c5efc9..7eb03eb 100644
--- a/common/Android.bp
+++ b/common/Android.bp
@@ -34,6 +34,7 @@
"operations/LogSoftmax.cpp",
"operations/PRelu.cpp",
"operations/Reduce.cpp",
+ "operations/RoiPooling.cpp",
"operations/Select.cpp",
],
}
@@ -115,7 +116,6 @@
"operations/Reshape.cpp",
"operations/RNN.cpp",
"operations/RoiAlign.cpp",
- "operations/RoiPooling.cpp",
"operations/SimpleMath.cpp",
"operations/Slice.cpp",
"operations/Split.cpp",
diff --git a/common/CpuExecutor.cpp b/common/CpuExecutor.cpp
index a1138b2..1e3a5db 100644
--- a/common/CpuExecutor.cpp
+++ b/common/CpuExecutor.cpp
@@ -2252,47 +2252,6 @@
break;
}
} break;
- case OperationType::ROI_POOLING: {
- if (!allParametersPresent(5, 1)) {
- return ANEURALNETWORKS_BAD_DATA;
- }
- const RunTimeOperandInfo& input = mOperands[ins[0]];
- const RunTimeOperandInfo& roi = mOperands[ins[1]];
- const RunTimeOperandInfo& outputShape = mOperands[ins[2]];
- const float spatialScale = getScalarData<float>(mOperands[ins[3]]);
- const bool data_layout = getScalarData<bool>(mOperands[ins[4]]);
-
- RunTimeOperandInfo& out = mOperands[outs[0]];
- Shape outShape = out.shape();
-
- RunTimeOperandInfo input_tmp, out_tmp;
- std::unique_ptr<uint8_t[]> input_tmp_guard, out_tmp_guard;
- if (!convertToNhwc(input_tmp, input, input_tmp_guard, data_layout)) {
- success = false;
- break;
- }
- out_tmp.lifetime = OperandLifeTime::TEMPORARY_VARIABLE;
- out_tmp.buffer = data_layout ? nullptr : out.buffer;
-
- if (!roiAlignPrepare(input_tmp.shape(), reinterpret_cast<const float*>(roi.buffer),
- roi.shape(), reinterpret_cast<const int32_t*>(outputShape.buffer),
- outputShape.shape(), spatialScale, &outShape) ||
- !setInfoAndAllocateIfNeeded(&out_tmp, outShape)) {
- success = false;
- break;
- }
-
- success = roiPoolingGeneric(input_tmp.buffer, input_tmp.shape(), roi.buffer,
- roi.shape(), spatialScale, out_tmp.buffer, outShape);
-
- if (data_layout) {
- out_tmp_guard.reset(out_tmp.buffer);
- }
- if (!success || !convertFromNhwc(out, out_tmp, data_layout)) {
- success = false;
- break;
- }
- } break;
case OperationType::MAXIMUM:
case OperationType::MINIMUM: {
if (!allParametersPresent(2, 1)) {
diff --git a/common/OperationResolver.cpp b/common/OperationResolver.cpp
index 8e612eb..54ff386 100644
--- a/common/OperationResolver.cpp
+++ b/common/OperationResolver.cpp
@@ -45,6 +45,7 @@
const OperationRegistration* register_REDUCE_MIN();
const OperationRegistration* register_REDUCE_PROD();
const OperationRegistration* register_REDUCE_SUM();
+const OperationRegistration* register_ROI_POOLING();
const OperationRegistration* register_SELECT();
OperationResolver::OperationResolver() {
@@ -69,6 +70,7 @@
registerOperation(register_REDUCE_MIN());
registerOperation(register_REDUCE_PROD());
registerOperation(register_REDUCE_SUM());
+ registerOperation(register_ROI_POOLING());
registerOperation(register_SELECT());
}
diff --git a/common/Utils.cpp b/common/Utils.cpp
index 0a1ddaf..da3dcf6 100644
--- a/common/Utils.cpp
+++ b/common/Utils.cpp
@@ -2189,30 +2189,6 @@
inExpectedTypes, outputCount, outputIndexes,
outExpectedTypes);
}
- case ANEURALNETWORKS_ROI_POOLING: {
- if (inputCount != 5 || outputCount != 1) {
- logInvalidInOutNumber(5, 1);
- return ANEURALNETWORKS_BAD_DATA;
- }
- std::vector<OperandType> inExpectedTypes;
- std::vector<OperandType> outExpectedTypes;
- auto inputType = operands[inputIndexes[0]].type;
- if (inputType == OperandType::TENSOR_FLOAT32 ||
- inputType == OperandType::TENSOR_QUANT8_ASYMM) {
- inExpectedTypes = {inputType, OperandType::TENSOR_FLOAT32,
- OperandType::TENSOR_INT32, OperandType::FLOAT32,
- OperandType::BOOL};
- outExpectedTypes = {inputType};
- } else {
- LOG(ERROR) << "Unsupported input tensor type for operation "
- << kOperationNames[opType];
- return ANEURALNETWORKS_BAD_DATA;
- }
- NN_RETURN_IF_ERROR(validateHalVersion(opType, halVersion, HalVersion::V1_2));
- return validateOperationOperandTypes(operands, inputCount, inputIndexes,
- inExpectedTypes, outputCount, outputIndexes,
- outExpectedTypes);
- }
case ANEURALNETWORKS_MAXIMUM:
case ANEURALNETWORKS_MINIMUM: {
if (inputCount != 2 || outputCount != 1) {
diff --git a/common/include/CpuOperationUtils.h b/common/include/CpuOperationUtils.h
index 2976b4e..fb1996a 100644
--- a/common/include/CpuOperationUtils.h
+++ b/common/include/CpuOperationUtils.h
@@ -91,6 +91,81 @@
return true;
}
+template <typename T>
+inline bool convertNhwcToNchw(const std::vector<T>& nhwc, const Shape& nhwcShape, T* nchw) {
+ NN_RET_CHECK_EQ(getNumberOfDimensions(nhwcShape), 4)
+ << "Error converting a non-4-D tensor to NCHW layout";
+ const auto& fromDim = nhwcShape.dimensions;
+ const auto from = nhwc.data();
+ uint32_t spatialSize = fromDim[1] * fromDim[2];
+ for (uint32_t n = 0; n < fromDim[0]; n++) {
+ for (uint32_t c = 0; c < fromDim[3]; c++) {
+ for (uint32_t hw = 0; hw < spatialSize; hw++) {
+ uint32_t fromIndex = n * spatialSize * fromDim[3] + hw * fromDim[3] + c;
+ *nchw++ = from[fromIndex];
+ }
+ }
+ }
+ return true;
+}
+
+template <typename T>
+class InputWithLayout {
+ public:
+ InputWithLayout(bool useNchw) : mDataOriginal(nullptr), mUseNchw(useNchw) {}
+
+ bool initialize(const T* data, const Shape& shape) {
+ mDataOriginal = data;
+ mShape = shape;
+ if (mUseNchw) {
+ return convertNchwToNhwc(mDataOriginal, shape, &mDataNhwc, &mShape);
+ }
+ return true;
+ }
+
+ const T* getNhwcBuffer() { return mUseNchw ? mDataNhwc.data() : mDataOriginal; }
+ const Shape& getNhwcShape() { return mShape; }
+
+ private:
+ const T* mDataOriginal;
+ std::vector<T> mDataNhwc;
+ Shape mShape;
+ bool mUseNchw;
+};
+
+template <typename T>
+class OutputWithLayout {
+ public:
+ OutputWithLayout(bool useNchw) : mDataOriginal(nullptr), mUseNchw(useNchw) {}
+
+ bool initialize(T* data, const Shape& shape) {
+ NN_RET_CHECK_EQ(getNumberOfDimensions(shape), 4);
+ mDataOriginal = data;
+ mShape = shape;
+ if (mUseNchw) {
+ const auto& dim = shape.dimensions;
+ mShape.dimensions = {dim[0], dim[2], dim[3], dim[1]};
+ mDataNhwc.resize(getNumberOfElements(shape));
+ }
+ return true;
+ }
+
+ T* getNhwcBuffer() { return mUseNchw ? mDataNhwc.data() : mDataOriginal; }
+ const Shape& getNhwcShape() { return mShape; }
+ bool commit() {
+ if (mUseNchw) {
+ return convertNhwcToNchw(mDataNhwc, mShape, mDataOriginal);
+ }
+ return true;
+ }
+
+ private:
+ T* mDataOriginal;
+ std::vector<T> mDataNhwc;
+ Shape mShape;
+ bool mUseNchw;
+};
+
} // nn
} // android
diff --git a/common/include/Operations.h b/common/include/Operations.h
index e0f878a..4e0c59c 100644
--- a/common/include/Operations.h
+++ b/common/include/Operations.h
@@ -286,10 +286,6 @@
const Shape& roiShape, float spatialScale, int32_t samplingRatio,
uint8_t* outputData, const Shape& outputShape);
-bool roiPoolingGeneric(const uint8_t* inputData, const Shape& inputShape, const uint8_t* roiData,
- const Shape& roiShape, float spatialScale, uint8_t* outputData,
- const Shape& outputShape);
-
bool groupedConvFloat16(const _Float16* inputData, const Shape& inputShape,
const _Float16* filterData, const Shape& filterShape,
const _Float16* biasData, const Shape& biasShape, int32_t numGroups,
diff --git a/common/operations/RoiPooling.cpp b/common/operations/RoiPooling.cpp
index 591617f..6050feb 100644
--- a/common/operations/RoiPooling.cpp
+++ b/common/operations/RoiPooling.cpp
@@ -15,7 +15,8 @@
*/
#include "CpuOperationUtils.h"
-#include "Operations.h"
+#include "OperationResolver.h"
+#include "OperationsUtils.h"
#include <cfloat>
#include <cmath>
@@ -24,15 +25,29 @@
namespace android {
namespace nn {
+namespace roi_pooling {
-template <typename T_Input>
-bool roiPoolingImpl(const T_Input* inputData, const Shape& inputShape, const float* roiData,
- const Shape& roiShape, float spatialScale, T_Input* outputData,
- const Shape& outputShape) {
+constexpr char kOperationName[] = "ROI_POOLING";
+
+constexpr uint32_t kNumInputs = 5;
+constexpr uint32_t kInputTensor = 0;
+constexpr uint32_t kRoiTensor = 1;
+constexpr uint32_t kOutputShapeTensor = 2;
+constexpr uint32_t kSpacialScaleScalar = 3;
+constexpr uint32_t kLayoutScalar = 4;
+
+constexpr uint32_t kNumOutputs = 1;
+constexpr uint32_t kOutputTensor = 0;
+
+namespace {
+
+template <typename T_Input, typename T_Roi>
+inline bool roiPoolingNhwc(const T_Input* inputData, const Shape& inputShape, const T_Roi* roiData,
+ const Shape& roiShape, T_Roi spatialScale, T_Input* outputData,
+ const Shape& outputShape) {
NNTRACE_TRANS("RoiPooling");
- const uint32_t kRoiDim = 4;
-
+ uint32_t numBatches = getSizeOfDimension(inputShape, 0);
uint32_t inHeight = getSizeOfDimension(inputShape, 1);
uint32_t inWidth = getSizeOfDimension(inputShape, 2);
uint32_t inDepth = getSizeOfDimension(inputShape, 3);
@@ -41,36 +56,54 @@
uint32_t numRois = getSizeOfDimension(roiShape, 0);
uint32_t roiInfoLength = getSizeOfDimension(roiShape, 1);
+ const uint32_t kRoiDim = 4;
T_Input* outPtr = outputData;
- const float* roiDataEnd = roiData + numRois * roiInfoLength;
- for (const float* roiInfo = roiData; roiInfo < roiDataEnd; roiInfo += kRoiDim) {
+ const T_Roi* roiDataEnd = roiData + numRois * roiInfoLength;
+ for (const T_Roi* roiInfo = roiData; roiInfo < roiDataEnd; roiInfo += kRoiDim) {
uint32_t batchId = 0;
// get optional batch id
if (roiInfoLength == kRoiDim + 1) {
- batchId = std::round(roiInfo[0]);
+ batchId = std::round(static_cast<float>(roiInfo[0]));
roiInfo++;
}
- const T_Input* batchBase = inputData + batchId * inHeight * inWidth * inDepth;
- int32_t wRoiStart = std::round(roiInfo[0] * spatialScale);
- int32_t hRoiStart = std::round(roiInfo[1] * spatialScale);
- int32_t wRoiEnd = std::round(roiInfo[2] * spatialScale);
- int32_t hRoiEnd = std::round(roiInfo[3] * spatialScale);
+ // Check for malformed data
+ // 1. invalid batch id
+ // 2. Region out of bound: x1|x2|y1|y2 < 0 || x1|x2 > inWidth || y1|y2 > inHeight
+ // 3. Invalid region: x2 <= x1 || y2 <= y1
+ NN_RET_CHECK_GE(batchId, 0);
+ NN_RET_CHECK_LT(batchId, numBatches);
+ NN_RET_CHECK(roiInfo[0] >= 0);
+ NN_RET_CHECK(roiInfo[1] >= 0);
+ NN_RET_CHECK(roiInfo[2] >= 0);
+ NN_RET_CHECK(roiInfo[3] >= 0);
+ NN_RET_CHECK(roiInfo[0] * spatialScale <= inWidth);
+ NN_RET_CHECK(roiInfo[1] * spatialScale <= inHeight);
+ NN_RET_CHECK(roiInfo[2] * spatialScale <= inWidth);
+ NN_RET_CHECK(roiInfo[3] * spatialScale <= inHeight);
+ NN_RET_CHECK(roiInfo[0] < roiInfo[2]);
+ NN_RET_CHECK(roiInfo[1] < roiInfo[3]);
+
+ int32_t wRoiStart = std::round(static_cast<float>(roiInfo[0] * spatialScale));
+ int32_t hRoiStart = std::round(static_cast<float>(roiInfo[1] * spatialScale));
+ int32_t wRoiEnd = std::round(static_cast<float>(roiInfo[2] * spatialScale));
+ int32_t hRoiEnd = std::round(static_cast<float>(roiInfo[3] * spatialScale));
// Rois with width/height < 1 are considered malformed and are forced to be 1
- float roiWidth = static_cast<float>(std::max(wRoiEnd - wRoiStart + 1, 1));
- float roiHeight = static_cast<float>(std::max(hRoiEnd - hRoiStart + 1, 1));
- float wStepSize = roiWidth / static_cast<float>(outWidth);
- float hStepSize = roiHeight / static_cast<float>(outHeight);
+ T_Roi roiWidth = static_cast<T_Roi>(std::max(wRoiEnd - wRoiStart + 1, 1));
+ T_Roi roiHeight = static_cast<T_Roi>(std::max(hRoiEnd - hRoiStart + 1, 1));
+ T_Roi wStepSize = roiWidth / static_cast<T_Roi>(outWidth);
+ T_Roi hStepSize = roiHeight / static_cast<T_Roi>(outHeight);
+ const T_Input* batchBase = inputData + batchId * inHeight * inWidth * inDepth;
for (uint32_t i = 0; i < outHeight; i++) {
for (uint32_t j = 0; j < outWidth; j++) {
// Take floor on start, ceil on end, start included, end excluded, i.e. [start, end)
// end is guaranteed to larger than start by at least 1
- uint32_t wStart = std::floor(wStepSize * j + wRoiStart);
- uint32_t wEnd = std::ceil(wStepSize * (j + 1) + wRoiStart);
- uint32_t hStart = std::floor(hStepSize * i + hRoiStart);
- uint32_t hEnd = std::ceil(hStepSize * (i + 1) + hRoiStart);
+ uint32_t wStart = std::floor(static_cast<float>(wStepSize * j + wRoiStart));
+ uint32_t wEnd = std::ceil(static_cast<float>(wStepSize * (j + 1) + wRoiStart));
+ uint32_t hStart = std::floor(static_cast<float>(hStepSize * i + hRoiStart));
+ uint32_t hEnd = std::ceil(static_cast<float>(hStepSize * (i + 1) + hRoiStart));
wStart = std::min(wStart, inWidth);
wEnd = std::min(wEnd, inWidth);
@@ -98,25 +131,117 @@
return true;
}
-bool roiPoolingGeneric(const uint8_t* inputData, const Shape& inputShape, const uint8_t* roiData,
- const Shape& roiShape, float spatialScale, uint8_t* outputData,
+template <typename T_Input, typename T_Roi>
+inline bool roiPooling(const T_Input* inputData, const Shape& inputShape, const T_Roi* roiData,
+ const Shape& roiShape, T_Roi spatialScale, bool useNchw, T_Input* outputData,
const Shape& outputShape) {
- NNTRACE_TRANS("roiPoolingGeneric");
- if (inputShape.type == OperandType::TENSOR_FLOAT32) {
- return roiPoolingImpl<float>(reinterpret_cast<const float*>(inputData), inputShape,
- reinterpret_cast<const float*>(roiData), roiShape,
- spatialScale, reinterpret_cast<float*>(outputData),
- outputShape);
- } else if (inputShape.type == OperandType::TENSOR_QUANT8_ASYMM) {
- return roiPoolingImpl<uint8_t>(reinterpret_cast<const uint8_t*>(inputData), inputShape,
- reinterpret_cast<const float*>(roiData), roiShape,
- spatialScale, reinterpret_cast<uint8_t*>(outputData),
- outputShape);
+ InputWithLayout<T_Input> input(useNchw);
+ OutputWithLayout<T_Input> output(useNchw);
+ NN_RET_CHECK(input.initialize(inputData, inputShape));
+ NN_RET_CHECK(output.initialize(outputData, outputShape));
+ NN_RET_CHECK(roiPoolingNhwc(input.getNhwcBuffer(), input.getNhwcShape(), roiData, roiShape,
+ spatialScale, output.getNhwcBuffer(), output.getNhwcShape()));
+ NN_RET_CHECK(output.commit());
+ return true;
+}
+
+} // namespace
+
+bool validate(const IOperationValidationContext* context) {
+ NN_RET_CHECK_EQ(context->getNumInputs(), kNumInputs);
+ NN_RET_CHECK_EQ(context->getNumOutputs(), kNumOutputs);
+ std::vector<OperandType> inExpectedTypes;
+ auto inputType = context->getInputType(kInputTensor);
+ if (inputType == OperandType::TENSOR_FLOAT32) {
+ inExpectedTypes = {OperandType::TENSOR_FLOAT32, OperandType::TENSOR_FLOAT32,
+ OperandType::TENSOR_INT32, OperandType::FLOAT32, OperandType::BOOL};
+ } else if (inputType == OperandType::TENSOR_FLOAT16) {
+ inExpectedTypes = {OperandType::TENSOR_FLOAT16, OperandType::TENSOR_FLOAT16,
+ OperandType::TENSOR_INT32, OperandType::FLOAT16, OperandType::BOOL};
+ } else if (inputType == OperandType::TENSOR_QUANT8_ASYMM) {
+ inExpectedTypes = {OperandType::TENSOR_QUANT8_ASYMM, OperandType::TENSOR_FLOAT32,
+ OperandType::TENSOR_INT32, OperandType::FLOAT32, OperandType::BOOL};
} else {
- LOG(ERROR) << "Unsupported data type";
+ LOG(ERROR) << "Unsupported input tensor type for operation " << kOperationName;
return false;
}
+ NN_RET_CHECK(validateInputTypes(context, inExpectedTypes));
+ NN_RET_CHECK(validateOutputTypes(context, {inputType}));
+ return validateHalVersion(context, HalVersion::V1_2);
}
+bool prepare(IOperationExecutionContext* context) {
+ bool useNchw = context->getInputValue<bool>(kLayoutScalar);
+ Shape input = context->getInputShape(kInputTensor);
+ Shape roiShape = context->getInputShape(kRoiTensor);
+ auto outputShapeData = context->getInputBuffer<int32_t>(kOutputShapeTensor);
+ Shape outputShapeShape = context->getInputShape(kOutputShapeTensor);
+
+ NN_RET_CHECK_EQ(getNumberOfDimensions(input), 4);
+ NN_RET_CHECK_EQ(getNumberOfDimensions(roiShape), 2);
+ NN_RET_CHECK_EQ(getNumberOfDimensions(outputShapeShape), 1);
+
+ uint32_t numBatches = getSizeOfDimension(input, 0);
+ uint32_t inHeight = getSizeOfDimension(input, useNchw ? 2 : 1);
+ uint32_t inWidth = getSizeOfDimension(input, useNchw ? 3 : 2);
+ uint32_t inDepth = getSizeOfDimension(input, useNchw ? 1 : 3);
+ uint32_t numRois = getSizeOfDimension(roiShape, 0);
+ uint32_t roiInfoLength = getSizeOfDimension(roiShape, 1);
+
+ const uint32_t kRoiDim = 4;
+ NN_RET_CHECK(roiInfoLength == (kRoiDim + 1) || (roiInfoLength == kRoiDim && numBatches == 1));
+ NN_RET_CHECK_EQ(getSizeOfDimension(outputShapeShape, 0), 2);
+
+ Shape output = context->getOutputShape(kOutputTensor);
+ output.type = input.type;
+ if (useNchw) {
+ output.dimensions = {numRois, inDepth, static_cast<uint32_t>(outputShapeData[0]),
+ static_cast<uint32_t>(outputShapeData[1])};
+ } else {
+ output.dimensions = {numRois, static_cast<uint32_t>(outputShapeData[0]),
+ static_cast<uint32_t>(outputShapeData[1]), inDepth};
+ }
+ return context->setOutputShape(kOutputTensor, output);
+}
+
+bool execute(IOperationExecutionContext* context) {
+ switch (context->getInputType(kInputTensor)) {
+ case OperandType::TENSOR_FLOAT16:
+ return roiPooling(context->getInputBuffer<_Float16>(kInputTensor),
+ context->getInputShape(kInputTensor),
+ context->getInputBuffer<_Float16>(kRoiTensor),
+ context->getInputShape(kRoiTensor),
+ context->getInputValue<_Float16>(kSpacialScaleScalar),
+ context->getInputValue<bool>(kLayoutScalar),
+ context->getOutputBuffer<_Float16>(kOutputTensor),
+ context->getOutputShape(kOutputTensor));
+ case OperandType::TENSOR_FLOAT32:
+ return roiPooling(context->getInputBuffer<float>(kInputTensor),
+ context->getInputShape(kInputTensor),
+ context->getInputBuffer<float>(kRoiTensor),
+ context->getInputShape(kRoiTensor),
+ context->getInputValue<float>(kSpacialScaleScalar),
+ context->getInputValue<bool>(kLayoutScalar),
+ context->getOutputBuffer<float>(kOutputTensor),
+ context->getOutputShape(kOutputTensor));
+ case OperandType::TENSOR_QUANT8_ASYMM:
+ return roiPooling(context->getInputBuffer<uint8_t>(kInputTensor),
+ context->getInputShape(kInputTensor),
+ context->getInputBuffer<float>(kRoiTensor),
+ context->getInputShape(kRoiTensor),
+ context->getInputValue<float>(kSpacialScaleScalar),
+ context->getInputValue<bool>(kLayoutScalar),
+ context->getOutputBuffer<uint8_t>(kOutputTensor),
+ context->getOutputShape(kOutputTensor));
+ default:
+ NN_RET_CHECK_FAIL() << "Unsupported tensor type for operation " << kOperationName;
+ }
+}
+
+} // namespace roi_pooling
+
+NN_REGISTER_OPERATION(ROI_POOLING, roi_pooling::kOperationName, roi_pooling::validate,
+ roi_pooling::prepare, roi_pooling::execute);
+
} // namespace nn
} // namespace android
diff --git a/runtime/include/NeuralNetworks.h b/runtime/include/NeuralNetworks.h
index e5debee..50ab0ae 100644
--- a/runtime/include/NeuralNetworks.h
+++ b/runtime/include/NeuralNetworks.h
@@ -3275,6 +3275,11 @@
* Rounding is applied in this operation to ensure integer boundary for
* regions of interest and pooling bins.
*
+ * Supported tensor {@link OperandCode}:
+ * * {@link ANEURALNETWORKS_TENSOR_FLOAT16}
+ * * {@link ANEURALNETWORKS_TENSOR_FLOAT32}
+ * * {@link ANEURALNETWORKS_TENSOR_QUANT8_ASYMM}
+ *
* Supported tensor rank: 4, with "NHWC" or "NCHW" data layout.
* With the default data layout NHWC, the data is stored in the order of:
* [batch, height, width, channels]. Alternatively, the data layout could
diff --git a/runtime/test/TestValidateOperations.cpp b/runtime/test/TestValidateOperations.cpp
index 0727fb7..c9231e4 100644
--- a/runtime/test/TestValidateOperations.cpp
+++ b/runtime/test/TestValidateOperations.cpp
@@ -1551,15 +1551,14 @@
roiAlignOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
}
-void roiPoolingOpTest(int32_t operandCode) {
+void roiPoolingOpTest(int32_t inputOperandCode, int32_t roiOperandCode, int32_t scalarOperandCode) {
uint32_t inDim[] = {1, 4, 4, 1}, roiDim[] = {4, 4}, outShapeDim[] = {2};
uint32_t outDim[] = {4, 2, 2, 1};
OperationTestBase roiPoolingTest(
ANEURALNETWORKS_ROI_POOLING,
- {getOpType(operandCode, 4, inDim), getOpType(ANEURALNETWORKS_TENSOR_FLOAT32, 2, roiDim),
- getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outShapeDim),
- getOpType(ANEURALNETWORKS_FLOAT32)},
- {getOpType(operandCode, 4, outDim)});
+ {getOpType(inputOperandCode, 4, inDim), getOpType(roiOperandCode, 2, roiDim),
+ getOpType(ANEURALNETWORKS_TENSOR_INT32, 1, outShapeDim), getOpType(scalarOperandCode)},
+ {getOpType(inputOperandCode, 4, outDim)});
EXPECT_TRUE(roiPoolingTest.testMutatingInputOperandCode());
EXPECT_TRUE(roiPoolingTest.testMutatingInputOperandCounts());
@@ -1567,12 +1566,19 @@
EXPECT_TRUE(roiPoolingTest.testMutatingOutputOperandCounts());
}
+TEST(OperationValidationTest, ROI_POOLING_float16) {
+ roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT16, ANEURALNETWORKS_TENSOR_FLOAT16,
+ ANEURALNETWORKS_FLOAT16);
+}
+
TEST(OperationValidationTest, ROI_POOLING_float32) {
- roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32);
+ roiPoolingOpTest(ANEURALNETWORKS_TENSOR_FLOAT32, ANEURALNETWORKS_TENSOR_FLOAT32,
+ ANEURALNETWORKS_FLOAT32);
}
TEST(OperationValidationTest, ROI_POOLING_quant8) {
- roiPoolingOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM);
+ roiPoolingOpTest(ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, ANEURALNETWORKS_TENSOR_FLOAT32,
+ ANEURALNETWORKS_FLOAT32);
}
void heatmapMaxKeypointOpTest(int32_t operandCode) {
diff --git a/runtime/test/generated/all_generated_V1_2_vts_tests.cpp b/runtime/test/generated/all_generated_V1_2_vts_tests.cpp
index fd00248..42bd10e 100644
--- a/runtime/test/generated/all_generated_V1_2_vts_tests.cpp
+++ b/runtime/test/generated/all_generated_V1_2_vts_tests.cpp
@@ -18417,6 +18417,21 @@
}
+TEST_F(NeuralnetworksHidlTest, roi_pooling_nhwc_float16) {
+ generated_tests::Execute(device,
+ roi_pooling::createTestModel_nhwc_float16,
+ roi_pooling::is_ignored_nhwc_float16,
+ roi_pooling::get_examples_nhwc_float16());
+}
+
+TEST_F(ValidationTest, roi_pooling_nhwc_float16) {
+ const Model model = roi_pooling::createTestModel_nhwc_float16();
+ const std::vector<Request> requests = createRequests(roi_pooling::get_examples_nhwc_float16());
+ validateModel(model);
+ validateRequests(model, requests);
+}
+
+
TEST_F(NeuralnetworksHidlTest, roi_pooling_nchw) {
generated_tests::Execute(device,
roi_pooling::createTestModel_nchw,
@@ -18462,6 +18477,21 @@
}
+TEST_F(NeuralnetworksHidlTest, roi_pooling_nchw_float16) {
+ generated_tests::Execute(device,
+ roi_pooling::createTestModel_nchw_float16,
+ roi_pooling::is_ignored_nchw_float16,
+ roi_pooling::get_examples_nchw_float16());
+}
+
+TEST_F(ValidationTest, roi_pooling_nchw_float16) {
+ const Model model = roi_pooling::createTestModel_nchw_float16();
+ const std::vector<Request> requests = createRequests(roi_pooling::get_examples_nchw_float16());
+ validateModel(model);
+ validateRequests(model, requests);
+}
+
+
TEST_F(NeuralnetworksHidlTest, roi_pooling_nhwc_2) {
generated_tests::Execute(device,
roi_pooling::createTestModel_nhwc_2,
@@ -18507,6 +18537,21 @@
}
+TEST_F(NeuralnetworksHidlTest, roi_pooling_nhwc_float16_2) {
+ generated_tests::Execute(device,
+ roi_pooling::createTestModel_nhwc_float16_2,
+ roi_pooling::is_ignored_nhwc_float16_2,
+ roi_pooling::get_examples_nhwc_float16_2());
+}
+
+TEST_F(ValidationTest, roi_pooling_nhwc_float16_2) {
+ const Model model = roi_pooling::createTestModel_nhwc_float16_2();
+ const std::vector<Request> requests = createRequests(roi_pooling::get_examples_nhwc_float16_2());
+ validateModel(model);
+ validateRequests(model, requests);
+}
+
+
TEST_F(NeuralnetworksHidlTest, roi_pooling_nchw_2) {
generated_tests::Execute(device,
roi_pooling::createTestModel_nchw_2,
@@ -18552,6 +18597,21 @@
}
+TEST_F(NeuralnetworksHidlTest, roi_pooling_nchw_float16_2) {
+ generated_tests::Execute(device,
+ roi_pooling::createTestModel_nchw_float16_2,
+ roi_pooling::is_ignored_nchw_float16_2,
+ roi_pooling::get_examples_nchw_float16_2());
+}
+
+TEST_F(ValidationTest, roi_pooling_nchw_float16_2) {
+ const Model model = roi_pooling::createTestModel_nchw_float16_2();
+ const std::vector<Request> requests = createRequests(roi_pooling::get_examples_nchw_float16_2());
+ validateModel(model);
+ validateRequests(model, requests);
+}
+
+
// Generated from: rotated_bbox_transform.mod.py.
namespace rotated_bbox_transform {
// Generated rotated_bbox_transform test
diff --git a/runtime/test/generated/examples/roi_pooling.example.cpp b/runtime/test/generated/examples/roi_pooling.example.cpp
index 41bd833..6de4cf5 100644
--- a/runtime/test/generated/examples/roi_pooling.example.cpp
+++ b/runtime/test/generated/examples/roi_pooling.example.cpp
@@ -123,6 +123,47 @@
return examples_nhwc_quant8;
};
+std::vector<MixedTypedExample>& get_examples_nhwc_float16() {
+static std::vector<MixedTypedExample> examples_nhwc_float16 = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {-10.0f, -1.0f, 4.0f, -5.0f, -8.0f, -2.0f, 9.0f, 1.0f, 7.0f, -2.0f, 3.0f, -7.0f, -2.0f, 10.0f, -3.0f, 5.0f}}, {1, {2.0f, 2.0f, 4.0f, 4.0f, 0.0f, 0.0f, 6.0f, 6.0f, 2.0f, 0.0f, 4.0f, 6.0f, 0.0f, 2.0f, 6.0f, 4.0f}}},
+ // int -> BOOL8 map
+ {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {-2.0f, 9.0f, -2.0f, 3.0f, -1.0f, 9.0f, 10.0f, 5.0f, -1.0f, 9.0f, 10.0f, 3.0f, -2.0f, 9.0f, 7.0f, 3.0f}}},
+ // int -> BOOL8 map
+ {},
+}
+},
+}, // End of an example
+};
+return examples_nhwc_float16;
+};
+
std::vector<MixedTypedExample>& get_examples_nchw() {
static std::vector<MixedTypedExample> examples_nchw = {
// Begin of an example
@@ -246,6 +287,47 @@
return examples_nchw_quant8;
};
+std::vector<MixedTypedExample>& get_examples_nchw_float16() {
+static std::vector<MixedTypedExample> examples_nchw_float16 = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {-10.0f, -1.0f, 4.0f, -5.0f, -8.0f, -2.0f, 9.0f, 1.0f, 7.0f, -2.0f, 3.0f, -7.0f, -2.0f, 10.0f, -3.0f, 5.0f}}, {1, {2.0f, 2.0f, 4.0f, 4.0f, 0.0f, 0.0f, 6.0f, 6.0f, 2.0f, 0.0f, 4.0f, 6.0f, 0.0f, 2.0f, 6.0f, 4.0f}}},
+ // int -> BOOL8 map
+ {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {-2.0f, 9.0f, -2.0f, 3.0f, -1.0f, 9.0f, 10.0f, 5.0f, -1.0f, 9.0f, 10.0f, 3.0f, -2.0f, 9.0f, 7.0f, 3.0f}}},
+ // int -> BOOL8 map
+ {},
+}
+},
+}, // End of an example
+};
+return examples_nchw_float16;
+};
+
std::vector<MixedTypedExample>& get_examples_nhwc_2() {
static std::vector<MixedTypedExample> examples_nhwc_2 = {
// Begin of an example
@@ -369,6 +451,47 @@
return examples_nhwc_quant8_2;
};
+std::vector<MixedTypedExample>& get_examples_nhwc_float16_2() {
+static std::vector<MixedTypedExample> examples_nhwc_float16_2 = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {8.84000015258789f, 8.880000114440918f, 7.409999847412109f, 5.599999904632568f, 9.949999809265137f, 4.369999885559082f, 0.10000000149011612f, 7.639999866485596f, 6.5f, 9.470000267028809f, 7.550000190734863f, 3.0f, 0.8899999856948853f, 3.009999990463257f, 6.300000190734863f, 4.400000095367432f, 1.6399999856948853f, 6.739999771118164f, 6.159999847412109f, 8.600000381469727f, 5.849999904632568f, 3.1700000762939453f, 7.119999885559082f, 6.789999961853027f, 5.769999980926514f, 6.619999885559082f, 5.130000114440918f, 8.4399995803833f, 5.079999923706055f, 7.119999885559082f, 2.8399999141693115f, 1.190000057220459f, 8.369999885559082f, 0.8999999761581421f, 7.860000133514404f, 9.6899995803833f, 1.9700000286102295f, 1.309999942779541f, 4.420000076293945f, 9.890000343322754f, 0.18000000715255737f, 9.0f, 9.300000190734863f, 0.4399999976158142f, 5.050000190734863f, 6.46999979019165f, 1.090000033378601f, 9.5f, 1.2999999523162842f, 2.180000066757202f, 2.049999952316284f, 7.739999771118164f, 7.659999847412109f, 0.6499999761581421f, 4.179999828338623f, 7.139999866485596f, 5.349999904632568f, 7.900000095367432f, 1.0399999618530273f, 1.4700000286102295f, 9.010000228881836f, 0.949999988079071f, 4.070000171661377f, 0.6499999761581421f, 5.46999979019165f, 2.640000104904175f, 0.8600000143051147f, 4.860000133514404f, 2.380000114440918f, 2.450000047683716f, 8.770000457763672f, 0.05999999865889549f, 3.5999999046325684f, 9.279999732971191f, 5.840000152587891f, 8.970000267028809f, 6.889999866485596f, 1.4299999475479126f, 3.9000000953674316f, 5.909999847412109f, 7.400000095367432f, 9.25f, 3.119999885559082f, 4.920000076293945f, 1.8700000047683716f, 3.2200000286102295f, 9.5f, 6.730000019073486f, 2.069999933242798f, 7.300000190734863f, 3.069999933242798f, 4.96999979019165f, 0.23999999463558197f, 8.90999984741211f, 1.090000033378601f, 0.27000001072883606f, 7.289999961853027f, 6.940000057220459f, 2.309999942779541f, 6.880000114440918f, 4.329999923706055f, 1.3700000047683716f, 0.8600000143051147f, 0.46000000834465027f, 6.070000171661377f, 3.809999942779541f, 0.8600000143051147f, 6.989999771118164f, 4.360000133514404f, 1.9199999570846558f, 8.1899995803833f, 3.569999933242798f, 7.900000095367432f, 6.78000020980835f, 4.639999866485596f, 6.820000171661377f, 6.179999828338623f, 9.630000114440918f, 2.630000114440918f, 2.3299999237060547f, 1.3600000143051147f, 2.700000047683716f, 9.989999771118164f, 9.850000381469727f, 8.0600004196167f, 4.800000190734863f, 7.800000190734863f, 5.429999828338623f}}, {1, {0.0f, 4.0f, 4.0f, 24.0f, 8.0f, 0.0f, 4.0f, 4.0f, 28.0f, 12.0f, 1.0f, 7.0f, 1.0f, 25.0f, 11.0f, 1.0f, 1.0f, 7.0f, 5.0f, 11.0f}}},
+ // int -> BOOL8 map
+ {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {6.159999847412109f, 8.600000381469727f, 7.119999885559082f, 6.789999961853027f, 5.130000114440918f, 8.4399995803833f, 7.860000133514404f, 9.6899995803833f, 4.420000076293945f, 9.890000343322754f, 9.300000190734863f, 6.46999979019165f, 7.860000133514404f, 9.890000343322754f, 9.300000190734863f, 9.890000343322754f, 9.300000190734863f, 9.5f, 7.860000133514404f, 9.890000343322754f, 9.300000190734863f, 9.890000343322754f, 9.300000190734863f, 9.5f, 9.5f, 6.730000019073486f, 9.5f, 9.279999732971191f, 6.889999866485596f, 8.970000267028809f, 6.179999828338623f, 9.630000114440918f, 9.989999771118164f, 9.850000381469727f, 9.989999771118164f, 9.850000381469727f, 7.289999961853027f, 6.940000057220459f, 7.289999961853027f, 6.940000057220459f, 2.309999942779541f, 6.880000114440918f, 7.900000095367432f, 6.78000020980835f, 7.900000095367432f, 6.820000171661377f, 4.639999866485596f, 6.820000171661377f}}},
+ // int -> BOOL8 map
+ {},
+}
+},
+}, // End of an example
+};
+return examples_nhwc_float16_2;
+};
+
std::vector<MixedTypedExample>& get_examples_nchw_2() {
static std::vector<MixedTypedExample> examples_nchw_2 = {
// Begin of an example
@@ -492,3 +615,44 @@
return examples_nchw_quant8_2;
};
+std::vector<MixedTypedExample>& get_examples_nchw_float16_2() {
+static std::vector<MixedTypedExample> examples_nchw_float16_2 = {
+// Begin of an example
+{
+.operands = {
+//Input(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {8.84000015258789f, 7.409999847412109f, 9.949999809265137f, 0.10000000149011612f, 6.5f, 7.550000190734863f, 0.8899999856948853f, 6.300000190734863f, 1.6399999856948853f, 6.159999847412109f, 5.849999904632568f, 7.119999885559082f, 5.769999980926514f, 5.130000114440918f, 5.079999923706055f, 2.8399999141693115f, 8.369999885559082f, 7.860000133514404f, 1.9700000286102295f, 4.420000076293945f, 0.18000000715255737f, 9.300000190734863f, 5.050000190734863f, 1.090000033378601f, 1.2999999523162842f, 2.049999952316284f, 7.659999847412109f, 4.179999828338623f, 5.349999904632568f, 1.0399999618530273f, 9.010000228881836f, 4.070000171661377f, 8.880000114440918f, 5.599999904632568f, 4.369999885559082f, 7.639999866485596f, 9.470000267028809f, 3.0f, 3.009999990463257f, 4.400000095367432f, 6.739999771118164f, 8.600000381469727f, 3.1700000762939453f, 6.789999961853027f, 6.619999885559082f, 8.4399995803833f, 7.119999885559082f, 1.190000057220459f, 0.8999999761581421f, 9.6899995803833f, 1.309999942779541f, 9.890000343322754f, 9.0f, 0.4399999976158142f, 6.46999979019165f, 9.5f, 2.180000066757202f, 7.739999771118164f, 0.6499999761581421f, 7.139999866485596f, 7.900000095367432f, 1.4700000286102295f, 0.949999988079071f, 0.6499999761581421f, 5.46999979019165f, 0.8600000143051147f, 2.380000114440918f, 8.770000457763672f, 3.5999999046325684f, 5.840000152587891f, 6.889999866485596f, 3.9000000953674316f, 7.400000095367432f, 3.119999885559082f, 1.8700000047683716f, 9.5f, 2.069999933242798f, 3.069999933242798f, 0.23999999463558197f, 1.090000033378601f, 7.289999961853027f, 2.309999942779541f, 4.329999923706055f, 0.8600000143051147f, 6.070000171661377f, 0.8600000143051147f, 4.360000133514404f, 8.1899995803833f, 7.900000095367432f, 4.639999866485596f, 6.179999828338623f, 2.630000114440918f, 1.3600000143051147f, 9.989999771118164f, 8.0600004196167f, 7.800000190734863f, 2.640000104904175f, 4.860000133514404f, 2.450000047683716f, 0.05999999865889549f, 9.279999732971191f, 8.970000267028809f, 1.4299999475479126f, 5.909999847412109f, 9.25f, 4.920000076293945f, 3.2200000286102295f, 6.730000019073486f, 7.300000190734863f, 4.96999979019165f, 8.90999984741211f, 0.27000001072883606f, 6.940000057220459f, 6.880000114440918f, 1.3700000047683716f, 0.46000000834465027f, 3.809999942779541f, 6.989999771118164f, 1.9199999570846558f, 3.569999933242798f, 6.78000020980835f, 6.820000171661377f, 9.630000114440918f, 2.3299999237060547f, 2.700000047683716f, 9.850000381469727f, 4.800000190734863f, 5.429999828338623f}}, {1, {0.0f, 4.0f, 4.0f, 24.0f, 8.0f, 0.0f, 4.0f, 4.0f, 28.0f, 12.0f, 1.0f, 7.0f, 1.0f, 25.0f, 11.0f, 1.0f, 1.0f, 7.0f, 5.0f, 11.0f}}},
+ // int -> BOOL8 map
+ {},
+},
+//Output(s)
+{ // See tools/test_generator/include/TestHarness.h:MixedTyped
+ // int -> FLOAT32 map
+ {},
+ // int -> INT32 map
+ {},
+ // int -> QUANT8_ASYMM map
+ {},
+ // int -> QUANT16_SYMM map
+ {},
+ // int -> FLOAT16 map
+ {{0, {6.159999847412109f, 7.119999885559082f, 5.130000114440918f, 7.860000133514404f, 4.420000076293945f, 9.300000190734863f, 8.600000381469727f, 6.789999961853027f, 8.4399995803833f, 9.6899995803833f, 9.890000343322754f, 6.46999979019165f, 7.860000133514404f, 9.300000190734863f, 9.300000190734863f, 7.860000133514404f, 9.300000190734863f, 9.300000190734863f, 9.890000343322754f, 9.890000343322754f, 9.5f, 9.890000343322754f, 9.890000343322754f, 9.5f, 9.5f, 9.5f, 6.889999866485596f, 6.179999828338623f, 9.989999771118164f, 9.989999771118164f, 6.730000019073486f, 9.279999732971191f, 8.970000267028809f, 9.630000114440918f, 9.850000381469727f, 9.850000381469727f, 7.289999961853027f, 7.289999961853027f, 2.309999942779541f, 7.900000095367432f, 7.900000095367432f, 4.639999866485596f, 6.940000057220459f, 6.940000057220459f, 6.880000114440918f, 6.78000020980835f, 6.820000171661377f, 6.820000171661377f}}},
+ // int -> BOOL8 map
+ {},
+}
+},
+}, // End of an example
+};
+return examples_nchw_float16_2;
+};
+
diff --git a/runtime/test/generated/models/roi_pooling.model.cpp b/runtime/test/generated/models/roi_pooling.model.cpp
index 6776185..895238c 100644
--- a/runtime/test/generated/models/roi_pooling.model.cpp
+++ b/runtime/test/generated/models/roi_pooling.model.cpp
@@ -104,20 +104,54 @@
return ignore.find(i) != ignore.end();
}
+void CreateModel_nhwc_float16(Model *model) {
+ OperandType type0(Type::BOOL, {});
+ OperandType type11(Type::TENSOR_FLOAT16, {1, 4, 4, 1});
+ OperandType type12(Type::TENSOR_FLOAT16, {4, 2, 2, 1});
+ OperandType type13(Type::FLOAT16, {});
+ OperandType type14(Type::TENSOR_FLOAT16, {4, 4});
+ OperandType type4(Type::TENSOR_INT32, {2});
+ // Phase 1, operands
+ auto in = model->addOperand(&type11);
+ auto roi = model->addOperand(&type14);
+ auto param = model->addOperand(&type4);
+ auto param1 = model->addOperand(&type13);
+ auto layout = model->addOperand(&type0);
+ auto out = model->addOperand(&type12);
+ // Phase 2, operations
+ static int32_t param_init[] = {2, 2};
+ model->setOperandValue(param, param_init, sizeof(int32_t) * 2);
+ static _Float16 param1_init[] = {0.5f};
+ model->setOperandValue(param1, param1_init, sizeof(_Float16) * 1);
+ static bool8 layout_init[] = {false};
+ model->setOperandValue(layout, layout_init, sizeof(bool8) * 1);
+ model->addOperation(ANEURALNETWORKS_ROI_POOLING, {in, roi, param, param1, layout}, {out});
+ // Phase 3, inputs and outputs
+ model->identifyInputsAndOutputs(
+ {in, roi},
+ {out});
+ assert(model->isValid());
+}
+
+inline bool is_ignored_nhwc_float16(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
void CreateModel_nchw(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type11(Type::TENSOR_FLOAT32, {1, 1, 4, 4});
- OperandType type12(Type::TENSOR_FLOAT32, {4, 1, 2, 2});
+ OperandType type15(Type::TENSOR_FLOAT32, {1, 1, 4, 4});
+ OperandType type16(Type::TENSOR_FLOAT32, {4, 1, 2, 2});
OperandType type2(Type::TENSOR_FLOAT32, {4, 4});
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
// Phase 1, operands
- auto in = model->addOperand(&type11);
+ auto in = model->addOperand(&type15);
auto roi = model->addOperand(&type2);
auto param = model->addOperand(&type4);
auto param1 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out = model->addOperand(&type12);
+ auto out = model->addOperand(&type16);
// Phase 2, operations
static int32_t param_init[] = {2, 2};
model->setOperandValue(param, param_init, sizeof(int32_t) * 2);
@@ -140,18 +174,18 @@
void CreateModel_nchw_relaxed(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type11(Type::TENSOR_FLOAT32, {1, 1, 4, 4});
- OperandType type12(Type::TENSOR_FLOAT32, {4, 1, 2, 2});
+ OperandType type15(Type::TENSOR_FLOAT32, {1, 1, 4, 4});
+ OperandType type16(Type::TENSOR_FLOAT32, {4, 1, 2, 2});
OperandType type2(Type::TENSOR_FLOAT32, {4, 4});
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
// Phase 1, operands
- auto in = model->addOperand(&type11);
+ auto in = model->addOperand(&type15);
auto roi = model->addOperand(&type2);
auto param = model->addOperand(&type4);
auto param1 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out = model->addOperand(&type12);
+ auto out = model->addOperand(&type16);
// Phase 2, operations
static int32_t param_init[] = {2, 2};
model->setOperandValue(param, param_init, sizeof(int32_t) * 2);
@@ -176,18 +210,18 @@
void CreateModel_nchw_quant8(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type13(Type::TENSOR_QUANT8_ASYMM, {1, 1, 4, 4}, 0.25f, 128);
- OperandType type14(Type::TENSOR_QUANT8_ASYMM, {4, 1, 2, 2}, 0.25f, 128);
+ OperandType type17(Type::TENSOR_QUANT8_ASYMM, {1, 1, 4, 4}, 0.25f, 128);
+ OperandType type18(Type::TENSOR_QUANT8_ASYMM, {4, 1, 2, 2}, 0.25f, 128);
OperandType type2(Type::TENSOR_FLOAT32, {4, 4});
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
// Phase 1, operands
- auto in = model->addOperand(&type13);
+ auto in = model->addOperand(&type17);
auto roi = model->addOperand(&type2);
auto param = model->addOperand(&type4);
auto param1 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out = model->addOperand(&type14);
+ auto out = model->addOperand(&type18);
// Phase 2, operations
static int32_t param_init[] = {2, 2};
model->setOperandValue(param, param_init, sizeof(int32_t) * 2);
@@ -208,6 +242,40 @@
return ignore.find(i) != ignore.end();
}
+void CreateModel_nchw_float16(Model *model) {
+ OperandType type0(Type::BOOL, {});
+ OperandType type13(Type::FLOAT16, {});
+ OperandType type14(Type::TENSOR_FLOAT16, {4, 4});
+ OperandType type19(Type::TENSOR_FLOAT16, {1, 1, 4, 4});
+ OperandType type20(Type::TENSOR_FLOAT16, {4, 1, 2, 2});
+ OperandType type4(Type::TENSOR_INT32, {2});
+ // Phase 1, operands
+ auto in = model->addOperand(&type19);
+ auto roi = model->addOperand(&type14);
+ auto param = model->addOperand(&type4);
+ auto param1 = model->addOperand(&type13);
+ auto layout = model->addOperand(&type0);
+ auto out = model->addOperand(&type20);
+ // Phase 2, operations
+ static int32_t param_init[] = {2, 2};
+ model->setOperandValue(param, param_init, sizeof(int32_t) * 2);
+ static _Float16 param1_init[] = {0.5f};
+ model->setOperandValue(param1, param1_init, sizeof(_Float16) * 1);
+ static bool8 layout_init[] = {true};
+ model->setOperandValue(layout, layout_init, sizeof(bool8) * 1);
+ model->addOperation(ANEURALNETWORKS_ROI_POOLING, {in, roi, param, param1, layout}, {out});
+ // Phase 3, inputs and outputs
+ model->identifyInputsAndOutputs(
+ {in, roi},
+ {out});
+ assert(model->isValid());
+}
+
+inline bool is_ignored_nchw_float16(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
void CreateModel_nhwc_2(Model *model) {
OperandType type0(Type::BOOL, {});
OperandType type4(Type::TENSOR_INT32, {2});
@@ -280,18 +348,18 @@
void CreateModel_nhwc_quant8_2(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type15(Type::TENSOR_QUANT8_ASYMM, {2, 4, 8, 2}, 0.04f, 0);
- OperandType type16(Type::TENSOR_QUANT8_ASYMM, {4, 2, 3, 2}, 0.04f, 0);
+ OperandType type21(Type::TENSOR_QUANT8_ASYMM, {2, 4, 8, 2}, 0.04f, 0);
+ OperandType type22(Type::TENSOR_QUANT8_ASYMM, {4, 2, 3, 2}, 0.04f, 0);
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
OperandType type7(Type::TENSOR_FLOAT32, {4, 5});
// Phase 1, operands
- auto in1 = model->addOperand(&type15);
+ auto in1 = model->addOperand(&type21);
auto roi1 = model->addOperand(&type7);
auto param2 = model->addOperand(&type4);
auto param3 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out1 = model->addOperand(&type16);
+ auto out1 = model->addOperand(&type22);
// Phase 2, operations
static int32_t param2_init[] = {2, 3};
model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
@@ -312,20 +380,54 @@
return ignore.find(i) != ignore.end();
}
+void CreateModel_nhwc_float16_2(Model *model) {
+ OperandType type0(Type::BOOL, {});
+ OperandType type13(Type::FLOAT16, {});
+ OperandType type23(Type::TENSOR_FLOAT16, {2, 4, 8, 2});
+ OperandType type24(Type::TENSOR_FLOAT16, {4, 2, 3, 2});
+ OperandType type25(Type::TENSOR_FLOAT16, {4, 5});
+ OperandType type4(Type::TENSOR_INT32, {2});
+ // Phase 1, operands
+ auto in1 = model->addOperand(&type23);
+ auto roi1 = model->addOperand(&type25);
+ auto param2 = model->addOperand(&type4);
+ auto param3 = model->addOperand(&type13);
+ auto layout = model->addOperand(&type0);
+ auto out1 = model->addOperand(&type24);
+ // Phase 2, operations
+ static int32_t param2_init[] = {2, 3};
+ model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
+ static _Float16 param3_init[] = {0.25f};
+ model->setOperandValue(param3, param3_init, sizeof(_Float16) * 1);
+ static bool8 layout_init[] = {false};
+ model->setOperandValue(layout, layout_init, sizeof(bool8) * 1);
+ model->addOperation(ANEURALNETWORKS_ROI_POOLING, {in1, roi1, param2, param3, layout}, {out1});
+ // Phase 3, inputs and outputs
+ model->identifyInputsAndOutputs(
+ {in1, roi1},
+ {out1});
+ assert(model->isValid());
+}
+
+inline bool is_ignored_nhwc_float16_2(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
void CreateModel_nchw_2(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type17(Type::TENSOR_FLOAT32, {2, 2, 4, 8});
- OperandType type18(Type::TENSOR_FLOAT32, {4, 2, 2, 3});
+ OperandType type26(Type::TENSOR_FLOAT32, {2, 2, 4, 8});
+ OperandType type27(Type::TENSOR_FLOAT32, {4, 2, 2, 3});
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
OperandType type7(Type::TENSOR_FLOAT32, {4, 5});
// Phase 1, operands
- auto in1 = model->addOperand(&type17);
+ auto in1 = model->addOperand(&type26);
auto roi1 = model->addOperand(&type7);
auto param2 = model->addOperand(&type4);
auto param3 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out1 = model->addOperand(&type18);
+ auto out1 = model->addOperand(&type27);
// Phase 2, operations
static int32_t param2_init[] = {2, 3};
model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
@@ -348,18 +450,18 @@
void CreateModel_nchw_relaxed_2(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type17(Type::TENSOR_FLOAT32, {2, 2, 4, 8});
- OperandType type18(Type::TENSOR_FLOAT32, {4, 2, 2, 3});
+ OperandType type26(Type::TENSOR_FLOAT32, {2, 2, 4, 8});
+ OperandType type27(Type::TENSOR_FLOAT32, {4, 2, 2, 3});
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
OperandType type7(Type::TENSOR_FLOAT32, {4, 5});
// Phase 1, operands
- auto in1 = model->addOperand(&type17);
+ auto in1 = model->addOperand(&type26);
auto roi1 = model->addOperand(&type7);
auto param2 = model->addOperand(&type4);
auto param3 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out1 = model->addOperand(&type18);
+ auto out1 = model->addOperand(&type27);
// Phase 2, operations
static int32_t param2_init[] = {2, 3};
model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
@@ -384,18 +486,18 @@
void CreateModel_nchw_quant8_2(Model *model) {
OperandType type0(Type::BOOL, {});
- OperandType type19(Type::TENSOR_QUANT8_ASYMM, {2, 2, 4, 8}, 0.04f, 0);
- OperandType type20(Type::TENSOR_QUANT8_ASYMM, {4, 2, 2, 3}, 0.04f, 0);
+ OperandType type28(Type::TENSOR_QUANT8_ASYMM, {2, 2, 4, 8}, 0.04f, 0);
+ OperandType type29(Type::TENSOR_QUANT8_ASYMM, {4, 2, 2, 3}, 0.04f, 0);
OperandType type4(Type::TENSOR_INT32, {2});
OperandType type5(Type::FLOAT32, {});
OperandType type7(Type::TENSOR_FLOAT32, {4, 5});
// Phase 1, operands
- auto in1 = model->addOperand(&type19);
+ auto in1 = model->addOperand(&type28);
auto roi1 = model->addOperand(&type7);
auto param2 = model->addOperand(&type4);
auto param3 = model->addOperand(&type5);
auto layout = model->addOperand(&type0);
- auto out1 = model->addOperand(&type20);
+ auto out1 = model->addOperand(&type29);
// Phase 2, operations
static int32_t param2_init[] = {2, 3};
model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
@@ -416,3 +518,37 @@
return ignore.find(i) != ignore.end();
}
+void CreateModel_nchw_float16_2(Model *model) {
+ OperandType type0(Type::BOOL, {});
+ OperandType type13(Type::FLOAT16, {});
+ OperandType type25(Type::TENSOR_FLOAT16, {4, 5});
+ OperandType type30(Type::TENSOR_FLOAT16, {2, 2, 4, 8});
+ OperandType type31(Type::TENSOR_FLOAT16, {4, 2, 2, 3});
+ OperandType type4(Type::TENSOR_INT32, {2});
+ // Phase 1, operands
+ auto in1 = model->addOperand(&type30);
+ auto roi1 = model->addOperand(&type25);
+ auto param2 = model->addOperand(&type4);
+ auto param3 = model->addOperand(&type13);
+ auto layout = model->addOperand(&type0);
+ auto out1 = model->addOperand(&type31);
+ // Phase 2, operations
+ static int32_t param2_init[] = {2, 3};
+ model->setOperandValue(param2, param2_init, sizeof(int32_t) * 2);
+ static _Float16 param3_init[] = {0.25f};
+ model->setOperandValue(param3, param3_init, sizeof(_Float16) * 1);
+ static bool8 layout_init[] = {true};
+ model->setOperandValue(layout, layout_init, sizeof(bool8) * 1);
+ model->addOperation(ANEURALNETWORKS_ROI_POOLING, {in1, roi1, param2, param3, layout}, {out1});
+ // Phase 3, inputs and outputs
+ model->identifyInputsAndOutputs(
+ {in1, roi1},
+ {out1});
+ assert(model->isValid());
+}
+
+inline bool is_ignored_nchw_float16_2(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
diff --git a/runtime/test/generated/tests/roi_pooling.mod.py.cpp b/runtime/test/generated/tests/roi_pooling.mod.py.cpp
index 923e9ea..80a02a9 100644
--- a/runtime/test/generated/tests/roi_pooling.mod.py.cpp
+++ b/runtime/test/generated/tests/roi_pooling.mod.py.cpp
@@ -27,6 +27,12 @@
roi_pooling::get_examples_nhwc_quant8());
}
+TEST_F(GeneratedTests, roi_pooling_nhwc_float16) {
+ execute(roi_pooling::CreateModel_nhwc_float16,
+ roi_pooling::is_ignored_nhwc_float16,
+ roi_pooling::get_examples_nhwc_float16());
+}
+
TEST_F(GeneratedTests, roi_pooling_nchw) {
execute(roi_pooling::CreateModel_nchw,
roi_pooling::is_ignored_nchw,
@@ -45,6 +51,12 @@
roi_pooling::get_examples_nchw_quant8());
}
+TEST_F(GeneratedTests, roi_pooling_nchw_float16) {
+ execute(roi_pooling::CreateModel_nchw_float16,
+ roi_pooling::is_ignored_nchw_float16,
+ roi_pooling::get_examples_nchw_float16());
+}
+
TEST_F(GeneratedTests, roi_pooling_nhwc_2) {
execute(roi_pooling::CreateModel_nhwc_2,
roi_pooling::is_ignored_nhwc_2,
@@ -63,6 +75,12 @@
roi_pooling::get_examples_nhwc_quant8_2());
}
+TEST_F(GeneratedTests, roi_pooling_nhwc_float16_2) {
+ execute(roi_pooling::CreateModel_nhwc_float16_2,
+ roi_pooling::is_ignored_nhwc_float16_2,
+ roi_pooling::get_examples_nhwc_float16_2());
+}
+
TEST_F(GeneratedTests, roi_pooling_nchw_2) {
execute(roi_pooling::CreateModel_nchw_2,
roi_pooling::is_ignored_nchw_2,
@@ -81,3 +99,9 @@
roi_pooling::get_examples_nchw_quant8_2());
}
+TEST_F(GeneratedTests, roi_pooling_nchw_float16_2) {
+ execute(roi_pooling::CreateModel_nchw_float16_2,
+ roi_pooling::is_ignored_nchw_float16_2,
+ roi_pooling::get_examples_nchw_float16_2());
+}
+
diff --git a/runtime/test/generated/vts_models/roi_pooling.model.cpp b/runtime/test/generated/vts_models/roi_pooling.model.cpp
index cec26cc..55dbdcf 100644
--- a/runtime/test/generated/vts_models/roi_pooling.model.cpp
+++ b/runtime/test/generated/vts_models/roi_pooling.model.cpp
@@ -269,6 +269,95 @@
}
// Create the model
+Model createTestModel_nhwc_float16() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {1, 4, 4, 1},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 4},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::FLOAT16,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 2},
+ },
+ {
+ .type = OperandType::BOOL,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 10, .length = 1},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 2, 2, 1},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::ROI_POOLING,
+ .inputs = {0, 1, 2, 3, 4},
+ .outputs = {5},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0, 1};
+ const std::vector<uint32_t> outputIndexes = {5};
+ std::vector<uint8_t> operandValues = {
+ 2, 0, 0, 0, 2, 0, 0, 0, 0, 56, 0
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored_nhwc_float16(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
+// Create the model
Model createTestModel_nchw() {
const std::vector<Operand> operands = {
{
@@ -537,6 +626,95 @@
}
// Create the model
+Model createTestModel_nchw_float16() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {1, 1, 4, 4},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 4},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::FLOAT16,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 2},
+ },
+ {
+ .type = OperandType::BOOL,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 10, .length = 1},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 1, 2, 2},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::ROI_POOLING,
+ .inputs = {0, 1, 2, 3, 4},
+ .outputs = {5},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0, 1};
+ const std::vector<uint32_t> outputIndexes = {5};
+ std::vector<uint8_t> operandValues = {
+ 2, 0, 0, 0, 2, 0, 0, 0, 0, 56, 1
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored_nchw_float16(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
+// Create the model
Model createTestModel_nhwc_2() {
const std::vector<Operand> operands = {
{
@@ -805,6 +983,95 @@
}
// Create the model
+Model createTestModel_nhwc_float16_2() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {2, 4, 8, 2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 5},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::FLOAT16,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 2},
+ },
+ {
+ .type = OperandType::BOOL,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 10, .length = 1},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 2, 3, 2},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::ROI_POOLING,
+ .inputs = {0, 1, 2, 3, 4},
+ .outputs = {5},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0, 1};
+ const std::vector<uint32_t> outputIndexes = {5};
+ std::vector<uint8_t> operandValues = {
+ 2, 0, 0, 0, 3, 0, 0, 0, 0, 52, 0
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored_nhwc_float16_2(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
+// Create the model
Model createTestModel_nchw_2() {
const std::vector<Operand> operands = {
{
@@ -1072,3 +1339,92 @@
return ignore.find(i) != ignore.end();
}
+// Create the model
+Model createTestModel_nchw_float16_2() {
+ const std::vector<Operand> operands = {
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {2, 2, 4, 8},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 5},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_INPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ },
+ {
+ .type = OperandType::TENSOR_INT32,
+ .dimensions = {2},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 0, .length = 8},
+ },
+ {
+ .type = OperandType::FLOAT16,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 8, .length = 2},
+ },
+ {
+ .type = OperandType::BOOL,
+ .dimensions = {},
+ .numberOfConsumers = 1,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::CONSTANT_COPY,
+ .location = {.poolIndex = 0, .offset = 10, .length = 1},
+ },
+ {
+ .type = OperandType::TENSOR_FLOAT16,
+ .dimensions = {4, 2, 2, 3},
+ .numberOfConsumers = 0,
+ .scale = 0.0f,
+ .zeroPoint = 0,
+ .lifetime = OperandLifeTime::MODEL_OUTPUT,
+ .location = {.poolIndex = 0, .offset = 0, .length = 0},
+ }
+ };
+
+ const std::vector<Operation> operations = {
+ {
+ .type = OperationType::ROI_POOLING,
+ .inputs = {0, 1, 2, 3, 4},
+ .outputs = {5},
+ }
+ };
+
+ const std::vector<uint32_t> inputIndexes = {0, 1};
+ const std::vector<uint32_t> outputIndexes = {5};
+ std::vector<uint8_t> operandValues = {
+ 2, 0, 0, 0, 3, 0, 0, 0, 0, 52, 1
+ };
+ const std::vector<hidl_memory> pools = {};
+
+ return {
+ .operands = operands,
+ .operations = operations,
+ .inputIndexes = inputIndexes,
+ .outputIndexes = outputIndexes,
+ .operandValues = operandValues,
+ .pools = pools,
+ };
+}
+
+inline bool is_ignored_nchw_float16_2(int i) {
+ static std::set<int> ignore = {};
+ return ignore.find(i) != ignore.end();
+}
+
diff --git a/runtime/test/specs/V1_2/roi_pooling.mod.py b/runtime/test/specs/V1_2/roi_pooling.mod.py
index 243bb76..af8cb88 100644
--- a/runtime/test/specs/V1_2/roi_pooling.mod.py
+++ b/runtime/test/specs/V1_2/roi_pooling.mod.py
@@ -47,7 +47,7 @@
-1, 9, 10, 3,
-2, 9, 7, 3
]
-}).AddNchw(i1, o1, layout).AddVariations("relaxed", quant8)
+}).AddNchw(i1, o1, layout).AddVariations("relaxed", quant8, "float16")
# TEST 2: ROI_ALIGN_2, outputShape = [2, 3], spatialScale = 0.25, samplingRatio = 4
@@ -91,4 +91,4 @@
9.50, 6.73, 9.50, 9.28, 6.89, 8.97, 6.18, 9.63, 9.99, 9.85, 9.99, 9.85,
7.29, 6.94, 7.29, 6.94, 2.31, 6.88, 7.90, 6.78, 7.90, 6.82, 4.64, 6.82
]
-}).AddNchw(i2, o2, layout).AddVariations("relaxed", quant8)
+}).AddNchw(i2, o2, layout).AddVariations("relaxed", quant8, "float16")