Newer
Older
#include "Vec.h"
#include "CudaUtilities.cuh"
template <class PixelTypeIn, class OutType>
__global__ void cudaSum(PixelTypeIn* arrayIn, OutType* arrayOut, size_t n)
extern __shared__ unsigned char sharedMem[];
OutType* sums = (OutType*)sharedMem;
size_t i = threadIdx.x + blockIdx.x*blockDim.x;
sums[threadIdx.x] += (OutType)(arrayIn[i+imStride]);
for (int localStride=blockDim.x/2; localStride>0; localStride=localStride/2)
{
if (threadIdx.x<localStride)
sums[threadIdx.x] += sums[threadIdx.x+localStride];
if (threadIdx.x==0)
{
arrayOut[blockIdx.x] = sums[0];
template < class OutType, class PixelTypeIn>
OutType sumArray(const PixelTypeIn* imageIn, size_t n, int device=0)
OutType sum = 0;
OutType* deviceSum;
OutType* hostSum;
PixelTypeIn* deviceBuffer;
cudaDeviceProp props;
cudaGetDeviceProperties(&props, device);
size_t availMem, total;
cudaMemGetInfo(&availMem,&total);
size_t numValsPerChunk = MIN(n,(size_t)((availMem*MAX_MEM_AVAIL)/sizeof(PixelTypeIn)));
int maxBlocks = (int)ceil((double)numValsPerChunk/(threads*2));
HANDLE_ERROR(cudaMalloc((void**)&deviceBuffer,sizeof(PixelTypeIn)*numValsPerChunk));
HANDLE_ERROR(cudaMalloc((void**)&deviceSum,sizeof(OutType)*maxBlocks));
for (size_t startIdx=0; startIdx<n; startIdx += numValsPerChunk)
size_t curNumVals = MIN(numValsPerChunk,n-startIdx);
HANDLE_ERROR(cudaMemcpy(deviceBuffer,imageIn+startIdx,sizeof(PixelTypeIn)*curNumVals,cudaMemcpyHostToDevice));
int blocks = (int)ceil((double)curNumVals/(threads*2));
size_t sharedMemSize = sizeof(OutType)*threads;
cudaSum<<<blocks,threads,sharedMemSize>>>(deviceBuffer,deviceSum,curNumVals);
HANDLE_ERROR(cudaMemcpy(hostSum,deviceSum,sizeof(OutType)*blocks,cudaMemcpyDeviceToHost));