【发布时间】:2014-04-11 06:18:14
【问题描述】:
我有一个在 GPU 上计算 Local Binary Patterns 的 CUDA 函数。基本上,LBP 是对图像像素的计算,其中任何给定像素 (i,j) 的值取决于它的 8 个邻居的强度。
到目前为止一切顺利,代码如下:
//The kernel
__global__ void LBP(unsigned char *in, unsigned char *out, const int w, const int h)
{
const unsigned int i = (blockIdx.x * blockDim.x) + threadIdx.x;
//Don't do edges!
if(
i < w //first row
|| i >= (w * (h - 1)) // last row
|| !(i % w) // first column
|| (i % w + 1 == w) // last column
)
{
out[i] = 0;
return;
}
unsigned char
code = 0,
center = in[i];
code |= (in[i-w-1] > center) << 7;
code |= (in[i-w ] > center) << 6;
code |= (in[i-w+1] > center) << 5;
code |= (in[i +1] > center) << 4;
code |= (in[i+w+1] > center) << 3;
code |= (in[i+w ] > center) << 2;
code |= (in[i+w-1] > center) << 1;
code |= (in[i -1] > center) << 0;
out[i] = code;
}
// A proxi function
void DoLBP(unsigned char *in, unsigned char *out, const int w, const int h)
{
const int
sz = w * h * sizeof(unsigned char);
unsigned char
*in_gpu,
*out_gpu;
cudaMalloc((void**)&in_gpu, sz);
cudaMalloc((void**)&out_gpu, sz);
cudaMemcpy(in_gpu, in, sz, cudaMemcpyHostToDevice);
cudaMemcpy(out_gpu, out, sz, cudaMemcpyHostToDevice);
dim3 threadsPerBlock(1024); //Max
dim3 numBlocks(w*h/threadsPerBlock.x + 1);
LBP<<<numBlocks,threadsPerBlock>>>(in_gpu, out_gpu, w, h);
cudaMemcpy(out, out_gpu, sz, cudaMemcpyDeviceToHost);
cudaFree(in_gpu);
cudaFree(out_gpu);
}
//The caller
int main()
{
printf("Starting\n");
const int
w = 4000,
h = 2000;
unsigned char
in[w*h],
out[w*h];
// Fill [in] with some data
DoLBP(in, out, w, h);
// Use [out] data
return 0;
}
图像作为 *unsigned char*s (array = [[row 1] [row 2] [row 3] ... [row n]]) 的单维数组传递给 GPU(它们是从 OpenCV 的 Mat 中提取的)
问题
此代码适用于相对较小的图像,它返回填充了正确值的输出数组但是当图像大小增加时,输出数组全部归零!
我的怀疑是图像数据溢出了一些 GPU 缓冲区或类似的东西。
我也不清楚 numberOfBlocks 和 threadsPerBlock 部分是如何工作的!如果你们中的任何人能就此提供一些基本的见解,我们将不胜感激。
(我在 CUDA 中就像 1 天大,所以可能有太多方法可以改进这个 sn-p 代码!)
【问题讨论】:
标签: c++ cuda parallel-processing gpu nvidia