
// for this simple illustration, it is assumed that the code runs in
// just one block, and that the number of threads evenly divides n

// improvements that could be made:
//    1.  change to multiple blocks, to try to use all SMs
//    2.  possibly use shared memory
//    3.  have each thread work on staggered elements of dx, rather than
//        on contiguous ones, to get more efficient bank access

#include <cuda.h>
#include <stdio.h>

__global__ void cumulker(int *dx, int n)
{  
   int me = threadIdx.x;
   int csize  = n / blockDim.x;
   int start = me * csize;
   int i,j,base;
   for (i = 1; i < csize; i++) {
      j = start + i;
      dx[j] = dx[j-1] + dx[j];
   }
   __syncthreads();
   if (me > 0) {
      base = 0;
      for (j = 0; j < me; j++)
         base += dx[(j+1)*csize-1];
   }
   __syncthreads();
   if (me > 0) {
      for (i = start; i < start + csize; i++)
         dx[i] += base;
   }
}

