我无法理解为什么下面的程序运行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)吗?
我必须明白! 谢谢!
答案 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)。