4

CudaCで加算代入演算子の問題が発生しています。次のエラーが発生します。

kernel.cu(5): error: expression must have integral or enum type

私のコードは:

import pycuda.driver as drv
import pycuda.autoinit
from pycuda.compiler import SourceModule
import numpy as np

mod=SourceModule("""
__global__ void addition(float* a,float* b,float*c){
int i=threadIdx.x + blockIdx.x * blockDim.x;
c[a[i]]+=b[i];
}
""")

addition=mod.get_function("addition")
a=np.array([1,2,3,1,2,3,2,1]).astype(np.float32)
b=np.array([0.1,0.2,0.1,0.5,0.1,0.2,0.1,0.5]).astype(np.float32)
c=np.zeros_like(a)
addition(drv.Out(c),drv.In(a),drv.In(b),block=(32,1,1))
print c

私の希望する出力はc=[0,1.1,0.4,0.3,0,0,0,0]です。誰かが解決策を提案できますか?

4

1 に答える 1

1

問題は、Aを使用してCでインデックスを作成するカーネルにあります
。Aはfloat型です。

また、32スレッドを起動していますが、8つの位置でのみインデックスを作成することに注意してください。これは、範囲外でインデックスを作成することを意味します。

直面する最後の問題は、aのインデックスが重複しているために、複数のスレッドがCの同じ位置を変更しようとすることです。これを修正する1つの方法は、AtomicAddを使用することです。

__global__ void addition(float* a,float* b,float*c, int n)
{
int i=threadIdx.x + blockIdx.x * blockDim.x;
if(i < n)
atomicAdd(&c[(int)a[i]],b[i]);
}

同じ方法でカーネルを起動しますが、aま​​たはbのサイズであるnを渡すことを忘れないでください。
カーネルを起動するときに、nを削除して、スレッドブロックの次元を変更することもできます。

于 2012-11-12T09:30:49.260 に答える