diff options
author | Éanna Ó Catháin <eanna.ocathain@arm.com> | 2018-11-12 11:36:34 +0000 |
---|---|---|
committer | Les Bell <les.bell@arm.com> | 2018-11-12 13:08:37 +0000 |
commit | 4e1e136cce3fca73ba49b570cfcb620f4ec574da (patch) | |
tree | 1fe9fcbb6a9dbafc12aa99ac543bc0da636a1cd1 /src/backends/backendsCommon | |
parent | f97debb95cbc7e0bbc60e66e5463ede517cac61b (diff) | |
download | armnn-4e1e136cce3fca73ba49b570cfcb620f4ec574da.tar.gz |
IVGCVSW-2054: BATCH_TO_SPACE_ND Reference implementation and Unit tests.
Change-Id: I13c6728dbb60643d0e086d171225c5d802987f92
Diffstat (limited to 'src/backends/backendsCommon')
-rw-r--r-- | src/backends/backendsCommon/ILayerSupport.cpp | 8 | ||||
-rw-r--r-- | src/backends/backendsCommon/WorkloadData.cpp | 8 | ||||
-rw-r--r-- | src/backends/backendsCommon/WorkloadData.hpp | 4 | ||||
-rw-r--r-- | src/backends/backendsCommon/WorkloadFactory.cpp | 12 | ||||
-rw-r--r-- | src/backends/backendsCommon/WorkloadFactory.hpp | 3 | ||||
-rw-r--r-- | src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp | 16 | ||||
-rwxr-xr-x | src/backends/backendsCommon/test/LayerTests.cpp | 167 | ||||
-rw-r--r-- | src/backends/backendsCommon/test/LayerTests.hpp | 6 |
8 files changed, 223 insertions, 1 deletions
diff --git a/src/backends/backendsCommon/ILayerSupport.cpp b/src/backends/backendsCommon/ILayerSupport.cpp index ebfff5d429..2cd57b7ad7 100644 --- a/src/backends/backendsCommon/ILayerSupport.cpp +++ b/src/backends/backendsCommon/ILayerSupport.cpp @@ -59,6 +59,14 @@ bool ILayerSupport::IsBatchNormalizationSupported(const TensorInfo& input, return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); } +bool ILayerSupport::IsBatchToSpaceNdSupported(const TensorInfo& input, + const TensorInfo& output, + const BatchToSpaceNdDescriptor& descriptor, + Optional<std::string&> reasonIfUnsupported) const +{ + return DefaultLayerSupport(__func__, __FILE__, __LINE__, reasonIfUnsupported); +} + bool ILayerSupport::IsConstantSupported(const TensorInfo& output, Optional<std::string&> reasonIfUnsupported) const { diff --git a/src/backends/backendsCommon/WorkloadData.cpp b/src/backends/backendsCommon/WorkloadData.cpp index 7c02947b32..9fbdfe94c2 100644 --- a/src/backends/backendsCommon/WorkloadData.cpp +++ b/src/backends/backendsCommon/WorkloadData.cpp @@ -918,4 +918,10 @@ void PadQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const } } -} //namespace armnn +void BatchToSpaceNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const +{ + ValidateSingleInput(workloadInfo, "BatchToSpaceNdQueueDescriptor"); + ValidateSingleOutput(workloadInfo, "BatchToSpaceNdQueueDescriptor"); +} + +} //namespace armnn
\ No newline at end of file diff --git a/src/backends/backendsCommon/WorkloadData.hpp b/src/backends/backendsCommon/WorkloadData.hpp index 7fb8855bf6..d54a71aa8c 100644 --- a/src/backends/backendsCommon/WorkloadData.hpp +++ b/src/backends/backendsCommon/WorkloadData.hpp @@ -335,4 +335,8 @@ struct ConvertFp32ToFp16QueueDescriptor : QueueDescriptor void Validate(const WorkloadInfo& workloadInfo) const; }; +struct BatchToSpaceNdQueueDescriptor : QueueDescriptorWithParameters<BatchToSpaceNdDescriptor> +{ + void Validate(const WorkloadInfo& workloadInfo) const; +}; } //namespace armnn diff --git a/src/backends/backendsCommon/WorkloadFactory.cpp b/src/backends/backendsCommon/WorkloadFactory.cpp index 9f974522aa..ec30f34880 100644 --- a/src/backends/backendsCommon/WorkloadFactory.cpp +++ b/src/backends/backendsCommon/WorkloadFactory.cpp @@ -116,6 +116,18 @@ bool IWorkloadFactory::IsLayerSupported(const BackendId& backendId, reason); break; } + case LayerType::BatchToSpaceNd: + { + const TensorInfo& input = layer.GetInputSlot(0).GetConnection()->GetTensorInfo(); + const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); + auto cLayer = boost::polymorphic_downcast<const BatchToSpaceNdLayer*>(&layer); + + result = layerSupportObject->IsBatchToSpaceNdSupported(OverrideDataType(input, dataType), + OverrideDataType(output, dataType), + cLayer->GetParameters(), + reason); + break; + } case LayerType::Constant: { const TensorInfo& output = layer.GetOutputSlot(0).GetTensorInfo(); diff --git a/src/backends/backendsCommon/WorkloadFactory.hpp b/src/backends/backendsCommon/WorkloadFactory.hpp index 67876e13a2..e3be9f501f 100644 --- a/src/backends/backendsCommon/WorkloadFactory.hpp +++ b/src/backends/backendsCommon/WorkloadFactory.hpp @@ -97,6 +97,9 @@ public: virtual std::unique_ptr<IWorkload> CreateBatchNormalization(const BatchNormalizationQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; + virtual std::unique_ptr<IWorkload> CreateBatchToSpaceNd(const BatchToSpaceNdQueueDescriptor& descriptor, + const WorkloadInfo& Info) const = 0; + virtual std::unique_ptr<IWorkload> CreateMemCopy(const MemCopyQueueDescriptor& descriptor, const WorkloadInfo& info) const = 0; diff --git a/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp b/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp index 2c992bc10b..25079058f6 100644 --- a/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp +++ b/src/backends/backendsCommon/test/IsLayerSupportedTestImpl.hpp @@ -92,6 +92,20 @@ struct DummyLayer<armnn::BatchNormalizationLayer> }; template<> +struct DummyLayer<armnn::BatchToSpaceNdLayer> +{ + DummyLayer() + { + m_Layer = dummyGraph.AddLayer<armnn::BatchToSpaceNdLayer>(armnn::BatchToSpaceNdDescriptor(), ""); + } + ~DummyLayer() + { + dummyGraph.EraseLayer(m_Layer); + } + armnn::BatchToSpaceNdLayer* m_Layer; +}; + +template<> struct DummyLayer<armnn::ConstantLayer, void> { DummyLayer() @@ -306,6 +320,8 @@ DECLARE_LAYER_POLICY_1_PARAM(Addition) DECLARE_LAYER_POLICY_2_PARAM(BatchNormalization) +DECLARE_LAYER_POLICY_2_PARAM(BatchToSpaceNd) + DECLARE_LAYER_POLICY_1_PARAM(Constant) DECLARE_LAYER_POLICY_1_PARAM(ConvertFp16ToFp32) diff --git a/src/backends/backendsCommon/test/LayerTests.cpp b/src/backends/backendsCommon/test/LayerTests.cpp index cdc989fe6d..4a003036ca 100755 --- a/src/backends/backendsCommon/test/LayerTests.cpp +++ b/src/backends/backendsCommon/test/LayerTests.cpp @@ -6169,3 +6169,170 @@ LayerTestResult<uint8_t, 4> SpaceToBatchNdPaddingNHWCUint8Test(armnn::IWorkloadF { return SpaceToBatchNdPaddingNHWCTest<uint8_t>(workloadFactory); } + +namespace { + +template<typename T, std::size_t InputDim, std::size_t OutputDim> +LayerTestResult<T, OutputDim> BatchToSpaceNdHelper(armnn::IWorkloadFactory &workloadFactory, + const armnn::DataLayout& dataLayout, + const unsigned int *inputShape, + const std::vector<T> &inputData, + const std::vector<unsigned int> &blockShape, + const std::vector<std::vector<unsigned int>> &crops, + const unsigned int *outputShape, + const std::vector<T> &outputData, + float scale = 1.0f, + int32_t offset = 0) + { + auto dataType = (std::is_same<T, uint8_t>::value ? armnn::DataType::QuantisedAsymm8 : armnn::DataType::Float32); + + armnn::TensorInfo inputTensorInfo(InputDim, inputShape, dataType); + armnn::TensorInfo outputTensorInfo(OutputDim, outputShape, dataType); + + inputTensorInfo.SetQuantizationScale(scale); + inputTensorInfo.SetQuantizationOffset(offset); + + outputTensorInfo.SetQuantizationScale(scale); + outputTensorInfo.SetQuantizationOffset(offset); + + auto input = MakeTensor<T, InputDim>(inputTensorInfo, inputData); + + LayerTestResult<T, OutputDim> result(outputTensorInfo); + result.outputExpected = MakeTensor<T, OutputDim>(outputTensorInfo, outputData); + + std::unique_ptr<armnn::ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo); + std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo); + + armnn::BatchToSpaceNdQueueDescriptor data; + data.m_Parameters.m_DataLayout = dataLayout; + data.m_Parameters.m_BlockShape = blockShape; + data.m_Parameters.m_Crops = crops; + armnn::WorkloadInfo info; + AddInputToWorkload(data, info, inputTensorInfo, inputHandle.get()); + AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get()); + + std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateBatchToSpaceNd(data, info); + + inputHandle->Allocate(); + outputHandle->Allocate(); + + CopyDataToITensorHandle(inputHandle.get(), input.origin()); + + workload->Execute(); + + CopyDataFromITensorHandle(&result.output[0][0][0][0], outputHandle.get()); + + return result; +} + +} // anonymous namespace + +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test1(armnn::IWorkloadFactory& workloadFactory) +{ + const unsigned int inputShape[] = {4, 2, 2, 1}; + const unsigned int outputShape[] = {1, 4, 4, 1 }; + + std::vector<float> input + ({ + // Batch 0, Height 0, Width (2) x Channel (1) + 1.0f, 3.0f, + // Batch 0, Height 1, Width (2) x Channel (1) + 9.0f, 11.0f, + + + // Batch 1, Height 0, Width (2) x Channel (1) + 2.0f, 4.0f, + // Batch 1, Height 1, Width (2) x Channel (1) + 10.0f, 12.0f, + + + // Batch 2, Height 0, Width (2) x Channel (1) + 5.0f, 7.0f, + // Batch 2, Height 1, Width (2) x Channel (1) + 13.0f, 15.0f, + + // Batch 3, Height 0, Width (2) x Channel (3) + 6.0f, 8.0f, + // Batch 3, Height 1, Width (2) x Channel (1) + 14.0f, 16.0f + }); + + std::vector<float> expectedOutput + ({ + 1.0f, 2.0f, 3.0f, 4.0f, + 5.0f, 6.0f, 7.0f, 8.0f, + 9.0f, 10.0f, 11.0f, 12.0f, + 13.0f, 14.0f, 15.0f, 16.0f + }); + + std::vector<unsigned int> blockShape {2, 2}; + std::vector<std::vector<unsigned int>> crops = {{0, 0}, {0, 0}}; + + return BatchToSpaceNdHelper<float, 4, 4>(workloadFactory, armnn::DataLayout::NHWC, inputShape, input, blockShape, + crops, outputShape, expectedOutput); +} + +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test2(armnn::IWorkloadFactory& workloadFactory) +{ + const unsigned int inputShape[] = {4, 1, 1, 1}; + const unsigned int outputShape[] = {1, 2, 2, 1}; + + std::vector<float> input + ({ + // Batch 0, Height 0, Width (2) x Channel (1) + 1.0f, 2.0f, 3.0f, 4.0f + }); + + std::vector<float> expectedOutput({1.0f, 2.0f, 3.0f, 4.0f}); + + std::vector<unsigned int> blockShape({2, 2}); + std::vector<std::vector<unsigned int>> crops = {{0, 0}, {0, 0}}; + + return BatchToSpaceNdHelper<float, 4, 4>(workloadFactory, armnn::DataLayout::NHWC, inputShape, input, blockShape, + crops, outputShape, expectedOutput); +} + +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test3(armnn::IWorkloadFactory& workloadFactory) +{ + const unsigned int inputShape[] = {4, 1, 1, 3}; + const unsigned int outputShape[] = {1, 2, 2, 3}; + + std::vector<float> input({ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f }); + + std::vector<float> expectedOutput({ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f }); + + std::vector<unsigned int> blockShape({2, 2}); + std::vector<std::vector<unsigned int>> crops = {{0, 0}, {0, 0}}; + + return BatchToSpaceNdHelper<float, 4, 4>(workloadFactory, armnn::DataLayout::NHWC, inputShape, input, blockShape, + crops, outputShape, expectedOutput); +} + +LayerTestResult<float, 4> BatchToSpaceNdNchwFloat32Test1(armnn::IWorkloadFactory &workloadFactory) +{ + const unsigned int inputShape[] = {4, 3, 1, 1}; + const unsigned int outputShape[] = {1, 3, 2, 2}; + + std::vector<float> input({ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, 10.0f, 11.0f, 12.0f }); + + std::vector<float> expectedOutput + ({ + // Batch 0, Channel 0, Height (2) x Width (2) + 1.0f, 4.0f, + 7.0f, 10.0f, + + // Batch 0, Channel 1, Height (2) x Width (2) + 2.0f, 5.0f, + 8.0f, 11.0f, + + // Batch 0, Channel 2, Height (2) x Width (2) + 3.0f, 6.0f, + 9.0f, 12.0f, + }); + + std::vector<unsigned int> blockShape({2, 2}); + std::vector<std::vector<unsigned int>> crops = {{0, 0}, {0, 0}}; + + return BatchToSpaceNdHelper<float, 4, 4>(workloadFactory, armnn::DataLayout::NCHW, inputShape, input, blockShape, + crops, outputShape, expectedOutput); +} diff --git a/src/backends/backendsCommon/test/LayerTests.hpp b/src/backends/backendsCommon/test/LayerTests.hpp index 66032c8f2a..cd8758e477 100644 --- a/src/backends/backendsCommon/test/LayerTests.hpp +++ b/src/backends/backendsCommon/test/LayerTests.hpp @@ -434,3 +434,9 @@ LayerTestResult<uint8_t, 4> SpaceToBatchNdSimpleNHWCUint8Test(armnn::IWorkloadFa LayerTestResult<uint8_t, 4> SpaceToBatchNdMultiChannelsNHWCUint8Test(armnn::IWorkloadFactory& workloadFactory); LayerTestResult<uint8_t, 4> SpaceToBatchNdMultiBlockNHWCUint8Test(armnn::IWorkloadFactory& workloadFactory); LayerTestResult<uint8_t, 4> SpaceToBatchNdPaddingNHWCUint8Test(armnn::IWorkloadFactory& workloadFactory); + +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test1(armnn::IWorkloadFactory& workloadFactory); +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test2(armnn::IWorkloadFactory& workloadFactory); +LayerTestResult<float, 4> BatchToSpaceNdNhwcFloat32Test3(armnn::IWorkloadFactory& workloadFactory); + +LayerTestResult<float, 4> BatchToSpaceNdNchwFloat32Test1(armnn::IWorkloadFactory &workloadFactory); |