Commit | Line | Data |
---|---|---|
72b9787e JB |
1 | /***************************************************************************** |
2 | * Copyright (C) 2013 x265 project | |
3 | * | |
4 | * Authors: Gopu Govindaswamy <gopu@govindaswamy.org> | |
5 | * Mandar Gurav <mandar@multicorewareinc.com> | |
6 | * Mahesh Pittala <mahesh@multicorewareinc.com> | |
7 | * | |
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. | |
12 | * | |
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. | |
17 | * | |
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. | |
21 | * | |
22 | * This program is also available under a commercial proprietary license. | |
23 | * For more information, contact us at license @ x265.com. | |
24 | *****************************************************************************/ | |
25 | ||
26 | #include "common.h" | |
27 | #include "primitives.h" | |
28 | #include "pixelharness.h" | |
29 | #include "mbdstharness.h" | |
30 | #include "ipfilterharness.h" | |
31 | #include "intrapredharness.h" | |
32 | #include "param.h" | |
33 | #include "cpu.h" | |
34 | ||
35 | using namespace x265; | |
36 | ||
37 | const char* lumaPartStr[NUM_LUMA_PARTITIONS] = | |
38 | { | |
39 | " 4x4", " 8x8", "16x16", "32x32", "64x64", | |
40 | " 8x4", " 4x8", | |
41 | " 16x8", " 8x16", | |
42 | "32x16", "16x32", | |
43 | "64x32", "32x64", | |
44 | "16x12", "12x16", " 16x4", " 4x16", | |
45 | "32x24", "24x32", " 32x8", " 8x32", | |
46 | "64x48", "48x64", "64x16", "16x64", | |
47 | }; | |
48 | ||
49 | const char* chromaPartStr420[NUM_CHROMA_PARTITIONS] = | |
50 | { | |
51 | " 2x2", " 4x4", " 8x8", "16x16", "32x32", | |
52 | " 4x2", " 2x4", | |
53 | " 8x4", " 4x8", | |
54 | " 16x8", " 8x16", | |
55 | "32x16", "16x32", | |
56 | " 8x6", " 6x8", " 8x2", " 2x8", | |
57 | "16x12", "12x16", " 16x4", " 4x16", | |
58 | "32x24", "24x32", " 32x8", " 8x32", | |
59 | }; | |
60 | ||
61 | const char* chromaPartStr422[NUM_CHROMA_PARTITIONS] = | |
62 | { | |
63 | " 2x4", " 4x8", " 8x16", "16x32", "32x64", | |
64 | " 4x4", " 2x8", | |
65 | " 8x8", " 4x16", | |
66 | "16x16", " 8x32", | |
67 | "32x32", "16x64", | |
68 | " 8x12", " 6x16", " 8x4", " 2x16", | |
69 | "16x24", "12x32", " 16x8", " 4x32", | |
70 | "32x48", "24x64", "32x16", " 8x64", | |
71 | }; | |
72 | ||
73 | const char* const* chromaPartStr[X265_CSP_COUNT] = | |
74 | { | |
75 | lumaPartStr, | |
76 | chromaPartStr420, | |
77 | chromaPartStr422, | |
78 | lumaPartStr | |
79 | }; | |
80 | ||
81 | void do_help() | |
82 | { | |
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"); | |
89 | } | |
90 | ||
91 | PixelHarness HPixel; | |
92 | MBDstHarness HMBDist; | |
93 | IPFilterHarness HIPFilter; | |
94 | IntraPredHarness HIPred; | |
95 | ||
96 | int main(int argc, char *argv[]) | |
97 | { | |
98 | int cpuid = x265::cpu_detect(); | |
99 | const char *testname = 0; | |
100 | ||
101 | if (!(argc & 1)) | |
102 | { | |
103 | do_help(); | |
104 | return 0; | |
105 | } | |
106 | for (int i = 1; i < argc - 1; i += 2) | |
107 | { | |
108 | if (strncmp(argv[i], "--", 2)) | |
109 | { | |
110 | printf("** invalid long argument: %s\n\n", argv[i]); | |
111 | do_help(); | |
112 | return 1; | |
113 | } | |
114 | const char *name = argv[i] + 2; | |
115 | const char *value = argv[i + 1]; | |
116 | if (!strncmp(name, "cpuid", strlen(name))) | |
117 | { | |
118 | bool bError = false; | |
119 | cpuid = parseCpuName(value, bError); | |
120 | if (bError) | |
121 | { | |
122 | printf("Invalid CPU name: %s\n", value); | |
123 | return 1; | |
124 | } | |
125 | } | |
126 | else if (!strncmp(name, "testbench", strlen(name))) | |
127 | { | |
128 | testname = value; | |
129 | printf("Testing only harnesses that match name <%s>\n", testname); | |
130 | } | |
131 | else | |
132 | { | |
133 | printf("** invalid long argument: %s\n\n", name); | |
134 | do_help(); | |
135 | return 1; | |
136 | } | |
137 | } | |
138 | ||
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]); | |
142 | srand(seed); | |
143 | ||
144 | // To disable classes of tests, simply comment them out in this list | |
145 | TestHarness *harness[] = | |
146 | { | |
147 | &HPixel, | |
148 | &HMBDist, | |
149 | &HIPFilter, | |
150 | &HIPred | |
151 | }; | |
152 | ||
153 | EncoderPrimitives cprim; | |
154 | memset(&cprim, 0, sizeof(EncoderPrimitives)); | |
155 | Setup_C_Primitives(cprim); | |
156 | Setup_Alias_Primitives(cprim); | |
157 | ||
158 | struct test_arch_t | |
159 | { | |
160 | char name[12]; | |
161 | int flag; | |
162 | } test_arch[] = | |
163 | { | |
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 }, | |
171 | { "", 0 }, | |
172 | }; | |
173 | ||
174 | for (int i = 0; test_arch[i].flag; i++) | |
175 | { | |
176 | if (test_arch[i].flag & cpuid) | |
177 | printf("Testing primitives: %s\n", test_arch[i].name); | |
178 | else | |
179 | continue; | |
180 | ||
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++) | |
185 | { | |
186 | if (testname && strncmp(testname, harness[h]->getName(), strlen(testname))) | |
187 | continue; | |
188 | if (!harness[h]->testCorrectness(cprim, vecprim)) | |
189 | { | |
190 | fprintf(stderr, "\nx265: intrinsic primitive has failed. Go and fix that Right Now!\n"); | |
191 | return -1; | |
192 | } | |
193 | } | |
194 | ||
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++) | |
200 | { | |
201 | if (testname && strncmp(testname, harness[h]->getName(), strlen(testname))) | |
202 | continue; | |
203 | if (!harness[h]->testCorrectness(cprim, asmprim)) | |
204 | { | |
205 | fprintf(stderr, "\nx265: asm primitive has failed. Go and fix that Right Now!\n"); | |
206 | return -1; | |
207 | } | |
208 | } | |
209 | } | |
210 | ||
211 | /******************* Cycle count for all primitives **********************/ | |
212 | ||
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); | |
218 | ||
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)); | |
223 | ||
224 | printf("\nTest performance improvement with full optimizations\n"); | |
225 | ||
226 | for (size_t h = 0; h < sizeof(harness) / sizeof(TestHarness*); h++) | |
227 | { | |
228 | if (testname && strncmp(testname, harness[h]->getName(), strlen(testname))) | |
229 | continue; | |
230 | printf("== %s primitives ==\n", harness[h]->getName()); | |
231 | harness[h]->measureSpeed(cprim, optprim); | |
232 | } | |
233 | ||
234 | printf("\n"); | |
235 | return 0; | |
236 | } |