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/armnn/layers/BatchToSpaceNdLayer.cpp | |
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/armnn/layers/BatchToSpaceNdLayer.cpp')
-rw-r--r-- | src/armnn/layers/BatchToSpaceNdLayer.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/armnn/layers/BatchToSpaceNdLayer.cpp b/src/armnn/layers/BatchToSpaceNdLayer.cpp new file mode 100644 index 0000000000..595ce4a7fe --- /dev/null +++ b/src/armnn/layers/BatchToSpaceNdLayer.cpp @@ -0,0 +1,89 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#include "BatchToSpaceNdLayer.hpp" + +#include "LayerCloneBase.hpp" +#include "LayerWithParameters.hpp" +#include "BatchToSpaceNdLayer.hpp" + +#include <armnn/TypesUtils.hpp> +#include <backendsCommon/CpuTensorHandle.hpp> +#include <backendsCommon/WorkloadData.hpp> +#include <backendsCommon/WorkloadFactory.hpp> + +namespace armnn +{ + +BatchToSpaceNdLayer::BatchToSpaceNdLayer(const armnn::BatchToSpaceNdDescriptor& param, const char* name) + : LayerWithParameters(1, 1, LayerType::BatchToSpaceNd, param, name) +{ +} + +std::unique_ptr<IWorkload> BatchToSpaceNdLayer::CreateWorkload(const Graph& graph, + const IWorkloadFactory& factory) const +{ + BatchToSpaceNdQueueDescriptor descriptor; + + return factory.CreateBatchToSpaceNd(descriptor, PrepInfoAndDesc(descriptor, graph)); +} + +BatchToSpaceNdLayer* BatchToSpaceNdLayer::Clone(Graph& graph) const +{ + auto layer = CloneBase<BatchToSpaceNdLayer>(graph, m_Param, GetName()); + return std::move(layer); +} + +void BatchToSpaceNdLayer::ValidateTensorShapesFromInputs() +{ + VerifyLayerConnections(1, CHECK_LOCATION()); + + auto inferredShapes = InferOutputShapes({GetInputSlot(0).GetConnection()->GetTensorInfo().GetShape()}); + + BOOST_ASSERT(inferredShapes.size() == 1); + + ConditionalThrowIfNotEqual<LayerValidationException>( + "BatchToSpaceLayer: TensorShape set on OutputSlot[0] does not match the inferred shape.", + GetOutputSlot(0).GetTensorInfo().GetShape(),inferredShapes[0]); +} + +std::vector<TensorShape> BatchToSpaceNdLayer::InferOutputShapes(const std::vector<TensorShape>& inputShapes) const +{ + const DataLayoutIndexed & dataLayout = m_Param.m_DataLayout; + const TensorShape& inputShape = inputShapes[0]; + unsigned int inBatchSize = inputShape[0]; + unsigned int channelSize = inputShape[dataLayout.GetChannelsIndex()]; + + std::vector<unsigned int> theBlockShape = m_Param.m_BlockShape; + + unsigned int overallSize = inBatchSize; + + for (unsigned int i = 0; i < theBlockShape.size(); ++i) + { + overallSize = overallSize * theBlockShape.at(i); + } + + std::vector<std::vector<unsigned int>> crops = m_Param.m_Crops; + + std::vector<unsigned int> yCrops = crops[0]; + std::vector<unsigned int> xCrops = crops[1]; + + unsigned int inputHeight = inputShape[dataLayout.GetHeightIndex()]; + unsigned int outputHeight = theBlockShape.at(0) * (inputHeight - (yCrops[0] + yCrops[1])); + + unsigned int inputWidth = inputShape[dataLayout.GetWidthIndex()]; + unsigned int outputWidth = theBlockShape.at(1) * (inputWidth - (xCrops[0] + xCrops[1])); + + unsigned int outputBatchSize = overallSize / (outputHeight * outputWidth); + + if (dataLayout == DataLayout::NHWC) + { + return std::vector<TensorShape>({ TensorShape({ outputBatchSize, outputHeight, outputWidth, channelSize }) }); + } + else + { + return std::vector<TensorShape>({ TensorShape({ outputBatchSize, channelSize, outputHeight, outputWidth }) }); + } +} +} // namespace armnn |