推力不调用设备功能

Thrust not calling device function

我有以下简单的 CUDA-Thrust 代码,它将 10 添加到设备向量,但该函数是在主机端而不是设备上调用的。

#include <algorithm>
#include <iostream>
#include <numeric>
#include <vector>
#include <stdio.h>
#include <thrust/device_vector.h>

__host__ __device__ int add(int x){
    #if defined(__CUDA_ARCH__)
     printf("In device\n");
    #else
     printf("In host\n");
    #endif

    return x+10;
}

int main(void)
{
    thrust::host_vector<int> H(4);
    H[0] = H[1] = H[2] = H[3] = 10;

    thrust::device_vector<int> data=H;

    std::transform(data.begin(), data.end(), data.begin(),add);
    return 0;
}

我做错了什么?

thrust quick start guide 有很好的榜样。

看起来你有几个问题,有些已经指出了。

  1. 如果要使用推力,应该使用thrust::transform,而不是std::transformstd::transform 不了解 GPU 或 CUDA 或 thrust,将调度您的 add 函数的主机版本。我不确定当您将 thrust::device_vector 传递给它时它会做什么。

  2. 推力算法需要使用函数对象(仿函数)而不是裸露的 CUDA __device__ 函数,原因由 Jared 指出(源代码中的推力算法实际上是主机代码。该主机代码无法发现裸 __device__ 函数的地址)。通过此修复,您可以非常确定 thrust 在处理设备向量时会分派设备代码路径。

这是对您的代码的修改:

$ cat t856.cu
#include <stdio.h>
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/transform.h>

struct my_func {

__host__ __device__
  int operator()(int x){
    #if defined(__CUDA_ARCH__)
     printf("In device, x is %d\n", x);
    #else
     printf("In host, x is %d\n", x);
    #endif

    return x+10;
  }
};

int main(void)
{
    thrust::host_vector<int> H(4);
    H[0] = H[1] = H[2] = H[3] = 10;

    thrust::device_vector<int> data=H;

    thrust::transform(data.begin(), data.end(), data.begin(),my_func());
    return 0;
}
$ nvcc -o t856 t856.cu
$ ./t856
In device, x is 10
In device, x is 10
In device, x is 10
In device, x is 10
$