CUDA 点积

标签 cuda dot-product

我正在尝试为 double 组实现经典的点积内核,并对各个 block 的最终总和进行原子计算。正如编程指南第 116 页所述,我使用atomicAdd 来实现 double 。可能我做错了什么。每个 block 中线程的部分总和计算正确,但事后原子操作似乎无法正常工作因为每次我使用相同的数据运行内核时,我都会收到不同的结果。如果有人能发现错误或提供替代解决方案,我将不胜感激! 这是我的内核:

__global__ void cuda_dot_kernel(int *n,double *a, double *b, double *dot_res)
{
    __shared__ double cache[threadsPerBlock]; //thread shared memory
    int global_tid=threadIdx.x + blockIdx.x * blockDim.x;
    int i=0,cacheIndex=0;
    double temp = 0;
    cacheIndex = threadIdx.x;
    while (global_tid < (*n)) {
        temp += a[global_tid] * b[global_tid];
        global_tid += blockDim.x * gridDim.x;
    }
    cache[cacheIndex] = temp;
    __syncthreads();
    for (i=blockDim.x/2; i>0; i>>=1) {
        if (threadIdx.x < i) {
            cache[threadIdx.x] += cache[threadIdx.x + i];
        }
        __syncthreads();
    }
    __syncthreads();
    if (cacheIndex==0) {
        *dot_res=cuda_atomicAdd(dot_res,cache[0]);
    }
}

这是我的设备函数atomicAdd:

__device__ double cuda_atomicAdd(double *address, double val)
{
    double assumed,old=*address;
    do {
        assumed=old;
        old= __longlong_as_double(atomicCAS((unsigned long long int*)address,
                    __double_as_longlong(assumed),
                    __double_as_longlong(val+assumed)));
    }while (assumed!=old);

    return old;
}

最佳答案

使用临时 CUDA 代码进行正确的缩减可能很棘手,因此这里有一个使用 Thrust 算法的替代解决方案,该算法包含在 CUDA 工具包中:

#include <thrust/inner_product.h>
#include <thrust/device_ptr.h>

double do_dot_product(int n, double *a, double *b)
{
  // wrap raw pointers to device memory with device_ptr
  thrust::device_ptr<double> d_a(a), d_b(b);

  // inner_product implements a mathematical dot product
  return thrust::inner_product(d_a, d_a + n, d_b, 0.0);
}

关于CUDA 点积,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9449541/

相关文章:

java - 余弦相似度

python - Cuda 并行化内核共享计数器变量

cuda - 如果我们有 GPGPU,为什么要使用 SIMD?

具有缺失值的 numpy 点积

python - PyTorch:逐行点积

Python numpy (einsum) 优化 : 1D to ND outer dot products

将字符数组从主机复制到设备后,CUDA: "Stack Overflow or Breakpoint Hit"和未指定的启动失败错误

performance - 比较 OpenCL 和 CUDA 程序的参数

caching - GPU L2 缓存命中率为 100%,DRAM 加载事务有时为 0

python - NumPy:一次对许多小矩阵进行点积