Computer Organization and Design assignements
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.
 
 
 
 
 

295 lignes
9.8 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. * Initialize matrix with random indices and return the matrix pointer.
  264. *
  265. * \param n The size of the matrix (both of them)
  266. * \return Pointer to allocated and initialized matrix
  267. */
  268. float* matrixInit(int const n) {
  269. float *M = (float *) malloc( n*n*sizeof(float) );
  270. for (int i = 0; i < n; i++) /* rows */
  271. for (int j = 0; j < n; j++) /* cols */
  272. M[ sub2ind(i,j,n) ] = (float)rand()/(float)(RAND_MAX);
  273. return M;
  274. }