]>
git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/erasure_code/gf_3vect_dot_prod_sse_test.c
1 /**********************************************************************
2 Copyright(c) 2011-2015 Intel Corporation All rights reserved.
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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
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.
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 **********************************************************************/
32 #include <string.h> // for memset, memcmp
33 #include "erasure_code.h"
36 #ifndef FUNCTION_UNDER_TEST
37 # define FUNCTION_UNDER_TEST gf_3vect_dot_prod_sse
40 # define TEST_MIN_SIZE 16
44 #define xstr(s) str(s)
47 #define TEST_SIZE (TEST_LEN/2)
48 #define TEST_MEM TEST_SIZE
49 #define TEST_LOOPS 10000
50 #define TEST_TYPE_STR ""
53 # define TEST_SOURCES 16
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
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
69 typedef unsigned char u8
;
71 extern void FUNCTION_UNDER_TEST(int len
, int vlen
, unsigned char *gftbls
,
72 unsigned char **src
, unsigned char **dest
);
74 void dump(unsigned char *buf
, int len
)
77 for (i
= 0; i
< len
;) {
78 printf(" %2x", 0xff & buf
[i
++]);
85 void dump_matrix(unsigned char **s
, int k
, int m
)
88 for (i
= 0; i
< k
; i
++) {
89 for (j
= 0; j
< m
; j
++) {
90 printf(" %2x", s
[i
][j
]);
97 void dump_u8xu8(unsigned char *s
, int k
, int m
)
100 for (i
= 0; i
< k
; i
++) {
101 for (j
= 0; j
< m
; j
++) {
102 printf(" %2x", 0xff & s
[j
+ (i
* m
)]);
109 int main(int argc
, char *argv
[])
111 int i
, j
, rtest
, srcs
;
113 u8 g1
[TEST_SOURCES
], g2
[TEST_SOURCES
], g3
[TEST_SOURCES
];
114 u8 g_tbls
[3 * TEST_SOURCES
* 32], *dest_ptrs
[3], *buffs
[TEST_SOURCES
];
115 u8
*dest1
, *dest2
, *dest3
, *dest_ref1
, *dest_ref2
, *dest_ref3
;
118 unsigned char *efence_buffs
[TEST_SOURCES
];
120 u8
*ubuffs
[TEST_SOURCES
];
122 printf(xstr(FUNCTION_UNDER_TEST
) "_test: %dx%d ", TEST_SOURCES
, TEST_LEN
);
124 // Allocate the arrays
125 for (i
= 0; i
< TEST_SOURCES
; i
++) {
126 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
127 printf("alloc error: Fail");
133 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
134 printf("alloc error: Fail");
139 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
140 printf("alloc error: Fail");
145 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
146 printf("alloc error: Fail");
151 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
152 printf("alloc error: Fail");
157 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
158 printf("alloc error: Fail");;
163 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
164 printf("alloc error: Fail");
169 dest_ptrs
[0] = dest1
;
170 dest_ptrs
[1] = dest2
;
171 dest_ptrs
[2] = dest3
;
174 for (i
= 0; i
< TEST_SOURCES
; i
++)
175 memset(buffs
[i
], 0, TEST_LEN
);
177 memset(dest1
, 0, TEST_LEN
);
178 memset(dest2
, 0, TEST_LEN
);
179 memset(dest3
, 0, TEST_LEN
);
180 memset(dest_ref1
, 0, TEST_LEN
);
181 memset(dest_ref2
, 0, TEST_LEN
);
182 memset(dest_ref3
, 0, TEST_LEN
);
183 memset(g1
, 2, TEST_SOURCES
);
184 memset(g2
, 1, TEST_SOURCES
);
185 memset(g3
, 7, TEST_SOURCES
);
187 for (i
= 0; i
< TEST_SOURCES
; i
++) {
188 gf_vect_mul_init(g1
[i
], &g_tbls
[i
* 32]);
189 gf_vect_mul_init(g2
[i
], &g_tbls
[32 * TEST_SOURCES
+ i
* 32]);
190 gf_vect_mul_init(g3
[i
], &g_tbls
[64 * TEST_SOURCES
+ i
* 32]);
193 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[0], buffs
, dest_ref1
);
194 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[32 * TEST_SOURCES
], buffs
,
196 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[64 * TEST_SOURCES
], buffs
,
199 FUNCTION_UNDER_TEST(TEST_LEN
, TEST_SOURCES
, g_tbls
, buffs
, dest_ptrs
);
201 if (0 != memcmp(dest_ref1
, dest1
, TEST_LEN
)) {
202 printf("Fail zero" xstr(FUNCTION_UNDER_TEST
) " test1\n");
203 dump_matrix(buffs
, 5, TEST_SOURCES
);
204 printf("dprod_base:");
206 printf("dprod_dut:");
210 if (0 != memcmp(dest_ref2
, dest2
, TEST_LEN
)) {
211 printf("Fail zero " xstr(FUNCTION_UNDER_TEST
) " test2\n");
212 dump_matrix(buffs
, 5, TEST_SOURCES
);
213 printf("dprod_base:");
215 printf("dprod_dut:");
219 if (0 != memcmp(dest_ref3
, dest3
, TEST_LEN
)) {
220 printf("Fail zero " xstr(FUNCTION_UNDER_TEST
) " test3\n");
221 dump_matrix(buffs
, 5, TEST_SOURCES
);
222 printf("dprod_base:");
224 printf("dprod_dut:");
233 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
234 for (i
= 0; i
< TEST_SOURCES
; i
++)
235 for (j
= 0; j
< TEST_LEN
; j
++)
236 buffs
[i
][j
] = rand();
238 for (i
= 0; i
< TEST_SOURCES
; i
++) {
244 for (i
= 0; i
< TEST_SOURCES
; i
++) {
245 gf_vect_mul_init(g1
[i
], &g_tbls
[i
* 32]);
246 gf_vect_mul_init(g2
[i
], &g_tbls
[(32 * TEST_SOURCES
) + (i
* 32)]);
247 gf_vect_mul_init(g3
[i
], &g_tbls
[(64 * TEST_SOURCES
) + (i
* 32)]);
250 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[0], buffs
, dest_ref1
);
251 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[32 * TEST_SOURCES
],
253 gf_vect_dot_prod_base(TEST_LEN
, TEST_SOURCES
, &g_tbls
[64 * TEST_SOURCES
],
256 FUNCTION_UNDER_TEST(TEST_LEN
, TEST_SOURCES
, g_tbls
, buffs
, dest_ptrs
);
258 if (0 != memcmp(dest_ref1
, dest1
, TEST_LEN
)) {
259 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test1 %d\n", rtest
);
260 dump_matrix(buffs
, 5, TEST_SOURCES
);
261 printf("dprod_base:");
263 printf("dprod_dut:");
267 if (0 != memcmp(dest_ref2
, dest2
, TEST_LEN
)) {
268 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test2 %d\n", rtest
);
269 dump_matrix(buffs
, 5, TEST_SOURCES
);
270 printf("dprod_base:");
272 printf("dprod_dut:");
276 if (0 != memcmp(dest_ref3
, dest3
, TEST_LEN
)) {
277 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test3 %d\n", rtest
);
278 dump_matrix(buffs
, 5, TEST_SOURCES
);
279 printf("dprod_base:");
281 printf("dprod_dut:");
289 // Rand data test with varied parameters
290 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
291 for (srcs
= TEST_SOURCES
; srcs
> 0; srcs
--) {
292 for (i
= 0; i
< srcs
; i
++)
293 for (j
= 0; j
< TEST_LEN
; j
++)
294 buffs
[i
][j
] = rand();
296 for (i
= 0; i
< srcs
; i
++) {
302 for (i
= 0; i
< srcs
; i
++) {
303 gf_vect_mul_init(g1
[i
], &g_tbls
[i
* 32]);
304 gf_vect_mul_init(g2
[i
], &g_tbls
[(32 * srcs
) + (i
* 32)]);
305 gf_vect_mul_init(g3
[i
], &g_tbls
[(64 * srcs
) + (i
* 32)]);
308 gf_vect_dot_prod_base(TEST_LEN
, srcs
, &g_tbls
[0], buffs
, dest_ref1
);
309 gf_vect_dot_prod_base(TEST_LEN
, srcs
, &g_tbls
[32 * srcs
], buffs
,
311 gf_vect_dot_prod_base(TEST_LEN
, srcs
, &g_tbls
[64 * srcs
], buffs
,
314 FUNCTION_UNDER_TEST(TEST_LEN
, srcs
, g_tbls
, buffs
, dest_ptrs
);
316 if (0 != memcmp(dest_ref1
, dest1
, TEST_LEN
)) {
317 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
)
318 " test1 srcs=%d\n", srcs
);
319 dump_matrix(buffs
, 5, TEST_SOURCES
);
320 printf("dprod_base:");
322 printf("dprod_dut:");
326 if (0 != memcmp(dest_ref2
, dest2
, TEST_LEN
)) {
327 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
)
328 " test2 srcs=%d\n", srcs
);
329 dump_matrix(buffs
, 5, TEST_SOURCES
);
330 printf("dprod_base:");
332 printf("dprod_dut:");
336 if (0 != memcmp(dest_ref3
, dest3
, TEST_LEN
)) {
337 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
)
338 " test3 srcs=%d\n", srcs
);
339 dump_matrix(buffs
, 5, TEST_SOURCES
);
340 printf("dprod_base:");
342 printf("dprod_dut:");
351 // Run tests at end of buffer for Electric Fence
352 align
= (LEN_ALIGN_CHK_B
!= 0) ? 1 : 16;
353 for (size
= TEST_MIN_SIZE
; size
<= TEST_SIZE
; size
+= align
) {
354 for (i
= 0; i
< TEST_SOURCES
; i
++)
355 for (j
= 0; j
< TEST_LEN
; j
++)
356 buffs
[i
][j
] = rand();
358 for (i
= 0; i
< TEST_SOURCES
; i
++) // Line up TEST_SIZE from end
359 efence_buffs
[i
] = buffs
[i
] + TEST_LEN
- size
;
361 for (i
= 0; i
< TEST_SOURCES
; i
++) {
367 for (i
= 0; i
< TEST_SOURCES
; i
++) {
368 gf_vect_mul_init(g1
[i
], &g_tbls
[i
* 32]);
369 gf_vect_mul_init(g2
[i
], &g_tbls
[(32 * TEST_SOURCES
) + (i
* 32)]);
370 gf_vect_mul_init(g3
[i
], &g_tbls
[(64 * TEST_SOURCES
) + (i
* 32)]);
373 gf_vect_dot_prod_base(size
, TEST_SOURCES
, &g_tbls
[0], efence_buffs
, dest_ref1
);
374 gf_vect_dot_prod_base(size
, TEST_SOURCES
, &g_tbls
[32 * TEST_SOURCES
],
375 efence_buffs
, dest_ref2
);
376 gf_vect_dot_prod_base(size
, TEST_SOURCES
, &g_tbls
[64 * TEST_SOURCES
],
377 efence_buffs
, dest_ref3
);
379 FUNCTION_UNDER_TEST(size
, TEST_SOURCES
, g_tbls
, efence_buffs
, dest_ptrs
);
381 if (0 != memcmp(dest_ref1
, dest1
, size
)) {
382 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test1 %d\n", rtest
);
383 dump_matrix(efence_buffs
, 5, TEST_SOURCES
);
384 printf("dprod_base:");
385 dump(dest_ref1
, align
);
386 printf("dprod_dut:");
391 if (0 != memcmp(dest_ref2
, dest2
, size
)) {
392 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test2 %d\n", rtest
);
393 dump_matrix(efence_buffs
, 5, TEST_SOURCES
);
394 printf("dprod_base:");
395 dump(dest_ref2
, align
);
396 printf("dprod_dut:");
401 if (0 != memcmp(dest_ref3
, dest3
, size
)) {
402 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test3 %d\n", rtest
);
403 dump_matrix(efence_buffs
, 5, TEST_SOURCES
);
404 printf("dprod_base:");
405 dump(dest_ref3
, align
);
406 printf("dprod_dut:");
414 // Test rand ptr alignment if available
416 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
417 size
= (TEST_LEN
- PTR_ALIGN_CHK_B
) & ~(TEST_MIN_SIZE
- 1);
418 srcs
= rand() % TEST_SOURCES
;
422 offset
= (PTR_ALIGN_CHK_B
!= 0) ? 1 : PTR_ALIGN_CHK_B
;
423 // Add random offsets
424 for (i
= 0; i
< srcs
; i
++)
425 ubuffs
[i
] = buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
427 udest_ptrs
[0] = dest1
+ (rand() & (PTR_ALIGN_CHK_B
- offset
));
428 udest_ptrs
[1] = dest2
+ (rand() & (PTR_ALIGN_CHK_B
- offset
));
429 udest_ptrs
[2] = dest3
+ (rand() & (PTR_ALIGN_CHK_B
- offset
));
431 memset(dest1
, 0, TEST_LEN
); // zero pad to check write-over
432 memset(dest2
, 0, TEST_LEN
);
433 memset(dest3
, 0, TEST_LEN
);
435 for (i
= 0; i
< srcs
; i
++)
436 for (j
= 0; j
< size
; j
++)
437 ubuffs
[i
][j
] = rand();
439 for (i
= 0; i
< srcs
; i
++) {
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 gf_vect_mul_init(g3
[i
], &g_tbls
[(64 * srcs
) + (i
* 32)]);
451 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[0], ubuffs
, dest_ref1
);
452 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[32 * srcs
], ubuffs
, dest_ref2
);
453 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[64 * srcs
], ubuffs
, dest_ref3
);
455 FUNCTION_UNDER_TEST(size
, srcs
, g_tbls
, ubuffs
, udest_ptrs
);
457 if (memcmp(dest_ref1
, udest_ptrs
[0], size
)) {
458 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign srcs=%d\n",
460 dump_matrix(ubuffs
, 5, TEST_SOURCES
);
461 printf("dprod_base:");
463 printf("dprod_dut:");
464 dump(udest_ptrs
[0], 25);
467 if (memcmp(dest_ref2
, udest_ptrs
[1], size
)) {
468 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign srcs=%d\n",
470 dump_matrix(ubuffs
, 5, TEST_SOURCES
);
471 printf("dprod_base:");
473 printf("dprod_dut:");
474 dump(udest_ptrs
[1], 25);
477 if (memcmp(dest_ref3
, udest_ptrs
[2], size
)) {
478 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign srcs=%d\n",
480 dump_matrix(ubuffs
, 5, TEST_SOURCES
);
481 printf("dprod_base:");
483 printf("dprod_dut:");
484 dump(udest_ptrs
[2], 25);
487 // Confirm that padding around dests is unchanged
488 memset(dest_ref1
, 0, PTR_ALIGN_CHK_B
); // Make reference zero buff
489 offset
= udest_ptrs
[0] - dest1
;
491 if (memcmp(dest1
, dest_ref1
, offset
)) {
492 printf("Fail rand ualign pad1 start\n");
495 if (memcmp(dest1
+ offset
+ size
, dest_ref1
, PTR_ALIGN_CHK_B
- offset
)) {
496 printf("Fail rand ualign pad1 end\n");
500 offset
= udest_ptrs
[1] - dest2
;
501 if (memcmp(dest2
, dest_ref1
, offset
)) {
502 printf("Fail rand ualign pad2 start\n");
505 if (memcmp(dest2
+ offset
+ size
, dest_ref1
, PTR_ALIGN_CHK_B
- offset
)) {
506 printf("Fail rand ualign pad2 end\n");
510 offset
= udest_ptrs
[2] - dest3
;
511 if (memcmp(dest3
, dest_ref1
, offset
)) {
512 printf("Fail rand ualign pad3 start\n");
515 if (memcmp(dest3
+ offset
+ size
, dest_ref1
, PTR_ALIGN_CHK_B
- offset
)) {
516 printf("Fail rand ualign pad3 end\n");;
523 // Test all size alignment
524 align
= (LEN_ALIGN_CHK_B
!= 0) ? 1 : 16;
526 for (size
= TEST_LEN
; size
>= TEST_MIN_SIZE
; size
-= align
) {
529 for (i
= 0; i
< srcs
; i
++)
530 for (j
= 0; j
< size
; j
++)
531 buffs
[i
][j
] = rand();
533 for (i
= 0; i
< srcs
; i
++) {
539 for (i
= 0; i
< srcs
; i
++) {
540 gf_vect_mul_init(g1
[i
], &g_tbls
[i
* 32]);
541 gf_vect_mul_init(g2
[i
], &g_tbls
[(32 * srcs
) + (i
* 32)]);
542 gf_vect_mul_init(g3
[i
], &g_tbls
[(64 * srcs
) + (i
* 32)]);
545 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[0], buffs
, dest_ref1
);
546 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[32 * srcs
], buffs
, dest_ref2
);
547 gf_vect_dot_prod_base(size
, srcs
, &g_tbls
[64 * srcs
], buffs
, dest_ref3
);
549 FUNCTION_UNDER_TEST(size
, srcs
, g_tbls
, buffs
, dest_ptrs
);
551 if (memcmp(dest_ref1
, dest_ptrs
[0], size
)) {
552 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign len=%d\n",
554 dump_matrix(buffs
, 5, TEST_SOURCES
);
555 printf("dprod_base:");
557 printf("dprod_dut:");
558 dump(dest_ptrs
[0], 25);
561 if (memcmp(dest_ref2
, dest_ptrs
[1], size
)) {
562 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign len=%d\n",
564 dump_matrix(buffs
, 5, TEST_SOURCES
);
565 printf("dprod_base:");
567 printf("dprod_dut:");
568 dump(dest_ptrs
[1], 25);
571 if (memcmp(dest_ref3
, dest_ptrs
[2], size
)) {
572 printf("Fail rand " xstr(FUNCTION_UNDER_TEST
) " test ualign len=%d\n",
574 dump_matrix(buffs
, 5, TEST_SOURCES
);
575 printf("dprod_base:");
577 printf("dprod_dut:");
578 dump(dest_ptrs
[2], 25);