我遵循简单的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;
}
我在这里做错了什么?
答案 0 :(得分:2)
thrust quick start guide有很好的例子可供使用。
看起来你有几个问题,有些问题已经指出过了。
如果您想使用推力,则应使用thrust::transform
,而不是std::transform
。 std::transform
不知道GPU或CUDA或推力,并会调度add
函数的主机版本。我不确定将thrust::device_vector
传递给它时会发生什么。
由于Jared指出的原因,推力算法需要使用函数对象(仿函数)而不是裸露的CUDA __device__
函数(源代码中的推力算法实际上是主机代码。主机代码不能发现裸__device__
函数的地址。通过此修复,您可以非常肯定推力将在处理设备向量时调度设备代码路径。
以下是对您的代码的修改:
$ 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
$