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.
 
 
 
 
 

333 lines
12 KiB

  1. /*!
  2. \file matmul.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 "matmul.h"
  10. /*!
  11. * Square Matrix multiplication - ijk
  12. * \param C pointer to output matrix
  13. * \param A pointer to input matrix A
  14. * \param B pointer to input matrix B
  15. * \param n Size of matrices (both sizes)
  16. * \return none
  17. */
  18. void matrixMult_ijk(float * const C, float const * const A, float const * const B, int const n) {
  19. for (int i = 0; i < n; ++i)
  20. for (int j = 0; j < n; ++j) {
  21. int k =0;
  22. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  23. for (k = 1; k < n; ++k)
  24. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  25. }
  26. }
  27. /*!
  28. * Square Matrix multiplication - ikj
  29. * \param C pointer to output matrix
  30. * \param A pointer to input matrix A
  31. * \param B pointer to input matrix B
  32. * \param n Size of matrices (both sizes)
  33. * \return none
  34. */
  35. void matrixMult_ikj(float * const C, float const * const A, float const * const B, int const n) {
  36. for (int i = 0; i < n; ++i)
  37. for (int k = 0; k < n; ++k) {
  38. if (!k) {
  39. for (int j = 0; j < n; ++j)
  40. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  41. } else {
  42. for (int j = 0; j < n; ++j)
  43. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  44. }
  45. }
  46. }
  47. /*!
  48. * Square Matrix multiplication - jik
  49. * \param C pointer to output matrix
  50. * \param A pointer to input matrix A
  51. * \param B pointer to input matrix B
  52. * \param n Size of matrices (both sizes)
  53. * \return none
  54. */
  55. void matrixMult_jik(float * const C, float const * const A, float const * const B, int const n) {
  56. for (int j = 0; j < n; j++)
  57. for (int i = 0; i < n; i++) {
  58. int k =0;
  59. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  60. for (k = 1; k < n; k++)
  61. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  62. }
  63. }
  64. /*!
  65. * Square Matrix multiplication - jki
  66. * \param C pointer to output matrix
  67. * \param A pointer to input matrix A
  68. * \param B pointer to input matrix B
  69. * \param n Size of matrices (both sizes)
  70. * \return none
  71. */
  72. void matrixMult_jki(float * const C, float const * const A, float const * const B, int const n) {
  73. for (int j = 0; j < n; ++j)
  74. for (int k = 0; k < n; ++k) {
  75. if (!k) {
  76. for (int i = 0; i < n; ++i)
  77. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  78. } else {
  79. for (int i = 0; i < n; ++i)
  80. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  81. }
  82. }
  83. }
  84. /*!
  85. * Square Matrix multiplication - kij
  86. * \param C pointer to output matrix
  87. * \param A pointer to input matrix A
  88. * \param B pointer to input matrix B
  89. * \param n Size of matrices (both sizes)
  90. * \return none
  91. */
  92. void matrixMult_kij(float * const C, float const * const A, float const * const B, int const n) {
  93. for (int k = 0; k < n; ++k) {
  94. if (!k) {
  95. for (int i = 0; i < n; ++i)
  96. for (int j = 0; j < n; ++j)
  97. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  98. } else {
  99. for (int i = 0; i < n; ++i)
  100. for (int j = 0; j < n; ++j)
  101. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  102. }
  103. }
  104. }
  105. /*!
  106. * Square Matrix multiplication - kji
  107. * \param C pointer to output matrix
  108. * \param A pointer to input matrix A
  109. * \param B pointer to input matrix B
  110. * \param n Size of matrices (both sizes)
  111. * \return none
  112. */
  113. void matrixMult_kji(float * const C, float const * const A, float const * const B, int const n) {
  114. for (int k = 0; k < n; ++k) {
  115. if (!k) {
  116. for (int j = 0; j < n; ++j)
  117. for (int i = 0; i < n; ++i)
  118. C[ sub2ind(i,j,n) ] = A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  119. } else {
  120. for (int j = 0; j < n; ++j)
  121. for (int i = 0; i < n; ++i)
  122. C[ sub2ind(i,j,n) ] += A[ sub2ind(i,k,n) ] * B[ sub2ind(k,j,n) ];
  123. }
  124. }
  125. }
  126. /*!
  127. * Square Matrix multiplication in blocks - ijk
  128. * \param C pointer to output matrix
  129. * \param A pointer to input matrix A
  130. * \param B pointer to input matrix B
  131. * \param n Size of matrices (both sizes)
  132. * \param s The block size
  133. * \return none
  134. */
  135. void matrixMult_ijk_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  136. for (int I =0; I<n; I +=s)
  137. for (int J =0; J<n; J +=s)
  138. for (int K = 0; K<n; K +=s)
  139. for (int i =0; i<s; ++i)
  140. for (int j =0; j<s; ++j) {
  141. int k =0;
  142. if (K+k == 0)
  143. C[ sub2ind(I+i,J+j,n) ] = 0;
  144. for (k =0; k<s; ++k)
  145. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  146. }
  147. }
  148. /*!
  149. * Square Matrix multiplication in blocks - ikj
  150. * \param C pointer to output matrix
  151. * \param A pointer to input matrix A
  152. * \param B pointer to input matrix B
  153. * \param n Size of matrices (both sizes)
  154. * \param s The block size
  155. * \return none
  156. */
  157. void matrixMult_ikj_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  158. for (int I =0; I<n; I +=s)
  159. for (int K =0; K<n; K +=s)
  160. for (int J = 0; J<n; J +=s)
  161. for (int i =0; i<s; ++i)
  162. for (int k =0; k<s; ++k) {
  163. if ((k+K) == 0) {
  164. for (int j =0; j<s; ++j)
  165. C[ sub2ind(I+i,J+j,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  166. }
  167. else {
  168. for (int j =0; j<s; ++j)
  169. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  170. }
  171. }
  172. }
  173. /*!
  174. * Square Matrix multiplication in blocks - jik
  175. * \param C pointer to output matrix
  176. * \param A pointer to input matrix A
  177. * \param B pointer to input matrix B
  178. * \param n Size of matrices (both sizes)
  179. * \param s The block size
  180. * \return none
  181. */
  182. void matrixMult_jik_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  183. for (int J =0; J<n; J +=s)
  184. for (int I =0; I<n; I +=s)
  185. for (int K = 0; K<n; K +=s)
  186. for (int j =0; j<s; ++j)
  187. for (int i =0; i<s; ++i) {
  188. int k =0;
  189. if (K+k == 0)
  190. C[ sub2ind(I+i,J+j,n) ] = 0;
  191. for (k =0; k<s; ++k)
  192. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  193. }
  194. }
  195. /*!
  196. * Square Matrix multiplication in blocks - jki
  197. * \param C pointer to output matrix
  198. * \param A pointer to input matrix A
  199. * \param B pointer to input matrix B
  200. * \param n Size of matrices (both sizes)
  201. * \param s The block size
  202. * \return none
  203. */
  204. void matrixMult_jki_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  205. for (int J =0; J<n; J +=s)
  206. for (int K =0; K<n; K +=s)
  207. for (int I = 0; I<n; I +=s)
  208. for (int j =0; j<s; ++j)
  209. for (int k =0; k<s; ++k) {
  210. if ((k+K) == 0) {
  211. for (int i =0; i<s; ++i)
  212. C[ sub2ind(I+i,J+j,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  213. }
  214. else {
  215. for (int i =0; i<s; ++i)
  216. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  217. }
  218. }
  219. }
  220. /*!
  221. * Square Matrix multiplication in blocks - kij
  222. * \param C pointer to output matrix
  223. * \param A pointer to input matrix A
  224. * \param B pointer to input matrix B
  225. * \param n Size of matrices (both sizes)
  226. * \param s The block size
  227. * \return none
  228. *
  229. * \warning
  230. * Calling this function will trigger undefined result. There is no initialization of C.
  231. */
  232. void matrixMult_kij_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  233. for (int K =0; K<n; K +=s)
  234. for (int I =0; I<n; I +=s)
  235. for (int J = 0; J<n; J +=s)
  236. for (int k =0; k<s; ++k)
  237. for (int i =0; i<s; ++i)
  238. for (int j =0; j<s; ++j)
  239. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  240. }
  241. /*!
  242. * Square Matrix multiplication in blocks - kji
  243. * \param C pointer to output matrix
  244. * \param A pointer to input matrix A
  245. * \param B pointer to input matrix B
  246. * \param n Size of matrices (both sizes)
  247. * \param s The block size
  248. * \return none
  249. *
  250. * \warning
  251. * Calling this function will trigger undefined result. There is no initialization of C.
  252. */
  253. void matrixMult_kji_block(float * const C, float const * const A, float const * const B, int const n, int const s) {
  254. for (int K =0; K<n; K +=s)
  255. for (int J =0; J<n; J +=s)
  256. for (int I = 0; I<n; I +=s)
  257. for (int k =0; k<s; ++k)
  258. for (int j =0; j<s; ++j)
  259. for (int i =0; i<s; ++i)
  260. C[ sub2ind(I+i,J+j,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+j,n) ];
  261. }
  262. /*!
  263. * Square Matrix multiplication in unrolling block of 8 - ikj
  264. * \param C pointer to output matrix
  265. * \param A pointer to input matrix A
  266. * \param B pointer to input matrix B
  267. * \param n Size of matrices (both sizes)
  268. * \param s The block size
  269. * \return none
  270. */
  271. void matrixMult_ikj8(float * const C, float const * const A, float const * const B, int const n) {
  272. for (int I =0; I<n; I +=8)
  273. for (int K =0; K<n; K +=8)
  274. for (int J = 0; J<n; J +=8)
  275. for (int i =0; i<8; ++i)
  276. for (int k =0; k<8; ++k) {
  277. if ((k+K) == 0) {
  278. C[ sub2ind(I+i,J+0,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+0,n) ];
  279. C[ sub2ind(I+i,J+1,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+1,n) ];
  280. C[ sub2ind(I+i,J+2,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+2,n) ];
  281. C[ sub2ind(I+i,J+3,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+3,n) ];
  282. C[ sub2ind(I+i,J+4,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+4,n) ];
  283. C[ sub2ind(I+i,J+5,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+5,n) ];
  284. C[ sub2ind(I+i,J+6,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+6,n) ];
  285. C[ sub2ind(I+i,J+7,n) ] = A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+7,n) ];
  286. }
  287. else {
  288. C[ sub2ind(I+i,J+0,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+0,n) ];
  289. C[ sub2ind(I+i,J+1,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+1,n) ];
  290. C[ sub2ind(I+i,J+2,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+2,n) ];
  291. C[ sub2ind(I+i,J+3,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+3,n) ];
  292. C[ sub2ind(I+i,J+4,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+4,n) ];
  293. C[ sub2ind(I+i,J+5,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+5,n) ];
  294. C[ sub2ind(I+i,J+6,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+6,n) ];
  295. C[ sub2ind(I+i,J+7,n) ] += A[ sub2ind(I+i,K+k,n) ] * B[ sub2ind(K+k,J+7,n) ];
  296. }
  297. }
  298. }
  299. /*!
  300. * Initialize matrix with random indices and return the matrix pointer.
  301. *
  302. * \param n The size of the matrix (both of them)
  303. * \return Pointer to allocated and initialized matrix
  304. */
  305. float* matrixInit(int const n) {
  306. float *M = (float *) malloc( n*n*sizeof(float) );
  307. for (int i = 0; i < n; i++) /* rows */
  308. for (int j = 0; j < n; j++) /* cols */
  309. M[ sub2ind(i,j,n) ] = (float)rand()/(float)(RAND_MAX);
  310. return M;
  311. }