]> git.proxmox.com Git - ceph.git/blame - ceph/src/isa-l/erasure_code/gf_2vect_dot_prod_sse_test.c
Import ceph 15.2.8
[ceph.git] / ceph / src / isa-l / erasure_code / gf_2vect_dot_prod_sse_test.c
CommitLineData
7c673cae
FG
1/**********************************************************************
2 Copyright(c) 2011-2015 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
f91f0fd5 5 modification, are permitted provided that the following conditions
7c673cae
FG
6 are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in
11 the documentation and/or other materials provided with the
12 distribution.
13 * Neither the name of Intel Corporation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28**********************************************************************/
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h> // for memset, memcmp
33#include "erasure_code.h"
34#include "types.h"
35
36#ifndef FUNCTION_UNDER_TEST
37# define FUNCTION_UNDER_TEST gf_2vect_dot_prod_sse
38#endif
39#ifndef TEST_MIN_SIZE
40# define TEST_MIN_SIZE 16
41#endif
42
43#define str(s) #s
44#define xstr(s) str(s)
45
46#define TEST_LEN 8192
47#define TEST_SIZE (TEST_LEN/2)
48#define TEST_MEM TEST_SIZE
49#define TEST_LOOPS 10000
50#define TEST_TYPE_STR ""
51
52#ifndef TEST_SOURCES
53# define TEST_SOURCES 16
54#endif
55#ifndef RANDOMS
56# define RANDOMS 20
57#endif
58
59#ifdef EC_ALIGNED_ADDR
60// Define power of 2 range to check ptr, len alignment
61# define PTR_ALIGN_CHK_B 0
62# define LEN_ALIGN_CHK_B 0 // 0 for aligned only
63#else
64// Define power of 2 range to check ptr, len alignment
65# define PTR_ALIGN_CHK_B 32
66# define LEN_ALIGN_CHK_B 32 // 0 for aligned only
67#endif
68
69typedef unsigned char u8;
70
71extern void FUNCTION_UNDER_TEST(int len, int vlen, unsigned char *gftbls,
72 unsigned char **src, unsigned char **dest);
73
74void dump(unsigned char *buf, int len)
75{
76 int i;
77 for (i = 0; i < len;) {
78 printf(" %2x", 0xff & buf[i++]);
79 if (i % 32 == 0)
80 printf("\n");
81 }
82 printf("\n");
83}
84
85void dump_matrix(unsigned char **s, int k, int m)
86{
87 int i, j;
88 for (i = 0; i < k; i++) {
89 for (j = 0; j < m; j++) {
90 printf(" %2x", s[i][j]);
91 }
92 printf("\n");
93 }
94 printf("\n");
95}
96
97void dump_u8xu8(unsigned char *s, int k, int m)
98{
99 int i, j;
100 for (i = 0; i < k; i++) {
101 for (j = 0; j < m; j++) {
102 printf(" %2x", 0xff & s[j + (i * m)]);
103 }
104 printf("\n");
105 }
106 printf("\n");
107}
108
109int main(int argc, char *argv[])
110{
111 int i, j, rtest, srcs;
112 void *buf;
113 u8 g1[TEST_SOURCES], g2[TEST_SOURCES], g_tbls[2 * TEST_SOURCES * 32];
114 u8 *dest1, *dest2, *dest_ref1, *dest_ref2, *dest_ptrs[2];
115 u8 *buffs[TEST_SOURCES];
116
117 int align, size;
118 unsigned char *efence_buffs[TEST_SOURCES];
119 unsigned int offset;
120 u8 *ubuffs[TEST_SOURCES];
121 u8 *udest_ptrs[2];
122
123 printf(xstr(FUNCTION_UNDER_TEST) ": %dx%d ", TEST_SOURCES, TEST_LEN);
124
125 // Allocate the arrays
126 for (i = 0; i < TEST_SOURCES; i++) {
127 if (posix_memalign(&buf, 64, TEST_LEN)) {
128 printf("alloc error: Fail");
129 return -1;
130 }
131 buffs[i] = buf;
132 }
133
134 if (posix_memalign(&buf, 64, TEST_LEN)) {
135 printf("alloc error: Fail");
136 return -1;
137 }
138 dest1 = buf;
139
140 if (posix_memalign(&buf, 64, TEST_LEN)) {
141 printf("alloc error: Fail");
142 return -1;
143 }
144 dest2 = buf;
145
146 if (posix_memalign(&buf, 64, TEST_LEN)) {
147 printf("alloc error: Fail");
148 return -1;
149 }
150 dest_ref1 = buf;
151
152 if (posix_memalign(&buf, 64, TEST_LEN)) {
153 printf("alloc error: Fail");
154 return -1;
155 }
156 dest_ref2 = buf;
157
158 dest_ptrs[0] = dest1;
159 dest_ptrs[1] = dest2;
160
161 // Test of all zeros
162 for (i = 0; i < TEST_SOURCES; i++)
163 memset(buffs[i], 0, TEST_LEN);
164
165 memset(dest1, 0, TEST_LEN);
166 memset(dest2, 0, TEST_LEN);
167 memset(dest_ref1, 0, TEST_LEN);
168 memset(dest_ref2, 0, TEST_LEN);
169 memset(g1, 2, TEST_SOURCES);
170 memset(g2, 1, TEST_SOURCES);
171
172 for (i = 0; i < TEST_SOURCES; i++) {
173 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
174 gf_vect_mul_init(g2[i], &g_tbls[32 * TEST_SOURCES + i * 32]);
175 }
176
177 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[0], buffs, dest_ref1);
178 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[32 * TEST_SOURCES], buffs,
179 dest_ref2);
180
181 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest_ptrs);
182
183 if (0 != memcmp(dest_ref1, dest1, TEST_LEN)) {
184 printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test1\n");
185 dump_matrix(buffs, 5, TEST_SOURCES);
186 printf("dprod_base:");
187 dump(dest_ref1, 25);
188 printf("dprod_dut:");
189 dump(dest1, 25);
190 return -1;
191 }
192 if (0 != memcmp(dest_ref2, dest2, TEST_LEN)) {
193 printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test2\n");
194 dump_matrix(buffs, 5, TEST_SOURCES);
195 printf("dprod_base:");
196 dump(dest_ref2, 25);
197 printf("dprod_dut:");
198 dump(dest2, 25);
199 return -1;
200 }
201
202 putchar('.');
203
204 // Rand data test
205
206 for (rtest = 0; rtest < RANDOMS; rtest++) {
207 for (i = 0; i < TEST_SOURCES; i++)
208 for (j = 0; j < TEST_LEN; j++)
209 buffs[i][j] = rand();
210
211 for (i = 0; i < TEST_SOURCES; i++) {
212 g1[i] = rand();
213 g2[i] = rand();
214 }
215
216 for (i = 0; i < TEST_SOURCES; i++) {
217 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
218 gf_vect_mul_init(g2[i], &g_tbls[(32 * TEST_SOURCES) + (i * 32)]);
219 }
220
221 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[0], buffs, dest_ref1);
222 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[32 * TEST_SOURCES],
223 buffs, dest_ref2);
224
225 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest_ptrs);
226
227 if (0 != memcmp(dest_ref1, dest1, TEST_LEN)) {
228 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test1 %d\n", rtest);
229 dump_matrix(buffs, 5, TEST_SOURCES);
230 printf("dprod_base:");
231 dump(dest_ref1, 25);
232 printf("dprod_dut:");
233 dump(dest1, 25);
234 return -1;
235 }
236 if (0 != memcmp(dest_ref2, dest2, TEST_LEN)) {
237 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test2 %d\n", rtest);
238 dump_matrix(buffs, 5, TEST_SOURCES);
239 printf("dprod_base:");
240 dump(dest_ref2, 25);
241 printf("dprod_dut:");
242 dump(dest2, 25);
243 return -1;
244 }
245
246 putchar('.');
247 }
248
249 // Rand data test with varied parameters
250 for (rtest = 0; rtest < RANDOMS; rtest++) {
251 for (srcs = TEST_SOURCES; srcs > 0; srcs--) {
252 for (i = 0; i < srcs; i++)
253 for (j = 0; j < TEST_LEN; j++)
254 buffs[i][j] = rand();
255
256 for (i = 0; i < srcs; i++) {
257 g1[i] = rand();
258 g2[i] = rand();
259 }
260
261 for (i = 0; i < srcs; i++) {
262 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
263 gf_vect_mul_init(g2[i], &g_tbls[(32 * srcs) + (i * 32)]);
264 }
265
266 gf_vect_dot_prod_base(TEST_LEN, srcs, &g_tbls[0], buffs, dest_ref1);
267 gf_vect_dot_prod_base(TEST_LEN, srcs, &g_tbls[32 * srcs], buffs,
268 dest_ref2);
269
270 FUNCTION_UNDER_TEST(TEST_LEN, srcs, g_tbls, buffs, dest_ptrs);
271
272 if (0 != memcmp(dest_ref1, dest1, TEST_LEN)) {
273 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
274 " test1 srcs=%d\n", srcs);
275 dump_matrix(buffs, 5, TEST_SOURCES);
276 printf("dprod_base:");
277 dump(dest_ref1, 25);
278 printf("dprod_dut:");
279 dump(dest1, 25);
280 return -1;
281 }
282 if (0 != memcmp(dest_ref2, dest2, TEST_LEN)) {
283 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
284 " test2 srcs=%d\n", srcs);
285 dump_matrix(buffs, 5, TEST_SOURCES);
286 printf("dprod_base:");
287 dump(dest_ref2, 25);
288 printf("dprod_dut:");
289 dump(dest2, 25);
290 return -1;
291 }
292
293 putchar('.');
294 }
295 }
296
297 // Run tests at end of buffer for Electric Fence
298 align = (LEN_ALIGN_CHK_B != 0) ? 1 : 16;
299 for (size = TEST_MIN_SIZE; size <= TEST_SIZE; size += align) {
300 for (i = 0; i < TEST_SOURCES; i++)
301 for (j = 0; j < TEST_LEN; j++)
302 buffs[i][j] = rand();
303
304 for (i = 0; i < TEST_SOURCES; i++) // Line up TEST_SIZE from end
305 efence_buffs[i] = buffs[i] + TEST_LEN - size;
306
307 for (i = 0; i < TEST_SOURCES; i++) {
308 g1[i] = rand();
309 g2[i] = rand();
310 }
311
312 for (i = 0; i < TEST_SOURCES; i++) {
313 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
314 gf_vect_mul_init(g2[i], &g_tbls[(32 * TEST_SOURCES) + (i * 32)]);
315 }
316
317 gf_vect_dot_prod_base(size, TEST_SOURCES, &g_tbls[0], efence_buffs, dest_ref1);
318 gf_vect_dot_prod_base(size, TEST_SOURCES, &g_tbls[32 * TEST_SOURCES],
319 efence_buffs, dest_ref2);
320
321 FUNCTION_UNDER_TEST(size, TEST_SOURCES, g_tbls, efence_buffs, dest_ptrs);
322
323 if (0 != memcmp(dest_ref1, dest1, size)) {
324 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test1 %d\n", rtest);
325 dump_matrix(efence_buffs, 5, TEST_SOURCES);
326 printf("dprod_base:");
327 dump(dest_ref1, align);
328 printf("dprod_dut:");
329 dump(dest1, align);
330 return -1;
331 }
332
333 if (0 != memcmp(dest_ref2, dest2, size)) {
334 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test2 %d\n", rtest);
335 dump_matrix(efence_buffs, 5, TEST_SOURCES);
336 printf("dprod_base:");
337 dump(dest_ref2, align);
338 printf("dprod_dut:");
339 dump(dest2, align);
340 return -1;
341 }
342
343 putchar('.');
344 }
345
346 // Test rand ptr alignment if available
347
348 for (rtest = 0; rtest < RANDOMS; rtest++) {
349 size = (TEST_LEN - PTR_ALIGN_CHK_B) & ~(TEST_MIN_SIZE - 1);
350 srcs = rand() % TEST_SOURCES;
351 if (srcs == 0)
352 continue;
353
354 offset = (PTR_ALIGN_CHK_B != 0) ? 1 : PTR_ALIGN_CHK_B;
355 // Add random offsets
356 for (i = 0; i < srcs; i++)
357 ubuffs[i] = buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
358
359 udest_ptrs[0] = dest1 + (rand() & (PTR_ALIGN_CHK_B - offset));
360 udest_ptrs[1] = dest2 + (rand() & (PTR_ALIGN_CHK_B - offset));
361
362 memset(dest1, 0, TEST_LEN); // zero pad to check write-over
363 memset(dest2, 0, TEST_LEN);
364
365 for (i = 0; i < srcs; i++)
366 for (j = 0; j < size; j++)
367 ubuffs[i][j] = rand();
368
369 for (i = 0; i < srcs; i++) {
370 g1[i] = rand();
371 g2[i] = rand();
372 }
373
374 for (i = 0; i < srcs; i++) {
375 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
376 gf_vect_mul_init(g2[i], &g_tbls[(32 * srcs) + (i * 32)]);
377 }
378
379 gf_vect_dot_prod_base(size, srcs, &g_tbls[0], ubuffs, dest_ref1);
380 gf_vect_dot_prod_base(size, srcs, &g_tbls[32 * srcs], ubuffs, dest_ref2);
381
382 FUNCTION_UNDER_TEST(size, srcs, g_tbls, ubuffs, udest_ptrs);
383
384 if (memcmp(dest_ref1, udest_ptrs[0], size)) {
385 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test ualign srcs=%d\n",
386 srcs);
387 dump_matrix(ubuffs, 5, TEST_SOURCES);
388 printf("dprod_base:");
389 dump(dest_ref1, 25);
390 printf("dprod_dut:");
391 dump(udest_ptrs[0], 25);
392 return -1;
393 }
394 if (memcmp(dest_ref2, udest_ptrs[1], size)) {
395 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test ualign srcs=%d\n",
396 srcs);
397 dump_matrix(ubuffs, 5, TEST_SOURCES);
398 printf("dprod_base:");
399 dump(dest_ref2, 25);
400 printf("dprod_dut:");
401 dump(udest_ptrs[1], 25);
402 return -1;
403 }
404 // Confirm that padding around dests is unchanged
405 memset(dest_ref1, 0, PTR_ALIGN_CHK_B); // Make reference zero buff
406 offset = udest_ptrs[0] - dest1;
407
408 if (memcmp(dest1, dest_ref1, offset)) {
409 printf("Fail rand ualign pad1 start\n");
410 return -1;
411 }
412 if (memcmp(dest1 + offset + size, dest_ref1, PTR_ALIGN_CHK_B - offset)) {
413 printf("Fail rand ualign pad1 end\n");
414 return -1;
415 }
416
417 offset = udest_ptrs[1] - dest2;
418 if (memcmp(dest2, dest_ref1, offset)) {
419 printf("Fail rand ualign pad2 start\n");
420 return -1;
421 }
422 if (memcmp(dest2 + offset + size, dest_ref1, PTR_ALIGN_CHK_B - offset)) {
423 printf("Fail rand ualign pad2 end\n");
424 return -1;
425 }
426
427 putchar('.');
428 }
429
430 // Test all size alignment
431 align = (LEN_ALIGN_CHK_B != 0) ? 1 : 16;
432
433 for (size = TEST_LEN; size >= TEST_MIN_SIZE; size -= align) {
434 srcs = TEST_SOURCES;
435
436 for (i = 0; i < srcs; i++)
437 for (j = 0; j < size; j++)
438 buffs[i][j] = rand();
439
440 for (i = 0; i < srcs; i++) {
441 g1[i] = rand();
442 g2[i] = rand();
443 }
444
445 for (i = 0; i < srcs; i++) {
446 gf_vect_mul_init(g1[i], &g_tbls[i * 32]);
447 gf_vect_mul_init(g2[i], &g_tbls[(32 * srcs) + (i * 32)]);
448 }
449
450 gf_vect_dot_prod_base(size, srcs, &g_tbls[0], buffs, dest_ref1);
451 gf_vect_dot_prod_base(size, srcs, &g_tbls[32 * srcs], buffs, dest_ref2);
452
453 FUNCTION_UNDER_TEST(size, srcs, g_tbls, buffs, dest_ptrs);
454
455 if (memcmp(dest_ref1, dest_ptrs[0], size)) {
456 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test ualign len=%d\n",
457 size);
458 dump_matrix(buffs, 5, TEST_SOURCES);
459 printf("dprod_base:");
460 dump(dest_ref1, 25);
461 printf("dprod_dut:");
462 dump(dest_ptrs[0], 25);
463 return -1;
464 }
465 if (memcmp(dest_ref2, dest_ptrs[1], size)) {
466 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test ualign len=%d\n",
467 size);
468 dump_matrix(buffs, 5, TEST_SOURCES);
469 printf("dprod_base:");
470 dump(dest_ref2, 25);
471 printf("dprod_dut:");
472 dump(dest_ptrs[1], 25);
473 return -1;
474 }
475 }
476
477 printf("Pass\n");
478 return 0;
479
480}