проблема расчета индекса смещения в 3D массив - PullRequest
1 голос
/ 30 января 2011

Я пишу ядро ​​CUDA для создания ковариационной матрицы 3x3 для каждого местоположения в основной матрице строк * столбцов.Таким образом, эта трехмерная матрица имеет размер строк * cols * 9, которые я выделил в одном malloc соответственно.Мне нужно получить доступ к этому в одном значении индекса

, 9 значений ковариационной матрицы 3x3 получают свои значения, установленные в соответствии с соответствующей строкой r и столбцом c из некоторых других двумерных массивов.

Другими словами - мне нужно рассчитать соответствующий индекс для доступа к 9 элементам ковариационной матрицы 3x3, а также к смещению строк и столбцов 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];  
   }

Когда я проверяю этот массив со значениями, рассчитанными на ЦП, который зацикливается наi = строки, j = столбцы, k = 1..9

Результаты не совпадают.

другими словами d_cov [i * row * cols + j * cols + k]! = correctAnswer [i] [j] [k]

Может кто-нибудь дать мне какие-нибудь советы о том, как решить эту проблему?Это проблема индексации или какая-то другая логическая ошибка?

Ответы [ 2 ]

1 голос
/ 30 января 2011

Вместо ответа (который я не выглядел достаточно усердно, чтобы найти), вот техника, которую я обычно использую для отладки такого рода проблем.Сначала установите все значения в вашем целевом массиве на NaN.(Вы можете сделать это с помощью cudaMemset - установите для каждого байта значение 0xFF.) Затем попробуйте равномерно установить для каждого местоположения значение строки, а затем проверьте результаты.Теоретически, это должно выглядеть примерно так:

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

Если вы видите NaN, вам не удалось записать элемент;если вы видите элементы строки не на своем месте, что-то не так, и они, как правило, будут неуместны в виде подсказок.Сделайте что-то подобное со значением столбца и с плоскостью.Обычно этот трюк помогает мне обнаружить, что часть расчета индекса ошибочна, что составляет большую часть битвы.Надеюсь, это поможет.

0 голосов
/ 30 января 2011

Я могу быть просто глуп, но какова логика в этой строке?

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

Разве у вас не должно быть

int ndx = offset*9;

Если бы вы сказали, что размер вашей ковариациимассив был строк * cols * 9, тогда не будет смещения * 9 приведет вас в том же месте в массиве 3D ковариации, что и в вашем входном массиве.Тогда смещение * 9 + 0 будет местом (0,0) ковариационной матрицы 3x3 элемента со смещением, смещение * 9 + 1 будет (0,1), смещение * 9 + 2 будет (0,2) смещение * 9 + 3 будет равно (1,0) и т. Д. До смещения * 9 + 8.

...