2 * Copyright (c) 2019 Guo Yejun
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libavfilter/dnn/dnn_backend_native_layer_pad.h"
28 static int test_with_mode_symmetric(void)
30 // the input data and expected data are generated with below python code.
32 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
33 y = tf.pad(x, [[0, 0], [2, 3], [3, 2], [0, 0]], 'SYMMETRIC')
34 data = np.arange(48).reshape(1, 4, 4, 3);
37 sess.run(tf.global_variables_initializer())
38 output = sess.run(y, feed_dict={x: data})
40 print(list(data.flatten()))
41 print(list(output.flatten()))
46 LayerPadParams params;
47 DnnOperand operands[2];
48 int32_t input_indexes[1];
49 float input[1*4*4*3] = {
50 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47
52 float expected_output[1*9*9*3] = {
53 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 6.0, 7.0, 8.0, 3.0,
54 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 6.0, 7.0, 8.0, 3.0, 4.0, 5.0, 0.0, 1.0, 2.0, 0.0, 1.0, 2.0, 3.0,
55 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 9.0, 10.0, 11.0, 6.0, 7.0, 8.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0, 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0,
56 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0, 30.0, 31.0, 32.0, 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0,
57 34.0, 35.0, 30.0, 31.0, 32.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0,
58 44.0, 42.0, 43.0, 44.0, 39.0, 40.0, 41.0, 36.0, 37.0, 38.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 45.0, 46.0, 47.0, 42.0, 43.0, 44.0, 30.0, 31.0, 32.0,
59 27.0, 28.0, 29.0, 24.0, 25.0, 26.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 33.0, 34.0, 35.0, 30.0, 31.0, 32.0, 18.0, 19.0, 20.0, 15.0, 16.0, 17.0, 12.0,
60 13.0, 14.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 21.0, 22.0, 23.0, 18.0, 19.0, 20.0
64 params.mode = LPMP_SYMMETRIC;
65 params.paddings[0][0] = 0;
66 params.paddings[0][1] = 0;
67 params.paddings[1][0] = 2;
68 params.paddings[1][1] = 3;
69 params.paddings[2][0] = 3;
70 params.paddings[2][1] = 2;
71 params.paddings[3][0] = 0;
72 params.paddings[3][1] = 0;
74 operands[0].data = input;
75 operands[0].dims[0] = 1;
76 operands[0].dims[1] = 4;
77 operands[0].dims[2] = 4;
78 operands[0].dims[3] = 3;
79 operands[1].data = NULL;
82 ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL);
84 output = operands[1].data;
85 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
86 if (fabs(output[i] - expected_output[i]) > EPSON) {
87 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
98 static int test_with_mode_reflect(void)
100 // the input data and expected data are generated with below python code.
102 x = tf.placeholder(tf.float32, shape=[3, None, None, 3])
103 y = tf.pad(x, [[1, 2], [0, 0], [0, 0], [0, 0]], 'REFLECT')
104 data = np.arange(36).reshape(3, 2, 2, 3);
107 sess.run(tf.global_variables_initializer())
108 output = sess.run(y, feed_dict={x: data})
110 print(list(data.flatten()))
111 print(list(output.flatten()))
116 LayerPadParams params;
117 DnnOperand operands[2];
118 int32_t input_indexes[1];
119 float input[3*2*2*3] = {
120 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35
122 float expected_output[6*2*2*3] = {
123 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0,
124 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0,
125 35.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0
129 params.mode = LPMP_REFLECT;
130 params.paddings[0][0] = 1;
131 params.paddings[0][1] = 2;
132 params.paddings[1][0] = 0;
133 params.paddings[1][1] = 0;
134 params.paddings[2][0] = 0;
135 params.paddings[2][1] = 0;
136 params.paddings[3][0] = 0;
137 params.paddings[3][1] = 0;
139 operands[0].data = input;
140 operands[0].dims[0] = 3;
141 operands[0].dims[1] = 2;
142 operands[0].dims[2] = 2;
143 operands[0].dims[3] = 3;
144 operands[1].data = NULL;
146 input_indexes[0] = 0;
147 ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL);
149 output = operands[1].data;
150 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
151 if (fabs(output[i] - expected_output[i]) > EPSON) {
152 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
163 static int test_with_mode_constant(void)
165 // the input data and expected data are generated with below python code.
167 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
168 y = tf.pad(x, [[0, 0], [1, 0], [0, 0], [1, 2]], 'CONSTANT', constant_values=728)
169 data = np.arange(12).reshape(1, 2, 2, 3);
172 sess.run(tf.global_variables_initializer())
173 output = sess.run(y, feed_dict={x: data})
175 print(list(data.flatten()))
176 print(list(output.flatten()))
181 LayerPadParams params;
182 DnnOperand operands[2];
183 int32_t input_indexes[1];
184 float input[1*2*2*3] = {
185 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
187 float expected_output[1*3*2*6] = {
188 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0, 728.0,
189 728.0, 728.0, 0.0, 1.0, 2.0, 728.0, 728.0, 728.0, 3.0, 4.0, 5.0, 728.0, 728.0,
190 728.0, 6.0, 7.0, 8.0, 728.0, 728.0, 728.0, 9.0, 10.0, 11.0, 728.0, 728.0
194 params.mode = LPMP_CONSTANT;
195 params.constant_values = 728;
196 params.paddings[0][0] = 0;
197 params.paddings[0][1] = 0;
198 params.paddings[1][0] = 1;
199 params.paddings[1][1] = 0;
200 params.paddings[2][0] = 0;
201 params.paddings[2][1] = 0;
202 params.paddings[3][0] = 1;
203 params.paddings[3][1] = 2;
205 operands[0].data = input;
206 operands[0].dims[0] = 1;
207 operands[0].dims[1] = 2;
208 operands[0].dims[2] = 2;
209 operands[0].dims[3] = 3;
210 operands[1].data = NULL;
212 input_indexes[0] = 0;
213 ff_dnn_execute_layer_pad(operands, input_indexes, 1, ¶ms, NULL);
215 output = operands[1].data;
216 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
217 if (fabs(output[i] - expected_output[i]) > EPSON) {
218 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
229 int main(int argc, char **argv)
231 if (test_with_mode_symmetric())
234 if (test_with_mode_reflect())
237 if (test_with_mode_constant())