]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* * |
2 | * Copyright (c) 2014, 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 | /* Jerasure's authors: | |
41 | ||
42 | Revision 2.x - 2014: James S. Plank and Kevin M. Greenan. | |
43 | Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman. | |
44 | Revision 1.0 - 2007: James S. Plank. | |
45 | */ | |
46 | ||
47 | #include <stdio.h> | |
48 | #include <stdlib.h> | |
49 | #include <string.h> | |
50 | #include <gf_complete.h> | |
51 | #include <gf_rand.h> | |
52 | #include <gf_method.h> | |
53 | #include <stdint.h> | |
54 | #include "jerasure.h" | |
55 | #include "reed_sol.h" | |
56 | ||
57 | static void *malloc16(int size) { | |
58 | void *mem = malloc(size+16+sizeof(void*)); | |
59 | void **ptr = (void**)((long)(mem+16+sizeof(void*)) & ~(15)); | |
60 | ptr[-1] = mem; | |
61 | return ptr; | |
62 | } | |
63 | ||
64 | static void free16(void *ptr) { | |
65 | free(((void**)ptr)[-1]); | |
66 | } | |
67 | ||
68 | #define talloc(type, num) (type *) malloc16(sizeof(type)*(num)) | |
69 | ||
70 | void | |
71 | timer_start (double *t) | |
72 | { | |
73 | struct timeval tv; | |
74 | ||
75 | gettimeofday (&tv, NULL); | |
76 | *t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6; | |
77 | } | |
78 | ||
79 | double | |
80 | timer_split (const double *t) | |
81 | { | |
82 | struct timeval tv; | |
83 | double cur_t; | |
84 | ||
85 | gettimeofday (&tv, NULL); | |
86 | cur_t = (double)tv.tv_sec + (double)tv.tv_usec * 1e-6; | |
87 | return (cur_t - *t); | |
88 | } | |
89 | ||
90 | usage(char *s) | |
91 | { | |
92 | fprintf(stderr, "usage: reed_sol_time_gf k m w seed iterations bufsize (additional GF args) - Test and time Reed-Solomon in a particular GF(2^w).\n"); | |
93 | fprintf(stderr, " \n"); | |
94 | fprintf(stderr, " w must be 8, 16 or 32. k+m must be <= 2^w.\n"); | |
95 | fprintf(stderr, " See the README for information on the additional GF args.\n"); | |
96 | fprintf(stderr, " Set up a Vandermonde-based distribution matrix and encodes k devices of\n"); | |
97 | fprintf(stderr, " bufsize bytes each with it. Then it decodes.\n"); | |
98 | fprintf(stderr, " \n"); | |
99 | fprintf(stderr, "This tests: jerasure_matrix_encode()\n"); | |
100 | fprintf(stderr, " jerasure_matrix_decode()\n"); | |
101 | fprintf(stderr, " jerasure_print_matrix()\n"); | |
102 | fprintf(stderr, " galois_change_technique()\n"); | |
103 | fprintf(stderr, " reed_sol_vandermonde_coding_matrix()\n"); | |
104 | if (s != NULL) fprintf(stderr, "%s\n", s); | |
105 | exit(1); | |
106 | } | |
107 | ||
108 | gf_t* get_gf(int w, int argc, char **argv, int starting) | |
109 | { | |
110 | gf_t *gf = (gf_t*)malloc(sizeof(gf_t)); | |
111 | if (create_gf_from_argv(gf, w, argc, argv, starting) == 0) { | |
112 | free(gf); | |
113 | gf = NULL; | |
114 | } | |
115 | return gf; | |
116 | } | |
117 | ||
118 | int main(int argc, char **argv) | |
119 | { | |
120 | long l; | |
121 | int k, w, i, j, m, iterations, bufsize; | |
122 | int *matrix; | |
123 | char **data, **coding, **old_values; | |
124 | int *erasures, *erased; | |
125 | int *decoding_matrix, *dm_ids; | |
126 | uint32_t seed; | |
127 | double t = 0, total_time = 0; | |
128 | gf_t *gf = NULL; | |
129 | ||
130 | if (argc < 8) usage(NULL); | |
131 | if (sscanf(argv[1], "%d", &k) == 0 || k <= 0) usage("Bad k"); | |
132 | if (sscanf(argv[2], "%d", &m) == 0 || m <= 0) usage("Bad m"); | |
133 | if (sscanf(argv[3], "%d", &w) == 0 || (w != 8 && w != 16 && w != 32)) usage("Bad w"); | |
134 | if (sscanf(argv[4], "%d", &seed) == 0) usage("Bad seed"); | |
135 | if (sscanf(argv[5], "%d", &iterations) == 0) usage("Bad iterations"); | |
136 | if (sscanf(argv[6], "%d", &bufsize) == 0) usage("Bad bufsize"); | |
137 | if (w <= 16 && k + m > (1 << w)) usage("k + m is too big"); | |
138 | ||
139 | MOA_Seed(seed); | |
140 | ||
141 | gf = get_gf(w, argc, argv, 7); | |
142 | ||
143 | if (gf == NULL) { | |
144 | usage("Invalid arguments given for GF!\n"); | |
145 | } | |
146 | ||
147 | galois_change_technique(gf, w); | |
148 | ||
149 | matrix = reed_sol_vandermonde_coding_matrix(k, m, w); | |
150 | ||
151 | printf("<HTML><TITLE>reed_sol_time_gf"); | |
152 | for (i = 1; i < argc; i++) printf(" %s", argv[i]); | |
153 | printf("</TITLE>\n"); | |
154 | printf("<h3>reed_sol_time_gf"); | |
155 | for (i = 1; i < argc; i++) printf(" %s", argv[i]); | |
156 | printf("</h3>\n"); | |
157 | printf("<pre>\n"); | |
158 | ||
159 | printf("Last m rows of the generator matrix (G^T):\n\n"); | |
160 | jerasure_print_matrix(matrix, m, k, w); | |
161 | printf("\n"); | |
162 | ||
163 | data = talloc(char *, k); | |
164 | for (i = 0; i < k; i++) { | |
165 | data[i] = talloc(char, bufsize); | |
166 | MOA_Fill_Random_Region(data[i], bufsize); | |
167 | } | |
168 | ||
169 | coding = talloc(char *, m); | |
170 | old_values = talloc(char *, m); | |
171 | for (i = 0; i < m; i++) { | |
172 | coding[i] = talloc(char, bufsize); | |
173 | old_values[i] = talloc(char, bufsize); | |
174 | } | |
175 | ||
176 | for (i = 0; i < iterations; i++) { | |
177 | timer_start(&t); | |
178 | jerasure_matrix_encode(k, m, w, matrix, data, coding, bufsize); | |
179 | total_time += timer_split(&t); | |
180 | } | |
181 | ||
182 | printf("Encode throughput for %d iterations: %.2f MB/s (%.2f sec)\n", iterations, (double)(k*iterations*bufsize/1024/1024) / total_time, total_time); | |
183 | ||
184 | erasures = talloc(int, (m+1)); | |
185 | erased = talloc(int, (k+m)); | |
186 | for (i = 0; i < m+k; i++) erased[i] = 0; | |
187 | l = 0; | |
188 | for (i = 0; i < m; ) { | |
189 | erasures[i] = ((unsigned int)MOA_Random_W(w, 1))%(k+m); | |
190 | if (erased[erasures[i]] == 0) { | |
191 | erased[erasures[i]] = 1; | |
192 | memcpy(old_values[i], (erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], bufsize); | |
193 | bzero((erasures[i] < k) ? data[erasures[i]] : coding[erasures[i]-k], bufsize); | |
194 | i++; | |
195 | } | |
196 | } | |
197 | erasures[i] = -1; | |
198 | ||
199 | for (i = 0; i < iterations; i++) { | |
200 | timer_start(&t); | |
201 | jerasure_matrix_decode(k, m, w, matrix, 1, erasures, data, coding, bufsize); | |
202 | total_time += timer_split(&t); | |
203 | } | |
204 | ||
205 | printf("Decode throughput for %d iterations: %.2f MB/s (%.2f sec)\n", iterations, (double)(k*iterations*bufsize/1024/1024) / total_time, total_time); | |
206 | ||
207 | for (i = 0; i < m; i++) { | |
208 | if (erasures[i] < k) { | |
209 | if (memcmp(data[erasures[i]], old_values[i], bufsize)) { | |
210 | fprintf(stderr, "Decoding failed for %d!\n", erasures[i]); | |
211 | exit(1); | |
212 | } | |
213 | } else { | |
214 | if (memcmp(coding[erasures[i]-k], old_values[i], bufsize)) { | |
215 | fprintf(stderr, "Decoding failed for %d!\n", erasures[i]); | |
216 | exit(1); | |
217 | } | |
218 | } | |
219 | } | |
220 | ||
221 | return 0; | |
222 | } |