Advertisement
czlowiekzgon

pkg

Nov 24th, 2019
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.16 KB | None | 0 0
  1. // Macierze są pamiętane wierszami, a więc:
  2. // M(row, col) = *(M.elements + row * M.width + col)
  3. typedef struct {
  4. int width;
  5. int height;
  6. float *elements;
  7. } Matrix;
  8. // definiujemy rozmiar bloku wątków:
  9. #define BLOCK_SIZE 16
  10. // prototyp funkcji mnożącej (kernela)
  11. __global__ void MatMulKernel(const Matrix, const Matrix, Matrix);
  12. // Zakładamy (dla uproszczenia rozważań), że wymiary macierzy są
  13. // całkowitymi wielokrotnościami wartości BLOCK_SIZE
  14.  
  15.  
  16. // Funkcja mnożąca
  17. void MatMul(const Matrix A, const Matrix B, Matrix C)
  18. {
  19. // kopiujemy macierze A i B to globalnej pamięci urządzenia
  20. // najpierw A
  21. Matrix d_A;
  22. d_A.width = A.width;
  23. d_A.height = A.height;
  24. size_t size = A.width * A.height * sizeof(float);
  25. cudaMalloc((void **)&d_A.elements, size);
  26. cudaMemcpy(d_A.elements, A.elements, size, cudaMemcpyHostToDevice);
  27. // potem B
  28. Matrix d_B;
  29. d_B.width = B.width;
  30. d_B.height = B.height;
  31. size = B.width * B.height * sizeof(float);
  32. cudaMalloc((void **)&d_B.elements, size);
  33. cudaMemcpy(d_B.elements, B.elements, size,cudaMemcpyHostToDevice);
  34. // przydzielamy macierz C w globalnej pamięci urządzenia
  35. Matrix d_C;
  36. d_C.width = C.width;
  37. d_C.height = C.height;
  38. size = C.width * C.height * sizeof(float);
  39. cudaMalloc((void **)&d_C.elements, size);
  40. // preparujemy środowisko i wywołujemy kernel
  41. dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
  42. dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
  43. MatMulKernel<<<dimGrid, dimBlock>>>(d_A, d_B, d_C);
  44. // odbieramy obliczoną macierz C z pamięci globalnej urządzenia
  45. cudaMemcpy(C.elements, d_C.elements, size, cudaMemcpyDeviceToHost);
  46. // zwalniamy pamięć
  47. cudaFree(d_A.elements);
  48. cudaFree(d_B.elements);
  49. cudaFree(d_C.elements);
  50. }
  51.  
  52. // kernel odpowiedzialny za wymnożenie macierzy
  53. __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C)
  54. {
  55. // każdy wątek oblicza jeden element macierzy C
  56. // akumulując wynik w zmiennej Cvalue
  57. float Cvalue = 0;
  58. int row = blockIdx.y * blockDim.y + threadIdx.y;
  59. int col = blockIdx.x * blockDim.x + threadIdx.x;
  60. for (int e = 0; e < A.width; ++e)
  61. Cvalue += A.elements[row * A.width + e]
  62. * B.elements[e * B.width + col];
  63. C.elements[row * C.width + col] = Cvalue;
  64. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement