Ok, so the main idea of the task is to calculate the average of multiple images, I have it running in the normal way so I thought I will give it a go using CUDA, but unfortunately what I receive in the output is the first image instead of the average. (Inside the Kernel I also tried to set some pixels to 0 to make sure something is happening but no luck..)
////My kernel:
//nImages - number of images in the memory
//nBytes - number of pixels*color per image (also it's a size of dataOut)
//nImages*nBytes gives us the size of dataIn
//nBatch - dataIn has 1 milion bytes per image, we run in 6144 threads, so we need 163 batches to calc the whole dataOut
__global__
void avg_arrays(unsigned char* cuDataIn, unsigned char* cuDataOut, int nImages, int nBytes, int nBatch)
{
//get the position of the correct byte
int j = threadIdx.x + nBatch;
//if we're outside of image then give up
if(j >= nBytes) return;
//proceed averaging
long lSum = 0;
for(int i=0; i < nImages; ++i)
lSum += cuDataIn[i*nBytes + j];
lSum = lSum / nImages;
cuDataOut[j] = lSum;
}
Memory allocation etc.
unsigned char* dataIn = 0;
unsigned char* dataOut= 0;
// Allocate and Transfer memory to the devicea
gpuErrchk( cudaMalloc((void**)&dataIn, nPixelCountBGR * nNumberOfImages * sizeof(unsigned char))); //dataIn
gpuErrchk( cudaMalloc((void**)&dataOut, nPixelCountBGR * sizeof(unsigned char))); //dataOut
gpuErrchk( cudaMemcpy(dataIn, bmps, nPixelCountBGR * nNumberOfImages * sizeof(unsigned char), cudaMemcpyHostToDevice )); //dataIn
gpuErrchk( cudaMemcpy(dataOut, basePixels, nPixelCountBGR * sizeof(unsigned char), cudaMemcpyHostToDevice )); //dataOut
// Perform the array addition
dim3 dimBlock(N);
dim3 dimGrid(1);
//do it in batches, unless it's possible to run more threads at once, anyway N is a number of max threads
for(int i=0; i<nPixelCountBGR; i+=N){
cout << "Running with: nImg: "<< nNumberOfImages << ", nPixBGR " << nPixelCountBGR << ", and i = " << i << endl;
avg_arrays<<<dimGrid, dimBlock>>>(dataIn, dataOut, nNumberOfImages, nPixelCountBGR, 0);
}
// Copy the Contents from the GPU
gpuErrchk(cudaMemcpy(basePixels, dataOut, nPixelCountBGR * sizeof(unsigned char), cudaMemcpyDeviceToHost));
gpuErrchk(cudaFree(dataOut));
gpuErrchk(cudaFree(dataIn));
The error check doesn't bring any messages, all the code runs smoothly, all I get at the end is the exact copy of the first image.
Just in case if someone needs here's some console output:
Running with: nImg: 29, nPixBGR 1228800, and i = 0
...
Running with: nImg: 29, nPixBGR 1228800, and i = 1210368
Running with: nImg: 29, nPixBGR 1228800, and i = 1216512
Running with: nImg: 29, nPixBGR 1228800, and i = 1222656
Time of averaging: 0.219