0

我不明白为什么下面的程序对于 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)

- - - - - - - 编辑 - - - - - - - - - - - - - - - - - - -----

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

但是,那么,我总是必须使用这个排列块(N,1,1)吗?

我必须明白这一点!谢谢!

4

2 回答 2

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;

或更准确地说(仅当使用 Z > 1 的 block(X, Y, Z) 时)

idx = (blockDim.y * threadIdx.z +  threadIdx.y) * blockDim.x + threadIdx.x;
于 2012-08-30T00:19:28.540 回答
-2

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

你应该能够使用(1,N,1)。

于 2012-08-29T16:19:43.423 回答