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)
285 gf_init_easy(&gf, w);
287 matS = malloc(sizeof(mylong)*t*len);
288 matG = malloc(sizeof(mylong)*t*n);
293 for(int i=0;i<t;i++) {
294 for(int j=0;j<len;j++) {
295 matS[i*len+j]=lrand48()<<32|lrand48();
299 for(int i=0;i<n;i++) {
300 for(int j=0;j<t;j++) {
301 matG[i*t+j]=lrand48()<<32|lrand48();
307 // printf("Matrix S:\n");
308 // display(matS, t, len);
310 printf("Matrix G:\n");
313 double tt=TimeStart();
314 matC=matrix_multiply(&gf, matG, matS, n, t, t, len, w);
315 printf("1st multiply %f\n",TimeStop(tt));
316 // printf("Matrix C:\n");
317 // display(matC, n, t);
319 ulong *matCs = malloc(sizeof(mylong)*t*len);
320 ulong *matGs = malloc(sizeof(mylong)*t*t);
322 for(int i=0;i<t;i++) {
323 for(int j=0;j<len;j++) {
324 matCs[i*len+j]=matC[i*len+j];
326 for(int j=0;j<t;j++) {
327 matGs[i*t+j]=matG[i*t+j];
334 printf("Matrix Gs:\n");
335 display(matGs, t, t);
337 // printf("Matrix Cs:\n");
338 // display(matCs, t, len);
340 ulong* matGs_copy = malloc(sizeof(mylong)* t*t);
342 //WARNINT invert changes the matrix
343 // invert = invertible_matrix(&gf,matGs, t, w);
344 // printf("\nInvertible Gs: %s\n", (invert == 1) ? "Yes" : "No");
346 memcpy(matGs_copy, matGs, sizeof(mylong)*t*t);
347 ulong *matInvGs = malloc(sizeof(mylong)*t*t);
348 invert_matrix(&gf, matGs_copy, matInvGs, t);
351 WARNING this changes matGs
352 identity=matrix_multiply(&gf, matInvGs, matGs, t, t, t, t, w);
353 printf("Identity:\n");
354 display(identity, t, t);
358 //printf("Matrix Gs:\n");
359 //display(matGs, t, t);
361 ulong *matS2 = malloc(sizeof(mylong)*t*len);
363 matS2=matrix_multiply(&gf, matInvGs, matCs, t, t, t, len, w);
364 printf("2nd multiply %f\n",TimeStop(tt));
368 //printf("Matrix S2:\n");
369 //display(matS2, t, len);
372 for(int i=0;i<t;i++) {
373 for(int j=0;j<len;j++) {
374 equal=matS[i*len+j]==matS2[i*len+j];
380 printf("EQUAL !!!\n");