2 * Copyright (c) 2020 Samsung Electronics Co., Ltd. All Rights Reserved
3 * Copyright 2019 The TensorFlow Authors. All Rights Reserved.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include "kernels/AveragePool2D.h"
20 #include "kernels/Utils.h"
22 #include "PALAveragePool2d.h"
24 namespace luci_interpreter
30 AveragePool2D::AveragePool2D(const Tensor *input, Tensor *output, Tensor *scratchpad,
31 const Pool2DParams ¶ms)
32 : KernelWithParams<Pool2DParams>({input}, {output, scratchpad}, params)
36 void AveragePool2D::configure()
38 if (input()->element_type() != output()->element_type())
40 assert(false && "Input Tensor and Output Tensor Type must be same");
42 if (input()->shape().num_dims() != 4)
44 assert(false && "Input Tensor Shape must be 4-D");
46 const Shape &input_shape = input()->shape();
48 const int32_t batches = input_shape.dim(0);
49 const int32_t input_height = input_shape.dim(1);
50 const int32_t input_width = input_shape.dim(2);
51 const int32_t depth = input_shape.dim(3);
53 const int32_t output_height =
54 computeOutputSize(_params.padding, input_height, _params.filter_height, _params.stride_height);
55 const int32_t output_width =
56 computeOutputSize(_params.padding, input_width, _params.filter_width, _params.stride_width);
59 computePadding(_params.stride_height, 1, input_height, _params.filter_height, output_height);
61 computePadding(_params.stride_width, 1, input_width, _params.filter_width, output_width);
62 if (input()->element_type() == DataType::U8)
64 LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
65 LUCI_INTERPRETER_CHECK(output()->zero_point() == input()->zero_point());
67 else if (input()->element_type() == DataType::S16)
69 LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
70 LUCI_INTERPRETER_CHECK(input()->zero_point() == 0 && output()->zero_point() == 0);
72 else if (input()->element_type() == DataType::S8)
74 LUCI_INTERPRETER_CHECK(std::abs(output()->scale() - input()->scale()) <= 1.0e-6);
75 LUCI_INTERPRETER_CHECK(output()->zero_point() == input()->zero_point());
77 // TODO: enable it only if kernel with dynamic shapes
78 output()->resize({batches, output_height, output_width, depth});
80 auto scratchpad = getOutputTensors()[1];
81 luci_interpreter_pal::SetupScratchpadTensor(scratchpad, input()->element_type(),
82 getTensorShape(input()), getTensorShape(output()));
85 void AveragePool2D::execute() const
87 switch (input()->element_type())
89 case DataType::FLOAT32:
102 assert(false && "Unsupported type.");
106 void AveragePool2D::evalFloat() const
108 float activation_min{};
109 float activation_max{};
110 calculateActivationRange(_params.activation, &activation_min, &activation_max);
112 tflite::PoolParams params{};
113 params.padding_values.height = _padding_height;
114 params.padding_values.width = _padding_width;
115 params.stride_height = _params.stride_height;
116 params.stride_width = _params.stride_width;
117 params.filter_height = _params.filter_height;
118 params.filter_width = _params.filter_width;
119 params.float_activation_min = activation_min;
120 params.float_activation_max = activation_max;
122 tflite::reference_ops::AveragePool(params, getTensorShape(input()), getTensorData<float>(input()),
123 getTensorShape(output()), getTensorData<float>(output()));
126 void AveragePool2D::evalQuantized() const
128 int32_t activation_min{};
129 int32_t activation_max{};
130 calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
132 tflite::PoolParams params{};
133 params.padding_values.height = _padding_height;
134 params.padding_values.width = _padding_width;
135 params.stride_height = _params.stride_height;
136 params.stride_width = _params.stride_width;
137 params.filter_height = _params.filter_height;
138 params.filter_width = _params.filter_width;
139 params.quantized_activation_min = activation_min;
140 params.quantized_activation_max = activation_max;
142 tflite::reference_ops::AveragePool(params, getTensorShape(input()),
143 getTensorData<uint8_t>(input()), getTensorShape(output()),
144 getTensorData<uint8_t>(output()));
147 void AveragePool2D::evalSInt8() const
149 int32_t activation_min{};
150 int32_t activation_max{};
151 calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
152 tflite::PoolParams params{};
153 params.padding_values.height = _padding_height;
154 params.padding_values.width = _padding_width;
155 params.stride_height = _params.stride_height;
156 params.stride_width = _params.stride_width;
157 params.filter_height = _params.filter_height;
158 params.filter_width = _params.filter_width;
159 params.quantized_activation_min = activation_min;
160 params.quantized_activation_max = activation_max;
162 auto scratchpad = getOutputTensors()[1];
163 int8_t *scratchpad_data = nullptr;
164 if (scratchpad->is_allocatable())
165 scratchpad_data = scratchpad->data<int8_t>();
167 luci_interpreter_pal::AveragePool<int8_t>(
168 params, getTensorShape(input()), getTensorData<int8_t>(input()), getTensorShape(output()),
169 getTensorData<int8_t>(output()), getTensorShape(scratchpad), scratchpad_data);
172 void AveragePool2D::evalSInt16() const
174 int32_t activation_min{};
175 int32_t activation_max{};
176 calculateActivationRangeQuantized(_params.activation, output(), &activation_min, &activation_max);
178 tflite::PoolParams params{};
179 params.padding_values.height = _padding_height;
180 params.padding_values.width = _padding_width;
181 params.stride_height = _params.stride_height;
182 params.stride_width = _params.stride_width;
183 params.filter_height = _params.filter_height;
184 params.filter_width = _params.filter_width;
185 params.quantized_activation_min = activation_min;
186 params.quantized_activation_max = activation_max;
188 tflite::reference_integer_ops::AveragePool(
189 params, getTensorShape(input()), getTensorData<int16_t>(input()), //
190 getTensorShape(output()), getTensorData<int16_t>(output()));
193 } // namespace kernels
194 } // namespace luci_interpreter