私が書きたいと思っていた簡単なプログラムのアイデアは、どのくらいの大きさの行列を乗算するかをユーザーから入力することです。CUDA Matrix Multiplicationが間違ったメモリ位置に書き込む
[email protected]:~/Desktop/multi$ ./program
What is the rowSize of a? 33
What is the colSize of a? 33
What is the rowSize of b? 33
What is the colSize of b? 33
Would you like to write the results to a file?(y or n)
y
Creating the random numbers now
Writing Matrix A to file now...
Writing Matrix B to file now...
Starting it on the device
Writing Matrix C to file now...
Finish
ただし、スレッドの計算に問題があります。私は32x32の行列に行くことができ、それは正常に実行され、私に正しい結果を与える。私は、次のような結果を得る33x33を実行したら、しかし:。
= [Matrix C] [Matrix A] X [Matrix B](代わりに、この記事にいくつかの巨大な行列を貼り付けるしかし、あなたはそれを通じてその半分の方法を書くために開始さ見ることができますcのマトリックスでそれらにリンクされています私のグラフィックスカードには32x32マトリックスの1024スレッドの制限があります。また、100x100マトリックスを実行すると、マトリックスCはすべて0です。
mem_size_Xをsizeof(float)* size_X、size_Xをブロックのサイズは32に対応します。
ホストコード(起動時) :
float* deviceMatrixA;
float* deviceMatrixB;
cudaMalloc((void**) &deviceMatrixA, mem_size_A);//allocate mem_size_x on the device.
cudaMalloc((void**) &deviceMatrixB, mem_size_B);
cudaMemcpy(deviceMatrixA, a.elements, mem_size_A, cudaMemcpyHostToDevice);
cudaMemcpy(deviceMatrixB, b.elements, mem_size_B, cudaMemcpyHostToDevice);
int size_C = c.rowSize * c.colSize;
int mem_size_C = sizeof(float) * size_C;
c.elements = (float*) malloc(mem_size_C);
float* deviceMatrixC;
cudaMalloc((void**) &deviceMatrixC, mem_size_C);
dim3 threads(block_size, block_size);
dim3 grid(c.colSize/threads.x, c.rowSize/threads.y);
matrixMul<<< grid, threads,2*block_size*block_size*sizeof(float)>>>(deviceMatrixC, deviceMatrixA, deviceMatrixB, a.colSize, b.colSize, block_size);//sizeof(float)*block_size*block_size
cudaThreadSynchronize();
カーネルコード:私はあなたのearlier, almost identical questionにあなたに言ったよう
// CUDA Kernel
__global__ void matrixMul(float* C, float* A, float* B, int wA, int wB,size_t block_size)
{
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int aBegin = wA * block_size * by;
int aEnd = aBegin + wA - 1;
int aStep = block_size;
int bBegin = block_size * bx;
int bStep = block_size * wB;
float Csub=0;
for (int a = aBegin, b = bBegin; a <= aEnd; a += aStep, b += bStep)
{
extern __shared__ float As[];
extern __shared__ float Bs[];
extern __shared__ float smem[];
smem[ty*block_size+tx] = A[a + wA * ty + tx];
smem[block_size*block_size+ty*block_size+tx] = B[b + wB * ty + tx];
__syncthreads();
for (int k = 0; k < block_size; ++k)
Csub += smem[ty*block_size+k] * smem[block_size*block_size+k*block_size+tx] ;
__syncthreads();
}
int c = wB * block_size * by + block_size * bx;
C[c + wB * ty + tx] = Csub;
}
おかげ
[行列の乗算CUDA](http:// stackoverflow)の可能な複写(http://stackoverflow.com/questions/8813750/matrix-multiplication-cuda) – talonmies
.com/questions/8813750/matrix-multiplication-cuda)、このコードは次元が 'block_size'の倍数である行列の計算を行うようにのみ設計されています。 'block_size = 32'を選択した場合、32x32、64x64、96x96、128x128などでしか使用できません。 – talonmies
それから、1x1から32x32はなぜ機能するのですか?すべてはキーボードで入力しますが、33では入力しません。だから私はあなたが言ったように64 x 64と128を128で試してみました。あなたがリンクしたスレッドで私のオリジナルの質問から元のコードを使用すると、128x128で動作します。 – Dan