aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCathal Corbett <cathal.corbett@arm.com>2022-12-20 18:35:34 +0000
committerCathal Corbett <cathal.corbett@arm.com>2022-12-21 15:12:02 +0000
commit0637bf38b24bba3a3d88f34ed956111a3abddda2 (patch)
tree81b348da58714cb817fcf6ab3bb31368b56ca8b7
parent8de96f7e72e212503dadb450ccdcd15b411a7a1a (diff)
downloadandroid-nn-driver-0637bf38b24bba3a3d88f34ed956111a3abddda2.tar.gz
IVGCVSW-7211 Fix float16 operators being wrongly unsupported with android-nn-driver.
!armnn:8862 * Added float16 mean test cases. * Float16 CTS/CTS pass on CpuAcc. Signed-off-by: Cathal Corbett <cathal.corbett@arm.com> Change-Id: Ibd9021d0ae4a205cc2c91555f3ae00c6dba84609
-rw-r--r--test/1.1/Mean.cpp14
-rw-r--r--test/1.2/Mean.cpp204
-rw-r--r--test/Android.mk16
-rw-r--r--test/TestHalfTensor.cpp33
-rw-r--r--test/TestHalfTensor.hpp38
5 files changed, 293 insertions, 12 deletions
diff --git a/test/1.1/Mean.cpp b/test/1.1/Mean.cpp
index 34c29bad..70bdc3d3 100644
--- a/test/1.1/Mean.cpp
+++ b/test/1.1/Mean.cpp
@@ -1,5 +1,5 @@
//
-// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
+// Copyright © 2017, 2022 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
@@ -124,7 +124,7 @@ DOCTEST_TEST_SUITE("MeanTests_CpuRef")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, armnn::Compute::CpuRef);
}
- DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuRef")
+ DOCTEST_TEST_CASE("MeanFp16EnabledNoKeepDimsTest_CpuRef")
{
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,
@@ -138,7 +138,7 @@ DOCTEST_TEST_SUITE("MeanTests_CpuRef")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuRef);
}
- DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuRef")
+ DOCTEST_TEST_CASE("MeanFp16EnabledKeepDimsTest_CpuRef")
{
TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } };
hidl_vec<uint32_t> axisDimensions = { 1 };
@@ -179,7 +179,7 @@ DOCTEST_TEST_SUITE("MeanTests_CpuAcc")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, armnn::Compute::CpuAcc);
}
- DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuAcc")
+ DOCTEST_TEST_CASE("MeanFp16EnabledNoKeepDimsTest_CpuAcc")
{
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,
@@ -193,7 +193,7 @@ DOCTEST_TEST_SUITE("MeanTests_CpuAcc")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuAcc);
}
- DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuAcc")
+ DOCTEST_TEST_CASE("MeanFp16EnabledKeepDimsTest_CpuAcc")
{
TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } };
hidl_vec<uint32_t> axisDimensions = { 1 };
@@ -232,7 +232,7 @@ DOCTEST_TEST_SUITE("MeanTests_GpuAcc")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, false, armnn::Compute::GpuAcc);
}
- DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_GpuAcc")
+ DOCTEST_TEST_CASE("MeanFp16EnabledNoKeepDimsTest_GpuAcc")
{
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,
@@ -246,7 +246,7 @@ DOCTEST_TEST_SUITE("MeanTests_GpuAcc")
MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::GpuAcc);
}
- DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_GpuAcc")
+ DOCTEST_TEST_CASE("MeanFp16EnabledKeepDimsTest_GpuAcc")
{
TestTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f } };
hidl_vec<uint32_t> axisDimensions = { 1 };
diff --git a/test/1.2/Mean.cpp b/test/1.2/Mean.cpp
new file mode 100644
index 00000000..a2a8b7a1
--- /dev/null
+++ b/test/1.2/Mean.cpp
@@ -0,0 +1,204 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "../DriverTestHelpers.hpp"
+#include "../TestHalfTensor.hpp"
+
+#include <1.2/HalPolicy.hpp>
+
+#include <array>
+
+using Half = half_float::half;
+
+using namespace android::hardware;
+using namespace driverTestHelpers;
+using namespace armnn_driver;
+
+using HalPolicy = hal_1_2::HalPolicy;
+using RequestArgument = V1_0::RequestArgument;
+
+namespace
+{
+
+void MeanTestImpl(const TestHalfTensor& input,
+ const hidl_vec<uint32_t>& axisDimensions,
+ const int32_t* axisValues,
+ int32_t keepDims,
+ const TestHalfTensor& expectedOutput,
+ bool fp16Enabled,
+ armnn::Compute computeDevice)
+{
+ auto driver = std::make_unique<ArmnnDriver>(DriverOptions(computeDevice, fp16Enabled));
+
+ HalPolicy::Model model = {};
+
+ AddInputOperand<HalPolicy>(model, input.GetDimensions(), V1_2::OperandType::TENSOR_FLOAT16);
+
+ AddTensorOperand<HalPolicy>(model,
+ axisDimensions,
+ const_cast<int32_t*>(axisValues),
+ HalPolicy::OperandType::TENSOR_INT32);
+
+ AddIntOperand<HalPolicy>(model, keepDims);
+
+ AddOutputOperand<HalPolicy>(model, expectedOutput.GetDimensions(), V1_2::OperandType::TENSOR_FLOAT16);
+
+ model.operations.resize(1);
+ model.operations[0].type = HalPolicy::OperationType::MEAN;
+ model.operations[0].inputs = hidl_vec<uint32_t>{ 0, 1, 2 };
+ model.operations[0].outputs = hidl_vec<uint32_t>{ 3 };
+ model.relaxComputationFloat32toFloat16 = fp16Enabled;
+
+ //android::sp<V1_0::IPreparedModel> preparedModel = PrepareModel(model, *driver);
+ android::sp<V1_2::IPreparedModel> preparedModel = PrepareModel_1_2(model, *driver);
+
+ // The request's memory pools will follow the same order as the inputs
+ V1_0::DataLocation inLoc = {};
+ inLoc.poolIndex = 0;
+ inLoc.offset = 0;
+ inLoc.length = input.GetNumElements() * sizeof(Half);
+ RequestArgument inArg = {};
+ inArg.location = inLoc;
+ inArg.dimensions = input.GetDimensions();
+
+ // An additional memory pool is needed for the output
+ V1_0::DataLocation outLoc = {};
+ outLoc.poolIndex = 1;
+ outLoc.offset = 0;
+ outLoc.length = expectedOutput.GetNumElements() * sizeof(Half);
+ RequestArgument outArg = {};
+ outArg.location = outLoc;
+ outArg.dimensions = expectedOutput.GetDimensions();
+
+ // Make the request based on the arguments
+ V1_0::Request request = {};
+ request.inputs = hidl_vec<RequestArgument>{ inArg };
+ request.outputs = hidl_vec<RequestArgument>{ outArg };
+
+ // Set the input data
+ AddPoolAndSetData(input.GetNumElements(), request, input.GetData());
+
+ // Add memory for the output
+ android::sp<IMemory> outMemory = AddPoolAndGetData<Half>(expectedOutput.GetNumElements(), request);
+ const Half* outputData = static_cast<const Half*>(static_cast<void*>(outMemory->getPointer()));
+
+ if (preparedModel.get() != nullptr)
+ {
+ V1_0::ErrorStatus execStatus = Execute(preparedModel, request);
+ DOCTEST_CHECK((int)execStatus == (int)V1_0::ErrorStatus::NONE);
+ }
+
+ const Half* expectedOutputData = expectedOutput.GetData();
+ for (unsigned int i = 0; i < expectedOutput.GetNumElements(); i++)
+ {
+ DOCTEST_CHECK(outputData[i] == expectedOutputData[i]);
+ }
+}
+
+} // anonymous namespace
+
+DOCTEST_TEST_SUITE("MeanTests_1.2_CpuRef")
+{
+
+DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuRef")
+{
+ using namespace half_float::literal;
+
+ TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
+ { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
+ 11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
+ 20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h } };
+ hidl_vec<uint32_t> axisDimensions = { 2 };
+ int32_t axisValues[] = { 0, 1 };
+ int32_t keepDims = 0;
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0_h, 13.0_h } };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuRef);
+}
+
+DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuRef")
+{
+ using namespace half_float::literal;
+
+ TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h } };
+ hidl_vec<uint32_t> axisDimensions = { 1 };
+ int32_t axisValues[] = { 2 };
+ int32_t keepDims = 1;
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, { 2.0_h, 2.0_h } };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuRef);
+}
+
+}
+
+#ifdef ARMCOMPUTECL_ENABLED
+DOCTEST_TEST_SUITE("MeanTests_1.2_CpuAcc")
+{
+ DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_CpuAcc")
+ {
+ using namespace half_float::literal;
+
+ std::vector<Half> in = { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
+ 11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
+ 20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h };
+ TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
+ in};
+ hidl_vec<uint32_t> axisDimensions = { 2 };
+ int32_t axisValues[] = { 0, 1 };
+ int32_t keepDims = 0;
+ std::vector<Half> out = { 12.0_h, 13.0_h };
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, out };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuAcc);
+ }
+
+ DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_CpuAcc")
+ {
+ using namespace half_float::literal;
+
+ std::vector<Half> in = { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h };
+ TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, in };
+ hidl_vec<uint32_t> axisDimensions = { 1 };
+ int32_t axisValues[] = { 2 };
+ int32_t keepDims = 1;
+ std::vector<Half> out = { 2.0_h, 2.0_h };
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, out };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::CpuAcc);
+ }
+}
+
+DOCTEST_TEST_SUITE("MeanTests_1.2_GpuAcc")
+{
+ DOCTEST_TEST_CASE("MeanFp16NoKeepDimsTest_GpuAcc")
+ {
+ using namespace half_float::literal;
+
+ TestHalfTensor input{ armnn::TensorShape{ 4, 3, 2 },
+ { 1.0_h, 2.0_h, 3.0_h, 4.0_h, 5.0_h, 6.0_h, 7.0_h, 8.0_h, 9.0_h, 10.0_h,
+ 11.0_h, 12.0_h, 13.0_h, 14.0_h, 15.0_h, 16.0_h, 17.0_h, 18.0_h, 19.0_h,
+ 20.0_h, 21.0_h, 22.0_h, 23.0_h, 24.0_h } };
+ hidl_vec<uint32_t> axisDimensions = { 2 };
+ int32_t axisValues[] = { 0, 1 };
+ int32_t keepDims = 0;
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 2 }, { 12.0_h, 13.0_h } };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::GpuAcc);
+ }
+
+ DOCTEST_TEST_CASE("MeanFp16KeepDimsTest_GpuAcc")
+ {
+ using namespace half_float::literal;
+
+ TestHalfTensor input{ armnn::TensorShape{ 1, 1, 3, 2 }, { 1.0_h, 1.0_h, 2.0_h, 2.0_h, 3.0_h, 3.0_h } };
+ hidl_vec<uint32_t> axisDimensions = { 1 };
+ int32_t axisValues[] = { 2 };
+ int32_t keepDims = 1;
+ TestHalfTensor expectedOutput{ armnn::TensorShape{ 1, 1, 1, 2 }, { 2.0_h, 2.0_h } };
+
+ MeanTestImpl(input, axisDimensions, axisValues, keepDims, expectedOutput, true, armnn::Compute::GpuAcc);
+ }
+}
+#endif
diff --git a/test/Android.mk b/test/Android.mk
index 930c7f91..8621182c 100644
--- a/test/Android.mk
+++ b/test/Android.mk
@@ -1,5 +1,5 @@
#
-# Copyright © 2017 ARM Ltd. All rights reserved.
+# Copyright © 2017, 2022 ARM Ltd. All rights reserved.
# SPDX-License-Identifier: MIT
#
@@ -91,7 +91,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
- TestTensor.cpp
+ TestTensor.cpp \
+ TestHalfTensor.cpp
LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
@@ -223,7 +224,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
- TestTensor.cpp
+ TestTensor.cpp \
+ TestHalfTensor.cpp
LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
@@ -339,6 +341,7 @@ LOCAL_SRC_FILES := \
1.1/Transpose.cpp \
1.2/Dilation.cpp \
1.2/Capabilities.cpp \
+ 1.2/Mean.cpp \
1.0/Lstm.cpp \
1.1/Lstm.cpp \
1.2/Lstm.cpp \
@@ -351,7 +354,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
- TestTensor.cpp
+ TestTensor.cpp \
+ TestHalfTensor.cpp
LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
@@ -462,6 +466,7 @@ LOCAL_SRC_FILES := \
1.1/Transpose.cpp \
1.2/Dilation.cpp \
1.2/Capabilities.cpp \
+ 1.2/Mean.cpp \
1.0/Lstm.cpp \
1.1/Lstm.cpp \
1.2/Lstm.cpp \
@@ -476,7 +481,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
- TestTensor.cpp
+ TestTensor.cpp \
+ TestHalfTensor.cpp
LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
diff --git a/test/TestHalfTensor.cpp b/test/TestHalfTensor.cpp
new file mode 100644
index 00000000..12cdc427
--- /dev/null
+++ b/test/TestHalfTensor.cpp
@@ -0,0 +1,33 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "TestHalfTensor.hpp"
+
+namespace driverTestHelpers
+{
+
+hidl_vec<uint32_t> TestHalfTensor::GetDimensions() const
+{
+ hidl_vec<uint32_t> dimensions;
+ dimensions.resize(m_Shape.GetNumDimensions());
+ for (uint32_t i=0; i<m_Shape.GetNumDimensions(); ++i)
+ {
+ dimensions[i] = m_Shape[i];
+ }
+ return dimensions;
+}
+
+unsigned int TestHalfTensor::GetNumElements() const
+{
+ return m_Shape.GetNumElements();
+}
+
+const Half * TestHalfTensor::GetData() const
+{
+ DOCTEST_CHECK(m_Data.empty() == false);
+ return &m_Data[0];
+}
+
+} // namespace driverTestHelpers
diff --git a/test/TestHalfTensor.hpp b/test/TestHalfTensor.hpp
new file mode 100644
index 00000000..2b7870f4
--- /dev/null
+++ b/test/TestHalfTensor.hpp
@@ -0,0 +1,38 @@
+//
+// Copyright © 2022 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <ArmnnDriver.hpp>
+#include "DriverTestHelpers.hpp"
+
+#include <half/half.hpp>
+
+using Half = half_float::half;
+
+namespace driverTestHelpers
+{
+
+class TestHalfTensor
+{
+public:
+ TestHalfTensor(const armnn::TensorShape & shape,
+ const std::vector<Half> & data)
+ : m_Shape{shape}
+ , m_Data{data}
+ {
+ DOCTEST_CHECK(m_Shape.GetNumElements() == m_Data.size());
+ }
+
+ hidl_vec<uint32_t> GetDimensions() const;
+ unsigned int GetNumElements() const;
+ const Half * GetData() const;
+
+private:
+ armnn::TensorShape m_Shape;
+ std::vector<Half> m_Data;
+};
+
+} // driverTestHelpers