aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Monahan <david.monahan@arm.com>2023-07-26 18:37:45 +0100
committerTeresaARM <teresa.charlinreyes@arm.com>2023-07-27 11:57:49 +0000
commit36e6eaecf616f08f4d717d56e6a4ee0400d96829 (patch)
treebd31823a9ffb37718dfb883a8e042698605f7519
parent7e4d936be9647ef9e1159747fc177d6b61c21556 (diff)
downloadarmnn-36e6eaecf616f08f4d717d56e6a4ee0400d96829.tar.gz
IVGCVSW-2292 Tile Operator Neon Implementation
* Added Implementation of the Tile Operator Workload to Neon * Added calls to the existing unittests * Added Documentation Signed-off-by: David Monahan <david.monahan@arm.com> Change-Id: I0030ffe514215c79f5629d20671254dde9bec452
-rw-r--r--docs/02_operator_list.dox16
-rw-r--r--src/backends/neon/NeonLayerSupport.cpp18
-rw-r--r--src/backends/neon/NeonLayerSupport.hpp5
-rw-r--r--src/backends/neon/NeonWorkloadFactory.cpp5
-rw-r--r--src/backends/neon/backend.mk1
-rw-r--r--src/backends/neon/test/NeonEndToEndTests.cpp31
-rw-r--r--src/backends/neon/test/NeonLayerTests.cpp18
-rw-r--r--src/backends/neon/workloads/CMakeLists.txt2
-rw-r--r--src/backends/neon/workloads/NeonTileWorkload.cpp46
-rw-r--r--src/backends/neon/workloads/NeonTileWorkload.hpp26
-rw-r--r--src/backends/neon/workloads/NeonWorkloads.hpp1
11 files changed, 164 insertions, 5 deletions
diff --git a/docs/02_operator_list.dox b/docs/02_operator_list.dox
index 02b72ca66c..d7b2bb5bb8 100644
--- a/docs/02_operator_list.dox
+++ b/docs/02_operator_list.dox
@@ -3336,13 +3336,19 @@ where N = batches, C = channels, H = height, W = width
<td>CpuAcc
<td>
<ul>
- <li>None
+ <li>All
</ul>
<td>
- <table>
- <tr><th>
- <tr><td>None
- </table>
+ <table>
+ <tr><th>
+ <tr><td>FLOAT16
+ <tr><td>FLOAT32
+ <tr><td>QASYMMS8
+ <tr><td>QASYMMU8
+ <tr><td>QASYMM8
+ <tr><td>QSYMMS16
+ <tr><td>SIGNED32
+ </table>
<tr>
<td>GpuAcc
<td>
diff --git a/src/backends/neon/NeonLayerSupport.cpp b/src/backends/neon/NeonLayerSupport.cpp
index d097240022..b491ba8493 100644
--- a/src/backends/neon/NeonLayerSupport.cpp
+++ b/src/backends/neon/NeonLayerSupport.cpp
@@ -81,6 +81,7 @@
#include "workloads/NeonStackWorkload.hpp"
#include "workloads/NeonStridedSliceWorkload.hpp"
#include "workloads/NeonSubtractionWorkload.hpp"
+#include "workloads/NeonTileWorkload.hpp"
#include "workloads/NeonTransposeConvolution2dWorkload.hpp"
#include "workloads/NeonTransposeWorkload.hpp"
#include "workloads/NeonUnidirectionalSequenceLstmFloatWorkload.hpp"
@@ -622,6 +623,11 @@ bool IsLayerTypeSupported(const LayerType& type,
reasonIfUnsupported);
case LayerType::Subtraction:
return support.IsSubtractionSupported(infos[0], infos[1], infos[2], reasonIfUnsupported);
+ case LayerType::Tile:
+ return support.IsTileSupported(infos[0],
+ infos[1],
+ *(PolymorphicDowncast<const TileDescriptor*>(&descriptor)),
+ reasonIfUnsupported);
case LayerType::Transpose:
return support.IsTransposeSupported(infos[0],
infos[1],
@@ -1595,6 +1601,18 @@ bool NeonLayerSupport::IsSubtractionSupported(const TensorInfo& input0,
nullptr);
}
+bool NeonLayerSupport::IsTileSupported(const TensorInfo& input,
+ const TensorInfo& output,
+ const TileDescriptor& descriptor,
+ Optional<std::string&> reasonIfUnsupported) const
+{
+ FORWARD_WORKLOAD_VALIDATE_FUNC(NeonTileWorkloadValidate,
+ reasonIfUnsupported,
+ input,
+ output,
+ descriptor);
+}
+
bool NeonLayerSupport::IsTransposeConvolution2dSupported(const TensorInfo& input,
const TensorInfo& output,
const TransposeConvolution2dDescriptor& descriptor,
diff --git a/src/backends/neon/NeonLayerSupport.hpp b/src/backends/neon/NeonLayerSupport.hpp
index 374a9049c8..8a33dce75a 100644
--- a/src/backends/neon/NeonLayerSupport.hpp
+++ b/src/backends/neon/NeonLayerSupport.hpp
@@ -330,6 +330,11 @@ public:
const TensorInfo& output,
Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+ bool IsTileSupported(const TensorInfo& input0,
+ const TensorInfo& output,
+ const TileDescriptor& descriptor,
+ Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const;
+
bool IsTransposeConvolution2dSupported(const TensorInfo& input,
const TensorInfo& output,
const TransposeConvolution2dDescriptor& descriptor,
diff --git a/src/backends/neon/NeonWorkloadFactory.cpp b/src/backends/neon/NeonWorkloadFactory.cpp
index eca386701b..29b3ff3499 100644
--- a/src/backends/neon/NeonWorkloadFactory.cpp
+++ b/src/backends/neon/NeonWorkloadFactory.cpp
@@ -617,6 +617,11 @@ std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateWorkload(LayerType type,
auto subtractionQueueDescriptor = PolymorphicDowncast<const SubtractionQueueDescriptor*>(&descriptor);
return std::make_unique<NeonSubtractionWorkload>(*subtractionQueueDescriptor, info);
}
+ case LayerType::Tile:
+ {
+ auto tileQueueDescriptor = PolymorphicDowncast<const TileQueueDescriptor*>(&descriptor);
+ return std::make_unique<NeonTileWorkload>(*tileQueueDescriptor, info);
+ }
case LayerType::Transpose :
{
auto transposeQueueDescriptor = PolymorphicDowncast<const TransposeQueueDescriptor*>(&descriptor);
diff --git a/src/backends/neon/backend.mk b/src/backends/neon/backend.mk
index 0e99c683cf..2c91d1491d 100644
--- a/src/backends/neon/backend.mk
+++ b/src/backends/neon/backend.mk
@@ -87,6 +87,7 @@ BACKEND_SOURCES := \
workloads/NeonStackWorkload.cpp \
workloads/NeonStridedSliceWorkload.cpp \
workloads/NeonSubtractionWorkload.cpp \
+ workloads/NeonTileWorkload.cpp \
workloads/NeonTransposeConvolution2dWorkload.cpp \
workloads/NeonTransposeWorkload.cpp \
workloads/NeonUnidirectionalSequenceLstmFloatWorkload.cpp \
diff --git a/src/backends/neon/test/NeonEndToEndTests.cpp b/src/backends/neon/test/NeonEndToEndTests.cpp
index 5672f8b993..4f3b8ec832 100644
--- a/src/backends/neon/test/NeonEndToEndTests.cpp
+++ b/src/backends/neon/test/NeonEndToEndTests.cpp
@@ -26,6 +26,7 @@
#include <backendsCommon/test/SpaceToDepthEndToEndTestImpl.hpp>
#include <backendsCommon/test/SplitterEndToEndTestImpl.hpp>
#include <backendsCommon/test/SubgraphUtilsTest.hpp>
+#include <backendsCommon/test/TileEndToEndTestImpl.hpp>
#include <backendsCommon/test/TransposeConvolution2dEndToEndTestImpl.hpp>
#include <backendsCommon/test/TransposeEndToEndTestImpl.hpp>
@@ -419,6 +420,36 @@ TEST_CASE("NeonSplitter4dDim3EndToEndUint8Test")
Splitter4dDim3EndToEnd<armnn::DataType::QAsymmU8>(neonDefaultBackends);
}
+// Tile
+TEST_CASE("NeonTileEndToEndFloat32")
+{
+ TileEndToEnd<armnn::DataType::Float32>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndFloat16")
+{
+ TileEndToEnd<armnn::DataType::Float16>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndQAsymmS8")
+{
+ TileEndToEnd<armnn::DataType::QAsymmS8>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndQAsymmU8")
+{
+ TileEndToEnd<armnn::DataType::QAsymmU8>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndQSymmS8")
+{
+ TileEndToEnd<armnn::DataType::QSymmS8>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndQSymmS16")
+{
+ TileEndToEnd<armnn::DataType::QSymmS16>(neonDefaultBackends);
+}
+TEST_CASE("NeonTileEndToEndSigned32")
+{
+ TileEndToEnd<armnn::DataType::Signed32>(neonDefaultBackends);
+}
+
TEST_CASE("NeonQuantizedLstmEndToEndTest")
{
QuantizedLstmEndToEnd(neonDefaultBackends);
diff --git a/src/backends/neon/test/NeonLayerTests.cpp b/src/backends/neon/test/NeonLayerTests.cpp
index c5b710a75c..ae8352d09e 100644
--- a/src/backends/neon/test/NeonLayerTests.cpp
+++ b/src/backends/neon/test/NeonLayerTests.cpp
@@ -1436,6 +1436,24 @@ ARMNN_AUTO_TEST_CASE_WITH_THF(StackOutput4DAxis3, StackOutput4DAxis3Float32Tes
ARMNN_AUTO_TEST_CASE_WITH_THF(StackOutput3DInputs3, StackOutput3DInputs3Float32Test)
ARMNN_AUTO_TEST_CASE_WITH_THF(StackOutput5D, StackOutput5DFloat32Test)
+//Tile
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile1dTestFloat32, Tile1dTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile2dTestFloat32, Tile2dTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile3dTestFloat32, Tile3dTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile4dTestFloat32, Tile4dTest<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile1dTestFloat16, Tile1dTest<DataType::Float16>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile2dTestFloat16, Tile2dTest<DataType::Float16>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile3dTestFloat16, Tile3dTest<DataType::Float16>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile4dTestFloat16, Tile4dTest<DataType::Float16>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile1dTestInt8, Tile1dTest<DataType::QAsymmS8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile2dTestInt8, Tile2dTest<DataType::QAsymmS8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile3dTestInt8, Tile3dTest<DataType::QAsymmS8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile4dTestInt8, Tile4dTest<DataType::QAsymmS8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile1dTestUint8, Tile1dTest<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile2dTestUint8, Tile2dTest<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile3dTestUint8, Tile3dTest<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE_WITH_THF(Tile4dTestUint8, Tile4dTest<DataType::QAsymmU8>)
+
// Transpose
ARMNN_AUTO_TEST_CASE_WITH_THF(SimpleTransposeFloat32, SimpleTransposeTest<DataType::Float32>)
ARMNN_AUTO_TEST_CASE_WITH_THF(TransposeFloat32ValueSet1Test, TransposeValueSet1Test<DataType::Float32>)
diff --git a/src/backends/neon/workloads/CMakeLists.txt b/src/backends/neon/workloads/CMakeLists.txt
index 53f2be750a..2cb2ccf385 100644
--- a/src/backends/neon/workloads/CMakeLists.txt
+++ b/src/backends/neon/workloads/CMakeLists.txt
@@ -133,6 +133,8 @@ list(APPEND armnnNeonBackendWorkloads_sources
NeonStridedSliceWorkload.hpp
NeonSubtractionWorkload.cpp
NeonSubtractionWorkload.hpp
+ NeonTileWorkload.cpp
+ NeonTileWorkload.hpp
NeonTransposeConvolution2dWorkload.cpp
NeonTransposeConvolution2dWorkload.hpp
NeonTransposeWorkload.cpp
diff --git a/src/backends/neon/workloads/NeonTileWorkload.cpp b/src/backends/neon/workloads/NeonTileWorkload.cpp
new file mode 100644
index 0000000000..9b699ef4f1
--- /dev/null
+++ b/src/backends/neon/workloads/NeonTileWorkload.cpp
@@ -0,0 +1,46 @@
+//
+// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#include "NeonTileWorkload.hpp"
+#include "NeonWorkloadUtils.hpp"
+#include <aclCommon/ArmComputeUtils.hpp>
+#include <vector>
+#include <algorithm>
+
+using namespace armnn::armcomputetensorutils;
+namespace armnn
+{
+arm_compute::Status NeonTileWorkloadValidate(const TensorInfo& input,
+ const TensorInfo& output,
+ const TileDescriptor& descriptor)
+{
+ const arm_compute::TensorInfo aclInput = BuildArmComputeTensorInfo(input);
+ const arm_compute::TensorInfo aclOutput = BuildArmComputeTensorInfo(output);
+
+ std::vector<unsigned int> aclMultiples = descriptor.m_Multiples;
+ std::reverse(aclMultiples.begin(),aclMultiples.end());
+
+ return arm_compute::NETile::validate(&aclInput, &aclOutput, aclMultiples);
+}
+
+NeonTileWorkload::NeonTileWorkload(const armnn::TileQueueDescriptor& descriptor,
+ const armnn::WorkloadInfo& info)
+ : BaseWorkload<TileQueueDescriptor>(descriptor, info)
+{
+ m_Data.ValidateInputsOutputs("NeonTileWorkload", 1, 1);
+
+ std::vector<unsigned int> aclMultiples = descriptor.m_Parameters.m_Multiples;
+ std::reverse(aclMultiples.begin(),aclMultiples.end());
+
+ arm_compute::ITensor& input = static_cast<IAclTensorHandle*>(m_Data.m_Inputs[0])->GetTensor();
+ arm_compute::ITensor& output = static_cast<IAclTensorHandle*>(m_Data.m_Outputs[0])->GetTensor();
+ m_Layer.configure(&input, &output, aclMultiples);
+}
+
+void NeonTileWorkload::Execute() const
+{
+ ARMNN_SCOPED_PROFILING_EVENT_NEON_GUID("NeonTileWorkload_Execute", this->GetGuid());
+ m_Layer.run();
+}
+} //namespace armnn \ No newline at end of file
diff --git a/src/backends/neon/workloads/NeonTileWorkload.hpp b/src/backends/neon/workloads/NeonTileWorkload.hpp
new file mode 100644
index 0000000000..a32e5e9a53
--- /dev/null
+++ b/src/backends/neon/workloads/NeonTileWorkload.hpp
@@ -0,0 +1,26 @@
+//
+// Copyright © 2023 Arm Ltd and Contributors. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+#pragma once
+#include "NeonBaseWorkload.hpp"
+#include <arm_compute/runtime/NEON/functions/NETile.h>
+
+namespace armnn
+{
+arm_compute::Status NeonTileWorkloadValidate(const TensorInfo& input,
+ const TensorInfo& output,
+ const TileDescriptor& descriptor);
+
+class NeonTileWorkload : public BaseWorkload<TileQueueDescriptor>
+{
+public:
+ NeonTileWorkload(const TileQueueDescriptor &descriptor,
+ const WorkloadInfo &info);
+ void Execute() const override;
+
+private:
+ mutable arm_compute::NETile m_Layer;
+};
+
+} //namespace armnn \ No newline at end of file
diff --git a/src/backends/neon/workloads/NeonWorkloads.hpp b/src/backends/neon/workloads/NeonWorkloads.hpp
index 024748690c..b72f3bb703 100644
--- a/src/backends/neon/workloads/NeonWorkloads.hpp
+++ b/src/backends/neon/workloads/NeonWorkloads.hpp
@@ -69,6 +69,7 @@
#include "NeonStackWorkload.hpp"
#include "NeonStridedSliceWorkload.hpp"
#include "NeonSubtractionWorkload.hpp"
+#include "NeonTileWorkload.hpp"
#include "NeonTransposeConvolution2dWorkload.hpp"
#include "NeonTransposeWorkload.hpp"
#include "NeonUnidirectionalSequenceLstmFloatWorkload.hpp"