私は並列プログラミングとスタックオーバーフローに非常に慣れていません。CUDA を使用した行列乗算の実装に取り組んでいます。行列表現として列順浮動小数点配列を使用しています。
私が開発したアルゴリズムは少しユニークで、次のようになります。行列 nxm 行列 A と mxk 行列 B を指定して、各ブロックに m スレッドを含む nxk ブロックを起動します。基本的に、結果の行列のすべてのエントリに対してブロックを起動し、各スレッドでそのエントリの 1 つの乗算を計算します。例えば、
1 0 0 0 1 2
0 1 0 * 3 4 5
0 0 1 6 7 8
結果のマトリックスの最初のエントリでは、各スレッドを次のように起動します
スレッド 0 コンピューティング 1 * 3 スレッド 1 コンピューティング 0 * 0 スレッド 2 コンピューティング 0 * 1
各スレッドが 0 で初期化されたマトリックスに追加されます。今のところ、正しい答えが得られていません。私はこれを何度も繰り返しています
0 0 2
0 0 5
0 0 8
私のカーネル関数は以下です。これはスレッド同期の問題でしょうか、それとも配列のインデックス付けなどを台無しにしていますか?
/*@param d_A: Column order matrix
*@param d_B: Column order matrix
*@param d_result: 0-initialized matrix that kernels write to
*@param dim_A: dimensionality of A (number of rows)
*@param dim_B: dimensionality of B (number of rows)
*/
__global__ void dot(float *d_A, float *d_B, float *d_result, int dim_A, int dim_B) {
int n = blockIdx.x;
int k = blockIdx.y;
int m = threadIdx.x;
float a = d_A[(m * dim_A) + n];
float b = d_B[(k * dim_B) + m];
//d_result[(k * dim_A) + n] += (a * b);
syncthreads();
float temp = d_result[(k*dim_A) + n];
syncthreads();
temp = temp + (a * b);
syncthreads();
d_result[(k*dim_A) + n] = temp;
syncthreads();
}