]>
git.proxmox.com Git - ceph.git/blob - ceph/src/spdk/isa-l/erasure_code/erasure_code_base_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"
37 #define TEST_SIZE (TEST_LEN/2)
40 # define TEST_SOURCES 127
46 #define MMAX TEST_SOURCES
47 #define KMAX TEST_SOURCES
49 #define EFENCE_TEST_MIN_SIZE 16
51 #ifdef EC_ALIGNED_ADDR
52 // Define power of 2 range to check ptr, len alignment
53 # define PTR_ALIGN_CHK_B 0
54 # define LEN_ALIGN_CHK_B 0 // 0 for aligned only
56 // Define power of 2 range to check ptr, len alignment
57 # define PTR_ALIGN_CHK_B 32
58 # define LEN_ALIGN_CHK_B 32 // 0 for aligned only
65 typedef unsigned char u8
;
67 void dump(unsigned char *buf
, int len
)
70 for (i
= 0; i
< len
;) {
71 printf(" %2x", 0xff & buf
[i
++]);
78 void dump_matrix(unsigned char **s
, int k
, int m
)
81 for (i
= 0; i
< k
; i
++) {
82 for (j
= 0; j
< m
; j
++) {
83 printf(" %2x", s
[i
][j
]);
90 void dump_u8xu8(unsigned char *s
, int k
, int m
)
93 for (i
= 0; i
< k
; i
++) {
94 for (j
= 0; j
< m
; j
++) {
95 printf(" %2x", 0xff & s
[j
+ (i
* m
)]);
102 // Generate Random errors
103 static void gen_err_list(unsigned char *src_err_list
,
104 unsigned char *src_in_err
, int *pnerrs
, int *pnsrcerrs
, int k
, int m
)
107 int nerrs
= 0, nsrcerrs
= 0;
109 for (i
= 0, nerrs
= 0, nsrcerrs
= 0; i
< m
&& nerrs
< m
- k
; i
++) {
113 src_err_list
[nerrs
++] = i
;
119 if (nerrs
== 0) { // should have at least one error
120 while ((err
= (rand() % KMAX
)) >= m
) ;
121 src_err_list
[nerrs
++] = err
;
127 *pnsrcerrs
= nsrcerrs
;
131 #define NO_INVERT_MATRIX -2
132 // Generate decode matrix from encode matrix
133 static int gf_gen_decode_matrix(unsigned char *encode_matrix
,
134 unsigned char *decode_matrix
,
135 unsigned char *invert_matrix
,
136 unsigned int *decode_index
,
137 unsigned char *src_err_list
,
138 unsigned char *src_in_err
,
139 int nerrs
, int nsrcerrs
, int k
, int m
)
143 unsigned char *backup
, *b
, s
;
146 b
= malloc(MMAX
* KMAX
);
147 backup
= malloc(MMAX
* KMAX
);
149 if (b
== NULL
|| backup
== NULL
) {
150 printf("Test failure! Error with malloc\n");
155 // Construct matrix b by removing error rows
156 for (i
= 0, r
= 0; i
< k
; i
++, r
++) {
157 while (src_in_err
[r
])
159 for (j
= 0; j
< k
; j
++) {
160 b
[k
* i
+ j
] = encode_matrix
[k
* r
+ j
];
161 backup
[k
* i
+ j
] = encode_matrix
[k
* r
+ j
];
166 while (gf_invert_matrix(b
, invert_matrix
, k
) < 0) {
167 if (nerrs
== (m
- k
)) {
170 printf("BAD MATRIX\n");
171 return NO_INVERT_MATRIX
;
174 memcpy(b
, backup
, MMAX
* KMAX
);
175 for (i
= nsrcerrs
; i
< nerrs
- nsrcerrs
; i
++) {
176 if (src_err_list
[i
] == (decode_index
[k
- 1] + incr
)) {
177 // skip the erased parity line
182 if (decode_index
[k
- 1] + incr
>= m
) {
185 printf("BAD MATRIX\n");
186 return NO_INVERT_MATRIX
;
188 decode_index
[k
- 1] += incr
;
189 for (j
= 0; j
< k
; j
++)
190 b
[k
* (k
- 1) + j
] = encode_matrix
[k
* decode_index
[k
- 1] + j
];
194 for (i
= 0; i
< nsrcerrs
; i
++) {
195 for (j
= 0; j
< k
; j
++) {
196 decode_matrix
[k
* i
+ j
] = invert_matrix
[k
* src_err_list
[i
] + j
];
199 /* src_err_list from encode_matrix * invert of b for parity decoding */
200 for (p
= nsrcerrs
; p
< nerrs
; p
++) {
201 for (i
= 0; i
< k
; i
++) {
203 for (j
= 0; j
< k
; j
++)
204 s
^= gf_mul(invert_matrix
[j
* k
+ i
],
205 encode_matrix
[k
* src_err_list
[p
] + j
]);
207 decode_matrix
[k
* p
+ i
] = s
;
215 int main(int argc
, char *argv
[])
218 int i
, j
, p
, rtest
, m
, k
;
221 unsigned int decode_index
[MMAX
];
222 unsigned char *temp_buffs
[TEST_SOURCES
], *buffs
[TEST_SOURCES
];
223 unsigned char *encode_matrix
, *decode_matrix
, *invert_matrix
, *g_tbls
;
224 unsigned char src_in_err
[TEST_SOURCES
], src_err_list
[TEST_SOURCES
];
225 unsigned char *recov
[TEST_SOURCES
];
227 int rows
, align
, size
;
228 unsigned char *efence_buffs
[TEST_SOURCES
];
230 u8
*ubuffs
[TEST_SOURCES
];
231 u8
*temp_ubuffs
[TEST_SOURCES
];
233 printf("erasure_code_base_test: %dx%d ", TEST_SOURCES
, TEST_LEN
);
236 // Allocate the arrays
237 for (i
= 0; i
< TEST_SOURCES
; i
++) {
238 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
239 printf("alloc error: Fail");
245 for (i
= 0; i
< TEST_SOURCES
; i
++) {
246 if (posix_memalign(&buf
, 64, TEST_LEN
)) {
247 printf("alloc error: Fail");
253 // Test erasure code by encode and recovery
255 encode_matrix
= malloc(MMAX
* KMAX
);
256 decode_matrix
= malloc(MMAX
* KMAX
);
257 invert_matrix
= malloc(MMAX
* KMAX
);
258 g_tbls
= malloc(KMAX
* TEST_SOURCES
* 32);
259 if (encode_matrix
== NULL
|| decode_matrix
== NULL
260 || invert_matrix
== NULL
|| g_tbls
== NULL
) {
261 printf("Test failure! Error with malloc\n");
267 if (m
> MMAX
|| k
> KMAX
)
271 for (i
= 0; i
< k
; i
++)
272 for (j
= 0; j
< TEST_LEN
; j
++)
273 buffs
[i
][j
] = rand();
275 // Generate encode matrix encode_matrix
276 // The matrix generated by gf_gen_rs_matrix
277 // is not always invertable.
278 gf_gen_rs_matrix(encode_matrix
, m
, k
);
280 // Generate g_tbls from encode matrix encode_matrix
281 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
283 // Perform matrix dot_prod for EC encoding
284 // using g_tbls from encode matrix encode_matrix
285 ec_encode_data_base(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
287 // Choose random buffers to be in erasure
288 memset(src_in_err
, 0, TEST_SOURCES
);
289 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
291 // Generate decode matrix
292 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
293 invert_matrix
, decode_index
, src_err_list
, src_in_err
,
294 nerrs
, nsrcerrs
, k
, m
);
296 printf("Fail to gf_gen_decode_matrix\n");
299 // Pack recovery array as list of valid sources
300 // Its order must be the same as the order
301 // to generate matrix b in gf_gen_decode_matrix
302 for (i
= 0; i
< k
; i
++) {
303 recov
[i
] = buffs
[decode_index
[i
]];
307 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
308 ec_encode_data_base(TEST_LEN
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
309 for (i
= 0; i
< nerrs
; i
++) {
311 if (0 != memcmp(temp_buffs
[k
+ i
], buffs
[src_err_list
[i
]], TEST_LEN
)) {
312 printf("Fail error recovery (%d, %d, %d)\n", m
, k
, nerrs
);
313 printf(" - erase list = ");
314 for (j
= 0; j
< nerrs
; j
++)
315 printf(" %d", src_err_list
[j
]);
316 printf(" - Index = ");
317 for (p
= 0; p
< k
; p
++)
318 printf(" %d", decode_index
[p
]);
319 printf("\nencode_matrix:\n");
320 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
322 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
323 printf("\ndecode_matrix:\n");
324 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
325 printf("recov %d:", src_err_list
[i
]);
326 dump(temp_buffs
[k
+ i
], 25);
328 dump(buffs
[src_err_list
[i
]], 25);
336 if (m
> MMAX
|| k
> KMAX
)
340 for (i
= 0; i
< k
; i
++)
341 for (j
= 0; j
< TEST_LEN
; j
++)
342 buffs
[i
][j
] = rand();
344 // The matrix generated by gf_gen_cauchy1_matrix
345 // is always invertable.
346 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
348 // Generate g_tbls from encode matrix encode_matrix
349 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
351 // Perform matrix dot_prod for EC encoding
352 // using g_tbls from encode matrix encode_matrix
353 ec_encode_data_base(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
355 // Choose random buffers to be in erasure
356 memset(src_in_err
, 0, TEST_SOURCES
);
357 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
359 // Generate decode matrix
360 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
361 invert_matrix
, decode_index
, src_err_list
, src_in_err
,
362 nerrs
, nsrcerrs
, k
, m
);
364 printf("Fail to gf_gen_decode_matrix\n");
367 // Pack recovery array as list of valid sources
368 // Its order must be the same as the order
369 // to generate matrix b in gf_gen_decode_matrix
370 for (i
= 0; i
< k
; i
++) {
371 recov
[i
] = buffs
[decode_index
[i
]];
375 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
376 ec_encode_data_base(TEST_LEN
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
377 for (i
= 0; i
< nerrs
; i
++) {
379 if (0 != memcmp(temp_buffs
[k
+ i
], buffs
[src_err_list
[i
]], TEST_LEN
)) {
380 printf("Fail error recovery (%d, %d, %d)\n", m
, k
, nerrs
);
381 printf(" - erase list = ");
382 for (j
= 0; j
< nerrs
; j
++)
383 printf(" %d", src_err_list
[j
]);
384 printf(" - Index = ");
385 for (p
= 0; p
< k
; p
++)
386 printf(" %d", decode_index
[p
]);
387 printf("\nencode_matrix:\n");
388 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
390 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
391 printf("\ndecode_matrix:\n");
392 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
393 printf("recov %d:", src_err_list
[i
]);
394 dump(temp_buffs
[k
+ i
], 25);
396 dump(buffs
[src_err_list
[i
]], 25);
401 // Do more random tests
402 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
403 while ((m
= (rand() % MMAX
)) < 2) ;
404 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
406 if (m
> MMAX
|| k
> KMAX
)
410 for (i
= 0; i
< k
; i
++)
411 for (j
= 0; j
< TEST_LEN
; j
++)
412 buffs
[i
][j
] = rand();
414 // The matrix generated by gf_gen_cauchy1_matrix
415 // is always invertable.
416 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
419 // Generate g_tbls from encode matrix a
420 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
421 // Perform matrix dot_prod for EC encoding
422 // using g_tbls from encode matrix a
423 ec_encode_data_base(TEST_LEN
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
426 memset(src_in_err
, 0, TEST_SOURCES
);
427 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
429 // Generate decode matrix
430 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
431 invert_matrix
, decode_index
, src_err_list
,
432 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
434 printf("Fail to gf_gen_decode_matrix\n");
437 // Pack recovery array as list of valid sources
438 // Its order must be the same as the order
439 // to generate matrix b in gf_gen_decode_matrix
440 for (i
= 0; i
< k
; i
++) {
441 recov
[i
] = buffs
[decode_index
[i
]];
445 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
446 ec_encode_data_base(TEST_LEN
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
448 for (i
= 0; i
< nerrs
; i
++) {
450 if (0 != memcmp(temp_buffs
[k
+ i
], buffs
[src_err_list
[i
]], TEST_LEN
)) {
451 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
452 printf(" - erase list = ");
453 for (j
= 0; j
< nerrs
; j
++)
454 printf(" %d", src_err_list
[j
]);
455 printf(" - Index = ");
456 for (p
= 0; p
< k
; p
++)
457 printf(" %d", decode_index
[p
]);
458 printf("\nencode_matrix:\n");
459 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
461 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
462 printf("\ndecode_matrix:\n");
463 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
464 printf("orig data:\n");
465 dump_matrix(buffs
, m
, 25);
467 dump(buffs
[src_err_list
[i
]], 25);
468 printf("recov %d:", src_err_list
[i
]);
469 dump(temp_buffs
[k
+ i
], 25);
476 // Run tests at end of buffer for Electric Fence
478 align
= (LEN_ALIGN_CHK_B
!= 0) ? 1 : 16;
482 for (rows
= 1; rows
<= 16; rows
++) {
488 for (i
= 0; i
< k
; i
++)
489 for (j
= 0; j
< TEST_LEN
; j
++)
490 buffs
[i
][j
] = rand();
492 for (size
= EFENCE_TEST_MIN_SIZE
; size
<= TEST_SIZE
; size
+= align
) {
493 for (i
= 0; i
< m
; i
++) { // Line up TEST_SIZE from end
494 efence_buffs
[i
] = buffs
[i
] + TEST_LEN
- size
;
497 // The matrix generated by gf_gen_cauchy1_matrix
498 // is always invertable.
499 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
502 // Generate g_tbls from encode matrix a
503 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
504 // Perform matrix dot_prod for EC encoding
505 // using g_tbls from encode matrix a
506 ec_encode_data_base(size
, k
, m
- k
, g_tbls
, efence_buffs
,
510 memset(src_in_err
, 0, TEST_SOURCES
);
511 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
513 // Generate decode matrix
514 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
515 invert_matrix
, decode_index
, src_err_list
,
516 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
518 printf("Fail to gf_gen_decode_matrix\n");
521 // Pack recovery array as list of valid sources
522 // Its order must be the same as the order
523 // to generate matrix b in gf_gen_decode_matrix
524 for (i
= 0; i
< k
; i
++) {
525 recov
[i
] = efence_buffs
[decode_index
[i
]];
529 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
530 ec_encode_data_base(size
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
532 for (i
= 0; i
< nerrs
; i
++) {
535 memcmp(temp_buffs
[k
+ i
], efence_buffs
[src_err_list
[i
]],
537 printf("Efence: Fail error recovery (%d, %d, %d)\n", m
,
540 printf("size = %d\n", size
);
542 printf("Test erase list = ");
543 for (j
= 0; j
< nerrs
; j
++)
544 printf(" %d", src_err_list
[j
]);
545 printf(" - Index = ");
546 for (p
= 0; p
< k
; p
++)
547 printf(" %d", decode_index
[p
]);
548 printf("\nencode_matrix:\n");
549 dump_u8xu8((u8
*) encode_matrix
, m
, k
);
551 dump_u8xu8((u8
*) invert_matrix
, k
, k
);
552 printf("\ndecode_matrix:\n");
553 dump_u8xu8((u8
*) decode_matrix
, m
, k
);
555 printf("recov %d:", src_err_list
[i
]);
556 dump(temp_buffs
[k
+ i
], align
);
558 dump(efence_buffs
[src_err_list
[i
]], align
);
566 // Test rand ptr alignment if available
568 for (rtest
= 0; rtest
< RANDOMS
; rtest
++) {
569 while ((m
= (rand() % MMAX
)) < 2) ;
570 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
572 if (m
> MMAX
|| k
> KMAX
)
575 size
= (TEST_LEN
- PTR_ALIGN_CHK_B
) & ~15;
577 offset
= (PTR_ALIGN_CHK_B
!= 0) ? 1 : PTR_ALIGN_CHK_B
;
578 // Add random offsets
579 for (i
= 0; i
< m
; i
++) {
580 memset(buffs
[i
], 0, TEST_LEN
); // zero pad to check write-over
581 memset(temp_buffs
[i
], 0, TEST_LEN
); // zero pad to check write-over
582 ubuffs
[i
] = buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
583 temp_ubuffs
[i
] = temp_buffs
[i
] + (rand() & (PTR_ALIGN_CHK_B
- offset
));
586 for (i
= 0; i
< k
; i
++)
587 for (j
= 0; j
< size
; j
++)
588 ubuffs
[i
][j
] = rand();
590 // The matrix generated by gf_gen_cauchy1_matrix
591 // is always invertable.
592 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
595 // Generate g_tbls from encode matrix a
596 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
597 // Perform matrix dot_prod for EC encoding
598 // using g_tbls from encode matrix a
599 ec_encode_data_base(size
, k
, m
- k
, g_tbls
, ubuffs
, &ubuffs
[k
]);
602 memset(src_in_err
, 0, TEST_SOURCES
);
603 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
605 // Generate decode matrix
606 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
607 invert_matrix
, decode_index
, src_err_list
,
608 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
610 printf("Fail to gf_gen_decode_matrix\n");
613 // Pack recovery array as list of valid sources
614 // Its order must be the same as the order
615 // to generate matrix b in gf_gen_decode_matrix
616 for (i
= 0; i
< k
; i
++) {
617 recov
[i
] = ubuffs
[decode_index
[i
]];
621 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
622 ec_encode_data_base(size
, k
, nerrs
, g_tbls
, recov
, &temp_ubuffs
[k
]);
624 for (i
= 0; i
< nerrs
; i
++) {
626 if (0 != memcmp(temp_ubuffs
[k
+ i
], ubuffs
[src_err_list
[i
]], size
)) {
627 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
628 printf(" - erase list = ");
629 for (j
= 0; j
< nerrs
; j
++)
630 printf(" %d", src_err_list
[j
]);
631 printf(" - Index = ");
632 for (p
= 0; p
< k
; p
++)
633 printf(" %d", decode_index
[p
]);
634 printf("\nencode_matrix:\n");
635 dump_u8xu8((unsigned char *)encode_matrix
, m
, k
);
637 dump_u8xu8((unsigned char *)invert_matrix
, k
, k
);
638 printf("\ndecode_matrix:\n");
639 dump_u8xu8((unsigned char *)decode_matrix
, m
, k
);
640 printf("orig data:\n");
641 dump_matrix(ubuffs
, m
, 25);
643 dump(ubuffs
[src_err_list
[i
]], 25);
644 printf("recov %d:", src_err_list
[i
]);
645 dump(temp_ubuffs
[k
+ i
], 25);
650 // Confirm that padding around dests is unchanged
651 memset(temp_buffs
[0], 0, PTR_ALIGN_CHK_B
); // Make reference zero buff
653 for (i
= 0; i
< m
; i
++) {
655 offset
= ubuffs
[i
] - buffs
[i
];
657 if (memcmp(buffs
[i
], temp_buffs
[0], offset
)) {
658 printf("Fail rand ualign encode pad start\n");
662 (buffs
[i
] + offset
+ size
, temp_buffs
[0],
663 PTR_ALIGN_CHK_B
- offset
)) {
664 printf("Fail rand ualign encode pad end\n");
669 for (i
= 0; i
< nerrs
; i
++) {
671 offset
= temp_ubuffs
[k
+ i
] - temp_buffs
[k
+ i
];
672 if (memcmp(temp_buffs
[k
+ i
], temp_buffs
[0], offset
)) {
673 printf("Fail rand ualign decode pad start\n");
677 (temp_buffs
[k
+ i
] + offset
+ size
, temp_buffs
[0],
678 PTR_ALIGN_CHK_B
- offset
)) {
679 printf("Fail rand ualign decode pad end\n");
687 // Test size alignment
689 align
= (LEN_ALIGN_CHK_B
!= 0) ? 13 : 16;
691 for (size
= TEST_LEN
; size
> 0; size
-= align
) {
692 while ((m
= (rand() % MMAX
)) < 2) ;
693 while ((k
= (rand() % KMAX
)) >= m
|| k
< 1) ;
695 if (m
> MMAX
|| k
> KMAX
)
698 for (i
= 0; i
< k
; i
++)
699 for (j
= 0; j
< size
; j
++)
700 buffs
[i
][j
] = rand();
702 // The matrix generated by gf_gen_cauchy1_matrix
703 // is always invertable.
704 gf_gen_cauchy1_matrix(encode_matrix
, m
, k
);
707 // Generate g_tbls from encode matrix a
708 ec_init_tables(k
, m
- k
, &encode_matrix
[k
* k
], g_tbls
);
709 // Perform matrix dot_prod for EC encoding
710 // using g_tbls from encode matrix a
711 ec_encode_data_base(size
, k
, m
- k
, g_tbls
, buffs
, &buffs
[k
]);
714 memset(src_in_err
, 0, TEST_SOURCES
);
715 gen_err_list(src_err_list
, src_in_err
, &nerrs
, &nsrcerrs
, k
, m
);
716 // Generate decode matrix
717 re
= gf_gen_decode_matrix(encode_matrix
, decode_matrix
,
718 invert_matrix
, decode_index
, src_err_list
,
719 src_in_err
, nerrs
, nsrcerrs
, k
, m
);
721 printf("Fail to gf_gen_decode_matrix\n");
724 // Pack recovery array as list of valid sources
725 // Its order must be the same as the order
726 // to generate matrix b in gf_gen_decode_matrix
727 for (i
= 0; i
< k
; i
++) {
728 recov
[i
] = buffs
[decode_index
[i
]];
732 ec_init_tables(k
, nerrs
, decode_matrix
, g_tbls
);
733 ec_encode_data_base(size
, k
, nerrs
, g_tbls
, recov
, &temp_buffs
[k
]);
735 for (i
= 0; i
< nerrs
; i
++) {
737 if (0 != memcmp(temp_buffs
[k
+ i
], buffs
[src_err_list
[i
]], size
)) {
738 printf("Fail error recovery (%d, %d, %d) - ", m
, k
, nerrs
);
739 printf(" - erase list = ");
740 for (j
= 0; j
< nerrs
; j
++)
741 printf(" %d", src_err_list
[j
]);
742 printf(" - Index = ");
743 for (p
= 0; p
< k
; p
++)
744 printf(" %d", decode_index
[p
]);
745 printf("\nencode_matrix:\n");
746 dump_u8xu8((unsigned char *)encode_matrix
, m
, k
);
748 dump_u8xu8((unsigned char *)invert_matrix
, k
, k
);
749 printf("\ndecode_matrix:\n");
750 dump_u8xu8((unsigned char *)decode_matrix
, m
, k
);
751 printf("orig data:\n");
752 dump_matrix(buffs
, m
, 25);
754 dump(buffs
[src_err_list
[i
]], 25);
755 printf("recov %d:", src_err_list
[i
]);
756 dump(temp_buffs
[k
+ i
], 25);
762 printf("done EC tests: Pass\n");