我正在编写一个 CUDA 内核来为 rows*cols 主矩阵中的每个位置创建一个 3x3 协方差矩阵。因此 3D 矩阵的大小为 rows*cols*9,我相应地在单个 malloc 中分配了它。我需要在单个索引值中访问它
3x3 协方差矩阵的 9 个值根据一些其他二维数组的相应行 r 和列 c 获取它们的值。
换句话说 - 我需要计算适当的索引来访问 3x3 协方差矩阵的 9 个元素,以及作为值输入的 2D 矩阵的行和列偏移量,以及适当的索引用于存储阵列。
我已尝试将其简化为以下内容:
//I am calling this kernel with 1D blocks who are 512 cols x 1row. TILE_WIDTH=512
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int r = by + ty;
int c = bx*TILE_WIDTH + tx;
int offset = r*cols+c;
int ndx = r*cols*rows + c*cols;
if((r < rows) && (c < cols)){ //this IF statement is trying to avoid the case where a threadblock went bigger than my original array..not sure if correct
d_cov[ndx + 0] = otherArray[offset];//otherArray just contains a value that I might do some operations on to set each of the ndx0-ndx9 values in d_cov
d_cov[ndx + 1] = otherArray[offset];
d_cov[ndx + 2] = otherArray[offset];
d_cov[ndx + 3] = otherArray[offset];
d_cov[ndx + 4] = otherArray[offset];
d_cov[ndx + 5] = otherArray[offset];
d_cov[ndx + 6] = otherArray[offset];
d_cov[ndx + 7] = otherArray[offset];
d_cov[ndx + 8] = otherArray[offset];
}
当我用在 CPU 上计算的值检查这个数组时,循环 i=rows, j=cols, k = 1..9
结果不匹配。
换句话说 d_cov[i*rows*cols + j*cols + k] != correctAnswer[i][j][k]
任何人都可以给我任何关于如何解决这个问题的提示吗?是索引问题,还是其他逻辑错误?
最佳答案
这里不是答案(我还没有认真地寻找答案),而是我通常用来调试这类问题的技术。首先,将目标数组中的所有值设置为 NaN。 (您可以通过 cudaMemset 执行此操作——将每个字节设置为 0xFF。)然后尝试将每个位置统一设置为行的值,然后检查结果。理论上,它应该看起来像:
0 0 0 ... 0
1 1 1 ... 1
. . . . .
. . . . .
. . . . .
n n n ... n
如果您看到 NaN,则说明您未能写入元素;如果您看到行元素错位,则说明有问题,并且它们通常会以暗示性模式错位。对列值和平面执行类似的操作。通常,这个技巧可以帮助我发现部分索引计算出错,这是大部分的战斗。希望对您有所帮助。
关于c++ - 无法将偏移索引计算到 3D 数组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4840110/