Skip to content

Commit

Permalink
IVGCVSW-7211 Fix float16 operators being wrongly unsupported with and…
Browse files Browse the repository at this point in the history
…roid-nn-driver.

!armnn:8862

  * Added float16 mean test cases.
  * Float16 CTS/CTS pass on CpuAcc.

Signed-off-by: Cathal Corbett <[email protected]>
Change-Id: Ibd9021d0ae4a205cc2c91555f3ae00c6dba84609
  • Loading branch information
catcor01 committed Dec 21, 2022
1 parent 8de96f7 commit 0637bf3
Show file tree
Hide file tree
Showing 5 changed files with 293 additions and 12 deletions.
14 changes: 7 additions & 7 deletions test/1.1/Mean.cpp
Original file line number Diff line number Diff line change
@@ -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
//

Expand Down Expand Up @@ -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,
Expand All @@ -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 };
Expand Down Expand Up @@ -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,
Expand All @@ -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 };
Expand Down Expand Up @@ -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,
Expand All @@ -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 };
Expand Down
204 changes: 204 additions & 0 deletions test/1.2/Mean.cpp
Original file line number Diff line number Diff line change
@@ -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
16 changes: 11 additions & 5 deletions test/Android.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright © 2017 ARM Ltd. All rights reserved.
# Copyright © 2017, 2022 ARM Ltd. All rights reserved.
# SPDX-License-Identifier: MIT
#

Expand Down Expand Up @@ -91,7 +91,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
TestTensor.cpp
TestTensor.cpp \
TestHalfTensor.cpp

LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
Expand Down Expand Up @@ -223,7 +224,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
TestTensor.cpp
TestTensor.cpp \
TestHalfTensor.cpp

LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
Expand Down Expand Up @@ -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 \
Expand All @@ -351,7 +354,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
TestTensor.cpp
TestTensor.cpp \
TestHalfTensor.cpp

LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
Expand Down Expand Up @@ -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 \
Expand All @@ -476,7 +481,8 @@ LOCAL_SRC_FILES := \
DriverTestHelpers.cpp \
SystemProperties.cpp \
Concat.cpp \
TestTensor.cpp
TestTensor.cpp \
TestHalfTensor.cpp

LOCAL_STATIC_LIBRARIES := \
libneuralnetworks_common \
Expand Down
33 changes: 33 additions & 0 deletions test/TestHalfTensor.cpp
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit 0637bf3

Please sign in to comment.