• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2011 The LibYuv Project Authors. All rights reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS. All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "../unit_test/unit_test.h"
12 
13 #include <stdlib.h>  // For getenv()
14 
15 #include <cstring>
16 
17 #ifdef LIBYUV_USE_GFLAGS
18 #include "gflags/gflags.h"
19 #endif
20 #include "libyuv/cpu_id.h"
21 
22 unsigned int fastrand_seed = 0xfb;
23 
24 #ifdef LIBYUV_USE_GFLAGS
25 DEFINE_int32(libyuv_width, 0, "width of test image.");
26 DEFINE_int32(libyuv_height, 0, "height of test image.");
27 DEFINE_int32(libyuv_repeat, 0, "number of times to repeat test.");
28 DEFINE_int32(libyuv_flags, 0, "cpu flags for reference code. 1 = C, -1 = SIMD");
29 DEFINE_int32(libyuv_cpu_info,
30              0,
31              "cpu flags for benchmark code. 1 = C, -1 = SIMD");
32 #else
33 // Disable command line parameters if gflags disabled.
34 static const int32_t FLAGS_libyuv_width = 0;
35 static const int32_t FLAGS_libyuv_height = 0;
36 static const int32_t FLAGS_libyuv_repeat = 0;
37 static const int32_t FLAGS_libyuv_flags = 0;
38 static const int32_t FLAGS_libyuv_cpu_info = 0;
39 #endif
40 
41 // Test environment variable for disabling CPU features. Any non-zero value
42 // to disable. Zero ignored to make it easy to set the variable on/off.
43 #if !defined(__native_client__) && !defined(_M_ARM)
TestEnv(const char * name)44 static LIBYUV_BOOL TestEnv(const char* name) {
45   const char* var = getenv(name);
46   if (var) {
47     if (var[0] != '0') {
48       return LIBYUV_TRUE;
49     }
50   }
51   return LIBYUV_FALSE;
52 }
53 #else  // nacl does not support getenv().
TestEnv(const char *)54 static LIBYUV_BOOL TestEnv(const char*) {
55   return LIBYUV_FALSE;
56 }
57 #endif
58 
TestCpuEnv(int cpu_info)59 int TestCpuEnv(int cpu_info) {
60 #if defined(__arm__) || defined(__aarch64__)
61   if (TestEnv("LIBYUV_DISABLE_NEON")) {
62     cpu_info &= ~libyuv::kCpuHasNEON;
63   }
64 #endif
65 #if defined(__mips__) && defined(__linux__)
66   if (TestEnv("LIBYUV_DISABLE_MSA")) {
67     cpu_info &= ~libyuv::kCpuHasMSA;
68   }
69   if (TestEnv("LIBYUV_DISABLE_MMI")) {
70     cpu_info &= ~libyuv::kCpuHasMMI;
71   }
72 #endif
73 #if !defined(__pnacl__) && !defined(__CLR_VER) &&                   \
74     (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || \
75      defined(_M_IX86))
76   if (TestEnv("LIBYUV_DISABLE_X86")) {
77     cpu_info &= ~libyuv::kCpuHasX86;
78   }
79   if (TestEnv("LIBYUV_DISABLE_SSE2")) {
80     cpu_info &= ~libyuv::kCpuHasSSE2;
81   }
82   if (TestEnv("LIBYUV_DISABLE_SSSE3")) {
83     cpu_info &= ~libyuv::kCpuHasSSSE3;
84   }
85   if (TestEnv("LIBYUV_DISABLE_SSE41")) {
86     cpu_info &= ~libyuv::kCpuHasSSE41;
87   }
88   if (TestEnv("LIBYUV_DISABLE_SSE42")) {
89     cpu_info &= ~libyuv::kCpuHasSSE42;
90   }
91   if (TestEnv("LIBYUV_DISABLE_AVX")) {
92     cpu_info &= ~libyuv::kCpuHasAVX;
93   }
94   if (TestEnv("LIBYUV_DISABLE_AVX2")) {
95     cpu_info &= ~libyuv::kCpuHasAVX2;
96   }
97   if (TestEnv("LIBYUV_DISABLE_ERMS")) {
98     cpu_info &= ~libyuv::kCpuHasERMS;
99   }
100   if (TestEnv("LIBYUV_DISABLE_FMA3")) {
101     cpu_info &= ~libyuv::kCpuHasFMA3;
102   }
103   if (TestEnv("LIBYUV_DISABLE_F16C")) {
104     cpu_info &= ~libyuv::kCpuHasF16C;
105   }
106   if (TestEnv("LIBYUV_DISABLE_AVX512BW")) {
107     cpu_info &= ~libyuv::kCpuHasAVX512BW;
108   }
109   if (TestEnv("LIBYUV_DISABLE_AVX512VL")) {
110     cpu_info &= ~libyuv::kCpuHasAVX512VL;
111   }
112   if (TestEnv("LIBYUV_DISABLE_AVX512VBMI")) {
113     cpu_info &= ~libyuv::kCpuHasAVX512VBMI;
114   }
115   if (TestEnv("LIBYUV_DISABLE_AVX512VBMI2")) {
116     cpu_info &= ~libyuv::kCpuHasAVX512VBMI2;
117   }
118   if (TestEnv("LIBYUV_DISABLE_AVX512VBITALG")) {
119     cpu_info &= ~libyuv::kCpuHasAVX512VBITALG;
120   }
121   if (TestEnv("LIBYUV_DISABLE_AVX512VPOPCNTDQ")) {
122     cpu_info &= ~libyuv::kCpuHasAVX512VPOPCNTDQ;
123   }
124   if (TestEnv("LIBYUV_DISABLE_GFNI")) {
125     cpu_info &= ~libyuv::kCpuHasGFNI;
126   }
127 #endif
128   if (TestEnv("LIBYUV_DISABLE_ASM")) {
129     cpu_info = libyuv::kCpuInitialized;
130   }
131   return cpu_info;
132 }
133 
134 // For quicker unittests, default is 128 x 72.  But when benchmarking,
135 // default to 720p.  Allow size to specify.
136 // Set flags to -1 for benchmarking to avoid slower C code.
137 
LibYUVConvertTest()138 LibYUVConvertTest::LibYUVConvertTest()
139     : benchmark_iterations_(1),
140       benchmark_width_(128),
141       benchmark_height_(72),
142       disable_cpu_flags_(1),
143       benchmark_cpu_info_(-1) {
144   const char* repeat = getenv("LIBYUV_REPEAT");
145   if (repeat) {
146     benchmark_iterations_ = atoi(repeat);  // NOLINT
147   }
148   if (FLAGS_libyuv_repeat) {
149     benchmark_iterations_ = FLAGS_libyuv_repeat;
150   }
151   if (benchmark_iterations_ > 1) {
152     benchmark_width_ = 1280;
153     benchmark_height_ = 720;
154   }
155   const char* width = getenv("LIBYUV_WIDTH");
156   if (width) {
157     benchmark_width_ = atoi(width);  // NOLINT
158   }
159   if (FLAGS_libyuv_width) {
160     benchmark_width_ = FLAGS_libyuv_width;
161   }
162   const char* height = getenv("LIBYUV_HEIGHT");
163   if (height) {
164     benchmark_height_ = atoi(height);  // NOLINT
165   }
166   if (FLAGS_libyuv_height) {
167     benchmark_height_ = FLAGS_libyuv_height;
168   }
169   const char* cpu_flags = getenv("LIBYUV_FLAGS");
170   if (cpu_flags) {
171     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
172   }
173   if (FLAGS_libyuv_flags) {
174     disable_cpu_flags_ = FLAGS_libyuv_flags;
175   }
176   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
177   if (cpu_info) {
178     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
179   }
180   if (FLAGS_libyuv_cpu_info) {
181     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
182   }
183   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
184   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
185   libyuv::MaskCpuFlags(benchmark_cpu_info_);
186   benchmark_pixels_div1280_ =
187       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
188                             static_cast<double>(Abs(benchmark_height_)) *
189                             static_cast<double>(benchmark_iterations_) +
190                         1279.0) /
191                        1280.0);
192 }
193 
LibYUVColorTest()194 LibYUVColorTest::LibYUVColorTest()
195     : benchmark_iterations_(1),
196       benchmark_width_(128),
197       benchmark_height_(72),
198       disable_cpu_flags_(1),
199       benchmark_cpu_info_(-1) {
200   const char* repeat = getenv("LIBYUV_REPEAT");
201   if (repeat) {
202     benchmark_iterations_ = atoi(repeat);  // NOLINT
203   }
204   if (FLAGS_libyuv_repeat) {
205     benchmark_iterations_ = FLAGS_libyuv_repeat;
206   }
207   if (benchmark_iterations_ > 1) {
208     benchmark_width_ = 1280;
209     benchmark_height_ = 720;
210   }
211   const char* width = getenv("LIBYUV_WIDTH");
212   if (width) {
213     benchmark_width_ = atoi(width);  // NOLINT
214   }
215   if (FLAGS_libyuv_width) {
216     benchmark_width_ = FLAGS_libyuv_width;
217   }
218   const char* height = getenv("LIBYUV_HEIGHT");
219   if (height) {
220     benchmark_height_ = atoi(height);  // NOLINT
221   }
222   if (FLAGS_libyuv_height) {
223     benchmark_height_ = FLAGS_libyuv_height;
224   }
225   const char* cpu_flags = getenv("LIBYUV_FLAGS");
226   if (cpu_flags) {
227     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
228   }
229   if (FLAGS_libyuv_flags) {
230     disable_cpu_flags_ = FLAGS_libyuv_flags;
231   }
232   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
233   if (cpu_info) {
234     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
235   }
236   if (FLAGS_libyuv_cpu_info) {
237     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
238   }
239   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
240   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
241   libyuv::MaskCpuFlags(benchmark_cpu_info_);
242   benchmark_pixels_div1280_ =
243       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
244                             static_cast<double>(Abs(benchmark_height_)) *
245                             static_cast<double>(benchmark_iterations_) +
246                         1279.0) /
247                        1280.0);
248 }
249 
LibYUVScaleTest()250 LibYUVScaleTest::LibYUVScaleTest()
251     : benchmark_iterations_(1),
252       benchmark_width_(128),
253       benchmark_height_(72),
254       disable_cpu_flags_(1),
255       benchmark_cpu_info_(-1) {
256   const char* repeat = getenv("LIBYUV_REPEAT");
257   if (repeat) {
258     benchmark_iterations_ = atoi(repeat);  // NOLINT
259   }
260   if (FLAGS_libyuv_repeat) {
261     benchmark_iterations_ = FLAGS_libyuv_repeat;
262   }
263   if (benchmark_iterations_ > 1) {
264     benchmark_width_ = 1280;
265     benchmark_height_ = 720;
266   }
267   const char* width = getenv("LIBYUV_WIDTH");
268   if (width) {
269     benchmark_width_ = atoi(width);  // NOLINT
270   }
271   if (FLAGS_libyuv_width) {
272     benchmark_width_ = FLAGS_libyuv_width;
273   }
274   const char* height = getenv("LIBYUV_HEIGHT");
275   if (height) {
276     benchmark_height_ = atoi(height);  // NOLINT
277   }
278   if (FLAGS_libyuv_height) {
279     benchmark_height_ = FLAGS_libyuv_height;
280   }
281   const char* cpu_flags = getenv("LIBYUV_FLAGS");
282   if (cpu_flags) {
283     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
284   }
285   if (FLAGS_libyuv_flags) {
286     disable_cpu_flags_ = FLAGS_libyuv_flags;
287   }
288   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
289   if (cpu_info) {
290     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
291   }
292   if (FLAGS_libyuv_cpu_info) {
293     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
294   }
295   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
296   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
297   libyuv::MaskCpuFlags(benchmark_cpu_info_);
298   benchmark_pixels_div1280_ =
299       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
300                             static_cast<double>(Abs(benchmark_height_)) *
301                             static_cast<double>(benchmark_iterations_) +
302                         1279.0) /
303                        1280.0);
304 }
305 
LibYUVRotateTest()306 LibYUVRotateTest::LibYUVRotateTest()
307     : benchmark_iterations_(1),
308       benchmark_width_(128),
309       benchmark_height_(72),
310       disable_cpu_flags_(1),
311       benchmark_cpu_info_(-1) {
312   const char* repeat = getenv("LIBYUV_REPEAT");
313   if (repeat) {
314     benchmark_iterations_ = atoi(repeat);  // NOLINT
315   }
316   if (FLAGS_libyuv_repeat) {
317     benchmark_iterations_ = FLAGS_libyuv_repeat;
318   }
319   if (benchmark_iterations_ > 1) {
320     benchmark_width_ = 1280;
321     benchmark_height_ = 720;
322   }
323   const char* width = getenv("LIBYUV_WIDTH");
324   if (width) {
325     benchmark_width_ = atoi(width);  // NOLINT
326   }
327   if (FLAGS_libyuv_width) {
328     benchmark_width_ = FLAGS_libyuv_width;
329   }
330   const char* height = getenv("LIBYUV_HEIGHT");
331   if (height) {
332     benchmark_height_ = atoi(height);  // NOLINT
333   }
334   if (FLAGS_libyuv_height) {
335     benchmark_height_ = FLAGS_libyuv_height;
336   }
337   const char* cpu_flags = getenv("LIBYUV_FLAGS");
338   if (cpu_flags) {
339     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
340   }
341   if (FLAGS_libyuv_flags) {
342     disable_cpu_flags_ = FLAGS_libyuv_flags;
343   }
344   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
345   if (cpu_info) {
346     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
347   }
348   if (FLAGS_libyuv_cpu_info) {
349     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
350   }
351   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
352   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
353   libyuv::MaskCpuFlags(benchmark_cpu_info_);
354   benchmark_pixels_div1280_ =
355       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
356                             static_cast<double>(Abs(benchmark_height_)) *
357                             static_cast<double>(benchmark_iterations_) +
358                         1279.0) /
359                        1280.0);
360 }
361 
LibYUVPlanarTest()362 LibYUVPlanarTest::LibYUVPlanarTest()
363     : benchmark_iterations_(1),
364       benchmark_width_(128),
365       benchmark_height_(72),
366       disable_cpu_flags_(1),
367       benchmark_cpu_info_(-1) {
368   const char* repeat = getenv("LIBYUV_REPEAT");
369   if (repeat) {
370     benchmark_iterations_ = atoi(repeat);  // NOLINT
371   }
372   if (FLAGS_libyuv_repeat) {
373     benchmark_iterations_ = FLAGS_libyuv_repeat;
374   }
375   if (benchmark_iterations_ > 1) {
376     benchmark_width_ = 1280;
377     benchmark_height_ = 720;
378   }
379   const char* width = getenv("LIBYUV_WIDTH");
380   if (width) {
381     benchmark_width_ = atoi(width);  // NOLINT
382   }
383   if (FLAGS_libyuv_width) {
384     benchmark_width_ = FLAGS_libyuv_width;
385   }
386   const char* height = getenv("LIBYUV_HEIGHT");
387   if (height) {
388     benchmark_height_ = atoi(height);  // NOLINT
389   }
390   if (FLAGS_libyuv_height) {
391     benchmark_height_ = FLAGS_libyuv_height;
392   }
393   const char* cpu_flags = getenv("LIBYUV_FLAGS");
394   if (cpu_flags) {
395     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
396   }
397   if (FLAGS_libyuv_flags) {
398     disable_cpu_flags_ = FLAGS_libyuv_flags;
399   }
400   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
401   if (cpu_info) {
402     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
403   }
404   if (FLAGS_libyuv_cpu_info) {
405     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
406   }
407   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
408   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
409   libyuv::MaskCpuFlags(benchmark_cpu_info_);
410   benchmark_pixels_div1280_ =
411       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
412                             static_cast<double>(Abs(benchmark_height_)) *
413                             static_cast<double>(benchmark_iterations_) +
414                         1279.0) /
415                        1280.0);
416 }
417 
LibYUVBaseTest()418 LibYUVBaseTest::LibYUVBaseTest()
419     : benchmark_iterations_(1),
420       benchmark_width_(128),
421       benchmark_height_(72),
422       disable_cpu_flags_(1),
423       benchmark_cpu_info_(-1) {
424   const char* repeat = getenv("LIBYUV_REPEAT");
425   if (repeat) {
426     benchmark_iterations_ = atoi(repeat);  // NOLINT
427   }
428   if (FLAGS_libyuv_repeat) {
429     benchmark_iterations_ = FLAGS_libyuv_repeat;
430   }
431   if (benchmark_iterations_ > 1) {
432     benchmark_width_ = 1280;
433     benchmark_height_ = 720;
434   }
435   const char* width = getenv("LIBYUV_WIDTH");
436   if (width) {
437     benchmark_width_ = atoi(width);  // NOLINT
438   }
439   if (FLAGS_libyuv_width) {
440     benchmark_width_ = FLAGS_libyuv_width;
441   }
442   const char* height = getenv("LIBYUV_HEIGHT");
443   if (height) {
444     benchmark_height_ = atoi(height);  // NOLINT
445   }
446   if (FLAGS_libyuv_height) {
447     benchmark_height_ = FLAGS_libyuv_height;
448   }
449   const char* cpu_flags = getenv("LIBYUV_FLAGS");
450   if (cpu_flags) {
451     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
452   }
453   if (FLAGS_libyuv_flags) {
454     disable_cpu_flags_ = FLAGS_libyuv_flags;
455   }
456   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
457   if (cpu_info) {
458     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
459   }
460   if (FLAGS_libyuv_cpu_info) {
461     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
462   }
463   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
464   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
465   libyuv::MaskCpuFlags(benchmark_cpu_info_);
466   benchmark_pixels_div1280_ =
467       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
468                             static_cast<double>(Abs(benchmark_height_)) *
469                             static_cast<double>(benchmark_iterations_) +
470                         1279.0) /
471                        1280.0);
472 }
473 
LibYUVCompareTest()474 LibYUVCompareTest::LibYUVCompareTest()
475     : benchmark_iterations_(1),
476       benchmark_width_(128),
477       benchmark_height_(72),
478       disable_cpu_flags_(1),
479       benchmark_cpu_info_(-1) {
480   const char* repeat = getenv("LIBYUV_REPEAT");
481   if (repeat) {
482     benchmark_iterations_ = atoi(repeat);  // NOLINT
483   }
484   if (FLAGS_libyuv_repeat) {
485     benchmark_iterations_ = FLAGS_libyuv_repeat;
486   }
487   if (benchmark_iterations_ > 1) {
488     benchmark_width_ = 1280;
489     benchmark_height_ = 720;
490   }
491   const char* width = getenv("LIBYUV_WIDTH");
492   if (width) {
493     benchmark_width_ = atoi(width);  // NOLINT
494   }
495   if (FLAGS_libyuv_width) {
496     benchmark_width_ = FLAGS_libyuv_width;
497   }
498   const char* height = getenv("LIBYUV_HEIGHT");
499   if (height) {
500     benchmark_height_ = atoi(height);  // NOLINT
501   }
502   if (FLAGS_libyuv_height) {
503     benchmark_height_ = FLAGS_libyuv_height;
504   }
505   const char* cpu_flags = getenv("LIBYUV_FLAGS");
506   if (cpu_flags) {
507     disable_cpu_flags_ = atoi(cpu_flags);  // NOLINT
508   }
509   if (FLAGS_libyuv_flags) {
510     disable_cpu_flags_ = FLAGS_libyuv_flags;
511   }
512   const char* cpu_info = getenv("LIBYUV_CPU_INFO");
513   if (cpu_info) {
514     benchmark_cpu_info_ = atoi(cpu_flags);  // NOLINT
515   }
516   if (FLAGS_libyuv_cpu_info) {
517     benchmark_cpu_info_ = FLAGS_libyuv_cpu_info;
518   }
519   disable_cpu_flags_ = TestCpuEnv(disable_cpu_flags_);
520   benchmark_cpu_info_ = TestCpuEnv(benchmark_cpu_info_);
521   libyuv::MaskCpuFlags(benchmark_cpu_info_);
522   benchmark_pixels_div1280_ =
523       static_cast<int>((static_cast<double>(Abs(benchmark_width_)) *
524                             static_cast<double>(Abs(benchmark_height_)) *
525                             static_cast<double>(benchmark_iterations_) +
526                         1279.0) /
527                        1280.0);
528 }
529 
main(int argc,char ** argv)530 int main(int argc, char** argv) {
531   ::testing::InitGoogleTest(&argc, argv);
532 #ifdef LIBYUV_USE_GFLAGS
533   // AllowCommandLineParsing allows us to ignore flags passed on to us by
534   // Chromium build bots without having to explicitly disable them.
535   google::AllowCommandLineReparsing();
536   google::ParseCommandLineFlags(&argc, &argv, true);
537 #endif
538   return RUN_ALL_TESTS();
539 }
540