pycuda only block(N,1,1)有效

时间:2012-08-29 15:53:05

标签: cuda pycuda

我无法理解为什么下面的程序运行ok = block,N,1,1但不适用于1,1,N(结果是无效值)或1,N,1(结果是0,1,0 ..... 0) 或10,50,1(结果为0,1,0..0)(N = 500)。

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)

-------------- EDIT ----------------------------- -----------

好的,我忘了,如果我使用int idx = threadIdx.y,那么我可以使用block(1,N,1)。

但是,那么,我一定要使用这个排列块(N,1,1)吗?

我必须明白! 谢谢!

2 个答案:

答案 0 :(得分:1)

第一个维度对应于threadIdx.x,第二个维度对应threadIdx.y,第三个维度对应threadIdx.z

当你启动block(N,1,1)时,threadIdx.x从0变为N,而threadIdx.y和threadIdx.z总是为零。

当你启动block(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;

答案 1 :(得分:-2)

如果我记得,第三个值仅限于2或3这样的小数字!

你应该可以使用(1,N,1)。