int main(void) { // Structs for timing data. struct rusage before, after; double ti_multiply=0.0; // Seed random number generator. srand(time(NULL)); // Initalize matrixes. Change values here for different size matrices. MATRIX* m1 = malloc(sizeof(MATRIX)); MATRIX* m2 = malloc(sizeof(MATRIX)); initialize_matrix(10,10,m1); initialize_matrix(10,10,m2); MATRIX* m3 = malloc(sizeof(MATRIX)); // Calculate time while multiplying. getrusage(RUSAGE_SELF, &before); strassen_mult(m1,m2,m3); getrusage(RUSAGE_SELF, &after); ti_multiply = calculate(&before, &after); // Print out matrices to stdout. Comment this section out for large matrices. print_matrix(m1); print_matrix(m2); print_matrix(m3); // Print out computation time. printf("\nTime Spent (in sec): %f\n", (ti_multiply)); // Free matrices when done with them. free_matrix(m1); free_matrix(m2); free_matrix(m3); }
static void thread_main(void *args){ struct work_struct *s = args; int tid = s->tid; int size = s->a_1.size; //printf("Thread %d Starting\n", tid); switch(tid){ case 0:{ matrix temp1 = new_matrix(size); matrix temp2 = new_matrix(size); plus(s->a_1, s->a_2, temp1); plus(s->b_1, s->b_2, temp2); strassen_mult(temp1, temp2, s->c); delete_matrix(temp2); delete_matrix(temp1); } break; case 1:{ matrix temp1 = new_matrix(size); plus(s->a_1, s->a_2, temp1); strassen_mult(temp1, s->b_1, s->c); delete_matrix(temp1); } break; case 2:{ matrix temp2 = new_matrix(size); minus(s->b_1, s->b_2, temp2); strassen_mult(s->a_1, temp2, s->c); delete_matrix(temp2); } break; case 3:{ matrix temp2 = new_matrix(size); minus(s->b_1, s->b_2, temp2); strassen_mult(s->a_1, temp2, s->c); delete_matrix(temp2); } break; case 4:{ matrix temp1 = new_matrix(size); plus(s->a_1, s->a_2, temp1); strassen_mult(temp1, s->b_1, s->c); delete_matrix(temp1); } break; case 5:{ matrix temp1 = new_matrix(size); matrix temp2 = new_matrix(size); minus(s->a_1, s->a_2, temp1); plus(s->b_1, s->b_2, temp2); strassen_mult(temp1, temp2, s->c); delete_matrix(temp2); delete_matrix(temp1); } break; case 6:{ matrix temp1 = new_matrix(size); matrix temp2 = new_matrix(size); minus(s->a_1, s->a_2, temp1); plus(s->b_1, s->b_2, temp2); strassen_mult(temp1, temp2, s->c); delete_matrix(temp2); delete_matrix(temp1); } break; } }
//expects c to be initialized void strassen_mult(matrix a, matrix b, matrix c){ matrix quar[12]; matrix m[7]; matrix temp1, temp2; int size = a.size/2; int i,j; // if(size==0){ // c.rows[0][0] = a.rows[0][0] * b.rows[0][0]; // return; // } if (a.size <= BREAK) { int i, j, k; for (i = 0; i < (a.size); i++) { for (k = 0; k < (a.size); k++) { for (j = 0; j < (a.size); j++) { c.rows[i][j] += a.rows[i][k] * b.rows[k][j]; } } } } quar[0]=get00(a); quar[1]=get01(a); quar[2]=get10(a); quar[3]=get11(a); quar[4]=get00(b); quar[5]=get01(b); quar[6]=get10(b); quar[7]=get11(b); quar[8]=get00(c); quar[9]=get01(c); quar[10]=get10(c); quar[11]=get11(c); for(i=0;i<7;i++){ m[i] = new_matrix(size); } if (a.size <= BREAK) goto group; temp1 = new_matrix(size); temp2 = new_matrix(size); plus(quar[0], quar[3], temp1); plus(quar[4], quar[7], temp2); strassen_mult(temp1,temp2,m[0]); plus(quar[2], quar[3], temp1); strassen_mult(temp1, quar[4], m[1]); minus(quar[5], quar[7], temp2); strassen_mult(quar[0], temp2, m[2]); minus(quar[6], quar[4], temp2); strassen_mult(quar[3], temp2, m[3]); plus(quar[0], quar[1], temp1); strassen_mult(temp1, quar[7], m[4]); minus(quar[2], quar[0], temp1); plus(quar[4], quar[5], temp2); strassen_mult(temp1, temp2, m[5]); minus(quar[1], quar[3], temp1); plus(quar[6], quar[7], temp2); strassen_mult(temp1, temp2, m[6]); delete_matrix(temp1); delete_matrix(temp2); group: for(i=0;i<size;i++){ for(j=0;j<size;j++){ quar[8].rows[i][j] = m[0].rows[i][j] + m[3].rows[i][j] - m[4].rows[i][j] + m[6].rows[i][j]; quar[9].rows[i][j] = m[2].rows[i][j] + m[4].rows[i][j]; quar[10].rows[i][j] = m[1].rows[i][j] + m[3].rows[i][j]; quar[11].rows[i][j] = m[0].rows[i][j] - m[1].rows[i][j] + m[2].rows[i][j] + m[5].rows[i][j]; } } for(i=0;i<12;i++){ delete_matrix(quar[i]); } for(i=0;i<7;i++){ delete_matrix(m[i]); } }