2011-01-29 10 views
1

私はCUDAカーネルを作成して、rows * colsメイン行列の各位置の3x3共分散行列を作成しています。したがって、3D行列は、* mallocに応じて割り当てられた行* cols * 9です。これを1つのインデックス値でアクセスする必要がありますオフセット配列を3D配列に計算する

3x3共分散行列の9個の値は、他の2D配列の適切な行rと列cに従って値を設定します。

つまり、3x3共分散行列の9要素にアクセスするための適切なインデックスと、値への入力である2D行列の行と列のオフセットと、適切なインデックスを計算する必要がありますストレージアレイのインデックス。

iは、以下にそれを簡素化することを試みた:

//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は、I =行、J = COLS、K = 1をループCPUで計算された値、この配列を確認

。 .9

結果が一致しません。言い換えれば

がd_cov [iの行を* * colsの+ J * colsの+ K]!= correctAnswer [I] [J] [K]

誰かが私にこの問題をsovleする方法上の任意のヒントを与えることはできますか?それは索引付けの問題か他の何らかの論理エラーですか?

答えて

1

答え(これは私が見つけ出すのに十分なほど熱心ではなかった)ではなく、これらの種類の問題をデバッグするために通常使用する技術です。まず、出力先配列のすべての値をNaNに設定します。 (これは、cudaMemsetで行うことができます - すべてのバイトを0xFFに設定します)。次に、すべての場所を行の値に一律に設定してから、結果を調べます。理論的には、次のようになります。

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

NaNが表示された場合は、要素に書き込めません。行要素が適切でない場合、何かが間違っていて、通常は暗示的なパターンで適切ではありません。列の値と同じようなやり方でプレーンを実行します。通常、このトリックは、インデックス計算の一部が間違っていることを見つけるのに役立ちます。これはほとんどの戦闘です。希望が役立ちます。

0

私はばかげたかもしれませんが、この行の論理は何ですか?あなたは共分散配列のサイズは、* COLS * 9は、その後、* 9は、同じ場所でであなたを取るオフセットではないでしょう行と言った場合

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

あなたは

int ndx = offset*9; 

を持つべきではありません入力配列のどこに3D共分散配列を置いていますか?したがって、オフセット* 9 + 1はオフセットの要素の3x3共分散行列の位置(0,0)になります。オフセット* 9 + 1は(0,1)、オフセット* 9 + 2は(0、 2)、オフセット* 9 + 3は(1,0)、オフセット* 9 + 8まで続きます。

+0

これは間違っていると思います。宇宙の次の「飛行機」では機能しません – Derek