blob: 8399c6c49db0644d42958d3f1682c4ecc25ec348 [file] [log] [blame]
Anthony Barbier6ff3b192017-09-04 18:44:23 +01001/*
Pablo Marquez Telloba933712023-11-13 15:57:54 +00002 * Copyright (c) 2017-2021, 2023 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 */
Michalis Spyrouebcebf12020-10-21 00:04:14 +010024#include "src/core/NEON/kernels/NENormalizationLayerKernel.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010025
26#include "arm_compute/core/Error.h"
27#include "arm_compute/core/Helpers.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010028#include "arm_compute/core/TensorInfo.h"
29#include "arm_compute/core/Utils.h"
30#include "arm_compute/core/Validate.h"
31#include "arm_compute/core/Window.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010032
Pablo Marquez Telloba933712023-11-13 15:57:54 +000033#include "src/core/common/Registrars.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010034#include "src/core/CPP/Validate.h"
Sang-Hoon Park68dd25f2020-10-19 16:00:11 +010035#include "src/core/helpers/AutoConfiguration.h"
36#include "src/core/helpers/NormalizationHelpers.h"
37#include "src/core/helpers/WindowHelpers.h"
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010038#include "src/core/NEON/NEFixedPoint.h"
39#include "src/core/NEON/NEMath.h"
40#include "src/core/NEON/wrapper/wrapper.h"
Pablo Marquez Telloba933712023-11-13 15:57:54 +000041#include "src/cpu/kernels/norm_layer/generic/neon/impl.h"
42#include "src/cpu/kernels/norm_layer/generic/neon/list.h"
Anthony Barbier6ff3b192017-09-04 18:44:23 +010043
Manuel Bottinif2c714b2020-06-15 16:50:35 +010044namespace arm_compute
45{
Michalis Spyrouafa5d812017-11-30 14:25:57 +000046namespace
47{
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010048Status validate_arguments(const ITensorInfo *input,
49 const ITensorInfo *input_squared,
50 const ITensorInfo *output,
51 const NormalizationLayerInfo &norm_info)
Michalis Spyrouafa5d812017-11-30 14:25:57 +000052{
53 ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, input_squared, output);
Anthony Barbiereaefd002018-07-20 17:49:35 +010054 ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(input);
Vidhya Sudhan Loganathan7485d5a2018-07-04 09:34:00 +010055 ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F16, DataType::F32);
Michalis Spyrouafa5d812017-11-30 14:25:57 +000056
57 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, input_squared);
58 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(input, input_squared);
59 ARM_COMPUTE_RETURN_ERROR_ON_MSG(!(norm_info.norm_size() % 2), "Normalization size should be odd");
60
Michalis Spyrouafa5d812017-11-30 14:25:57 +000061 // Checks performed when output is configured
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010062 if (output->total_size() != 0)
Michalis Spyrouafa5d812017-11-30 14:25:57 +000063 {
64 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
65 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(input, output);
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +000066 ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, output);
Michalis Spyrouafa5d812017-11-30 14:25:57 +000067 }
68
69 return Status{};
70}
71
Michalis Spyrouafa5d812017-11-30 14:25:57 +000072} // namespace
73
Anthony Barbier6ff3b192017-09-04 18:44:23 +010074NENormalizationLayerKernel::NENormalizationLayerKernel()
Manuel Bottinif2c714b2020-06-15 16:50:35 +010075 : _func(nullptr), _input(nullptr), _input_squared(nullptr), _output(nullptr), _norm_info(NormType::IN_MAP_1D)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010076{
77}
78
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010079void NENormalizationLayerKernel::configure(const ITensor *input,
80 const ITensor *input_squared,
81 ITensor *output,
82 NormalizationLayerInfo norm_info)
Anthony Barbier6ff3b192017-09-04 18:44:23 +010083{
Michalis Spyrouafa5d812017-11-30 14:25:57 +000084 ARM_COMPUTE_ERROR_ON_NULLPTR(input, input_squared, output);
Georgios Pinitas09004ca2017-07-03 17:30:14 +010085 // Output tensor auto initialization if not yet initialized
Michalis Spyrouafa5d812017-11-30 14:25:57 +000086 auto_init_if_empty(*output->info(), *input->info());
87
88 // Perform validation step
89 ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), input_squared->info(), output->info(), norm_info));
Anthony Barbier6ff3b192017-09-04 18:44:23 +010090
Manuel Bottinif2c714b2020-06-15 16:50:35 +010091 const unsigned int norm_idx = get_normalization_dimension_index(input->info()->data_layout(), norm_info);
Anthony Barbier6ff3b192017-09-04 18:44:23 +010092
93 _input = input;
94 _input_squared = input_squared;
95 _output = output;
96 _norm_info = norm_info;
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +010097 switch (_input->info()->data_type())
Anthony Barbier6ff3b192017-09-04 18:44:23 +010098 {
Pablo Tellodf246182017-07-03 16:25:09 +010099 case DataType::F32:
100 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100101 switch (norm_idx)
Pablo Tellodf246182017-07-03 16:25:09 +0100102 {
Georgios Pinitase2220552018-07-20 13:23:44 +0100103 case 0:
104 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100105 if (norm_info.type() == NormType::IN_MAP_2D)
Georgios Pinitase2220552018-07-20 13:23:44 +0100106 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000107 _func = REGISTER_FP32_NEON(cpu::neon_normalize_float32_4_0_2D);
Georgios Pinitase2220552018-07-20 13:23:44 +0100108 }
109 else
110 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000111 _func = REGISTER_FP32_NEON(cpu::neon_normalize_float32_4_0);
Georgios Pinitase2220552018-07-20 13:23:44 +0100112 }
Pablo Tellodf246182017-07-03 16:25:09 +0100113 break;
Georgios Pinitase2220552018-07-20 13:23:44 +0100114 }
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000115 case 1:
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100116 if (norm_info.type() == NormType::IN_MAP_2D)
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000117 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000118 _func = REGISTER_FP32_NEON(cpu::neon_normalize_float32_4_1_2D);
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000119 }
120 else
121 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000122 _func = REGISTER_FP32_NEON(cpu::neon_normalize_float32_4_1);
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000123 }
124 break;
Georgios Pinitase2220552018-07-20 13:23:44 +0100125 case 2:
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000126 _func = REGISTER_FP32_NEON(cpu::neon_normalize_float32_4_2);
Pablo Tellodf246182017-07-03 16:25:09 +0100127 break;
128 default:
Pablo Tellodf246182017-07-03 16:25:09 +0100129 break;
130 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100131 break;
Pablo Tellodf246182017-07-03 16:25:09 +0100132 }
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000133#ifdef ARM_COMPUTE_ENABLE_FP16
Pablo Tellodf246182017-07-03 16:25:09 +0100134 case DataType::F16:
135 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100136 switch (norm_idx)
Pablo Tellodf246182017-07-03 16:25:09 +0100137 {
Georgios Pinitase2220552018-07-20 13:23:44 +0100138 case 0:
139 {
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100140 if (norm_info.type() == NormType::IN_MAP_2D)
Georgios Pinitase2220552018-07-20 13:23:44 +0100141 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000142 _func = REGISTER_FP16_NEON(cpu::neon_normalize_float16_8_0_2D);
Georgios Pinitase2220552018-07-20 13:23:44 +0100143 }
144 else
145 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000146 _func = REGISTER_FP16_NEON(cpu::neon_normalize_float16_8_0);
Georgios Pinitase2220552018-07-20 13:23:44 +0100147 }
Pablo Tellodf246182017-07-03 16:25:09 +0100148 break;
Georgios Pinitase2220552018-07-20 13:23:44 +0100149 }
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000150 case 1:
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100151 if (norm_info.type() == NormType::IN_MAP_2D)
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000152 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000153 _func = REGISTER_FP16_NEON(cpu::neon_normalize_float16_8_1_2D);
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000154 }
155 else
156 {
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000157 _func = REGISTER_FP16_NEON(cpu::neon_normalize_float16_8_1);
Michalis Spyrou0c71d0b2018-11-22 11:22:18 +0000158 }
159 break;
Georgios Pinitase2220552018-07-20 13:23:44 +0100160 case 2:
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000161 _func = REGISTER_FP16_NEON(cpu::neon_normalize_float16_8_2);
Pablo Tellodf246182017-07-03 16:25:09 +0100162 break;
163 default:
Pablo Tellodf246182017-07-03 16:25:09 +0100164 break;
165 }
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100166 break;
Pablo Tellodf246182017-07-03 16:25:09 +0100167 }
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000168#endif /* ARM_COMPUTE_ENABLE_FP16 */
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100169 default:
170 ARM_COMPUTE_ERROR("NOT SUPPORTED!");
171 }
172
Michalis Spyrouafa5d812017-11-30 14:25:57 +0000173 // Configure kernel window
SiCongLib88272e2021-02-24 15:40:57 +0000174 Window win = calculate_max_window(*input->info(), Steps());
Manuel Bottinif2c714b2020-06-15 16:50:35 +0100175 INEKernel::configure(win);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100176}
177
Felix Thomasmathibalanafd38f02023-09-27 17:46:17 +0100178Status NENormalizationLayerKernel::validate(const ITensorInfo *input,
179 const ITensorInfo *input_squared,
180 const ITensorInfo *output,
181 const NormalizationLayerInfo norm_info)
Michalis Spyrouafa5d812017-11-30 14:25:57 +0000182{
183 ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, input_squared, output, norm_info));
Michalis Spyrouafa5d812017-11-30 14:25:57 +0000184
185 return Status{};
186}
187
Moritz Pflanzerc186b572017-09-07 09:48:04 +0100188void NENormalizationLayerKernel::run(const Window &window, const ThreadInfo &info)
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100189{
Moritz Pflanzerc186b572017-09-07 09:48:04 +0100190 ARM_COMPUTE_UNUSED(info);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100191 ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
192 ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);
193 ARM_COMPUTE_ERROR_ON(_func == nullptr);
194
195 // Run function
Pablo Marquez Telloba933712023-11-13 15:57:54 +0000196 (*_func)(window, _input, _input_squared, _output, _norm_info);
Anthony Barbier6ff3b192017-09-04 18:44:23 +0100197}
Sheri Zhangac6499a2021-02-10 15:32:38 +0000198} // namespace arm_compute