我想在我的内核中使用一些标准的库代码。具体来说,假设我想使用std::swap()
。如果我尝试这样做,nvcc会抱怨这是设备代码中使用的主机功能。
现在,如果这是我自己编写的一个函数,我会按照this question的答案中的建议将其声明为__host__ __device__
;但它不是......我显然不会触及C ++标准库头。我该怎么办?
答案 0 :(得分:3)
我该怎么办?
简短的回答是,你什么都不做。如果您希望C ++标准库中的函数在CUDA设备代码中使用,那么除了编写自己的CUDA实现或在设备代码库中查找现有实现(例如cub)之外别无选择。 / p>
在您的简单示例中,std::swap
可以重新实现,如:
// standard disclaimer: written in browser, never tested or compiled, use at own risk
namespace gpustd
{
template <class T>
__device__ void swap ( T& a, T& b ){ T c(a); a=b; b=c; }
}
// ......
__global__ void kernel(float *x, float *y, int n)
{
int tid = threadIdx.x + blockIdx.x * blockDim.x;
for(; tid < n; tid += gridDim.x * blockDim.x) {
gpustd::swap<float>(x[tid], y[tid]);
}
}
即。设备代码不必很复杂,但您必须编写它。
使用一些明智的__device__
限定符来装饰像GNU C ++标准库这样的选定部分是不切实际/不可能的,这将神奇地使你成为GPU C ++标准库。 CUDA编译器支持的C ++语言特性和模板定义复杂程度根本不足以使该方法可行。