我遇到了Cuda C中添加赋值运算符的问题。我收到以下错误:
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]。有谁能建议解决方案?
答案 0 :(得分:1)
问题出现在您的内核中,您使用A在C中进行索引 A是float类型。
另请注意,您正在启动32个线程,但您只会在8个位置编入索引,这意味着您将索引越界。
您将面临的最后一个问题是,由于a中的重复索引,多个线程会尝试更改C中的相同位置。解决它的一种方法是使用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并更改threadblock维度。