我已经在《 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]””?
测试函数中的结构是否可以用*d_test<float>->val
实例化?
KR, 伊吉
答案 0 :(得分:2)
不幸的是,CUDA编译器似乎通常在变量模板方面存在一些问题。如果您look at the assembly,您会发现一切正常。显然,编译器确实实例化了变量模板并分配了相应的设备对象。
.global .align 8 .u64 _Z6d_testIfE;
生成的代码使用该对象的方式就像
ld.global.u64 %rd3, [_Z6d_testIfE];
我会将此警告视为编译器错误。请注意,我无法在此处重现CUDA 10的问题,因此,到目前为止,此问题很可能已得到修复。考虑更新您的编译器...
答案 1 :(得分:1)
@MichaelKenzel是正确的。
这几乎可以肯定是一个nvcc错误-我现在filed(您可能需要一个帐户才能访问它)。
还请注意,我已经可以用更少的代码重现该问题:
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>(); }
并同时查看result on GodBolt。