proffreda

Cuda Transpose Exercise

Sep 25th, 2016
774
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.01 KB | None | 0 0
  1. #include <stdio.h>
  2. #include "gputimer.h"
  3. //#include "utils.h"
  4.  
  5. const int N= 1024; // matrix size will be NxN
  6.  
  7. int compare_matrices(float *gpu, float *ref, int N)
  8. {
  9. int result = 0;
  10. for(int j=0; j < N; j++)
  11. for(int i=0; i < N; i++)
  12. if (ref[i + j*N] != gpu[i + j*N])
  13. {result = 1;}
  14. return result;
  15. }
  16.  
  17.  
  18. // fill a matrix with sequential numbers in the range 0..N-1
  19. void fill_matrix(float *mat, int N)
  20. {
  21. for(int j=0; j < N * N; j++)
  22. mat[j] = (float) j;
  23. }
  24.  
  25. // The following functions and kernels are for your references
  26. void
  27. transpose_CPU(float in[], float out[])
  28. {
  29. for(int j=0; j < N; j++)
  30. for(int i=0; i < N; i++)
  31. out[j + i*N] = in[i + j*N]; // out(j,i) = in(i,j)
  32. }
  33.  
  34. // to be launched on a single thread
  35. __global__ void
  36. transpose_serial(float in[], float out[])
  37. {
  38. for(int j=0; j < N; j++)
  39. for(int i=0; i < N; i++)
  40. out[j + i*N] = in[i + j*N]; // out(j,i) = in(i,j)
  41. }
  42.  
  43. // to be launched with one thread per row of output matrix
  44. __global__ void
  45. transpose_parallel_per_row(float in[], float out[])
  46. {
  47. int i = threadIdx.x + blockDim.x * blockIdx.x;
  48.  
  49. for(int j=0; j < N; j++)
  50. out[j + i*N] = in[i + j*N]; // out(j,i) = in(i,j)
  51. }
  52.  
  53.  
  54.  
  55. // Write two tiled versions of transpose -- One using shared memory.
  56. // To be launched with one thread per element, in KxK threadblocks.
  57. // You will determine for each thread (x,y) in tile the element (i,j) of global output matrix.
  58.  
  59. __global__ void
  60. transpose_parallel_per_element_tiled(float in[], float out[])
  61. {
  62. //ToDo
  63. }
  64.  
  65. __global__ void
  66. transpose_parallel_per_element_tiled_shared(float in[], float out[])
  67. {
  68. //ToDo
  69. }
  70.  
  71. int main(int argc, char **argv)
  72. {
  73. int numbytes = N * N * sizeof(float);
  74.  
  75. float *in = (float *) malloc(numbytes);
  76. float *out = (float *) malloc(numbytes);
  77. float *gold = (float *) malloc(numbytes);
  78.  
  79. fill_matrix(in, N);
  80. transpose_CPU(in, gold);
  81.  
  82. float *d_in, *d_out;
  83.  
  84. cudaMalloc(&d_in, numbytes);
  85. cudaMalloc(&d_out, numbytes);
  86. cudaMemcpy(d_in, in, numbytes, cudaMemcpyHostToDevice);
  87.  
  88. GpuTimer timer;
  89.  
  90.  
  91. timer.Start();
  92. transpose_serial<<<1,1>>>(d_in, d_out);
  93. timer.Stop();
  94. for (int i=0; i < N*N; ++i){out[i] = 0.0;}
  95. cudaMemcpy(out, d_out, numbytes, cudaMemcpyDeviceToHost);
  96. printf("transpose_serial: %g ms.\nVerifying ...%s\n",
  97. timer.Elapsed(), compare_matrices(out, gold, N) ? "Failed" : "Success");
  98.  
  99.  
  100. cudaMemcpy(d_out, d_in, numbytes, cudaMemcpyDeviceToDevice); //clean d_out
  101. timer.Start();
  102. transpose_parallel_per_row<<<1,N>>>(d_in, d_out);
  103. timer.Stop();
  104. for (int i=0; i < N*N; ++i){out[i] = 0.0;} //clean out
  105. cudaMemcpy(out, d_out, numbytes, cudaMemcpyDeviceToHost);
  106. printf("transpose_parallel_per_row: %g ms.\nVerifying ...%s\n",
  107. timer.Elapsed(), compare_matrices(out, gold, N) ? "Failed" : "Success");
  108.  
  109. cudaMemcpy(d_out, d_in, numbytes, cudaMemcpyDeviceToDevice); //clean d_out
  110. // Tiled versions
  111. const int K= 16;
  112. dim3 blocks_tiled(N/K,N/K);
  113. dim3 threads_tiled(K,K);
  114. timer.Start();
  115. transpose_parallel_per_element_tiled<<<blocks_tiled,threads_tiled>>>(d_in, d_out);
  116. timer.Stop();
  117. for (int i=0; i < N*N; ++i){out[i] = 0.0;}
  118. cudaMemcpy(out, d_out, numbytes, cudaMemcpyDeviceToHost);
  119. printf("transpose_parallel_per_element_tiled %dx%d: %g ms.\nVerifying ...%s\n",
  120. K, K, timer.Elapsed(), compare_matrices(out, gold, N) ? "Failed" : "Success");
  121.  
  122. cudaMemcpy(d_out, d_in, numbytes, cudaMemcpyDeviceToDevice); //clean d_out
  123. dim3 blocks_tiled_sh(N/K,N/K);
  124. dim3 threads_tiled_sh(K,K);
  125. timer.Start();
  126. transpose_parallel_per_element_tiled_shared<<<blocks_tiled_sh,threads_tiled_sh>>>(d_in, d_out);
  127. timer.Stop();
  128. for (int i=0; i < N*N; ++i){out[i] = 0.0;}
  129. cudaMemcpy(out, d_out, numbytes, cudaMemcpyDeviceToHost);
  130. printf("transpose_parallel_per_element_tiled_shared %dx%d: %g ms.\nVerifying ...%s\n",
  131. K, K, timer.Elapsed(), compare_matrices(out, gold, N) ? "Failed" : "Success");
  132.  
  133. cudaFree(d_in);
  134. cudaFree(d_out);
  135. }
Advertisement
Add Comment
Please, Sign In to add comment