sja91

Untitled

Jan 5th, 2013
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.18 KB | None | 0 0
  1. // MP 3: Due Sunday, Dec 30, 2012 at 11:59 p.m. PST
  2. #include <wb.h>
  3.  
  4. #define TILE_SIZE 16
  5. #define wbCheck(stmt) do { \
  6. cudaError_t err = stmt; \
  7. if (err != cudaSuccess) { \
  8. wbLog(ERROR, "Failed to run stmt ", #stmt); \
  9. return -1; \
  10. } \
  11. } while(0)
  12.  
  13. // Compute C = A * B
  14. __global__ void matrixMultiplyShared(float * A, float * B, float * C,
  15. int numARows, int numAColumns,
  16. int numBRows, int numBColumns,
  17. int numCRows, int numCColumns) {
  18.  
  19. //@@ Insert code to implement matrix multiplication here
  20. //@@ You have to use shared memory for this MP
  21.  
  22. __shared__ float tileA[TILE_SIZE][TILE_SIZE];
  23. __shared__ float tileB[TILE_SIZE][TILE_SIZE];
  24.  
  25. int col = blockIdx.x * TILE_SIZE + threadIdx.x;
  26. int row = blockIdx.y * TILE_SIZE + threadIdx.y;
  27. float pValue = 0;
  28.  
  29. for(int m = 0; m < (numAColumns + 1) / TILE_SIZE -1; m++)
  30. {
  31.  
  32.  
  33. if(m * TILE_SIZE + threadIdx.x < numAColumns && row < numARows)
  34. tileA[threadIdx.y][threadIdx.x] = A[row * numAColumns + m * TILE_SIZE + threadIdx.x];
  35. else
  36. tileA[threadIdx.y][threadIdx.x] = 0;
  37.  
  38. if(col && m * TILE_SIZE + threadIdx.y < numBRows)
  39. tileB[threadIdx.y][threadIdx.x] = B[(m * TILE_SIZE + threadIdx.y) * numBColumns + col];
  40. else
  41. tileB[threadIdx.y][threadIdx.x] = 0;
  42.  
  43. __syncthreads();
  44.  
  45. for(int k = 0; k < TILE_SIZE; k++)
  46. pValue += tileA[threadIdx.y][k] * tileB[k][threadIdx.x];
  47.  
  48. __syncthreads();
  49. }
  50.  
  51. if(row < numCRows && col < numCColumns)
  52. C[row * numCColumns + col] = pValue;
  53.  
  54. }
  55.  
  56. int main(int argc, char ** argv) {
  57. wbArg_t args;
  58. float * hostA; // The A matrix
  59. float * hostB; // The B matrix
  60. float * hostC; // The output C matrix
  61. float * deviceA;
  62. float * deviceB;
  63. float * deviceC;
  64. int numARows; // number of rows in the matrix A
  65. int numAColumns; // number of columns in the matrix A
  66. int numBRows; // number of rows in the matrix B
  67. int numBColumns; // number of columns in the matrix B
  68. int numCRows; // number of rows in the matrix C (you have to set this)
  69. int numCColumns; // number of columns in the matrix C (you have to set this)
  70.  
  71. args = wbArg_read(argc, argv);
  72.  
  73. wbTime_start(Generic, "Importing data and creating memory on host");
  74. hostA = (float *) wbImport(wbArg_getInputFile(args, 0), &numARows, &numAColumns);
  75. hostB = (float *) wbImport(wbArg_getInputFile(args, 1), &numBRows, &numBColumns);
  76.  
  77.  
  78. //@@ Set numCRows and numCColumns
  79. if(numAColumns != numBRows)
  80. {
  81. wbLog(TRACE, "Incompatible matrices");
  82. return 1;
  83. }
  84.  
  85. numCRows = numARows;
  86. numCColumns = numBColumns;
  87.  
  88.  
  89. //@@ Allocate the hostC matrix
  90. int sizeOfA = numAColumns * numARows * sizeof(float);
  91. int sizeOfB = numBColumns * numBRows * sizeof(float);
  92. int sizeOfC = numCColumns * numCRows * sizeof(float);
  93.  
  94. hostC = (float *)malloc(sizeOfC);
  95.  
  96. wbTime_stop(Generic, "Importing data and creating memory on host");
  97.  
  98. wbLog(TRACE, "The dimensions of A are ", numARows, " x ", numAColumns);
  99. wbLog(TRACE, "The dimensions of B are ", numBRows, " x ", numBColumns);
  100.  
  101. wbTime_start(GPU, "Allocating GPU memory.");
  102.  
  103.  
  104.  
  105. //@@ Allocate GPU memory here
  106. wbCheck(cudaMalloc((void**)&deviceA, sizeOfA));
  107. wbCheck(cudaMalloc((void**)&deviceB, sizeOfB));
  108. wbCheck(cudaMalloc((void**)&deviceC, sizeOfC));
  109.  
  110.  
  111. wbTime_stop(GPU, "Allocating GPU memory.");
  112.  
  113. wbTime_start(GPU, "Copying input memory to the GPU.");
  114.  
  115.  
  116. //@@ Copy memory to the GPU here
  117. wbCheck(cudaMemcpy(deviceA, hostA, sizeOfA, cudaMemcpyHostToDevice));
  118. wbCheck(cudaMemcpy(deviceB, hostB, sizeOfB, cudaMemcpyHostToDevice));
  119.  
  120.  
  121.  
  122. wbTime_stop(GPU, "Copying input memory to the GPU.");
  123.  
  124.  
  125. //@@ Initialize the grid and block dimensions here
  126. dim3 dimBlock(TILE_SIZE, TILE_SIZE, 1);
  127. dim3 dimGrid((numCColumns - 1)/dimBlock.x + 1, (numCRows - 1)/dimBlock.y + 1, 1);
  128.  
  129.  
  130.  
  131. wbTime_start(Compute, "Performing CUDA computation");
  132.  
  133.  
  134. //@@ Launch the GPU Kernel here
  135. matrixMultiplyShared<<<dimGrid, dimBlock>>>(deviceA, deviceB, deviceC,
  136. numARows, numAColumns,
  137. numBRows, numBColumns,
  138. numCRows, numCColumns);
  139.  
  140. cudaThreadSynchronize();
  141. wbTime_stop(Compute, "Performing CUDA computation");
  142.  
  143. wbTime_start(Copy, "Copying output memory to the CPU");
  144.  
  145.  
  146. //@@ Copy the GPU memory back to the CPU here
  147. wbCheck(cudaMemcpy(hostC, deviceC, sizeOfC, cudaMemcpyDeviceToHost));
  148.  
  149.  
  150. wbTime_stop(Copy, "Copying output memory to the CPU");
  151.  
  152. wbTime_start(GPU, "Freeing GPU Memory");
  153.  
  154.  
  155. //@@ Free the GPU memory here
  156. wbCheck(cudaFree(deviceA));
  157. wbCheck(cudaFree(deviceB));
  158. wbCheck(cudaFree(deviceC));
  159.  
  160.  
  161.  
  162. wbTime_stop(GPU, "Freeing GPU Memory");
  163.  
  164. wbSolution(args, hostC, numCRows, numCColumns);
  165.  
  166. free(hostA);
  167. free(hostB);
  168. free(hostC);
  169.  
  170. return 0;
  171. }
Advertisement
Add Comment
Please, Sign In to add comment