2012-12-22 181 views
4

EDITED與鏈接問題後的當前狀態對應。CUDA C矩陣乘法

我目前正試圖在CUDA中重新實現基本的矩陣乘法,而我的代碼對於Square矩陣和尺寸爲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,烏鴉*的sizeof(浮點)* CColumns,cudaMemcpyDeviceToHost);

現在我已經重複了我的算法,我不相信它有什麼問題,所以我個人認爲我使用的塊/網格大小方案可能有問題。如果有人更瞭解CUDA/C,那麼我可以(Ruby/JavaScript的人)來看看它,然後逐步瞭解我做錯了什麼,我將非常感激。

+0

[這個問題](http://stackoverflow.com/questions/13896560/multiply-rectangular-matrices-kernel)可能是感興趣的。 –

+1

爲什麼我們需要所有的行和列變量?不要numARows,ARows,CRows,都必須是相同的數字?同樣適用於BColumns和CColums。無論如何,因爲事物的尺寸可以被8整除,我的猜測是當尺寸不能被8整除時(在邊界上強制額外的塊),一些線程沒有被正確關閉。所以我會把重點放在這一行上:if((Row

+0

所有這些輸入參數都是由教師給出的模板代碼的一部分。 –

回答

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; 
+0

謝謝! 我有一個問題是,是否有一個原因,你設置後的事實,而不是隨着網格初始化他們的X和Y值? 此外,這種方法是更高效的天花板/演員,還是有不同的理由這樣做? –

+0

不,沒有理由。它僅用於代碼可讀性。再次不,它只是保存一個函數調用。 – sgarizvi