2011-05-27 59 views
3

我試圖調試我有我的CUDA機器上的指標問題CUDAFunctionLoad在數學 - 索引問題

Cuda Machine Info: 

{1 - > {名稱 - >特斯拉C2050,時鐘速率 - > 1147000,計算能力 - > 2,GPU重疊 - > 1,最大塊尺寸 - > {1024,1024,64},最大柵格尺寸 - > {65535,65535,65535},每塊最大線程數 - > 1024,最大共享內存每塊 - > 49152,總恆定存儲器 - > 65536,變形大小 - > 32,最大間距 - > 2147483647,每塊最大寄存器 - > 32768,紋理對齊 - > 512,多處理器計數 - > 14,核心計數 - > 448 ,執行超時 - > 0,集成 - >錯誤,可映射主機內存 - >真,計算模式 - >默認,紋理1D寬度 - > 65536,紋理2D W width2> 65536,Texture2D Height-> 65535,Texture3D Width-> 2048,Texture3D Height-> 2048,Texture3D Depth-> 2048,Texture2D Array Width-> 16384,Texture2D Array Height-> 16384,Texture2D Array Slices-> 2048,表面Alignment-> 512,併發Kernels-> True時,ECC Enabled-> True時,總內存 - > 2817982462},

所有這些代碼也被設定以3D陣列的等於CUDA是索引值使用:

__global __ void cudaMatExp(
float *matrix1, float *matrixStore, int lengthx, int lengthy, int lengthz){ 

long UniqueBlockIndex = blockIdx.y * gridDim.x + blockIdx.x; 

long index = UniqueBlockIndex * blockDim.z * blockDim.y * blockDim.x + 
    threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + 
    threadIdx.x; 

if (index < lengthx*lengthy*lengthz) { 

matrixStore[index] = index; 

} 
} 

由於某些原因,一旦3D數組的維度變得過大,索引停止。

我已經嘗試了不同的塊尺寸(blockDim.x由blockDim.y由blockDim.z):

8x8x8只給出了正確的索引到陣列尺寸12x12x12

9x9x9只給出了正確的索引到陣列尺寸14x14x14

10x10x10只給出了正確的索引達陣尺寸15x15x15

對於尺寸比這些更大的所有塊大小不同,最終再次開始增加,但他們從未達到暗淡的值^ 3-1(其是在CUDA線程應該達到最大索引)

下面是一些曲線圖展示了此行爲:

例如:這是在x軸上標繪3D陣列的尺寸(x是x x x),y軸是在cuda執行過程中處理的最大索引編號。這個特殊的情節是爲10x10x10的塊尺寸。

enter image description here

這裏是(數學)碼來生成的情節,但是當我跑這一個,我使用的1024x1x1塊尺寸:

CUDAExp = CUDAFunctionLoad[codeexp, "cudaMatExp", 
    {{"Float", _,"Input"}, {"Float", _,"Output"}, 
    _Integer, _Integer, _Integer}, 
    {1024, 1, 1}]; (*These last three numbers are the block dimensions*) 

max = 100; (* the maximum dimension of the 3D array *) 
hold = Table[1, {i, 1, max}]; 
compare = Table[i^3, {i, 1, max}]; 
Do[ 
    dim = ii; 
    AA = CUDAMemoryLoad[ConstantArray[1.0, {dim, dim, dim}], Real, 
            "TargetPrecision" -> "Single"]; 
    BB = CUDAMemoryLoad[ConstantArray[1.0, {dim, dim, dim}], Real, 
            "TargetPrecision" -> "Single"]; 

    hold[[ii]] = Max[Flatten[ 
        CUDAMemoryGet[CUDAExp[AA, BB, dim, dim, dim][[1]]]]]; 

, {ii, 1, max}] 

ListLinePlot[{compare, Flatten[hold]}, PlotRange -> All] 

這是相同的情節,但是現在繪製x^3來比較它應該在哪裏。請注意,它的發散之後陣列的尺寸爲> 32

enter image description here

我測試的3D陣列的尺寸,並期待在索引走多遠,並與暗淡^ 3-1比較。例如。對於dim = 32,cuda最大索引是32767(即32^3 -1),但對於dim = 33,當cuda輸出應該是35936(33^3 -1)時,cuda輸出爲33791。注意33791-32767 = 1024 = blockDim。X

問題:

有一種方法來正確索引尺寸小於在數學塊尺寸大的陣列?

現在,我知道有些人在他們的索引公式中使用了__mul24(threadIdx.y,blockDim.x)來防止位乘法錯誤,但它似乎對我的情況沒有幫助。

另外,我看到有人提到你應該用-arch = sm_11編譯你的代碼,因爲默認情況下它是爲計算能力1.0編譯的。雖然我不知道Mathematica是否屬於這種情況。我會假設CUDAFunctionLoad []知道用2.0的能力進行編譯。任何人都知道?

任何建議將是非常有益的!

+0

歡迎來到stackoverflow Krukrupol!不要忘記爲自己喜歡的下面的答案投票,如果其中一方回答您的問題並達到您的滿意程度,請使用答案旁邊的複選標記接受答案。只要你喜歡,你可以改變你的選擇。 – 2011-05-27 21:42:59

+0

看來imgur網站的鏈接已經死亡。你可以再試一次,還是使用其他網站? – 2011-05-28 10:58:21

+0

謝謝你修復圖像誰做了:) – krukrupol 2011-05-28 17:04:17

回答

1

因此,Mathematica有一種處理網格尺寸的隱藏方式,爲了將網格尺寸固定爲可以工作的東西,必須在調用的函數的末尾添加另一個數字。

參數表示要啓動的線程數(或網格維度時間塊維度)。

例如,在上述我的代碼:

CUDAExp = 
    CUDAFunctionLoad[codeexp, 
    "cudaMatExp", { 
      {"Float", _, "Input"}, {"Float", _,"Output"}, 
         _Integer, _Integer, _Integer}, 
    {8, 8, 8}, "ShellOutputFunction" -> Print]; 

(8,8,8)表示塊的尺寸。

當你在Mathematica中調用CUDAExp[],您可以添加表示線程數推出的說法:

在這個例子中,我終於得到它具有以下工作:

// AA and BB are 3D arrays of 0 with dimensions dim^3 
dim = 64; 
CUDAExp[AA, BB, dim, dim, dim, 4089]; 

注當你使用CUDAFunctionLoad []進行編譯時,它只需要5個輸入,第一個是你傳遞它的數組(尺寸dim x dim x dim),第二個是存儲內存的地方。第三,第四和第五是尺寸。

當你把它傳遞給第6個時,mathematica將它翻譯爲gridDim.x * blockDim.x,所以,因爲我知道我需要gridDim.x = 512以便處理數組中的每個元素,所以我將這個數設置爲512 * 8 = 4089.

我希望這對於將來會遇到此問題的人來說是清楚而有用的。