summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author오형석/On-Device Lab(SR)/Staff Engineer/삼성전자 <hseok82.oh@samsung.com>2019-04-16 06:52:28 (GMT)
committerGitHub Enterprise <noreply-CODE@samsung.com>2019-04-16 06:52:28 (GMT)
commit71c34c60d8ef732f11896fd150deda8650aec159 (patch)
tree4625a9d7703880bd603d1f8223f5185dbd3824fe
parent26595a5da4ccb025348751f9eafabbfb2ba3a97d (diff)
downloadnnfw-71c34c60d8ef732f11896fd150deda8650aec159.zip
nnfw-71c34c60d8ef732f11896fd150deda8650aec159.tar.gz
nnfw-71c34c60d8ef732f11896fd150deda8650aec159.tar.bz2
Modify cpu average pool kernel (#5004)
Move loop invariant codes Calculate filter count at once and compare Signed-off-by: Hyeongseok Oh <hseok82.oh@samsung.com>
-rw-r--r--libs/cker/include/cker/operation/AveragePool.h48
1 files changed, 26 insertions, 22 deletions
diff --git a/libs/cker/include/cker/operation/AveragePool.h b/libs/cker/include/cker/operation/AveragePool.h
index 1784c1c..81e9933 100644
--- a/libs/cker/include/cker/operation/AveragePool.h
+++ b/libs/cker/include/cker/operation/AveragePool.h
@@ -63,18 +63,22 @@ inline void AveragePool(const AveragePoolParams &params, const Shape &input_shap
{
for (int out_x = 0; out_x < output_width; ++out_x)
{
+ const int in_x_origin = (out_x * stride_width) - params.padding_values.width;
+ const int in_y_origin = (out_y * stride_height) - params.padding_values.height;
+ // Compute the boundaries of the filter region clamped so as to
+ // ensure that the filter window fits in the input array.
+ const int filter_x_start = std::max(0, -in_x_origin);
+ const int filter_x_end = std::min(params.filter_width, input_width - in_x_origin);
+ const int filter_y_start = std::max(0, -in_y_origin);
+ const int filter_y_end = std::min(params.filter_height, input_height - in_y_origin);
+ int filter_count = (filter_y_end - filter_y_start) * (filter_x_end - filter_x_start);
+ if (filter_count <= 0)
+ {
+ continue;
+ }
for (int channel = 0; channel < depth; ++channel)
{
- const int in_x_origin = (out_x * stride_width) - params.padding_values.width;
- const int in_y_origin = (out_y * stride_height) - params.padding_values.height;
- // Compute the boundaries of the filter region clamped so as to
- // ensure that the filter window fits in the input array.
- const int filter_x_start = std::max(0, -in_x_origin);
- const int filter_x_end = std::min(params.filter_width, input_width - in_x_origin);
- const int filter_y_start = std::max(0, -in_y_origin);
- const int filter_y_end = std::min(params.filter_height, input_height - in_y_origin);
float total = 0.f;
- int filter_count = 0;
for (int filter_y = filter_y_start; filter_y < filter_y_end; ++filter_y)
{
for (int filter_x = filter_x_start; filter_x < filter_x_end; ++filter_x)
@@ -82,10 +86,8 @@ inline void AveragePool(const AveragePoolParams &params, const Shape &input_shap
const int in_x = in_x_origin + filter_x;
const int in_y = in_y_origin + filter_y;
total += input_data[Offset(input_shape, batch, in_y, in_x, channel)];
- filter_count++;
}
}
- assert(filter_count != 0);
const float average = total / (float)filter_count;
output_data[Offset(output_shape, batch, out_y, out_x, channel)] =
ActivationFunctionWithMinMax(average, params.float_activation_min,
@@ -116,18 +118,22 @@ inline void AveragePool(const AveragePoolParams &params, const Shape &input_shap
{
for (int out_x = 0; out_x < output_width; ++out_x)
{
+ const int in_x_origin = (out_x * stride_width) - params.padding_values.width;
+ const int in_y_origin = (out_y * stride_height) - params.padding_values.height;
+ // Compute the boundaries of the filter region clamped so as to
+ // ensure that the filter window fits in the input array.
+ const int filter_x_start = std::max(0, -in_x_origin);
+ const int filter_x_end = std::min(params.filter_width, input_width - in_x_origin);
+ const int filter_y_start = std::max(0, -in_y_origin);
+ const int filter_y_end = std::min(params.filter_height, input_height - in_y_origin);
+ int filter_count = (filter_y_end - filter_y_start) * (filter_x_end - filter_x_start);
+ if (filter_count <= 0)
+ {
+ continue;
+ }
for (int channel = 0; channel < depth; ++channel)
{
- const int in_x_origin = (out_x * stride_width) - params.padding_values.width;
- const int in_y_origin = (out_y * stride_height) - params.padding_values.height;
- // Compute the boundaries of the filter region clamped so as to
- // ensure that the filter window fits in the input array.
- const int filter_x_start = std::max(0, -in_x_origin);
- const int filter_x_end = std::min(params.filter_width, input_width - in_x_origin);
- const int filter_y_start = std::max(0, -in_y_origin);
- const int filter_y_end = std::min(params.filter_height, input_height - in_y_origin);
int32_t acc = 0;
- int filter_count = 0;
for (int filter_y = filter_y_start; filter_y < filter_y_end; ++filter_y)
{
for (int filter_x = filter_x_start; filter_x < filter_x_end; ++filter_x)
@@ -135,10 +141,8 @@ inline void AveragePool(const AveragePoolParams &params, const Shape &input_shap
const int in_x = in_x_origin + filter_x;
const int in_y = in_y_origin + filter_y;
acc += input_data[Offset(input_shape, batch, in_y, in_x, channel)];
- filter_count++;
}
}
- assert(filter_count != 0);
acc = (acc + filter_count / 2) / filter_count;
acc = std::max(acc, params.quantized_activation_min);
acc = std::min(acc, params.quantized_activation_max);