cuda - Cuda C 中的加法赋值运算符

标签 cuda gpgpu gpu pycuda

我在 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]。任何人都可以提出解决方案吗?

最佳答案

问题出在您的内核中,您使用 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]);
}

以相同的方式启动内核,但不要忘记传递 n,它是 a 或 b 的大小。
您还可以在启动内核时消除 n 并更改线程块维度。

关于cuda - Cuda C 中的加法赋值运算符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13341110/

相关文章:

javascript - 获取 CPU/GPU/内存信息

c++ - 如何在 MacOS 上的 C++ 计算中使用双 AMD FirePro D300 的 GPU?

cuda - 安装多个版本的 CUDA 和 cuDNN

在 Cuda 内核中调用 Opencv 函数

three.js - 如何在 THREE.js 中为可旋转的毛茸茸的球制作动画?

iphone - 在 iPhone 上进行 GPU 加速计算 (GPGPU) 的资源?

opencl - GPU中缓存未命中的变化

c++ - 具有多个阵列的共享内存的 CUDA 减少

c++ - visual studio 中的 cublas 链接

python - tensorflow 的 XLA_GPU 和 XLA_CPU 是什么