FFmpeg  4.3
checkasm.c
Go to the documentation of this file.
1 /*
2  * Assembly testing and benchmarking tool
3  * Copyright (c) 2015 Henrik Gramner
4  * Copyright (c) 2008 Loren Merritt
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with FFmpeg; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 #include "config.h"
24 
25 #if CONFIG_LINUX_PERF
26 # ifndef _GNU_SOURCE
27 # define _GNU_SOURCE // for syscall (performance monitoring API)
28 # endif
29 #endif
30 
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include "checkasm.h"
36 #include "libavutil/common.h"
37 #include "libavutil/cpu.h"
38 #include "libavutil/intfloat.h"
39 #include "libavutil/random_seed.h"
40 
41 #if HAVE_IO_H
42 #include <io.h>
43 #endif
44 
45 #if HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
46 #include <windows.h>
47 #define COLOR_RED FOREGROUND_RED
48 #define COLOR_GREEN FOREGROUND_GREEN
49 #define COLOR_YELLOW (FOREGROUND_RED|FOREGROUND_GREEN)
50 #else
51 #define COLOR_RED 1
52 #define COLOR_GREEN 2
53 #define COLOR_YELLOW 3
54 #endif
55 
56 #if HAVE_UNISTD_H
57 #include <unistd.h>
58 #endif
59 
60 #if !HAVE_ISATTY
61 #define isatty(fd) 1
62 #endif
63 
64 #if ARCH_ARM && HAVE_ARMV5TE_EXTERNAL
65 #include "libavutil/arm/cpu.h"
66 
67 void (*checkasm_checked_call)(void *func, int dummy, ...) = checkasm_checked_call_novfp;
68 #endif
69 
70 /* List of tests to invoke */
71 static const struct {
72  const char *name;
73  void (*func)(void);
74 } tests[] = {
75 #if CONFIG_AVCODEC
76  #if CONFIG_AAC_DECODER
77  { "aacpsdsp", checkasm_check_aacpsdsp },
78  { "sbrdsp", checkasm_check_sbrdsp },
79  #endif
80  #if CONFIG_ALAC_DECODER
81  { "alacdsp", checkasm_check_alacdsp },
82  #endif
83  #if CONFIG_AUDIODSP
84  { "audiodsp", checkasm_check_audiodsp },
85  #endif
86  #if CONFIG_BLOCKDSP
87  { "blockdsp", checkasm_check_blockdsp },
88  #endif
89  #if CONFIG_BSWAPDSP
90  { "bswapdsp", checkasm_check_bswapdsp },
91  #endif
92  #if CONFIG_DCA_DECODER
93  { "synth_filter", checkasm_check_synth_filter },
94  #endif
95  #if CONFIG_EXR_DECODER
96  { "exrdsp", checkasm_check_exrdsp },
97  #endif
98  #if CONFIG_FLACDSP
99  { "flacdsp", checkasm_check_flacdsp },
100  #endif
101  #if CONFIG_FMTCONVERT
102  { "fmtconvert", checkasm_check_fmtconvert },
103  #endif
104  #if CONFIG_G722DSP
105  { "g722dsp", checkasm_check_g722dsp },
106  #endif
107  #if CONFIG_H264DSP
108  { "h264dsp", checkasm_check_h264dsp },
109  #endif
110  #if CONFIG_H264PRED
111  { "h264pred", checkasm_check_h264pred },
112  #endif
113  #if CONFIG_H264QPEL
114  { "h264qpel", checkasm_check_h264qpel },
115  #endif
116  #if CONFIG_HEVC_DECODER
117  { "hevc_add_res", checkasm_check_hevc_add_res },
118  { "hevc_idct", checkasm_check_hevc_idct },
119  { "hevc_sao", checkasm_check_hevc_sao },
120  #endif
121  #if CONFIG_HUFFYUV_DECODER
122  { "huffyuvdsp", checkasm_check_huffyuvdsp },
123  #endif
124  #if CONFIG_JPEG2000_DECODER
125  { "jpeg2000dsp", checkasm_check_jpeg2000dsp },
126  #endif
127  #if CONFIG_HUFFYUVDSP
128  { "llviddsp", checkasm_check_llviddsp },
129  #endif
130  #if CONFIG_LLVIDENCDSP
131  { "llviddspenc", checkasm_check_llviddspenc },
132  #endif
133  #if CONFIG_OPUS_DECODER
134  { "opusdsp", checkasm_check_opusdsp },
135  #endif
136  #if CONFIG_PIXBLOCKDSP
137  { "pixblockdsp", checkasm_check_pixblockdsp },
138  #endif
139  #if CONFIG_UTVIDEO_DECODER
140  { "utvideodsp", checkasm_check_utvideodsp },
141  #endif
142  #if CONFIG_V210_DECODER
143  { "v210dec", checkasm_check_v210dec },
144  #endif
145  #if CONFIG_V210_ENCODER
146  { "v210enc", checkasm_check_v210enc },
147  #endif
148  #if CONFIG_VP8DSP
149  { "vp8dsp", checkasm_check_vp8dsp },
150  #endif
151  #if CONFIG_VP9_DECODER
152  { "vp9dsp", checkasm_check_vp9dsp },
153  #endif
154  #if CONFIG_VIDEODSP
155  { "videodsp", checkasm_check_videodsp },
156  #endif
157 #endif
158 #if CONFIG_AVFILTER
159  #if CONFIG_AFIR_FILTER
160  { "af_afir", checkasm_check_afir },
161  #endif
162  #if CONFIG_BLEND_FILTER
163  { "vf_blend", checkasm_check_blend },
164  #endif
165  #if CONFIG_COLORSPACE_FILTER
166  { "vf_colorspace", checkasm_check_colorspace },
167  #endif
168  #if CONFIG_EQ_FILTER
169  { "vf_eq", checkasm_check_vf_eq },
170  #endif
171  #if CONFIG_GBLUR_FILTER
172  { "vf_gblur", checkasm_check_vf_gblur },
173  #endif
174  #if CONFIG_HFLIP_FILTER
175  { "vf_hflip", checkasm_check_vf_hflip },
176  #endif
177  #if CONFIG_NLMEANS_FILTER
178  { "vf_nlmeans", checkasm_check_nlmeans },
179  #endif
180  #if CONFIG_THRESHOLD_FILTER
181  { "vf_threshold", checkasm_check_vf_threshold },
182  #endif
183 #endif
184 #if CONFIG_SWSCALE
185  { "sw_rgb", checkasm_check_sw_rgb },
186  { "sw_scale", checkasm_check_sw_scale },
187 #endif
188 #if CONFIG_AVUTIL
189  { "fixed_dsp", checkasm_check_fixed_dsp },
190  { "float_dsp", checkasm_check_float_dsp },
191 #endif
192  { NULL }
193 };
194 
195 /* List of cpu flags to check */
196 static const struct {
197  const char *name;
198  const char *suffix;
199  int flag;
200 } cpus[] = {
201 #if ARCH_AARCH64
202  { "ARMV8", "armv8", AV_CPU_FLAG_ARMV8 },
203  { "NEON", "neon", AV_CPU_FLAG_NEON },
204 #elif ARCH_ARM
205  { "ARMV5TE", "armv5te", AV_CPU_FLAG_ARMV5TE },
206  { "ARMV6", "armv6", AV_CPU_FLAG_ARMV6 },
207  { "ARMV6T2", "armv6t2", AV_CPU_FLAG_ARMV6T2 },
208  { "VFP", "vfp", AV_CPU_FLAG_VFP },
209  { "VFP_VM", "vfp_vm", AV_CPU_FLAG_VFP_VM },
210  { "VFPV3", "vfp3", AV_CPU_FLAG_VFPV3 },
211  { "NEON", "neon", AV_CPU_FLAG_NEON },
212 #elif ARCH_PPC
213  { "ALTIVEC", "altivec", AV_CPU_FLAG_ALTIVEC },
214  { "VSX", "vsx", AV_CPU_FLAG_VSX },
215  { "POWER8", "power8", AV_CPU_FLAG_POWER8 },
216 #elif ARCH_X86
217  { "MMX", "mmx", AV_CPU_FLAG_MMX|AV_CPU_FLAG_CMOV },
218  { "MMXEXT", "mmxext", AV_CPU_FLAG_MMXEXT },
219  { "3DNOW", "3dnow", AV_CPU_FLAG_3DNOW },
220  { "3DNOWEXT", "3dnowext", AV_CPU_FLAG_3DNOWEXT },
221  { "SSE", "sse", AV_CPU_FLAG_SSE },
222  { "SSE2", "sse2", AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW },
223  { "SSE3", "sse3", AV_CPU_FLAG_SSE3|AV_CPU_FLAG_SSE3SLOW },
224  { "SSSE3", "ssse3", AV_CPU_FLAG_SSSE3|AV_CPU_FLAG_ATOM },
225  { "SSE4.1", "sse4", AV_CPU_FLAG_SSE4 },
226  { "SSE4.2", "sse42", AV_CPU_FLAG_SSE42 },
227  { "AES-NI", "aesni", AV_CPU_FLAG_AESNI },
228  { "AVX", "avx", AV_CPU_FLAG_AVX },
229  { "XOP", "xop", AV_CPU_FLAG_XOP },
230  { "FMA3", "fma3", AV_CPU_FLAG_FMA3 },
231  { "FMA4", "fma4", AV_CPU_FLAG_FMA4 },
232  { "AVX2", "avx2", AV_CPU_FLAG_AVX2 },
233  { "AVX-512", "avx512", AV_CPU_FLAG_AVX512 },
234 #endif
235  { NULL }
236 };
237 
238 typedef struct CheckasmFuncVersion {
240  void *func;
241  int ok;
242  int cpu;
245 
246 /* Binary search tree node */
247 typedef struct CheckasmFunc {
248  struct CheckasmFunc *child[2];
250  uint8_t color; /* 0 = red, 1 = black */
251  char name[1];
252 } CheckasmFunc;
253 
254 /* Internal state */
255 static struct {
259  const char *current_test_name;
260  const char *bench_pattern;
264 
265  /* perf */
266  int nop_time;
267  int sysfd;
268 
269  int cpu_flag;
270  const char *cpu_flag_name;
271  const char *test_name;
272  int verbose;
273 } state;
274 
275 /* PRNG state */
277 
278 /* float compare support code */
279 static int is_negative(union av_intfloat32 u)
280 {
281  return u.i >> 31;
282 }
283 
284 int float_near_ulp(float a, float b, unsigned max_ulp)
285 {
286  union av_intfloat32 x, y;
287 
288  x.f = a;
289  y.f = b;
290 
291  if (is_negative(x) != is_negative(y)) {
292  // handle -0.0 == +0.0
293  return a == b;
294  }
295 
296  if (llabs((int64_t)x.i - y.i) <= max_ulp)
297  return 1;
298 
299  return 0;
300 }
301 
302 int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp,
303  unsigned len)
304 {
305  unsigned i;
306 
307  for (i = 0; i < len; i++) {
308  if (!float_near_ulp(a[i], b[i], max_ulp))
309  return 0;
310  }
311  return 1;
312 }
313 
314 int float_near_abs_eps(float a, float b, float eps)
315 {
316  float abs_diff = fabsf(a - b);
317  if (abs_diff < eps)
318  return 1;
319 
320  fprintf(stderr, "test failed comparing %g with %g (abs diff=%g with EPS=%g)\n", a, b, abs_diff, eps);
321 
322  return 0;
323 }
324 
325 int float_near_abs_eps_array(const float *a, const float *b, float eps,
326  unsigned len)
327 {
328  unsigned i;
329 
330  for (i = 0; i < len; i++) {
331  if (!float_near_abs_eps(a[i], b[i], eps))
332  return 0;
333  }
334  return 1;
335 }
336 
337 int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp)
338 {
339  return float_near_ulp(a, b, max_ulp) || float_near_abs_eps(a, b, eps);
340 }
341 
342 int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps,
343  unsigned max_ulp, unsigned len)
344 {
345  unsigned i;
346 
347  for (i = 0; i < len; i++) {
348  if (!float_near_abs_eps_ulp(a[i], b[i], eps, max_ulp))
349  return 0;
350  }
351  return 1;
352 }
353 
354 int double_near_abs_eps(double a, double b, double eps)
355 {
356  double abs_diff = fabs(a - b);
357 
358  return abs_diff < eps;
359 }
360 
361 int double_near_abs_eps_array(const double *a, const double *b, double eps,
362  unsigned len)
363 {
364  unsigned i;
365 
366  for (i = 0; i < len; i++) {
367  if (!double_near_abs_eps(a[i], b[i], eps))
368  return 0;
369  }
370  return 1;
371 }
372 
373 /* Print colored text to stderr if the terminal supports it */
374 static void color_printf(int color, const char *fmt, ...)
375 {
376  static int use_color = -1;
377  va_list arg;
378 
379 #if HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
380  static HANDLE con;
381  static WORD org_attributes;
382 
383  if (use_color < 0) {
384  CONSOLE_SCREEN_BUFFER_INFO con_info;
385  con = GetStdHandle(STD_ERROR_HANDLE);
386  if (con && con != INVALID_HANDLE_VALUE && GetConsoleScreenBufferInfo(con, &con_info)) {
387  org_attributes = con_info.wAttributes;
388  use_color = 1;
389  } else
390  use_color = 0;
391  }
392  if (use_color)
393  SetConsoleTextAttribute(con, (org_attributes & 0xfff0) | (color & 0x0f));
394 #else
395  if (use_color < 0) {
396  const char *term = getenv("TERM");
397  use_color = term && strcmp(term, "dumb") && isatty(2);
398  }
399  if (use_color)
400  fprintf(stderr, "\x1b[%d;3%dm", (color & 0x08) >> 3, color & 0x07);
401 #endif
402 
403  va_start(arg, fmt);
404  vfprintf(stderr, fmt, arg);
405  va_end(arg);
406 
407  if (use_color) {
408 #if HAVE_SETCONSOLETEXTATTRIBUTE && HAVE_GETSTDHANDLE
409  SetConsoleTextAttribute(con, org_attributes);
410 #else
411  fprintf(stderr, "\x1b[0m");
412 #endif
413  }
414 }
415 
416 /* Deallocate a tree */
418 {
419  if (f) {
420  CheckasmFuncVersion *v = f->versions.next;
421  while (v) {
422  CheckasmFuncVersion *next = v->next;
423  free(v);
424  v = next;
425  }
426 
427  destroy_func_tree(f->child[0]);
428  destroy_func_tree(f->child[1]);
429  free(f);
430  }
431 }
432 
433 /* Allocate a zero-initialized block, clean up and exit on failure */
434 static void *checkasm_malloc(size_t size)
435 {
436  void *ptr = calloc(1, size);
437  if (!ptr) {
438  fprintf(stderr, "checkasm: malloc failed\n");
439  destroy_func_tree(state.funcs);
440  exit(1);
441  }
442  return ptr;
443 }
444 
445 /* Get the suffix of the specified cpu flag */
446 static const char *cpu_suffix(int cpu)
447 {
448  int i = FF_ARRAY_ELEMS(cpus);
449 
450  while (--i >= 0)
451  if (cpu & cpus[i].flag)
452  return cpus[i].suffix;
453 
454  return "c";
455 }
456 
457 static int cmp_nop(const void *a, const void *b)
458 {
459  return *(const uint16_t*)a - *(const uint16_t*)b;
460 }
461 
462 /* Measure the overhead of the timing code (in decicycles) */
463 static int measure_nop_time(void)
464 {
465  uint16_t nops[10000];
466  int i, nop_sum = 0;
467  av_unused const int sysfd = state.sysfd;
468 
469  uint64_t t = 0;
470  for (i = 0; i < 10000; i++) {
471  PERF_START(t);
472  PERF_STOP(t);
473  nops[i] = t;
474  }
475 
476  qsort(nops, 10000, sizeof(uint16_t), cmp_nop);
477  for (i = 2500; i < 7500; i++)
478  nop_sum += nops[i];
479 
480  return nop_sum / 500;
481 }
482 
483 /* Print benchmark results */
485 {
486  if (f) {
487  print_benchs(f->child[0]);
488 
489  /* Only print functions with at least one assembly version */
490  if (f->versions.cpu || f->versions.next) {
491  CheckasmFuncVersion *v = &f->versions;
492  do {
493  CheckasmPerf *p = &v->perf;
494  if (p->iterations) {
495  int decicycles = (10*p->cycles/p->iterations - state.nop_time) / 4;
496  printf("%s_%s: %d.%d\n", f->name, cpu_suffix(v->cpu), decicycles/10, decicycles%10);
497  }
498  } while ((v = v->next));
499  }
500 
501  print_benchs(f->child[1]);
502  }
503 }
504 
505 /* ASCIIbetical sort except preserving natural order for numbers */
506 static int cmp_func_names(const char *a, const char *b)
507 {
508  const char *start = a;
509  int ascii_diff, digit_diff;
510 
511  for (; !(ascii_diff = *(const unsigned char*)a - *(const unsigned char*)b) && *a; a++, b++);
512  for (; av_isdigit(*a) && av_isdigit(*b); a++, b++);
513 
514  if (a > start && av_isdigit(a[-1]) && (digit_diff = av_isdigit(*a) - av_isdigit(*b)))
515  return digit_diff;
516 
517  return ascii_diff;
518 }
519 
520 /* Perform a tree rotation in the specified direction and return the new root */
522 {
523  CheckasmFunc *r = f->child[dir^1];
524  f->child[dir^1] = r->child[dir];
525  r->child[dir] = f;
526  r->color = f->color;
527  f->color = 0;
528  return r;
529 }
530 
531 #define is_red(f) ((f) && !(f)->color)
532 
533 /* Balance a left-leaning red-black tree at the specified node */
534 static void balance_tree(CheckasmFunc **root)
535 {
536  CheckasmFunc *f = *root;
537 
538  if (is_red(f->child[0]) && is_red(f->child[1])) {
539  f->color ^= 1;
540  f->child[0]->color = f->child[1]->color = 1;
541  }
542 
543  if (!is_red(f->child[0]) && is_red(f->child[1]))
544  *root = rotate_tree(f, 0); /* Rotate left */
545  else if (is_red(f->child[0]) && is_red(f->child[0]->child[0]))
546  *root = rotate_tree(f, 1); /* Rotate right */
547 }
548 
549 /* Get a node with the specified name, creating it if it doesn't exist */
550 static CheckasmFunc *get_func(CheckasmFunc **root, const char *name)
551 {
552  CheckasmFunc *f = *root;
553 
554  if (f) {
555  /* Search the tree for a matching node */
556  int cmp = cmp_func_names(name, f->name);
557  if (cmp) {
558  f = get_func(&f->child[cmp > 0], name);
559 
560  /* Rebalance the tree on the way up if a new node was inserted */
561  if (!f->versions.func)
562  balance_tree(root);
563  }
564  } else {
565  /* Allocate and insert a new node into the tree */
566  int name_length = strlen(name);
567  f = *root = checkasm_malloc(sizeof(CheckasmFunc) + name_length);
568  memcpy(f->name, name, name_length + 1);
569  }
570 
571  return f;
572 }
573 
574 /* Perform tests and benchmarks for the specified cpu flag if supported by the host */
575 static void check_cpu_flag(const char *name, int flag)
576 {
577  int old_cpu_flag = state.cpu_flag;
578 
579  flag |= old_cpu_flag;
580  av_force_cpu_flags(-1);
581  state.cpu_flag = flag & av_get_cpu_flags();
582  av_force_cpu_flags(state.cpu_flag);
583 
584  if (!flag || state.cpu_flag != old_cpu_flag) {
585  int i;
586 
587  state.cpu_flag_name = name;
588  for (i = 0; tests[i].func; i++) {
589  if (state.test_name && strcmp(tests[i].name, state.test_name))
590  continue;
591  state.current_test_name = tests[i].name;
592  tests[i].func();
593  }
594  }
595 }
596 
597 /* Print the name of the current CPU flag, but only do it once */
598 static void print_cpu_name(void)
599 {
600  if (state.cpu_flag_name) {
601  color_printf(COLOR_YELLOW, "%s:\n", state.cpu_flag_name);
602  state.cpu_flag_name = NULL;
603  }
604 }
605 
606 #if CONFIG_LINUX_PERF
607 static int bench_init_linux(void)
608 {
609  struct perf_event_attr attr = {
610  .type = PERF_TYPE_HARDWARE,
611  .size = sizeof(struct perf_event_attr),
612  .config = PERF_COUNT_HW_CPU_CYCLES,
613  .disabled = 1, // start counting only on demand
614  .exclude_kernel = 1,
615  .exclude_hv = 1,
616  };
617 
618  printf("benchmarking with Linux Perf Monitoring API\n");
619 
620  state.sysfd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
621  if (state.sysfd == -1) {
622  perror("syscall");
623  return -1;
624  }
625  return 0;
626 }
627 #endif
628 
629 #if !CONFIG_LINUX_PERF
630 static int bench_init_ffmpeg(void)
631 {
632 #ifdef AV_READ_TIME
633  printf("benchmarking with native FFmpeg timers\n");
634  return 0;
635 #else
636  fprintf(stderr, "checkasm: --bench is not supported on your system\n");
637  return -1;
638 #endif
639 }
640 #endif
641 
642 static int bench_init(void)
643 {
644 #if CONFIG_LINUX_PERF
645  int ret = bench_init_linux();
646 #else
647  int ret = bench_init_ffmpeg();
648 #endif
649  if (ret < 0)
650  return ret;
651 
652  state.nop_time = measure_nop_time();
653  printf("nop: %d.%d\n", state.nop_time/10, state.nop_time%10);
654  return 0;
655 }
656 
657 static void bench_uninit(void)
658 {
659 #if CONFIG_LINUX_PERF
660  if (state.sysfd > 0)
661  close(state.sysfd);
662 #endif
663 }
664 
665 int main(int argc, char *argv[])
666 {
667  unsigned int seed = av_get_random_seed();
668  int i, ret = 0;
669 
670 #if ARCH_ARM && HAVE_ARMV5TE_EXTERNAL
672  checkasm_checked_call = checkasm_checked_call_vfp;
673 #endif
674 
675  if (!tests[0].func || !cpus[0].flag) {
676  fprintf(stderr, "checkasm: no tests to perform\n");
677  return 0;
678  }
679 
680  while (argc > 1) {
681  if (!strncmp(argv[1], "--bench", 7)) {
682  if (bench_init() < 0)
683  return 1;
684  if (argv[1][7] == '=') {
685  state.bench_pattern = argv[1] + 8;
686  state.bench_pattern_len = strlen(state.bench_pattern);
687  } else
688  state.bench_pattern = "";
689  } else if (!strncmp(argv[1], "--test=", 7)) {
690  state.test_name = argv[1] + 7;
691  } else if (!strcmp(argv[1], "--verbose") || !strcmp(argv[1], "-v")) {
692  state.verbose = 1;
693  } else {
694  seed = strtoul(argv[1], NULL, 10);
695  }
696 
697  argc--;
698  argv++;
699  }
700 
701  fprintf(stderr, "checkasm: using random seed %u\n", seed);
703 
704  check_cpu_flag(NULL, 0);
705  for (i = 0; cpus[i].flag; i++)
707 
708  if (state.num_failed) {
709  fprintf(stderr, "checkasm: %d of %d tests have failed\n", state.num_failed, state.num_checked);
710  ret = 1;
711  } else {
712  fprintf(stderr, "checkasm: all %d tests passed\n", state.num_checked);
713  if (state.bench_pattern) {
714  print_benchs(state.funcs);
715  }
716  }
717 
718  destroy_func_tree(state.funcs);
719  bench_uninit();
720  return ret;
721 }
722 
723 /* Decide whether or not the specified function needs to be tested and
724  * allocate/initialize data structures if needed. Returns a pointer to a
725  * reference function if the function should be tested, otherwise NULL */
726 void *checkasm_check_func(void *func, const char *name, ...)
727 {
728  char name_buf[256];
729  void *ref = func;
731  int name_length;
732  va_list arg;
733 
734  va_start(arg, name);
735  name_length = vsnprintf(name_buf, sizeof(name_buf), name, arg);
736  va_end(arg);
737 
738  if (!func || name_length <= 0 || name_length >= sizeof(name_buf))
739  return NULL;
740 
741  state.current_func = get_func(&state.funcs, name_buf);
742  state.funcs->color = 1;
743  v = &state.current_func->versions;
744 
745  if (v->func) {
746  CheckasmFuncVersion *prev;
747  do {
748  /* Only test functions that haven't already been tested */
749  if (v->func == func)
750  return NULL;
751 
752  if (v->ok)
753  ref = v->func;
754 
755  prev = v;
756  } while ((v = v->next));
757 
758  v = prev->next = checkasm_malloc(sizeof(CheckasmFuncVersion));
759  }
760 
761  v->func = func;
762  v->ok = 1;
763  v->cpu = state.cpu_flag;
764  state.current_func_ver = v;
765 
766  if (state.cpu_flag)
767  state.num_checked++;
768 
769  return ref;
770 }
771 
772 /* Decide whether or not the current function needs to be benchmarked */
774 {
775  return !state.num_failed && state.bench_pattern &&
776  !strncmp(state.current_func->name, state.bench_pattern, state.bench_pattern_len);
777 }
778 
779 /* Indicate that the current test has failed */
780 void checkasm_fail_func(const char *msg, ...)
781 {
782  if (state.current_func_ver->cpu && state.current_func_ver->ok) {
783  va_list arg;
784 
785  print_cpu_name();
786  fprintf(stderr, " %s_%s (", state.current_func->name, cpu_suffix(state.current_func_ver->cpu));
787  va_start(arg, msg);
788  vfprintf(stderr, msg, arg);
789  va_end(arg);
790  fprintf(stderr, ")\n");
791 
792  state.current_func_ver->ok = 0;
793  state.num_failed++;
794  }
795 }
796 
797 /* Get the benchmark context of the current function */
799 {
800  CheckasmPerf *perf = &state.current_func_ver->perf;
801  memset(perf, 0, sizeof(*perf));
802  perf->sysfd = state.sysfd;
803  return perf;
804 }
805 
806 /* Print the outcome of all tests performed since the last time this function was called */
807 void checkasm_report(const char *name, ...)
808 {
809  static int prev_checked, prev_failed, max_length;
810 
811  if (state.num_checked > prev_checked) {
812  int pad_length = max_length + 4;
813  va_list arg;
814 
815  print_cpu_name();
816  pad_length -= fprintf(stderr, " - %s.", state.current_test_name);
817  va_start(arg, name);
818  pad_length -= vfprintf(stderr, name, arg);
819  va_end(arg);
820  fprintf(stderr, "%*c", FFMAX(pad_length, 0) + 2, '[');
821 
822  if (state.num_failed == prev_failed)
823  color_printf(COLOR_GREEN, "OK");
824  else
825  color_printf(COLOR_RED, "FAILED");
826  fprintf(stderr, "]\n");
827 
828  prev_checked = state.num_checked;
829  prev_failed = state.num_failed;
830  } else if (!state.cpu_flag) {
831  /* Calculate the amount of padding required to make the output vertically aligned */
832  int length = strlen(state.current_test_name);
833  va_list arg;
834 
835  va_start(arg, name);
836  length += vsnprintf(NULL, 0, name, arg);
837  va_end(arg);
838 
839  if (length > max_length)
840  max_length = length;
841  }
842 }
843 
844 #define DEF_CHECKASM_CHECK_FUNC(type, fmt) \
845 int checkasm_check_##type(const char *const file, const int line, \
846  const type *buf1, ptrdiff_t stride1, \
847  const type *buf2, ptrdiff_t stride2, \
848  const int w, int h, const char *const name) \
849 { \
850  int y = 0; \
851  stride1 /= sizeof(*buf1); \
852  stride2 /= sizeof(*buf2); \
853  for (y = 0; y < h; y++) \
854  if (memcmp(&buf1[y*stride1], &buf2[y*stride2], w*sizeof(*buf1))) \
855  break; \
856  if (y == h) \
857  return 0; \
858  checkasm_fail_func("%s:%d", file, line); \
859  if (!state.verbose) \
860  return 1; \
861  fprintf(stderr, "%s:\n", name); \
862  while (h--) { \
863  for (int x = 0; x < w; x++) \
864  fprintf(stderr, " " fmt, buf1[x]); \
865  fprintf(stderr, " "); \
866  for (int x = 0; x < w; x++) \
867  fprintf(stderr, " " fmt, buf2[x]); \
868  fprintf(stderr, " "); \
869  for (int x = 0; x < w; x++) \
870  fprintf(stderr, "%c", buf1[x] != buf2[x] ? 'x' : '.'); \
871  buf1 += stride1; \
872  buf2 += stride2; \
873  fprintf(stderr, "\n"); \
874  } \
875  return 1; \
876 }
877 
879 DEF_CHECKASM_CHECK_FUNC(uint16_t, "%04x")
880 DEF_CHECKASM_CHECK_FUNC(int16_t, "%6d")
checkasm_check_nlmeans
void checkasm_check_nlmeans(void)
Definition: vf_nlmeans.c:31
AV_CPU_FLAG_VFP
#define AV_CPU_FLAG_VFP
Definition: cpu.h:67
bench_pattern_len
int bench_pattern_len
Definition: checkasm.c:261
av_force_cpu_flags
void av_force_cpu_flags(int arg)
Disables cpu detection and forces the specified flags.
Definition: cpu.c:65
checkasm_check_vp8dsp
void checkasm_check_vp8dsp(void)
Definition: vp8dsp.c:507
checkasm_check_blockdsp
void checkasm_check_blockdsp(void)
Definition: blockdsp.c:54
AV_CPU_FLAG_SSE3
#define AV_CPU_FLAG_SSE3
Prescott SSE3 functions.
Definition: cpu.h:40
destroy_func_tree
static void destroy_func_tree(CheckasmFunc *f)
Definition: checkasm.c:417
checkasm_check_videodsp
void checkasm_check_videodsp(void)
Definition: videodsp.c:80
cmp_nop
static int cmp_nop(const void *a, const void *b)
Definition: checkasm.c:457
checkasm_check_vf_eq
void checkasm_check_vf_eq(void)
Definition: vf_eq.c:75
COLOR_RED
#define COLOR_RED
Definition: checkasm.c:51
checkasm_lfg
AVLFG checkasm_lfg
Definition: checkasm.c:276
color
Definition: vf_paletteuse.c:588
av_lfg_init
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:32
u
#define u(width, name, range_min, range_max)
Definition: cbs_h2645.c:262
checkasm_check_alacdsp
void checkasm_check_alacdsp(void)
Definition: alacdsp.c:115
checkasm_check_v210dec
void checkasm_check_v210dec(void)
Definition: v210dec.c:47
float_near_abs_eps_array
int float_near_abs_eps_array(const float *a, const float *b, float eps, unsigned len)
Definition: checkasm.c:325
AV_CPU_FLAG_SSE3SLOW
#define AV_CPU_FLAG_SSE3SLOW
SSE3 supported, but usually not faster.
Definition: cpu.h:41
CheckasmFunc
Definition: checkasm.c:247
name
const char * name
Definition: checkasm.c:72
bench_pattern
const char * bench_pattern
Definition: checkasm.c:260
av_unused
#define av_unused
Definition: attributes.h:131
checkasm_check_hevc_idct
void checkasm_check_hevc_idct(void)
Definition: hevc_idct.c:86
checkasm_check_sw_scale
void checkasm_check_sw_scale(void)
Definition: sw_scale.c:130
CheckasmFunc::child
struct CheckasmFunc * child[2]
Definition: checkasm.c:248
checkasm_check_afir
void checkasm_check_afir(void)
Definition: af_afir.c:79
print_cpu_name
static void print_cpu_name(void)
Definition: checkasm.c:598
tests
static const struct @312 tests[]
AV_CPU_FLAG_3DNOW
#define AV_CPU_FLAG_3DNOW
AMD 3DNOW.
Definition: cpu.h:34
av_intfloat32::i
uint32_t i
Definition: intfloat.h:28
float_near_abs_eps
int float_near_abs_eps(float a, float b, float eps)
Definition: checkasm.c:314
b
#define b
Definition: input.c:41
checkasm_check_aacpsdsp
void checkasm_check_aacpsdsp(void)
Definition: aacpsdsp.c:233
bench_uninit
static void bench_uninit(void)
Definition: checkasm.c:657
CheckasmFuncVersion::cpu
int cpu
Definition: checkasm.c:242
cpu_flag
int cpu_flag
Definition: checkasm.c:269
av_get_cpu_flags
int av_get_cpu_flags(void)
Return the flags which specify extensions supported by the CPU.
Definition: cpu.c:93
cpu_suffix
static const char * cpu_suffix(int cpu)
Definition: checkasm.c:446
CheckasmPerf::sysfd
int sysfd
Definition: checkasm.h:212
checkasm_check_llviddspenc
void checkasm_check_llviddspenc(void)
Definition: llviddspenc.c:104
intfloat.h
checkasm_check_h264dsp
void checkasm_check_h264dsp(void)
Definition: h264dsp.c:441
color_printf
static void color_printf(int color, const char *fmt,...)
Definition: checkasm.c:374
av_get_random_seed
uint32_t av_get_random_seed(void)
Get a seed to use in conjunction with random functions.
Definition: random_seed.c:120
main
int main(int argc, char *argv[])
Definition: checkasm.c:665
AV_CPU_FLAG_SSSE3
#define AV_CPU_FLAG_SSSE3
Conroe SSSE3 functions.
Definition: cpu.h:43
double_near_abs_eps
int double_near_abs_eps(double a, double b, double eps)
Definition: checkasm.c:354
CheckasmPerf
Definition: checkasm.h:211
current_test_name
const char * current_test_name
Definition: checkasm.c:259
PERF_START
#define PERF_START(t)
Definition: checkasm.h:262
rotate_tree
static CheckasmFunc * rotate_tree(CheckasmFunc *f, int dir)
Definition: checkasm.c:521
AV_CPU_FLAG_XOP
#define AV_CPU_FLAG_XOP
Bulldozer XOP functions.
Definition: cpu.h:51
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
checkasm_check_vp9dsp
void checkasm_check_vp9dsp(void)
Definition: vp9dsp.c:625
checkasm.h
checkasm_check_vf_threshold
void checkasm_check_vf_threshold(void)
Definition: vf_threshold.c:78
checkasm_check_vf_gblur
void checkasm_check_vf_gblur(void)
Definition: vf_gblur.c:36
AV_CPU_FLAG_3DNOWEXT
#define AV_CPU_FLAG_3DNOWEXT
AMD 3DNowExt.
Definition: cpu.h:39
float_near_abs_eps_ulp
int float_near_abs_eps_ulp(float a, float b, float eps, unsigned max_ulp)
Definition: checkasm.c:337
AV_CPU_FLAG_VSX
#define AV_CPU_FLAG_VSX
ISA 2.06.
Definition: cpu.h:61
num_failed
int num_failed
Definition: checkasm.c:263
checkasm_check_float_dsp
void checkasm_check_float_dsp(void)
Definition: float_dsp.c:280
AV_CPU_FLAG_AVX512
#define AV_CPU_FLAG_AVX512
AVX-512 functions: requires OS support even if YMM/ZMM registers aren't used.
Definition: cpu.h:58
bench_init
static int bench_init(void)
Definition: checkasm.c:642
checkasm_check_pixblockdsp
void checkasm_check_pixblockdsp(void)
Definition: pixblockdsp.c:81
CheckasmFuncVersion
Definition: checkasm.c:238
COLOR_YELLOW
#define COLOR_YELLOW
Definition: checkasm.c:53
nop_time
int nop_time
Definition: checkasm.c:266
CheckasmFuncVersion::perf
CheckasmPerf perf
Definition: checkasm.c:243
checkasm_report
void checkasm_report(const char *name,...)
Definition: checkasm.c:807
get_func
static CheckasmFunc * get_func(CheckasmFunc **root, const char *name)
Definition: checkasm.c:550
checkasm_fail_func
void checkasm_fail_func(const char *msg,...)
Definition: checkasm.c:780
checkasm_check_sw_rgb
void checkasm_check_sw_rgb(void)
Definition: sw_rgb.c:182
checkasm_check_hevc_sao
void checkasm_check_hevc_sao(void)
Definition: hevc_sao.c:131
num_checked
int num_checked
Definition: checkasm.c:262
AV_CPU_FLAG_ARMV6
#define AV_CPU_FLAG_ARMV6
Definition: cpu.h:65
AV_CPU_FLAG_SSE4
#define AV_CPU_FLAG_SSE4
Penryn SSE4.1 functions.
Definition: cpu.h:46
cmp
static av_always_inline int cmp(MpegEncContext *s, const int x, const int y, const int subx, const int suby, const int size, const int h, int ref_index, int src_index, me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, const int flags)
compares a block (either a full macroblock or a partition thereof) against a proposed motion-compensa...
Definition: motion_est.c:260
f
#define f(width, name)
Definition: cbs_vp9.c:255
CheckasmPerf::iterations
int iterations
Definition: checkasm.h:214
CheckasmFuncVersion::ok
int ok
Definition: checkasm.c:241
int32_t
int32_t
Definition: audio_convert.c:194
arg
const char * arg
Definition: jacosubdec.c:66
func
void(* func)(void)
Definition: checkasm.c:73
NULL
#define NULL
Definition: coverity.c:32
measure_nop_time
static int measure_nop_time(void)
Definition: checkasm.c:463
double_near_abs_eps_array
int double_near_abs_eps_array(const double *a, const double *b, double eps, unsigned len)
Definition: checkasm.c:361
checkasm_check_fmtconvert
void checkasm_check_fmtconvert(void)
Definition: fmtconvert.c:44
COLOR_GREEN
#define COLOR_GREEN
Definition: checkasm.c:52
cpu.h
av_intfloat32
Definition: intfloat.h:27
AV_CPU_FLAG_CMOV
#define AV_CPU_FLAG_CMOV
supports cmov instruction
Definition: cpu.h:53
seed
static unsigned int seed
Definition: videogen.c:78
AV_CPU_FLAG_ALTIVEC
#define AV_CPU_FLAG_ALTIVEC
standard
Definition: cpu.h:60
print_benchs
static void print_benchs(CheckasmFunc *f)
Definition: checkasm.c:484
current_func
CheckasmFunc * current_func
Definition: checkasm.c:257
AV_CPU_FLAG_SSE2
#define AV_CPU_FLAG_SSE2
PIV SSE2 functions.
Definition: cpu.h:36
CheckasmFunc::color
uint8_t color
Definition: checkasm.c:250
AVLFG
Context structure for the Lagged Fibonacci PRNG.
Definition: lfg.h:33
AV_CPU_FLAG_AVX
#define AV_CPU_FLAG_AVX
AVX functions: requires OS support even if YMM registers aren't used.
Definition: cpu.h:49
AV_CPU_FLAG_FMA4
#define AV_CPU_FLAG_FMA4
Bulldozer FMA4 functions.
Definition: cpu.h:52
cpu.h
AV_CPU_FLAG_AVX2
#define AV_CPU_FLAG_AVX2
AVX2 functions: requires OS support even if YMM registers aren't used.
Definition: cpu.h:54
checkasm_check_llviddsp
void checkasm_check_llviddsp(void)
Definition: llviddsp.c:195
FFMAX
#define FFMAX(a, b)
Definition: common.h:94
AV_CPU_FLAG_SSE2SLOW
#define AV_CPU_FLAG_SSE2SLOW
SSE2 supported, but usually not faster.
Definition: cpu.h:37
AV_CPU_FLAG_NEON
#define AV_CPU_FLAG_NEON
Definition: cpu.h:69
size
int size
Definition: twinvq_data.h:11134
state
static struct @314 state
DEF_CHECKASM_CHECK_FUNC
#define DEF_CHECKASM_CHECK_FUNC(type, fmt)
Definition: checkasm.c:844
printf
printf("static const uint8_t my_array[100] = {\n")
sysfd
int sysfd
Definition: checkasm.c:267
have_neon
#define have_neon(flags)
Definition: cpu.h:26
CheckasmFuncVersion::func
void * func
Definition: checkasm.c:240
checkasm_check_h264pred
void checkasm_check_h264pred(void)
Definition: h264pred.c:232
av_isdigit
static av_const int av_isdigit(int c)
Locale-independent conversion of ASCII isdigit.
Definition: avstring.h:206
AV_CPU_FLAG_FMA3
#define AV_CPU_FLAG_FMA3
Haswell FMA3 functions.
Definition: cpu.h:55
a
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:41
checkasm_check_huffyuvdsp
void checkasm_check_huffyuvdsp(void)
Definition: huffyuvdsp.c:67
float_near_abs_eps_array_ulp
int float_near_abs_eps_array_ulp(const float *a, const float *b, float eps, unsigned max_ulp, unsigned len)
Definition: checkasm.c:342
test_name
const char * test_name
Definition: checkasm.c:271
CheckasmPerf::cycles
uint64_t cycles
Definition: checkasm.h:213
checkasm_get_perf_context
CheckasmPerf * checkasm_get_perf_context(void)
Definition: checkasm.c:798
checkasm_check_fixed_dsp
void checkasm_check_fixed_dsp(void)
Definition: fixed_dsp.c:132
checkasm_check_colorspace
void checkasm_check_colorspace(void)
Definition: vf_colorspace.c:308
r
#define r
Definition: input.c:40
checkasm_check_utvideodsp
void checkasm_check_utvideodsp(void)
Definition: utvideodsp.c:90
is_negative
static int is_negative(union av_intfloat32 u)
Definition: checkasm.c:279
checkasm_check_audiodsp
void checkasm_check_audiodsp(void)
Definition: audiodsp.c:51
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
checkasm_check_flacdsp
void checkasm_check_flacdsp(void)
Definition: flacdsp.c:56
checkasm_check_func
void * checkasm_check_func(void *func, const char *name,...)
Definition: checkasm.c:726
AV_CPU_FLAG_SSE42
#define AV_CPU_FLAG_SSE42
Nehalem SSE4.2 functions.
Definition: cpu.h:47
CheckasmFuncVersion::next
struct CheckasmFuncVersion * next
Definition: checkasm.c:239
vsnprintf
#define vsnprintf
Definition: snprintf.h:36
common.h
use_color
static int use_color
Definition: log.c:121
checkasm_check_synth_filter
void checkasm_check_synth_filter(void)
Definition: synth_filter.c:44
cmp_func_names
static int cmp_func_names(const char *a, const char *b)
Definition: checkasm.c:506
uint8_t
uint8_t
Definition: audio_convert.c:194
AV_CPU_FLAG_ARMV8
#define AV_CPU_FLAG_ARMV8
Definition: cpu.h:70
len
int len
Definition: vorbis_enc_data.h:452
checkasm_check_g722dsp
void checkasm_check_g722dsp(void)
Definition: g722dsp.c:53
PERF_STOP
#define PERF_STOP(t)
Definition: checkasm.h:263
is_red
#define is_red(f)
Definition: checkasm.c:531
AV_CPU_FLAG_ATOM
#define AV_CPU_FLAG_ATOM
Atom processor, some SSSE3 instructions are slower.
Definition: cpu.h:45
have_vfp
#define have_vfp(flags)
Definition: cpu.h:27
checkasm_check_vf_hflip
void checkasm_check_vf_hflip(void)
Definition: vf_hflip.c:69
ret
ret
Definition: filter_design.txt:187
checkasm_check_blend
void checkasm_check_blend(void)
Definition: vf_blend.c:88
verbose
int verbose
Definition: checkasm.c:272
AV_CPU_FLAG_VFPV3
#define AV_CPU_FLAG_VFPV3
Definition: cpu.h:68
checkasm_check_bswapdsp
void checkasm_check_bswapdsp(void)
Definition: bswapdsp.c:59
FF_ARRAY_ELEMS
#define FF_ARRAY_ELEMS(a)
Definition: sinewin_tablegen_template.c:38
AV_CPU_FLAG_ARMV5TE
#define AV_CPU_FLAG_ARMV5TE
Definition: cpu.h:64
AV_CPU_FLAG_MMX
#define AV_CPU_FLAG_MMX
standard MMX
Definition: cpu.h:31
suffix
const char * suffix
Definition: checkasm.c:198
checkasm_malloc
static void * checkasm_malloc(size_t size)
Definition: checkasm.c:434
void
typedef void(RENAME(mix_any_func_type))
Definition: rematrix_template.c:52
checkasm_check_h264qpel
void checkasm_check_h264qpel(void)
Definition: h264qpel.c:50
random_seed.h
AV_CPU_FLAG_AESNI
#define AV_CPU_FLAG_AESNI
Advanced Encryption Standard functions.
Definition: cpu.h:48
checkasm_bench_func
int checkasm_bench_func(void)
Definition: checkasm.c:773
config.h
dummy
int dummy
Definition: motion.c:64
AV_CPU_FLAG_POWER8
#define AV_CPU_FLAG_POWER8
ISA 2.07.
Definition: cpu.h:62
cpu_flag_name
const char * cpu_flag_name
Definition: checkasm.c:270
AV_CPU_FLAG_SSE
#define AV_CPU_FLAG_SSE
SSE functions.
Definition: cpu.h:35
ref
static int ref[MAX_W *MAX_W]
Definition: jpeg2000dwt.c:107
float_near_ulp_array
int float_near_ulp_array(const float *a, const float *b, unsigned max_ulp, unsigned len)
Definition: checkasm.c:302
AV_CPU_FLAG_MMXEXT
#define AV_CPU_FLAG_MMXEXT
SSE integer functions or AMD MMX ext.
Definition: cpu.h:32
av_intfloat32::f
float f
Definition: intfloat.h:29
flag
int flag
Definition: checkasm.c:199
checkasm_check_v210enc
void checkasm_check_v210enc(void)
Definition: v210enc.c:81
checkasm_check_sbrdsp
void checkasm_check_sbrdsp(void)
Definition: sbrdsp.c:252
AV_CPU_FLAG_VFP_VM
#define AV_CPU_FLAG_VFP_VM
VFPv2 vector mode, deprecated in ARMv7-A and unavailable in various CPUs implementations.
Definition: cpu.h:71
checkasm_check_jpeg2000dsp
void checkasm_check_jpeg2000dsp(void)
Definition: jpeg2000dsp.c:91
checkasm_check_hevc_add_res
void checkasm_check_hevc_add_res(void)
Definition: hevc_add_res.c:85
float_near_ulp
int float_near_ulp(float a, float b, unsigned max_ulp)
Definition: checkasm.c:284
current_func_ver
CheckasmFuncVersion * current_func_ver
Definition: checkasm.c:258
check_cpu_flag
static void check_cpu_flag(const char *name, int flag)
Definition: checkasm.c:575
bench_init_ffmpeg
static int bench_init_ffmpeg(void)
Definition: checkasm.c:630
CheckasmFunc::versions
CheckasmFuncVersion versions
Definition: checkasm.c:249
isatty
#define isatty(fd)
Definition: checkasm.c:61
CheckasmFunc::name
char name[1]
Definition: checkasm.c:251
checkasm_check_exrdsp
void checkasm_check_exrdsp(void)
Definition: exrdsp.c:76
balance_tree
static void balance_tree(CheckasmFunc **root)
Definition: checkasm.c:534
AV_CPU_FLAG_ARMV6T2
#define AV_CPU_FLAG_ARMV6T2
Definition: cpu.h:66
funcs
CheckasmFunc * funcs
Definition: checkasm.c:256
cpus
static const struct @313 cpus[]
checkasm_check_opusdsp
void checkasm_check_opusdsp(void)
Definition: opusdsp.c:83