推动不调用设备功能

时间:2015-07-28 18:27:32

标签: cuda thrust

我遵循简单的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;
}

我在这里做错了什么?

1 个答案:

答案 0 :(得分:2)

thrust quick start guide有很好的例子可供使用。

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

  1. 如果您想使用推力,则应使用thrust::transform,而不是std::transformstd::transform不知道GPU或CUDA或推力,并会调度add函数的主机版本。我不确定将thrust::device_vector传递给它时会发生什么。

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

  3. 以下是对您的代码的修改:

    $ 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
    $