4

リンクされた質問の後に現在の状態に対応するように編集されました。

現在、CUDA で基本的な行列乗算を再実装しようとしています。私のコードは正方行列と、次元が 8 の倍数である四角形行列では正常に機能しますが、次元が 8 の倍数ではない四角形行列では機能しないようです。

以下は、私のカーネル乗算関数です。

 __global__ void matrixMultiply(float * A, float * B, float * C,
               int numARows, int numAColumns,
               int numBRows, int numBColumns,
               int numCRows, int numCColumns) {
    int Row = blockIdx.y * blockDim.y + threadIdx.y;
    int Col = blockIdx.x * blockDim.x + threadIdx.x;
    if (numAColumns != numBRows) return ;
    if ((Row < numARows) && (Col < numBColumns)){
        float Cvalue = 0;
        for (int k = 0 ; k < numAColumns ; ++k )
            Cvalue += A[Row*numAColumns + k] * B[k * numBColumns + Col];
        C[Row*numCColumns + Col] = Cvalue;
    }

}

以下はメモリ割り当てです(読みやすくするためにエラーチェックを省略しています):

cudaMalloc((void**) &deviceA, ARows*sizeof(float)*AColumns);
cudaMalloc((void**) &deviceB, BRows*sizeof(float)*BColumns);
cudaMalloc((void**) &deviceC, CRows*sizeof(float)*CColumns);
cudaMemcpy(deviceA, hostA, ARows*sizeof(float)*AColumns, cudaMemcpyHostToDevice);
cudaMemcpy(deviceB, hostB, BRows*sizeof(float)*BColumns, cudaMemcpyHostToDevice);
cudaMemcpy(deviceC, hostC, CRows*sizeof(float)*CColumns, cudaMemcpyHostToDevice);

以下は呼び出しですが:

dim3 dimGrid((int)ceil(numCRows / 8.0) , (int)ceil(numCColumns / 8.0), 1);
dim3 dimBlock(8 , 8, 1);
multiplyMatrices<<<dimGrid,dimBlock>>>(deviceA, deviceB, deviceC, numARows, AColumns, BRows, BColumns, CRows, CColumns);

最後にメモリを元に戻します: cudaMemcpy(hostC, deviceC, CRows*sizeof(float)*CColumns, cudaMemcpyDeviceToHost);

今、私は自分のアルゴリズムを繰り返しトレースしましたが、何か問題があるとは思わないので、個人的には、私が使用したブロック/グリッドのサイズ設定スキームに何か問題があるのではないかと考えています. CUDA/C を私よりもよく知っている人 (ここでは Ruby/JavaScript 担当者) がそれを見て、私が間違っていることの正確な原因を教えてくれれば、とても感謝しています。

4

1 に答える 1

3

問題は、作成しているグリッド サイズにあります。

dim3 dimGrid((int)ceil(numCRows / 8.0) , (int)ceil(numCColumns / 8.0), 1);

行は行列の Y 次元であり、列は X 次元であるため、実際には転置されたグリッドを作成しています。

正しいグリッドを作成するには、次の手順を実行します。

dim3 dimGrid((int)ceil(numCColumns / 8.0) , (int)ceil(numCRows / 8.0), 1);

より良いアプローチは、次のことを行うことです。

dim3 dimGrid;

dimGrid.x = (numCColumns + dimBlock.x - 1)/dimBlock.x;

dimGrid.y = (numCRows + dimBlock.y - 1)/dimBlock.y;
于 2012-12-23T17:30:50.270 に答える