【问题标题】:trouble calculating offset index into 3D array将偏移索引计算为 3D 数组时遇到问题
【发布时间】:2011-06-17 22:16:09
【问题描述】:

我正在编写一个 CUDA 内核来为 rows*cols 主矩阵中的每个位置创建一个 3x3 协方差矩阵。所以这个 3D 矩阵的大小是 rows*cols*9,我相应地分配在一个 malloc 中。我需要在单个索引值中访问它

3x3 协方差矩阵的 9 个值根据其他一些 2D 数组中的相应行 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]

谁能给我一些关于如何解决这个问题的提示?是索引问题,还是其他逻辑错误?

【问题讨论】:

    标签: c++ arrays indexing multidimensional-array cuda


    【解决方案1】:

    这里是我通常用于调试这类问题的技术,而不是答案(我还没有仔细寻找)。首先,将目标数组中的所有值设置为 NaN。 (您可以通过 cudaMemset 执行此操作——将每个字节设置为 0xFF。)然后尝试将每个位置统一设置为行的值,然后检查结果。理论上,它应该类似于:

    0 0 0 ... 0
    1 1 1 ... 1
    . . . .   .
    . . .  .  .
    . . .   . .
    n n n ... n
    

    如果您看到 NaN,则说明您未能写入元素;如果您看到行元素不合适,则说明出了点问题,并且它们通常会以暗示的方式不合适。对列值和平面执行类似的操作。通常,这个技巧可以帮助我发现部分索引计算有问题,这是大部分的战斗。希望对您有所帮助。

    【讨论】:

      【解决方案2】:

      我可能只是愚蠢,但这句话的逻辑是什么?

      int ndx = r*cols*rows + c*cols;
      

      你不应该有

      int ndx = offset*9;
      

      如果您说协方差数组的大小是 rows*cols*9,那么 offset*9 不会将您带到 3D 协方差数组中与您在输入数组中的位置相同的位置。那么 offset*9+0 将是偏移处元素的 3x3 协方差矩阵的位置 (0,0),offset*9+1 将是 (0,1),offset*9+2 将是 (0, 2), offset*9+3 将是 (1,0) 等等,直到 offset*9+8。

      【讨论】:

      • 我认为这是不正确的。它不适用于空间中的下一个“平面”
      猜你喜欢
      • 2018-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 2023-03-06
      • 2016-08-05
      • 1970-01-01
      相关资源
      最近更新 更多