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