ONE - On-device Neural Engine
Loading...
Searching...
No Matches
AveragePool.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2024 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#ifndef __NNFW_CKER_TRAIN_OPERATION_AVERAGEPOOL_H__
18#define __NNFW_CKER_TRAIN_OPERATION_AVERAGEPOOL_H__
19
20#include "cker/Shape.h"
21#include "cker/Utils.h"
22#include "cker/eigen/Utils.h"
23
24#include <Eigen/Core>
25
26namespace nnfw
27{
28namespace cker
29{
30namespace train
31{
32
33inline void AveragePool2DGrad(const PoolParams &params, const Shape &incoming_shape,
34 const float *incoming_data, const Shape &grad_shape, float *grad_data)
35{
36 assert(grad_shape.DimensionsCount() == 4);
37 assert(incoming_shape.DimensionsCount() == 4);
38
39 const int batches = MatchingDim(incoming_shape, 0, grad_shape, 0);
40 const int grad_height = grad_shape.Dims(1);
41 const int grad_width = grad_shape.Dims(2);
42 const int incoming_height = incoming_shape.Dims(1);
43 const int incoming_width = incoming_shape.Dims(2);
44 const int stride_height = params.stride_height;
45 const int stride_width = params.stride_width;
46
47 // initialize grad_data
48 std::fill(grad_data, grad_data + grad_shape.FlatSize(), 0.0);
49
50 const auto incoming_mat = MapAsMatrixWithLastDimAsRows(incoming_data, incoming_shape);
51 auto grad_mat = MapAsMatrixWithLastDimAsRows(grad_data, grad_shape);
52
53 for (int b = 0; b < batches; ++b)
54 {
55 for (int h = 0; h < incoming_height; ++h)
56 {
57 for (int w = 0; w < incoming_width; ++w)
58 {
59 // (h_start, h_end) * (w_start, w_end) is input range
60 // that output is projected from.
61 int h_start = h * stride_height - params.padding_values.height;
62 int h_end = std::min(h_start + params.filter_height, grad_height);
63 h_start = h_start < 0 ? 0 : h_start;
64
65 int w_start = w * stride_width - params.padding_values.width;
66 int w_end = std::min(w_start + params.filter_width, grad_width);
67 w_start = w_start < 0 ? 0 : w_start;
68
69 int count = (h_end - h_start) * (w_end - w_start);
70
71 if (h_end <= 0 || w_end <= 0 || count <= 0 || h_start >= grad_height ||
72 w_start >= grad_width)
73 continue;
74
75 int incoming_offset = NodeOffset(b, h, w, incoming_height, incoming_width);
76 for (int ph = h_start; ph < h_end; ++ph)
77 {
78 for (int pw = w_start; pw < w_end; ++pw)
79 {
80 int grad_offset = NodeOffset(b, ph, pw, grad_height, grad_width);
81 grad_mat.col(grad_offset) += incoming_mat.col(incoming_offset) / count;
82 }
83 }
84 }
85 }
86 }
87}
88
89} // namespace train
90} // namespace cker
91} // namespace nnfw
92
93#endif // __NNFW_CKER_TRAIN_OPERATION_AVERAGEPOOL_H__
int32_t DimensionsCount() const
Definition Shape.h:91
int32_t Dims(int i) const
Definition Shape.h:92
int FlatSize() const
Definition Shape.h:181
void AveragePool2DGrad(const PoolParams &params, const Shape &incoming_shape, const float *incoming_data, const Shape &grad_shape, float *grad_data)
Definition AveragePool.h:33
int MatchingDim(const Shape &shape1, int index1, const Shape &shape2, int index2)
Definition Shape.h:220
int NodeOffset(int b, int h, int w, int height, int width)
Definition Utils.h:147
MatrixMap< Scalar > MapAsMatrixWithLastDimAsRows(Scalar *data, const Shape &shape)
Definition Utils.h:60
Definition topk_v2.h:30
PaddingValues padding_values
Definition Types.h:89