1 /*****************************************************************************
2 * Copyright (C) 2013 x265 project
4 * Authors: Gopu Govindaswamy <gopu@govindaswamy.org>
5 * Mandar Gurav <mandar@multicorewareinc.com>
6 * Mahesh Pittala <mahesh@multicorewareinc.com>
8 * This program 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.
13 * This program 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.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA.
22 * This program is also available under a commercial proprietary license.
23 * For more information, contact us at license @ x265.com.
24 *****************************************************************************/
27 #include "primitives.h"
28 #include "pixelharness.h"
29 #include "mbdstharness.h"
30 #include "ipfilterharness.h"
31 #include "intrapredharness.h"
37 const char* lumaPartStr
[NUM_LUMA_PARTITIONS
] =
39 " 4x4", " 8x8", "16x16", "32x32", "64x64",
44 "16x12", "12x16", " 16x4", " 4x16",
45 "32x24", "24x32", " 32x8", " 8x32",
46 "64x48", "48x64", "64x16", "16x64",
49 const char* chromaPartStr420
[NUM_CHROMA_PARTITIONS
] =
51 " 2x2", " 4x4", " 8x8", "16x16", "32x32",
56 " 8x6", " 6x8", " 8x2", " 2x8",
57 "16x12", "12x16", " 16x4", " 4x16",
58 "32x24", "24x32", " 32x8", " 8x32",
61 const char* chromaPartStr422
[NUM_CHROMA_PARTITIONS
] =
63 " 2x4", " 4x8", " 8x16", "16x32", "32x64",
68 " 8x12", " 6x16", " 8x4", " 2x16",
69 "16x24", "12x32", " 16x8", " 4x32",
70 "32x48", "24x64", "32x16", " 8x64",
73 const char* const* chromaPartStr
[X265_CSP_COUNT
] =
83 printf("x265 optimized primitive testbench\n\n");
84 printf("usage: TestBench [--cpuid CPU] [--testbench BENCH] [--help]\n\n");
85 printf(" CPU is comma separated SIMD arch list, example: SSE4,AVX\n");
86 printf(" BENCH is one of (pixel,transforms,interp,intrapred)\n\n");
87 printf("By default, the test bench will test all benches on detected CPU architectures\n");
88 printf("Options and testbench name may be truncated.\n");
93 IPFilterHarness HIPFilter
;
94 IntraPredHarness HIPred
;
96 int main(int argc
, char *argv
[])
98 int cpuid
= x265::cpu_detect();
99 const char *testname
= 0;
106 for (int i
= 1; i
< argc
- 1; i
+= 2)
108 if (strncmp(argv
[i
], "--", 2))
110 printf("** invalid long argument: %s\n\n", argv
[i
]);
114 const char *name
= argv
[i
] + 2;
115 const char *value
= argv
[i
+ 1];
116 if (!strncmp(name
, "cpuid", strlen(name
)))
119 cpuid
= parseCpuName(value
, bError
);
122 printf("Invalid CPU name: %s\n", value
);
126 else if (!strncmp(name
, "testbench", strlen(name
)))
129 printf("Testing only harnesses that match name <%s>\n", testname
);
133 printf("** invalid long argument: %s\n\n", name
);
139 int seed
= (int)time(NULL
);
140 const char *bpp
[] = { "8bpp", "16bpp" };
141 printf("Using random seed %X %s\n", seed
, bpp
[HIGH_BIT_DEPTH
]);
144 // To disable classes of tests, simply comment them out in this list
145 TestHarness
*harness
[] =
153 EncoderPrimitives cprim
;
154 memset(&cprim
, 0, sizeof(EncoderPrimitives
));
155 Setup_C_Primitives(cprim
);
156 Setup_Alias_Primitives(cprim
);
164 { "SSE2", X265_CPU_SSE2
},
165 { "SSE3", X265_CPU_SSE3
},
166 { "SSSE3", X265_CPU_SSSE3
},
167 { "SSE4", X265_CPU_SSE4
},
168 { "AVX", X265_CPU_AVX
},
169 { "XOP", X265_CPU_XOP
},
170 { "AVX2", X265_CPU_AVX2
},
174 for (int i
= 0; test_arch
[i
].flag
; i
++)
176 if (test_arch
[i
].flag
& cpuid
)
177 printf("Testing primitives: %s\n", test_arch
[i
].name
);
181 EncoderPrimitives vecprim
;
182 memset(&vecprim
, 0, sizeof(vecprim
));
183 Setup_Instrinsic_Primitives(vecprim
, test_arch
[i
].flag
);
184 for (size_t h
= 0; h
< sizeof(harness
) / sizeof(TestHarness
*); h
++)
186 if (testname
&& strncmp(testname
, harness
[h
]->getName(), strlen(testname
)))
188 if (!harness
[h
]->testCorrectness(cprim
, vecprim
))
190 fprintf(stderr
, "\nx265: intrinsic primitive has failed. Go and fix that Right Now!\n");
195 EncoderPrimitives asmprim
;
196 memset(&asmprim
, 0, sizeof(asmprim
));
197 Setup_Assembly_Primitives(asmprim
, test_arch
[i
].flag
);
198 memcpy(&primitives
, &asmprim
, sizeof(EncoderPrimitives
));
199 for (size_t h
= 0; h
< sizeof(harness
) / sizeof(TestHarness
*); h
++)
201 if (testname
&& strncmp(testname
, harness
[h
]->getName(), strlen(testname
)))
203 if (!harness
[h
]->testCorrectness(cprim
, asmprim
))
205 fprintf(stderr
, "\nx265: asm primitive has failed. Go and fix that Right Now!\n");
211 /******************* Cycle count for all primitives **********************/
213 EncoderPrimitives optprim
;
214 memset(&optprim
, 0, sizeof(optprim
));
215 Setup_Instrinsic_Primitives(optprim
, cpuid
);
216 Setup_Assembly_Primitives(optprim
, cpuid
);
217 Setup_Alias_Primitives(optprim
);
219 /* some hybrid primitives may rely on other primitives in the
220 * global primitive table, so set up those pointers. This is a
221 * bit ugly, but I don't see a better solution */
222 memcpy(&primitives
, &optprim
, sizeof(EncoderPrimitives
));
224 printf("\nTest performance improvement with full optimizations\n");
226 for (size_t h
= 0; h
< sizeof(harness
) / sizeof(TestHarness
*); h
++)
228 if (testname
&& strncmp(testname
, harness
[h
]->getName(), strlen(testname
)))
230 printf("== %s primitives ==\n", harness
[h
]->getName());
231 harness
[h
]->measureSpeed(cprim
, optprim
);