sja91

Untitled

Feb 16th, 2014
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.11 KB | None | 0 0
  1. // MP Scan
  2. // Given a list (lst) of length n
  3. // Output its prefix sum = {lst[0], lst[0] + lst[1], lst[0] + lst[1] + ... + lst[n-1]}
  4.  
  5. #include    <wb.h>
  6.  
  7. #define BLOCK_SIZE 512 //@@ You can change this
  8.  
  9. #define wbCheck(stmt) do {                                                    \
  10.         cudaError_t err = stmt;                                               \
  11.         if (err != cudaSuccess) {                                             \
  12.             wbLog(ERROR, "Failed to run stmt ", #stmt);                       \
  13.             wbLog(ERROR, "Got CUDA error ...  ", cudaGetErrorString(err));    \
  14.             return -1;                                                        \
  15.         }                                                                     \
  16.     } while(0)
  17.    
  18. __global__ void scan(float * input, float * output, int len) {
  19.     //@@ Modify the body of this function to complete the functionality of
  20.     //@@ the scan on the device
  21.     //@@ You may need multiple kernel calls; write your kernels before this
  22.     //@@ function and call them from here
  23.    
  24.     __shared__ float sList[2*BLOCK_SIZE];
  25.    
  26.     int t = threadIdx.x;
  27.     int b = blockIdx.x*(BLOCK_SIZE*2);
  28.    
  29.     sList[t]            = ( b   + t < len ? input[b  +t] : 0);
  30.     sList[t+BLOCK_SIZE] = ( b+BLOCK_SIZE+t < len ? input[b+BLOCK_SIZE+t] : 0);
  31.    
  32.     __syncthreads();
  33.    
  34.     for( int s = 1; s <= BLOCK_SIZE; s *= 2)
  35.     {
  36.         int i = (t+1)*s*2 -1;
  37.         if( i < 2*BLOCK_SIZE)
  38.             sList[i] += sList[i-s];
  39.         __syncthreads();
  40.     }
  41.    
  42.     for( int s = BLOCK_SIZE/2; s > 0; s /= 2)
  43.     {
  44.         __syncthreads();
  45.         int i = (t+1)*s*2 -1;
  46.         if( i+s < 2*BLOCK_SIZE)
  47.             sList[i+s] += sList[i];
  48.     }
  49.    
  50.     __syncthreads();
  51.    
  52.     if( b+t < len) output[b+t] = sList[t];
  53.     if( b+BLOCK_SIZE+t < len) output[b+BLOCK_SIZE+t] = sList[t+BLOCK_SIZE];    
  54. }
  55.  
  56. int main(int argc, char ** argv) {
  57.     wbArg_t args;
  58.     float * hostInput; // The input 1D list
  59.     float * hostOutput; // The output list
  60.     float * deviceInput;
  61.     float * deviceOutput;
  62.     int numElements; // number of elements in the list
  63.  
  64.     args = wbArg_read(argc, argv);
  65.  
  66.     wbTime_start(Generic, "Importing data and creating memory on host");
  67.     hostInput = (float *) wbImport(wbArg_getInputFile(args, 0), &numElements);
  68.     hostOutput = (float*) malloc(numElements * sizeof(float));
  69.     wbTime_stop(Generic, "Importing data and creating memory on host");
  70.  
  71.     wbLog(TRACE, "The number of input elements in the input is ", numElements);
  72.  
  73.     wbTime_start(GPU, "Allocating GPU memory.");
  74.     wbCheck(cudaMalloc((void**)&deviceInput, numElements*sizeof(float)));
  75.     wbCheck(cudaMalloc((void**)&deviceOutput, numElements*sizeof(float)));
  76.     wbTime_stop(GPU, "Allocating GPU memory.");
  77.  
  78.     wbTime_start(GPU, "Clearing output memory.");
  79.     wbCheck(cudaMemset(deviceOutput, 0, numElements*sizeof(float)));
  80.     wbTime_stop(GPU, "Clearing output memory.");
  81.  
  82.     wbTime_start(GPU, "Copying input memory to the GPU.");
  83.     wbCheck(cudaMemcpy(deviceInput, hostInput, numElements*sizeof(float), cudaMemcpyHostToDevice));
  84.     wbTime_stop(GPU, "Copying input memory to the GPU.");
  85.  
  86.     //@@ Initialize the grid and block dimensions here
  87.  
  88.     dim3 Block( BLOCK_SIZE, 1, 1);
  89.     dim3 Grid((numElements-1) / (BLOCK_SIZE*2) +1, 1, 1);  
  90.    
  91.     wbTime_start(Compute, "Performing CUDA computation");
  92.     //@@ Modify this to complete the functionality of the scan
  93.     //@@ on the deivce
  94.    
  95.     scan<<< Grid, Block>>>( deviceInput, deviceOutput, numElements);
  96.        
  97.     cudaDeviceSynchronize();
  98.     wbTime_stop(Compute, "Performing CUDA computation");
  99.  
  100.     wbTime_start(Copy, "Copying output memory to the CPU");
  101.     wbCheck(cudaMemcpy(hostOutput, deviceOutput, numElements*sizeof(float), cudaMemcpyDeviceToHost));
  102.     wbTime_stop(Copy, "Copying output memory to the CPU");
  103.  
  104.     wbTime_start(GPU, "Freeing GPU Memory");
  105.     cudaFree(deviceInput);
  106.     cudaFree(deviceOutput);
  107.     wbTime_stop(GPU, "Freeing GPU Memory");
  108.  
  109.     for( int i = BLOCK_SIZE*2; i < numElements; i++)
  110.     {
  111.         hostOutput[i]+= hostOutput[(i/(BLOCK_SIZE*2))*BLOCK_SIZE*2 -1];
  112.     }
  113.    
  114.     wbSolution(args, hostOutput, numElements);
  115.  
  116.     free(hostInput);
  117.     free(hostOutput);
  118.  
  119.     return 0;
  120. }
Advertisement
Add Comment
Please, Sign In to add comment