nvcc 警告设备变量是主机变量 - 为什么?
nvcc warns about a device variable being a host variable - why?
我一直在阅读 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>());
}
我得到了正确的结果,但有一个警告:
"warning: a host variable "d_test [with T=T]“不能在设备函数中直接读取”?
testfunction 中的结构是否要用 *d_test<float>->val
实例化?
韩国,
伊吉
不幸的是,CUDA 编译器似乎通常在变量模板方面存在一些问题。如果你 look at the assembly,你会发现一切正常。编译器显然确实实例化了变量模板并分配了相应的设备对象。
.global .align 8 .u64 _Z6d_testIfE;
生成的代码使用这个对象就像它应该的那样
ld.global.u64 %rd3, [_Z6d_testIfE];
我认为此警告是编译器错误。请注意,我无法在此处重现 CUDA 10 的问题,因此该问题很可能现在已得到修复。考虑更新你的编译器…
@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。
我一直在阅读 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>());
}
我得到了正确的结果,但有一个警告:
"warning: a host variable "d_test [with T=T]“不能在设备函数中直接读取”?
testfunction 中的结构是否要用 *d_test<float>->val
实例化?
韩国, 伊吉
不幸的是,CUDA 编译器似乎通常在变量模板方面存在一些问题。如果你 look at the assembly,你会发现一切正常。编译器显然确实实例化了变量模板并分配了相应的设备对象。
.global .align 8 .u64 _Z6d_testIfE;
生成的代码使用这个对象就像它应该的那样
ld.global.u64 %rd3, [_Z6d_testIfE];
我认为此警告是编译器错误。请注意,我无法在此处重现 CUDA 10 的问题,因此该问题很可能现在已得到修复。考虑更新你的编译器…
@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。