]> git.proxmox.com Git - ceph.git/blame - ceph/src/spdk/isa-l/erasure_code/gf_vect_mad_test.c
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / spdk / isa-l / erasure_code / gf_vect_mad_test.c
CommitLineData
9f95a23c
TL
1/**********************************************************************
2 Copyright(c) 2011-2015 Intel Corporation All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions
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 ALIGN_SIZE
37# define ALIGN_SIZE 32
38#endif
39
40#ifndef FUNCTION_UNDER_TEST
41//By default, test multi-binary version
42# define FUNCTION_UNDER_TEST gf_vect_mad
43# define REF_FUNCTION gf_vect_dot_prod
44# define VECT 1
45#endif
46
47#ifndef TEST_MIN_SIZE
f67539c2 48# define TEST_MIN_SIZE 64
9f95a23c
TL
49#endif
50
51#define str(s) #s
52#define xstr(s) str(s)
53
54#define TEST_LEN 8192
55#define TEST_SIZE (TEST_LEN/2)
56#define TEST_MEM TEST_SIZE
57#define TEST_LOOPS 20000
58#define TEST_TYPE_STR ""
59
60#ifndef TEST_SOURCES
61# define TEST_SOURCES 16
62#endif
63#ifndef RANDOMS
64# define RANDOMS 20
65#endif
66
67#ifdef EC_ALIGNED_ADDR
68// Define power of 2 range to check ptr, len alignment
69# define PTR_ALIGN_CHK_B 0
70# define LEN_ALIGN_CHK_B 0 // 0 for aligned only
71#else
72// Define power of 2 range to check ptr, len alignment
73# define PTR_ALIGN_CHK_B ALIGN_SIZE
74# define LEN_ALIGN_CHK_B ALIGN_SIZE // 0 for aligned only
75#endif
76
77#define str(s) #s
78#define xstr(s) str(s)
79
80typedef unsigned char u8;
81
82#if (VECT == 1)
83# define LAST_ARG *dest
84#else
85# define LAST_ARG **dest
86#endif
87
88extern void FUNCTION_UNDER_TEST(int len, int vec, int vec_i, unsigned char *gftbls,
89 unsigned char *src, unsigned char LAST_ARG);
90extern void REF_FUNCTION(int len, int vlen, unsigned char *gftbls, unsigned char **src,
91 unsigned char LAST_ARG);
92
93void dump(unsigned char *buf, int len)
94{
95 int i;
96 for (i = 0; i < len;) {
97 printf(" %2x", 0xff & buf[i++]);
98 if (i % 32 == 0)
99 printf("\n");
100 }
101 printf("\n");
102}
103
104void dump_matrix(unsigned char **s, int k, int m)
105{
106 int i, j;
107 for (i = 0; i < k; i++) {
108 for (j = 0; j < m; j++) {
109 printf(" %2x", s[i][j]);
110 }
111 printf("\n");
112 }
113 printf("\n");
114}
115
116void dump_u8xu8(unsigned char *s, int k, int m)
117{
118 int i, j;
119 for (i = 0; i < k; i++) {
120 for (j = 0; j < m; j++) {
121 printf(" %2x", 0xff & s[j + (i * m)]);
122 }
123 printf("\n");
124 }
125 printf("\n");
126}
127
128int main(int argc, char *argv[])
129{
130 int i, j, rtest, srcs;
131 void *buf;
132 u8 gf[6][TEST_SOURCES];
133 u8 *g_tbls;
134 u8 *dest_ref[VECT];
135 u8 *dest_ptrs[VECT], *buffs[TEST_SOURCES];
136 int vector = VECT;
137
138 int align, size;
139 unsigned char *efence_buffs[TEST_SOURCES];
140 unsigned int offset;
141 u8 *ubuffs[TEST_SOURCES];
142 u8 *udest_ptrs[VECT];
143 printf("test" xstr(FUNCTION_UNDER_TEST) ": %dx%d ", TEST_SOURCES, TEST_LEN);
144
145 // Allocate the arrays
146 for (i = 0; i < TEST_SOURCES; i++) {
147 if (posix_memalign(&buf, 64, TEST_LEN)) {
148 printf("alloc error: Fail");
149 return -1;
150 }
151 buffs[i] = buf;
152 }
153
154 if (posix_memalign(&buf, 16, 2 * (vector * TEST_SOURCES * 32))) {
155 printf("alloc error: Fail");
156 return -1;
157 }
158 g_tbls = buf;
159
160 for (i = 0; i < vector; i++) {
161 if (posix_memalign(&buf, 64, TEST_LEN)) {
162 printf("alloc error: Fail");
163 return -1;
164 }
165 dest_ptrs[i] = buf;
166 memset(dest_ptrs[i], 0, TEST_LEN);
167 }
168
169 for (i = 0; i < vector; i++) {
170 if (posix_memalign(&buf, 64, TEST_LEN)) {
171 printf("alloc error: Fail");
172 return -1;
173 }
174 dest_ref[i] = buf;
175 memset(dest_ref[i], 0, TEST_LEN);
176 }
177
178 // Test of all zeros
179 for (i = 0; i < TEST_SOURCES; i++)
180 memset(buffs[i], 0, TEST_LEN);
181
182 switch (vector) {
183 case 6:
184 memset(gf[5], 0xe6, TEST_SOURCES);
185 case 5:
186 memset(gf[4], 4, TEST_SOURCES);
187 case 4:
188 memset(gf[3], 9, TEST_SOURCES);
189 case 3:
190 memset(gf[2], 7, TEST_SOURCES);
191 case 2:
192 memset(gf[1], 1, TEST_SOURCES);
193 case 1:
194 memset(gf[0], 2, TEST_SOURCES);
195 break;
196 default:
197 return -1;
198 }
199
200 for (i = 0; i < TEST_SOURCES; i++)
201 for (j = 0; j < TEST_LEN; j++)
202 buffs[i][j] = rand();
203
204 for (i = 0; i < vector; i++)
205 for (j = 0; j < TEST_SOURCES; j++) {
206 gf[i][j] = rand();
207 gf_vect_mul_init(gf[i][j], &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
208 }
209
210 for (i = 0; i < vector; i++)
211 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES, &g_tbls[i * 32 * TEST_SOURCES],
212 buffs, dest_ref[i]);
213
214 for (i = 0; i < vector; i++)
215 memset(dest_ptrs[i], 0, TEST_LEN);
216 for (i = 0; i < TEST_SOURCES; i++) {
217#if (VECT == 1)
218 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i], *dest_ptrs);
219#else
220 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i], dest_ptrs);
221#endif
222 }
223 for (i = 0; i < vector; i++) {
224 if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
225 printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test%d\n", i);
226 dump_matrix(buffs, vector, TEST_SOURCES);
227 printf("dprod_base:");
228 dump(dest_ref[i], 25);
229 printf("dprod_dut:");
230 dump(dest_ptrs[i], 25);
231 return -1;
232 }
233 }
234
235#if (VECT == 1)
236 REF_FUNCTION(TEST_LEN, TEST_SOURCES, g_tbls, buffs, *dest_ref);
237#else
238 REF_FUNCTION(TEST_LEN, TEST_SOURCES, g_tbls, buffs, dest_ref);
239#endif
240 for (i = 0; i < vector; i++) {
241 if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
242 printf("Fail zero " xstr(FUNCTION_UNDER_TEST) " test%d\n", i);
243 dump_matrix(buffs, vector, TEST_SOURCES);
244 printf("dprod_base:");
245 dump(dest_ref[i], 25);
246 printf("dprod_dut:");
247 dump(dest_ptrs[i], 25);
248 return -1;
249 }
250 }
251
252 putchar('.');
253
254 // Rand data test
255
256 for (rtest = 0; rtest < RANDOMS; rtest++) {
257 for (i = 0; i < TEST_SOURCES; i++)
258 for (j = 0; j < TEST_LEN; j++)
259 buffs[i][j] = rand();
260
261 for (i = 0; i < vector; i++)
262 for (j = 0; j < TEST_SOURCES; j++) {
263 gf[i][j] = rand();
264 gf_vect_mul_init(gf[i][j],
265 &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
266 }
267
268 for (i = 0; i < vector; i++)
269 gf_vect_dot_prod_base(TEST_LEN, TEST_SOURCES,
270 &g_tbls[i * 32 * TEST_SOURCES], buffs,
271 dest_ref[i]);
272
273 for (i = 0; i < vector; i++)
274 memset(dest_ptrs[i], 0, TEST_LEN);
275 for (i = 0; i < TEST_SOURCES; i++) {
276#if (VECT == 1)
277 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i],
278 *dest_ptrs);
279#else
280 FUNCTION_UNDER_TEST(TEST_LEN, TEST_SOURCES, i, g_tbls, buffs[i],
281 dest_ptrs);
282#endif
283 }
284 for (i = 0; i < vector; i++) {
285 if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
286 printf("Fail rand " xstr(FUNCTION_UNDER_TEST) " test%d %d\n",
287 i, rtest);
288 dump_matrix(buffs, vector, TEST_SOURCES);
289 printf("dprod_base:");
290 dump(dest_ref[i], 25);
291 printf("dprod_dut:");
292 dump(dest_ptrs[i], 25);
293 return -1;
294 }
295 }
296
297 putchar('.');
298 }
299
300 // Rand data test with varied parameters
301 for (rtest = 0; rtest < RANDOMS; rtest++) {
302 for (srcs = TEST_SOURCES; srcs > 0; srcs--) {
303 for (i = 0; i < srcs; i++)
304 for (j = 0; j < TEST_LEN; j++)
305 buffs[i][j] = rand();
306
307 for (i = 0; i < vector; i++)
308 for (j = 0; j < srcs; j++) {
309 gf[i][j] = rand();
310 gf_vect_mul_init(gf[i][j],
311 &g_tbls[i * (32 * srcs) + j * 32]);
312 }
313
314 for (i = 0; i < vector; i++)
315 gf_vect_dot_prod_base(TEST_LEN, srcs, &g_tbls[i * 32 * srcs],
316 buffs, dest_ref[i]);
317
318 for (i = 0; i < vector; i++)
319 memset(dest_ptrs[i], 0, TEST_LEN);
320 for (i = 0; i < srcs; i++) {
321#if (VECT == 1)
322 FUNCTION_UNDER_TEST(TEST_LEN, srcs, i, g_tbls, buffs[i],
323 *dest_ptrs);
324#else
325 FUNCTION_UNDER_TEST(TEST_LEN, srcs, i, g_tbls, buffs[i],
326 dest_ptrs);
327#endif
328
329 }
330 for (i = 0; i < vector; i++) {
331 if (0 != memcmp(dest_ref[i], dest_ptrs[i], TEST_LEN)) {
332 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
333 " test%d srcs=%d\n", i, srcs);
334 dump_matrix(buffs, vector, TEST_SOURCES);
335 printf("dprod_base:");
336 dump(dest_ref[i], 25);
337 printf("dprod_dut:");
338 dump(dest_ptrs[i], 25);
339 return -1;
340 }
341 }
342
343 putchar('.');
344 }
345 }
346
347 // Run tests at end of buffer for Electric Fence
348 align = (LEN_ALIGN_CHK_B != 0) ? 1 : ALIGN_SIZE;
349 for (size = TEST_MIN_SIZE; size <= TEST_SIZE; size += align) {
350 for (i = 0; i < TEST_SOURCES; i++)
351 for (j = 0; j < TEST_LEN; j++)
352 buffs[i][j] = rand();
353
354 for (i = 0; i < TEST_SOURCES; i++) // Line up TEST_SIZE from end
355 efence_buffs[i] = buffs[i] + TEST_LEN - size;
356
357 for (i = 0; i < vector; i++)
358 for (j = 0; j < TEST_SOURCES; j++) {
359 gf[i][j] = rand();
360 gf_vect_mul_init(gf[i][j],
361 &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
362 }
363
364 for (i = 0; i < vector; i++)
365 gf_vect_dot_prod_base(size, TEST_SOURCES,
366 &g_tbls[i * 32 * TEST_SOURCES], efence_buffs,
367 dest_ref[i]);
368
369 for (i = 0; i < vector; i++)
370 memset(dest_ptrs[i], 0, size);
371 for (i = 0; i < TEST_SOURCES; i++) {
372#if (VECT == 1)
373 FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, efence_buffs[i],
374 *dest_ptrs);
375#else
376 FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, efence_buffs[i],
377 dest_ptrs);
378#endif
379 }
380 for (i = 0; i < vector; i++) {
381 if (0 != memcmp(dest_ref[i], dest_ptrs[i], size)) {
382 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
383 " test%d size=%d\n", i, size);
384 dump_matrix(buffs, vector, TEST_SOURCES);
385 printf("dprod_base:");
386 dump(dest_ref[i], TEST_MIN_SIZE + align);
387 printf("dprod_dut:");
388 dump(dest_ptrs[i], TEST_MIN_SIZE + align);
389 return -1;
390 }
391 }
392
393 putchar('.');
394 }
395
396 // Test rand ptr alignment if available
397
398 for (rtest = 0; rtest < RANDOMS; rtest++) {
399 size = (TEST_LEN - PTR_ALIGN_CHK_B) & ~(TEST_MIN_SIZE - 1);
400 srcs = rand() % TEST_SOURCES;
401 if (srcs == 0)
402 continue;
403
404 offset = (PTR_ALIGN_CHK_B != 0) ? 1 : PTR_ALIGN_CHK_B;
405 // Add random offsets
406 for (i = 0; i < srcs; i++)
407 ubuffs[i] = buffs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
408
409 for (i = 0; i < vector; i++) {
410 udest_ptrs[i] = dest_ptrs[i] + (rand() & (PTR_ALIGN_CHK_B - offset));
411 memset(dest_ptrs[i], 0, TEST_LEN); // zero pad to check write-over
412 }
413
414 for (i = 0; i < srcs; i++)
415 for (j = 0; j < size; j++)
416 ubuffs[i][j] = rand();
417
418 for (i = 0; i < vector; i++)
419 for (j = 0; j < srcs; j++) {
420 gf[i][j] = rand();
421 gf_vect_mul_init(gf[i][j], &g_tbls[i * (32 * srcs) + j * 32]);
422 }
423
424 for (i = 0; i < vector; i++)
425 gf_vect_dot_prod_base(size, srcs, &g_tbls[i * 32 * srcs], ubuffs,
426 dest_ref[i]);
427
428 for (i = 0; i < srcs; i++) {
429#if (VECT == 1)
430 FUNCTION_UNDER_TEST(size, srcs, i, g_tbls, ubuffs[i], *udest_ptrs);
431#else
432 FUNCTION_UNDER_TEST(size, srcs, i, g_tbls, ubuffs[i], udest_ptrs);
433#endif
434 }
435 for (i = 0; i < vector; i++) {
436 if (0 != memcmp(dest_ref[i], udest_ptrs[i], size)) {
437 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
438 " test%d ualign srcs=%d\n", i, srcs);
439 dump_matrix(buffs, vector, TEST_SOURCES);
440 printf("dprod_base:");
441 dump(dest_ref[i], 25);
442 printf("dprod_dut:");
443 dump(udest_ptrs[i], 25);
444 return -1;
445 }
446 }
447
448 // Confirm that padding around dests is unchanged
449 memset(dest_ref[0], 0, PTR_ALIGN_CHK_B); // Make reference zero buff
450
451 for (i = 0; i < vector; i++) {
452 offset = udest_ptrs[i] - dest_ptrs[i];
453 if (memcmp(dest_ptrs[i], dest_ref[0], offset)) {
454 printf("Fail rand ualign pad1 start\n");
455 return -1;
456 }
457 if (memcmp
458 (dest_ptrs[i] + offset + size, dest_ref[0],
459 PTR_ALIGN_CHK_B - offset)) {
460 printf("Fail rand ualign pad1 end\n");
461 return -1;
462 }
463 }
464
465 putchar('.');
466 }
467
468 // Test all size alignment
469 align = (LEN_ALIGN_CHK_B != 0) ? 1 : ALIGN_SIZE;
470
471 for (size = TEST_LEN; size >= TEST_MIN_SIZE; size -= align) {
472 for (i = 0; i < TEST_SOURCES; i++)
473 for (j = 0; j < size; j++)
474 buffs[i][j] = rand();
475
476 for (i = 0; i < vector; i++) {
477 for (j = 0; j < TEST_SOURCES; j++) {
478 gf[i][j] = rand();
479 gf_vect_mul_init(gf[i][j],
480 &g_tbls[i * (32 * TEST_SOURCES) + j * 32]);
481 }
482 memset(dest_ptrs[i], 0, TEST_LEN); // zero pad to check write-over
483 }
484
485 for (i = 0; i < vector; i++)
486 gf_vect_dot_prod_base(size, TEST_SOURCES,
487 &g_tbls[i * 32 * TEST_SOURCES], buffs,
488 dest_ref[i]);
489
490 for (i = 0; i < TEST_SOURCES; i++) {
491#if (VECT == 1)
492 FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, buffs[i],
493 *dest_ptrs);
494#else
495 FUNCTION_UNDER_TEST(size, TEST_SOURCES, i, g_tbls, buffs[i],
496 dest_ptrs);
497#endif
498 }
499 for (i = 0; i < vector; i++) {
500 if (0 != memcmp(dest_ref[i], dest_ptrs[i], size)) {
501 printf("Fail rand " xstr(FUNCTION_UNDER_TEST)
502 " test%d ualign len=%d\n", i, size);
503 dump_matrix(buffs, vector, TEST_SOURCES);
504 printf("dprod_base:");
505 dump(dest_ref[i], 25);
506 printf("dprod_dut:");
507 dump(dest_ptrs[i], 25);
508 return -1;
509 }
510 }
511
512 putchar('.');
513
514 }
515
516 printf("Pass\n");
517 return 0;
518
519}