Computer Organization and Design assignements
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

133 lines
4.1 KiB

  1. /*!
  2. \file main.c
  3. \brief Matrix multiplication implementation.
  4. \author Nikos Pitsianis
  5. \author Dimitris Floros
  6. \author Christos Choutouridis 8997 <cchoutou@ece.auth.gr>
  7. \date 2020-05-05
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <math.h>
  13. #include <sys/time.h>
  14. #include <assert.h>
  15. #include "matmul.h"
  16. extern double sqrt (double);
  17. int cmpfunc (const void * a, const void * b) {
  18. double v =*(double*)a - *(double*)b;
  19. return (v < 0) ? -1 : (v > 0) ? 1 : 0;
  20. }
  21. double median (double* t, size_t n) {
  22. qsort ((void*)t, n, sizeof(t[0]), cmpfunc);
  23. return (n % 2) ? t[n/2] : (t[n/2] + t[n/2 -1]) /2;
  24. }
  25. double std_deviation (double* t, size_t n) {
  26. double av =0;
  27. for (size_t i=0 ; i<n ; ++i) {
  28. av += t[i];
  29. }
  30. av /= n;
  31. double s =0;
  32. for (size_t i=0 ; i<n ; ++i) {
  33. s += (t[i]-av)*(t[i]-av);
  34. }
  35. return sqrt (s/n);
  36. }
  37. mMult_ft multSelect (char* order) {
  38. if (! strcmp ((const char*)order, "ijk")) return matrixMult_ijk;
  39. else if (! strcmp ((const char*)order, "ikj")) return matrixMult_ikj;
  40. else if (! strcmp ((const char*)order, "jik")) return matrixMult_jik;
  41. else if (! strcmp ((const char*)order, "jki")) return matrixMult_jki;
  42. else if (! strcmp ((const char*)order, "kij")) return matrixMult_kij;
  43. else if (! strcmp ((const char*)order, "kji")) return matrixMult_kji;
  44. else if (! strcmp ((const char*)order, "ikj8")) return matrixMult_ikj8;
  45. else return matrixMult_ijk;
  46. }
  47. mMultBlock_ft multBlockSelect (char* order) {
  48. if (! strcmp ((const char*)order, "ijk")) return matrixMult_ijk_block;
  49. else if (! strcmp ((const char*)order, "ikj")) return matrixMult_ikj_block;
  50. else if (! strcmp ((const char*)order, "jik")) return matrixMult_jik_block;
  51. else if (! strcmp ((const char*)order, "jki")) return matrixMult_jki_block;
  52. else if (! strcmp ((const char*)order, "kij")) return matrixMult_kij_block;
  53. else if (! strcmp ((const char*)order, "kji")) return matrixMult_kji_block;
  54. else return matrixMult_ijk_block;
  55. }
  56. /*!
  57. * A unit testing like main function to profile our code
  58. */
  59. int main(int argc, char **argv) {
  60. struct timeval start, end; /* time structs */
  61. double time[MAX_ITER] = {0.0}; /* execution time array in ms */
  62. float *A, *B, *C; /* matrix declarations */
  63. mMult_ft mMult =NULL;
  64. mMultBlock_ft mMultBlock =NULL;
  65. /* read matrix size (or use default) */
  66. if (argc < 3){
  67. fprintf( stderr,
  68. "Usage:\n"
  69. "%s n order [block], where \n"
  70. " n: is the matrix size.\n"
  71. " order: the loop order ex: ijk , jik, ...\n"
  72. " block: Optional block size\n",
  73. argv[0]);
  74. exit(1);
  75. }
  76. int n = atoi( argv[1] );
  77. if (argc == 4)
  78. mMultBlock = multBlockSelect(argv[2]);
  79. else
  80. mMult = multSelect(argv[2]);
  81. /* initialize matrices */
  82. A = matrixInit( n );
  83. B = matrixInit( n );
  84. C = (float *) malloc( n*n*sizeof(float) );
  85. /* compute matrix multiplication */
  86. for (int it = 0; it < MAX_ITER; it++) {
  87. if (argc == 4) {
  88. gettimeofday(&start, NULL);
  89. mMultBlock( C, A, B, n, atoi(argv[3]) );
  90. gettimeofday(&end, NULL);
  91. }
  92. else {
  93. gettimeofday(&start, NULL);
  94. mMult( C, A, B, n );
  95. gettimeofday(&end, NULL);
  96. }
  97. time[it] = (end.tv_sec - start.tv_sec) * 1000.0 + /* sec to ms */
  98. (end.tv_usec - start.tv_usec) / 1000.0; /* us to ms */
  99. printf("Iter: %d Time: %f ms\n", it, time[it]);
  100. }
  101. /* we need to use the result -- verify it */
  102. for (int i = 0; i < n; i++) { /* rows */
  103. for (int j = 0; j < n; j++) { /* cols */
  104. float gold = 0;
  105. for (int k = 0; k < n; k++) { /* accumulate products */
  106. gold += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  107. }
  108. assert( (gold - C[sub2ind(i,j,n)]) < 1e-3 );
  109. }
  110. }
  111. // statistical data
  112. printf ("Median: %f [msec]\n", median (time, MAX_ITER));
  113. printf ("Std.Dev: %f [msec]\n", std_deviation(time, MAX_ITER));
  114. }