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) を使用できることを忘れていました。

しかし、それでは、常にこの配置 block(N,1,1) を使用する必要がありますか?

私はそれを理解しなければなりません!ありがとうございました!

4

2 に答える 2

1

最初の次元は threadIdx.x に対応し、2 番目は threadIdx.y に対応し、3 番目は threadIdx.z に対応します。

block(N,1,1) を起動すると、threadIdx.x は 0 から N になり、threadIdx.y と threadIdx.z は常にゼロになります。

block(1, N, 1) を起動すると、threadIdx.x は常に 0 になり、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

覚えている限り、3 番目の値は 2 や 3 のような小さな数に制限されています。

(1,N,1) を使用できるはずです。

于 2012-08-29T16:19:43.423 に答える