FFmpeg
dnn-layer-pad-test.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 
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  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 
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  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 
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  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 }
#define NULL
Definition: coverity.c:32
int dnn_execute_layer_pad(DnnOperand *operands, const int32_t *input_operand_indexes, int32_t output_operand_index, const void *parameters, NativeContext *ctx)
static int test_with_mode_reflect(void)
static int test_with_mode_symmetric(void)
static int test_with_mode_constant(void)
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
int main(int argc, char **argv)
void * data
data pointer with data length in bytes.
GLenum GLint * params
Definition: opengl_enc.c:113
int32_t dims[4]
there are two memory layouts, NHWC or NCHW, so we use dims, dims[0] is Number.
int32_t
layer pad (equivalent to tf.pad) for native backend.
#define EPSON
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
printf("static const uint8_t my_array[100] = {\n")
#define av_freep(p)
int i
Definition: input.c:407