blob: 887f00de2459f242a63853694033a002d217f6e8 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Michele Di Giorgiod9eaf612020-07-08 11:12:57 +01002 * Copyright (c) 2017-2020 Arm Limited.
Anthony Barbier6ff3b192017-09-04 18:44:23 +01003 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to
8 * deal in the Software without restriction, including without limitation the
9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10 * sell copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in all
14 * copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24#include "arm_compute/runtime/NEON/functions/NEPoolingLayer.h"
25
Gian Marco Iodice16824302017-09-28 15:41:37 +010026#include "arm_compute/core/ITensor.h"
27#include "arm_compute/runtime/NEON/NEScheduler.h"
Michalis Spyrouebcebf12020-10-21 00:04:14 +010028#include "src/core/NEON/kernels/NEFillBorderKernel.h"
29#include "src/core/NEON/kernels/NEPoolingLayerKernel.h"
Gian Marco Iodice16824302017-09-28 15:41:37 +010030
Michalis Spyrouebcebf12020-10-21 00:04:14 +010031namespace arm_compute
32{
33NEPoolingLayer::~NEPoolingLayer() = default;
Anthony Barbier6ff3b192017-09-04 18:44:23 +010034
Gian Marco Iodice16824302017-09-28 15:41:37 +010035NEPoolingLayer::NEPoolingLayer()
Michalis Spyrou57dac842018-03-01 16:03:50 +000036 : _pooling_layer_kernel(), _border_handler(), _is_global_pooling_layer(false), _data_layout(DataLayout::NCHW)
Gian Marco Iodice16824302017-09-28 15:41:37 +010037{
38}
39
morgolockcc1f6c92020-03-24 09:26:48 +000040void NEPoolingLayer::configure(ITensor *input, ITensor *output, const PoolingLayerInfo &pool_info, ITensor *indices)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010041{
Gian Marco Iodice16824302017-09-28 15:41:37 +010042 // Check if we have Global Pooling Layer
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +000043 _is_global_pooling_layer = (input->info()->dimension(0) == pool_info.pool_size.width) && (input->info()->dimension(1) == pool_info.pool_size.height);
Gian Marco Iodice16824302017-09-28 15:41:37 +010044
Michalis Spyrou57dac842018-03-01 16:03:50 +000045 // Get data layout
Sang-Hoon Park11fedda2020-01-15 14:44:04 +000046 _data_layout = pool_info.data_layout == DataLayout::UNKNOWN ? input->info()->data_layout() : pool_info.data_layout;
Michalis Spyrou57dac842018-03-01 16:03:50 +000047
Anthony Barbier6ff3b192017-09-04 18:44:23 +010048 // Configure pooling kernel
Georgios Pinitas40f51a62020-11-21 03:04:18 +000049 _pooling_layer_kernel = std::make_unique<NEPoolingLayerKernel>();
Michalis Spyrouebcebf12020-10-21 00:04:14 +010050 _pooling_layer_kernel->configure(input, output, pool_info, indices);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010051
Michalis Spyrou57dac842018-03-01 16:03:50 +000052 switch(_data_layout)
Georgios Pinitas55186712018-01-08 17:37:12 +000053 {
Michalis Spyrou57dac842018-03-01 16:03:50 +000054 case DataLayout::NCHW:
55 {
56 // Configure border depending on operation required (quantize border in case of asymmetric data_type)
morgolock37722d92020-04-09 14:17:48 +010057 BorderMode border_mode = (!indices && pool_info.pool_type == PoolingType::MAX) ? BorderMode::REPLICATE : BorderMode::CONSTANT;
58 PixelValue zero_value((indices) ? std::numeric_limits<int>::min() : 0.f);
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +000059 if(is_data_type_quantized_asymmetric(input->info()->data_type()) && !pool_info.exclude_padding)
Michalis Spyrou57dac842018-03-01 16:03:50 +000060 {
Manuel Bottinib4bb8272019-12-18 18:01:27 +000061 zero_value = PixelValue(0, input->info()->data_type(), input->info()->quantization_info());
Michalis Spyrou57dac842018-03-01 16:03:50 +000062 }
Georgios Pinitas40f51a62020-11-21 03:04:18 +000063 _border_handler = std::make_unique<NEFillBorderKernel>();
Michalis Spyrouebcebf12020-10-21 00:04:14 +010064 _border_handler->configure(input, _pooling_layer_kernel->border_size(), border_mode, zero_value);
Michalis Spyrou57dac842018-03-01 16:03:50 +000065 break;
66 }
67 case DataLayout::NHWC:
68 break;
69 default:
70 ARM_COMPUTE_ERROR("Data layout not supported");
Georgios Pinitas55186712018-01-08 17:37:12 +000071 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +010072}
Gian Marco Iodice16824302017-09-28 15:41:37 +010073
morgolockcc1f6c92020-03-24 09:26:48 +000074Status NEPoolingLayer::validate(const ITensorInfo *input, const ITensorInfo *output, const PoolingLayerInfo &pool_info, const ITensorInfo *indices)
Michalis Spyrouafa5d812017-11-30 14:25:57 +000075{
morgolockcc1f6c92020-03-24 09:26:48 +000076 return NEPoolingLayerKernel::validate(input, output, pool_info, indices);
Michalis Spyrouafa5d812017-11-30 14:25:57 +000077}
78
Gian Marco Iodice16824302017-09-28 15:41:37 +010079void NEPoolingLayer::run()
80{
Michalis Spyrou57dac842018-03-01 16:03:50 +000081 switch(_data_layout)
82 {
83 case DataLayout::NCHW:
84 // Fill border
Michalis Spyrouebcebf12020-10-21 00:04:14 +010085 NEScheduler::get().schedule(_border_handler.get(), Window::DimY);
Gian Marco Iodice16824302017-09-28 15:41:37 +010086
Michalis Spyrou57dac842018-03-01 16:03:50 +000087 // Run pooling layer
Michalis Spyrouebcebf12020-10-21 00:04:14 +010088 NEScheduler::get().schedule(_pooling_layer_kernel.get(), _is_global_pooling_layer ? Window::DimZ : Window::DimY);
Michalis Spyrou57dac842018-03-01 16:03:50 +000089 break;
90 case DataLayout::NHWC:
91 // Run pooling layer
Michalis Spyrouebcebf12020-10-21 00:04:14 +010092 NEScheduler::get().schedule(_pooling_layer_kernel.get(), Window::DimX);
Michalis Spyrou57dac842018-03-01 16:03:50 +000093 break;
94 default:
95 ARM_COMPUTE_ERROR("Data layout not supported");
96 }
Sang-Hoon Park0cb3da62020-01-15 12:39:56 +000097}
Michalis Spyrouebcebf12020-10-21 00:04:14 +010098
99} // namespace arm_compute