FFmpeg
dnn-layer-mathbinary-test.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020
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 #include "libavutil/avassert.h"
26 
27 #define EPSON 0.00005
28 
29 static float get_expected(float f1, float f2, DNNMathBinaryOperation op)
30 {
31  switch (op)
32  {
33  case DMBO_SUB:
34  return f1 - f2;
35  case DMBO_ADD:
36  return f1 + f2;
37  case DMBO_MUL:
38  return f1 * f2;
39  case DMBO_REALDIV:
40  return f1 / f2;
41  case DMBO_MINIMUM:
42  return (f1 < f2) ? f1 : f2;
43  default:
44  av_assert0(!"not supported yet");
45  return 0.f;
46  }
47 }
48 
50 {
52  DnnOperand operands[2];
53  int32_t input_indexes[1];
54  float input[1*1*2*3] = {
55  -3, 2.5, 2, -2.1, 7.8, 100
56  };
57  float *output;
58 
59  params.bin_op = op;
60  params.input0_broadcast = 1;
61  params.input1_broadcast = 0;
62  params.v = 7.28;
63 
64  operands[0].data = input;
65  operands[0].dims[0] = 1;
66  operands[0].dims[1] = 1;
67  operands[0].dims[2] = 2;
68  operands[0].dims[3] = 3;
69  operands[1].data = NULL;
70 
71  input_indexes[0] = 0;
72  dnn_execute_layer_math_binary(operands, input_indexes, 1, &params);
73 
74  output = operands[1].data;
75  for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
76  float expected_output = get_expected(params.v, input[i], op);
77  if (fabs(output[i] - expected_output) > EPSON) {
78  printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
79  op, i, output[i], expected_output, __FILE__, __LINE__);
80  av_freep(&output);
81  return 1;
82  }
83  }
84 
85  av_freep(&output);
86  return 0;
87 }
88 
90 {
92  DnnOperand operands[2];
93  int32_t input_indexes[1];
94  float input[1*1*2*3] = {
95  -3, 2.5, 2, -2.1, 7.8, 100
96  };
97  float *output;
98 
99  params.bin_op = op;
100  params.input0_broadcast = 0;
101  params.input1_broadcast = 1;
102  params.v = 7.28;
103 
104  operands[0].data = input;
105  operands[0].dims[0] = 1;
106  operands[0].dims[1] = 1;
107  operands[0].dims[2] = 2;
108  operands[0].dims[3] = 3;
109  operands[1].data = NULL;
110 
111  input_indexes[0] = 0;
112  dnn_execute_layer_math_binary(operands, input_indexes, 1, &params);
113 
114  output = operands[1].data;
115  for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
116  float expected_output = get_expected(input[i], params.v, op);
117  if (fabs(output[i] - expected_output) > EPSON) {
118  printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
119  op, i, output[i], expected_output, __FILE__, __LINE__);
120  av_freep(&output);
121  return 1;
122  }
123  }
124 
125  av_freep(&output);
126  return 0;
127 }
128 
130 {
132  DnnOperand operands[3];
133  int32_t input_indexes[2];
134  float input0[1*1*2*3] = {
135  -3, 2.5, 2, -2.1, 7.8, 100
136  };
137  float input1[1*1*2*3] = {
138  -1, 2, 3, -21, 8, 10.0
139  };
140  float *output;
141 
142  params.bin_op = op;
143  params.input0_broadcast = 0;
144  params.input1_broadcast = 0;
145 
146  operands[0].data = input0;
147  operands[0].dims[0] = 1;
148  operands[0].dims[1] = 1;
149  operands[0].dims[2] = 2;
150  operands[0].dims[3] = 3;
151  operands[1].data = input1;
152  operands[1].dims[0] = 1;
153  operands[1].dims[1] = 1;
154  operands[1].dims[2] = 2;
155  operands[1].dims[3] = 3;
156  operands[2].data = NULL;
157 
158  input_indexes[0] = 0;
159  input_indexes[1] = 1;
160  dnn_execute_layer_math_binary(operands, input_indexes, 2, &params);
161 
162  output = operands[2].data;
163  for (int i = 0; i < sizeof(input0) / sizeof(float); i++) {
164  float expected_output = get_expected(input0[i], input1[i], op);
165  if (fabs(output[i] - expected_output) > EPSON) {
166  printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
167  op, i, output[i], expected_output, __FILE__, __LINE__);
168  av_freep(&output);
169  return 1;
170  }
171  }
172 
173  av_freep(&output);
174  return 0;
175 }
176 
178 {
179  if (test_broadcast_input0(op))
180  return 1;
181 
182  if (test_broadcast_input1(op))
183  return 1;
184 
185  if (test_no_broadcast(op))
186  return 1;
187 
188  return 0;
189 }
190 
191 int main(int argc, char **argv)
192 {
193  if (test(DMBO_SUB))
194  return 1;
195 
196  if (test(DMBO_ADD))
197  return 1;
198 
199  if (test(DMBO_MUL))
200  return 1;
201 
202  if (test(DMBO_REALDIV))
203  return 1;
204 
205  if (test(DMBO_MINIMUM))
206  return 1;
207 
208  return 0;
209 }
#define NULL
Definition: coverity.c:32
static int test(DNNMathBinaryOperation op)
static float get_expected(float f1, float f2, DNNMathBinaryOperation op)
static int test_broadcast_input1(DNNMathBinaryOperation op)
static int test_broadcast_input0(DNNMathBinaryOperation op)
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
DNN inference functions interface for native backend.
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 dnn_execute_layer_math_binary(DnnOperand *operands, const int32_t *input_operand_indexes, int32_t output_operand_index, const void *parameters)
void * data
data pointer with data length in bytes.
GLenum GLint * params
Definition: opengl_enc.c:113
simple assert() macros that are a bit more flexible than ISO C assert().
int32_t dims[4]
there are two memory layouts, NHWC or NCHW, so we use dims, dims[0] is Number.
int32_t
#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
int main(int argc, char **argv)
static int op(uint8_t **dst, const uint8_t *dst_end, GetByteContext *gb, int pixel, int count, int *x, int width, int linesize)
Perform decode operation.
Definition: anm.c:75
printf("static const uint8_t my_array[100] = {\n")
static int test_no_broadcast(DNNMathBinaryOperation op)
#define av_freep(p)
int i
Definition: input.c:407