我有以下简单的 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有很好的例子可供引用。
看起来您有几个问题,其中一些已经指出了。
如果你想使用推力,你应该使用
thrust::transform
,而不是std::transform
。std::transform
不了解 GPU 或 CUDA 或推力,并且将调度add
函数的主机版本。我不确定当您将thrust::device_vector
传递给它时,它会具体执行什么操作。推力算法需要使用函数对象(仿函数)而不是裸露的 CUDA
__device__
函数,原因由 Jared 指出(源代码中的推力算法实际上是主机代码。即主机代码无法发现裸__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
$
关于cuda - 推力不调用设备功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31684346/