2

我一直在阅读关于模板函数的 CUDA 编程指南,这样的工作是否有效?

#include <cstdio>

/* host struct */
template <typename T>
struct Test {
    T  *val;
    int size;
};

/* struct device */
template <typename T>
__device__ Test<T> *d_test;

/* test function */
template <typename T>
T __device__ testfunc() {
    return *d_test<T>->val;
}

/* test kernel */
__global__ void kernel() {
    printf("funcout = %g \n", testfunc<float>());
}

我得到了正确的结果,但有一个警告:

“警告:不能在设备函数中直接读取主机变量“d_test [with T=T]”?

testfunction 中的结构是否要实例化*d_test<float>->val

KR,伊吉

4

2 回答 2

2

不幸的是,CUDA 编译器似乎通常在变量模板方面存在一些问题。如果您查看程序集,您会发现一切正常。编译器显然会实例化变量模板并分配相应的设备对象。

.global .align 8 .u64 _Z6d_testIfE;

生成的代码就像它应该使用的那样使用这个对象

ld.global.u64   %rd3, [_Z6d_testIfE];

我认为这个警告是编译器错误。请注意,我无法在此处重现 CUDA 10 的问题,因此这个问题很可能现在已经修复。考虑更新你的编译器……

于 2019-03-28T20:02:42.403 回答
1

@MichaelKenzel 是正确的。

这几乎可以肯定是一个 nvcc 错误 - 我现在已经提交了(您可能需要一个帐户才能访问它。

另请注意,我已经能够用更少的代码重现该问题:

template <typename T>
struct foo { int  val; };

template <typename T>
__device__ foo<T> *x;

template <typename T>
int __device__ f() { return x<T>->val; }

__global__ void kernel() { int y = f<float>(); }

并查看GodBolt 上的结果

于 2019-03-28T20:31:07.373 回答