ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Pad.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_PAD_H__
18#define __NNFW_CKER_TRAIN_OPERATION_PAD_H__
19
20#include "cker/operation/Pad.h"
21
22namespace nnfw
23{
24namespace cker
25{
26namespace train
27{
28
29/*
30 * input_data will be transformed by PAD operation with padding options(such as constant C) to
31 * output_data
32 *
33 * input_data -> output_data
34 * [0,1] -> [C,C,C,C]
35 * [2,3] -> [C,0,1,C]
36 * -> [C,2,3,C]
37 * -> [C,C,C,C]
38 */
39/*
40 * input_data(backward_output_data) will be transformed by backward of PAD operation (Depad) with
41 * padding options to output_data(backward_input_data)
42 *
43 * input_data(backward_output_data) -> output_data(backward_input_data)
44 * [C,C,C,C] -> [0,1]
45 * [C,0,1,C] -> [2,3]
46 * [C,2,3,C] ->
47 * [C,C,C,C] ->
48 */
49template <typename T>
50inline void Depad(const int32_t *padding_data, int32_t pad_rank, const Shape &input_shape,
51 const T *input_data, const Shape &output_shape, T *output_data)
52{
53 using PaddingInfo = std::pair<int32_t, int32_t>;
54 using PaddingList = std::vector<PaddingInfo>;
55
56 assert(output_shape.DimensionsCount() == input_shape.DimensionsCount());
57 assert(output_shape.DimensionsCount() == pad_rank);
58
59 PaddingList padding_list(pad_rank);
60 for (int32_t n = 0; n < pad_rank; ++n)
61 {
62 const int32_t *from = padding_data + (n * 2);
63 assert(from[0] >= 0 && from[1] >= 0);
64 padding_list[n] = {from[0], from[1]};
65 }
66 for (int32_t i = 0; i < pad_rank; ++i)
67 {
68 assert(output_shape.Dims(i) ==
69 input_shape.Dims(i) - padding_list[i].first - padding_list[i].second);
70 }
71
72 // logical axis: row -> col -> plain -> cube
73 switch (pad_rank)
74 {
75 case 0:
76 case 1:
77 {
78 const int32_t out_row_len = output_shape.Dims(0);
79 const int32_t padding_left = padding_list[0].first;
80 std::memcpy(output_data, input_data + padding_left, out_row_len * sizeof(T));
81 break;
82 }
83 case 2: // HW
84 {
85 const int32_t out_col_len = output_shape.Dims(0);
86 const int32_t out_row_len = output_shape.Dims(1);
87 const int32_t in_row_len = input_shape.Dims(1);
88 const int32_t padding_top = padding_list[0].first;
89 const int32_t padding_left = padding_list[1].first;
90 for (auto i = 0; i < out_col_len; ++i)
91 {
92 const auto in_offset = (i + padding_top) * in_row_len + padding_left;
93 const auto out_offset = i * out_row_len;
94 // copy a row of input data to output data
95 std::memcpy(output_data + out_offset, input_data + in_offset, out_row_len * sizeof(T));
96 }
97 break;
98 }
99 case 3: // HWC
100 {
101 const int32_t out_plain_len = output_shape.Dims(0);
102 const int32_t out_col_len = output_shape.Dims(1);
103 const int32_t out_row_len = output_shape.Dims(2);
104 const int32_t out_plain_size = out_col_len * out_row_len;
105 const int32_t in_col_len = input_shape.Dims(1);
106 const int32_t in_row_len = input_shape.Dims(2);
107 const int32_t in_plain_size = in_col_len * in_row_len;
108 const int32_t padding_depth = padding_list[0].first;
109 const int32_t padding_top = padding_list[1].first;
110 const int32_t padding_left = padding_list[2].first;
111 for (auto d = 0; d < out_plain_len; ++d)
112 {
113 for (auto h = 0; h < out_col_len; ++h)
114 {
115 const auto in_offset =
116 (d + padding_depth) * in_plain_size + (h + padding_top) * in_row_len + (padding_left);
117 const auto out_offset = (d * out_plain_size) + (h * out_row_len);
118 // copy a row of input data to output data
119 std::memcpy(output_data + out_offset, input_data + in_offset, out_row_len * sizeof(T));
120 }
121 }
122 break;
123 }
124 case 4: // NHWC
125 {
126 const int32_t out_cube_len = output_shape.Dims(0);
127 const int32_t out_plain_len = output_shape.Dims(1);
128 const int32_t out_col_len = output_shape.Dims(2);
129 const int32_t out_row_len = output_shape.Dims(3);
130 const int32_t out_plain_size = out_col_len * out_row_len;
131 const int32_t out_cube_size = out_plain_len * out_plain_size;
132 const int32_t in_plain_len = input_shape.Dims(1);
133 const int32_t in_col_len = input_shape.Dims(2);
134 const int32_t in_row_len = input_shape.Dims(3);
135 const int32_t in_plain_size = in_col_len * in_row_len;
136 const int32_t in_cube_size = in_plain_len * in_plain_size;
137 const int32_t padding_cube = padding_list[0].first;
138 const int32_t padding_depth = padding_list[1].first;
139 const int32_t padding_top = padding_list[2].first;
140 const int32_t padding_left = padding_list[3].first;
141 for (auto c = 0; c < out_cube_len; ++c)
142 {
143 for (auto d = 0; d < out_plain_len; ++d)
144 {
145 for (auto h = 0; h < out_col_len; ++h)
146 {
147 const auto in_offset = (c + padding_cube) * in_cube_size +
148 (d + padding_depth) * in_plain_size +
149 (h + padding_top) * in_row_len + (padding_left);
150 const auto out_offset = (c * out_cube_size) + (d * out_plain_size) + (h * out_row_len);
151 // copy a row of input data to output data
152 std::memcpy(output_data + out_offset, input_data + in_offset, out_row_len * sizeof(T));
153 }
154 }
155 }
156 break;
157 }
158 default:
159 throw std::runtime_error("Padding for rank > 4 NYI");
160 break;
161 }
162}
163
164} // namespace train
165} // namespace cker
166} // namespace nnfw
167
168#endif // __NNFW_CKER_TRAIN_OPERATION_PAD_H__
int32_t DimensionsCount() const
Definition Shape.h:91
int32_t Dims(int i) const
Definition Shape.h:92
const luci_interpreter::RuntimeShape output_shape
void Depad(const int32_t *padding_data, int32_t pad_rank, const Shape &input_shape, const T *input_data, const Shape &output_shape, T *output_data)
Definition Pad.h:50
Definition topk_v2.h:30