aboutsummaryrefslogtreecommitdiff
path: root/src/backends/reference/workloads/SpaceToBatchNd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/backends/reference/workloads/SpaceToBatchNd.cpp')
-rw-r--r--src/backends/reference/workloads/SpaceToBatchNd.cpp123
1 files changed, 123 insertions, 0 deletions
diff --git a/src/backends/reference/workloads/SpaceToBatchNd.cpp b/src/backends/reference/workloads/SpaceToBatchNd.cpp
new file mode 100644
index 0000000000..48c212764f
--- /dev/null
+++ b/src/backends/reference/workloads/SpaceToBatchNd.cpp
@@ -0,0 +1,123 @@
+//
+// Copyright © 2017 Arm Ltd. All rights reserved.
+// SPDX-License-Identifier: MIT
+//
+
+#include "SpaceToBatchNd.hpp"
+
+namespace armnn
+{
+
+unsigned int GetOffset(const TensorShape& shape,
+ unsigned int b,
+ unsigned int h,
+ unsigned int w,
+ unsigned int c,
+ const DataLayoutIndexed& dataLayout)
+{
+ if (dataLayout.GetDataLayout() == DataLayout::NHWC)
+ {
+ return ((b * shape[dataLayout.GetHeightIndex()] + h) * shape[dataLayout.GetWidthIndex()] + w) *
+ shape[dataLayout.GetChannelsIndex()] + c;
+ }
+ else
+ {
+ return ((b * shape[dataLayout.GetChannelsIndex()] + c) * shape[dataLayout.GetHeightIndex()] + h) *
+ shape[dataLayout.GetWidthIndex()] + w;
+ }
+}
+
+template<typename T>
+void SpaceToBatchNd(const TensorInfo& inputInfo,
+ const TensorInfo& outputInfo,
+ const SpaceToBatchNdDescriptor& params,
+ const T* inputData,
+ T* outputData)
+{
+ DataLayoutIndexed dataLayout = params.m_DataLayout;
+
+ const TensorShape& inputShape = inputInfo.GetShape();
+ const TensorShape& outputShape = outputInfo.GetShape();
+
+ const unsigned int channels = inputShape[dataLayout.GetChannelsIndex()];
+
+ const unsigned int inputBatchSize = inputShape[0];
+ const unsigned int inputHeight = inputShape[dataLayout.GetHeightIndex()];
+ const unsigned int inputWidth = inputShape[dataLayout.GetWidthIndex()];
+
+ const unsigned int outputBatchSize = outputShape[0];
+ const unsigned int outputHeight = outputShape[dataLayout.GetHeightIndex()];
+ const unsigned int outputWidth = outputShape[dataLayout.GetWidthIndex()];
+
+ const unsigned int blockHeight = params.m_BlockShape[0];
+ const unsigned int blockWidth = params.m_BlockShape[1];
+
+ const unsigned int paddingTop = params.m_PadList[0].first;
+ const unsigned int paddingLeft = params.m_PadList[1].first;
+
+ for (unsigned int outB = 0; outB < outputBatchSize; outB++)
+ {
+ unsigned int inB = outB % inputBatchSize;
+
+ unsigned int shiftW = (outB / inputBatchSize) % blockWidth;
+ unsigned int shiftH = (outB / inputBatchSize) / blockWidth;
+
+ for (unsigned int outH = 0; outH < outputHeight; outH++)
+ {
+ for (unsigned int outW = 0; outW < outputWidth; outW++)
+ {
+ if (outH * blockHeight + shiftH < paddingTop ||
+ outH * blockHeight + shiftH >= paddingTop + inputHeight ||
+ outW * blockWidth + shiftW < paddingLeft ||
+ outW * blockWidth + shiftW >= paddingLeft + inputWidth)
+ {
+ for (unsigned int c = 0; c < channels; c++)
+ {
+ unsigned int outOffset = GetOffset(outputShape,
+ outB,
+ outH,
+ outW,
+ c,
+ dataLayout);
+ outputData[outOffset] = 0;
+ }
+ }
+ else
+ {
+ for (unsigned int c = 0; c < channels; c++)
+ {
+ unsigned int inOffset = GetOffset(inputShape,
+ inB,
+ (outH * blockHeight + shiftH) - paddingTop,
+ (outW * blockWidth + shiftW) - paddingLeft,
+ c,
+ dataLayout);
+
+ unsigned int outOffset = GetOffset(outputShape,
+ outB,
+ outH,
+ outW,
+ c,
+ dataLayout);
+
+ outputData[outOffset] = inputData[inOffset];
+ }
+ }
+ }
+ }
+ }
+}
+
+template void SpaceToBatchNd<float>(const TensorInfo& inputInfo,
+ const TensorInfo& outputInfo,
+ const SpaceToBatchNdDescriptor& params,
+ const float* inputData,
+ float* outData);
+
+template void SpaceToBatchNd<uint8_t>(const TensorInfo& inputInfo,
+ const TensorInfo& outputInfo,
+ const SpaceToBatchNdDescriptor& params,
+ const uint8_t* inputData,
+ uint8_t* outData);
+
+} //namespace armnn