From 73f66421c6719c007325b69d51ca73dd58eb8c33 Mon Sep 17 00:00:00 2001 From: Aron Virginas-Tar Date: Mon, 23 Sep 2019 19:11:59 +0100 Subject: IVGCVSW-3885 Add reference workload for DepthToSpace Signed-off-by: Aron Virginas-Tar Change-Id: Id937dc4425884ad1985dcdfaae8bf3fb64f0c766 --- src/backends/backendsCommon/common.mk | 1 + src/backends/backendsCommon/test/CMakeLists.txt | 2 + src/backends/backendsCommon/test/LayerTests.hpp | 1 + .../test/layerTests/DepthToSpaceTestImpl.cpp | 342 +++++++++++++++++++++ .../test/layerTests/DepthToSpaceTestImpl.hpp | 36 +++ src/backends/reference/RefLayerSupport.cpp | 28 ++ src/backends/reference/RefLayerSupport.hpp | 5 + src/backends/reference/RefWorkloadFactory.cpp | 6 + src/backends/reference/RefWorkloadFactory.hpp | 3 + src/backends/reference/backend.mk | 2 + src/backends/reference/test/RefLayerTests.cpp | 40 +++ src/backends/reference/workloads/CMakeLists.txt | 4 + src/backends/reference/workloads/DepthToSpace.cpp | 79 +++++ src/backends/reference/workloads/DepthToSpace.hpp | 20 ++ .../workloads/RefDepthToSpaceWorkload.cpp | 27 ++ .../workloads/RefDepthToSpaceWorkload.hpp | 20 ++ src/backends/reference/workloads/RefWorkloads.hpp | 4 +- 17 files changed, 619 insertions(+), 1 deletion(-) create mode 100644 src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp create mode 100644 src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp create mode 100644 src/backends/reference/workloads/DepthToSpace.cpp create mode 100644 src/backends/reference/workloads/DepthToSpace.hpp create mode 100644 src/backends/reference/workloads/RefDepthToSpaceWorkload.cpp create mode 100644 src/backends/reference/workloads/RefDepthToSpaceWorkload.hpp (limited to 'src') diff --git a/src/backends/backendsCommon/common.mk b/src/backends/backendsCommon/common.mk index abf924aca5..343af5a019 100644 --- a/src/backends/backendsCommon/common.mk +++ b/src/backends/backendsCommon/common.mk @@ -45,6 +45,7 @@ COMMON_TEST_SOURCES := \ test/layerTests/ConvertFp16ToFp32TestImpl.cpp \ test/layerTests/ConvertFp32ToFp16TestImpl.cpp \ test/layerTests/DebugTestImpl.cpp \ + test/layerTests/DepthToSpaceTestImpl.cpp \ test/layerTests/DequantizeTestImpl.cpp \ test/layerTests/DivisionTestImpl.cpp \ test/layerTests/EqualTestImpl.cpp \ diff --git a/src/backends/backendsCommon/test/CMakeLists.txt b/src/backends/backendsCommon/test/CMakeLists.txt index 0cebf90319..481d7d8423 100644 --- a/src/backends/backendsCommon/test/CMakeLists.txt +++ b/src/backends/backendsCommon/test/CMakeLists.txt @@ -63,6 +63,8 @@ list(APPEND armnnBackendsCommonUnitTests_sources layerTests/ConvertFp32ToFp16TestImpl.hpp layerTests/DebugTestImpl.cpp layerTests/DebugTestImpl.hpp + layerTests/DepthToSpaceTestImpl.cpp + layerTests/DepthToSpaceTestImpl.hpp layerTests/DequantizeTestImpl.cpp layerTests/DequantizeTestImpl.hpp layerTests/DetectionPostProcessTestImpl.hpp diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp index 14ff26610f..84125b55d3 100644 --- a/src/backends/backendsCommon/test/LayerTests.hpp +++ b/src/backends/backendsCommon/test/LayerTests.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp new file mode 100644 index 0000000000..9588f560ef --- /dev/null +++ b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.cpp @@ -0,0 +1,342 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "DepthToSpaceTestImpl.hpp" + +#include + +#include + +#include +#include + +#include + +namespace +{ + +template +LayerTestResult DepthToSpaceTestImpl( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::TensorInfo& inputInfo, + armnn::TensorInfo& outputInfo, + std::vector& inputData, + std::vector& expectedOutputData, + armnn::DepthToSpaceQueueDescriptor descriptor, + const float qScale = 1.0f, + const int32_t qOffset = 0) +{ + const armnn::PermutationVector permVector{0, 2, 3, 1}; + + if (descriptor.m_Parameters.m_DataLayout == armnn::DataLayout::NCHW) + { + inputInfo = armnnUtils::Permuted(inputInfo, permVector); + outputInfo = armnnUtils::Permuted(outputInfo, permVector); + + constexpr size_t typeSize = sizeof(float); + + std::vector inputTmp(inputData.size()); + armnnUtils::Permute(inputInfo.GetShape(), permVector, inputData.data(), inputTmp.data(), typeSize); + inputData = inputTmp; + + std::vector outputTmp(expectedOutputData.size()); + armnnUtils::Permute(outputInfo.GetShape(), permVector, expectedOutputData.data(), outputTmp.data(), typeSize); + expectedOutputData = outputTmp; + } + + if(armnn::IsQuantizedType()) + { + inputInfo.SetQuantizationScale(qScale); + inputInfo.SetQuantizationOffset(qOffset); + outputInfo.SetQuantizationScale(qScale); + outputInfo.SetQuantizationOffset(qOffset); + } + + boost::multi_array input = MakeTensor(inputInfo, QuantizedVector(qScale, qOffset, inputData)); + + LayerTestResult result(outputInfo); + result.outputExpected = MakeTensor(outputInfo, QuantizedVector(qScale, qOffset, expectedOutputData)); + + std::unique_ptr inputHandle = workloadFactory.CreateTensorHandle(inputInfo); + std::unique_ptr outputHandle = workloadFactory.CreateTensorHandle(outputInfo); + + armnn::WorkloadInfo info; + AddInputToWorkload(descriptor, info, inputInfo, inputHandle.get()); + AddOutputToWorkload(descriptor, info, outputInfo, outputHandle.get()); + + std::unique_ptr workload = workloadFactory.CreateDepthToSpace(descriptor, info); + + inputHandle->Allocate(); + outputHandle->Allocate(); + + CopyDataToITensorHandle(inputHandle.get(), input.origin()); + + workload->Execute(); + + CopyDataFromITensorHandle(result.output.origin(), outputHandle.get()); + return result; +} + +} // anonymous namespace + +template +LayerTestResult DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout) +{ + unsigned int inputShape[] = { 1, 1, 1, 8 }; + unsigned int outputShape[] = { 1, 2, 2, 2 }; + + // in: + // [[[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]]] + // + // out: + // [[[[1, 2, 3], [4, 5, 6]], + // [[7, 8, 9], [10, 11, 12]]]] + + std::vector input = { 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 7.f, 8.f }; + std::vector expectedOutput = input; + + armnn::DepthToSpaceQueueDescriptor desc; + desc.m_Parameters.m_DataLayout = dataLayout; + desc.m_Parameters.m_BlockSize = 2; + + armnn::TensorInfo inputInfo(4, inputShape, ArmnnType); + armnn::TensorInfo outputInfo(4, outputShape, ArmnnType); + + return DepthToSpaceTestImpl(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc); +} + +template +LayerTestResult DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout) +{ + unsigned int inputShape[] = { 1, 2, 2, 4 }; + unsigned int outputShape[] = { 1, 4, 4, 1 }; + + // in: + // [[[[1, 2, 3, 4], + // [5, 6, 7, 8]], + // [[9, 10, 11, 12], + // [13, 14, 15, 16]]]] + // + // out: + // [[[ [1], [2], [5], [6]], + // [ [3], [4], [7], [8]], + // [ [9], [10], [13], [14]], + // [ [11], [12], [15], [16]]]] + + std::vector input = + { + 1.f, 2.f, 3.f, 4.f, + + 5.f, 6.f, 7.f, 8.f, + + 9.f, 10.f, 11.f, 12.f, + + 13.f, 14.f, 15.f, 16.f + }; + + std::vector expectedOutput + { + 1.f, 2.f, 5.f, 6.f, + 3.f, 4.f, 7.f, 8.f, + 9.f, 10.f, 13.f, 14.f, + 11.f, 12.f, 15.f, 16.f + }; + + armnn::DepthToSpaceQueueDescriptor desc; + desc.m_Parameters.m_DataLayout = dataLayout; + desc.m_Parameters.m_BlockSize = 2; + + armnn::TensorInfo inputInfo(4, inputShape, ArmnnType); + armnn::TensorInfo outputInfo(4, outputShape, ArmnnType); + + return DepthToSpaceTestImpl(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc); +} + +template +LayerTestResult DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout) +{ + unsigned int inputShape[] = { 2, 1, 1, 4 }; + unsigned int outputShape[] = { 2, 2, 2, 1 }; + + std::vector input = + { + 1.f, 2.f, 3.f, 4.f, // batch 0 + 5.f, 6.f, 7.f, 8.f // batch 1 + }; + + std::vector expectedOutput = input; + + armnn::DepthToSpaceQueueDescriptor desc; + desc.m_Parameters.m_DataLayout = dataLayout; + desc.m_Parameters.m_BlockSize = 2; + + armnn::TensorInfo inputInfo(4, inputShape, ArmnnType); + armnn::TensorInfo outputInfo(4, outputShape, ArmnnType); + + return DepthToSpaceTestImpl(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc); +} + +template +LayerTestResult DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout) +{ + unsigned int inputShape[] = { 2, 2, 2, 4 }; + unsigned int outputShape[] = { 2, 4, 4, 1 }; + + std::vector input = + { + 1.f, 2.f, 3.f, 4.f, + + 5.f, 6.f, 7.f, 8.f, + + 9.f, 10.f, 11.f, 12.f, + + 13.f, 14.f, 15.f, 16.f, + + + 17.f, 18.f, 19.f, 20.f, + + 21.f, 22.f, 23.f, 24.f, + + 25.f, 26.f, 27.f, 28.f, + + 29.f, 30.f, 31.f, 32.f + }; + + std::vector expectedOutput + { + 1.f, 2.f, 5.f, 6.f, + 3.f, 4.f, 7.f, 8.f, + 9.f, 10.f, 13.f, 14.f, + 11.f, 12.f, 15.f, 16.f, + + + 17.f, 18.f, 21.f, 22.f, + 19.f, 20.f, 23.f, 24.f, + 25.f, 26.f, 29.f, 30.f, + 27.f, 28.f, 31.f, 32.f + }; + + armnn::DepthToSpaceQueueDescriptor desc; + desc.m_Parameters.m_DataLayout = dataLayout; + desc.m_Parameters.m_BlockSize = 2; + + armnn::TensorInfo inputInfo(4, inputShape, ArmnnType); + armnn::TensorInfo outputInfo(4, outputShape, ArmnnType); + + return DepthToSpaceTestImpl(workloadFactory, memoryManager, inputInfo, outputInfo, input, expectedOutput, desc); +} + +// Float32 +template LayerTestResult, 4> +DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +// Float16 +template LayerTestResult, 4> +DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +// QuantisedAsymm8 +template LayerTestResult, 4> +DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +// QuantisedSymm16 +template LayerTestResult, 4> +DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template LayerTestResult, 4> +DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); diff --git a/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp new file mode 100644 index 0000000000..4dbcd266d7 --- /dev/null +++ b/src/backends/backendsCommon/test/layerTests/DepthToSpaceTestImpl.hpp @@ -0,0 +1,36 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "LayerTestResult.hpp" + +#include + +#include +#include + +template> +LayerTestResult DepthToSpaceTest1( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template> +LayerTestResult DepthToSpaceTest2( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template> +LayerTestResult DepthToSpaceTest3( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); + +template> +LayerTestResult DepthToSpaceTest4( + armnn::IWorkloadFactory& workloadFactory, + const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager, + armnn::DataLayout dataLayout); diff --git a/src/backends/reference/RefLayerSupport.cpp b/src/backends/reference/RefLayerSupport.cpp index 14183a7b68..06da77603d 100644 --- a/src/backends/reference/RefLayerSupport.cpp +++ b/src/backends/reference/RefLayerSupport.cpp @@ -466,6 +466,34 @@ bool RefLayerSupport::IsDebugSupported(const TensorInfo& input, return supported; } +bool RefLayerSupport::IsDepthToSpaceSupported(const TensorInfo& input, + const TensorInfo& output, + const DepthToSpaceDescriptor& descriptor, + Optional reasonIfUnsupported) const +{ + ignore_unused(descriptor); + bool supported = true; + + std::array supportedTypes = + { + DataType::Float32, + DataType::Float16, + DataType::QuantisedAsymm8, + DataType::QuantisedSymm16 + }; + + supported &= CheckSupportRule(TypeAnyOf(input, supportedTypes), reasonIfUnsupported, + "Reference DepthToSpace: input type not supported"); + + supported &= CheckSupportRule(TypeAnyOf(output, supportedTypes), reasonIfUnsupported, + "Reference DepthToSpace: output type not supported"); + + supported &= CheckSupportRule(TypesAreEqual(input, output), reasonIfUnsupported, + "Reference DepthToSpace: input and output types are mismatched"); + + return supported; +} + bool RefLayerSupport::IsDepthwiseConvolutionSupported(const TensorInfo& input, const TensorInfo& output, const DepthwiseConvolution2dDescriptor& descriptor, diff --git a/src/backends/reference/RefLayerSupport.hpp b/src/backends/reference/RefLayerSupport.hpp index 9e8c914512..cc9478d871 100644 --- a/src/backends/reference/RefLayerSupport.hpp +++ b/src/backends/reference/RefLayerSupport.hpp @@ -72,6 +72,11 @@ public: const TensorInfo& output, Optional reasonIfUnsupported = EmptyOptional()) const override; + bool IsDepthToSpaceSupported(const TensorInfo& input, + const TensorInfo& output, + const DepthToSpaceDescriptor& descriptor, + Optional reasonIfUnsupported = EmptyOptional()) const override; + bool IsDepthwiseConvolutionSupported(const TensorInfo& input, const TensorInfo& output, const DepthwiseConvolution2dDescriptor& descriptor, diff --git a/src/backends/reference/RefWorkloadFactory.cpp b/src/backends/reference/RefWorkloadFactory.cpp index 480b7e24ac..254b221cc8 100644 --- a/src/backends/reference/RefWorkloadFactory.cpp +++ b/src/backends/reference/RefWorkloadFactory.cpp @@ -193,6 +193,12 @@ std::unique_ptr RefWorkloadFactory::CreateConvolution2d( return std::make_unique(descriptor, info); } +std::unique_ptr RefWorkloadFactory::CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor, + const WorkloadInfo& info) const +{ + return std::make_unique(descriptor, info); +} + std::unique_ptr RefWorkloadFactory::CreateDepthwiseConvolution2d( const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const { diff --git a/src/backends/reference/RefWorkloadFactory.hpp b/src/backends/reference/RefWorkloadFactory.hpp index 033f81779d..e8e11e027e 100644 --- a/src/backends/reference/RefWorkloadFactory.hpp +++ b/src/backends/reference/RefWorkloadFactory.hpp @@ -94,6 +94,9 @@ public: std::unique_ptr CreateConvolution2d(const Convolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; + std::unique_ptr CreateDepthToSpace(const DepthToSpaceQueueDescriptor& descriptor, + const WorkloadInfo& info) const override; + std::unique_ptr CreateDepthwiseConvolution2d(const DepthwiseConvolution2dQueueDescriptor& descriptor, const WorkloadInfo& info) const override; diff --git a/src/backends/reference/backend.mk b/src/backends/reference/backend.mk index fd0df27907..597fba8d7d 100644 --- a/src/backends/reference/backend.mk +++ b/src/backends/reference/backend.mk @@ -29,6 +29,7 @@ BACKEND_SOURCES := \ workloads/Broadcast.cpp \ workloads/ConvImpl.cpp \ workloads/Debug.cpp \ + workloads/DepthToSpace.cpp \ workloads/DetectionPostProcess.cpp \ workloads/ElementwiseFunction.cpp \ workloads/FullyConnected.cpp \ @@ -50,6 +51,7 @@ BACKEND_SOURCES := \ workloads/RefConvertFp32ToFp16Workload.cpp \ workloads/RefConvolution2dWorkload.cpp \ workloads/RefDebugWorkload.cpp \ + workloads/RefDepthToSpaceWorkload.cpp \ workloads/RefDepthwiseConvolution2dWorkload.cpp \ workloads/RefDequantizeWorkload.cpp \ workloads/RefDetectionPostProcessWorkload.cpp \ diff --git a/src/backends/reference/test/RefLayerTests.cpp b/src/backends/reference/test/RefLayerTests.cpp index a5164f072b..901017ad99 100644 --- a/src/backends/reference/test/RefLayerTests.cpp +++ b/src/backends/reference/test/RefLayerTests.cpp @@ -1136,6 +1136,46 @@ ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_5, BatchToSpaceNdNchwTest5) ARMNN_AUTO_TEST_CASE(BatchToSpaceNdNchwQsymm16_7, BatchToSpaceNdNchwTest7) +// DepthToSpace +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat32_1, DepthToSpaceTest1, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat32_2, DepthToSpaceTest2, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat32_3, DepthToSpaceTest3, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat32_4, DepthToSpaceTest4, DataLayout::NCHW); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat16_1, DepthToSpaceTest1, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat16_2, DepthToSpaceTest2, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat16_3, DepthToSpaceTest3, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwFloat16_4, DepthToSpaceTest4, DataLayout::NCHW); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwUint8_1, DepthToSpaceTest1, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwUint8_2, DepthToSpaceTest2, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwUint8_3, DepthToSpaceTest3, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwUint8_4, DepthToSpaceTest4, DataLayout::NCHW); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwInt16_1, DepthToSpaceTest1, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwInt16_2, DepthToSpaceTest2, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwInt16_3, DepthToSpaceTest3, DataLayout::NCHW); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNchwInt16_4, DepthToSpaceTest4, DataLayout::NCHW); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat32_1, DepthToSpaceTest1, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat32_2, DepthToSpaceTest2, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat32_3, DepthToSpaceTest3, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat32_4, DepthToSpaceTest4, DataLayout::NHWC); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat16_1, DepthToSpaceTest1, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat16_2, DepthToSpaceTest2, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat16_3, DepthToSpaceTest3, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcFloat16_4, DepthToSpaceTest4, DataLayout::NHWC); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcUint8_1, DepthToSpaceTest1, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcUint8_2, DepthToSpaceTest2, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcUint8_3, DepthToSpaceTest3, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcUint8_4, DepthToSpaceTest4, DataLayout::NHWC); + +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcInt16_1, DepthToSpaceTest1, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcInt16_2, DepthToSpaceTest2, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcInt16_3, DepthToSpaceTest3, DataLayout::NHWC); +ARMNN_AUTO_TEST_CASE(DepthToSpaceNhwcInt16_4, DepthToSpaceTest4, DataLayout::NHWC); // SpaceToDepth ARMNN_AUTO_TEST_CASE(SpaceToDepthNchwAsymmQ8, SpaceToDepthNchwAsymmQ8Test) diff --git a/src/backends/reference/workloads/CMakeLists.txt b/src/backends/reference/workloads/CMakeLists.txt index 83444eda1f..c2eb025789 100644 --- a/src/backends/reference/workloads/CMakeLists.txt +++ b/src/backends/reference/workloads/CMakeLists.txt @@ -24,6 +24,8 @@ list(APPEND armnnRefBackendWorkloads_sources Debug.cpp Debug.hpp Decoders.hpp + DepthToSpace.cpp + DepthToSpace.hpp DetectionPostProcess.cpp DetectionPostProcess.hpp ElementwiseFunction.cpp @@ -71,6 +73,8 @@ list(APPEND armnnRefBackendWorkloads_sources RefElementwiseWorkload.hpp RefDebugWorkload.cpp RefDebugWorkload.hpp + RefDepthToSpaceWorkload.cpp + RefDepthToSpaceWorkload.hpp RefDepthwiseConvolution2dWorkload.cpp RefDepthwiseConvolution2dWorkload.hpp RefDequantizeWorkload.cpp diff --git a/src/backends/reference/workloads/DepthToSpace.cpp b/src/backends/reference/workloads/DepthToSpace.cpp new file mode 100644 index 0000000000..046bd47a6f --- /dev/null +++ b/src/backends/reference/workloads/DepthToSpace.cpp @@ -0,0 +1,79 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "DepthToSpace.hpp" + +#include +#include + +#include + +using namespace armnnUtils; + +namespace armnn +{ + +void DepthToSpace(const TensorInfo& inputInfo, + const DepthToSpaceDescriptor& descriptor, + const void* inputData, + void* outputData, + unsigned int dataTypeSize) +{ + const unsigned int blockSize = descriptor.m_BlockSize; + BOOST_ASSERT(blockSize != 0u); + + const TensorShape& inputShape = inputInfo.GetShape(); + const unsigned int batches = inputShape[0]; + + armnnUtils::DataLayoutIndexed dataLayoutIndexed(descriptor.m_DataLayout); + const unsigned int inDepth = inputShape[dataLayoutIndexed.GetChannelsIndex()]; + const unsigned int inHeight = inputShape[dataLayoutIndexed.GetHeightIndex()]; + const unsigned int inWidth = inputShape[dataLayoutIndexed.GetWidthIndex()]; + + const unsigned int outDepth = inDepth / (blockSize * blockSize); + + // The 4D input data can be interpreted as 6D (implicitly reshaped) as follows: + // + // [batch, block size, block size, inDepth, inHeight, inWidth] for NCHW and + // [batch, inHeight, inWidth, blockSize, blockSize, outDepth] for NHWC. + // + // DepthToSpace can then be implemented as a permutation in 6D resulting in + // the following shapes: + // + // [batch, outDepth, inHeight, blockSize, inWidth, blockSize] for NCHW and + // [batch, inHeight, blockSize, inWidth, blockSize, outDepth] for NHWC. + // + // NOTE: + // Since 6D tensors are not currently supported, in practice we need to handle each + // batch separately and execute 5D permutations + + TensorShape permDestShape; + std::initializer_list permVector; + if (descriptor.m_DataLayout == DataLayout::NCHW) + { + permDestShape = TensorShape({ outDepth, inHeight, blockSize, inWidth, blockSize }); + permVector = { 2, 4, 0, 1, 3 }; + } + else + { + permDestShape = TensorShape({ inHeight, blockSize, inWidth, blockSize, outDepth }); + permVector = { 0, 2, 1, 3, 4 }; + } + + const unsigned int numElementsPerBatch = inputShape.GetNumElements() / batches; + + for (unsigned int batchIndex = 0u; batchIndex < batches; ++batchIndex) + { + const uintptr_t batchDataOffset = batchIndex * (numElementsPerBatch * dataTypeSize); + + armnnUtils::Permute(permDestShape, + PermutationVector(permVector), + static_cast(reinterpret_cast(inputData) + batchDataOffset), + static_cast(reinterpret_cast(outputData) + batchDataOffset), + dataTypeSize); + } +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/DepthToSpace.hpp b/src/backends/reference/workloads/DepthToSpace.hpp new file mode 100644 index 0000000000..a1805c02be --- /dev/null +++ b/src/backends/reference/workloads/DepthToSpace.hpp @@ -0,0 +1,20 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include +#include + +namespace armnn +{ + +void DepthToSpace(const TensorInfo& inputInfo, + const DepthToSpaceDescriptor& descriptor, + const void* inputData, + void* outputData, + unsigned int dataTypeSize); + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefDepthToSpaceWorkload.cpp b/src/backends/reference/workloads/RefDepthToSpaceWorkload.cpp new file mode 100644 index 0000000000..93c1120a1c --- /dev/null +++ b/src/backends/reference/workloads/RefDepthToSpaceWorkload.cpp @@ -0,0 +1,27 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#include "RefDepthToSpaceWorkload.hpp" + +#include "DepthToSpace.hpp" +#include "RefWorkloadUtils.hpp" + +namespace armnn +{ + +void RefDepthToSpaceWorkload::Execute() const +{ + ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefDepthToSpaceWorkload_Execute"); + + const TensorInfo inputInfo = GetTensorInfo(m_Data.m_Inputs[0]); + + DepthToSpace(inputInfo, + m_Data.m_Parameters, + m_Data.m_Inputs[0]->Map(), + m_Data.m_Outputs[0]->Map(), + GetDataTypeSize(inputInfo.GetDataType())); +} + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefDepthToSpaceWorkload.hpp b/src/backends/reference/workloads/RefDepthToSpaceWorkload.hpp new file mode 100644 index 0000000000..327cd9d78d --- /dev/null +++ b/src/backends/reference/workloads/RefDepthToSpaceWorkload.hpp @@ -0,0 +1,20 @@ +// +// Copyright © 2019 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// + +#pragma once + +#include "backendsCommon/Workload.hpp" + +namespace armnn +{ + +class RefDepthToSpaceWorkload : public BaseWorkload +{ +public: + using BaseWorkload::BaseWorkload; + virtual void Execute() const override; +}; + +} // namespace armnn diff --git a/src/backends/reference/workloads/RefWorkloads.hpp b/src/backends/reference/workloads/RefWorkloads.hpp index b4721b11aa..94592cb53e 100644 --- a/src/backends/reference/workloads/RefWorkloads.hpp +++ b/src/backends/reference/workloads/RefWorkloads.hpp @@ -25,9 +25,11 @@ #include "RefConcatWorkload.hpp" #include "RefConvertFp16ToFp32Workload.hpp" #include "RefConvertFp32ToFp16Workload.hpp" +#include "RefDebugWorkload.hpp" +#include "RefDepthToSpaceWorkload.hpp" #include "RefDepthwiseConvolution2dWorkload.hpp" +#include "RefDequantizeWorkload.hpp" #include "RefDetectionPostProcessWorkload.hpp" -#include "RefDebugWorkload.hpp" #include "RefDequantizeWorkload.hpp" #include "RefElementwiseWorkload.hpp" #include "RefFullyConnectedWorkload.hpp" -- cgit v1.2.1