From 8d50f8f4b848547635a74e6fdec29f632748ebb1 Mon Sep 17 00:00:00 2001 From: Matteo Martincigh Date: Thu, 25 Oct 2018 15:39:33 +0100 Subject: IVGCVSW-2051 Added unit tests in the Android NN Driver for the new Mean layer * Added unit tests (in a new file test/1.1/Mean.cpp) * Refactored ArmnnDriverImpl to remove redundant tags in the log messages * Modified AddInputOperand to accept a quantized input tensor Change-Id: Ie037ce426777daab28b0501124e1cc8686ad6184 --- test/1.1/Mean.cpp | 137 +++++++++++++++++++++++++++++++++++++++++++++ test/Android.mk | 1 + test/DriverTestHelpers.hpp | 1 + 3 files changed, 139 insertions(+) create mode 100644 test/1.1/Mean.cpp (limited to 'test') diff --git a/test/1.1/Mean.cpp b/test/1.1/Mean.cpp new file mode 100644 index 00000000..4ebb8cfa --- /dev/null +++ b/test/1.1/Mean.cpp @@ -0,0 +1,137 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "../DriverTestHelpers.hpp" +#include "../TestTensor.hpp" + +#include +#include + +BOOST_AUTO_TEST_SUITE(MeanTests) + +using namespace android::hardware; +using namespace driverTestHelpers; +using namespace armnn_driver; + +namespace +{ + +static const boost::array COMPUTE_DEVICES = {{ armnn::Compute::CpuRef, armnn::Compute::GpuAcc }}; + +void MeanTestImpl(const TestTensor& input, + const hidl_vec& axisDimensions, + const int32_t* axisValues, + int32_t keepDims, + const TestTensor& expectedOutput, + bool fp16Enabled, + armnn::Compute computeDevice) +{ + auto driver = std::make_unique(DriverOptions(computeDevice, fp16Enabled)); + + V1_1::Model model = {}; + AddInputOperand (model, input.GetDimensions()); + AddTensorOperand(model, axisDimensions, const_cast(axisValues), OperandType::TENSOR_INT32); + AddIntOperand (model, keepDims); + AddOutputOperand(model, expectedOutput.GetDimensions()); + + model.operations.resize(1); + model.operations[0].type = V1_1::OperationType::MEAN; + model.operations[0].inputs = hidl_vec{ 0, 1, 2 }; + model.operations[0].outputs = hidl_vec{ 3 }; + model.relaxComputationFloat32toFloat16 = fp16Enabled; + + android::sp preparedModel = PrepareModel(model, *driver); + + // The request's memory pools will follow the same order as the inputs + DataLocation inLoc = {}; + inLoc.poolIndex = 0; + inLoc.offset = 0; + inLoc.length = input.GetNumElements() * sizeof(float); + RequestArgument inArg = {}; + inArg.location = inLoc; + inArg.dimensions = input.GetDimensions(); + + // An additional memory pool is needed for the output + DataLocation outLoc = {}; + outLoc.poolIndex = 1; + outLoc.offset = 0; + outLoc.length = expectedOutput.GetNumElements() * sizeof(float); + RequestArgument outArg = {}; + outArg.location = outLoc; + outArg.dimensions = expectedOutput.GetDimensions(); + + // Make the request based on the arguments + Request request = {}; + request.inputs = hidl_vec{ inArg }; + request.outputs = hidl_vec{ outArg }; + + // Set the input data + AddPoolAndSetData(input.GetNumElements(), request, input.GetData()); + + // Add memory for the output + android::sp outMemory = AddPoolAndGetData(expectedOutput.GetNumElements(), request); + const float* outputData = static_cast(static_cast(outMemory->getPointer())); + + ErrorStatus execStatus = Execute(preparedModel, request); + BOOST_TEST(execStatus == ErrorStatus::NONE); + + const float* expectedOutputData = expectedOutput.GetData(); + for (unsigned int i = 0; i < expectedOutput.GetNumElements(); i++) + { + BOOST_TEST(outputData[i] == expectedOutputData[i]); + } +} + +} // anonymous namespace + +BOOST_DATA_TEST_CASE(MeanNoKeepDimsTest, COMPUTE_DEVICES) +{ + TestTensor input{ armnn::TensorShape{ 4, 3, 2 }, { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, + 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f } }; + hidl_vec axisDimensions = { 2 }; + int32_t axisValues[] = { 0, 1 }; + int32_t keepDims = 0; + TestTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0f, 13.0f } }; + + MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, sample); +} + +BOOST_DATA_TEST_CASE(MeanKeepDimsTest, COMPUTE_DEVICES) +{ + TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } }; + hidl_vec axisDimensions = { 1 }; + int32_t axisValues[] = { 2 }; + int32_t keepDims = 1; + TestTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, { 2.0f, 2.0f } }; + + MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, sample); +} + +BOOST_DATA_TEST_CASE(MeanFp16NoKeepDimsTest, COMPUTE_DEVICES) +{ + TestTensor input{ armnn::TensorShape{ 4, 3, 2 }, { 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, + 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f, 19.0f, + 20.0f, 21.0f, 22.0f, 23.0f, 24.0f } }; + hidl_vec axisDimensions = { 2 }; + int32_t axisValues[] = { 0, 1 }; + int32_t keepDims = 0; + TestTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0f, 13.0f } }; + + MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, sample); +} + +BOOST_DATA_TEST_CASE(MeanFp16KeepDimsTest, COMPUTE_DEVICES) +{ + TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } }; + hidl_vec axisDimensions = { 1 }; + int32_t axisValues[] = { 2 }; + int32_t keepDims = 1; + TestTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, { 2.0f, 2.0f } }; + + MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, sample); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/Android.mk b/test/Android.mk index 3a58618b..da3ac706 100644 --- a/test/Android.mk +++ b/test/Android.mk @@ -121,6 +121,7 @@ LOCAL_CFLAGS := \ LOCAL_SRC_FILES := \ 1.0/Convolution2D.cpp \ 1.1/Convolution2D.cpp \ + 1.1/Mean.cpp \ 1.1/Transpose.cpp \ Tests.cpp \ UtilsTests.cpp \ diff --git a/test/DriverTestHelpers.hpp b/test/DriverTestHelpers.hpp index cce220e5..370936fe 100644 --- a/test/DriverTestHelpers.hpp +++ b/test/DriverTestHelpers.hpp @@ -146,6 +146,7 @@ void AddInputOperand(HalModel& model, { Operand op = {}; op.type = operandType; + op.scale = operandType == OperandType::TENSOR_QUANT8_ASYMM ? 1.f / 255.f : 0.f; op.dimensions = dimensions; op.lifetime = OperandLifeTime::MODEL_INPUT; -- cgit v1.2.1