IVGCVSW-4380 Add NEON backend support for BatchToSpaceNd
authorMike Kelly <mike.kelly@arm.com>
Mon, 27 Jan 2020 12:14:47 +0000 (12:14 +0000)
committermike.kelly <mike.kelly@arm.com>
Mon, 27 Jan 2020 14:49:07 +0000 (14:49 +0000)
 * Added NeonBatchToSpaceNdWorkload class.
 * Added CreateBatchToSpaceNd implementation to NeonWorkloadFactory.
 * Added IsBatchToSpaceNdSupported implementation to NeonLayerSupport.
 * Enabled BatchToSpaceNd tests on Neon backend.

Signed-off-by: Mike Kelly <mike.kelly@arm.com>
Change-Id: I179feefaa67dc87a03fcbe52e5df100c1188f9a5

src/backends/neon/NeonLayerSupport.cpp
src/backends/neon/NeonLayerSupport.hpp
src/backends/neon/NeonWorkloadFactory.cpp
src/backends/neon/backend.mk
src/backends/neon/test/NeonLayerTests.cpp
src/backends/neon/workloads/CMakeLists.txt
src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.cpp [new file with mode: 0644]
src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.hpp [new file with mode: 0644]
src/backends/neon/workloads/NeonWorkloads.hpp

index b8725be..7d6e6d8 100644 (file)
@@ -24,6 +24,7 @@
 #include "workloads/NeonActivationWorkload.hpp"
 #include "workloads/NeonArgMinMaxWorkload.hpp"
 #include "workloads/NeonBatchNormalizationWorkload.hpp"
+#include "workloads/NeonBatchToSpaceNdWorkload.hpp"
 #include "workloads/NeonConvolution2dWorkload.hpp"
 #include "workloads/NeonDepthToSpaceWorkload.hpp"
 #include "workloads/NeonDepthwiseConvolutionWorkload.hpp"
@@ -193,6 +194,18 @@ bool NeonLayerSupport::IsBatchNormalizationSupported(const TensorInfo& input,
                                    descriptor);
 }
 
+bool NeonLayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input,
+                                                 const TensorInfo& output,
+                                                 const BatchToSpaceNdDescriptor& descriptor,
+                                                 Optional<std::string&> reasonIfUnsupported) const
+{
+    FORWARD_WORKLOAD_VALIDATE_FUNC(NeonBatchToSpaceNdWorkloadValidate,
+                                   reasonIfUnsupported,
+                                   input,
+                                   output,
+                                   descriptor);
+}
+
 bool NeonLayerSupport::IsComparisonSupported(const TensorInfo& input0,
                                              const TensorInfo& input1,
                                              const TensorInfo& output,
index 56a70c4..d4f0051 100644 (file)
@@ -41,6 +41,11 @@ public:
                                        const BatchNormalizationDescriptor& descriptor,
                                        Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
 
+    bool IsBatchToSpaceNdSupported(const TensorInfo& input,
+                                   const TensorInfo& output,
+                                   const BatchToSpaceNdDescriptor& descriptor,
+                                   Optional<std::string&> reasonIfUnsupported = EmptyOptional()) const override;
+
     bool IsComparisonSupported(const TensorInfo& input0,
                                const TensorInfo& input1,
                                const TensorInfo& output,
index cb2e88e..38e471f 100644 (file)
@@ -133,7 +133,7 @@ std::unique_ptr<armnn::IWorkload> NeonWorkloadFactory::CreateBatchNormalization(
 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor,
                                                                      const WorkloadInfo& info) const
 {
-    return MakeWorkloadHelper<NullWorkload, NullWorkload>(descriptor, info);
+    return std::make_unique<NeonBatchToSpaceNdWorkload>(descriptor, info);
 }
 
 std::unique_ptr<IWorkload> NeonWorkloadFactory::CreateComparison(const ComparisonQueueDescriptor& descriptor,
index 740cbcd..1c572e6 100644 (file)
@@ -26,6 +26,7 @@ BACKEND_SOURCES := \
         workloads/NeonAdditionWorkload.cpp \
         workloads/NeonArgMinMaxWorkload.cpp \
         workloads/NeonBatchNormalizationWorkload.cpp \
+        workloads/NeonBatchToSpaceNdWorkload.cpp \
         workloads/NeonConcatWorkload.cpp \
         workloads/NeonConstantWorkload.cpp \
         workloads/NeonConvertFp16ToFp32Workload.cpp \
index 1b25cad..1a9d7a9 100644 (file)
@@ -27,6 +27,23 @@ using FactoryType = NeonWorkloadFactory;
 // ============================================================================
 // UNIT tests
 
+// BatchToSpace
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcFloat321, BatchToSpaceNdNhwcTest1<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcFloat322, BatchToSpaceNdNhwcTest2<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcFloat323, BatchToSpaceNdNhwcTest3<DataType::Float32>)
+
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat321, BatchToSpaceNdNchwTest1<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat322, BatchToSpaceNdNchwTest2<DataType::Float32>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwFloat323, BatchToSpaceNdNchwTest3<DataType::Float32>)
+
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint1, BatchToSpaceNdNhwcTest1<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint2, BatchToSpaceNdNhwcTest2<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNhwcUint3, BatchToSpaceNdNhwcTest3<DataType::QAsymmU8>)
+
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwUint1, BatchToSpaceNdNchwTest1<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwUint2, BatchToSpaceNdNchwTest2<DataType::QAsymmU8>)
+ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwUint3, BatchToSpaceNdNchwTest3<DataType::QAsymmU8>)
+
 // Convolution
 ARMNN_AUTO_TEST_CASE(SimpleConvolution1d, Convolution1dTest, true)
 
index 46b5332..02ffedc 100644 (file)
@@ -14,6 +14,8 @@ list(APPEND armnnNeonBackendWorkloads_sources
     NeonArgMinMaxWorkload.hpp
     NeonBatchNormalizationWorkload.cpp
     NeonBatchNormalizationWorkload.hpp
+    NeonBatchToSpaceNdWorkload.cpp
+    NeonBatchToSpaceNdWorkload.hpp
     NeonConcatWorkload.cpp
     NeonConcatWorkload.hpp
     NeonConstantWorkload.cpp
diff --git a/src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.cpp b/src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.cpp
new file mode 100644 (file)
index 0000000..a6e7aa4
--- /dev/null
@@ -0,0 +1,67 @@
+//
+// Copyright © 2020 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "NeonBatchToSpaceNdWorkload.hpp"
+
+#include "NeonWorkloadUtils.hpp"
+#include <ResolveType.hpp>
+
+namespace armnn
+{
+
+using namespace armcomputetensorutils;
+
+arm_compute::Status NeonBatchToSpaceNdWorkloadValidate(const TensorInfo& input,
+                                                       const TensorInfo& output,
+                                                       const BatchToSpaceNdDescriptor& desc)
+{
+    const arm_compute::TensorInfo aclInputInfo = BuildArmComputeTensorInfo(input, desc.m_DataLayout);
+    const arm_compute::TensorInfo aclOutputInfo = BuildArmComputeTensorInfo(output, desc.m_DataLayout);
+
+    // ArmNN blockShape is [H, W] Cl asks for W, H
+    int32_t blockHeight = boost::numeric_cast<int32_t>(desc.m_BlockShape[0]);
+    int32_t blockWidth = boost::numeric_cast<int32_t>(desc.m_BlockShape[1]);
+
+    const arm_compute::Status aclStatus = arm_compute::NEBatchToSpaceLayer::validate(&aclInputInfo,
+                                                                                     blockWidth,
+                                                                                     blockHeight,
+                                                                                     &aclOutputInfo);
+    return aclStatus;
+}
+
+NeonBatchToSpaceNdWorkload::NeonBatchToSpaceNdWorkload(const BatchToSpaceNdQueueDescriptor& desc,
+                                                       const WorkloadInfo& info)
+    : BaseWorkload<BatchToSpaceNdQueueDescriptor>(desc, info)
+{
+    m_Data.ValidateInputsOutputs("NeonBatchToSpaceNdWorkload", 1, 1);
+
+    arm_compute::ITensor& input  =
+            boost::polymorphic_pointer_downcast<IAclTensorHandle>(m_Data.m_Inputs[0])->GetTensor();
+    arm_compute::ITensor& output =
+            boost::polymorphic_pointer_downcast<IAclTensorHandle>(m_Data.m_Outputs[0])->GetTensor();
+
+    arm_compute::DataLayout aclDataLayout = ConvertDataLayout(m_Data.m_Parameters.m_DataLayout);
+    input.info()->set_data_layout(aclDataLayout);
+    output.info()->set_data_layout(aclDataLayout);
+
+    // ArmNN blockShape is [H, W] Cl asks for W, H
+    int32_t blockHeight = boost::numeric_cast<int32_t>(desc.m_Parameters.m_BlockShape[0]);
+    int32_t blockWidth = boost::numeric_cast<int32_t>(desc.m_Parameters.m_BlockShape[1]);
+
+    m_Layer.reset(new arm_compute::NEBatchToSpaceLayer());
+    m_Layer->configure(&input, blockWidth, blockHeight, &output);
+    m_Layer->prepare();
+}
+
+void NeonBatchToSpaceNdWorkload::Execute() const
+{
+    if (m_Layer)
+    {
+        ARMNN_SCOPED_PROFILING_EVENT_NEON("NeonSpaceToBatchNdWorkload_Execute");
+        m_Layer->run();
+    }
+}
+
+} //namespace armnn
diff --git a/src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.hpp b/src/backends/neon/workloads/NeonBatchToSpaceNdWorkload.hpp
new file mode 100644 (file)
index 0000000..dd146e5
--- /dev/null
@@ -0,0 +1,35 @@
+//
+// Copyright © 2020 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#pragma once
+
+#include <armnn/Tensor.hpp>
+#include <armnn/Descriptors.hpp>
+
+#include <backendsCommon/Workload.hpp>
+
+#include <arm_compute/runtime/NEON/functions/NEBatchToSpaceLayer.h>
+
+namespace armnn
+{
+
+arm_compute::Status NeonBatchToSpaceNdWorkloadValidate(const TensorInfo& input,
+                                                       const TensorInfo& output,
+                                                       const BatchToSpaceNdDescriptor& descriptor);
+
+class NeonBatchToSpaceNdWorkload : public BaseWorkload<BatchToSpaceNdQueueDescriptor>
+{
+public:
+    using BaseWorkload<BatchToSpaceNdQueueDescriptor>::BaseWorkload;
+
+    NeonBatchToSpaceNdWorkload(const BatchToSpaceNdQueueDescriptor& descriptor, const WorkloadInfo& info);
+
+    virtual void Execute() const override;
+
+private:
+    mutable std::unique_ptr<arm_compute::NEBatchToSpaceLayer> m_Layer;
+};
+
+}
index 39cf044..b08483c 100644 (file)
@@ -10,6 +10,7 @@
 #include "NeonDivisionWorkload.hpp"
 #include "NeonArgMinMaxWorkload.hpp"
 #include "NeonBatchNormalizationWorkload.hpp"
+#include "NeonBatchToSpaceNdWorkload.hpp"
 #include "NeonConstantWorkload.hpp"
 #include "NeonConvertFp16ToFp32Workload.hpp"
 #include "NeonConvertFp32ToFp16Workload.hpp"