]>
Commit | Line | Data |
---|---|---|
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 | #include "test.h" | |
36 | ||
37 | //By default, test multibinary version | |
38 | #ifndef FUNCTION_UNDER_TEST | |
39 | # define FUNCTION_UNDER_TEST ec_encode_data_update | |
40 | # define REF_FUNCTION ec_encode_data | |
41 | #endif | |
42 | ||
43 | //By default, test EC(8+4) | |
44 | #if (!defined(VECT)) | |
45 | # define VECT 4 | |
46 | #endif | |
47 | ||
48 | #define str(s) #s | |
49 | #define xstr(s) str(s) | |
50 | ||
51 | //#define CACHED_TEST | |
52 | #ifdef CACHED_TEST | |
53 | // Cached test, loop many times over small dataset | |
54 | # define TEST_SOURCES 32 | |
55 | # define TEST_LEN(m) ((128*1024 / m) & ~(64-1)) | |
7c673cae FG |
56 | # define TEST_TYPE_STR "_warm" |
57 | #else | |
58 | # ifndef TEST_CUSTOM | |
59 | // Uncached test. Pull from large mem base. | |
60 | # define TEST_SOURCES 32 | |
61 | # define GT_L3_CACHE 32*1024*1024 /* some number > last level cache */ | |
62 | # define TEST_LEN(m) ((GT_L3_CACHE / m) & ~(64-1)) | |
7c673cae FG |
63 | # define TEST_TYPE_STR "_cold" |
64 | # else | |
65 | # define TEST_TYPE_STR "_cus" | |
7c673cae FG |
66 | # endif |
67 | #endif | |
68 | ||
69 | #define MMAX TEST_SOURCES | |
70 | #define KMAX TEST_SOURCES | |
71 | ||
72 | typedef unsigned char u8; | |
73 | ||
74 | void 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 | ||
f91f0fd5 TL |
85 | void encode_update_test_ref(int m, int k, u8 * g_tbls, u8 ** buffs, u8 * a) |
86 | { | |
87 | ec_init_tables(k, m - k, &a[k * k], g_tbls); | |
88 | REF_FUNCTION(TEST_LEN(m), k, m - k, g_tbls, buffs, &buffs[k]); | |
89 | } | |
90 | ||
91 | void encode_update_test(int m, int k, u8 * g_tbls, u8 ** perf_update_buffs, u8 * a) | |
92 | { | |
93 | int i; | |
94 | ||
95 | // Make parity vects | |
96 | ec_init_tables(k, m - k, &a[k * k], g_tbls); | |
97 | for (i = 0; i < k; i++) { | |
98 | FUNCTION_UNDER_TEST(TEST_LEN(m), k, m - k, i, g_tbls, | |
99 | perf_update_buffs[i], &perf_update_buffs[k]); | |
100 | } | |
101 | } | |
102 | ||
103 | int decode_test(int m, int k, u8 ** update_buffs, u8 ** recov, u8 * a, u8 * src_in_err, | |
104 | u8 * src_err_list, int nerrs, u8 * g_tbls, u8 ** perf_update_buffs) | |
105 | { | |
106 | int i, j, r; | |
107 | u8 b[MMAX * KMAX], c[MMAX * KMAX], d[MMAX * KMAX]; | |
108 | // Construct b by removing error rows | |
109 | for (i = 0, r = 0; i < k; i++, r++) { | |
110 | while (src_in_err[r]) | |
111 | r++; | |
112 | recov[i] = update_buffs[r]; | |
113 | for (j = 0; j < k; j++) | |
114 | b[k * i + j] = a[k * r + j]; | |
115 | } | |
116 | ||
117 | if (gf_invert_matrix(b, d, k) < 0) { | |
118 | printf("BAD MATRIX\n"); | |
119 | return -1; | |
120 | } | |
121 | ||
122 | for (i = 0; i < nerrs; i++) | |
123 | for (j = 0; j < k; j++) | |
124 | c[k * i + j] = d[k * src_err_list[i] + j]; | |
125 | ||
126 | // Recover data | |
127 | ec_init_tables(k, nerrs, c, g_tbls); | |
128 | for (i = 0; i < k; i++) { | |
129 | FUNCTION_UNDER_TEST(TEST_LEN(m), k, nerrs, i, g_tbls, recov[i], | |
130 | perf_update_buffs); | |
131 | } | |
132 | return 0; | |
133 | } | |
134 | ||
7c673cae FG |
135 | int main(int argc, char *argv[]) |
136 | { | |
f91f0fd5 | 137 | int i, j, check, m, k, nerrs; |
7c673cae FG |
138 | void *buf; |
139 | u8 *temp_buffs[TEST_SOURCES], *buffs[TEST_SOURCES]; | |
140 | u8 *update_buffs[TEST_SOURCES]; | |
141 | u8 *perf_update_buffs[TEST_SOURCES]; | |
f91f0fd5 | 142 | u8 a[MMAX * KMAX]; |
7c673cae FG |
143 | u8 g_tbls[KMAX * TEST_SOURCES * 32], src_in_err[TEST_SOURCES]; |
144 | u8 src_err_list[TEST_SOURCES], *recov[TEST_SOURCES]; | |
f91f0fd5 | 145 | struct perf start; |
7c673cae FG |
146 | |
147 | // Pick test parameters | |
148 | k = 10; | |
149 | m = k + VECT; | |
150 | nerrs = VECT; | |
151 | const u8 err_list[] = { 0, 2, 4, 5, 7, 8 }; | |
152 | ||
153 | printf(xstr(FUNCTION_UNDER_TEST) "_perf: %dx%d %d\n", m, TEST_LEN(m), nerrs); | |
154 | ||
155 | if (m > MMAX || k > KMAX || nerrs > (m - k)) { | |
156 | printf(" Input test parameter error\n"); | |
157 | return -1; | |
158 | } | |
159 | ||
160 | memcpy(src_err_list, err_list, nerrs); | |
161 | memset(src_in_err, 0, TEST_SOURCES); | |
162 | for (i = 0; i < nerrs; i++) | |
163 | src_in_err[src_err_list[i]] = 1; | |
164 | ||
165 | // Allocate the arrays | |
166 | for (i = 0; i < m; i++) { | |
167 | if (posix_memalign(&buf, 64, TEST_LEN(m))) { | |
168 | printf("alloc error: Fail\n"); | |
169 | return -1; | |
170 | } | |
171 | buffs[i] = buf; | |
172 | } | |
173 | ||
174 | for (i = 0; i < (m - k); i++) { | |
175 | if (posix_memalign(&buf, 64, TEST_LEN(m))) { | |
176 | printf("alloc error: Fail\n"); | |
177 | return -1; | |
178 | } | |
179 | temp_buffs[i] = buf; | |
180 | memset(temp_buffs[i], 0, TEST_LEN(m)); // initialize the destination buffer to be zero for update function | |
181 | } | |
182 | ||
183 | for (i = 0; i < TEST_SOURCES; i++) { | |
184 | if (posix_memalign(&buf, 64, TEST_LEN(m))) { | |
185 | printf("alloc error: Fail"); | |
186 | return -1; | |
187 | } | |
188 | update_buffs[i] = buf; | |
189 | memset(update_buffs[i], 0, TEST_LEN(m)); // initialize the destination buffer to be zero for update function | |
190 | } | |
191 | for (i = 0; i < TEST_SOURCES; i++) { | |
192 | if (posix_memalign(&buf, 64, TEST_LEN(m))) { | |
193 | printf("alloc error: Fail"); | |
194 | return -1; | |
195 | } | |
196 | perf_update_buffs[i] = buf; | |
197 | memset(perf_update_buffs[i], 0, TEST_LEN(m)); // initialize the destination buffer to be zero for update function | |
198 | } | |
199 | ||
200 | // Make random data | |
201 | for (i = 0; i < k; i++) | |
202 | for (j = 0; j < TEST_LEN(m); j++) { | |
203 | buffs[i][j] = rand(); | |
204 | update_buffs[i][j] = buffs[i][j]; | |
205 | } | |
206 | ||
207 | gf_gen_rs_matrix(a, m, k); | |
7c673cae | 208 | |
f91f0fd5 TL |
209 | encode_update_test_ref(m, k, g_tbls, buffs, a); |
210 | encode_update_test(m, k, g_tbls, update_buffs, a); | |
7c673cae FG |
211 | for (i = 0; i < m - k; i++) { |
212 | if (0 != memcmp(update_buffs[k + i], buffs[k + i], TEST_LEN(m))) { | |
213 | printf("\nupdate_buffs%d :", i); | |
214 | dump(update_buffs[k + i], 25); | |
215 | printf("buffs%d :", i); | |
216 | dump(buffs[k + i], 25); | |
217 | return -1; | |
218 | } | |
219 | } | |
220 | ||
221 | #ifdef DO_REF_PERF | |
7c673cae | 222 | // Start encode test |
f91f0fd5 | 223 | BENCHMARK(&start, BENCHMARK_TIME, encode_update_test_ref(m, k, g_tbls, buffs, a)); |
7c673cae | 224 | printf(xstr(REF_FUNCTION) TEST_TYPE_STR ": "); |
f91f0fd5 | 225 | perf_print(start, (long long)(TEST_LEN(m)) * (m)); |
7c673cae | 226 | #endif |
f91f0fd5 | 227 | |
7c673cae | 228 | // Start encode test |
f91f0fd5 TL |
229 | BENCHMARK(&start, BENCHMARK_TIME, |
230 | encode_update_test(m, k, g_tbls, perf_update_buffs, a)); | |
7c673cae | 231 | printf(xstr(FUNCTION_UNDER_TEST) TEST_TYPE_STR ": "); |
f91f0fd5 | 232 | perf_print(start, (long long)(TEST_LEN(m)) * (m)); |
7c673cae FG |
233 | |
234 | // Start encode test | |
f91f0fd5 TL |
235 | BENCHMARK(&start, BENCHMARK_TIME, |
236 | // Make parity vects | |
237 | ec_init_tables(k, m - k, &a[k * k], g_tbls); | |
238 | FUNCTION_UNDER_TEST(TEST_LEN(m), k, m - k, 0, g_tbls, perf_update_buffs[0], | |
239 | &perf_update_buffs[k])); | |
7c673cae | 240 | printf(xstr(FUNCTION_UNDER_TEST) "_single_src" TEST_TYPE_STR ": "); |
f91f0fd5 | 241 | perf_print(start, (long long)(TEST_LEN(m)) * (m - k + 1)); |
7c673cae FG |
242 | |
243 | // Start encode test | |
f91f0fd5 TL |
244 | BENCHMARK(&start, BENCHMARK_TIME, |
245 | // Make parity vects | |
246 | FUNCTION_UNDER_TEST(TEST_LEN(m), k, m - k, 0, g_tbls, perf_update_buffs[0], | |
247 | &perf_update_buffs[k])); | |
7c673cae | 248 | printf(xstr(FUNCTION_UNDER_TEST) "_single_src_simple" TEST_TYPE_STR ": "); |
f91f0fd5 | 249 | perf_print(start, (long long)(TEST_LEN(m)) * (m - k + 1)); |
7c673cae FG |
250 | |
251 | for (i = k; i < m; i++) { | |
252 | memset(update_buffs[i], 0, TEST_LEN(m)); // initialize the destination buffer to be zero for update function | |
253 | } | |
254 | for (i = 0; i < k; i++) { | |
255 | FUNCTION_UNDER_TEST(TEST_LEN(m), k, m - k, i, g_tbls, update_buffs[i], | |
256 | &update_buffs[k]); | |
257 | } | |
7c673cae | 258 | |
f91f0fd5 TL |
259 | decode_test(m, k, update_buffs, recov, a, src_in_err, src_err_list, |
260 | nerrs, g_tbls, temp_buffs); | |
261 | BENCHMARK(&start, BENCHMARK_TIME, check = | |
262 | decode_test(m, k, update_buffs, recov, a, src_in_err, src_err_list, | |
263 | nerrs, g_tbls, perf_update_buffs)); | |
264 | if (check) { | |
265 | printf("BAD_MATRIX\n"); | |
7c673cae FG |
266 | return -1; |
267 | } | |
268 | ||
7c673cae FG |
269 | for (i = 0; i < nerrs; i++) { |
270 | if (0 != memcmp(temp_buffs[i], update_buffs[src_err_list[i]], TEST_LEN(m))) { | |
f91f0fd5 | 271 | printf("Fail error recovery (%d, %d, %d) - \n", m, k, nerrs); |
7c673cae FG |
272 | return -1; |
273 | } | |
274 | } | |
275 | ||
276 | printf(xstr(FUNCTION_UNDER_TEST) "_decode" TEST_TYPE_STR ": "); | |
f91f0fd5 | 277 | perf_print(start, (long long)(TEST_LEN(m)) * (k + nerrs)); |
7c673cae FG |
278 | |
279 | printf("done all: Pass\n"); | |
280 | return 0; | |
281 | } |