2012-08-29 24 views
0

我不明白爲什麼下面的程序對於block = N,1,1運行正常,但對於1,1,N(結果是無效值)或1, N,1(結果是0,1,0 ..... 0) 或10,50,1(結果是0,1,0..0)(N = 500)。pycuda only block(N,1,1)

import pycuda.gpuarray as gpuarray 
import pycuda.driver as cuda 
import pycuda.autoinit 
from pycuda.compiler import SourceModule 
import numpy as np 
import random 
from pycuda.curandom import rand 
import cmath 
import pycuda.driver as drv 


N=500 
a_gpu=gpuarray.to_gpu(np.zeros(N).astype(np.int32)) 

mod =SourceModule(""" 
#include <cmath> 

extern "C" {  

__global__ void myfunc(int *a,int N) 
    { 

    int idx=threadIdx.x; //+blockIdx.x*blockDim.x; 

    if (idx<N) 
      a[idx]=idx; 

} 
} 

""",no_extern_c=1) 

#call the function(kernel) 
func = mod.get_function("myfunc") 

func(a_gpu,np.int32(N), block=(N,1,1),grid=(1,1)) 

a=a_gpu.get() 
print("a = ",a) 

--------------編輯--------------------------- --------------解決方案-------------

好吧,我忘了,如果我使用int idx = threadIdx.y,那麼我可以使用塊(1,N,1)。

但是,總是我必須使用這個排列塊(N,1,1)?

我必須明白! 謝謝!

+0

塊的第三維限制爲64個線程,並且塊中的線程總數爲512或1024,具體取決於您的GPU。所有在文檔中,如果你喜歡閱讀它 – talonmies

+0

我編輯了我的文章(自20分鐘前):)。我不明白的事情,我必須總是使用(N,1,1)安排?謝謝! – George

回答

1

第一維對應於threadIdx.x,第二與threadIdx.y和第三與threadIdx.z

當您啓動塊(N,1,1)threadIdx.x從0到N,而threadIdx.y和threadIdx.z總是爲零。

當您啓動塊(1,N,1)threadIdx.x總是爲零,threadIdx.y從0到N.

所以代替具有

idx = threadIdx.x; 

更改它

idx = blockDim.x * threadIdx.y + threadIdx.x; 

或更精確地(僅當使用塊(X,Y,Z)以Z> 1)

idx = (blockDim.y * threadIdx.z + threadIdx.y) * blockDim.x + threadIdx.x; 
+0

您的最後一個示例無法正常工作。我找到了idx = threadIdx.x + threadIdx.y * blockDim.x + threadIdx.z * blockDim.x * blockDim.y;這工作ok.And謝謝,我現在意識到它應該如何工作。也許你可以幫我這個嗎?http://stackoverflow.com/questions/12159709/cuda-out-of-memory-threads-and-blocks-issue – George

+0

@george,謝謝你指出。我有blockIdx而不是blockDim。現在修復代碼。 – ashokk

-2

如果我還記得,第三個值只限於2或3這樣的小數字!

你應該可以使用(1,N,1)。

+0

塊的第三維限制爲64 – talonmies