History

tests/dnn: Make DNN tests regular libavfilter tests

They test libavfilter internal API, so they should be libavfilter test programs (which implies: linked statically to libavfilter to access internal APIs and linked normally (statically or dynamically depending upon the build configuration) against all the other libs). Right now, they are always linked statically against all libs, which is a significant size waste compared to shared libs as all of libavcodec has been pulled in despite not being really used. This also leads to linking failures on systems for which av_export_avutil is intended: libavcodec does not expect to be linked statically against the library providing avpriv_(cga|vga16)_font in this case. This is fixed by this commit.

Andreas Rheinhardt committed 4 years ago

Commit c26730e1 parent 69a45b814 files · +31 −45Browse files

Showing the changes to libavfilter/tests (9 of 14 files). Show all

Unified · Split

9 files
  1. libavfilter/tests/.gitignore +8 −0
  2. libavfilter/tests/dnn-layer-avgpool.c +197 −0
  3. libavfilter/tests/dnn-layer-conv2d.c +248 −0
  4. libavfilter/tests/dnn-layer-dense.c +131 −0
  5. libavfilter/tests/dnn-layer-depth2space.c +102 −0
  6. libavfilter/tests/dnn-layer-mathbinary.c +214 −0
  7. libavfilter/tests/dnn-layer-mathunary.c +148 −0
  8. libavfilter/tests/dnn-layer-maximum.c +71 −0
  9. libavfilter/tests/dnn-layer-pad.c +239 −0
libavfilter/tests/.gitignore+8−0
@@ -1,3 +1,11 @@
1/dnn-layer-conv2d
2/dnn-layer-depth2space
3/dnn-layer-maximum
4/dnn-layer-pad
5/dnn-layer-mathbinary
6/dnn-layer-mathunary
7/dnn-layer-avgpool
8/dnn-layer-dense
1/drawutils9/drawutils
2/filtfmts10/filtfmts
3/formats11/formats
libavfilter/tests/dnn-layer-avgpool.c+197−0
@@ -0,0 +1,197 @@
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 "libavfilter/dnn/dnn_backend_native_layer_avgpool.h"
23
24#define EPSON 0.00001
25
26static int test_with_same(void)
27{
28 // the input data and expected data are generated with below python code.
29 /*
30 import tensorflow as tf
31 import numpy as np
32
33 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
34 y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID')
35 data = np.random.rand(1, 5, 6, 3);
36
37 sess=tf.Session()
38 sess.run(tf.global_variables_initializer())
39
40 output = sess.run(y, feed_dict={x: data})
41
42 print("input:")
43 print(data.shape)
44 print(list(data.flatten()))
45
46 print("output:")
47 print(output.shape)
48 print(list(output.flatten()))
49 */
50
51 AvgPoolParams params;
52 DnnOperand operands[2];
53 int32_t input_indexes[1];
54 float input[1*5*6*3] = {
55 0.7461309859908424, 0.7567538372797069, 0.07662743569678687, 0.8882112610336333, 0.9720443314026668, 0.3337200343220823, 0.4421032129780248,
56 0.14940809044964876, 0.6773177061961277, 0.9778844630669781, 0.6522650522626998, 0.0317651530878591, 0.31259897552911364, 0.6235936821891896,
57 0.40016094349542775, 0.4599222930032276, 0.7893807222960093, 0.8475986363538283, 0.5058802717647394, 0.7827005363222633, 0.3032188123727916,
58 0.8983728631302361, 0.20622408444965523, 0.22966072303869878, 0.09535751273161308, 0.8760709100995375, 0.9982324154558745, 0.7904595468621013,
59 0.13883671508879347, 0.9332751439533138, 0.0010861680752152214, 0.3607210449251048, 0.6600652759586171, 0.7629572058138805, 0.29441975810476106,
60 0.2683471432889405, 0.22574580829831536, 0.8893251976212904, 0.3907737043801005, 0.6421829842863968, 0.6670373870457297, 0.9383850793160277,
61 0.4120458907436003, 0.3589847212711481, 0.48047736550128983, 0.6428192648418949, 0.0313661686292348, 0.429357100401472, 0.5123413386514056,
62 0.8492446404097114, 0.9045286128486804, 0.8123708563814285, 0.3943245008451698, 0.9576713003177785, 0.5985610965938726, 0.9350833279543561,
63 0.8010079897491659, 0.45882114217642866, 0.35275037908941487, 0.4555844661432271, 0.12352455940255314, 0.37801756635035544, 0.2824056214573083,
64 0.6229462823245029, 0.7235305681391472, 0.5408259266122064, 0.12142224381781208, 0.34431198802873686, 0.7112823816321276, 0.6307144385115417,
65 0.8136734589018082, 0.842095618140585, 0.8602767724004784, 0.6649236853766185, 0.5184782829419623, 0.9119607270982825, 0.3084111974561645,
66 0.39460705638161364, 0.17710447526170836, 0.1715485945814199, 0.17277563576521882, 0.40188232428735704, 0.22847985411491878, 0.4135361701550696,
67 0.24621846601980057, 0.6576588108454774, 0.6063336087333997, 0.6452342242996931, 0.7071689702737508, 0.1973416063225648
68 };
69 float expected_output[] = {
70 0.75964886, 0.6794307, 0.23580676, 0.5810112, 0.5509369, 0.55973274, 0.5764512, 0.45414522, 0.6601476, 0.52050734, 0.44385415,
71 0.50631666, 0.38414115, 0.5170288, 0.544043, 0.61143976, 0.5419003, 0.5579729, 0.5680455, 0.6363218, 0.4655096, 0.51198983,
72 0.5270792, 0.66168886, 0.48517057, 0.3513146, 0.7103355, 0.48667657, 0.34504217, 0.7318065, 0.5221889, 0.4746775, 0.69765306,
73 0.78766406, 0.34437215, 0.6130092, 0.48132777, 0.7110491, 0.6464378, 0.40914366, 0.4391975, 0.5392131, 0.45033398, 0.37297475,
74 0.43326652, 0.4748823, 0.48711336, 0.64649844, 0.51921225, 0.60038865, 0.8538945, 0.7215426, 0.60399896, 0.89988345, 0.707405,
75 0.5652921, 0.54241943, 0.41785273, 0.30268195, 0.3263432, 0.3313644, 0.37539417, 0.35238582, 0.34811732, 0.48849532, 0.56799453,
76 0.41089734, 0.63070333, 0.5892633, 0.6379743, 0.7604212, 0.5197186, 0.88611877, 0.48666745, 0.45654267, 0.5445326, 0.2399799,
77 0.28369135, 0.28949338, 0.20001422, 0.2931559, 0.3240504, 0.44306934, 0.5099349, 0.44572634, 0.68241394, 0.40183762, 0.6452342,
78 0.707169, 0.1973416
79 };
80 float *output;
81
82 params.strides = 1;
83 params.kernel_size = 2;
84 params.padding_method = SAME;
85
86 operands[0].data = input;
87 operands[0].dims[0] = 1;
88 operands[0].dims[1] = 5;
89 operands[0].dims[2] = 6;
90 operands[0].dims[3] = 3;
91 operands[1].data = NULL;
92
93 input_indexes[0] = 0;
94 ff_dnn_execute_layer_avg_pool(operands, input_indexes, 1, &params, NULL);
95
96 output = operands[1].data;
97 for (int i = 0; i < sizeof(expected_output) / sizeof(float); ++i) {
98 if (fabs(output[i] - expected_output[i]) > EPSON) {
99 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
100 av_freep(&output);
101 return 1;
102 }
103 }
104
105 av_freep(&output);
106 return 0;
107}
108
109static int test_with_valid(void)
110{
111 // the input data and expected data are generated with below python code.
112 /*
113 import tensorflow as tf
114 import numpy as np
115
116 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
117 y = tf.layers.average_pooling2d(x, pool_size=[2,2], strides=[1,1], padding='VALID')
118 data = np.random.rand(1, 5, 6, 3);
119
120 sess=tf.Session()
121 sess.run(tf.global_variables_initializer())
122
123 output = sess.run(y, feed_dict={x: data})
124
125 print("input:")
126 print(data.shape)
127 print(list(data.flatten()))
128
129 print("output:")
130 print(output.shape)
131 print(list(output.flatten()))
132 */
133
134 AvgPoolParams params;
135 DnnOperand operands[2];
136 int32_t input_indexes[1];
137 float input[1*5*6*3] = {
138 0.5046741692941682, 0.9273653202485155, 0.8193878359859937, 0.1904059431360905, 0.8664919633253656, 0.7484625128286059, 0.984534184632278,
139 0.31900804890072254, 0.3259426099940872, 0.05388974903570376, 0.7356610151331133, 0.46710858713311965, 0.718553768817036, 0.062478421853278676,
140 0.7813224786584609, 0.4826837517658389, 0.9748095400220147, 0.8078547703898341, 0.11976750668368585, 0.8713586777195065, 0.41447321551284355,
141 0.9818788239089807, 0.4335715767584073, 0.4059793452147419, 0.3677205907204525, 0.47919995923571, 0.8341395256258882, 0.7059726374074609,
142 0.5478504551919791, 0.8622900484790175, 0.8343709722511167, 0.05089827275068537, 0.6465283980840416, 0.544539116066677, 0.39812057257884337,
143 0.9578115576866337, 0.25012888117580145, 0.579333516024662, 0.5556732133051457, 0.6119862111181243, 0.0018736758772316398, 0.9795490254040474,
144 0.4488085008883018, 0.28947489777011737, 0.4834108668633247, 0.9280490084385024, 0.9895821458049648, 0.31777618554697606, 0.42679693258977847,
145 0.74447844466923, 0.9752225305081498, 0.17564130841849335, 0.22382692067314292, 0.009602884447469373, 0.5144884415025782, 0.031622570708844555,
146 0.8277532752502512, 0.4111593210409763, 0.5272084646575664, 0.28856508082905297, 0.11317726946036655, 0.7203328275540273, 0.8310055019972384,
147 0.8535951508685228, 0.40230347305233227, 0.2819703265132867, 0.6243143957791139, 0.7512463693822311, 0.7523056340495644, 0.8838077258040928,
148 0.5472240664033092, 0.2550538284454935, 0.5560317774456567, 0.8966847087518931, 0.6728358284165321, 0.30361297147530875, 0.464343925441822,
149 0.34507695659461224, 0.6333175615390685, 0.26661369038523497, 0.9926748632253231, 0.9994267301382666, 0.8684917986974414, 0.3598754806113009,
150 0.49550268625464666, 0.03652458679973214, 0.13469081713137177, 0.4579424049273835, 0.48641107969110353, 0.9670250266945365
151 };
152 float expected_output[1*4*5*3] = {
153 0.44918162, 0.7746969, 0.5970757, 0.63113487, 0.5245679, 0.578631, 0.52802926, 0.52042985, 0.6223702, 0.57819676, 0.34922206,
154 0.6893124, 0.64503694, 0.37157673, 0.7983793, 0.49094033, 0.47153437, 0.5889187, 0.6025985, 0.30103004, 0.6757697, 0.6126377,
155 0.5765268, 0.62440413, 0.7237974, 0.5832023, 0.7004543, 0.49533707, 0.35433105, 0.6472913, 0.44694072, 0.28500956, 0.6628852,
156 0.39628282, 0.38472247, 0.6456326, 0.58590746, 0.60042334, 0.47854072, 0.7081889, 0.7219026, 0.5818187, 0.5276401, 0.56669396,
157 0.49804622, 0.4463231, 0.4799649, 0.5335578, 0.36531678, 0.4946247, 0.6143306, 0.6498792, 0.5644355, 0.6163815, 0.7432098,
158 0.5146416, 0.38221055, 0.6153918, 0.45535153, 0.5272688
159 };
160 float *output;
161
162 params.strides = 1;
163 params.kernel_size = 2;
164 params.padding_method = VALID;
165
166 operands[0].data = input;
167 operands[0].dims[0] = 1;
168 operands[0].dims[1] = 5;
169 operands[0].dims[2] = 6;
170 operands[0].dims[3] = 3;
171 operands[1].data = NULL;
172
173 input_indexes[0] = 0;
174 ff_dnn_execute_layer_avg_pool(operands, input_indexes, 1, &params, NULL);
175
176 output = operands[1].data;
177 for (int i = 0; i < sizeof(expected_output) / sizeof(float); ++i) {
178 if (fabs(output[i] - expected_output[i]) > EPSON) {
179 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
180 av_freep(&output);
181 return 1;
182 }
183 }
184
185 av_freep(&output);
186 return 0;
187}
188
189int main(int argc, char **argv)
190{
191 if (test_with_same())
192 return 1;
193 if (test_with_valid())
194 return 1;
195
196 return 0;
197}
libavfilter/tests/dnn-layer-conv2d.c+248−0
@@ -0,0 +1,248 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_conv2d.h"
25
26#define EPSON 0.00001
27
28static int test_with_same_dilate(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.layers.conv2d(x, 2, 3, activation=tf.nn.tanh, padding='same', dilation_rate=(2, 2), bias_initializer=tf.keras.initializers.he_normal())
34 data = np.random.rand(1, 5, 6, 3);
35
36 sess=tf.Session()
37 sess.run(tf.global_variables_initializer())
38
39 weights = dict([(var.name, sess.run(var)) for var in tf.trainable_variables()])
40 kernel = weights['conv2d/kernel:0']
41 kernel = np.transpose(kernel, [3, 0, 1, 2])
42 print("kernel:")
43 print(kernel.shape)
44 print(list(kernel.flatten()))
45
46 bias = weights['conv2d/bias:0']
47 print("bias:")
48 print(bias.shape)
49 print(list(bias.flatten()))
50
51 output = sess.run(y, feed_dict={x: data})
52
53 print("input:")
54 print(data.shape)
55 print(list(data.flatten()))
56
57 print("output:")
58 print(output.shape)
59 print(list(output.flatten()))
60 */
61
62 ConvolutionalParams params;
63 DnnOperand operands[2];
64 int32_t input_indexes[1];
65 float input[1*5*6*3] = {
66 0.7012556460308194, 0.4233847954643357, 0.19515900664313612, 0.16343083004926495, 0.5758261611052848, 0.9510767434014871, 0.11014085055947687,
67 0.906327053637727, 0.8136794715542507, 0.45371764543639526, 0.5768443343523952, 0.19543668786046986, 0.15648326047898609, 0.2099500241141279,
68 0.17658777090552413, 0.059335724777169196, 0.1729991838469117, 0.8150514704819208, 0.4435535466703049, 0.3752188477566878, 0.749936650421431,
69 0.6823494635284907, 0.10776389679424747, 0.34247481674596836, 0.5147867256244629, 0.9063709728129032, 0.12423605800856818, 0.6064872945412728,
70 0.5891681538551459, 0.9865836236466314, 0.9002163879294677, 0.003968273184274618, 0.8628374809643967, 0.1327176268279583, 0.8449799925703798,
71 0.1937671869354366, 0.41524410152707425, 0.02038786604756837, 0.49792466069597496, 0.8881874553848784, 0.9683921035597336, 0.4122972568010813,
72 0.843553550993252, 0.9588482762501964, 0.5190350762645546, 0.4283584264145317, 0.09781496073714646, 0.9501058833776156, 0.8665541760152776,
73 0.31669272550095806, 0.07133074675453632, 0.606438007334886, 0.7007157020538224, 0.4827996264130444, 0.5167615606392761, 0.6385043039312651,
74 0.23069664707810555, 0.058233497329354456, 0.06323892961591071, 0.24816458893245974, 0.8646369065257812, 0.24742185893094837, 0.09991225948167437,
75 0.625700606979606, 0.7678541502111257, 0.6215834594679912, 0.5623003956582483, 0.07389123942681242, 0.7659100715711249, 0.486061471642225,
76 0.9947455699829012, 0.9094911797643259, 0.7644355876253265, 0.05384315321492239, 0.13565394382783613, 0.9810628204953316, 0.007386389078887889,
77 0.226182754156241, 0.2609021390764772, 0.24182802076928933, 0.13264782451941648, 0.2035816485767682, 0.005504188177612557, 0.7014619934040155,
78 0.956215988391991, 0.5670398541013633, 0.9809764721750784, 0.6886338100487461, 0.5758152317218274, 0.7137823176776179
79 };
80 float expected_output[1*5*6*2] = {
81 -0.9480655, -0.7169147, -0.9404794, -0.5567385, -0.8991124, -0.8306558, -0.94487447, -0.8932543, -0.88238764, -0.7301602,
82 -0.8974813, -0.7026703, -0.8858988, -0.53203243, -0.92881465, -0.5648504, -0.8871471, -0.7000097, -0.91754407, -0.79684794,
83 -0.760465, -0.117928326, -0.88302773, -0.8975289, -0.70615053, 0.19231977, -0.8318776, -0.386184, -0.80698484, -0.8556624,
84 -0.7336671, -0.6168619, -0.7658234, -0.63449603, -0.73314047, -0.87502456, -0.58158904, -0.4184259, -0.52618927, -0.13613208,
85 -0.5093187, -0.21027721, -0.39455596, -0.44507834, -0.22269244, -0.73400885, -0.77655095, -0.74408925, -0.57313335, -0.15333457,
86 -0.74620694, -0.34858236, -0.42586932, -0.5240488, 0.1634339, -0.2447881, -0.57927346, -0.62732303, -0.82287043, -0.8474058
87 };
88 float *output;
89 float kernel[2*3*3*3] = {
90 0.26025516, 0.16536498, -0.24351254, 0.33892477, -0.34005195, 0.35202783, 0.34056443, 0.01422739, 0.13799345, 0.29489166,
91 0.2781723, 0.178585, 0.22122234, 0.044115514, 0.13134438, 0.31705368, 0.22527462, -0.021323413, 0.115134746, -0.18216397,
92 -0.21197563, -0.027848959, -0.01704529, -0.12401503, -0.23415318, -0.12661739, -0.35338148, 0.20049328, -0.076153606,
93 -0.23642601, -0.3125769, -0.025851756, -0.30006272, 0.050762743, 0.32003498, 0.3052225, -0.0017385483, 0.25337684, -0.25664508,
94 0.27846587, -0.3112659, 0.2066065, 0.31499845, 0.113178134, 0.09449363, -0.11828774, -0.12671001, -0.36259216, 0.2710235,
95 -0.19676702, 0.023612618, -0.2596915, -0.34949252, -0.108270735
96 };
97 float bias[2] = { -1.6574852, -0.72915393 };
98
99 NativeContext ctx;
100 ctx.class = NULL;
101 ctx.options.conv2d_threads = 1;
102
103 params.activation = TANH;
104 params.has_bias = 1;
105 params.biases = bias;
106 params.dilation = 2;
107 params.input_num = 3;
108 params.kernel = kernel;
109 params.kernel_size = 3;
110 params.output_num = 2;
111 params.padding_method = SAME;
112
113 operands[0].data = input;
114 operands[0].dims[0] = 1;
115 operands[0].dims[1] = 5;
116 operands[0].dims[2] = 6;
117 operands[0].dims[3] = 3;
118 operands[1].data = NULL;
119
120 input_indexes[0] = 0;
121 ff_dnn_execute_layer_conv2d(operands, input_indexes, 1, &params, &ctx);
122
123 output = operands[1].data;
124 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
125 if (fabs(output[i] - expected_output[i]) > EPSON) {
126 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
127 av_freep(&output);
128 return 1;
129 }
130 }
131
132 av_freep(&output);
133 return 0;
134}
135
136static int test_with_valid(void)
137{
138 // the input data and expected data are generated with below python code.
139 /*
140 x = tf.placeholder(tf.float32, shape=[1, None, None, 3])
141 y = tf.layers.conv2d(x, 2, 3, activation=tf.nn.tanh, padding='valid', bias_initializer=tf.keras.initializers.he_normal())
142 data = np.random.rand(1, 5, 6, 3);
143
144 sess=tf.Session()
145 sess.run(tf.global_variables_initializer())
146
147 weights = dict([(var.name, sess.run(var)) for var in tf.trainable_variables()])
148 kernel = weights['conv2d/kernel:0']
149 kernel = np.transpose(kernel, [3, 0, 1, 2])
150 print("kernel:")
151 print(kernel.shape)
152 print(list(kernel.flatten()))
153
154 bias = weights['conv2d/bias:0']
155 print("bias:")
156 print(bias.shape)
157 print(list(bias.flatten()))
158
159 output = sess.run(y, feed_dict={x: data})
160
161 print("input:")
162 print(data.shape)
163 print(list(data.flatten()))
164
165 print("output:")
166 print(output.shape)
167 print(list(output.flatten()))
168 */
169
170 ConvolutionalParams params;
171 DnnOperand operands[2];
172 int32_t input_indexes[1];
173 float input[1*5*6*3] = {
174 0.26126657468269665, 0.42762216215337556, 0.7466274030131497, 0.802550266787863, 0.3709323443076644, 0.5919817068197668, 0.49274512279324967,
175 0.7170132295090351, 0.0911793215410649, 0.5134213878288361, 0.670132600785118, 0.49417034512633484, 0.03887389460089885, 0.436785102836845,
176 0.1490231658611978, 0.6413606121498127, 0.8595987991375995, 0.9132593077586231, 0.7075959004873255, 0.17754995944845464, 0.5212507214937141,
177 0.35379732738215475, 0.25205107358505296, 0.3928792840544273, 0.09485294189485782, 0.8685115437448666, 0.6489046799288605, 0.509253797582924,
178 0.8993255536791972, 0.18740056466602373, 0.34237617336313986, 0.3871438962989183, 0.1488532571774911, 0.5187002331293636, 0.8137098818752955,
179 0.521761863717401, 0.4622312310118274, 0.29038411334638825, 0.16194915718170566, 0.5175999923925211, 0.8852230040101133, 0.0218263385047206,
180 0.08482355352852367, 0.3463638568376264, 0.28627127120619733, 0.9553293378948409, 0.4803391055970835, 0.841635695030805, 0.3556828280031952,
181 0.06778527221541808, 0.28193560357091596, 0.8399957619031576, 0.03305536359456385, 0.6625039162109645, 0.9300552020023897, 0.8551529138204146,
182 0.6133216915522418, 0.222427800857393, 0.1315422686800336, 0.6189144989185527, 0.5346184916866876, 0.8348888624532548, 0.6544834567840291,
183 0.2844062293389934, 0.28780026600883324, 0.5372272015684924, 0.6250226011503823, 0.28119106062279453, 0.49655812908420094, 0.6451488959145951,
184 0.7362580606834843, 0.44815578616664087, 0.6454760235835586, 0.6794062414265861, 0.045378883014935756, 0.9008388543865096, 0.7949752851269782,
185 0.4179928876222264, 0.28733419007048644, 0.996902319501908, 0.5690851338677467, 0.9511814013279738, 0.025323788678181636, 0.5594359732604794,
186 0.1213732595086251, 0.7172624313368294, 0.6759328959074691, 0.07252138454885071, 0.17557735158403442, 0.5988895455048769
187 };
188 float expected_output[1*3*4*2] = {
189 -0.556947, -0.42143887, -0.092070885, 0.27404794, -0.41886684, 0.0862887, -0.25001016, -0.342721, 0.020730592, 0.04016919, -0.69839877,
190 -0.06136704, 0.14186388, -0.11655602, -0.23489095, -0.3845829, -0.19017771, 0.1595885, -0.18308741, -0.3071209, -0.5848686, -0.22509028,
191 -0.6023201, -0.14448485
192 };
193 float *output;
194 float kernel[2*3*3*3] = {
195 -0.25291282, 0.22402048, 0.028642118, -0.14615723, -0.27362752, -0.34801802, -0.2759148, 0.19594926, -0.25029412, 0.34606284, 0.10376671,
196 -0.1015394, 0.23616093, 0.2134214, 0.35285157, 0.05893758, 0.0024731457, -0.17143056, 0.35758412, 0.2186206, -0.28384736, -0.21206513,
197 -0.20871592, 0.27070445, 0.25878823, 0.11136332, -0.33737376, 0.08353335, -0.34290665, 0.041805506, -0.09738535, 0.3284936, -0.16838405,
198 -0.032494456, -0.29193437, 0.033259362, -0.09272635, -0.2802651, -0.28648436, 0.3542878, 0.2432127, -0.24551713, 0.27813476, 0.21024024,
199 -0.013690501, -0.1350077, -0.07826337, -0.34563828, 0.3220685, -0.07571727, 0.19420576, 0.20783454, 0.18738335, 0.16672492
200 };
201 float bias[2] = { -0.4773722, -0.19620377 };
202
203 NativeContext ctx;
204 ctx.class = NULL;
205 ctx.options.conv2d_threads = 1;
206
207 params.activation = TANH;
208 params.has_bias = 1;
209 params.biases = bias;
210 params.dilation = 1;
211 params.input_num = 3;
212 params.kernel = kernel;
213 params.kernel_size = 3;
214 params.output_num = 2;
215 params.padding_method = VALID;
216
217 operands[0].data = input;
218 operands[0].dims[0] = 1;
219 operands[0].dims[1] = 5;
220 operands[0].dims[2] = 6;
221 operands[0].dims[3] = 3;
222 operands[1].data = NULL;
223
224 input_indexes[0] = 0;
225 ff_dnn_execute_layer_conv2d(operands, input_indexes, 1, &params, &ctx);
226
227 output = operands[1].data;
228 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
229 if (fabs(output[i] - expected_output[i]) > EPSON) {
230 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
231 av_freep(&output);
232 return 1;
233 }
234 }
235
236 av_freep(&output);
237 return 0;
238}
239
240int main(int argc, char **argv)
241{
242 if (test_with_valid())
243 return 1;
244 if (test_with_same_dilate())
245 return 1;
246
247 return 0;
248}
libavfilter/tests/dnn-layer-dense.c+131−0
@@ -0,0 +1,131 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_dense.h"
25
26#define EPSON 0.00001
27
28static int test(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.layers.dense(input_x, 3, activation=tf.nn.sigmoid, bias_initializer=tf.keras.initializers.he_normal())
34 data = np.random.rand(1, 5, 6, 3);
35
36 sess=tf.Session()
37 sess.run(tf.global_variables_initializer())
38
39 weights = dict([(var.name, sess.run(var)) for var in tf.trainable_variables()])
40 kernel = weights['dense/kernel:0']
41 kernel = np.transpose(kernel, [1, 0])
42 print("kernel:")
43 print(kernel.shape)
44 print(list(kernel.flatten()))
45
46 bias = weights['dense/bias:0']
47 print("bias:")
48 print(bias.shape)
49 print(list(bias.flatten()))
50
51 output = sess.run(y, feed_dict={x: data})
52
53 print("input:")
54 print(data.shape)
55 print(list(data.flatten()))
56
57 print("output:")
58 print(output.shape)
59 print(list(output.flatten()))
60 */
61
62 DenseParams params;
63 DnnOperand operands[2];
64 int32_t input_indexes[1];
65 float input[1*5*6*3] = {
66 0.5552418686576308, 0.20653189262022464, 0.31115120939398877, 0.5897014433221428, 0.37340078861060655, 0.6470921693941893, 0.8039950367872679, 0.8762700891949274,
67 0.6556655583829558, 0.5911096107039339, 0.18640250865290997, 0.2803248779238966, 0.31586613136402053, 0.9447300740056483, 0.9443980824873418, 0.8158851991115941,
68 0.5631010340387631, 0.9407402251929046, 0.6485434876551682, 0.5631376966470001, 0.17581924875609634, 0.7033802439103178, 0.04802402495561675, 0.9183681450194972,
69 0.46059317944364, 0.07964160481596883, 0.871787076270302, 0.973743142324361, 0.15923146943258415, 0.8212946080584571, 0.5415954459227064, 0.9552813822803975,
70 0.4908552668172057, 0.33723691635292274, 0.46588057864910026, 0.8994239961321776, 0.09845220457674186, 0.1713400292123486, 0.39570294912818826, 0.08018956486392803,
71 0.5290478278169032, 0.7141906125920976, 0.0320878067840098, 0.6412406575332606, 0.0075712007102423096, 0.7150828462386156, 0.1311989216968138, 0.4706847944253756,
72 0.5447610794883336, 0.3430923933318001, 0.536082357943209, 0.4371629342483694, 0.40227962985019927, 0.3553806249465469, 0.031806622424259245, 0.7053916426174,
73 0.3261570237309813, 0.419500213292063, 0.3155691223480851, 0.05664028113178088, 0.3636491555914486, 0.8502419746667123, 0.9836596530684955, 0.1628681802975801,
74 0.09410832912479894, 0.28407218939480294, 0.7983417928813697, 0.24132158596506748, 0.8154729498062224, 0.29173768373895637, 0.13407102008052096, 0.18705786678800385,
75 0.7167943621295573, 0.09222004247174376, 0.2319220738766018, 0.17708964382285064, 0.1391440370249517, 0.3254088083499256, 0.4013916894718289, 0.4819742663322323,
76 0.15080103744648077, 0.9302407847555013, 0.9397597961319524, 0.5719200825550793, 0.9538938024682824, 0.9583882089203861, 0.5168861091262276, 0.1926396841842669,
77 0.6781176744337578, 0.719366447288566
78 };
79 float expected_output[1*5*6*3] = {
80 -0.3921688, -0.9243112, -0.29659146, -0.64000785, -0.9466343, -0.62125254, -0.71759033, -0.9171336, -0.735589, -0.34365994,
81 -0.92100817, -0.23903961, -0.8962277, -0.9521279, -0.90962386, -0.7488303, -0.9563761, -0.7701762, -0.40800542, -0.87684774,
82 -0.3339763, -0.6354543, -0.97068924, -0.6246325, -0.6992075, -0.9706726, -0.6818918, -0.51864433, -0.9592881, -0.51187396,
83 -0.7423632, -0.89911884, -0.7457824, -0.82009757, -0.96402895, -0.8235518, -0.61980766, -0.94494647, -0.5410502, -0.8281218,
84 -0.95508635, -0.8201453, -0.5937325, -0.8679507, -0.500767, -0.39430764, -0.93967676, -0.32183182, -0.58913624, -0.939717,
85 -0.55179894, -0.55004454, -0.9214453, -0.4889004, -0.75294703, -0.9118363, -0.7200309, -0.3248641, -0.8878874, -0.18977344,
86 -0.8873837, -0.9571257, -0.90145934, -0.50521654, -0.93739635, -0.39051685, -0.61143184, -0.9591179, -0.605999, -0.40008977,
87 -0.92219675, -0.26732883, -0.19607787, -0.9172511, -0.07068595, -0.5409857, -0.9387041, -0.44181606, -0.4705004, -0.8899935,
88 -0.37997037, -0.66105115, -0.89754754, -0.68141997, -0.6324047, -0.886776, -0.65066385, -0.8334821, -0.94801456, -0.83297
89 };
90 float *output;
91 float kernel[3*3] = {
92 0.56611896, -0.5144603, -0.82600045, 0.19219112, 0.3835776, -0.7475352, 0.5209291, -0.6301091, -0.99442935};
93 float bias[3] = {-0.3654299, -1.5711838, -0.15546428};
94
95 params.activation = TANH;
96 params.has_bias = 1;
97 params.biases = bias;
98 params.input_num = 3;
99 params.kernel = kernel;
100 params.output_num = 3;
101
102 operands[0].data = input;
103 operands[0].dims[0] = 1;
104 operands[0].dims[1] = 5;
105 operands[0].dims[2] = 6;
106 operands[0].dims[3] = 3;
107 operands[1].data = NULL;
108
109 input_indexes[0] = 0;
110 ff_dnn_execute_layer_dense(operands, input_indexes, 1, &params, NULL);
111
112 output = operands[1].data;
113 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
114 if (fabs(output[i] - expected_output[i]) > EPSON) {
115 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
116 av_freep(&output);
117 return 1;
118 }
119 }
120
121 av_freep(&output);
122 return 0;
123}
124
125int main(int argc, char **argv)
126{
127 if (test())
128 return 1;
129
130 return 0;
131}
libavfilter/tests/dnn-layer-depth2space.c+102−0
@@ -0,0 +1,102 @@
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>
24#include "libavfilter/dnn/dnn_backend_native.h"
25#include "libavfilter/dnn/dnn_backend_native_layer_depth2space.h"
26
27#define EPSON 0.00001
28
29static int test(void)
30{
31 // the input data and expected data are generated with below python code.
32 /*
33 x = tf.placeholder(tf.float32, shape=[1, None, None, 4])
34 y = tf.depth_to_space(x, 2)
35 data = np.random.rand(1, 5, 3, 4);
36
37 sess=tf.Session()
38 sess.run(tf.global_variables_initializer())
39
40 output = sess.run(y, feed_dict={x: data})
41
42 print("input:")
43 print(data.shape)
44 print(list(data.flatten()))
45
46 print("output:")
47 print(output.shape)
48 print(list(output.flatten()))
49 */
50
51 DepthToSpaceParams params;
52 DnnOperand operands[2];
53 int32_t input_indexes[1];
54 float input[1*5*3*4] = {
55 0.09771065121566602, 0.6336807372403175, 0.5142416549709786, 0.8027206567330333, 0.2154276025069397, 0.12112878462616772, 0.913936596765778,
56 0.38881443647542646, 0.5850447615898835, 0.9311499327398275, 0.3613660929428246, 0.5420722002125493, 0.6002131190230359, 0.44800665702299525,
57 0.7271322557896777, 0.3869293511885826, 0.5144404769364138, 0.6910844856987723, 0.6142102742269762, 0.6249991371621018, 0.45663376215836626,
58 0.19523477129943423, 0.2483895888532045, 0.64326768256278, 0.5485877602998981, 0.45442067849873546, 0.529374943304256, 0.30439850391811885,
59 0.11961343361340993, 0.2909643484561082, 0.9810970344127848, 0.8886928489786549, 0.6112237084436409, 0.8852482695156674, 0.9110868043114374,
60 0.21242780027585217, 0.7101536973207572, 0.9709717457443375, 0.2702666770969332, 0.7718295953780221, 0.3957005164588574, 0.24383544252475453,
61 0.040143453532367035, 0.26358051835323115, 0.013130251443791319, 0.3016550481482074, 0.03582340459943956, 0.718025513612361, 0.09844204177633753,
62 0.04433767496953056, 0.6221895044119757, 0.6190414032940228, 0.8963550834625371, 0.5642449700064629, 0.2482982014723497, 0.17824909294583013,
63 0.024401882408643272, 0.21742800875253465, 0.6794724473181843, 0.4814830479242237
64 };
65 float expected_output[1*10*6*1] = {
66 0.097710654, 0.63368076, 0.2154276, 0.12112878, 0.58504474, 0.93114996, 0.51424164, 0.80272067, 0.9139366, 0.38881445,
67 0.3613661, 0.5420722, 0.6002131, 0.44800666, 0.5144405, 0.6910845, 0.45663378, 0.19523478, 0.72713226, 0.38692936,
68 0.61421025, 0.62499917, 0.24838959, 0.6432677, 0.54858774, 0.4544207, 0.11961343, 0.29096434, 0.6112237, 0.88524824,
69 0.52937496, 0.3043985, 0.98109704, 0.88869286, 0.9110868, 0.2124278, 0.7101537, 0.97097176, 0.3957005, 0.24383545,
70 0.013130251, 0.30165505, 0.27026668, 0.7718296, 0.040143453, 0.26358053, 0.035823405, 0.7180255, 0.09844204,
71 0.044337675, 0.8963551, 0.564245, 0.024401883, 0.21742801, 0.6221895, 0.6190414, 0.2482982, 0.17824909, 0.67947245, 0.48148304
72 };
73 float *output;
74
75 operands[0].data = input;
76 operands[0].dims[0] = 1;
77 operands[0].dims[1] = 5;
78 operands[0].dims[2] = 3;
79 operands[0].dims[3] = 4;
80 operands[1].data = NULL;
81
82 input_indexes[0] = 0;
83 params.block_size = 2;
84 ff_dnn_execute_layer_depth2space(operands, input_indexes, 1, &params, NULL);
85
86 output = operands[1].data;
87 for (int i = 0; i < sizeof(expected_output) / sizeof(float); i++) {
88 if (fabs(output[i] - expected_output[i]) > EPSON) {
89 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output[i]);
90 av_freep(&output);
91 return 1;
92 }
93 }
94
95 av_freep(&output);
96 return 0;
97}
98
99int main(int argc, char **argv)
100{
101 return test();
102}
libavfilter/tests/dnn-layer-mathbinary.c+214−0
@@ -0,0 +1,214 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_mathbinary.h"
25#include "libavutil/avassert.h"
26
27#define EPSON 0.00005
28
29static 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 case DMBO_FLOORMOD:
44 return (float)((int)(f1) % (int)(f2));
45 default:
46 av_assert0(!"not supported yet");
47 return 0.f;
48 }
49}
50
51static int test_broadcast_input0(DNNMathBinaryOperation op)
52{
53 DnnLayerMathBinaryParams params;
54 DnnOperand operands[2];
55 int32_t input_indexes[1];
56 float input[1*1*2*3] = {
57 -3, 2.5, 2, -2.1, 7.8, 100
58 };
59 float *output;
60
61 params.bin_op = op;
62 params.input0_broadcast = 1;
63 params.input1_broadcast = 0;
64 params.v = 7.28;
65
66 operands[0].data = input;
67 operands[0].dims[0] = 1;
68 operands[0].dims[1] = 1;
69 operands[0].dims[2] = 2;
70 operands[0].dims[3] = 3;
71 operands[1].data = NULL;
72
73 input_indexes[0] = 0;
74 ff_dnn_execute_layer_math_binary(operands, input_indexes, 1, &params, NULL);
75
76 output = operands[1].data;
77 for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
78 float expected_output = get_expected(params.v, input[i], op);
79 if (fabs(output[i] - expected_output) > EPSON) {
80 printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
81 op, i, output[i], expected_output, __FILE__, __LINE__);
82 av_freep(&output);
83 return 1;
84 }
85 }
86
87 av_freep(&output);
88 return 0;
89}
90
91static int test_broadcast_input1(DNNMathBinaryOperation op)
92{
93 DnnLayerMathBinaryParams params;
94 DnnOperand operands[2];
95 int32_t input_indexes[1];
96 float input[1*1*2*3] = {
97 -3, 2.5, 2, -2.1, 7.8, 100
98 };
99 float *output;
100
101 params.bin_op = op;
102 params.input0_broadcast = 0;
103 params.input1_broadcast = 1;
104 params.v = 7.28;
105
106 operands[0].data = input;
107 operands[0].dims[0] = 1;
108 operands[0].dims[1] = 1;
109 operands[0].dims[2] = 2;
110 operands[0].dims[3] = 3;
111 operands[1].data = NULL;
112
113 input_indexes[0] = 0;
114 ff_dnn_execute_layer_math_binary(operands, input_indexes, 1, &params, NULL);
115
116 output = operands[1].data;
117 for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
118 float expected_output = get_expected(input[i], params.v, op);
119 if (fabs(output[i] - expected_output) > EPSON) {
120 printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
121 op, i, output[i], expected_output, __FILE__, __LINE__);
122 av_freep(&output);
123 return 1;
124 }
125 }
126
127 av_freep(&output);
128 return 0;
129}
130
131static int test_no_broadcast(DNNMathBinaryOperation op)
132{
133 DnnLayerMathBinaryParams params;
134 DnnOperand operands[3];
135 int32_t input_indexes[2];
136 float input0[1*1*2*3] = {
137 -3, 2.5, 2, -2.1, 7.8, 100
138 };
139 float input1[1*1*2*3] = {
140 -1, 2, 3, -21, 8, 10.0
141 };
142 float *output;
143
144 params.bin_op = op;
145 params.input0_broadcast = 0;
146 params.input1_broadcast = 0;
147
148 operands[0].data = input0;
149 operands[0].dims[0] = 1;
150 operands[0].dims[1] = 1;
151 operands[0].dims[2] = 2;
152 operands[0].dims[3] = 3;
153 operands[1].data = input1;
154 operands[1].dims[0] = 1;
155 operands[1].dims[1] = 1;
156 operands[1].dims[2] = 2;
157 operands[1].dims[3] = 3;
158 operands[2].data = NULL;
159
160 input_indexes[0] = 0;
161 input_indexes[1] = 1;
162 ff_dnn_execute_layer_math_binary(operands, input_indexes, 2, &params, NULL);
163
164 output = operands[2].data;
165 for (int i = 0; i < sizeof(input0) / sizeof(float); i++) {
166 float expected_output = get_expected(input0[i], input1[i], op);
167 if (fabs(output[i] - expected_output) > EPSON) {
168 printf("op %d, at index %d, output: %f, expected_output: %f (%s:%d)\n",
169 op, i, output[i], expected_output, __FILE__, __LINE__);
170 av_freep(&output);
171 return 1;
172 }
173 }
174
175 av_freep(&output);
176 return 0;
177}
178
179static int test(DNNMathBinaryOperation op)
180{
181 if (test_broadcast_input0(op))
182 return 1;
183
184 if (test_broadcast_input1(op))
185 return 1;
186
187 if (test_no_broadcast(op))
188 return 1;
189
190 return 0;
191}
192
193int main(int argc, char **argv)
194{
195 if (test(DMBO_SUB))
196 return 1;
197
198 if (test(DMBO_ADD))
199 return 1;
200
201 if (test(DMBO_MUL))
202 return 1;
203
204 if (test(DMBO_REALDIV))
205 return 1;
206
207 if (test(DMBO_MINIMUM))
208 return 1;
209
210 if (test(DMBO_FLOORMOD))
211 return 1;
212
213 return 0;
214}
libavfilter/tests/dnn-layer-mathunary.c+148−0
@@ -0,0 +1,148 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_mathunary.h"
25#include "libavutil/avassert.h"
26
27#define EPS 0.00001
28
29static float get_expected(float f, DNNMathUnaryOperation op)
30{
31 switch (op)
32 {
33 case DMUO_ABS:
34 return (f >= 0) ? f : -f;
35 case DMUO_SIN:
36 return sin(f);
37 case DMUO_COS:
38 return cos(f);
39 case DMUO_TAN:
40 return tan(f);
41 case DMUO_ASIN:
42 return asin(f);
43 case DMUO_ACOS:
44 return acos(f);
45 case DMUO_ATAN:
46 return atan(f);
47 case DMUO_SINH:
48 return sinh(f);
49 case DMUO_COSH:
50 return cosh(f);
51 case DMUO_TANH:
52 return tanh(f);
53 case DMUO_ASINH:
54 return asinh(f);
55 case DMUO_ACOSH:
56 return acosh(f);
57 case DMUO_ATANH:
58 return atanh(f);
59 case DMUO_CEIL:
60 return ceil(f);
61 case DMUO_FLOOR:
62 return floor(f);
63 case DMUO_ROUND:
64 return round(f);
65 case DMUO_EXP:
66 return exp(f);
67 default:
68 av_assert0(!"not supported yet");
69 return 0.f;
70 }
71}
72
73static int test(DNNMathUnaryOperation op)
74{
75 DnnLayerMathUnaryParams params;
76 DnnOperand operands[2];
77 int32_t input_indexes[1];
78 float input[1*1*3*3] = {
79 0.1, 0.5, 0.75, -3, 2.5, 2, -2.1, 7.8, 100};
80 float *output;
81
82 params.un_op = op;
83
84 operands[0].data = input;
85 operands[0].dims[0] = 1;
86 operands[0].dims[1] = 1;
87 operands[0].dims[2] = 3;
88 operands[0].dims[3] = 3;
89 operands[1].data = NULL;
90
91 input_indexes[0] = 0;
92 ff_dnn_execute_layer_math_unary(operands, input_indexes, 1, &params, NULL);
93
94 output = operands[1].data;
95 for (int i = 0; i < sizeof(input) / sizeof(float); ++i) {
96 float expected_output = get_expected(input[i], op);
97 int output_nan = isnan(output[i]);
98 int expected_nan = isnan(expected_output);
99 if ((!output_nan && !expected_nan && fabs(output[i] - expected_output) > EPS) ||
100 (output_nan && !expected_nan) || (!output_nan && expected_nan)) {
101 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output);
102 av_freep(&output);
103 return 1;
104 }
105 }
106
107 av_freep(&output);
108 return 0;
109}
110
111int main(int agrc, char **argv)
112{
113 if (test(DMUO_ABS))
114 return 1;
115 if (test(DMUO_SIN))
116 return 1;
117 if (test(DMUO_COS))
118 return 1;
119 if (test(DMUO_TAN))
120 return 1;
121 if (test(DMUO_ASIN))
122 return 1;
123 if (test(DMUO_ACOS))
124 return 1;
125 if (test(DMUO_ATAN))
126 return 1;
127 if (test(DMUO_SINH))
128 return 1;
129 if (test(DMUO_COSH))
130 return 1;
131 if (test(DMUO_TANH))
132 return 1;
133 if (test(DMUO_ASINH))
134 return 1;
135 if (test(DMUO_ACOSH))
136 return 1;
137 if (test(DMUO_ATANH))
138 return 1;
139 if (test(DMUO_CEIL))
140 return 1;
141 if (test(DMUO_FLOOR))
142 return 1;
143 if (test(DMUO_ROUND))
144 return 1;
145 if (test(DMUO_EXP))
146 return 1;
147 return 0;
148}
libavfilter/tests/dnn-layer-maximum.c+71−0
@@ -0,0 +1,71 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_maximum.h"
25
26#define EPSON 0.00001
27
28static int test(void)
29{
30 DnnLayerMaximumParams params;
31 DnnOperand operands[2];
32 int32_t input_indexes[1];
33 float input[1*1*2*3] = {
34 -3, 2.5, 2, -2.1, 7.8, 100
35 };
36 float *output;
37
38 params.val.y = 2.3;
39
40 operands[0].data = input;
41 operands[0].dims[0] = 1;
42 operands[0].dims[1] = 1;
43 operands[0].dims[2] = 2;
44 operands[0].dims[3] = 3;
45 operands[1].data = NULL;
46
47 input_indexes[0] = 0;
48 ff_dnn_execute_layer_maximum(operands, input_indexes, 1, &params, NULL);
49
50 output = operands[1].data;
51 for (int i = 0; i < sizeof(input) / sizeof(float); i++) {
52 float expected_output = input[i] > params.val.y ? input[i] : params.val.y;
53 if (fabs(output[i] - expected_output) > EPSON) {
54 printf("at index %d, output: %f, expected_output: %f\n", i, output[i], expected_output);
55 av_freep(&output);
56 return 1;
57 }
58 }
59
60 av_freep(&output);
61 return 0;
62
63}
64
65int main(int argc, char **argv)
66{
67 if (test())
68 return 1;
69
70 return 0;
71}
libavfilter/tests/dnn-layer-pad.c+239−0
@@ -0,0 +1,239 @@
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>
24#include "libavfilter/dnn/dnn_backend_native_layer_pad.h"
25
26#define EPSON 0.00001
27
28static 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
98static 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
163static 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
229int main(int argc, char **argv)
230{
231 if (test_with_mode_symmetric())
232 return 1;
233
234 if (test_with_mode_reflect())
235 return 1;
236
237 if (test_with_mode_constant())
238 return 1;
239}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t