Add Resize Nearest Neighbour support to TOSA Reference Backend
* Add support for quantized data in TosaRefPreCompiledWorkloadGetOutput.
* Remove extra includes from all TOSA operators headers.
* Added positive and negative unit tests for resize.
* Resolves: IVGCVSW-7346
Signed-off-by: Teresa Charlin <teresa.charlinreyes@arm.com>
Change-Id: Ib6e30d018a7a1bf26b380fc794560aae108b26c3
diff --git a/src/backends/tosaReference/TosaRefLayerSupport.cpp b/src/backends/tosaReference/TosaRefLayerSupport.cpp
index e1c349f..04be52d 100644
--- a/src/backends/tosaReference/TosaRefLayerSupport.cpp
+++ b/src/backends/tosaReference/TosaRefLayerSupport.cpp
@@ -71,6 +71,7 @@
case LayerType::ElementwiseUnary:
case LayerType::Pooling2d:
case LayerType::Reshape:
+ case LayerType::Resize:
case LayerType::Slice:
case LayerType::Transpose:
inputInfos.push_back(&infos[0]);
diff --git a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp
index 26cadd2..b35dacb 100644
--- a/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp
+++ b/src/backends/tosaReference/test/TosaRefEndToEndTests.cpp
@@ -11,6 +11,7 @@
#include "backendsCommon/test/MultiplicationEndToEndTestImpl.hpp"
#include "backendsCommon/test/Pooling2dEndToEndTestImpl.hpp"
#include "backendsCommon/test/ReshapeEndToEndTestImpl.hpp"
+#include "backendsCommon/test/ResizeEndToEndTestImpl.hpp"
#include "backendsCommon/test/ElementwiseUnaryEndToEndTestImpl.hpp"
#include "backendsCommon/test/SliceEndToEndTestImpl.hpp"
#include "backendsCommon/test/SubtractionEndToEndTestImpl.hpp"
@@ -145,6 +146,47 @@
UnaryOperation::Rsqrt);
}
+// Resize
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndFloat32AlignCornersNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::Float32>(tosaDefaultBackends, armnn::DataLayout::NHWC, true, false);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndFloat32HalfPixelNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::Float32>(tosaDefaultBackends, armnn::DataLayout::NHWC, false, true);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndFloat16AlignCornersNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::Float16>(tosaDefaultBackends, armnn::DataLayout::NHWC, true, false);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndFloat16HalfPixelNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::Float16>(tosaDefaultBackends, armnn::DataLayout::NHWC, false, true);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndInt8AlignCornersNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::QSymmS8>(tosaDefaultBackends, armnn::DataLayout::NHWC, true, false);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndInt8HalfPixelNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::QSymmS8>(tosaDefaultBackends, armnn::DataLayout::NHWC, false, true);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndInt16AlignCornersNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::QSymmS16>(tosaDefaultBackends, armnn::DataLayout::NHWC, true, false);
+}
+
+TEST_CASE("TosaRefResizeNearestNeighborEndToEndInt16HalfPixelNhwcTest")
+{
+ ResizeNearestNeighborEndToEnd<armnn::DataType::QSymmS16>(tosaDefaultBackends, armnn::DataLayout::NHWC, false, true);
+}
+
// Slice
TEST_CASE("TosaRefSliceEndtoEndTestFloat32")
{
diff --git a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp
index e32894f..fb4c84f 100644
--- a/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp
+++ b/src/backends/tosaReference/test/TosaRefLayerSupportTests.cpp
@@ -352,6 +352,30 @@
CHECK(supported);
}
+TEST_CASE("IsLayerSupportedTosaReferenceResize")
+{
+ TensorShape inShape = { 1, 720, 1280, 3 };
+ TensorShape outShape = { 1, 1080, 1920, 3 };
+ TensorInfo in(inShape, DataType::Float32);
+ TensorInfo out(outShape, DataType::Float32);
+
+ ResizeDescriptor descriptor;
+ descriptor.m_DataLayout = armnn::DataLayout::NHWC;
+ descriptor.m_TargetHeight = 1080;
+ descriptor.m_TargetWidth = 1920;
+
+ TosaRefLayerSupport supportChecker;
+ std::string reasonIfNotSupported;
+ auto supported = supportChecker.IsLayerSupported(LayerType::Resize,
+ {in, out},
+ descriptor,
+ EmptyOptional(),
+ EmptyOptional(),
+ reasonIfNotSupported);
+
+ CHECK(supported);
+}
+
TEST_CASE("IsLayerSupportedTosaReferenceReshapeUnsupported")
{
TensorShape inShape = {3,4};
diff --git a/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.cpp b/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.cpp
index 8b08f01..5e4103a 100644
--- a/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.cpp
+++ b/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.cpp
@@ -50,9 +50,15 @@
SetInput<float>(runner, inputNames[inputSlotIdx], inputSlotIdx);
break;
case DataType::QAsymmU8:
+ SetInput<uint8_t, int32_t>(runner, inputNames[inputSlotIdx], inputSlotIdx);
+ break;
case DataType::QAsymmS8:
case DataType::QSymmS8:
+ SetInput<int8_t, int32_t>(runner, inputNames[inputSlotIdx], inputSlotIdx);
+ break;
case DataType::QSymmS16:
+ SetInput<int16_t, int32_t>(runner, inputNames[inputSlotIdx], inputSlotIdx);
+ break;
case DataType::Signed32:
SetInput<int32_t>(runner, inputNames[inputSlotIdx], inputSlotIdx);
break;
@@ -87,9 +93,15 @@
GetOutput<float>(runner, outputNames[outputSlotIdx], outputSlotIdx);
break;
case DataType::QAsymmU8:
+ GetOutput<uint8_t, int32_t>(runner, outputNames[outputSlotIdx], outputSlotIdx);
+ break;
case DataType::QAsymmS8:
case DataType::QSymmS8:
+ GetOutput<int8_t, int32_t>(runner, outputNames[outputSlotIdx], outputSlotIdx);
+ break;
case DataType::QSymmS16:
+ GetOutput<int16_t, int32_t>(runner, outputNames[outputSlotIdx], outputSlotIdx);
+ break;
case DataType::Signed32:
GetOutput<int32_t>(runner, outputNames[outputSlotIdx], outputSlotIdx);
break;
@@ -110,10 +122,23 @@
std::string inputName,
uint32_t inputIndex) const
{
+ SetInput<T, T>(runner, inputName, inputIndex);
+}
+
+template <typename T, typename Trunner>
+void TosaRefPreCompiledWorkload::SetInput(TosaReference::IModelRunner& runner,
+ std::string inputName,
+ uint32_t inputIndex) const
+{
std::vector<T> inputData(m_Data.m_Inputs[inputIndex]->GetShape().GetNumElements());
+ std::vector<Trunner> inputDataRunner(m_Data.m_Inputs[inputIndex]->GetShape().GetNumElements());
+
m_Data.m_Inputs[inputIndex]->CopyOutTo(inputData.data());
- runner.setInput<T>(inputName, inputData);
+ std::transform(inputData.begin(), inputData.end(),
+ inputDataRunner.begin(), [](T x) { return static_cast<Trunner>(x);});
+
+ runner.setInput<Trunner>(inputName, inputDataRunner);
}
template <typename T>
@@ -121,7 +146,19 @@
std::string outputName,
uint32_t outputIndex) const
{
- std::vector<T> actualOutputs = runner.getOutput<T>(outputName);
+ GetOutput<T, T>(runner, outputName, outputIndex);
+}
+
+template <typename T, typename Trunner>
+void TosaRefPreCompiledWorkload::GetOutput(TosaReference::IModelRunner& runner,
+ std::string outputName,
+ uint32_t outputIndex) const
+{
+ std::vector<Trunner> actualOutputsRunner = runner.getOutput<Trunner>(outputName);
+ std::vector<T> actualOutputs (actualOutputsRunner.size());
+
+ std::transform(actualOutputsRunner.begin(), actualOutputsRunner.end(),
+ actualOutputs.begin(), [](Trunner x) { return static_cast<T>(x);});
m_Data.m_Outputs[outputIndex]->CopyInFrom(actualOutputs.data());
}
diff --git a/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.hpp b/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.hpp
index 2b3a314..337e8f9 100644
--- a/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.hpp
+++ b/src/backends/tosaReference/workloads/TosaRefPreCompiledWorkload.hpp
@@ -42,9 +42,15 @@
this->m_Data.m_Outputs[slot] = tensorHandle;
}
+ template <typename T, typename Trunner>
+ void SetInput(TosaReference::IModelRunner& runner, std::string inputName, uint32_t inputIndex) const;
+
template <typename T>
void SetInput(TosaReference::IModelRunner& runner, std::string inputName, uint32_t inputIndex) const;
+ template <typename T, typename Trunner>
+ void GetOutput(TosaReference::IModelRunner& runner, std::string outputName, uint32_t outputIndex) const;
+
template <typename T>
void GetOutput(TosaReference::IModelRunner& runner, std::string outputName, uint32_t outputIndex) const;