2 * Copyright (c) 2014, James S. Plank and Kevin Greenan
5 * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
8 * Revision 2.0: Galois Field backend now links to GF-Complete
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
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
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.
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.
40 /* Jerasure's authors:
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.
54 typedef unsigned long mylong;
55 #define LLUI (long long unsigned int)
59 struct timeval tstart;
60 gettimeofday(&tstart,0);
61 return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
64 double TimeStop(double t)
68 gettimeofday(&tend,0);
69 t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
73 void display(mylong *mat, int r, int c) {
74 for(int i=0;i<r;i++) {
75 for(int j=0;j<c;j++) {
76 printf("%016llu ",LLUI mat[i*c+j]);
83 mylong *matrix_multiply(gf_t *gf, mylong *m1, mylong *m2, int r1, int c1, int r2, int c2, int w)
88 product = (mylong *) malloc(sizeof(mylong)*r1*c2);
89 for (i = 0; i < r1*c2; i++) product[i] = 0;
91 for (i = 0; i < r1; i++) {
92 for (j = 0; j < c2; j++) {
93 for (k = 0; k < r2; k++) {
94 product[i*c2+j] ^= gf->multiply.w64(gf,m1[i*c1+k], m2[k*c2+j]);
103 int invert_matrix(gf_t *gf, mylong *mat, mylong *inv, int rows)
105 int cols, i, j, k, x, rs2;
112 for (i = 0; i < rows; i++) {
113 for (j = 0; j < cols; j++) {
114 inv[k] = (i == j) ? 1 : 0;
118 // display(inv, rows, rows);
121 /* First -- convert into upper triangular */
122 for (i = 0; i < cols; i++) {
125 /* Swap rows if we ave a zero i,i element. If we can't swap, then the
126 matrix was not invertible */
128 if (mat[row_start+i] == 0) {
129 for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
130 if (j == rows) return -1;
132 for (k = 0; k < cols; k++) {
133 tmp = mat[row_start+k];
134 mat[row_start+k] = mat[rs2+k];
136 tmp = inv[row_start+k];
137 inv[row_start+k] = inv[rs2+k];
142 /* Multiply the row by 1/element i,i */
143 tmp = mat[row_start+i];
145 inverse = gf->divide.w64(gf,1, tmp);
146 for (j = 0; j < cols; j++) {
147 mat[row_start+j] = gf->multiply.w64(gf,mat[row_start+j], inverse);
148 inv[row_start+j] = gf->multiply.w64(gf,inv[row_start+j], inverse);
152 /* Now for each j>i, add A_ji*Ai to Aj */
154 for (j = i+1; j != cols; j++) {
159 for (x = 0; x < cols; x++) {
160 mat[rs2+x] ^= mat[row_start+x];
161 inv[rs2+x] ^= inv[row_start+x];
166 for (x = 0; x < cols; x++) {
167 mat[rs2+x] ^= gf->multiply.w64(gf,tmp, mat[row_start+x]);
168 inv[rs2+x] ^= gf->multiply.w64(gf,tmp, inv[row_start+x]);
175 /* Now the matrix is upper triangular. Start at the top and multiply down */
177 for (i = rows-1; i >= 0; i--) {
179 for (j = 0; j < i; j++) {
181 if (mat[rs2+i] != 0) {
184 for (k = 0; k < cols; k++) {
185 inv[rs2+k] ^= gf->multiply.w64(gf,tmp, inv[row_start+k]);
192 display(mat, rows, rows);
195 display(inv, rows, rows);
204 int invertible_matrix(gf_t *gf, int *mat, int rows, int w)
206 int cols, i, j, k, x, rs2;
212 /* First -- convert into upper triangular */
213 for (i = 0; i < cols; i++) {
216 /* Swap rows if we ave a zero i,i element. If we can't swap, then the
217 matrix was not invertible */
219 if (mat[row_start+i] == 0) {
220 for (j = i+1; j < rows && mat[cols*j+i] == 0; j++) ;
221 if (j == rows) return 0;
223 for (k = 0; k < cols; k++) {
224 tmp = mat[row_start+k];
225 mat[row_start+k] = mat[rs2+k];
230 /* Multiply the row by 1/element i,i */
231 tmp = mat[row_start+i];
233 inverse = gf->divide.w64(gf,1, tmp);
234 for (j = 0; j < cols; j++) {
235 mat[row_start+j] = gf->multiply.w64(gf,mat[row_start+j], inverse);
239 /* Now for each j>i, add A_ji*Ai to Aj */
241 for (j = i+1; j != cols; j++) {
246 for (x = 0; x < cols; x++) {
247 mat[rs2+x] ^= mat[row_start+x];
252 for (x = 0; x < cols; x++) {
253 mat[rs2+x] ^= gf->multiply.w64(gf,tmp,mat[row_start+x]);
264 int main(int argc, char **argv)
282 gf_init_easy(&gf, w);
284 matS = malloc(sizeof(mylong)*t*len);
285 matG = malloc(sizeof(mylong)*t*n);
290 for(int i=0;i<t;i++) {
291 for(int j=0;j<len;j++) {
292 matS[i*len+j]=lrand48()<<32|lrand48();
296 for(int i=0;i<n;i++) {
297 for(int j=0;j<t;j++) {
298 matG[i*t+j]=lrand48()<<32|lrand48();
304 // printf("Matrix S:\n");
305 // display(matS, t, len);
307 printf("Matrix G:\n");
310 double tt=TimeStart();
311 matC=matrix_multiply(&gf, matG, matS, n, t, t, len, w);
312 printf("1st multiply %f\n",TimeStop(tt));
313 // printf("Matrix C:\n");
314 // display(matC, n, t);
316 ulong *matCs = malloc(sizeof(mylong)*t*len);
317 ulong *matGs = malloc(sizeof(mylong)*t*t);
319 for(int i=0;i<t;i++) {
320 for(int j=0;j<len;j++) {
321 matCs[i*len+j]=matC[i*len+j];
323 for(int j=0;j<t;j++) {
324 matGs[i*t+j]=matG[i*t+j];
328 printf("Matrix Gs:\n");
329 display(matGs, t, t);
331 // printf("Matrix Cs:\n");
332 // display(matCs, t, len);
334 ulong* matGs_copy = malloc(sizeof(mylong)* t*t);
336 //WARNINT invert changes the matrix
337 // invert = invertible_matrix(&gf,matGs, t, w);
338 // printf("\nInvertible Gs: %s\n", (invert == 1) ? "Yes" : "No");
340 memcpy(matGs_copy, matGs, sizeof(mylong)*t*t);
341 ulong *matInvGs = malloc(sizeof(mylong)*t*t);
342 invert_matrix(&gf, matGs_copy, matInvGs, t);
345 WARNING this changes matGs
346 identity=matrix_multiply(&gf, matInvGs, matGs, t, t, t, t, w);
347 printf("Identity:\n");
348 display(identity, t, t);
352 //printf("Matrix Gs:\n");
353 //display(matGs, t, t);
355 ulong *matS2 = malloc(sizeof(mylong)*t*len);
357 matS2=matrix_multiply(&gf, matInvGs, matCs, t, t, t, len, w);
358 printf("2nd multiply %f\n",TimeStop(tt));
360 //printf("Matrix S2:\n");
361 //display(matS2, t, len);
364 for(int i=0;i<t;i++) {
365 for(int j=0;j<len;j++) {
366 equal=matS[i*len+j]==matS2[i*len+j];
372 printf("EQUAL !!!\n");