Skip to content

Commit d8c84dc

Browse files
committed
Added tests for the GF init helper functions in galois.c
Updated the README to explain the GF change procedure.
1 parent e5170f7 commit d8c84dc

8 files changed

+729
-65
lines changed

Examples/makefile

+9-4
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ ALL = jerasure_01 \
6363
reed_sol_04 \
6464
reed_sol_test_gf \
6565
reed_sol_time_gf \
66+
reed_sol_hard_time_gf \
6667
cauchy_01 \
6768
cauchy_02 \
6869
cauchy_03 \
@@ -190,9 +191,13 @@ decoder: decoder.o galois.o jerasure.o liberation.o reed_sol.o cauchy.o
190191
$(CC) $(CFLAGS) -o decoder decoder.o liberation.o jerasure.o galois.o reed_sol.o cauchy.o -lgf_complete
191192

192193
reed_sol_test_gf.o: galois.h reed_sol.h jerasure.h
193-
reed_sol_test_gf: reed_sol_test_gf.o galois.o ${LIBDIR}/gf_complete.a jerasure.o reed_sol.o
194-
$(CC) $(CFLAGS) -o reed_sol_test_gf reed_sol_test_gf.o reed_sol.o jerasure.o galois.o ${LIBDIR}/gf_complete.a
194+
reed_sol_test_gf: reed_sol_test_gf.o galois.o jerasure.o reed_sol.o
195+
$(CC) $(CFLAGS) -o reed_sol_test_gf reed_sol_test_gf.o reed_sol.o jerasure.o galois.o -lgf_complete
195196

196197
reed_sol_time_gf.o: galois.h reed_sol.h jerasure.h
197-
reed_sol_time_gf: reed_sol_time_gf.o galois.o ${LIBDIR}/gf_complete.a jerasure.o reed_sol.o
198-
$(CC) $(CFLAGS) -o reed_sol_time_gf reed_sol_time_gf.o reed_sol.o jerasure.o galois.o ${LIBDIR}/gf_complete.a
198+
reed_sol_time_gf: reed_sol_time_gf.o galois.o jerasure.o reed_sol.o
199+
$(CC) $(CFLAGS) -o reed_sol_time_gf reed_sol_time_gf.o reed_sol.o jerasure.o galois.o -lgf_complete
200+
201+
reed_sol_hard_time_gf.o: galois.h reed_sol.h jerasure.h
202+
reed_sol_hard_time_gf: reed_sol_hard_time_gf.o galois.o jerasure.o reed_sol.o
203+
$(CC) $(CFLAGS) -o reed_sol_hard_time_gf reed_sol_hard_time_gf.o reed_sol.o jerasure.o galois.o -lgf_complete

Examples/reed_sol_hard_time_gf.c

+361
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
/* *
2+
* Copyright (c) 2013, James S. Plank and Kevin Greenan
3+
* All rights reserved.
4+
*
5+
* Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
6+
* Coding Techniques
7+
*
8+
* Revision 2.0: Galois Field backend now links to GF-Complete
9+
*
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions
12+
* are met:
13+
*
14+
* - Redistributions of source code must retain the above copyright
15+
* notice, this list of conditions and the following disclaimer.
16+
*
17+
* - Redistributions in binary form must reproduce the above copyright
18+
* notice, this list of conditions and the following disclaimer in
19+
* the documentation and/or other materials provided with the
20+
* distribution.
21+
*
22+
* - Neither the name of the University of Tennessee nor the names of its
23+
* contributors may be used to endorse or promote products derived
24+
* from this software without specific prior written permission.
25+
*
26+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30+
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
33+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
36+
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37+
* POSSIBILITY OF SUCH DAMAGE.
38+
*/
39+
40+
41+
42+
#include <stdio.h>
43+
#include <stdlib.h>
44+
#include <string.h>
45+
#include <gf_complete.h>
46+
#include "jerasure.h"
47+
#include "reed_sol.h"
48+
49+
#define BUFSIZE 4096
50+
51+
int get_gfp_from_argv(gf_t **gfp, int w, int argc, char **argv, int starting)
52+
{
53+
int mult_type, divide_type, region_type;
54+
int arg1, arg2, subrg_size, degree;
55+
uint64_t prim_poly;
56+
gf_t *base;
57+
char *crt, *x, *y;
58+
59+
mult_type = GF_MULT_DEFAULT;
60+
region_type = GF_REGION_DEFAULT;
61+
divide_type = GF_DIVIDE_DEFAULT;
62+
prim_poly = 0;
63+
base = NULL;
64+
arg1 = 0;
65+
arg2 = 0;
66+
degree = 0;
67+
while (1) {
68+
if (argc > starting) {
69+
if (strcmp(argv[starting], "-m") == 0) {
70+
starting++;
71+
if (mult_type != GF_MULT_DEFAULT) {
72+
if (base != NULL) gf_free(base, 1);
73+
return 0;
74+
}
75+
if (strcmp(argv[starting], "SHIFT") == 0) {
76+
mult_type = GF_MULT_SHIFT;
77+
starting++;
78+
} else if (strcmp(argv[starting], "CARRY_FREE") == 0) {
79+
mult_type = GF_MULT_CARRY_FREE;
80+
starting++;
81+
} else if (strcmp(argv[starting], "GROUP") == 0) {
82+
mult_type = GF_MULT_GROUP;
83+
if (argc < starting + 3) {
84+
return 0;
85+
}
86+
if (sscanf(argv[starting+1], "%d", &arg1) == 0 ||
87+
sscanf(argv[starting+2], "%d", &arg2) == 0) {
88+
return 0;
89+
}
90+
starting += 3;
91+
} else if (strcmp(argv[starting], "BYTWO_p") == 0) {
92+
mult_type = GF_MULT_BYTWO_p;
93+
starting++;
94+
} else if (strcmp(argv[starting], "BYTWO_b") == 0) {
95+
mult_type = GF_MULT_BYTWO_b;
96+
starting++;
97+
} else if (strcmp(argv[starting], "TABLE") == 0) {
98+
mult_type = GF_MULT_TABLE;
99+
starting++;
100+
} else if (strcmp(argv[starting], "LOG") == 0) {
101+
mult_type = GF_MULT_LOG_TABLE;
102+
starting++;
103+
} else if (strcmp(argv[starting], "LOG_ZERO") == 0) {
104+
mult_type = GF_MULT_LOG_ZERO;
105+
starting++;
106+
} else if (strcmp(argv[starting], "LOG_ZERO_EXT") == 0) {
107+
mult_type = GF_MULT_LOG_ZERO_EXT;
108+
starting++;
109+
} else if (strcmp(argv[starting], "SPLIT") == 0) {
110+
mult_type = GF_MULT_SPLIT_TABLE;
111+
if (argc < starting + 3) {
112+
return 0;
113+
}
114+
if (sscanf(argv[starting+1], "%d", &arg1) == 0 ||
115+
sscanf(argv[starting+2], "%d", &arg2) == 0) {
116+
return 0;
117+
}
118+
starting += 3;
119+
} else if (strcmp(argv[starting], "COMPOSITE") == 0) {
120+
mult_type = GF_MULT_COMPOSITE;
121+
if (argc < starting + 2) { return 0; }
122+
if (sscanf(argv[starting+1], "%d", &arg1) == 0) {
123+
return 0;
124+
}
125+
starting += 2;
126+
degree = arg1;
127+
starting = get_gfp_from_argv(&base, w/degree, argc, argv, starting);
128+
if (starting == 0) {
129+
free(base);
130+
return 0;
131+
}
132+
} else {
133+
if (base != NULL) gf_free(base, 1);
134+
return 0;
135+
}
136+
} else if (strcmp(argv[starting], "-r") == 0) {
137+
starting++;
138+
if (strcmp(argv[starting], "DOUBLE") == 0) {
139+
region_type |= GF_REGION_DOUBLE_TABLE;
140+
starting++;
141+
} else if (strcmp(argv[starting], "QUAD") == 0) {
142+
region_type |= GF_REGION_QUAD_TABLE;
143+
starting++;
144+
} else if (strcmp(argv[starting], "LAZY") == 0) {
145+
region_type |= GF_REGION_LAZY;
146+
starting++;
147+
} else if (strcmp(argv[starting], "SSE") == 0) {
148+
region_type |= GF_REGION_SSE;
149+
starting++;
150+
} else if (strcmp(argv[starting], "NOSSE") == 0) {
151+
region_type |= GF_REGION_NOSSE;
152+
starting++;
153+
} else if (strcmp(argv[starting], "CAUCHY") == 0) {
154+
region_type |= GF_REGION_CAUCHY;
155+
starting++;
156+
} else if (strcmp(argv[starting], "ALTMAP") == 0) {
157+
region_type |= GF_REGION_ALTMAP;
158+
starting++;
159+
} else {
160+
if (base != NULL) gf_free(base, 1);
161+
return 0;
162+
}
163+
} else if (strcmp(argv[starting], "-p") == 0) {
164+
starting++;
165+
if (sscanf(argv[starting], "%llx", (long long unsigned int *)(&prim_poly)) == 0) {
166+
if (base != NULL) gf_free(base, 1);
167+
return 0;
168+
}
169+
starting++;
170+
} else if (strcmp(argv[starting], "-d") == 0) {
171+
starting++;
172+
if (divide_type != GF_DIVIDE_DEFAULT) {
173+
if (base != NULL) gf_free(base, 1);
174+
return 0;
175+
} else if (strcmp(argv[starting], "EUCLID") == 0) {
176+
divide_type = GF_DIVIDE_EUCLID;
177+
starting++;
178+
} else if (strcmp(argv[starting], "MATRIX") == 0) {
179+
divide_type = GF_DIVIDE_MATRIX;
180+
starting++;
181+
} else {
182+
return 0;
183+
}
184+
} else if (strcmp(argv[starting], "-") == 0) {
185+
if (mult_type == GF_MULT_COMPOSITE) {
186+
*gfp = galois_init_composite_field(w, region_type, divide_type, degree, base);
187+
} else {
188+
*gfp = galois_init_field(w, mult_type, region_type, divide_type, prim_poly, arg1, arg2);
189+
}
190+
starting++;
191+
break;
192+
} else {
193+
if (base != NULL) gf_free(base, 1);
194+
return 0;
195+
}
196+
}
197+
}
198+
199+
return starting;
200+
}
201+
202+
static void *malloc16(int size) {
203+
void *mem = malloc(size+16+sizeof(void*));
204+
void **ptr = (void**)((long)(mem+16+sizeof(void*)) & ~(15));
205+
ptr[-1] = mem;
206+
return ptr;
207+
}
208+
209+
static void free16(void *ptr) {
210+
free(((void**)ptr)[-1]);
211+
}
212+
213+
#define talloc(type, num) (type *) malloc16(sizeof(type)*(num))
214+
215+
void
216+
timer_start (double *t)
217+
{
218+
struct timeval tv;
219+
220+
gettimeofday (&tv, NULL);
221+
*t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
222+
}
223+
224+
double
225+
timer_split (const double *t)
226+
{
227+
struct timeval tv;
228+
double cur_t;
229+
230+
gettimeofday (&tv, NULL);
231+
cur_t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
232+
return (cur_t - *t);
233+
}
234+
235+
usage(char *s)
236+
{
237+
fprintf(stderr, "usage: reed_sol_hard_test_gf k m w [additional GF args]- Test and time Reed-Solomon in a particular GF(2^w).\n");
238+
fprintf(stderr, " \n");
239+
fprintf(stderr, " w must be 8, 16 or 32. k+m must be <= 2^w.\n");
240+
fprintf(stderr, " See the README for information on the additional GF args.\n");
241+
fprintf(stderr, " Set up a Vandermonde-based distribution matrix and encodes k devices of\n");
242+
fprintf(stderr, " %d bytes each with it. Then it decodes.\n", BUFSIZE);
243+
fprintf(stderr, " \n");
244+
fprintf(stderr, "This tests: jerasure_matrix_encode()\n");
245+
fprintf(stderr, " jerasure_matrix_decode()\n");
246+
fprintf(stderr, " jerasure_print_matrix()\n");
247+
fprintf(stderr, " galois_init_composite_field()\n");
248+
fprintf(stderr, " galois_init_field()\n");
249+
fprintf(stderr, " galois_change_technique()\n");
250+
fprintf(stderr, " reed_sol_vandermonde_coding_matrix()\n");
251+
if (s != NULL) fprintf(stderr, "%s\n", s);
252+
exit(1);
253+
}
254+
255+
static void fill_buffer(unsigned char *buf, int size)
256+
{
257+
int i;
258+
259+
buf[0] = (char)(lrand48() % 256);
260+
261+
for (i=1; i < size; i++) {
262+
buf[i] = ((buf[i-1] + i) % 256);
263+
}
264+
}
265+
266+
int main(int argc, char **argv)
267+
{
268+
long l;
269+
int k, w, i, j, m, iterations, bufsize;
270+
int *matrix;
271+
char **data, **coding, **old_values;
272+
int *erasures, *erased;
273+
int *decoding_matrix, *dm_ids;
274+
double t = 0, total_time = 0;
275+
gf_t *gf = NULL;
276+
int ret = 0;
277+
278+
if (argc < 6) usage(NULL);
279+
if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k");
280+
if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m");
281+
if (sscanf(argv[3], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32)) usage("Bad w");
282+
if (sscanf(argv[4], "%d", &iterations) == 0) usage("Bad iterations");
283+
if (sscanf(argv[5], "%d", &bufsize) == 0) usage("Bad bufsize");
284+
if (w <= 16 && k + m > (1 << w)) usage("k + m is too big");
285+
286+
srand48(time(0));
287+
288+
ret = get_gfp_from_argv(&gf, w, argc, argv, 6);
289+
290+
if (ret == 0 || gf == NULL) {
291+
usage("Invalid arguments given for GF!\n");
292+
}
293+
294+
galois_change_technique(gf, w);
295+
296+
matrix = reed_sol_vandermonde_coding_matrix(k, m, w);
297+
298+
printf("Last m rows of the Distribution Matrix:\n\n");
299+
jerasure_print_matrix(matrix, m, k, w);
300+
printf("\n");
301+
302+
data = talloc(char *, k);
303+
for (i = 0; i < k; i++) {
304+
data[i] = talloc(char, bufsize);
305+
fill_buffer(data[i], bufsize);
306+
}
307+
308+
coding = talloc(char *, m);
309+
old_values = talloc(char *, m);
310+
for (i = 0; i < m; i++) {
311+
coding[i] = talloc(char, bufsize);
312+
old_values[i] = talloc(char, bufsize);
313+
}
314+
315+
for (i = 0; i < iterations; i++) {
316+
timer_start(&t);
317+
jerasure_matrix_encode(k, m, w, matrix, data, coding, bufsize);
318+
total_time += timer_split(&t);
319+
}
320+
321+
fprintf(stderr, "Encode thput for %d iterations: %.2f MB/s (%.2f sec)\n", iterations, (double)(k*iterations*bufsize/1024/1024) / total_time, total_time);
322+
323+
erasures = talloc(int, (m+1));
324+
erased = talloc(int, (k+m));
325+
for (i = 0; i < m+k; i++) erased[i] = 0;
326+
l = 0;
327+
for (i = 0; i < m; ) {
328+
erasures[i] = ((unsigned int)lrand48())%(k+m);
329+
if (erased[erasures[i]] == 0) {
330+
erased[erasures[i]] = 1;
331+
memcpy(old_values[i], (erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], bufsize);
332+
bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], bufsize);
333+
i++;
334+
}
335+
}
336+
erasures[i] = -1;
337+
338+
for (i = 0; i < iterations; i++) {
339+
timer_start(&t);
340+
jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, bufsize);
341+
total_time += timer_split(&t);
342+
}
343+
344+
fprintf(stderr, "Decode thput for %d iterations: %.2f MB/s (%.2f sec)\n", iterations, (double)(m*iterations*bufsize/1024/1024) / total_time, total_time);
345+
346+
for (i = 0; i < m; i++) {
347+
if (erasures[i] < k) {
348+
if (memcmp(data[erasures[i]], old_values[i], bufsize)) {
349+
fprintf(stderr, "Decoding failed for %d!\n", erasures[i]);
350+
exit(1);
351+
}
352+
} else {
353+
if (memcmp(coding[erasures[i]-k], old_values[i], bufsize)) {
354+
fprintf(stderr, "Decoding failed for %d!\n", erasures[i]);
355+
exit(1);
356+
}
357+
}
358+
}
359+
360+
return 0;
361+
}
File renamed without changes.

0 commit comments

Comments
 (0)