Advertisement
Guest User

Untitled

a guest
Nov 20th, 2017
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.57 KB | None | 0 0
  1. // Karty_2.cpp : Defines the entry point for the console application.
  2. //
  3.  
  4. #include "stdafx.h"
  5. #include <ctime>
  6. // Macierze są pamiętane wierszami, a więc:
  7. // M(row, col) = *(M.elements + row * M.width + col)
  8.  
  9. typedef struct {
  10. int width;
  11. int height;
  12. float *elements;
  13. } Matrix;
  14.  
  15. // definiujemy rozmiar bloku wątków:
  16. #define BLOCK_SIZE 16
  17.  
  18. // prototyp funkcji mnożącej (kernela)
  19. __global__ void MatMulKernel(const Matrix, const Matrix, Matrix);
  20.  
  21. // prototyp funkcji uzupelniajaca macierz
  22. void pseudolosowe(Matrix *pointer);
  23.  
  24. // prototyp funkcji mnożącej (CPU)
  25. void CPU_mnozenie(const Matrix, const Matrix ,Matrix);
  26.  
  27. // Zakładamy (dla uproszczenia rozważań), że wymiary macierzy są
  28. // całkowitymi wielokrotnościami wartości BLOCK_SIZE
  29.  
  30. int main()
  31. {
  32. // przygotowujemy środowisko i wywołujemy kernel
  33. dim3 dimBlock(BLOCK_SIZE, BLOCK_SIZE);
  34. dim3 dimGrid(B.width / dimBlock.x, A.height / dimBlock.y);
  35. MatMulKernel << <dimGrid, dimBlock >> >(d_A, d_B, d_C);
  36.  
  37. // odbieramy obliczoną macierz C z pamięci globalnej urządzenia
  38. cudaMemcpy(C.elements, d_C.elements, size, cudaMemcpyDeviceToHost);
  39. // cudaMemcpyDeviceToHost kierunek transferu danych (pamięć źródłowa w karcie, a obszar docelowy w RAM)
  40.  
  41. // zwalniamy pamięć
  42. cudaFree(d_A.elements);
  43. cudaFree(d_B.elements);
  44. cudaFree(d_C.elements);
  45.  
  46. return 0;
  47. }
  48.  
  49. // Funkcja mnożąca
  50. void MatMul(const Matrix A, const Matrix B, Matrix C)
  51. {
  52. // kopiujemy macierze A i B to globalnej pamięci urządzenia
  53.  
  54. // najpierw A
  55. Matrix d_A;
  56. d_A.width = A.width;
  57. d_A.height = A.height;
  58. size_t size = A.width * A.height * sizeof(float); // okreslamy jakiego potrzebujemy rozmiaru
  59. cudaMalloc((void **)&d_A.elements, size); // alokuje pamiec na karcie graficznej
  60. pseudolosowe(d_A);
  61. cudaMemcpy(d_A.elements, A.elements, size, cudaMemcpyHostToDevice); // Kopiuje dane między kartą graficzną, a pamięcią RAM
  62. // cudaMemcpyHostToDevice - kierunek transferu danych (pamięć źródłowa w RAM, a obszar docelowy w karcie graficznej
  63.  
  64. // potem B
  65. Matrix d_B;
  66. d_B.width = B.width;
  67. d_B.height = B.height;
  68. size = B.width * B.height * sizeof(float);
  69. cudaMalloc((void **)&d_B.elements, size);
  70. pseudolosowe(d_B);
  71. cudaMemcpy(d_B.elements, B.elements, size, cudaMemcpyHostToDevice);
  72.  
  73. // przydzielamy macierz C w globalnej pamięci urządzenia
  74. Matrix d_C;
  75. d_C.width = C.width;
  76. d_C.height = C.height;
  77. size = C.width * C.height * sizeof(float);
  78. cudaMalloc((void **)&d_C.elements, size);
  79. }
  80.  
  81. // kernel odpowiedzialny za wymnożenie macierzy
  82. __global__ void MatMulKernel(Matrix A, Matrix B, Matrix C)
  83. {
  84. // każdy wątek oblicza jeden element macierzy C
  85. // akumulując wynik w zmiennej Cvalue
  86. float Cvalue = 0;
  87. int row = blockIdx.y * blockDim.y + threadIdx.y;
  88. int col = blockIdx.x * blockDim.x + threadIdx.x;
  89. for (int e = 0; e < A.width; ++e)
  90. Cvalue += A.elements[row * A.width + e]
  91. * B.elements[e * B.width + col];
  92. C.elements[row * C.width + col] = Cvalue;
  93. }
  94.  
  95. void pseudolosowe(&Matrix)
  96. {
  97. srand(time(NULL));
  98. for (int i = 0; i < pointer->width * pointer->height; i++)
  99. {
  100. pointer->elements[i] = (((std::rand() % 100000) + 1) / 10000); // tak uzyskujemy wartości po przecinku
  101. }
  102. }
  103.  
  104. void CPU_mnozenie(Matrix A, Matrix B, Matrix C)
  105. {
  106. for (int row = 0; row < A.height; row++)
  107. {
  108. for (int col = 0; col < B.width; col++)
  109. {
  110. float cValue = 0;
  111. for (int e = 0; e < A.width; e++)
  112. {
  113. cValue += A.elements[row * A.width + e] * B.elements[e * B.width + col];
  114. }
  115. C->elements[row * C->width + col] = cValue;
  116. }
  117. }
  118. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement