当我尝试访问CUDA内核中的每个矩阵点时,我遇到了问题。我正在使用OpenCV,我正试图在矩阵的每个点上“做点什么”。
所以,我正在将uint8_t
矩阵转换为float
矩阵,如下所示:
for(int i=0; i<inputMatrix.rows; ++i){
for(int j=0; j<inputMatrix.cols * cn; j+=cn){
examMatrix[i*inputMatrix.cols*cn + j + 0] = pixelPtr[i*inputMatrix.cols*cn + j + 0]; // B
examMatrix[i*inputMatrix.cols*cn + j + 1] = pixelPtr[i*inputMatrix.cols*cn + j + 1]; // G
examMatrix[i*inputMatrix.cols*cn + j + 2] = pixelPtr[i*inputMatrix.cols*cn + j + 2]; // R
}
}
这适用于3通道图像,如果我从该矩阵创建输出图像(在转换为uint8_t
之后)看起来与输入相同。
但我想使用CUDA进行一些更改:
我像这样设置块大小和网格大小:
dim3 dimBlock(count, 3);
dim3 dimGrid( frameHeight/count, frameWidth/count);
count
是主题号,3
是通道号,frameHeight
和frameWidth
是帧大小。
所以,我分配了GPUexamMatrix
和GPUresultMatrix
并尝试访问内核中的每个点。我的内核看起来像这样:
resultMatrix[(blockIdx.x * blockIdx.y) + (threadIdx.x * threadIdx.y)] = examMatrix[(blockIdx.x * blockIdx.y) + (threadIdx.x * threadIdx.y)];
所以,正如你所看到的,我试图简单地复制矩阵。在这个操作之后,当我将矩阵返回到主机并打印出来时,矩阵内部的数字非常小或非常大float
,而不是检查矩阵中的数字。
我想我在内核中做错了什么。有什么想法吗?
答案 0 :(得分:1)
您对内置变量的使用可能不正确。举一个简单的例子,threadIdx.x = 0和threadIdx.y = 2将访问与threadIdx.x = 2和threadIdx.y = 0相同的点。您没有唯一的索引。我可以尝试给你一些可行的东西,但我对你的dimBlock变量感到有些困惑。简而言之,这不是我如何设置网格/块/索引来处理2D数组。我不会在我的threadblock尺寸标注
中使用3,即频道编号尝试这样的事情:
// make sure count is small like 16: count*count<512 or 1024 depending on GPU
dim3 dimBlock(count, count);
dim3 dimGrid( frameWidth/dimBlock.x, frameHeight/dimBlock.y);
并在你的内核中:
int row = threadIdx.y + blockIdx.y*blockDim.y;
int col = threadIdx.x + blockIdx.x*blockDim.x;
resultMatrix[3*(row*frameWidth + col) + 0] = examMatrix[3*(row*frameWidth + col) + 0];
resultMatrix[3*(row*frameWidth + col) + 1] = examMatrix[3*(row*frameWidth + col) + 1];
resultMatrix[3*(row*frameWidth + col) + 2] = examMatrix[3*(row*frameWidth + col) + 2];
上述假设frameWidth
和frameHeight
可被count