Imported Upstream version 1.25.0
[platform/core/ml/nnfw.git] / onert-micro / luci-interpreter / src / kernels / AveragePool2D.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *    http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "Builders.h"
18
19 #include "kernels/Utils.h"
20 #include "PALAveragePool2D.h"
21
22 namespace luci_interpreter
23 {
24
25 // TODO: reduce code duplication with MaxPool2D
26 void configure_kernel_CircleAveragePool2D(const circle::Operator *cur_op,
27                                           BaseRuntimeGraph *runtime_graph)
28 {
29   const auto input_index = cur_op->inputs()->operator[](0);
30   const auto output_index = cur_op->outputs()->operator[](0);
31
32   assert(input_index != -1);
33   assert(output_index != -1);
34
35   const auto input = runtime_graph->getCircleTensorByIndex(input_index);
36   const auto output = runtime_graph->getCircleTensorByIndex(output_index);
37
38   LUCI_INTERPRETER_CHECK(Tensor::element_type(input) == Tensor::element_type(output));
39   assert(Tensor::num_dims(input) == 4);
40 }
41
42 void execute_kernel_CircleAveragePool2D(const circle::Operator *cur_op,
43                                         BaseRuntimeGraph *runtime_graph)
44 {
45   const auto input_index = cur_op->inputs()->operator[](0);
46   const auto output_index = cur_op->outputs()->operator[](0);
47
48   assert(input_index != -1);
49   assert(output_index != -1);
50
51   const auto input = runtime_graph->getCircleTensorByIndex(input_index);
52   auto output = runtime_graph->getCircleTensorByIndex(output_index);
53
54   const auto *options = cur_op->builtin_options_as_Pool2DOptions();
55
56   const int32_t input_height = Tensor::dim(input, 1);
57   const int32_t input_width = Tensor::dim(input, 2);
58
59   const int32_t output_height = kernels::computeOutputSize(
60     luci_padding(options->padding()), input_height, options->filter_height(), options->stride_h());
61   const int32_t output_width = kernels::computeOutputSize(
62     luci_padding(options->padding()), input_width, options->filter_width(), options->stride_w());
63
64   const auto padding_height = kernels::computePadding(options->stride_h(), 1, input_height,
65                                                       options->filter_height(), output_height);
66   const auto padding_width = kernels::computePadding(options->stride_w(), 1, input_width,
67                                                      options->filter_width(), output_width);
68
69   const auto *input_data = runtime_graph->getDataByTensor(input);
70   auto *output_data = runtime_graph->getDataByTensor(output);
71
72   float activation_min{};
73   float activation_max{};
74   kernels::calculateActivationRange(luci_actfunc(options->fused_activation_function()),
75                                     &activation_min, &activation_max);
76   luci_interpreter_pal::PoolParams params{};
77   params.padding_values.height = padding_height;
78   params.padding_values.width = padding_width;
79   params.stride_height = options->stride_h();
80   params.stride_width = options->stride_w();
81   params.filter_height = options->filter_height();
82   params.filter_width = options->filter_width();
83   params.float_activation_min = activation_min;
84   params.float_activation_max = activation_max;
85
86   switch (Tensor::element_type(input))
87   {
88 #ifndef DIS_FLOAT
89     case DataType::FLOAT32:
90       luci_interpreter_pal::AveragePool(
91         params, kernels::getTensorShape(input), kernels::getTensorData<float>(input_data),
92         kernels::getTensorShape(output), kernels::getTensorData<float>(output_data));
93       break;
94 #endif // DIS_FLOAT
95     default:
96       assert(false && "Unsupported type.");
97   }
98 }
99
100 } // namespace luci_interpreter