diff options
author | David Beck <david.beck@arm.com> | 2018-09-19 12:03:20 +0100 |
---|---|---|
committer | Matthew Bentham <matthew.bentham@arm.com> | 2018-10-10 16:16:56 +0100 |
commit | 10b4dfd8e9ccd7a03df7bb053ee1c644cb37f8ab (patch) | |
tree | 1ac5b4f415531e2ef759439ab8e113f177bea7c5 /src/armnn/backends/RefWorkloads/Pooling2d.cpp | |
parent | a3f165624b2cdfbced674af5a6e11856b1e746d9 (diff) | |
download | armnn-10b4dfd8e9ccd7a03df7bb053ee1c644cb37f8ab.tar.gz |
IVGCVSW-1897 : build infrastructure for the src/backends folder
Change-Id: I7ebafb675ccc77ad54d1deb01412a8379a5356bb
Diffstat (limited to 'src/armnn/backends/RefWorkloads/Pooling2d.cpp')
-rw-r--r-- | src/armnn/backends/RefWorkloads/Pooling2d.cpp | 241 |
1 files changed, 0 insertions, 241 deletions
diff --git a/src/armnn/backends/RefWorkloads/Pooling2d.cpp b/src/armnn/backends/RefWorkloads/Pooling2d.cpp deleted file mode 100644 index 5812a290e7..0000000000 --- a/src/armnn/backends/RefWorkloads/Pooling2d.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// -// Copyright © 2017 Arm Ltd. All rights reserved. -// SPDX-License-Identifier: MIT -// - -#include "Pooling2d.hpp" - -#include <armnn/Exceptions.hpp> -#include <armnn/Types.hpp> - -#include <boost/numeric/conversion/cast.hpp> - -#include <limits> -#include <algorithm> -#include <functional> - -namespace -{ - using PoolingAlgorithm = armnn::PoolingAlgorithm; - - float DefaultInitializer(PoolingAlgorithm algorithm) - { - switch (algorithm) - { - case PoolingAlgorithm::Max: - { - return std::numeric_limits<float>::lowest(); - } - case PoolingAlgorithm::Average: - case PoolingAlgorithm::L2: - { - return 0.0f; - } - default: - { - throw armnn::InvalidArgumentException("Unsupported pooling algorithm"); - } - } - } - - using Accumulator = std::function<void(float & accu, float value)>; - - Accumulator GetAccumulator(PoolingAlgorithm algorithm) - { - switch (algorithm) - { - case PoolingAlgorithm::Max: - { - return [](float & accu, float value) { - if (value > accu) { - accu = value; - } - }; - } - - case PoolingAlgorithm::Average: - { - return [](float & accu, float value) { - accu += value; - }; - } - - case PoolingAlgorithm::L2: - { - return [](float & accu, float value) { - accu += (value*value); - }; - } - - default: - { - throw armnn::InvalidArgumentException("Unsupported pooling algorithm"); - } - } - } - - using Executor = std::function<void(float & accumulated, float kernelSize)>; - - Executor GetExecutor(PoolingAlgorithm algorithm) - { - switch (algorithm) - { - case PoolingAlgorithm::Max: - { - return [](float & accumulated, float kernelSize) {}; - } - - case PoolingAlgorithm::Average: - { - return [](float & accumulated, float kernelSize) { - accumulated /= kernelSize; - }; - } - - case PoolingAlgorithm::L2: - { - return [](float & accumulated, float kernelSize) { - accumulated = sqrtf(accumulated / kernelSize); - }; - } - - default: - { - throw armnn::InvalidArgumentException("Unsupported pooling algorithm"); - } - } - } - - bool OnPaddingOnly(int start, int end, int maxRange, int padding) - { - if (end <= 0 || start > (maxRange - padding)) - { - return true; - } - else - { - return false; - } - } - - - bool ClampRange(int & start, int & end, int maxRange) - { - if (start < 0 || end > maxRange) - { - start = std::min(std::max(start, 0), maxRange); - end = std::min(std::max(end, 0), maxRange); - return true; - } - else - { - return false; - } - } -} - -namespace armnn -{ - -void Pooling2d(const float* in, - float* out, - const TensorInfo& inputInfo, - const TensorInfo& outputInfo, - const Pooling2dDescriptor& params) -{ - const int batchSize = boost::numeric_cast<int>(outputInfo.GetShape()[0]); - const int channels = boost::numeric_cast<int>(outputInfo.GetShape()[1]); - const int heightOutput = boost::numeric_cast<int>(outputInfo.GetShape()[2]); - const int widthOutput = boost::numeric_cast<int>(outputInfo.GetShape()[3]); - const int heightInput = boost::numeric_cast<int>(inputInfo.GetShape()[2]); - const int widthInput = boost::numeric_cast<int>(inputInfo.GetShape()[3]); - const int padLeft = boost::numeric_cast<int>(params.m_PadLeft); - const int padRight = boost::numeric_cast<int>(params.m_PadRight); - const int padTop = boost::numeric_cast<int>(params.m_PadTop); - const int padBottom = boost::numeric_cast<int>(params.m_PadBottom); - const int strideX = boost::numeric_cast<int>(params.m_StrideX); - const int strideY = boost::numeric_cast<int>(params.m_StrideY); - const int poolHeight = boost::numeric_cast<int>(params.m_PoolHeight); - const int poolWidth = boost::numeric_cast<int>(params.m_PoolWidth); - - float defaultInitializer = DefaultInitializer(params.m_PoolType); - - Accumulator accumulate = GetAccumulator(params.m_PoolType); - Executor execute = GetExecutor(params.m_PoolType); - - // Check supported padding methods outside the loop to simplify - // the inner loop. - if (params.m_PaddingMethod != PaddingMethod::Exclude && - params.m_PaddingMethod != PaddingMethod::IgnoreValue) - { - throw armnn::InvalidArgumentException("Unsupported padding type"); - } - - for (int n = 0; n < batchSize; n++) - { - for (int c = 0; c < channels; c++) - { - for (int yOutput = 0; yOutput < heightOutput; yOutput++) - { - for (int xOutput = 0; xOutput < widthOutput; xOutput++) - { - int hstart = (yOutput * strideY) - padTop; - int wstart = (xOutput * strideX) - padLeft; - int hend = hstart + poolHeight; - int wend = wstart + poolWidth; - - // Clamp the pooling region inside the valid input area (which includes the padding). - // This is necessary because the final pooling in a row may overlap beyond the padding. - hend = std::min(hend, heightInput + padBottom); - wend = std::min(wend, widthInput + padRight); - - float result = defaultInitializer; - float poolAreaSize = boost::numeric_cast<float>((hend - hstart) * (wend - wstart)); - - // Special case: when the pooling kernel is over a padding region and the padding - // size is larger or equal to the kernel and the kernel only covers - // padding and no real values, then we initialize the result as zero - // by convention. This is because we need to choose a value here and - // all values we have are padding, which we ignore. - if (OnPaddingOnly(hstart, hend, heightInput, padBottom) || - OnPaddingOnly(wstart, wend, widthInput, padRight)) - { - result = 0.0f; - } - - bool clamped = ClampRange(wstart, wend, widthInput); - clamped |= ClampRange(hstart, hend, heightInput); - - if (clamped && params.m_PaddingMethod == PaddingMethod::Exclude) - { - // When we exclude the padding, it means we calculate with a smaller - // kernel size, so I changed the divisor here. - poolAreaSize = boost::numeric_cast<float>((hend - hstart) * (wend - wstart)); - } - - for (auto yInput = hstart; yInput < hend; yInput++) - { - for (auto xInput = wstart; xInput < wend; xInput++) - { - float inval = in[n * widthInput * heightInput * channels + - c * widthInput * heightInput + - yInput * widthInput + - xInput]; - - accumulate(result, inval); - } - } - - execute(result, poolAreaSize); - - out[n * widthOutput * heightOutput * channels + - c * widthOutput * heightOutput + - yOutput * widthOutput + - xOutput] = result; - } - } - } - } -} - -} //namespace armnn |