FFmpeg
Loading...
Searching...
No Matches
float_dsp.c
Go to the documentation of this file.
1/*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 */
18
19#include <float.h>
20#include <stdint.h>
21#include <string.h>
22
23#include "libavutil/float_dsp.h"
24#include "libavutil/internal.h"
25#include "libavutil/mem.h"
27
28#include "checkasm.h"
29
30#define LEN 256
31
32static void test_vector_fmul(const float *src0, const float *src1)
33{
34 LOCAL_ALIGNED_32(float, cdst, [LEN]);
35 LOCAL_ALIGNED_32(float, odst, [LEN]);
36 int i;
37
38 declare_func(void, float *dst, const float *src0, const float *src1,
39 int len);
40
41 call_ref(cdst, src0, src1, LEN);
42 call_new(odst, src0, src1, LEN);
43 for (i = 0; i < LEN; i++) {
44 double t = fabs(src0[i]) + fabs(src1[i]) + fabs(src0[i] * src1[i]) + 1.0;
45 if (!float_near_abs_eps(cdst[i], odst[i], t * 2 * FLT_EPSILON)) {
46 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
47 i, cdst[i], odst[i], cdst[i] - odst[i]);
48 fail();
49 break;
50 }
51 }
52 bench_new(odst, src0, src1, LEN);
53}
54
55static void test_vector_dmul(const double *src0, const double *src1)
56{
57 LOCAL_ALIGNED_32(double, cdst, [LEN]);
58 LOCAL_ALIGNED_32(double, odst, [LEN]);
59 int i;
60
61 declare_func(void, double *dst, const double *src0, const double *src1,
62 int len);
63
64 call_ref(cdst, src0, src1, LEN);
65 call_new(odst, src0, src1, LEN);
66 for (i = 0; i < LEN; i++) {
67 double t = fabs(src0[i]) + fabs(src1[i]) + fabs(src0[i] * src1[i]) + 1.0;
68 if (!double_near_abs_eps(cdst[i], odst[i], t * 2 * DBL_EPSILON)) {
69 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
70 i, cdst[i], odst[i], cdst[i] - odst[i]);
71 fail();
72 break;
73 }
74 }
75 bench_new(odst, src0, src1, LEN);
76}
77
78#define ARBITRARY_FMUL_ADD_CONST 0.005
79static void test_vector_fmul_add(const float *src0, const float *src1, const float *src2)
80{
81 LOCAL_ALIGNED_32(float, cdst, [LEN]);
82 LOCAL_ALIGNED_32(float, odst, [LEN]);
83 int i;
84
85 declare_func(void, float *dst, const float *src0, const float *src1,
86 const float *src2, int len);
87
88 call_ref(cdst, src0, src1, src2, LEN);
89 call_new(odst, src0, src1, src2, LEN);
90 for (i = 0; i < LEN; i++) {
91 if (!float_near_abs_eps(cdst[i], odst[i], ARBITRARY_FMUL_ADD_CONST)) {
92 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
93 i, cdst[i], odst[i], cdst[i] - odst[i]);
94 fail();
95 break;
96 }
97 }
98 bench_new(odst, src0, src1, src2, LEN);
99}
100
101static void test_vector_fmul_scalar(const float *src0, const float *src1)
102{
103 LOCAL_ALIGNED_16(float, cdst, [LEN]);
104 LOCAL_ALIGNED_16(float, odst, [LEN]);
105 int i;
106
107 declare_func(void, float *dst, const float *src, float mul, int len);
108
109 call_ref(cdst, src0, src1[0], LEN);
110 call_new(odst, src0, src1[0], LEN);
111 for (i = 0; i < LEN; i++) {
112 double t = fabs(src0[i]) + fabs(src1[0]) + fabs(src0[i] * src1[0]) + 1.0;
113 if (!float_near_abs_eps(cdst[i], odst[i], t * 2 * FLT_EPSILON)) {
114 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
115 i, cdst[i], odst[i], cdst[i] - odst[i]);
116 fail();
117 break;
118 }
119 }
120 bench_new(odst, src0, src1[0], LEN);
121}
122
123#define ARBITRARY_FMUL_WINDOW_CONST 0.008
124static void test_vector_fmul_window(const float *src0, const float *src1, const float *win)
125{
126 LOCAL_ALIGNED_16(float, cdst, [LEN]);
127 LOCAL_ALIGNED_16(float, odst, [LEN]);
128 int i;
129
130 declare_func(void, float *dst, const float *src0, const float *src1,
131 const float *win, int len);
132
133 call_ref(cdst, src0, src1, win, LEN / 2);
134 call_new(odst, src0, src1, win, LEN / 2);
135 for (i = 0; i < LEN; i++) {
137 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
138 i, cdst[i], odst[i], cdst[i] - odst[i]);
139 fail();
140 break;
141 }
142 }
143 bench_new(odst, src0, src1, win, LEN / 2);
144}
145
146#define ARBITRARY_FMAC_SCALAR_CONST 0.005
147static void test_vector_fmac_scalar(const float *src0, const float *src1, const float *src2)
148{
149 LOCAL_ALIGNED_32(float, cdst, [LEN]);
150 LOCAL_ALIGNED_32(float, odst, [LEN]);
151 int i;
152
153 declare_func(void, float *dst, const float *src, float mul, int len);
154
155 memcpy(cdst, src2, LEN * sizeof(*src2));
156 memcpy(odst, src2, LEN * sizeof(*src2));
157
158 call_ref(cdst, src0, src1[0], LEN);
159 call_new(odst, src0, src1[0], LEN);
160 for (i = 0; i < LEN; i++) {
162 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
163 i, cdst[i], odst[i], cdst[i] - odst[i]);
164 fail();
165 break;
166 }
167 }
168 memcpy(odst, src2, LEN * sizeof(*src2));
169 bench_new(odst, src0, src1[0], LEN);
170}
171
172static void test_vector_dmul_scalar(const double *src0, const double *src1)
173{
174 LOCAL_ALIGNED_32(double, cdst, [LEN]);
175 LOCAL_ALIGNED_32(double, odst, [LEN]);
176 int i;
177
178 declare_func(void, double *dst, const double *src, double mul, int len);
179
180 call_ref(cdst, src0, src1[0], LEN);
181 call_new(odst, src0, src1[0], LEN);
182 for (i = 0; i < LEN; i++) {
183 double t = fabs(src1[0]) + fabs(src0[i]) + fabs(src1[0] * src0[i]) + 1.0;
184 if (!double_near_abs_eps(cdst[i], odst[i], t * 2 * DBL_EPSILON)) {
185 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n", i,
186 cdst[i], odst[i], cdst[i] - odst[i]);
187 fail();
188 break;
189 }
190 }
191 bench_new(odst, src0, src1[0], LEN);
192}
193
194#define ARBITRARY_DMAC_SCALAR_CONST 0.005
195static void test_vector_dmac_scalar(const double *src0, const double *src1, const double *src2)
196{
197 LOCAL_ALIGNED_32(double, cdst, [LEN]);
198 LOCAL_ALIGNED_32(double, odst, [LEN]);
199 int i;
200
201 declare_func(void, double *dst, const double *src, double mul, int len);
202
203 memcpy(cdst, src2, LEN * sizeof(*src2));
204 memcpy(odst, src2, LEN * sizeof(*src2));
205 call_ref(cdst, src0, src1[0], LEN);
206 call_new(odst, src0, src1[0], LEN);
207 for (i = 0; i < LEN; i++) {
209 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
210 i, cdst[i], odst[i], cdst[i] - odst[i]);
211 fail();
212 break;
213 }
214 }
215 memcpy(odst, src2, LEN * sizeof(*src2));
216 bench_new(odst, src0, src1[0], LEN);
217}
218
219static void test_butterflies_float(const float *src0, const float *src1)
220{
221 LOCAL_ALIGNED_16(float, cdst, [LEN]);
222 LOCAL_ALIGNED_16(float, odst, [LEN]);
223 LOCAL_ALIGNED_16(float, cdst1, [LEN]);
224 LOCAL_ALIGNED_16(float, odst1, [LEN]);
225 int i;
226
227 declare_func(void, float *restrict src0, float *restrict src1,
228 int len);
229
230 memcpy(cdst, src0, LEN * sizeof(*src0));
231 memcpy(cdst1, src1, LEN * sizeof(*src1));
232 memcpy(odst, src0, LEN * sizeof(*src0));
233 memcpy(odst1, src1, LEN * sizeof(*src1));
234
235 call_ref(cdst, cdst1, LEN);
236 call_new(odst, odst1, LEN);
237 for (i = 0; i < LEN; i++) {
238 if (!float_near_abs_eps(cdst[i], odst[i], FLT_EPSILON) ||
239 !float_near_abs_eps(cdst1[i], odst1[i], FLT_EPSILON)) {
240 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
241 i, cdst[i], odst[i], cdst[i] - odst[i]);
242 fprintf(stderr, "%d: %- .12f - %- .12f = % .12g\n",
243 i, cdst1[i], odst1[i], cdst1[i] - odst1[i]);
244 fail();
245 break;
246 }
247 }
248 memcpy(odst, src0, LEN * sizeof(*src0));
249 memcpy(odst1, src1, LEN * sizeof(*src1));
250 bench_new(odst, odst1, LEN);
251}
252
253#define ARBITRARY_SCALARPRODUCT_CONST 0.2
254static void test_scalarproduct_float(const float *src0, const float *src1)
255{
256 float cprod, oprod;
257
258 declare_func_float(float, const float *src0, const float *src1, int len);
259
260 cprod = call_ref(src0, src1, LEN);
261 oprod = call_new(src0, src1, LEN);
263 fprintf(stderr, "%- .12f - %- .12f = % .12g\n",
264 cprod, oprod, cprod - oprod);
265 fail();
266 }
268}
269
270static void test_scalarproduct_double(const double *src0, const double *src1)
271{
272 double cprod, oprod;
273
274 declare_func_float(double, const double *, const double *, size_t);
275
276 cprod = call_ref(src0, src1, LEN);
277 oprod = call_new(src0, src1, LEN);
279 fprintf(stderr, "%- .12f - %- .12f = % .12g\n",
280 cprod, oprod, cprod - oprod);
281 fail();
282 }
284}
285
287{
288 LOCAL_ALIGNED_32(float, src0, [LEN]);
289 LOCAL_ALIGNED_32(float, src1, [LEN]);
290 LOCAL_ALIGNED_32(float, src2, [LEN]);
291 LOCAL_ALIGNED_16(float, src3, [LEN]);
292 LOCAL_ALIGNED_16(float, src4, [LEN]);
293 LOCAL_ALIGNED_16(float, src5, [LEN]);
294 LOCAL_ALIGNED_32(double, dbl_src0, [LEN]);
295 LOCAL_ALIGNED_32(double, dbl_src1, [LEN]);
296 LOCAL_ALIGNED_32(double, dbl_src2, [LEN]);
298
299 if (!fdsp) {
300 fprintf(stderr, "floatdsp: Out of memory error\n");
301 return;
302 }
303
304 randomize_stddev(src0, LEN, 10.0);
305 randomize_stddev(src1, LEN, 10.0);
306 randomize_stddev(src2, LEN, 10.0);
307 randomize_stddev(src3, LEN, 10.0);
308 randomize_stddev(src4, LEN, 10.0);
309 randomize_stddev(src5, LEN, 10.0);
310 randomize_stddev_dbl(dbl_src0, LEN, 10.0);
311 randomize_stddev_dbl(dbl_src1, LEN, 10.0);
312 randomize_stddev_dbl(dbl_src2, LEN, 10.0);
313
314 if (check_func(fdsp->vector_fmul, "vector_fmul"))
316 if (check_func(fdsp->vector_fmul_add, "vector_fmul_add"))
318 if (check_func(fdsp->vector_fmul_scalar, "vector_fmul_scalar"))
319 test_vector_fmul_scalar(src3, src4);
320 if (check_func(fdsp->vector_fmul_reverse, "vector_fmul_reverse"))
322 if (check_func(fdsp->vector_fmul_window, "vector_fmul_window"))
323 test_vector_fmul_window(src3, src4, src5);
324 report("vector_fmul");
325 if (check_func(fdsp->vector_fmac_scalar, "vector_fmac_scalar"))
327 report("vector_fmac");
328 if (check_func(fdsp->vector_dmul, "vector_dmul"))
329 test_vector_dmul(dbl_src0, dbl_src1);
330 if (check_func(fdsp->vector_dmul_scalar, "vector_dmul_scalar"))
331 test_vector_dmul_scalar(dbl_src0, dbl_src1);
332 report("vector_dmul");
333 if (check_func(fdsp->vector_dmac_scalar, "vector_dmac_scalar"))
334 test_vector_dmac_scalar(dbl_src0, dbl_src1, dbl_src2);
335 report("vector_dmac");
336 if (check_func(fdsp->butterflies_float, "butterflies_float"))
337 test_butterflies_float(src3, src4);
338 report("butterflies_float");
339 if (check_func(fdsp->scalarproduct_float, "scalarproduct_float"))
340 test_scalarproduct_float(src3, src4);
341 report("scalarproduct_float");
342 if (check_func(fdsp->scalarproduct_double, "scalarproduct_double"))
343 test_scalarproduct_double(dbl_src0, dbl_src1);
344 report("scalarproduct_double");
345
346 av_freep(&fdsp);
347}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
static float win(SuperEqualizerContext *s, float n, int N)
#define LEN
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define declare_func_float
Definition checkasm.h:136
#define randomize_stddev(buf, size, stddev)
Definition checkasm.h:139
#define randomize_stddev_dbl(buf, size, stddev)
Definition checkasm.h:141
static __device__ float fabs(float a)
#define declare_func
Definition test.h:489
#define fail
Definition test.h:479
#define bench_new
Definition test.h:487
#define check_func
Definition test.h:481
#define call_new
Definition test.h:486
#define call_ref
Definition test.h:485
#define float_near_abs_eps
Definition utils.h:449
#define report
Definition test.h:480
#define double_near_abs_eps
Definition utils.h:454
const pixel * src2
av_cold AVFloatDSPContext * avpriv_float_dsp_alloc(int bit_exact)
Allocate a float DSP context.
Definition float_dsp.c:135
common internal API header
Memory handling functions.
#define LOCAL_ALIGNED_32(t, v,...)
#define LOCAL_ALIGNED_16(t, v,...)
void(* vector_fmul_reverse)(float *dst, const float *src0, const float *src1, int len)
Calculate the entry wise product of two vectors of floats, and store the result in a vector of floats...
Definition float_dsp.h:154
void(* vector_dmul_scalar)(double *dst, const double *src, double mul, int len)
Multiply a vector of double by a scalar double.
Definition float_dsp.h:100
void(* vector_fmul_add)(float *dst, const float *src0, const float *src1, const float *src2, int len)
Calculate the entry wise product of two vectors of floats, add a third vector of floats and store the...
Definition float_dsp.h:137
void(* vector_dmac_scalar)(double *dst, const double *src, double mul, int len)
Multiply a vector of doubles by a scalar double and add to destination vector.
Definition float_dsp.h:70
float(* scalarproduct_float)(const float *v1, const float *v2, int len)
Calculate the scalar product of two vectors of floats.
Definition float_dsp.h:175
void(* vector_fmul_scalar)(float *dst, const float *src, float mul, int len)
Multiply a vector of floats by a scalar float.
Definition float_dsp.h:85
void(* butterflies_float)(float *restrict v1, float *restrict v2, int len)
Calculate the sum and difference of two vectors of floats.
Definition float_dsp.h:164
void(* vector_dmul)(double *dst, const double *src0, const double *src1, int len)
Calculate the entry wise product of two vectors of doubles and store the result in a vector of double...
Definition float_dsp.h:190
void(* vector_fmul_window)(float *dst, const float *src0, const float *src1, const float *win, int len)
Overlap/add with window function.
Definition float_dsp.h:119
void(* vector_fmul)(float *dst, const float *src0, const float *src1, int len)
Calculate the entry wise product of two vectors of floats and store the result in a vector of floats.
Definition float_dsp.h:38
double(* scalarproduct_double)(const double *v1, const double *v2, size_t len)
Calculate the scalar product of two vectors of doubles.
Definition float_dsp.h:205
void(* vector_fmac_scalar)(float *dst, const float *src, float mul, int len)
Multiply a vector of floats by a scalar float and add to destination vector.
Definition float_dsp.h:54
#define av_freep(p)
static void test_vector_dmul(const double *src0, const double *src1)
Definition float_dsp.c:55
#define ARBITRARY_FMAC_SCALAR_CONST
Definition float_dsp.c:146
static void test_vector_dmul_scalar(const double *src0, const double *src1)
Definition float_dsp.c:172
static void test_butterflies_float(const float *src0, const float *src1)
Definition float_dsp.c:219
void checkasm_check_float_dsp(void)
Definition float_dsp.c:286
static void test_vector_fmul_scalar(const float *src0, const float *src1)
Definition float_dsp.c:101
static void test_vector_fmul_add(const float *src0, const float *src1, const float *src2)
Definition float_dsp.c:79
#define ARBITRARY_FMUL_WINDOW_CONST
Definition float_dsp.c:123
static void test_vector_fmac_scalar(const float *src0, const float *src1, const float *src2)
Definition float_dsp.c:147
#define ARBITRARY_SCALARPRODUCT_CONST
Definition float_dsp.c:253
#define ARBITRARY_DMAC_SCALAR_CONST
Definition float_dsp.c:194
#define ARBITRARY_FMUL_ADD_CONST
Definition float_dsp.c:78
static void test_scalarproduct_float(const float *src0, const float *src1)
Definition float_dsp.c:254
static void test_vector_fmul(const float *src0, const float *src1)
Definition float_dsp.c:32
static void test_scalarproduct_double(const double *src0, const double *src1)
Definition float_dsp.c:270
static void test_vector_fmul_window(const float *src0, const float *src1, const float *win)
Definition float_dsp.c:124
static void test_vector_dmac_scalar(const double *src0, const double *src1, const double *src2)
Definition float_dsp.c:195
#define src1
Definition h264pred.c:141
#define src0
Definition h264pred.c:140
#define src
Definition vp8dsp.c:248
int len