FFmpeg
dnn-layer-pad.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2019 Guo Yejun
3  *
4  * This file is part of FFmpeg.
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
25 
26 #define EPSON 0.00001
27 
28 static int test_with_mode_symmetric(void)
29 {
30  // the input data and expected data are generated with below python code.
31  /*
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);
35 
36  sess=tf.Session()
37  sess.run(tf.global_variables_initializer())
38  output = sess.run(y, feed_dict={x: data})
39 
40  print(list(data.flatten()))
41  print(list(output.flatten()))
42  print(data.shape)
43  print(output.shape)
44  */
45 
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
51  };
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
61  };
62  float *output;
63 
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;
73 
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;
80 
81  input_indexes[0] = 0;
82  ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
83 
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]);
88  av_freep(&output);
89  return 1;
90  }
91  }
92 
93  av_freep(&output);
94  return 0;
95 
96 }
97 
98 static int test_with_mode_reflect(void)
99 {
100  // the input data and expected data are generated with below python code.
101  /*
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);
105 
106  sess=tf.Session()
107  sess.run(tf.global_variables_initializer())
108  output = sess.run(y, feed_dict={x: data})
109 
110  print(list(data.flatten()))
111  print(list(output.flatten()))
112  print(data.shape)
113  print(output.shape)
114  */
115 
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
121  };
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
126  };
127  float *output;
128 
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;
138 
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;
145 
146  input_indexes[0] = 0;
147  ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
148 
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]);
153  av_freep(&output);
154  return 1;
155  }
156  }
157 
158  av_freep(&output);
159  return 0;
160 
161 }
162 
163 static int test_with_mode_constant(void)
164 {
165  // the input data and expected data are generated with below python code.
166  /*
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);
170 
171  sess=tf.Session()
172  sess.run(tf.global_variables_initializer())
173  output = sess.run(y, feed_dict={x: data})
174 
175  print(list(data.flatten()))
176  print(list(output.flatten()))
177  print(data.shape)
178  print(output.shape)
179  */
180 
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
186  };
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
191  };
192  float *output;
193 
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;
204 
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;
211 
212  input_indexes[0] = 0;
213  ff_dnn_execute_layer_pad(operands, input_indexes, 1, &params, NULL);
214 
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]);
219  av_freep(&output);
220  return 1;
221  }
222  }
223 
224  av_freep(&output);
225  return 0;
226 
227 }
228 
229 int main(int argc, char **argv)
230 {
232  return 1;
233 
235  return 1;
236 
238  return 1;
239 }
output
filter_frame For filters that do not use the this method is called when a frame is pushed to the filter s input It can be called at any time except in a reentrant way If the input frame is enough to produce output
Definition: filter_design.txt:225
LPMP_REFLECT
@ LPMP_REFLECT
Definition: dnn_backend_native_layer_pad.h:31
dnn_backend_native_layer_pad.h
ff_dnn_execute_layer_pad
int ff_dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, int32_t output_operand_index, const void *parameters, NativeContext *ctx)
Definition: dnn_backend_native_layer_pad.c:78
test_with_mode_reflect
static int test_with_mode_reflect(void)
Definition: dnn-layer-pad.c:98
LayerPadParams::mode
LayerPadModeParam mode
Definition: dnn_backend_native_layer_pad.h:35
EPSON
#define EPSON
Definition: dnn-layer-pad.c:26
DnnOperand::data
void * data
data pointer with data length in bytes.
Definition: dnn_backend_native.h:104
LayerPadParams
Definition: dnn_backend_native_layer_pad.h:33
fabs
static __device__ float fabs(float a)
Definition: cuda_runtime.h:182
NULL
#define NULL
Definition: coverity.c:32
DnnOperand::dims
int32_t dims[4]
there are two memory layouts, NHWC or NCHW, so we use dims, dims[0] is Number.
Definition: dnn_backend_native.h:74
LPMP_SYMMETRIC
@ LPMP_SYMMETRIC
Definition: dnn_backend_native_layer_pad.h:31
LPMP_CONSTANT
@ LPMP_CONSTANT
Definition: dnn_backend_native_layer_pad.h:31
printf
printf("static const uint8_t my_array[100] = {\n")
input
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some input
Definition: filter_design.txt:172
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
LayerPadParams::paddings
int32_t paddings[4][2]
Definition: dnn_backend_native_layer_pad.h:34
DnnOperand
Definition: dnn_backend_native.h:69
test_with_mode_symmetric
static int test_with_mode_symmetric(void)
Definition: dnn-layer-pad.c:28
test_with_mode_constant
static int test_with_mode_constant(void)
Definition: dnn-layer-pad.c:163
LayerPadParams::constant_values
float constant_values
Definition: dnn_backend_native_layer_pad.h:36
main
int main(int argc, char **argv)
Definition: dnn-layer-pad.c:229
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
int32_t
int32_t
Definition: audioconvert.c:56